|
@@ -286,7 +286,7 @@ replay:
|
|
|
RCU_INIT_POINTER(*back, next);
|
|
|
|
|
|
tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
|
|
|
- tcf_destroy(tp);
|
|
|
+ tcf_destroy(tp, true);
|
|
|
err = 0;
|
|
|
goto errout;
|
|
|
}
|
|
@@ -301,14 +301,20 @@ replay:
|
|
|
err = -EEXIST;
|
|
|
if (n->nlmsg_flags & NLM_F_EXCL) {
|
|
|
if (tp_created)
|
|
|
- tcf_destroy(tp);
|
|
|
+ tcf_destroy(tp, true);
|
|
|
goto errout;
|
|
|
}
|
|
|
break;
|
|
|
case RTM_DELTFILTER:
|
|
|
err = tp->ops->delete(tp, fh);
|
|
|
- if (err == 0)
|
|
|
+ if (err == 0) {
|
|
|
tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
|
|
|
+ if (tcf_destroy(tp, false)) {
|
|
|
+ struct tcf_proto *next = rtnl_dereference(tp->next);
|
|
|
+
|
|
|
+ RCU_INIT_POINTER(*back, next);
|
|
|
+ }
|
|
|
+ }
|
|
|
goto errout;
|
|
|
case RTM_GETTFILTER:
|
|
|
err = tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
|
|
@@ -329,7 +335,7 @@ replay:
|
|
|
tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
|
|
|
} else {
|
|
|
if (tp_created)
|
|
|
- tcf_destroy(tp);
|
|
|
+ tcf_destroy(tp, true);
|
|
|
}
|
|
|
|
|
|
errout:
|