@@ -55,6 +55,24 @@ static void tcf_action_goto_chain_exec(const struct tc_action *a,
55
55
res -> goto_tp = rcu_dereference_bh (chain -> filter_chain );
56
56
}
57
57
58
+ static void tcf_free_cookie_rcu (struct rcu_head * p )
59
+ {
60
+ struct tc_cookie * cookie = container_of (p , struct tc_cookie , rcu );
61
+
62
+ kfree (cookie -> data );
63
+ kfree (cookie );
64
+ }
65
+
66
+ static void tcf_set_action_cookie (struct tc_cookie __rcu * * old_cookie ,
67
+ struct tc_cookie * new_cookie )
68
+ {
69
+ struct tc_cookie * old ;
70
+
71
+ old = xchg (old_cookie , new_cookie );
72
+ if (old )
73
+ call_rcu (& old -> rcu , tcf_free_cookie_rcu );
74
+ }
75
+
58
76
/* XXX: For standalone actions, we don't need a RCU grace period either, because
59
77
* actions are always connected to filters and filters are already destroyed in
60
78
* RCU callbacks, so after a RCU grace period actions are already disconnected
@@ -65,10 +83,7 @@ static void free_tcf(struct tc_action *p)
65
83
free_percpu (p -> cpu_bstats );
66
84
free_percpu (p -> cpu_qstats );
67
85
68
- if (p -> act_cookie ) {
69
- kfree (p -> act_cookie -> data );
70
- kfree (p -> act_cookie );
71
- }
86
+ tcf_set_action_cookie (& p -> act_cookie , NULL );
72
87
if (p -> goto_chain )
73
88
tcf_action_goto_chain_fini (p );
74
89
@@ -567,16 +582,22 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
567
582
int err = - EINVAL ;
568
583
unsigned char * b = skb_tail_pointer (skb );
569
584
struct nlattr * nest ;
585
+ struct tc_cookie * cookie ;
570
586
571
587
if (nla_put_string (skb , TCA_KIND , a -> ops -> kind ))
572
588
goto nla_put_failure ;
573
589
if (tcf_action_copy_stats (skb , a , 0 ))
574
590
goto nla_put_failure ;
575
- if (a -> act_cookie ) {
576
- if (nla_put (skb , TCA_ACT_COOKIE , a -> act_cookie -> len ,
577
- a -> act_cookie -> data ))
591
+
592
+ rcu_read_lock ();
593
+ cookie = rcu_dereference (a -> act_cookie );
594
+ if (cookie ) {
595
+ if (nla_put (skb , TCA_ACT_COOKIE , cookie -> len , cookie -> data )) {
596
+ rcu_read_unlock ();
578
597
goto nla_put_failure ;
598
+ }
579
599
}
600
+ rcu_read_unlock ();
580
601
581
602
nest = nla_nest_start (skb , TCA_OPTIONS );
582
603
if (nest == NULL )
@@ -719,13 +740,8 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
719
740
if (err < 0 )
720
741
goto err_mod ;
721
742
722
- if (name == NULL && tb [TCA_ACT_COOKIE ]) {
723
- if (a -> act_cookie ) {
724
- kfree (a -> act_cookie -> data );
725
- kfree (a -> act_cookie );
726
- }
727
- a -> act_cookie = cookie ;
728
- }
743
+ if (!name && tb [TCA_ACT_COOKIE ])
744
+ tcf_set_action_cookie (& a -> act_cookie , cookie );
729
745
730
746
/* module count goes up only when brand new policy is created
731
747
* if it exists and is only bound to in a_o->init() then
0 commit comments