|
@@ -214,6 +214,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
|
|
|
struct Qdisc *q;
|
|
struct Qdisc *q;
|
|
|
struct tcf_proto __rcu **back;
|
|
struct tcf_proto __rcu **back;
|
|
|
struct tcf_proto __rcu **chain;
|
|
struct tcf_proto __rcu **chain;
|
|
|
|
|
+ struct tcf_proto *next;
|
|
|
struct tcf_proto *tp;
|
|
struct tcf_proto *tp;
|
|
|
const struct Qdisc_class_ops *cops;
|
|
const struct Qdisc_class_ops *cops;
|
|
|
unsigned long cl;
|
|
unsigned long cl;
|
|
@@ -355,10 +356,8 @@ replay:
|
|
|
|
|
|
|
|
if (fh == 0) {
|
|
if (fh == 0) {
|
|
|
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
|
|
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
|
|
|
- struct tcf_proto *next = rtnl_dereference(tp->next);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ next = rtnl_dereference(tp->next);
|
|
|
RCU_INIT_POINTER(*back, next);
|
|
RCU_INIT_POINTER(*back, next);
|
|
|
-
|
|
|
|
|
tfilter_notify(net, skb, n, tp, fh,
|
|
tfilter_notify(net, skb, n, tp, fh,
|
|
|
RTM_DELTFILTER, false);
|
|
RTM_DELTFILTER, false);
|
|
|
tcf_proto_destroy(tp, true);
|
|
tcf_proto_destroy(tp, true);
|
|
@@ -383,16 +382,13 @@ replay:
|
|
|
break;
|
|
break;
|
|
|
case RTM_DELTFILTER:
|
|
case RTM_DELTFILTER:
|
|
|
err = tp->ops->delete(tp, fh);
|
|
err = tp->ops->delete(tp, fh);
|
|
|
- if (err == 0) {
|
|
|
|
|
- struct tcf_proto *next = rtnl_dereference(tp->next);
|
|
|
|
|
-
|
|
|
|
|
- tfilter_notify(net, skb, n, tp,
|
|
|
|
|
- t->tcm_handle,
|
|
|
|
|
- RTM_DELTFILTER, false);
|
|
|
|
|
- if (tcf_proto_destroy(tp, false))
|
|
|
|
|
- RCU_INIT_POINTER(*back, next);
|
|
|
|
|
- }
|
|
|
|
|
- goto errout;
|
|
|
|
|
|
|
+ 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))
|
|
|
|
|
+ RCU_INIT_POINTER(*back, next);
|
|
|
case RTM_GETTFILTER:
|
|
case RTM_GETTFILTER:
|
|
|
err = tfilter_notify(net, skb, n, tp, fh,
|
|
err = tfilter_notify(net, skb, n, tp, fh,
|
|
|
RTM_NEWTFILTER, true);
|
|
RTM_NEWTFILTER, true);
|