mirror of
https://github.com/torvalds/linux.git
synced 2024-12-18 00:53:40 +00:00
[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>
This commit is contained in:
parent
6d0b842d3b
commit
29c5d4afba
@ -58,7 +58,6 @@ struct nfulnl_instance {
|
|||||||
|
|
||||||
unsigned int qlen; /* number of nlmsgs in skb */
|
unsigned int qlen; /* number of nlmsgs in skb */
|
||||||
struct sk_buff *skb; /* pre-allocatd skb */
|
struct sk_buff *skb; /* pre-allocatd skb */
|
||||||
struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */
|
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
int peer_pid; /* PID of the peer process */
|
int peer_pid; /* PID of the peer process */
|
||||||
|
|
||||||
@ -345,10 +344,12 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size,
|
|||||||
static int
|
static int
|
||||||
__nfulnl_send(struct nfulnl_instance *inst)
|
__nfulnl_send(struct nfulnl_instance *inst)
|
||||||
{
|
{
|
||||||
int status;
|
int status = -1;
|
||||||
|
|
||||||
if (inst->qlen > 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);
|
status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
@ -358,8 +359,8 @@ __nfulnl_send(struct nfulnl_instance *inst)
|
|||||||
|
|
||||||
inst->qlen = 0;
|
inst->qlen = 0;
|
||||||
inst->skb = NULL;
|
inst->skb = NULL;
|
||||||
inst->lastnlh = NULL;
|
|
||||||
|
|
||||||
|
nlmsg_failure:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,7 +539,6 @@ __build_packet_message(struct nfulnl_instance *inst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nlh->nlmsg_len = inst->skb->tail - old_tail;
|
nlh->nlmsg_len = inst->skb->tail - old_tail;
|
||||||
inst->lastnlh = nlh;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nlmsg_failure:
|
nlmsg_failure:
|
||||||
@ -644,7 +644,8 @@ nfulnl_log_packet(unsigned int pf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (inst->qlen >= qthreshold ||
|
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
|
/* either the queue len is too high or we don't have
|
||||||
* enough room in the skb left. flush to userspace. */
|
* enough room in the skb left. flush to userspace. */
|
||||||
UDEBUG("flushing old skb\n");
|
UDEBUG("flushing old skb\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user