[NETFILTER]: nfnetlink_log: fix sending of multipart messages

The following patch fixes the handling of netlink packets containing
multiple messages.

As exposed during netfilter workshop, nfnetlink_log was overwritten the
message type of the last message (setting it to MSG_DONE) in a multipart
packet. The consequence was libnfnetlink to ignore the last message in the
packet.

The following patch adds a supplementary message (with type MSG_DONE) af
the end of the netlink skb.

Signed-off-by: Eric Leblond <eric@inl.fr>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index e185a5b..2351533 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -58,7 +58,6 @@
 
 	unsigned int qlen;		/* number of nlmsgs in skb */
 	struct sk_buff *skb;		/* pre-allocatd skb */
-	struct nlmsghdr *lastnlh;	/* netlink header of last msg in skb */
 	struct timer_list timer;
 	int peer_pid;			/* PID of the peer process */
 
@@ -345,10 +344,12 @@
 static int
 __nfulnl_send(struct nfulnl_instance *inst)
 {
-	int status;
+	int status = -1;
 
 	if (inst->qlen > 1)
-		inst->lastnlh->nlmsg_type = NLMSG_DONE;
+		NLMSG_PUT(inst->skb, 0, 0,
+			  NLMSG_DONE,
+			  sizeof(struct nfgenmsg));
 
 	status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT);
 	if (status < 0) {
@@ -358,8 +359,8 @@
 
 	inst->qlen = 0;
 	inst->skb = NULL;
-	inst->lastnlh = NULL;
 
+nlmsg_failure:
 	return status;
 }
 
@@ -538,7 +539,6 @@
 	}
 
 	nlh->nlmsg_len = inst->skb->tail - old_tail;
-	inst->lastnlh = nlh;
 	return 0;
 
 nlmsg_failure:
@@ -644,7 +644,8 @@
 	}
 
 	if (inst->qlen >= qthreshold ||
-	    (inst->skb && size > skb_tailroom(inst->skb))) {
+	    (inst->skb && size >
+	     skb_tailroom(inst->skb) - sizeof(struct nfgenmsg))) {
 		/* either the queue len is too high or we don't have
 		 * enough room in the skb left. flush to userspace. */
 		UDEBUG("flushing old skb\n");