hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sched/act_simple.c
....@@ -1,13 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * net/sched/act_simple.c Simple example of an action
34 *
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
- *
95 * Authors: Jamal Hadi Salim (2005-8)
10
- *
116 */
127
138 #include <linux/module.h>
....@@ -18,8 +13,7 @@
1813 #include <linux/rtnetlink.h>
1914 #include <net/netlink.h>
2015 #include <net/pkt_sched.h>
21
-
22
-#define TCA_ACT_SIMP 22
16
+#include <net/pkt_cls.h>
2317
2418 #include <linux/tc_act/tc_defact.h>
2519 #include <net/tc_act/tc_defact.h>
....@@ -41,7 +35,7 @@
4135 * Example if this was the 3rd packet and the string was "hello"
4236 * then it would look like "hello_3" (without quotes)
4337 */
44
- pr_info("simple: %s_%d\n",
38
+ pr_info("simple: %s_%llu\n",
4539 (char *)d->tcfd_defdata, d->tcf_bstats.packets);
4640 spin_unlock(&d->tcf_lock);
4741 return d->tcf_action;
....@@ -62,14 +56,26 @@
6256 return 0;
6357 }
6458
65
-static void reset_policy(struct tcf_defact *d, const struct nlattr *defdata,
66
- struct tc_defact *p)
59
+static int reset_policy(struct tc_action *a, const struct nlattr *defdata,
60
+ struct tc_defact *p, struct tcf_proto *tp,
61
+ struct netlink_ext_ack *extack)
6762 {
63
+ struct tcf_chain *goto_ch = NULL;
64
+ struct tcf_defact *d;
65
+ int err;
66
+
67
+ err = tcf_action_check_ctrlact(p->action, tp, &goto_ch, extack);
68
+ if (err < 0)
69
+ return err;
70
+ d = to_defact(a);
6871 spin_lock_bh(&d->tcf_lock);
69
- d->tcf_action = p->action;
72
+ goto_ch = tcf_action_set_ctrlact(a, p->action, goto_ch);
7073 memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
7174 nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
7275 spin_unlock_bh(&d->tcf_lock);
76
+ if (goto_ch)
77
+ tcf_chain_put_by_act(goto_ch);
78
+ return 0;
7379 }
7480
7581 static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
....@@ -80,10 +86,12 @@
8086 static int tcf_simp_init(struct net *net, struct nlattr *nla,
8187 struct nlattr *est, struct tc_action **a,
8288 int ovr, int bind, bool rtnl_held,
89
+ struct tcf_proto *tp, u32 flags,
8390 struct netlink_ext_ack *extack)
8491 {
8592 struct tc_action_net *tn = net_generic(net, simp_net_id);
8693 struct nlattr *tb[TCA_DEF_MAX + 1];
94
+ struct tcf_chain *goto_ch = NULL;
8795 struct tc_defact *parm;
8896 struct tcf_defact *d;
8997 bool exists = false;
....@@ -93,7 +101,8 @@
93101 if (nla == NULL)
94102 return -EINVAL;
95103
96
- err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy, NULL);
104
+ err = nla_parse_nested_deprecated(tb, TCA_DEF_MAX, nla, simple_policy,
105
+ NULL);
97106 if (err < 0)
98107 return err;
99108
....@@ -119,34 +128,42 @@
119128
120129 if (!exists) {
121130 ret = tcf_idr_create(tn, index, est, a,
122
- &act_simp_ops, bind, false);
131
+ &act_simp_ops, bind, false, flags);
123132 if (ret) {
124133 tcf_idr_cleanup(tn, index);
125134 return ret;
126135 }
127136
128137 d = to_defact(*a);
129
- ret = alloc_defdata(d, tb[TCA_DEF_DATA]);
130
- if (ret < 0) {
131
- tcf_idr_release(*a, bind);
132
- return ret;
133
- }
134
- d->tcf_action = parm->action;
138
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch,
139
+ extack);
140
+ if (err < 0)
141
+ goto release_idr;
142
+
143
+ err = alloc_defdata(d, tb[TCA_DEF_DATA]);
144
+ if (err < 0)
145
+ goto put_chain;
146
+
147
+ tcf_action_set_ctrlact(*a, parm->action, goto_ch);
135148 ret = ACT_P_CREATED;
136149 } else {
137
- d = to_defact(*a);
138
-
139150 if (!ovr) {
140
- tcf_idr_release(*a, bind);
141
- return -EEXIST;
151
+ err = -EEXIST;
152
+ goto release_idr;
142153 }
143154
144
- reset_policy(d, tb[TCA_DEF_DATA], parm);
155
+ err = reset_policy(*a, tb[TCA_DEF_DATA], parm, tp, extack);
156
+ if (err)
157
+ goto release_idr;
145158 }
146159
147
- if (ret == ACT_P_CREATED)
148
- tcf_idr_insert(tn, *a);
149160 return ret;
161
+put_chain:
162
+ if (goto_ch)
163
+ tcf_chain_put_by_act(goto_ch);
164
+release_idr:
165
+ tcf_idr_release(*a, bind);
166
+ return err;
150167 }
151168
152169 static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
....@@ -190,8 +207,7 @@
190207 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
191208 }
192209
193
-static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index,
194
- struct netlink_ext_ack *extack)
210
+static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index)
195211 {
196212 struct tc_action_net *tn = net_generic(net, simp_net_id);
197213
....@@ -200,7 +216,7 @@
200216
201217 static struct tc_action_ops act_simp_ops = {
202218 .kind = "simple",
203
- .type = TCA_ACT_SIMP,
219
+ .id = TCA_ID_SIMP,
204220 .owner = THIS_MODULE,
205221 .act = tcf_simp_act,
206222 .dump = tcf_simp_dump,