|
@@ -43,7 +43,8 @@
|
|
#define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE
|
|
#define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE
|
|
#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */
|
|
#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */
|
|
#define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */
|
|
#define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */
|
|
-#define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */
|
|
|
|
|
|
+/* max packet size is limited by 16-bit struct nfattr nfa_len field */
|
|
|
|
+#define NFULNL_COPY_RANGE_MAX (0xFFFF - NLA_HDRLEN)
|
|
|
|
|
|
#define PRINTR(x, args...) do { if (net_ratelimit()) \
|
|
#define PRINTR(x, args...) do { if (net_ratelimit()) \
|
|
printk(x, ## args); } while (0);
|
|
printk(x, ## args); } while (0);
|
|
@@ -252,6 +253,8 @@ nfulnl_set_mode(struct nfulnl_instance *inst, u_int8_t mode,
|
|
|
|
|
|
case NFULNL_COPY_PACKET:
|
|
case NFULNL_COPY_PACKET:
|
|
inst->copy_mode = mode;
|
|
inst->copy_mode = mode;
|
|
|
|
+ if (range == 0)
|
|
|
|
+ range = NFULNL_COPY_RANGE_MAX;
|
|
inst->copy_range = min_t(unsigned int,
|
|
inst->copy_range = min_t(unsigned int,
|
|
range, NFULNL_COPY_RANGE_MAX);
|
|
range, NFULNL_COPY_RANGE_MAX);
|
|
break;
|
|
break;
|
|
@@ -343,26 +346,25 @@ nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size,
|
|
return skb;
|
|
return skb;
|
|
}
|
|
}
|
|
|
|
|
|
-static int
|
|
|
|
|
|
+static void
|
|
__nfulnl_send(struct nfulnl_instance *inst)
|
|
__nfulnl_send(struct nfulnl_instance *inst)
|
|
{
|
|
{
|
|
- int status = -1;
|
|
|
|
-
|
|
|
|
if (inst->qlen > 1) {
|
|
if (inst->qlen > 1) {
|
|
struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0,
|
|
struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0,
|
|
NLMSG_DONE,
|
|
NLMSG_DONE,
|
|
sizeof(struct nfgenmsg),
|
|
sizeof(struct nfgenmsg),
|
|
0);
|
|
0);
|
|
- if (!nlh)
|
|
|
|
|
|
+ if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n",
|
|
|
|
+ inst->skb->len, skb_tailroom(inst->skb))) {
|
|
|
|
+ kfree_skb(inst->skb);
|
|
goto out;
|
|
goto out;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
|
|
|
|
- MSG_DONTWAIT);
|
|
|
|
-
|
|
|
|
|
|
+ nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
|
|
|
|
+ MSG_DONTWAIT);
|
|
|
|
+out:
|
|
inst->qlen = 0;
|
|
inst->qlen = 0;
|
|
inst->skb = NULL;
|
|
inst->skb = NULL;
|
|
-out:
|
|
|
|
- return status;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
static void
|
|
@@ -649,7 +651,8 @@ nfulnl_log_packet(struct net *net,
|
|
+ nla_total_size(sizeof(u_int32_t)) /* gid */
|
|
+ nla_total_size(sizeof(u_int32_t)) /* gid */
|
|
+ nla_total_size(plen) /* prefix */
|
|
+ nla_total_size(plen) /* prefix */
|
|
+ nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
|
|
+ nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
|
|
- + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
|
|
|
|
|
|
+ + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp))
|
|
|
|
+ + nla_total_size(sizeof(struct nfgenmsg)); /* NLMSG_DONE */
|
|
|
|
|
|
if (in && skb_mac_header_was_set(skb)) {
|
|
if (in && skb_mac_header_was_set(skb)) {
|
|
size += nla_total_size(skb->dev->hard_header_len)
|
|
size += nla_total_size(skb->dev->hard_header_len)
|
|
@@ -678,8 +681,7 @@ nfulnl_log_packet(struct net *net,
|
|
break;
|
|
break;
|
|
|
|
|
|
case NFULNL_COPY_PACKET:
|
|
case NFULNL_COPY_PACKET:
|
|
- if (inst->copy_range == 0
|
|
|
|
- || inst->copy_range > skb->len)
|
|
|
|
|
|
+ if (inst->copy_range > skb->len)
|
|
data_len = skb->len;
|
|
data_len = skb->len;
|
|
else
|
|
else
|
|
data_len = inst->copy_range;
|
|
data_len = inst->copy_range;
|
|
@@ -692,8 +694,7 @@ nfulnl_log_packet(struct net *net,
|
|
goto unlock_and_release;
|
|
goto unlock_and_release;
|
|
}
|
|
}
|
|
|
|
|
|
- if (inst->skb &&
|
|
|
|
- size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
|
|
|
|
|
|
+ if (inst->skb && size > skb_tailroom(inst->skb)) {
|
|
/* 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. */
|
|
__nfulnl_flush(inst);
|
|
__nfulnl_flush(inst);
|