]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/netlink/af_netlink.c
[NETLINK]: Ignore control messages directly in netlink_run_queue()
[net-next-2.6.git] / net / netlink / af_netlink.c
index 8488c15f26434a6f05aa67430563bad101c9b74f..5d1079b1838c3880e8b3f6904bc14e86a433f840 100644 (file)
@@ -1470,10 +1470,19 @@ static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
 
        while (skb->len >= nlmsg_total_size(0)) {
                nlh = nlmsg_hdr(skb);
+               err = 0;
 
                if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
                        return 0;
 
+               /* Only requests are handled by the kernel */
+               if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
+                       goto skip;
+
+               /* Skip control messages */
+               if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
+                       goto skip;
+
                if (cb(skb, nlh, &err) < 0) {
                        /* Not an error, but we have to interrupt processing
                         * here. Note: that in this case we do not pull
@@ -1481,9 +1490,10 @@ static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
                         */
                        if (err == 0)
                                return -1;
+               }
+skip:
+               if (nlh->nlmsg_flags & NLM_F_ACK || err)
                        netlink_ack(skb, nlh, err);
-               } else if (nlh->nlmsg_flags & NLM_F_ACK)
-                       netlink_ack(skb, nlh, 0);
 
                netlink_queue_skip(nlh, skb);
        }