|
@@ -178,14 +178,11 @@ errout:
|
|
|
return ERR_PTR(err);
|
|
|
}
|
|
|
|
|
|
-static bool tcf_proto_destroy(struct tcf_proto *tp, bool force)
|
|
|
+static void tcf_proto_destroy(struct tcf_proto *tp)
|
|
|
{
|
|
|
- if (tp->ops->destroy(tp, force)) {
|
|
|
- module_put(tp->ops->owner);
|
|
|
- kfree_rcu(tp, rcu);
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
+ tp->ops->destroy(tp);
|
|
|
+ module_put(tp->ops->owner);
|
|
|
+ kfree_rcu(tp, rcu);
|
|
|
}
|
|
|
|
|
|
void tcf_destroy_chain(struct tcf_proto __rcu **fl)
|
|
@@ -194,7 +191,7 @@ void tcf_destroy_chain(struct tcf_proto __rcu **fl)
|
|
|
|
|
|
while ((tp = rtnl_dereference(*fl)) != NULL) {
|
|
|
RCU_INIT_POINTER(*fl, tp->next);
|
|
|
- tcf_proto_destroy(tp, true);
|
|
|
+ tcf_proto_destroy(tp);
|
|
|
}
|
|
|
}
|
|
|
EXPORT_SYMBOL(tcf_destroy_chain);
|
|
@@ -361,7 +358,7 @@ replay:
|
|
|
RCU_INIT_POINTER(*back, next);
|
|
|
tfilter_notify(net, skb, n, tp, fh,
|
|
|
RTM_DELTFILTER, false);
|
|
|
- tcf_proto_destroy(tp, true);
|
|
|
+ tcf_proto_destroy(tp);
|
|
|
err = 0;
|
|
|
goto errout;
|
|
|
}
|
|
@@ -372,24 +369,28 @@ replay:
|
|
|
goto errout;
|
|
|
}
|
|
|
} else {
|
|
|
+ bool last;
|
|
|
+
|
|
|
switch (n->nlmsg_type) {
|
|
|
case RTM_NEWTFILTER:
|
|
|
if (n->nlmsg_flags & NLM_F_EXCL) {
|
|
|
if (tp_created)
|
|
|
- tcf_proto_destroy(tp, true);
|
|
|
+ tcf_proto_destroy(tp);
|
|
|
err = -EEXIST;
|
|
|
goto errout;
|
|
|
}
|
|
|
break;
|
|
|
case RTM_DELTFILTER:
|
|
|
- err = tp->ops->delete(tp, fh);
|
|
|
+ err = tp->ops->delete(tp, fh, &last);
|
|
|
if (err)
|
|
|
goto errout;
|
|
|
next = rtnl_dereference(tp->next);
|
|
|
tfilter_notify(net, skb, n, tp, t->tcm_handle,
|
|
|
RTM_DELTFILTER, false);
|
|
|
- if (tcf_proto_destroy(tp, false))
|
|
|
+ if (last) {
|
|
|
RCU_INIT_POINTER(*back, next);
|
|
|
+ tcf_proto_destroy(tp);
|
|
|
+ }
|
|
|
goto errout;
|
|
|
case RTM_GETTFILTER:
|
|
|
err = tfilter_notify(net, skb, n, tp, fh,
|
|
@@ -411,7 +412,7 @@ replay:
|
|
|
tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false);
|
|
|
} else {
|
|
|
if (tp_created)
|
|
|
- tcf_proto_destroy(tp, true);
|
|
|
+ tcf_proto_destroy(tp);
|
|
|
}
|
|
|
|
|
|
errout:
|