Skip to content

Commit 35c55fc

Browse files
congwangdavem330
authored andcommitted
cls_u32: use tcf_exts_get_net() before call_rcu()
Hold netns refcnt before call_rcu() and release it after the tcf_exts_destroy() is done. Note, on ->destroy() path we have to respect the return value of tcf_exts_get_net(), on other paths it should always return true, so we don't need to care. Cc: Lucas Bates <[email protected]> Cc: Jamal Hadi Salim <[email protected]> Cc: Jiri Pirko <[email protected]> Signed-off-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f2b7510 commit 35c55fc

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

net/sched/cls_u32.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
399399
bool free_pf)
400400
{
401401
tcf_exts_destroy(&n->exts);
402+
tcf_exts_put_net(&n->exts);
402403
if (n->ht_down)
403404
n->ht_down->refcnt--;
404405
#ifdef CONFIG_CLS_U32_PERF
@@ -476,6 +477,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode *key)
476477
RCU_INIT_POINTER(*kp, key->next);
477478

478479
tcf_unbind_filter(tp, &key->res);
480+
tcf_exts_get_net(&key->exts);
479481
call_rcu(&key->rcu, u32_delete_key_freepf_rcu);
480482
return 0;
481483
}
@@ -588,7 +590,10 @@ static void u32_clear_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht)
588590
rtnl_dereference(n->next));
589591
tcf_unbind_filter(tp, &n->res);
590592
u32_remove_hw_knode(tp, n->handle);
591-
call_rcu(&n->rcu, u32_delete_key_freepf_rcu);
593+
if (tcf_exts_get_net(&n->exts))
594+
call_rcu(&n->rcu, u32_delete_key_freepf_rcu);
595+
else
596+
u32_destroy_key(n->tp, n, true);
592597
}
593598
}
594599
}
@@ -949,6 +954,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
949954

950955
u32_replace_knode(tp, tp_c, new);
951956
tcf_unbind_filter(tp, &n->res);
957+
tcf_exts_get_net(&n->exts);
952958
call_rcu(&n->rcu, u32_delete_key_rcu);
953959
return 0;
954960
}

0 commit comments

Comments
 (0)