Blame view
net/sched/act_pedit.c
10.9 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
0c6965dd3 sched: fix act fi... |
2 |
* net/sched/act_pedit.c Generic packet editor |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 10 |
* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Authors: Jamal Hadi Salim (2002-4) */ |
1da177e4c Linux-2.6.12-rc2 |
11 12 |
#include <linux/types.h> #include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
13 |
#include <linux/string.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include <linux/errno.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 17 18 |
#include <linux/skbuff.h> #include <linux/rtnetlink.h> #include <linux/module.h> #include <linux/init.h> |
5a0e3ad6a include cleanup: ... |
19 |
#include <linux/slab.h> |
dc5fc579b [NETLINK]: Use nl... |
20 |
#include <net/netlink.h> |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 |
#include <net/pkt_sched.h> #include <linux/tc_act/tc_pedit.h> #include <net/tc_act/tc_pedit.h> |
71d0ed707 net/act_pedit: Su... |
24 |
#include <uapi/linux/tc_act/tc_pedit.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
|
c7d03a00b netns: make struc... |
26 |
static unsigned int pedit_net_id; |
a85a970af net_sched: move t... |
27 |
static struct tc_action_ops act_pedit_ops; |
ddf97ccdd net_sched: add ne... |
28 |
|
53b2bf3f8 [NET_SCHED]: Use ... |
29 |
static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { |
53f7e35f8 pkt_sched: pedit ... |
30 |
[TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) }, |
71d0ed707 net/act_pedit: Su... |
31 |
[TCA_PEDIT_KEYS_EX] = { .type = NLA_NESTED }, |
53b2bf3f8 [NET_SCHED]: Use ... |
32 |
}; |
71d0ed707 net/act_pedit: Su... |
33 34 |
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... |
35 |
[TCA_PEDIT_KEY_EX_CMD] = { .type = NLA_U16 }, |
71d0ed707 net/act_pedit: Su... |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
}; 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; if (!nla || !n) 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; } err = nla_parse_nested(tb, TCA_PEDIT_KEY_EX_MAX, ka, |
fceb6435e netlink: pass ext... |
71 |
pedit_key_ex_policy, NULL); |
71d0ed707 net/act_pedit: Su... |
72 73 |
if (err) goto err_out; |
853a14ba4 net/act_pedit: In... |
74 75 |
if (!tb[TCA_PEDIT_KEY_EX_HTYPE] || !tb[TCA_PEDIT_KEY_EX_CMD]) { |
71d0ed707 net/act_pedit: Su... |
76 77 78 79 80 |
err = -EINVAL; goto err_out; } k->htype = nla_get_u16(tb[TCA_PEDIT_KEY_EX_HTYPE]); |
853a14ba4 net/act_pedit: In... |
81 |
k->cmd = nla_get_u16(tb[TCA_PEDIT_KEY_EX_CMD]); |
71d0ed707 net/act_pedit: Su... |
82 |
|
853a14ba4 net/act_pedit: In... |
83 84 |
if (k->htype > TCA_PEDIT_HDR_TYPE_MAX || k->cmd > TCA_PEDIT_CMD_MAX) { |
71d0ed707 net/act_pedit: Su... |
85 86 87 88 89 90 |
err = -EINVAL; goto err_out; } k++; } |
c4f65b09b net/act_pedit: fi... |
91 92 |
if (n) { err = -EINVAL; |
71d0ed707 net/act_pedit: Su... |
93 |
goto err_out; |
c4f65b09b net/act_pedit: fi... |
94 |
} |
71d0ed707 net/act_pedit: Su... |
95 96 97 98 99 100 101 102 103 104 105 106 |
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) { struct nlattr *keys_start = nla_nest_start(skb, TCA_PEDIT_KEYS_EX); |
417b068a6 net/sched: act_pe... |
107 108 |
if (!keys_start) goto nla_failure; |
71d0ed707 net/act_pedit: Su... |
109 110 111 112 |
for (; n > 0; n--) { struct nlattr *key_start; key_start = nla_nest_start(skb, TCA_PEDIT_KEY_EX); |
417b068a6 net/sched: act_pe... |
113 114 |
if (!key_start) goto nla_failure; |
71d0ed707 net/act_pedit: Su... |
115 |
|
853a14ba4 net/act_pedit: In... |
116 |
if (nla_put_u16(skb, TCA_PEDIT_KEY_EX_HTYPE, keys_ex->htype) || |
417b068a6 net/sched: act_pe... |
117 118 |
nla_put_u16(skb, TCA_PEDIT_KEY_EX_CMD, keys_ex->cmd)) goto nla_failure; |
71d0ed707 net/act_pedit: Su... |
119 120 121 122 123 124 125 126 127 |
nla_nest_end(skb, key_start); keys_ex++; } nla_nest_end(skb, keys_start); return 0; |
417b068a6 net/sched: act_pe... |
128 129 130 |
nla_failure: nla_nest_cancel(skb, keys_start); return -EINVAL; |
71d0ed707 net/act_pedit: Su... |
131 |
} |
c1b52739e pkt_sched: namesp... |
132 |
static int tcf_pedit_init(struct net *net, struct nlattr *nla, |
a85a970af net_sched: move t... |
133 |
struct nlattr *est, struct tc_action **a, |
c1b52739e pkt_sched: namesp... |
134 |
int ovr, int bind) |
1da177e4c Linux-2.6.12-rc2 |
135 |
{ |
ddf97ccdd net_sched: add ne... |
136 |
struct tc_action_net *tn = net_generic(net, pedit_net_id); |
7ba699c60 [NET_SCHED]: Conv... |
137 |
struct nlattr *tb[TCA_PEDIT_MAX + 1]; |
71d0ed707 net/act_pedit: Su... |
138 |
struct nlattr *pattr; |
1da177e4c Linux-2.6.12-rc2 |
139 |
struct tc_pedit *parm; |
cee63723b [NET_SCHED]: Prop... |
140 |
int ret = 0, err; |
1da177e4c Linux-2.6.12-rc2 |
141 142 |
struct tcf_pedit *p; struct tc_pedit_key *keys = NULL; |
71d0ed707 net/act_pedit: Su... |
143 |
struct tcf_pedit_key_ex *keys_ex; |
1da177e4c Linux-2.6.12-rc2 |
144 |
int ksize; |
cee63723b [NET_SCHED]: Prop... |
145 |
if (nla == NULL) |
1da177e4c Linux-2.6.12-rc2 |
146 |
return -EINVAL; |
fceb6435e netlink: pass ext... |
147 |
err = nla_parse_nested(tb, TCA_PEDIT_MAX, nla, pedit_policy, NULL); |
cee63723b [NET_SCHED]: Prop... |
148 149 |
if (err < 0) return err; |
71d0ed707 net/act_pedit: Su... |
150 151 152 153 |
pattr = tb[TCA_PEDIT_PARMS]; if (!pattr) pattr = tb[TCA_PEDIT_PARMS_EX]; if (!pattr) |
1da177e4c Linux-2.6.12-rc2 |
154 |
return -EINVAL; |
71d0ed707 net/act_pedit: Su... |
155 156 |
parm = nla_data(pattr); |
1da177e4c Linux-2.6.12-rc2 |
157 |
ksize = parm->nkeys * sizeof(struct tc_pedit_key); |
71d0ed707 net/act_pedit: Su... |
158 |
if (nla_len(pattr) < sizeof(*parm) + ksize) |
1da177e4c Linux-2.6.12-rc2 |
159 |
return -EINVAL; |
71d0ed707 net/act_pedit: Su... |
160 161 162 |
keys_ex = tcf_pedit_keys_ex_parse(tb[TCA_PEDIT_KEYS_EX], parm->nkeys); if (IS_ERR(keys_ex)) return PTR_ERR(keys_ex); |
65a206c01 net/sched: Change... |
163 |
if (!tcf_idr_check(tn, parm->index, a, bind)) { |
1da177e4c Linux-2.6.12-rc2 |
164 165 |
if (!parm->nkeys) return -EINVAL; |
65a206c01 net/sched: Change... |
166 167 |
ret = tcf_idr_create(tn, parm->index, est, a, &act_pedit_ops, bind, false); |
86062033f net_sched: act: h... |
168 169 |
if (ret) return ret; |
a85a970af net_sched: move t... |
170 |
p = to_pedit(*a); |
1da177e4c Linux-2.6.12-rc2 |
171 172 |
keys = kmalloc(ksize, GFP_KERNEL); if (keys == NULL) { |
01a808396 net/sched: fix id... |
173 |
tcf_idr_release(*a, bind); |
71d0ed707 net/act_pedit: Su... |
174 |
kfree(keys_ex); |
1da177e4c Linux-2.6.12-rc2 |
175 176 177 178 |
return -ENOMEM; } ret = ACT_P_CREATED; } else { |
1a29321ed net_sched: act: D... |
179 180 |
if (bind) return 0; |
65a206c01 net/sched: Change... |
181 |
tcf_idr_release(*a, bind); |
1a29321ed net_sched: act: D... |
182 |
if (!ovr) |
1da177e4c Linux-2.6.12-rc2 |
183 |
return -EEXIST; |
a85a970af net_sched: move t... |
184 |
p = to_pedit(*a); |
e9ce1cd3c [PKT_SCHED]: Kill... |
185 |
if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) { |
1da177e4c Linux-2.6.12-rc2 |
186 |
keys = kmalloc(ksize, GFP_KERNEL); |
71d0ed707 net/act_pedit: Su... |
187 188 |
if (!keys) { kfree(keys_ex); |
1da177e4c Linux-2.6.12-rc2 |
189 |
return -ENOMEM; |
71d0ed707 net/act_pedit: Su... |
190 |
} |
1da177e4c Linux-2.6.12-rc2 |
191 192 |
} } |
e9ce1cd3c [PKT_SCHED]: Kill... |
193 194 195 |
spin_lock_bh(&p->tcf_lock); p->tcfp_flags = parm->flags; p->tcf_action = parm->action; |
1da177e4c Linux-2.6.12-rc2 |
196 |
if (keys) { |
e9ce1cd3c [PKT_SCHED]: Kill... |
197 198 199 |
kfree(p->tcfp_keys); p->tcfp_keys = keys; p->tcfp_nkeys = parm->nkeys; |
1da177e4c Linux-2.6.12-rc2 |
200 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
201 |
memcpy(p->tcfp_keys, parm->keys, ksize); |
71d0ed707 net/act_pedit: Su... |
202 203 204 |
kfree(p->tcfp_keys_ex); p->tcfp_keys_ex = keys_ex; |
e9ce1cd3c [PKT_SCHED]: Kill... |
205 |
spin_unlock_bh(&p->tcf_lock); |
1da177e4c Linux-2.6.12-rc2 |
206 |
if (ret == ACT_P_CREATED) |
65a206c01 net/sched: Change... |
207 |
tcf_idr_insert(tn, *a); |
1da177e4c Linux-2.6.12-rc2 |
208 209 |
return ret; } |
a5b5c958f net_sched: act: r... |
210 |
static void tcf_pedit_cleanup(struct tc_action *a, int bind) |
1da177e4c Linux-2.6.12-rc2 |
211 |
{ |
a85a970af net_sched: move t... |
212 |
struct tcf_pedit *p = to_pedit(a); |
a5b5c958f net_sched: act: r... |
213 214 |
struct tc_pedit_key *keys = p->tcfp_keys; kfree(keys); |
71d0ed707 net/act_pedit: Su... |
215 |
kfree(p->tcfp_keys_ex); |
1da177e4c Linux-2.6.12-rc2 |
216 |
} |
95c2027bf net/sched: pedit:... |
217 218 219 220 221 222 223 224 225 226 |
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... |
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
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; }; return ret; } |
dc7f9f6e8 net: sched: const... |
259 |
static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, |
e9ce1cd3c [PKT_SCHED]: Kill... |
260 |
struct tcf_result *res) |
1da177e4c Linux-2.6.12-rc2 |
261 |
{ |
a85a970af net_sched: move t... |
262 |
struct tcf_pedit *p = to_pedit(a); |
4749c3ef8 net: sched: remov... |
263 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
264 |
|
14bbd6a56 net: Add skb_uncl... |
265 |
if (skb_unclone(skb, GFP_ATOMIC)) |
cc7ec456f net_sched: cleanups |
266 |
return p->tcf_action; |
1da177e4c Linux-2.6.12-rc2 |
267 |
|
e9ce1cd3c [PKT_SCHED]: Kill... |
268 |
spin_lock(&p->tcf_lock); |
1da177e4c Linux-2.6.12-rc2 |
269 |
|
9c4a4e488 net sched: action... |
270 |
tcf_lastuse_update(&p->tcf_tm); |
1da177e4c Linux-2.6.12-rc2 |
271 |
|
e9ce1cd3c [PKT_SCHED]: Kill... |
272 273 |
if (p->tcfp_nkeys > 0) { struct tc_pedit_key *tkey = p->tcfp_keys; |
71d0ed707 net/act_pedit: Su... |
274 275 |
struct tcf_pedit_key_ex *tkey_ex = p->tcfp_keys_ex; enum pedit_header_type htype = TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; |
853a14ba4 net/act_pedit: In... |
276 |
enum pedit_cmd cmd = TCA_PEDIT_KEY_EX_CMD_SET; |
1da177e4c Linux-2.6.12-rc2 |
277 |
|
e9ce1cd3c [PKT_SCHED]: Kill... |
278 |
for (i = p->tcfp_nkeys; i > 0; i--, tkey++) { |
db2c24175 act_pedit: access... |
279 |
u32 *ptr, _data; |
1da177e4c Linux-2.6.12-rc2 |
280 |
int offset = tkey->off; |
71d0ed707 net/act_pedit: Su... |
281 |
int hoffset; |
853a14ba4 net/act_pedit: In... |
282 |
u32 val; |
71d0ed707 net/act_pedit: Su... |
283 284 285 286 |
int rc; if (tkey_ex) { htype = tkey_ex->htype; |
853a14ba4 net/act_pedit: In... |
287 |
cmd = tkey_ex->cmd; |
71d0ed707 net/act_pedit: Su... |
288 289 290 291 292 293 294 295 296 297 |
tkey_ex++; } rc = pedit_skb_hdr_offset(skb, htype, &hoffset); if (rc) { pr_info("tc filter pedit bad header type specified (0x%x) ", htype); goto bad; } |
1da177e4c Linux-2.6.12-rc2 |
298 299 |
if (tkey->offmask) { |
db2c24175 act_pedit: access... |
300 |
char *d, _d; |
71d0ed707 net/act_pedit: Su... |
301 |
if (!offset_valid(skb, hoffset + tkey->at)) { |
95c2027bf net/sched: pedit:... |
302 303 |
pr_info("tc filter pedit 'at' offset %d out of bounds ", |
71d0ed707 net/act_pedit: Su... |
304 |
hoffset + tkey->at); |
95c2027bf net/sched: pedit:... |
305 306 |
goto bad; } |
71d0ed707 net/act_pedit: Su... |
307 |
d = skb_header_pointer(skb, hoffset + tkey->at, 1, |
db2c24175 act_pedit: access... |
308 309 |
&_d); if (!d) |
1da177e4c Linux-2.6.12-rc2 |
310 |
goto bad; |
db2c24175 act_pedit: access... |
311 |
offset += (*d & tkey->offmask) >> tkey->shift; |
1da177e4c Linux-2.6.12-rc2 |
312 313 314 |
} if (offset % 4) { |
6ff9c3644 net sched: printk... |
315 316 317 |
pr_info("tc filter pedit" " offset must be on 32 bit boundaries "); |
1da177e4c Linux-2.6.12-rc2 |
318 319 |
goto bad; } |
95c2027bf net/sched: pedit:... |
320 |
|
71d0ed707 net/act_pedit: Su... |
321 |
if (!offset_valid(skb, hoffset + offset)) { |
95c2027bf net/sched: pedit:... |
322 323 |
pr_info("tc filter pedit offset %d out of bounds ", |
71d0ed707 net/act_pedit: Su... |
324 |
hoffset + offset); |
1da177e4c Linux-2.6.12-rc2 |
325 326 |
goto bad; } |
71d0ed707 net/act_pedit: Su... |
327 |
ptr = skb_header_pointer(skb, hoffset + offset, 4, &_data); |
db2c24175 act_pedit: access... |
328 329 |
if (!ptr) goto bad; |
1da177e4c Linux-2.6.12-rc2 |
330 |
/* just do it, baby */ |
853a14ba4 net/act_pedit: In... |
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
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: pr_info("tc filter pedit bad command (%d) ", cmd); goto bad; } *ptr = ((*ptr & tkey->mask) ^ val); |
db2c24175 act_pedit: access... |
346 |
if (ptr == &_data) |
71d0ed707 net/act_pedit: Su... |
347 |
skb_store_bits(skb, hoffset + offset, ptr, 4); |
1da177e4c Linux-2.6.12-rc2 |
348 |
} |
10297b993 [NET] SCHED: Fix ... |
349 |
|
1da177e4c Linux-2.6.12-rc2 |
350 |
goto done; |
6ff9c3644 net sched: printk... |
351 352 353 |
} else WARN(1, "pedit BUG: index %d ", p->tcf_index); |
1da177e4c Linux-2.6.12-rc2 |
354 355 |
bad: |
e9ce1cd3c [PKT_SCHED]: Kill... |
356 |
p->tcf_qstats.overlimits++; |
1da177e4c Linux-2.6.12-rc2 |
357 |
done: |
bfe0d0298 net_sched: factor... |
358 |
bstats_update(&p->tcf_bstats, skb); |
e9ce1cd3c [PKT_SCHED]: Kill... |
359 360 |
spin_unlock(&p->tcf_lock); return p->tcf_action; |
1da177e4c Linux-2.6.12-rc2 |
361 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
362 363 |
static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) |
1da177e4c Linux-2.6.12-rc2 |
364 |
{ |
27a884dc3 [SK_BUFF]: Conver... |
365 |
unsigned char *b = skb_tail_pointer(skb); |
a85a970af net_sched: move t... |
366 |
struct tcf_pedit *p = to_pedit(a); |
1da177e4c Linux-2.6.12-rc2 |
367 |
struct tc_pedit *opt; |
1da177e4c Linux-2.6.12-rc2 |
368 |
struct tcf_t t; |
10297b993 [NET] SCHED: Fix ... |
369 |
int s; |
e9ce1cd3c [PKT_SCHED]: Kill... |
370 |
s = sizeof(*opt) + p->tcfp_nkeys * sizeof(struct tc_pedit_key); |
1da177e4c Linux-2.6.12-rc2 |
371 372 |
/* netlink spinlocks held above us - must use ATOMIC */ |
0da974f4f [NET]: Conversion... |
373 |
opt = kzalloc(s, GFP_ATOMIC); |
e9ce1cd3c [PKT_SCHED]: Kill... |
374 |
if (unlikely(!opt)) |
1da177e4c Linux-2.6.12-rc2 |
375 |
return -ENOBUFS; |
1da177e4c Linux-2.6.12-rc2 |
376 |
|
e9ce1cd3c [PKT_SCHED]: Kill... |
377 378 379 380 381 382 383 384 |
memcpy(opt->keys, p->tcfp_keys, p->tcfp_nkeys * sizeof(struct tc_pedit_key)); opt->index = p->tcf_index; opt->nkeys = p->tcfp_nkeys; opt->flags = p->tcfp_flags; opt->action = p->tcf_action; opt->refcnt = p->tcf_refcnt - ref; opt->bindcnt = p->tcf_bindcnt - bind; |
1da177e4c Linux-2.6.12-rc2 |
385 |
|
71d0ed707 net/act_pedit: Su... |
386 |
if (p->tcfp_keys_ex) { |
417b068a6 net/sched: act_pe... |
387 388 389 390 |
if (tcf_pedit_key_ex_dump(skb, p->tcfp_keys_ex, p->tcfp_nkeys)) goto nla_put_failure; |
71d0ed707 net/act_pedit: Su... |
391 392 393 394 395 396 397 |
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... |
398 399 |
tcf_tm_dump(&t, &p->tcf_tm); |
9854518ea sched: align nlat... |
400 |
if (nla_put_64bit(skb, TCA_PEDIT_TM, sizeof(t), &t, TCA_PEDIT_PAD)) |
1b34ec43c pkt_sched: Stop u... |
401 |
goto nla_put_failure; |
48d8ee169 net sched actions... |
402 |
|
541673c85 [PKT_SCHED]: Fix ... |
403 |
kfree(opt); |
1da177e4c Linux-2.6.12-rc2 |
404 |
return skb->len; |
7ba699c60 [NET_SCHED]: Conv... |
405 |
nla_put_failure: |
dc5fc579b [NETLINK]: Use nl... |
406 |
nlmsg_trim(skb, b); |
541673c85 [PKT_SCHED]: Fix ... |
407 |
kfree(opt); |
1da177e4c Linux-2.6.12-rc2 |
408 409 |
return -1; } |
ddf97ccdd net_sched: add ne... |
410 411 |
static int tcf_pedit_walker(struct net *net, struct sk_buff *skb, struct netlink_callback *cb, int type, |
a85a970af net_sched: move t... |
412 |
const struct tc_action_ops *ops) |
ddf97ccdd net_sched: add ne... |
413 414 |
{ struct tc_action_net *tn = net_generic(net, pedit_net_id); |
a85a970af net_sched: move t... |
415 |
return tcf_generic_walker(tn, skb, cb, type, ops); |
ddf97ccdd net_sched: add ne... |
416 |
} |
a85a970af net_sched: move t... |
417 |
static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index) |
ddf97ccdd net_sched: add ne... |
418 419 |
{ struct tc_action_net *tn = net_generic(net, pedit_net_id); |
65a206c01 net/sched: Change... |
420 |
return tcf_idr_search(tn, a, index); |
ddf97ccdd net_sched: add ne... |
421 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
422 |
static struct tc_action_ops act_pedit_ops = { |
1da177e4c Linux-2.6.12-rc2 |
423 424 |
.kind = "pedit", .type = TCA_ACT_PEDIT, |
1da177e4c Linux-2.6.12-rc2 |
425 426 427 428 |
.owner = THIS_MODULE, .act = tcf_pedit, .dump = tcf_pedit_dump, .cleanup = tcf_pedit_cleanup, |
1da177e4c Linux-2.6.12-rc2 |
429 |
.init = tcf_pedit_init, |
ddf97ccdd net_sched: add ne... |
430 431 |
.walk = tcf_pedit_walker, .lookup = tcf_pedit_search, |
a85a970af net_sched: move t... |
432 |
.size = sizeof(struct tcf_pedit), |
ddf97ccdd net_sched: add ne... |
433 434 435 436 437 |
}; static __net_init int pedit_init_net(struct net *net) { struct tc_action_net *tn = net_generic(net, pedit_net_id); |
c7e460ce5 Revert "net_sched... |
438 |
return tc_action_net_init(tn, &act_pedit_ops); |
ddf97ccdd net_sched: add ne... |
439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
} static void __net_exit pedit_exit_net(struct net *net) { struct tc_action_net *tn = net_generic(net, pedit_net_id); tc_action_net_exit(tn); } static struct pernet_operations pedit_net_ops = { .init = pedit_init_net, .exit = pedit_exit_net, .id = &pedit_net_id, .size = sizeof(struct tc_action_net), |
1da177e4c Linux-2.6.12-rc2 |
453 454 455 456 457 |
}; MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); MODULE_DESCRIPTION("Generic Packet Editor actions"); MODULE_LICENSE("GPL"); |
e9ce1cd3c [PKT_SCHED]: Kill... |
458 |
static int __init pedit_init_module(void) |
1da177e4c Linux-2.6.12-rc2 |
459 |
{ |
ddf97ccdd net_sched: add ne... |
460 |
return tcf_register_action(&act_pedit_ops, &pedit_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
461 |
} |
e9ce1cd3c [PKT_SCHED]: Kill... |
462 |
static void __exit pedit_cleanup_module(void) |
1da177e4c Linux-2.6.12-rc2 |
463 |
{ |
ddf97ccdd net_sched: add ne... |
464 |
tcf_unregister_action(&act_pedit_ops, &pedit_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
465 466 467 468 |
} module_init(pedit_init_module); module_exit(pedit_cleanup_module); |