27
27
struct tcf_bpf_cfg {
28
28
struct bpf_prog * filter ;
29
29
struct sock_filter * bpf_ops ;
30
- char * bpf_name ;
30
+ const char * bpf_name ;
31
31
u32 bpf_fd ;
32
32
u16 bpf_num_ops ;
33
+ bool is_ebpf ;
33
34
};
34
35
35
36
static int tcf_bpf (struct sk_buff * skb , const struct tc_action * act ,
@@ -207,6 +208,7 @@ static int tcf_bpf_init_from_ops(struct nlattr **tb, struct tcf_bpf_cfg *cfg)
207
208
cfg -> bpf_ops = bpf_ops ;
208
209
cfg -> bpf_num_ops = bpf_num_ops ;
209
210
cfg -> filter = fp ;
211
+ cfg -> is_ebpf = false;
210
212
211
213
return 0 ;
212
214
}
@@ -241,18 +243,40 @@ static int tcf_bpf_init_from_efd(struct nlattr **tb, struct tcf_bpf_cfg *cfg)
241
243
cfg -> bpf_fd = bpf_fd ;
242
244
cfg -> bpf_name = name ;
243
245
cfg -> filter = fp ;
246
+ cfg -> is_ebpf = true;
244
247
245
248
return 0 ;
246
249
}
247
250
251
+ static void tcf_bpf_cfg_cleanup (const struct tcf_bpf_cfg * cfg )
252
+ {
253
+ if (cfg -> is_ebpf )
254
+ bpf_prog_put (cfg -> filter );
255
+ else
256
+ bpf_prog_destroy (cfg -> filter );
257
+
258
+ kfree (cfg -> bpf_ops );
259
+ kfree (cfg -> bpf_name );
260
+ }
261
+
262
+ static void tcf_bpf_prog_fill_cfg (const struct tcf_bpf * prog ,
263
+ struct tcf_bpf_cfg * cfg )
264
+ {
265
+ cfg -> is_ebpf = tcf_bpf_is_ebpf (prog );
266
+ cfg -> filter = prog -> filter ;
267
+
268
+ cfg -> bpf_ops = prog -> bpf_ops ;
269
+ cfg -> bpf_name = prog -> bpf_name ;
270
+ }
271
+
248
272
static int tcf_bpf_init (struct net * net , struct nlattr * nla ,
249
273
struct nlattr * est , struct tc_action * act ,
250
274
int replace , int bind )
251
275
{
252
276
struct nlattr * tb [TCA_ACT_BPF_MAX + 1 ];
277
+ struct tcf_bpf_cfg cfg , old ;
253
278
struct tc_act_bpf * parm ;
254
279
struct tcf_bpf * prog ;
255
- struct tcf_bpf_cfg cfg ;
256
280
bool is_bpf , is_ebpf ;
257
281
int ret ;
258
282
@@ -301,6 +325,9 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
301
325
prog = to_bpf (act );
302
326
spin_lock_bh (& prog -> tcf_lock );
303
327
328
+ if (ret != ACT_P_CREATED )
329
+ tcf_bpf_prog_fill_cfg (prog , & old );
330
+
304
331
prog -> bpf_ops = cfg .bpf_ops ;
305
332
prog -> bpf_name = cfg .bpf_name ;
306
333
@@ -316,32 +343,22 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
316
343
317
344
if (ret == ACT_P_CREATED )
318
345
tcf_hash_insert (act );
346
+ else
347
+ tcf_bpf_cfg_cleanup (& old );
319
348
320
349
return ret ;
321
350
322
351
destroy_fp :
323
- if (is_ebpf )
324
- bpf_prog_put (cfg .filter );
325
- else
326
- bpf_prog_destroy (cfg .filter );
327
-
328
- kfree (cfg .bpf_ops );
329
- kfree (cfg .bpf_name );
330
-
352
+ tcf_bpf_cfg_cleanup (& cfg );
331
353
return ret ;
332
354
}
333
355
334
356
static void tcf_bpf_cleanup (struct tc_action * act , int bind )
335
357
{
336
- const struct tcf_bpf * prog = act -> priv ;
337
-
338
- if (tcf_bpf_is_ebpf (prog ))
339
- bpf_prog_put (prog -> filter );
340
- else
341
- bpf_prog_destroy (prog -> filter );
358
+ struct tcf_bpf_cfg tmp ;
342
359
343
- kfree ( prog -> bpf_ops );
344
- kfree ( prog -> bpf_name );
360
+ tcf_bpf_prog_fill_cfg ( act -> priv , & tmp );
361
+ tcf_bpf_cfg_cleanup ( & tmp );
345
362
}
346
363
347
364
static struct tc_action_ops act_bpf_ops __read_mostly = {
0 commit comments