Blame view
net/sched/cls_fw.c
9.71 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 |
/* * net/sched/cls_fw.c Classifier mapping ipchains' fwmark to traffic class. * |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 9 10 |
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> * * Changes: * Karlis Peisenieks <karlis@mt.lv> : 990415 : fw_walk off by one * Karlis Peisenieks <karlis@mt.lv> : 990415 : fw_delete killed all the filter (and kernel). * Alex <alex@pilotsoft.com> : 2004xxyy: Added Action extension |
1da177e4c Linux-2.6.12-rc2 |
11 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
12 |
#include <linux/module.h> |
5a0e3ad6a include cleanup: ... |
13 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 |
#include <linux/types.h> #include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
16 |
#include <linux/string.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
#include <linux/errno.h> |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include <linux/skbuff.h> |
0ba480538 [NET_SCHED]: Remo... |
19 |
#include <net/netlink.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 |
#include <net/act_api.h> #include <net/pkt_cls.h> |
1abf27202 net: sched: tcind... |
22 |
#include <net/sch_generic.h> |
1da177e4c Linux-2.6.12-rc2 |
23 |
|
d37d8ac17 net: sched: use n... |
24 |
#define HTSIZE 256 |
c5c13fafd [PKT_SCHED]: impr... |
25 |
|
cc7ec456f net_sched: cleanups |
26 |
struct fw_head { |
d37d8ac17 net: sched: use n... |
27 |
u32 mask; |
e35a8ee59 net: sched: fw us... |
28 29 |
struct fw_filter __rcu *ht[HTSIZE]; struct rcu_head rcu; |
1da177e4c Linux-2.6.12-rc2 |
30 |
}; |
cc7ec456f net_sched: cleanups |
31 |
struct fw_filter { |
e35a8ee59 net: sched: fw us... |
32 |
struct fw_filter __rcu *next; |
1da177e4c Linux-2.6.12-rc2 |
33 34 |
u32 id; struct tcf_result res; |
2519a602c net_sched: optimi... |
35 |
int ifindex; |
1da177e4c Linux-2.6.12-rc2 |
36 |
struct tcf_exts exts; |
e35a8ee59 net: sched: fw us... |
37 |
struct tcf_proto *tp; |
aaa908ffb net_sched: switch... |
38 |
struct rcu_work rwork; |
1da177e4c Linux-2.6.12-rc2 |
39 |
}; |
d37d8ac17 net: sched: use n... |
40 |
static u32 fw_hash(u32 handle) |
1da177e4c Linux-2.6.12-rc2 |
41 |
{ |
d37d8ac17 net: sched: use n... |
42 43 44 |
handle ^= (handle >> 16); handle ^= (handle >> 8); return handle % HTSIZE; |
1da177e4c Linux-2.6.12-rc2 |
45 |
} |
dc7f9f6e8 net: sched: const... |
46 |
static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, |
5a7a5555a net sched: stylis... |
47 |
struct tcf_result *res) |
1da177e4c Linux-2.6.12-rc2 |
48 |
{ |
e35a8ee59 net: sched: fw us... |
49 |
struct fw_head *head = rcu_dereference_bh(tp->root); |
1da177e4c Linux-2.6.12-rc2 |
50 51 |
struct fw_filter *f; int r; |
5c804bfdc [NET_SCHED]: cls_... |
52 |
u32 id = skb->mark; |
1da177e4c Linux-2.6.12-rc2 |
53 54 |
if (head != NULL) { |
5c804bfdc [NET_SCHED]: cls_... |
55 |
id &= head->mask; |
e35a8ee59 net: sched: fw us... |
56 57 58 |
for (f = rcu_dereference_bh(head->ht[fw_hash(id)]); f; f = rcu_dereference_bh(f->next)) { |
1da177e4c Linux-2.6.12-rc2 |
59 60 |
if (f->id == id) { *res = f->res; |
2519a602c net_sched: optimi... |
61 |
if (!tcf_match_indev(skb, f->ifindex)) |
1da177e4c Linux-2.6.12-rc2 |
62 |
continue; |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 66 67 68 69 70 |
r = tcf_exts_exec(skb, &f->exts, res); if (r < 0) continue; return r; } } } else { |
1abf27202 net: sched: tcind... |
71 |
struct Qdisc *q = tcf_block_q(tp->chain->block); |
d8aecb101 net: revert "net_... |
72 |
/* Old method: classify the packet using its skb mark. */ |
cc7ec456f net_sched: cleanups |
73 |
if (id && (TC_H_MAJ(id) == 0 || |
1abf27202 net: sched: tcind... |
74 |
!(TC_H_MAJ(id ^ q->handle)))) { |
1da177e4c Linux-2.6.12-rc2 |
75 76 77 78 79 80 81 82 |
res->classid = id; res->class = 0; return 0; } } return -1; } |
8113c0956 net_sched: use vo... |
83 |
static void *fw_get(struct tcf_proto *tp, u32 handle) |
1da177e4c Linux-2.6.12-rc2 |
84 |
{ |
e35a8ee59 net: sched: fw us... |
85 |
struct fw_head *head = rtnl_dereference(tp->root); |
1da177e4c Linux-2.6.12-rc2 |
86 87 88 |
struct fw_filter *f; if (head == NULL) |
8113c0956 net_sched: use vo... |
89 |
return NULL; |
1da177e4c Linux-2.6.12-rc2 |
90 |
|
e35a8ee59 net: sched: fw us... |
91 92 |
f = rtnl_dereference(head->ht[fw_hash(handle)]); for (; f; f = rtnl_dereference(f->next)) { |
1da177e4c Linux-2.6.12-rc2 |
93 |
if (f->id == handle) |
8113c0956 net_sched: use vo... |
94 |
return f; |
1da177e4c Linux-2.6.12-rc2 |
95 |
} |
8113c0956 net_sched: use vo... |
96 |
return NULL; |
1da177e4c Linux-2.6.12-rc2 |
97 |
} |
1da177e4c Linux-2.6.12-rc2 |
98 99 |
static int fw_init(struct tcf_proto *tp) { |
d8aecb101 net: revert "net_... |
100 101 102 |
/* We don't allocate fw_head here, because in the old method * we don't need it at all. */ |
1da177e4c Linux-2.6.12-rc2 |
103 104 |
return 0; } |
d5f984f5a cls_fw: use tcf_e... |
105 106 107 108 109 110 |
static void __fw_delete_filter(struct fw_filter *f) { tcf_exts_destroy(&f->exts); tcf_exts_put_net(&f->exts); kfree(f); } |
e071dff2a net_sched: use tc... |
111 |
static void fw_delete_filter_work(struct work_struct *work) |
1da177e4c Linux-2.6.12-rc2 |
112 |
{ |
aaa908ffb net_sched: switch... |
113 114 115 |
struct fw_filter *f = container_of(to_rcu_work(work), struct fw_filter, rwork); |
e071dff2a net_sched: use tc... |
116 |
rtnl_lock(); |
d5f984f5a cls_fw: use tcf_e... |
117 |
__fw_delete_filter(f); |
e071dff2a net_sched: use tc... |
118 119 |
rtnl_unlock(); } |
12db03b65 net: sched: exten... |
120 121 |
static void fw_destroy(struct tcf_proto *tp, bool rtnl_held, struct netlink_ext_ack *extack) |
1da177e4c Linux-2.6.12-rc2 |
122 |
{ |
e35a8ee59 net: sched: fw us... |
123 |
struct fw_head *head = rtnl_dereference(tp->root); |
1da177e4c Linux-2.6.12-rc2 |
124 125 126 127 |
struct fw_filter *f; int h; if (head == NULL) |
763dbf632 net_sched: move t... |
128 |
return; |
1da177e4c Linux-2.6.12-rc2 |
129 |
|
cc7ec456f net_sched: cleanups |
130 |
for (h = 0; h < HTSIZE; h++) { |
e35a8ee59 net: sched: fw us... |
131 132 133 |
while ((f = rtnl_dereference(head->ht[h])) != NULL) { RCU_INIT_POINTER(head->ht[h], rtnl_dereference(f->next)); |
18cdb37eb net: sched: do no... |
134 |
tcf_unbind_filter(tp, &f->res); |
d5f984f5a cls_fw: use tcf_e... |
135 |
if (tcf_exts_get_net(&f->exts)) |
aaa908ffb net_sched: switch... |
136 |
tcf_queue_work(&f->rwork, fw_delete_filter_work); |
d5f984f5a cls_fw: use tcf_e... |
137 138 |
else __fw_delete_filter(f); |
1da177e4c Linux-2.6.12-rc2 |
139 140 |
} } |
e35a8ee59 net: sched: fw us... |
141 |
kfree_rcu(head, rcu); |
1da177e4c Linux-2.6.12-rc2 |
142 |
} |
571acf210 net: sched: cls: ... |
143 |
static int fw_delete(struct tcf_proto *tp, void *arg, bool *last, |
12db03b65 net: sched: exten... |
144 |
bool rtnl_held, struct netlink_ext_ack *extack) |
1da177e4c Linux-2.6.12-rc2 |
145 |
{ |
e35a8ee59 net: sched: fw us... |
146 |
struct fw_head *head = rtnl_dereference(tp->root); |
8113c0956 net_sched: use vo... |
147 |
struct fw_filter *f = arg; |
e35a8ee59 net: sched: fw us... |
148 149 |
struct fw_filter __rcu **fp; struct fw_filter *pfp; |
763dbf632 net_sched: move t... |
150 151 |
int ret = -EINVAL; int h; |
1da177e4c Linux-2.6.12-rc2 |
152 153 154 |
if (head == NULL || f == NULL) goto out; |
e35a8ee59 net: sched: fw us... |
155 156 157 158 159 160 |
fp = &head->ht[fw_hash(f->id)]; for (pfp = rtnl_dereference(*fp); pfp; fp = &pfp->next, pfp = rtnl_dereference(*fp)) { if (pfp == f) { RCU_INIT_POINTER(*fp, rtnl_dereference(f->next)); |
18cdb37eb net: sched: do no... |
161 |
tcf_unbind_filter(tp, &f->res); |
d5f984f5a cls_fw: use tcf_e... |
162 |
tcf_exts_get_net(&f->exts); |
aaa908ffb net_sched: switch... |
163 |
tcf_queue_work(&f->rwork, fw_delete_filter_work); |
763dbf632 net_sched: move t... |
164 165 |
ret = 0; break; |
1da177e4c Linux-2.6.12-rc2 |
166 167 |
} } |
763dbf632 net_sched: move t... |
168 169 170 171 172 173 174 175 |
*last = true; for (h = 0; h < HTSIZE; h++) { if (rcu_access_pointer(head->ht[h])) { *last = false; break; } } |
1da177e4c Linux-2.6.12-rc2 |
176 |
out: |
763dbf632 net_sched: move t... |
177 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
178 |
} |
6fa8c0144 [NET_SCHED]: Use ... |
179 180 181 182 183 |
static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = { [TCA_FW_CLASSID] = { .type = NLA_U32 }, [TCA_FW_INDEV] = { .type = NLA_STRING, .len = IFNAMSIZ }, [TCA_FW_MASK] = { .type = NLA_U32 }, }; |
1e5003af3 net: sched: cls_f... |
184 185 |
static int fw_set_parms(struct net *net, struct tcf_proto *tp, struct fw_filter *f, struct nlattr **tb, |
50a561900 net: sched: cls: ... |
186 187 |
struct nlattr **tca, unsigned long base, bool ovr, struct netlink_ext_ack *extack) |
1da177e4c Linux-2.6.12-rc2 |
188 |
{ |
e35a8ee59 net: sched: fw us... |
189 |
struct fw_head *head = rtnl_dereference(tp->root); |
b4e9b520c [NET_SCHED]: Add ... |
190 |
u32 mask; |
1da177e4c Linux-2.6.12-rc2 |
191 |
int err; |
50a561900 net: sched: cls: ... |
192 |
err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &f->exts, ovr, |
ec6743a10 net: sched: track... |
193 |
true, extack); |
1da177e4c Linux-2.6.12-rc2 |
194 195 |
if (err < 0) return err; |
add93b610 [NET_SCHED]: Conv... |
196 |
if (tb[TCA_FW_CLASSID]) { |
1587bac49 [NET_SCHED]: Use ... |
197 |
f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); |
1da177e4c Linux-2.6.12-rc2 |
198 199 |
tcf_bind_filter(tp, &f->res, base); } |
add93b610 [NET_SCHED]: Conv... |
200 |
if (tb[TCA_FW_INDEV]) { |
2519a602c net_sched: optimi... |
201 |
int ret; |
1057c55f6 net: sched: cls: ... |
202 |
ret = tcf_change_indev(net, tb[TCA_FW_INDEV], extack); |
94611bff6 net: sched: cls_f... |
203 204 |
if (ret < 0) return ret; |
2519a602c net_sched: optimi... |
205 |
f->ifindex = ret; |
1da177e4c Linux-2.6.12-rc2 |
206 |
} |
1da177e4c Linux-2.6.12-rc2 |
207 |
|
cb95ec626 pkt_sched: fix er... |
208 |
err = -EINVAL; |
add93b610 [NET_SCHED]: Conv... |
209 |
if (tb[TCA_FW_MASK]) { |
1587bac49 [NET_SCHED]: Use ... |
210 |
mask = nla_get_u32(tb[TCA_FW_MASK]); |
b4e9b520c [NET_SCHED]: Add ... |
211 |
if (mask != head->mask) |
94611bff6 net: sched: cls_f... |
212 |
return err; |
b4e9b520c [NET_SCHED]: Add ... |
213 |
} else if (head->mask != 0xFFFFFFFF) |
94611bff6 net: sched: cls_f... |
214 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
215 216 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
217 |
} |
c1b52739e pkt_sched: namesp... |
218 |
static int fw_change(struct net *net, struct sk_buff *in_skb, |
af4c6641f net sched: Pass t... |
219 |
struct tcf_proto *tp, unsigned long base, |
8113c0956 net_sched: use vo... |
220 |
u32 handle, struct nlattr **tca, void **arg, |
12db03b65 net: sched: exten... |
221 222 |
bool ovr, bool rtnl_held, struct netlink_ext_ack *extack) |
1da177e4c Linux-2.6.12-rc2 |
223 |
{ |
e35a8ee59 net: sched: fw us... |
224 |
struct fw_head *head = rtnl_dereference(tp->root); |
8113c0956 net_sched: use vo... |
225 |
struct fw_filter *f = *arg; |
add93b610 [NET_SCHED]: Conv... |
226 227 |
struct nlattr *opt = tca[TCA_OPTIONS]; struct nlattr *tb[TCA_FW_MAX + 1]; |
1da177e4c Linux-2.6.12-rc2 |
228 229 230 |
int err; if (!opt) |
d8aecb101 net: revert "net_... |
231 |
return handle ? -EINVAL : 0; /* Succeed if it is old method. */ |
1da177e4c Linux-2.6.12-rc2 |
232 |
|
8cb081746 netlink: make val... |
233 234 |
err = nla_parse_nested_deprecated(tb, TCA_FW_MAX, opt, fw_policy, NULL); |
cee63723b [NET_SCHED]: Prop... |
235 236 |
if (err < 0) return err; |
1da177e4c Linux-2.6.12-rc2 |
237 |
|
e35a8ee59 net: sched: fw us... |
238 239 240 |
if (f) { struct fw_filter *pfp, *fnew; struct fw_filter __rcu **fp; |
1da177e4c Linux-2.6.12-rc2 |
241 242 |
if (f->id != handle && handle) return -EINVAL; |
e35a8ee59 net: sched: fw us... |
243 244 245 246 247 248 249 |
fnew = kzalloc(sizeof(struct fw_filter), GFP_KERNEL); if (!fnew) return -ENOBUFS; fnew->id = f->id; fnew->res = f->res; |
e35a8ee59 net: sched: fw us... |
250 |
fnew->ifindex = f->ifindex; |
e35a8ee59 net: sched: fw us... |
251 |
fnew->tp = f->tp; |
14215108a net_sched: initia... |
252 253 |
err = tcf_exts_init(&fnew->exts, net, TCA_FW_ACT, TCA_FW_POLICE); |
b9a24bb76 net_sched: proper... |
254 255 256 257 |
if (err < 0) { kfree(fnew); return err; } |
e1f93eb06 net: sched: cls_f... |
258 |
|
50a561900 net: sched: cls: ... |
259 |
err = fw_set_parms(net, tp, fnew, tb, tca, base, ovr, extack); |
e35a8ee59 net: sched: fw us... |
260 |
if (err < 0) { |
b9a24bb76 net_sched: proper... |
261 |
tcf_exts_destroy(&fnew->exts); |
e35a8ee59 net: sched: fw us... |
262 263 264 265 266 267 268 269 270 271 272 273 |
kfree(fnew); return err; } fp = &head->ht[fw_hash(fnew->id)]; for (pfp = rtnl_dereference(*fp); pfp; fp = &pfp->next, pfp = rtnl_dereference(*fp)) if (pfp == f) break; RCU_INIT_POINTER(fnew->next, rtnl_dereference(pfp->next)); rcu_assign_pointer(*fp, fnew); |
18cdb37eb net: sched: do no... |
274 |
tcf_unbind_filter(tp, &f->res); |
d5f984f5a cls_fw: use tcf_e... |
275 |
tcf_exts_get_net(&f->exts); |
aaa908ffb net_sched: switch... |
276 |
tcf_queue_work(&f->rwork, fw_delete_filter_work); |
e35a8ee59 net: sched: fw us... |
277 |
|
8113c0956 net_sched: use vo... |
278 |
*arg = fnew; |
e35a8ee59 net: sched: fw us... |
279 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
280 281 282 283 |
} if (!handle) return -EINVAL; |
d8aecb101 net: revert "net_... |
284 285 |
if (!head) { u32 mask = 0xFFFFFFFF; |
6fa8c0144 [NET_SCHED]: Use ... |
286 |
if (tb[TCA_FW_MASK]) |
d8aecb101 net: revert "net_... |
287 288 289 290 291 292 293 294 |
mask = nla_get_u32(tb[TCA_FW_MASK]); head = kzalloc(sizeof(*head), GFP_KERNEL); if (!head) return -ENOBUFS; head->mask = mask; rcu_assign_pointer(tp->root, head); |
1da177e4c Linux-2.6.12-rc2 |
295 |
} |
0da974f4f [NET]: Conversion... |
296 |
f = kzalloc(sizeof(struct fw_filter), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
297 298 |
if (f == NULL) return -ENOBUFS; |
1da177e4c Linux-2.6.12-rc2 |
299 |
|
14215108a net_sched: initia... |
300 |
err = tcf_exts_init(&f->exts, net, TCA_FW_ACT, TCA_FW_POLICE); |
b9a24bb76 net_sched: proper... |
301 302 |
if (err < 0) goto errout; |
1da177e4c Linux-2.6.12-rc2 |
303 |
f->id = handle; |
e35a8ee59 net: sched: fw us... |
304 |
f->tp = tp; |
1da177e4c Linux-2.6.12-rc2 |
305 |
|
50a561900 net: sched: cls: ... |
306 |
err = fw_set_parms(net, tp, f, tb, tca, base, ovr, extack); |
1da177e4c Linux-2.6.12-rc2 |
307 308 |
if (err < 0) goto errout; |
e35a8ee59 net: sched: fw us... |
309 310 |
RCU_INIT_POINTER(f->next, head->ht[fw_hash(handle)]); rcu_assign_pointer(head->ht[fw_hash(handle)], f); |
1da177e4c Linux-2.6.12-rc2 |
311 |
|
8113c0956 net_sched: use vo... |
312 |
*arg = f; |
1da177e4c Linux-2.6.12-rc2 |
313 314 315 |
return 0; errout: |
b9a24bb76 net_sched: proper... |
316 |
tcf_exts_destroy(&f->exts); |
a51482bde [NET]: kfree cleanup |
317 |
kfree(f); |
1da177e4c Linux-2.6.12-rc2 |
318 319 |
return err; } |
12db03b65 net: sched: exten... |
320 321 |
static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg, bool rtnl_held) |
1da177e4c Linux-2.6.12-rc2 |
322 |
{ |
e35a8ee59 net: sched: fw us... |
323 |
struct fw_head *head = rtnl_dereference(tp->root); |
1da177e4c Linux-2.6.12-rc2 |
324 |
int h; |
1d9978757 Revert "net: sche... |
325 326 327 328 |
if (head == NULL) arg->stop = 1; if (arg->stop) |
1da177e4c Linux-2.6.12-rc2 |
329 |
return; |
c5c13fafd [PKT_SCHED]: impr... |
330 |
for (h = 0; h < HTSIZE; h++) { |
1da177e4c Linux-2.6.12-rc2 |
331 |
struct fw_filter *f; |
e35a8ee59 net: sched: fw us... |
332 333 |
for (f = rtnl_dereference(head->ht[h]); f; f = rtnl_dereference(f->next)) { |
1da177e4c Linux-2.6.12-rc2 |
334 335 336 337 |
if (arg->count < arg->skip) { arg->count++; continue; } |
8113c0956 net_sched: use vo... |
338 |
if (arg->fn(tp, f, arg) < 0) { |
1da177e4c Linux-2.6.12-rc2 |
339 340 341 342 343 344 345 |
arg->stop = 1; return; } arg->count++; } } } |
8113c0956 net_sched: use vo... |
346 |
static int fw_dump(struct net *net, struct tcf_proto *tp, void *fh, |
12db03b65 net: sched: exten... |
347 |
struct sk_buff *skb, struct tcmsg *t, bool rtnl_held) |
1da177e4c Linux-2.6.12-rc2 |
348 |
{ |
e35a8ee59 net: sched: fw us... |
349 |
struct fw_head *head = rtnl_dereference(tp->root); |
8113c0956 net_sched: use vo... |
350 |
struct fw_filter *f = fh; |
4b3550ef5 [NET_SCHED]: Use ... |
351 |
struct nlattr *nest; |
1da177e4c Linux-2.6.12-rc2 |
352 353 354 355 356 |
if (f == NULL) return skb->len; t->tcm_handle = f->id; |
6fc6d06e5 net: sched: remov... |
357 |
if (!f->res.classid && !tcf_exts_has_actions(&f->exts)) |
1da177e4c Linux-2.6.12-rc2 |
358 |
return skb->len; |
ae0be8de9 netlink: make nla... |
359 |
nest = nla_nest_start_noflag(skb, TCA_OPTIONS); |
4b3550ef5 [NET_SCHED]: Use ... |
360 361 |
if (nest == NULL) goto nla_put_failure; |
1da177e4c Linux-2.6.12-rc2 |
362 |
|
1b34ec43c pkt_sched: Stop u... |
363 364 365 |
if (f->res.classid && nla_put_u32(skb, TCA_FW_CLASSID, f->res.classid)) goto nla_put_failure; |
2519a602c net_sched: optimi... |
366 367 368 369 370 371 |
if (f->ifindex) { struct net_device *dev; dev = __dev_get_by_index(net, f->ifindex); if (dev && nla_put_string(skb, TCA_FW_INDEV, dev->name)) goto nla_put_failure; } |
1b34ec43c pkt_sched: Stop u... |
372 373 374 |
if (head->mask != 0xFFFFFFFF && nla_put_u32(skb, TCA_FW_MASK, head->mask)) goto nla_put_failure; |
1da177e4c Linux-2.6.12-rc2 |
375 |
|
5da57f422 net_sched: cls: r... |
376 |
if (tcf_exts_dump(skb, &f->exts) < 0) |
add93b610 [NET_SCHED]: Conv... |
377 |
goto nla_put_failure; |
1da177e4c Linux-2.6.12-rc2 |
378 |
|
4b3550ef5 [NET_SCHED]: Use ... |
379 |
nla_nest_end(skb, nest); |
1da177e4c Linux-2.6.12-rc2 |
380 |
|
5da57f422 net_sched: cls: r... |
381 |
if (tcf_exts_dump_stats(skb, &f->exts) < 0) |
add93b610 [NET_SCHED]: Conv... |
382 |
goto nla_put_failure; |
1da177e4c Linux-2.6.12-rc2 |
383 384 |
return skb->len; |
add93b610 [NET_SCHED]: Conv... |
385 |
nla_put_failure: |
6ea3b446b net: sched: cls: ... |
386 |
nla_nest_cancel(skb, nest); |
1da177e4c Linux-2.6.12-rc2 |
387 388 |
return -1; } |
2e24cd755 net_sched: fix op... |
389 390 |
static void fw_bind_class(void *fh, u32 classid, unsigned long cl, void *q, unsigned long base) |
07d79fc7d net_sched: add re... |
391 392 |
{ struct fw_filter *f = fh; |
2e24cd755 net_sched: fix op... |
393 394 395 396 397 398 |
if (f && f->res.classid == classid) { if (cl) __tcf_bind_filter(q, &f->res, base); else __tcf_unbind_filter(q, &f->res); } |
07d79fc7d net_sched: add re... |
399 |
} |
2eb9d75c7 [NET_SCHED]: mark... |
400 |
static struct tcf_proto_ops cls_fw_ops __read_mostly = { |
1da177e4c Linux-2.6.12-rc2 |
401 402 403 404 405 |
.kind = "fw", .classify = fw_classify, .init = fw_init, .destroy = fw_destroy, .get = fw_get, |
1da177e4c Linux-2.6.12-rc2 |
406 407 408 409 |
.change = fw_change, .delete = fw_delete, .walk = fw_walk, .dump = fw_dump, |
07d79fc7d net_sched: add re... |
410 |
.bind_class = fw_bind_class, |
1da177e4c Linux-2.6.12-rc2 |
411 412 413 414 415 416 417 |
.owner = THIS_MODULE, }; static int __init init_fw(void) { return register_tcf_proto_ops(&cls_fw_ops); } |
10297b993 [NET] SCHED: Fix ... |
418 |
static void __exit exit_fw(void) |
1da177e4c Linux-2.6.12-rc2 |
419 420 421 422 423 424 425 |
{ unregister_tcf_proto_ops(&cls_fw_ops); } module_init(init_fw) module_exit(exit_fw) MODULE_LICENSE("GPL"); |