| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * net/sched/cls_cgroup.c Control Group Classifier |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or |
|---|
| 5 | | - * modify it under the terms of the GNU General Public License |
|---|
| 6 | | - * as published by the Free Software Foundation; either version |
|---|
| 7 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 8 | 4 | * |
|---|
| 9 | 5 | * Authors: Thomas Graf <tgraf@suug.ch> |
|---|
| 10 | 6 | */ |
|---|
| .. | .. |
|---|
| 32 | 28 | struct cls_cgroup_head *head = rcu_dereference_bh(tp->root); |
|---|
| 33 | 29 | u32 classid = task_get_classid(skb); |
|---|
| 34 | 30 | |
|---|
| 31 | + if (unlikely(!head)) |
|---|
| 32 | + return -1; |
|---|
| 35 | 33 | if (!classid) |
|---|
| 36 | 34 | return -1; |
|---|
| 37 | 35 | if (!tcf_em_tree_match(skb, &head->ematches, NULL)) |
|---|
| .. | .. |
|---|
| 78 | 76 | static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, |
|---|
| 79 | 77 | struct tcf_proto *tp, unsigned long base, |
|---|
| 80 | 78 | u32 handle, struct nlattr **tca, |
|---|
| 81 | | - void **arg, bool ovr, |
|---|
| 79 | + void **arg, bool ovr, bool rtnl_held, |
|---|
| 82 | 80 | struct netlink_ext_ack *extack) |
|---|
| 83 | 81 | { |
|---|
| 84 | 82 | struct nlattr *tb[TCA_CGROUP_MAX + 1]; |
|---|
| .. | .. |
|---|
| 99 | 97 | if (!new) |
|---|
| 100 | 98 | return -ENOBUFS; |
|---|
| 101 | 99 | |
|---|
| 102 | | - err = tcf_exts_init(&new->exts, TCA_CGROUP_ACT, TCA_CGROUP_POLICE); |
|---|
| 100 | + err = tcf_exts_init(&new->exts, net, TCA_CGROUP_ACT, TCA_CGROUP_POLICE); |
|---|
| 103 | 101 | if (err < 0) |
|---|
| 104 | 102 | goto errout; |
|---|
| 105 | 103 | new->handle = handle; |
|---|
| 106 | 104 | new->tp = tp; |
|---|
| 107 | | - err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS], |
|---|
| 108 | | - cgroup_policy, NULL); |
|---|
| 105 | + err = nla_parse_nested_deprecated(tb, TCA_CGROUP_MAX, |
|---|
| 106 | + tca[TCA_OPTIONS], cgroup_policy, |
|---|
| 107 | + NULL); |
|---|
| 109 | 108 | if (err < 0) |
|---|
| 110 | 109 | goto errout; |
|---|
| 111 | 110 | |
|---|
| 112 | 111 | err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &new->exts, ovr, |
|---|
| 113 | | - extack); |
|---|
| 112 | + true, extack); |
|---|
| 114 | 113 | if (err < 0) |
|---|
| 115 | 114 | goto errout; |
|---|
| 116 | 115 | |
|---|
| .. | .. |
|---|
| 130 | 129 | return err; |
|---|
| 131 | 130 | } |
|---|
| 132 | 131 | |
|---|
| 133 | | -static void cls_cgroup_destroy(struct tcf_proto *tp, |
|---|
| 132 | +static void cls_cgroup_destroy(struct tcf_proto *tp, bool rtnl_held, |
|---|
| 134 | 133 | struct netlink_ext_ack *extack) |
|---|
| 135 | 134 | { |
|---|
| 136 | 135 | struct cls_cgroup_head *head = rtnl_dereference(tp->root); |
|---|
| .. | .. |
|---|
| 145 | 144 | } |
|---|
| 146 | 145 | |
|---|
| 147 | 146 | static int cls_cgroup_delete(struct tcf_proto *tp, void *arg, bool *last, |
|---|
| 148 | | - struct netlink_ext_ack *extack) |
|---|
| 147 | + bool rtnl_held, struct netlink_ext_ack *extack) |
|---|
| 149 | 148 | { |
|---|
| 150 | 149 | return -EOPNOTSUPP; |
|---|
| 151 | 150 | } |
|---|
| 152 | 151 | |
|---|
| 153 | | -static void cls_cgroup_walk(struct tcf_proto *tp, struct tcf_walker *arg) |
|---|
| 152 | +static void cls_cgroup_walk(struct tcf_proto *tp, struct tcf_walker *arg, |
|---|
| 153 | + bool rtnl_held) |
|---|
| 154 | 154 | { |
|---|
| 155 | 155 | struct cls_cgroup_head *head = rtnl_dereference(tp->root); |
|---|
| 156 | 156 | |
|---|
| 157 | 157 | if (arg->count < arg->skip) |
|---|
| 158 | 158 | goto skip; |
|---|
| 159 | 159 | |
|---|
| 160 | + if (!head) |
|---|
| 161 | + return; |
|---|
| 160 | 162 | if (arg->fn(tp, head, arg) < 0) { |
|---|
| 161 | 163 | arg->stop = 1; |
|---|
| 162 | 164 | return; |
|---|
| .. | .. |
|---|
| 166 | 168 | } |
|---|
| 167 | 169 | |
|---|
| 168 | 170 | static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, void *fh, |
|---|
| 169 | | - struct sk_buff *skb, struct tcmsg *t) |
|---|
| 171 | + struct sk_buff *skb, struct tcmsg *t, bool rtnl_held) |
|---|
| 170 | 172 | { |
|---|
| 171 | 173 | struct cls_cgroup_head *head = rtnl_dereference(tp->root); |
|---|
| 172 | 174 | struct nlattr *nest; |
|---|
| 173 | 175 | |
|---|
| 174 | 176 | t->tcm_handle = head->handle; |
|---|
| 175 | 177 | |
|---|
| 176 | | - nest = nla_nest_start(skb, TCA_OPTIONS); |
|---|
| 178 | + nest = nla_nest_start_noflag(skb, TCA_OPTIONS); |
|---|
| 177 | 179 | if (nest == NULL) |
|---|
| 178 | 180 | goto nla_put_failure; |
|---|
| 179 | 181 | |
|---|