net_sched: do not broadcast RTM_GETTFILTER result
[cascardo/linux.git] / net / sched / cls_api.c
index 11da7da..2ee29a3 100644 (file)
@@ -101,7 +101,7 @@ EXPORT_SYMBOL(unregister_tcf_proto_ops);
 
 static int tfilter_notify(struct net *net, struct sk_buff *oskb,
                          struct nlmsghdr *n, struct tcf_proto *tp,
-                         unsigned long fh, int event);
+                         unsigned long fh, int event, bool unicast);
 
 static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
                                 struct nlmsghdr *n,
@@ -112,7 +112,7 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
 
        for (it_chain = chain; (tp = rtnl_dereference(*it_chain)) != NULL;
             it_chain = &tp->next)
-               tfilter_notify(net, oskb, n, tp, 0, event);
+               tfilter_notify(net, oskb, n, tp, 0, event, false);
 }
 
 /* Select new prio value from the range, managed by kernel. */
@@ -319,7 +319,8 @@ replay:
 
                        RCU_INIT_POINTER(*back, next);
 
-                       tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
+                       tfilter_notify(net, skb, n, tp, fh,
+                                      RTM_DELTFILTER, false);
                        tcf_destroy(tp, true);
                        err = 0;
                        goto errout;
@@ -345,14 +346,14 @@ replay:
                                struct tcf_proto *next = rtnl_dereference(tp->next);
 
                                tfilter_notify(net, skb, n, tp, fh,
-                                              RTM_DELTFILTER);
+                                              RTM_DELTFILTER, false);
                                if (tcf_destroy(tp, false))
                                        RCU_INIT_POINTER(*back, next);
                        }
                        goto errout;
                case RTM_GETTFILTER:
                        err = tfilter_notify(net, skb, n, tp, fh,
-                                            RTM_NEWTFILTER);
+                                            RTM_NEWTFILTER, true);
                        goto errout;
                default:
                        err = -EINVAL;
@@ -367,7 +368,7 @@ replay:
                        RCU_INIT_POINTER(tp->next, rtnl_dereference(*back));
                        rcu_assign_pointer(*back, tp);
                }
-               tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
+               tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false);
        } else {
                if (tp_created)
                        tcf_destroy(tp, true);
@@ -419,7 +420,7 @@ nla_put_failure:
 
 static int tfilter_notify(struct net *net, struct sk_buff *oskb,
                          struct nlmsghdr *n, struct tcf_proto *tp,
-                         unsigned long fh, int event)
+                         unsigned long fh, int event, bool unicast)
 {
        struct sk_buff *skb;
        u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
@@ -433,6 +434,9 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
                return -EINVAL;
        }
 
+       if (unicast)
+               return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT);
+
        return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
                              n->nlmsg_flags & NLM_F_ECHO);
 }