|
@@ -1565,7 +1565,11 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
|
|
|
|
|
|
netlink_dump(sk);
|
|
|
sock_put(sk);
|
|
|
- return 0;
|
|
|
+
|
|
|
+ /* We successfully started a dump, by returning -EINTR we
|
|
|
+ * signal not to send ACK even if it was requested.
|
|
|
+ */
|
|
|
+ return -EINTR;
|
|
|
}
|
|
|
|
|
|
void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
|
|
@@ -1619,17 +1623,21 @@ int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
|
|
|
|
|
|
/* Only requests are handled by the kernel */
|
|
|
if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
|
|
|
- goto skip;
|
|
|
+ goto ack;
|
|
|
|
|
|
/* Skip control messages */
|
|
|
if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
|
|
|
- goto skip;
|
|
|
+ goto ack;
|
|
|
|
|
|
err = cb(skb, nlh);
|
|
|
-skip:
|
|
|
+ if (err == -EINTR)
|
|
|
+ goto skip;
|
|
|
+
|
|
|
+ack:
|
|
|
if (nlh->nlmsg_flags & NLM_F_ACK || err)
|
|
|
netlink_ack(skb, nlh, err);
|
|
|
|
|
|
+skip:
|
|
|
msglen = NLMSG_ALIGN(nlh->nlmsg_len);
|
|
|
if (msglen > skb->len)
|
|
|
msglen = skb->len;
|