]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/sched/cls_api.c
net: sched: don't set tunnel for decap action
[linux.git] / net / sched / cls_api.c
index 2c2aac4ac721c94d8c198f4d49ea24146b9906c7..9115f053883f375e6f38d73530a7b88d0b2bd96c 100644 (file)
@@ -367,7 +367,7 @@ static void tcf_chain_destroy(struct tcf_chain *chain, bool free_block)
        struct tcf_block *block = chain->block;
 
        mutex_destroy(&chain->filter_chain_lock);
-       kfree(chain);
+       kfree_rcu(chain, rcu);
        if (free_block)
                tcf_block_destroy(block);
 }
@@ -1893,6 +1893,7 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
 {
        struct sk_buff *skb;
        u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
+       int err = 0;
 
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb)
@@ -1906,10 +1907,14 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
        }
 
        if (unicast)
-               return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
+               err = netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
+       else
+               err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
+                                    n->nlmsg_flags & NLM_F_ECHO);
 
-       return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
-                             n->nlmsg_flags & NLM_F_ECHO);
+       if (err > 0)
+               err = 0;
+       return err;
 }
 
 static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
@@ -1941,12 +1946,15 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
        }
 
        if (unicast)
-               return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
-
-       err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
-                            n->nlmsg_flags & NLM_F_ECHO);
+               err = netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
+       else
+               err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
+                                    n->nlmsg_flags & NLM_F_ECHO);
        if (err < 0)
                NL_SET_ERR_MSG(extack, "Failed to send filter delete notification");
+
+       if (err > 0)
+               err = 0;
        return err;
 }
 
@@ -2688,6 +2696,7 @@ static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb,
        struct tcf_block *block = chain->block;
        struct net *net = block->net;
        struct sk_buff *skb;
+       int err = 0;
 
        skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!skb)
@@ -2701,9 +2710,14 @@ static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb,
        }
 
        if (unicast)
-               return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
+               err = netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
+       else
+               err = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
+                                    flags & NLM_F_ECHO);
 
-       return rtnetlink_send(skb, net, portid, RTNLGRP_TC, flags & NLM_F_ECHO);
+       if (err > 0)
+               err = 0;
+       return err;
 }
 
 static int tc_chain_notify_delete(const struct tcf_proto_ops *tmplt_ops,
@@ -3215,7 +3229,6 @@ int tc_setup_flow_action(struct flow_action *flow_action,
                        entry->tunnel = tcf_tunnel_info(act);
                } else if (is_tcf_tunnel_release(act)) {
                        entry->id = FLOW_ACTION_TUNNEL_DECAP;
-                       entry->tunnel = tcf_tunnel_info(act);
                } else if (is_tcf_pedit(act)) {
                        for (k = 0; k < tcf_pedit_nkeys(act); k++) {
                                switch (tcf_pedit_cmd(act, k)) {