int type;
        int err;
 
-       /* Only requests are handled by kernel now */
-       if (!(nlh->nlmsg_flags&NLM_F_REQUEST))
-               return 0;
-
        type = nlh->nlmsg_type;
 
        /* A control message: ignore them */
 
 
        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
                         */
                        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);
        }
 
        struct genlmsghdr *hdr = nlmsg_data(nlh);
        int hdrlen, err = -EINVAL;
 
-       if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
-               goto ignore;
-
        if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
                goto ignore;