16
16
#include <net/sch_generic.h>
17
17
#include <net/pkt_cls.h>
18
18
19
- struct cls_mall_filter {
19
+ struct cls_mall_head {
20
20
struct tcf_exts exts ;
21
21
struct tcf_result res ;
22
22
u32 handle ;
23
- struct rcu_head rcu ;
24
23
u32 flags ;
25
- };
26
-
27
- struct cls_mall_head {
28
- struct cls_mall_filter * filter ;
29
24
struct rcu_head rcu ;
30
25
};
31
26
32
27
static int mall_classify (struct sk_buff * skb , const struct tcf_proto * tp ,
33
28
struct tcf_result * res )
34
29
{
35
30
struct cls_mall_head * head = rcu_dereference_bh (tp -> root );
36
- struct cls_mall_filter * f = head -> filter ;
37
31
38
- if (tc_skip_sw (f -> flags ))
32
+ if (tc_skip_sw (head -> flags ))
39
33
return -1 ;
40
34
41
- return tcf_exts_exec (skb , & f -> exts , res );
35
+ return tcf_exts_exec (skb , & head -> exts , res );
42
36
}
43
37
44
38
static int mall_init (struct tcf_proto * tp )
45
39
{
46
- struct cls_mall_head * head ;
47
-
48
- head = kzalloc (sizeof (* head ), GFP_KERNEL );
49
- if (!head )
50
- return - ENOBUFS ;
51
-
52
- rcu_assign_pointer (tp -> root , head );
53
-
54
40
return 0 ;
55
41
}
56
42
57
- static void mall_destroy_filter (struct rcu_head * head )
43
+ static void mall_destroy_rcu (struct rcu_head * rcu )
58
44
{
59
- struct cls_mall_filter * f = container_of (head , struct cls_mall_filter , rcu );
45
+ struct cls_mall_head * head = container_of (rcu , struct cls_mall_head ,
46
+ rcu );
60
47
61
- tcf_exts_destroy (& f -> exts );
62
-
63
- kfree (f );
48
+ tcf_exts_destroy (& head -> exts );
49
+ kfree (head );
64
50
}
65
51
66
52
static int mall_replace_hw_filter (struct tcf_proto * tp ,
67
- struct cls_mall_filter * f ,
53
+ struct cls_mall_head * head ,
68
54
unsigned long cookie )
69
55
{
70
56
struct net_device * dev = tp -> q -> dev_queue -> dev ;
@@ -74,15 +60,15 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
74
60
offload .type = TC_SETUP_MATCHALL ;
75
61
offload .cls_mall = & mall_offload ;
76
62
offload .cls_mall -> command = TC_CLSMATCHALL_REPLACE ;
77
- offload .cls_mall -> exts = & f -> exts ;
63
+ offload .cls_mall -> exts = & head -> exts ;
78
64
offload .cls_mall -> cookie = cookie ;
79
65
80
66
return dev -> netdev_ops -> ndo_setup_tc (dev , tp -> q -> handle , tp -> protocol ,
81
67
& offload );
82
68
}
83
69
84
70
static void mall_destroy_hw_filter (struct tcf_proto * tp ,
85
- struct cls_mall_filter * f ,
71
+ struct cls_mall_head * head ,
86
72
unsigned long cookie )
87
73
{
88
74
struct net_device * dev = tp -> q -> dev_queue -> dev ;
@@ -103,29 +89,20 @@ static bool mall_destroy(struct tcf_proto *tp, bool force)
103
89
{
104
90
struct cls_mall_head * head = rtnl_dereference (tp -> root );
105
91
struct net_device * dev = tp -> q -> dev_queue -> dev ;
106
- struct cls_mall_filter * f = head -> filter ;
107
92
108
- if (!force && f )
109
- return false ;
93
+ if (!head )
94
+ return true ;
110
95
111
- if (f ) {
112
- if (tc_should_offload (dev , tp , f -> flags ))
113
- mall_destroy_hw_filter (tp , f , (unsigned long ) f );
96
+ if (tc_should_offload (dev , tp , head -> flags ))
97
+ mall_destroy_hw_filter (tp , head , (unsigned long ) head );
114
98
115
- call_rcu (& f -> rcu , mall_destroy_filter );
116
- }
117
- kfree_rcu (head , rcu );
99
+ call_rcu (& head -> rcu , mall_destroy_rcu );
118
100
return true;
119
101
}
120
102
121
103
static unsigned long mall_get (struct tcf_proto * tp , u32 handle )
122
104
{
123
- struct cls_mall_head * head = rtnl_dereference (tp -> root );
124
- struct cls_mall_filter * f = head -> filter ;
125
-
126
- if (f && f -> handle == handle )
127
- return (unsigned long ) f ;
128
- return 0 ;
105
+ return 0UL ;
129
106
}
130
107
131
108
static const struct nla_policy mall_policy [TCA_MATCHALL_MAX + 1 ] = {
@@ -134,7 +111,7 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
134
111
};
135
112
136
113
static int mall_set_parms (struct net * net , struct tcf_proto * tp ,
137
- struct cls_mall_filter * f ,
114
+ struct cls_mall_head * head ,
138
115
unsigned long base , struct nlattr * * tb ,
139
116
struct nlattr * est , bool ovr )
140
117
{
@@ -147,11 +124,11 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp,
147
124
return err ;
148
125
149
126
if (tb [TCA_MATCHALL_CLASSID ]) {
150
- f -> res .classid = nla_get_u32 (tb [TCA_MATCHALL_CLASSID ]);
151
- tcf_bind_filter (tp , & f -> res , base );
127
+ head -> res .classid = nla_get_u32 (tb [TCA_MATCHALL_CLASSID ]);
128
+ tcf_bind_filter (tp , & head -> res , base );
152
129
}
153
130
154
- tcf_exts_change (tp , & f -> exts , & e );
131
+ tcf_exts_change (tp , & head -> exts , & e );
155
132
156
133
return 0 ;
157
134
}
@@ -162,21 +139,17 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
162
139
unsigned long * arg , bool ovr )
163
140
{
164
141
struct cls_mall_head * head = rtnl_dereference (tp -> root );
165
- struct cls_mall_filter * fold = (struct cls_mall_filter * ) * arg ;
166
142
struct net_device * dev = tp -> q -> dev_queue -> dev ;
167
- struct cls_mall_filter * f ;
168
143
struct nlattr * tb [TCA_MATCHALL_MAX + 1 ];
144
+ struct cls_mall_head * new ;
169
145
u32 flags = 0 ;
170
146
int err ;
171
147
172
148
if (!tca [TCA_OPTIONS ])
173
149
return - EINVAL ;
174
150
175
- if (head -> filter )
176
- return - EBUSY ;
177
-
178
- if (fold )
179
- return - EINVAL ;
151
+ if (head )
152
+ return - EEXIST ;
180
153
181
154
err = nla_parse_nested (tb , TCA_MATCHALL_MAX ,
182
155
tca [TCA_OPTIONS ], mall_policy );
@@ -189,23 +162,23 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
189
162
return - EINVAL ;
190
163
}
191
164
192
- f = kzalloc (sizeof (* f ), GFP_KERNEL );
193
- if (!f )
165
+ new = kzalloc (sizeof (* new ), GFP_KERNEL );
166
+ if (!new )
194
167
return - ENOBUFS ;
195
168
196
- tcf_exts_init (& f -> exts , TCA_MATCHALL_ACT , 0 );
169
+ tcf_exts_init (& new -> exts , TCA_MATCHALL_ACT , 0 );
197
170
198
171
if (!handle )
199
172
handle = 1 ;
200
- f -> handle = handle ;
201
- f -> flags = flags ;
173
+ new -> handle = handle ;
174
+ new -> flags = flags ;
202
175
203
- err = mall_set_parms (net , tp , f , base , tb , tca [TCA_RATE ], ovr );
176
+ err = mall_set_parms (net , tp , new , base , tb , tca [TCA_RATE ], ovr );
204
177
if (err )
205
178
goto errout ;
206
179
207
180
if (tc_should_offload (dev , tp , flags )) {
208
- err = mall_replace_hw_filter (tp , f , (unsigned long ) f );
181
+ err = mall_replace_hw_filter (tp , new , (unsigned long ) new );
209
182
if (err ) {
210
183
if (tc_skip_sw (flags ))
211
184
goto errout ;
@@ -214,39 +187,29 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
214
187
}
215
188
}
216
189
217
- * arg = (unsigned long ) f ;
218
- rcu_assign_pointer (head -> filter , f );
219
-
190
+ * arg = (unsigned long ) head ;
191
+ rcu_assign_pointer (tp -> root , new );
192
+ if (head )
193
+ call_rcu (& head -> rcu , mall_destroy_rcu );
220
194
return 0 ;
221
195
222
196
errout :
223
- kfree (f );
197
+ kfree (new );
224
198
return err ;
225
199
}
226
200
227
201
static int mall_delete (struct tcf_proto * tp , unsigned long arg )
228
202
{
229
- struct cls_mall_head * head = rtnl_dereference (tp -> root );
230
- struct cls_mall_filter * f = (struct cls_mall_filter * ) arg ;
231
- struct net_device * dev = tp -> q -> dev_queue -> dev ;
232
-
233
- if (tc_should_offload (dev , tp , f -> flags ))
234
- mall_destroy_hw_filter (tp , f , (unsigned long ) f );
235
-
236
- RCU_INIT_POINTER (head -> filter , NULL );
237
- tcf_unbind_filter (tp , & f -> res );
238
- call_rcu (& f -> rcu , mall_destroy_filter );
239
- return 0 ;
203
+ return - EOPNOTSUPP ;
240
204
}
241
205
242
206
static void mall_walk (struct tcf_proto * tp , struct tcf_walker * arg )
243
207
{
244
208
struct cls_mall_head * head = rtnl_dereference (tp -> root );
245
- struct cls_mall_filter * f = head -> filter ;
246
209
247
210
if (arg -> count < arg -> skip )
248
211
goto skip ;
249
- if (arg -> fn (tp , (unsigned long ) f , arg ) < 0 )
212
+ if (arg -> fn (tp , (unsigned long ) head , arg ) < 0 )
250
213
arg -> stop = 1 ;
251
214
skip :
252
215
arg -> count ++ ;
@@ -255,28 +218,28 @@ static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg)
255
218
static int mall_dump (struct net * net , struct tcf_proto * tp , unsigned long fh ,
256
219
struct sk_buff * skb , struct tcmsg * t )
257
220
{
258
- struct cls_mall_filter * f = (struct cls_mall_filter * ) fh ;
221
+ struct cls_mall_head * head = (struct cls_mall_head * ) fh ;
259
222
struct nlattr * nest ;
260
223
261
- if (!f )
224
+ if (!head )
262
225
return skb -> len ;
263
226
264
- t -> tcm_handle = f -> handle ;
227
+ t -> tcm_handle = head -> handle ;
265
228
266
229
nest = nla_nest_start (skb , TCA_OPTIONS );
267
230
if (!nest )
268
231
goto nla_put_failure ;
269
232
270
- if (f -> res .classid &&
271
- nla_put_u32 (skb , TCA_MATCHALL_CLASSID , f -> res .classid ))
233
+ if (head -> res .classid &&
234
+ nla_put_u32 (skb , TCA_MATCHALL_CLASSID , head -> res .classid ))
272
235
goto nla_put_failure ;
273
236
274
- if (tcf_exts_dump (skb , & f -> exts ))
237
+ if (tcf_exts_dump (skb , & head -> exts ))
275
238
goto nla_put_failure ;
276
239
277
240
nla_nest_end (skb , nest );
278
241
279
- if (tcf_exts_dump_stats (skb , & f -> exts ) < 0 )
242
+ if (tcf_exts_dump_stats (skb , & head -> exts ) < 0 )
280
243
goto nla_put_failure ;
281
244
282
245
return skb -> len ;
0 commit comments