]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/netlink/af_netlink.c
[NETLINK]: Ignore !NLM_F_REQUEST messages directly in netlink_run_queue()
[net-next-2.6.git] / net / netlink / af_netlink.c
index 04b72d3c1dea8607ff8ca8f1c957ec1ef8cd7670..7b455980e9bfcd520f127c26541f8f1180ad794f 100644 (file)
@@ -396,7 +396,6 @@ static int netlink_create(struct socket *sock, int protocol)
 {
        struct module *module = NULL;
        struct netlink_sock *nlk;
-       unsigned int groups;
        int err = 0;
 
        sock->state = SS_UNCONNECTED;
@@ -418,7 +417,6 @@ static int netlink_create(struct socket *sock, int protocol)
        if (nl_table[protocol].registered &&
            try_module_get(nl_table[protocol].module))
                module = nl_table[protocol].module;
-       groups = nl_table[protocol].groups;
        netlink_unlock_table();
 
        if ((err = __netlink_create(sock, protocol)) < 0)
@@ -1472,10 +1470,15 @@ 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;
+
                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
@@ -1483,9 +1486,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);
        }