hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sched/act_skbmod.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * net/sched/act_skbmod.c skb data modifier
34 *
45 * Copyright (c) 2016 Jamal Hadi Salim <jhs@mojatatu.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
106 */
117
128 #include <linux/module.h>
....@@ -17,6 +13,7 @@
1713 #include <linux/rtnetlink.h>
1814 #include <net/netlink.h>
1915 #include <net/pkt_sched.h>
16
+#include <net/pkt_cls.h>
2017
2118 #include <linux/tc_act/tc_skbmod.h>
2219 #include <net/tc_act/tc_skbmod.h>
....@@ -86,11 +83,13 @@
8683 static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
8784 struct nlattr *est, struct tc_action **a,
8885 int ovr, int bind, bool rtnl_held,
86
+ struct tcf_proto *tp, u32 flags,
8987 struct netlink_ext_ack *extack)
9088 {
9189 struct tc_action_net *tn = net_generic(net, skbmod_net_id);
9290 struct nlattr *tb[TCA_SKBMOD_MAX + 1];
9391 struct tcf_skbmod_params *p, *p_old;
92
+ struct tcf_chain *goto_ch = NULL;
9493 struct tc_skbmod *parm;
9594 u32 lflags = 0, index;
9695 struct tcf_skbmod *d;
....@@ -103,7 +102,8 @@
103102 if (!nla)
104103 return -EINVAL;
105104
106
- err = nla_parse_nested(tb, TCA_SKBMOD_MAX, nla, skbmod_policy, NULL);
105
+ err = nla_parse_nested_deprecated(tb, TCA_SKBMOD_MAX, nla,
106
+ skbmod_policy, NULL);
107107 if (err < 0)
108108 return err;
109109
....@@ -147,7 +147,7 @@
147147
148148 if (!exists) {
149149 ret = tcf_idr_create(tn, index, est, a,
150
- &act_skbmod_ops, bind, true);
150
+ &act_skbmod_ops, bind, true, flags);
151151 if (ret) {
152152 tcf_idr_cleanup(tn, index);
153153 return ret;
....@@ -158,21 +158,24 @@
158158 tcf_idr_release(*a, bind);
159159 return -EEXIST;
160160 }
161
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
162
+ if (err < 0)
163
+ goto release_idr;
161164
162165 d = to_skbmod(*a);
163166
164167 p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL);
165168 if (unlikely(!p)) {
166
- tcf_idr_release(*a, bind);
167
- return -ENOMEM;
169
+ err = -ENOMEM;
170
+ goto put_chain;
168171 }
169172
170173 p->flags = lflags;
171
- d->tcf_action = parm->action;
172174
173175 if (ovr)
174176 spin_lock_bh(&d->tcf_lock);
175177 /* Protected by tcf_lock if overwriting existing action. */
178
+ goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
176179 p_old = rcu_dereference_protected(d->skbmod_p, 1);
177180
178181 if (lflags & SKBMOD_F_DMAC)
....@@ -188,10 +191,16 @@
188191
189192 if (p_old)
190193 kfree_rcu(p_old, rcu);
194
+ if (goto_ch)
195
+ tcf_chain_put_by_act(goto_ch);
191196
192
- if (ret == ACT_P_CREATED)
193
- tcf_idr_insert(tn, *a);
194197 return ret;
198
+put_chain:
199
+ if (goto_ch)
200
+ tcf_chain_put_by_act(goto_ch);
201
+release_idr:
202
+ tcf_idr_release(*a, bind);
203
+ return err;
195204 }
196205
197206 static void tcf_skbmod_cleanup(struct tc_action *a)
....@@ -256,8 +265,7 @@
256265 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
257266 }
258267
259
-static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index,
260
- struct netlink_ext_ack *extack)
268
+static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index)
261269 {
262270 struct tc_action_net *tn = net_generic(net, skbmod_net_id);
263271
....@@ -266,7 +274,7 @@
266274
267275 static struct tc_action_ops act_skbmod_ops = {
268276 .kind = "skbmod",
269
- .type = TCA_ACT_SKBMOD,
277
+ .id = TCA_ACT_SKBMOD,
270278 .owner = THIS_MODULE,
271279 .act = tcf_skbmod_act,
272280 .dump = tcf_skbmod_dump,