Blame view
net/sched/act_pedit.c
12 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
0c6965dd3 sched: fix act fi... |
3 |
* net/sched/act_pedit.c Generic packet editor |
1da177e4c Linux-2.6.12-rc2 |
4 |
* |
1da177e4c Linux-2.6.12-rc2 |
5 6 |
* Authors: Jamal Hadi Salim (2002-4) */ |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
#include <linux/types.h> #include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
#include <linux/string.h> |
1da177e4c Linux-2.6.12-rc2 |
10 |
#include <linux/errno.h> |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 14 |
#include <linux/skbuff.h> #include <linux/rtnetlink.h> #include <linux/module.h> #include <linux/init.h> |
5a0e3ad6a include cleanup: ... |
15 |
#include <linux/slab.h> |
dc5fc579b [NETLINK]: Use nl... |
16 |
#include <net/netlink.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 |
#include <net/pkt_sched.h> #include <linux/tc_act/tc_pedit.h> #include <net/tc_act/tc_pedit.h> |
71d0ed707 net/act_pedit: Su... |
20 |
#include <uapi/linux/tc_act/tc_pedit.h> |
6ac86ca35 net/sched: act_pe... |
21 |
#include <net/pkt_cls.h> |
1da177e4c Linux-2.6.12-rc2 |
22 |
|
c7d03a00b netns: make struc... |
23 |
static unsigned int pedit_net_id; |
a85a970af net_sched: move t... |
24 |
static struct tc_action_ops act_pedit_ops; |
ddf97ccdd net_sched: add ne... |
25 |
|
53b2bf3f8 [NET_SCHED]: Use ... |
26 |
static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { |
53f7e35f8 pkt_sched: pedit ... |
27 |
[TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) }, |
71d0ed707 net/act_pedit: Su... |
28 |
[TCA_PEDIT_KEYS_EX] = { .type = NLA_NESTED }, |
53b2bf3f8 [NET_SCHED]: Use ... |
29 |
}; |
71d0ed707 net/act_pedit: Su... |
30 31 |
static const struct nla_policy pedit_key_ex_policy[TCA_PEDIT_KEY_EX_MAX + 1] = { [TCA_PEDIT_KEY_EX_HTYPE] = { .type = NLA_U16 }, |
853a14ba4 net/act_pedit: In... |
32 |
[TCA_PEDIT_KEY_EX_CMD] = { .type = NLA_U16 }, |
71d0ed707 net/act_pedit: Su... |
33 34 35 36 37 38 39 40 41 42 |
}; static struct tcf_pedit_key_ex *tcf_pedit_keys_ex_parse(struct nlattr *nla, u8 n) { struct tcf_pedit_key_ex *keys_ex; struct tcf_pedit_key_ex *k; const struct nlattr *ka; int err = -EINVAL; int rem; |
f67169fef net/sched: act_pe... |
43 |
if (!nla) |
71d0ed707 net/act_pedit: Su... |
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
return NULL; keys_ex = kcalloc(n, sizeof(*k), GFP_KERNEL); if (!keys_ex) return ERR_PTR(-ENOMEM); k = keys_ex; nla_for_each_nested(ka, nla, rem) { struct nlattr *tb[TCA_PEDIT_KEY_EX_MAX + 1]; if (!n) { err = -EINVAL; goto err_out; } n--; if (nla_type(ka) != TCA_PEDIT_KEY_EX) { err = -EINVAL; goto err_out; } |
8cb081746 netlink: make val... |
65 66 67 |
err = nla_parse_nested_deprecated(tb, TCA_PEDIT_KEY_EX_MAX, ka, pedit_key_ex_policy, NULL); |
71d0ed707 net/act_pedit: Su... |
68 69 |
if (err) goto err_out; |
853a14ba4 net/act_pedit: In... |
70 71 |
if (!tb[TCA_PEDIT_KEY_EX_HTYPE] || !tb[TCA_PEDIT_KEY_EX_CMD]) { |
71d0ed707 net/act_pedit: Su... |
72 73 74 75 76 |
err = -EINVAL; goto err_out; } k->htype = nla_get_u16(tb[TCA_PEDIT_KEY_EX_HTYPE]); |
853a14ba4 net/act_pedit: In... |
77 |
k->cmd = nla_get_u16(tb[TCA_PEDIT_KEY_EX_CMD]); |
71d0ed707 net/act_pedit: Su... |
78 |
|
853a14ba4 net/act_pedit: In... |
79 80 |
if (k->htype > TCA_PEDIT_HDR_TYPE_MAX || k->cmd > TCA_PEDIT_CMD_MAX) { |
71d0ed707 net/act_pedit: Su... |
81 82 83 84 85 86 |
err = -EINVAL; goto err_out; } k++; } |
c4f65b09b net/act_pedit: fi... |
87 88 |
if (n) { err = -EINVAL; |
71d0ed707 net/act_pedit: Su... |
89 |
goto err_out; |
c4f65b09b net/act_pedit: fi... |
90 |
} |
71d0ed707 net/act_pedit: Su... |
91 92 93 94 95 96 97 98 99 100 101 |
return keys_ex; err_out: kfree(keys_ex); return ERR_PTR(err); } static int tcf_pedit_key_ex_dump(struct sk_buff *skb, struct tcf_pedit_key_ex *keys_ex, int n) { |
ae0be8de9 netlink: make nla... |
102 103 |
struct nlattr *keys_start = nla_nest_start_noflag(skb, TCA_PEDIT_KEYS_EX); |
71d0ed707 net/act_pedit: Su... |
104 |
|
85eb9af18 net/sched: act_pe... |
105 106 |
if (!keys_start) goto nla_failure; |
71d0ed707 net/act_pedit: Su... |
107 108 |
for (; n > 0; n--) { struct nlattr *key_start; |
ae0be8de9 netlink: make nla... |
109 |
key_start = nla_nest_start_noflag(skb, TCA_PEDIT_KEY_EX); |
85eb9af18 net/sched: act_pe... |
110 111 |
if (!key_start) goto nla_failure; |
71d0ed707 net/act_pedit: Su... |
112 |
|
853a14ba4 net/act_pedit: In... |
113 |
if (nla_put_u16(skb, TCA_PEDIT_KEY_EX_HTYPE, keys_ex->htype) || |
85eb9af18 net/sched: act_pe... |
114 115 |
nla_put_u16(skb, TCA_PEDIT_KEY_EX_CMD, keys_ex->cmd)) goto nla_failure; |
71d0ed707 net/act_pedit: Su... |
116 117 118 119 120 121 122 123 124 |
nla_nest_end(skb, key_start); keys_ex++; } nla_nest_end(skb, keys_start); return 0; |
85eb9af18 net/sched: act_pe... |
125 126 127 |
nla_failure: nla_nest_cancel(skb, keys_start); return -EINVAL; |
71d0ed707 net/act_pedit: Su... |
128 |
} |
c1b52739e pkt_sched: namesp... |
129 |
static int tcf_pedit_init(struct net *net, struct nlattr *nla, |
a85a970af net_sched: move t... |
130 |
struct nlattr *est, struct tc_action **a, |
789871bb2 net: sched: imple... |
131 |
int ovr, int bind, bool rtnl_held, |
abbb0d336 net: sched: exten... |
132 133 |
struct tcf_proto *tp, u32 flags, struct netlink_ext_ack *extack) |
1da177e4c Linux-2.6.12-rc2 |
134 |
{ |
ddf97ccdd net_sched: add ne... |
135 |
struct tc_action_net *tn = net_generic(net, pedit_net_id); |
7ba699c60 [NET_SCHED]: Conv... |
136 |
struct nlattr *tb[TCA_PEDIT_MAX + 1]; |
6ac86ca35 net/sched: act_pe... |
137 |
struct tcf_chain *goto_ch = NULL; |
1da177e4c Linux-2.6.12-rc2 |
138 |
struct tc_pedit_key *keys = NULL; |
71d0ed707 net/act_pedit: Su... |
139 |
struct tcf_pedit_key_ex *keys_ex; |
80f0f574c net sched actions... |
140 141 142 143 |
struct tc_pedit *parm; struct nlattr *pattr; struct tcf_pedit *p; int ret = 0, err; |
1da177e4c Linux-2.6.12-rc2 |
144 |
int ksize; |
7be8ef2cd net: sched: use t... |
145 |
u32 index; |
1da177e4c Linux-2.6.12-rc2 |
146 |
|
9868c0b2e net sched actions... |
147 148 |
if (!nla) { NL_SET_ERR_MSG_MOD(extack, "Pedit requires attributes to be passed"); |
1da177e4c Linux-2.6.12-rc2 |
149 |
return -EINVAL; |
9868c0b2e net sched actions... |
150 |
} |
1da177e4c Linux-2.6.12-rc2 |
151 |
|
8cb081746 netlink: make val... |
152 153 |
err = nla_parse_nested_deprecated(tb, TCA_PEDIT_MAX, nla, pedit_policy, NULL); |
cee63723b [NET_SCHED]: Prop... |
154 155 |
if (err < 0) return err; |
71d0ed707 net/act_pedit: Su... |
156 157 158 |
pattr = tb[TCA_PEDIT_PARMS]; if (!pattr) pattr = tb[TCA_PEDIT_PARMS_EX]; |
9868c0b2e net sched actions... |
159 160 |
if (!pattr) { NL_SET_ERR_MSG_MOD(extack, "Missing required TCA_PEDIT_PARMS or TCA_PEDIT_PARMS_EX pedit attribute"); |
1da177e4c Linux-2.6.12-rc2 |
161 |
return -EINVAL; |
9868c0b2e net sched actions... |
162 |
} |
71d0ed707 net/act_pedit: Su... |
163 164 |
parm = nla_data(pattr); |
f67169fef net/sched: act_pe... |
165 166 167 168 |
if (!parm->nkeys) { NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed"); return -EINVAL; } |
1da177e4c Linux-2.6.12-rc2 |
169 |
ksize = parm->nkeys * sizeof(struct tc_pedit_key); |
9868c0b2e net sched actions... |
170 171 |
if (nla_len(pattr) < sizeof(*parm) + ksize) { NL_SET_ERR_MSG_ATTR(extack, pattr, "Length of TCA_PEDIT_PARMS or TCA_PEDIT_PARMS_EX pedit attribute is invalid"); |
1da177e4c Linux-2.6.12-rc2 |
172 |
return -EINVAL; |
9868c0b2e net sched actions... |
173 |
} |
1da177e4c Linux-2.6.12-rc2 |
174 |
|
71d0ed707 net/act_pedit: Su... |
175 176 177 |
keys_ex = tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys); if (IS_ERR(keys_ex)) return PTR_ERR(keys_ex); |
7be8ef2cd net: sched: use t... |
178 179 |
index = parm->index; err = tcf_idr_check_alloc(tn, &index, a, bind); |
0190c1d45 net: sched: atomi... |
180 |
if (!err) { |
7be8ef2cd net: sched: use t... |
181 |
ret = tcf_idr_create(tn, index, est, a, |
e38226786 net: sched: updat... |
182 |
&act_pedit_ops, bind, false, 0); |
0190c1d45 net: sched: atomi... |
183 |
if (ret) { |
7be8ef2cd net: sched: use t... |
184 |
tcf_idr_cleanup(tn, index); |
30e99ed6d net: sched: act_p... |
185 |
goto out_free; |
0190c1d45 net: sched: atomi... |
186 |
} |
1da177e4c Linux-2.6.12-rc2 |
187 |
ret = ACT_P_CREATED; |
0190c1d45 net: sched: atomi... |
188 |
} else if (err > 0) { |
1a29321ed net_sched: act: D... |
189 |
if (bind) |
30e99ed6d net: sched: act_p... |
190 |
goto out_free; |
30e99ed6d net: sched: act_p... |
191 192 |
if (!ovr) { ret = -EEXIST; |
67b0c1a3c net: sched: act_p... |
193 |
goto out_release; |
1da177e4c Linux-2.6.12-rc2 |
194 |
} |
0190c1d45 net: sched: atomi... |
195 |
} else { |
19ab69107 net/sched: act_pe... |
196 197 |
ret = err; goto out_free; |
1da177e4c Linux-2.6.12-rc2 |
198 |
} |
6ac86ca35 net/sched: act_pe... |
199 200 201 202 203 |
err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack); if (err < 0) { ret = err; goto out_release; } |
67b0c1a3c net: sched: act_p... |
204 |
p = to_pedit(*a); |
e9ce1cd3c [PKT_SCHED]: Kill... |
205 |
spin_lock_bh(&p->tcf_lock); |
67b0c1a3c net: sched: act_p... |
206 207 208 209 210 211 212 |
if (ret == ACT_P_CREATED || (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys)) { keys = kmalloc(ksize, GFP_ATOMIC); if (!keys) { spin_unlock_bh(&p->tcf_lock); ret = -ENOMEM; |
6ac86ca35 net/sched: act_pe... |
213 |
goto put_chain; |
67b0c1a3c net: sched: act_p... |
214 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
215 216 217 |
kfree(p->tcfp_keys); p->tcfp_keys = keys; p->tcfp_nkeys = parm->nkeys; |
1da177e4c Linux-2.6.12-rc2 |
218 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
219 |
memcpy(p->tcfp_keys, parm->keys, ksize); |
71d0ed707 net/act_pedit: Su... |
220 |
|
67b0c1a3c net: sched: act_p... |
221 |
p->tcfp_flags = parm->flags; |
6ac86ca35 net/sched: act_pe... |
222 |
goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); |
67b0c1a3c net: sched: act_p... |
223 |
|
71d0ed707 net/act_pedit: Su... |
224 225 |
kfree(p->tcfp_keys_ex); p->tcfp_keys_ex = keys_ex; |
e9ce1cd3c [PKT_SCHED]: Kill... |
226 |
spin_unlock_bh(&p->tcf_lock); |
6ac86ca35 net/sched: act_pe... |
227 228 |
if (goto_ch) tcf_chain_put_by_act(goto_ch); |
1da177e4c Linux-2.6.12-rc2 |
229 |
return ret; |
67b0c1a3c net: sched: act_p... |
230 |
|
6ac86ca35 net/sched: act_pe... |
231 232 233 |
put_chain: if (goto_ch) tcf_chain_put_by_act(goto_ch); |
67b0c1a3c net: sched: act_p... |
234 235 |
out_release: tcf_idr_release(*a, bind); |
30e99ed6d net: sched: act_p... |
236 237 238 |
out_free: kfree(keys_ex); return ret; |
1da177e4c Linux-2.6.12-rc2 |
239 |
} |
9a63b255d net_sched: remove... |
240 |
static void tcf_pedit_cleanup(struct tc_action *a) |
1da177e4c Linux-2.6.12-rc2 |
241 |
{ |
a85a970af net_sched: move t... |
242 |
struct tcf_pedit *p = to_pedit(a); |
a5b5c958f net_sched: act: r... |
243 |
struct tc_pedit_key *keys = p->tcfp_keys; |
80f0f574c net sched actions... |
244 |
|
a5b5c958f net_sched: act: r... |
245 |
kfree(keys); |
71d0ed707 net/act_pedit: Su... |
246 |
kfree(p->tcfp_keys_ex); |
1da177e4c Linux-2.6.12-rc2 |
247 |
} |
95c2027bf net/sched: pedit:... |
248 249 250 251 252 253 254 255 256 257 |
static bool offset_valid(struct sk_buff *skb, int offset) { if (offset > 0 && offset > skb->len) return false; if (offset < 0 && -offset > skb_headroom(skb)) return false; return true; } |
71d0ed707 net/act_pedit: Su... |
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
static int pedit_skb_hdr_offset(struct sk_buff *skb, enum pedit_header_type htype, int *hoffset) { int ret = -EINVAL; switch (htype) { case TCA_PEDIT_KEY_EX_HDR_TYPE_ETH: if (skb_mac_header_was_set(skb)) { *hoffset = skb_mac_offset(skb); ret = 0; } break; case TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK: case TCA_PEDIT_KEY_EX_HDR_TYPE_IP4: case TCA_PEDIT_KEY_EX_HDR_TYPE_IP6: *hoffset = skb_network_offset(skb); ret = 0; break; case TCA_PEDIT_KEY_EX_HDR_TYPE_TCP: case TCA_PEDIT_KEY_EX_HDR_TYPE_UDP: if (skb_transport_header_was_set(skb)) { *hoffset = skb_transport_offset(skb); ret = 0; } break; default: ret = -EINVAL; break; |
0a80848ec act_pedit: remove... |
286 |
} |
71d0ed707 net/act_pedit: Su... |
287 288 289 |
return ret; } |
6a2b401cd net: sched: act_p... |
290 291 |
static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) |
1da177e4c Linux-2.6.12-rc2 |
292 |
{ |
a85a970af net_sched: move t... |
293 |
struct tcf_pedit *p = to_pedit(a); |
4749c3ef8 net: sched: remov... |
294 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
295 |
|
14bbd6a56 net: Add skb_uncl... |
296 |
if (skb_unclone(skb, GFP_ATOMIC)) |
cc7ec456f net_sched: cleanups |
297 |
return p->tcf_action; |
1da177e4c Linux-2.6.12-rc2 |
298 |
|
e9ce1cd3c [PKT_SCHED]: Kill... |
299 |
spin_lock(&p->tcf_lock); |
1da177e4c Linux-2.6.12-rc2 |
300 |
|
9c4a4e488 net sched: action... |
301 |
tcf_lastuse_update(&p->tcf_tm); |
1da177e4c Linux-2.6.12-rc2 |
302 |
|
e9ce1cd3c [PKT_SCHED]: Kill... |
303 304 |
if (p->tcfp_nkeys > 0) { struct tc_pedit_key *tkey = p->tcfp_keys; |
71d0ed707 net/act_pedit: Su... |
305 |
struct tcf_pedit_key_ex *tkey_ex = p->tcfp_keys_ex; |
80f0f574c net sched actions... |
306 307 |
enum pedit_header_type htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; |
853a14ba4 net/act_pedit: In... |
308 |
enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET; |
1da177e4c Linux-2.6.12-rc2 |
309 |
|
e9ce1cd3c [PKT_SCHED]: Kill... |
310 |
for (i = p->tcfp_nkeys; i > 0; i--, tkey++) { |
544377cd2 net sched actions... |
311 |
u32 *ptr, hdata; |
1da177e4c Linux-2.6.12-rc2 |
312 |
int offset = tkey->off; |
71d0ed707 net/act_pedit: Su... |
313 |
int hoffset; |
853a14ba4 net/act_pedit: In... |
314 |
u32 val; |
71d0ed707 net/act_pedit: Su... |
315 316 317 318 |
int rc; if (tkey_ex) { htype = tkey_ex->htype; |
853a14ba4 net/act_pedit: In... |
319 |
cmd = tkey_ex->cmd; |
71d0ed707 net/act_pedit: Su... |
320 321 322 323 324 |
tkey_ex++; } rc = pedit_skb_hdr_offset(skb, htype, &hoffset); if (rc) { |
95b0d2dc1 net sched actions... |
325 326 |
pr_info("tc action pedit bad header type specified (0x%x) ", |
71d0ed707 net/act_pedit: Su... |
327 328 329 |
htype); goto bad; } |
1da177e4c Linux-2.6.12-rc2 |
330 331 |
if (tkey->offmask) { |
430527415 net sched actions... |
332 |
u8 *d, _d; |
db2c24175 act_pedit: access... |
333 |
|
71d0ed707 net/act_pedit: Su... |
334 |
if (!offset_valid(skb, hoffset + tkey->at)) { |
95b0d2dc1 net sched actions... |
335 336 |
pr_info("tc action pedit 'at' offset %d out of bounds ", |
71d0ed707 net/act_pedit: Su... |
337 |
hoffset + tkey->at); |
95c2027bf net/sched: pedit:... |
338 339 |
goto bad; } |
80f0f574c net sched actions... |
340 |
d = skb_header_pointer(skb, hoffset + tkey->at, |
6ff7586e3 net sched actions... |
341 |
sizeof(_d), &_d); |
db2c24175 act_pedit: access... |
342 |
if (!d) |
1da177e4c Linux-2.6.12-rc2 |
343 |
goto bad; |
db2c24175 act_pedit: access... |
344 |
offset += (*d & tkey->offmask) >> tkey->shift; |
1da177e4c Linux-2.6.12-rc2 |
345 346 347 |
} if (offset % 4) { |
95b0d2dc1 net sched actions... |
348 349 |
pr_info("tc action pedit offset must be on 32 bit boundaries "); |
1da177e4c Linux-2.6.12-rc2 |
350 351 |
goto bad; } |
95c2027bf net/sched: pedit:... |
352 |
|
71d0ed707 net/act_pedit: Su... |
353 |
if (!offset_valid(skb, hoffset + offset)) { |
95b0d2dc1 net sched actions... |
354 355 |
pr_info("tc action pedit offset %d out of bounds ", |
71d0ed707 net/act_pedit: Su... |
356 |
hoffset + offset); |
1da177e4c Linux-2.6.12-rc2 |
357 358 |
goto bad; } |
80f0f574c net sched actions... |
359 |
ptr = skb_header_pointer(skb, hoffset + offset, |
6ff7586e3 net sched actions... |
360 |
sizeof(hdata), &hdata); |
db2c24175 act_pedit: access... |
361 362 |
if (!ptr) goto bad; |
1da177e4c Linux-2.6.12-rc2 |
363 |
/* just do it, baby */ |
853a14ba4 net/act_pedit: In... |
364 365 366 367 368 369 370 371 |
switch (cmd) { case TCA_PEDIT_KEY_EX_CMD_SET: val = tkey->val; break; case TCA_PEDIT_KEY_EX_CMD_ADD: val = (*ptr + tkey->val) & ~tkey->mask; break; default: |
95b0d2dc1 net sched actions... |
372 373 |
pr_info("tc action pedit bad command (%d) ", |
853a14ba4 net/act_pedit: In... |
374 375 376 377 378 |
cmd); goto bad; } *ptr = ((*ptr & tkey->mask) ^ val); |
544377cd2 net sched actions... |
379 |
if (ptr == &hdata) |
71d0ed707 net/act_pedit: Su... |
380 |
skb_store_bits(skb, hoffset + offset, ptr, 4); |
1da177e4c Linux-2.6.12-rc2 |
381 |
} |
10297b993 [NET] SCHED: Fix ... |
382 |
|
1da177e4c Linux-2.6.12-rc2 |
383 |
goto done; |
80f0f574c net sched actions... |
384 |
} else { |
6ff9c3644 net sched: printk... |
385 386 |
WARN(1, "pedit BUG: index %d ", p->tcf_index); |
80f0f574c net sched actions... |
387 |
} |
1da177e4c Linux-2.6.12-rc2 |
388 389 |
bad: |
e9ce1cd3c [PKT_SCHED]: Kill... |
390 |
p->tcf_qstats.overlimits++; |
1da177e4c Linux-2.6.12-rc2 |
391 |
done: |
bfe0d0298 net_sched: factor... |
392 |
bstats_update(&p->tcf_bstats, skb); |
e9ce1cd3c [PKT_SCHED]: Kill... |
393 394 |
spin_unlock(&p->tcf_lock); return p->tcf_action; |
1da177e4c Linux-2.6.12-rc2 |
395 |
} |
4b61d3e8d net: qos offload ... |
396 397 |
static void tcf_pedit_stats_update(struct tc_action *a, u64 bytes, u64 packets, u64 drops, u64 lastuse, bool hw) |
d4d9d9c53 sched: act_pedit:... |
398 399 400 |
{ struct tcf_pedit *d = to_pedit(a); struct tcf_t *tm = &d->tcf_tm; |
4b61d3e8d net: qos offload ... |
401 |
tcf_action_update_stats(a, bytes, packets, drops, hw); |
d4d9d9c53 sched: act_pedit:... |
402 403 |
tm->lastuse = max_t(u64, tm->lastuse, lastuse); } |
e9ce1cd3c [PKT_SCHED]: Kill... |
404 405 |
static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) |
1da177e4c Linux-2.6.12-rc2 |
406 |
{ |
27a884dc3 [SK_BUFF]: Conver... |
407 |
unsigned char *b = skb_tail_pointer(skb); |
a85a970af net_sched: move t... |
408 |
struct tcf_pedit *p = to_pedit(a); |
1da177e4c Linux-2.6.12-rc2 |
409 |
struct tc_pedit *opt; |
1da177e4c Linux-2.6.12-rc2 |
410 |
struct tcf_t t; |
10297b993 [NET] SCHED: Fix ... |
411 |
int s; |
8fe5756c7 net/sched: use st... |
412 |
s = struct_size(opt, keys, p->tcfp_nkeys); |
1da177e4c Linux-2.6.12-rc2 |
413 414 |
/* netlink spinlocks held above us - must use ATOMIC */ |
0da974f4f [NET]: Conversion... |
415 |
opt = kzalloc(s, GFP_ATOMIC); |
e9ce1cd3c [PKT_SCHED]: Kill... |
416 |
if (unlikely(!opt)) |
1da177e4c Linux-2.6.12-rc2 |
417 |
return -ENOBUFS; |
1da177e4c Linux-2.6.12-rc2 |
418 |
|
67b0c1a3c net: sched: act_p... |
419 |
spin_lock_bh(&p->tcf_lock); |
a0d716d8e net/sched: act_pe... |
420 |
memcpy(opt->keys, p->tcfp_keys, flex_array_size(opt, keys, p->tcfp_nkeys)); |
e9ce1cd3c [PKT_SCHED]: Kill... |
421 422 423 424 |
opt->index = p->tcf_index; opt->nkeys = p->tcfp_nkeys; opt->flags = p->tcfp_flags; opt->action = p->tcf_action; |
036bb4432 net: sched: chang... |
425 426 |
opt->refcnt = refcount_read(&p->tcf_refcnt) - ref; opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind; |
1da177e4c Linux-2.6.12-rc2 |
427 |
|
71d0ed707 net/act_pedit: Su... |
428 |
if (p->tcfp_keys_ex) { |
85eb9af18 net/sched: act_pe... |
429 430 431 432 |
if (tcf_pedit_key_ex_dump(skb, p->tcfp_keys_ex, p->tcfp_nkeys)) goto nla_put_failure; |
71d0ed707 net/act_pedit: Su... |
433 434 435 436 437 438 439 |
if (nla_put(skb, TCA_PEDIT_PARMS_EX, s, opt)) goto nla_put_failure; } else { if (nla_put(skb, TCA_PEDIT_PARMS, s, opt)) goto nla_put_failure; } |
48d8ee169 net sched actions... |
440 441 |
tcf_tm_dump(&t, &p->tcf_tm); |
9854518ea sched: align nlat... |
442 |
if (nla_put_64bit(skb, TCA_PEDIT_TM, sizeof(t), &t, TCA_PEDIT_PAD)) |
1b34ec43c pkt_sched: Stop u... |
443 |
goto nla_put_failure; |
67b0c1a3c net: sched: act_p... |
444 |
spin_unlock_bh(&p->tcf_lock); |
48d8ee169 net sched actions... |
445 |
|
541673c85 [PKT_SCHED]: Fix ... |
446 |
kfree(opt); |
1da177e4c Linux-2.6.12-rc2 |
447 |
return skb->len; |
7ba699c60 [NET_SCHED]: Conv... |
448 |
nla_put_failure: |
67b0c1a3c net: sched: act_p... |
449 |
spin_unlock_bh(&p->tcf_lock); |
dc5fc579b [NETLINK]: Use nl... |
450 |
nlmsg_trim(skb, b); |
541673c85 [PKT_SCHED]: Fix ... |
451 |
kfree(opt); |
1da177e4c Linux-2.6.12-rc2 |
452 453 |
return -1; } |
ddf97ccdd net_sched: add ne... |
454 455 |
static int tcf_pedit_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, |
417801055 net: sched: act: ... |
456 457 |
const struct tc_action_ops *ops, struct netlink_ext_ack *extack) |
ddf97ccdd net_sched: add ne... |
458 459 |
{ struct tc_action_net *tn = net_generic(net, pedit_net_id); |
b36201455 net: sched: act: ... |
460 |
return tcf_generic_walker(tn, skb, cb, type, ops, extack); |
ddf97ccdd net_sched: add ne... |
461 |
} |
f061b48c1 Revert "net: sche... |
462 |
static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index) |
ddf97ccdd net_sched: add ne... |
463 464 |
{ struct tc_action_net *tn = net_generic(net, pedit_net_id); |
65a206c01 net/sched: Change... |
465 |
return tcf_idr_search(tn, a, index); |
ddf97ccdd net_sched: add ne... |
466 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
467 |
static struct tc_action_ops act_pedit_ops = { |
1da177e4c Linux-2.6.12-rc2 |
468 |
.kind = "pedit", |
eddd2cf19 net: Change TCA_A... |
469 |
.id = TCA_ID_PEDIT, |
1da177e4c Linux-2.6.12-rc2 |
470 |
.owner = THIS_MODULE, |
6a2b401cd net: sched: act_p... |
471 |
.act = tcf_pedit_act, |
d4d9d9c53 sched: act_pedit:... |
472 |
.stats_update = tcf_pedit_stats_update, |
1da177e4c Linux-2.6.12-rc2 |
473 474 |
.dump = tcf_pedit_dump, .cleanup = tcf_pedit_cleanup, |
1da177e4c Linux-2.6.12-rc2 |
475 |
.init = tcf_pedit_init, |
ddf97ccdd net_sched: add ne... |
476 477 |
.walk = tcf_pedit_walker, .lookup = tcf_pedit_search, |
a85a970af net_sched: move t... |
478 |
.size = sizeof(struct tcf_pedit), |
ddf97ccdd net_sched: add ne... |
479 480 481 482 483 |
}; static __net_init int pedit_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, pedit_net_id); |
981471bd3 net_sched: fix a ... |
484 |
return tc_action_net_init(net, tn, &act_pedit_ops); |
ddf97ccdd net_sched: add ne... |
485 |
} |
039af9c66 net_sched: switch... |
486 |
static void __net_exit pedit_exit_net(struct list_head *net_list) |
ddf97ccdd net_sched: add ne... |
487 |
{ |
039af9c66 net_sched: switch... |
488 |
tc_action_net_exit(net_list, pedit_net_id); |
ddf97ccdd net_sched: add ne... |
489 490 491 492 |
} static struct pernet_operations pedit_net_ops = { .init = pedit_init_net, |
039af9c66 net_sched: switch... |
493 |
.exit_batch = pedit_exit_net, |
ddf97ccdd net_sched: add ne... |
494 495 |
.id = &pedit_net_id, .size = sizeof(struct tc_action_net), |
1da177e4c Linux-2.6.12-rc2 |
496 497 498 499 500 |
}; MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); MODULE_DESCRIPTION("Generic Packet Editor actions"); MODULE_LICENSE("GPL"); |
e9ce1cd3c [PKT_SCHED]: Kill... |
501 |
static int __init pedit_init_module(void) |
1da177e4c Linux-2.6.12-rc2 |
502 |
{ |
ddf97ccdd net_sched: add ne... |
503 |
return tcf_register_action(&act_pedit_ops, &pedit_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
504 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
505 |
static void __exit pedit_cleanup_module(void) |
1da177e4c Linux-2.6.12-rc2 |
506 |
{ |
ddf97ccdd net_sched: add ne... |
507 |
tcf_unregister_action(&act_pedit_ops, &pedit_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
508 509 510 511 |
} module_init(pedit_init_module); module_exit(pedit_cleanup_module); |