.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * net/sched/act_simple.c Simple example of an action |
---|
3 | 4 | * |
---|
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 | | - * |
---|
9 | 5 | * Authors: Jamal Hadi Salim (2005-8) |
---|
10 | | - * |
---|
11 | 6 | */ |
---|
12 | 7 | |
---|
13 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
18 | 13 | #include <linux/rtnetlink.h> |
---|
19 | 14 | #include <net/netlink.h> |
---|
20 | 15 | #include <net/pkt_sched.h> |
---|
21 | | - |
---|
22 | | -#define TCA_ACT_SIMP 22 |
---|
| 16 | +#include <net/pkt_cls.h> |
---|
23 | 17 | |
---|
24 | 18 | #include <linux/tc_act/tc_defact.h> |
---|
25 | 19 | #include <net/tc_act/tc_defact.h> |
---|
.. | .. |
---|
41 | 35 | * Example if this was the 3rd packet and the string was "hello" |
---|
42 | 36 | * then it would look like "hello_3" (without quotes) |
---|
43 | 37 | */ |
---|
44 | | - pr_info("simple: %s_%d\n", |
---|
| 38 | + pr_info("simple: %s_%llu\n", |
---|
45 | 39 | (char *)d->tcfd_defdata, d->tcf_bstats.packets); |
---|
46 | 40 | spin_unlock(&d->tcf_lock); |
---|
47 | 41 | return d->tcf_action; |
---|
.. | .. |
---|
62 | 56 | return 0; |
---|
63 | 57 | } |
---|
64 | 58 | |
---|
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) |
---|
67 | 62 | { |
---|
| 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); |
---|
68 | 71 | spin_lock_bh(&d->tcf_lock); |
---|
69 | | - d->tcf_action = p->action; |
---|
| 72 | + goto_ch = tcf_action_set_ctrlact(a, p->action, goto_ch); |
---|
70 | 73 | memset(d->tcfd_defdata, 0, SIMP_MAX_DATA); |
---|
71 | 74 | nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); |
---|
72 | 75 | spin_unlock_bh(&d->tcf_lock); |
---|
| 76 | + if (goto_ch) |
---|
| 77 | + tcf_chain_put_by_act(goto_ch); |
---|
| 78 | + return 0; |
---|
73 | 79 | } |
---|
74 | 80 | |
---|
75 | 81 | static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = { |
---|
.. | .. |
---|
80 | 86 | static int tcf_simp_init(struct net *net, struct nlattr *nla, |
---|
81 | 87 | struct nlattr *est, struct tc_action **a, |
---|
82 | 88 | int ovr, int bind, bool rtnl_held, |
---|
| 89 | + struct tcf_proto *tp, u32 flags, |
---|
83 | 90 | struct netlink_ext_ack *extack) |
---|
84 | 91 | { |
---|
85 | 92 | struct tc_action_net *tn = net_generic(net, simp_net_id); |
---|
86 | 93 | struct nlattr *tb[TCA_DEF_MAX + 1]; |
---|
| 94 | + struct tcf_chain *goto_ch = NULL; |
---|
87 | 95 | struct tc_defact *parm; |
---|
88 | 96 | struct tcf_defact *d; |
---|
89 | 97 | bool exists = false; |
---|
.. | .. |
---|
93 | 101 | if (nla == NULL) |
---|
94 | 102 | return -EINVAL; |
---|
95 | 103 | |
---|
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); |
---|
97 | 106 | if (err < 0) |
---|
98 | 107 | return err; |
---|
99 | 108 | |
---|
.. | .. |
---|
119 | 128 | |
---|
120 | 129 | if (!exists) { |
---|
121 | 130 | ret = tcf_idr_create(tn, index, est, a, |
---|
122 | | - &act_simp_ops, bind, false); |
---|
| 131 | + &act_simp_ops, bind, false, flags); |
---|
123 | 132 | if (ret) { |
---|
124 | 133 | tcf_idr_cleanup(tn, index); |
---|
125 | 134 | return ret; |
---|
126 | 135 | } |
---|
127 | 136 | |
---|
128 | 137 | 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); |
---|
135 | 148 | ret = ACT_P_CREATED; |
---|
136 | 149 | } else { |
---|
137 | | - d = to_defact(*a); |
---|
138 | | - |
---|
139 | 150 | if (!ovr) { |
---|
140 | | - tcf_idr_release(*a, bind); |
---|
141 | | - return -EEXIST; |
---|
| 151 | + err = -EEXIST; |
---|
| 152 | + goto release_idr; |
---|
142 | 153 | } |
---|
143 | 154 | |
---|
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; |
---|
145 | 158 | } |
---|
146 | 159 | |
---|
147 | | - if (ret == ACT_P_CREATED) |
---|
148 | | - tcf_idr_insert(tn, *a); |
---|
149 | 160 | 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; |
---|
150 | 167 | } |
---|
151 | 168 | |
---|
152 | 169 | static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, |
---|
.. | .. |
---|
190 | 207 | return tcf_generic_walker(tn, skb, cb, type, ops, extack); |
---|
191 | 208 | } |
---|
192 | 209 | |
---|
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) |
---|
195 | 211 | { |
---|
196 | 212 | struct tc_action_net *tn = net_generic(net, simp_net_id); |
---|
197 | 213 | |
---|
.. | .. |
---|
200 | 216 | |
---|
201 | 217 | static struct tc_action_ops act_simp_ops = { |
---|
202 | 218 | .kind = "simple", |
---|
203 | | - .type = TCA_ACT_SIMP, |
---|
| 219 | + .id = TCA_ID_SIMP, |
---|
204 | 220 | .owner = THIS_MODULE, |
---|
205 | 221 | .act = tcf_simp_act, |
---|
206 | 222 | .dump = tcf_simp_dump, |
---|