diff options
-rw-r--r-- | include/uapi/linux/netfilter/nfnetlink_queue.h | 7 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_queue_core.c | 16 |
2 files changed, 23 insertions, 0 deletions
diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h index 70ec8c2bc11a..0069da370464 100644 --- a/include/uapi/linux/netfilter/nfnetlink_queue.h +++ b/include/uapi/linux/netfilter/nfnetlink_queue.h | |||
@@ -45,6 +45,7 @@ enum nfqnl_attr_type { | |||
45 | NFQA_CT, /* nf_conntrack_netlink.h */ | 45 | NFQA_CT, /* nf_conntrack_netlink.h */ |
46 | NFQA_CT_INFO, /* enum ip_conntrack_info */ | 46 | NFQA_CT_INFO, /* enum ip_conntrack_info */ |
47 | NFQA_CAP_LEN, /* __u32 length of captured packet */ | 47 | NFQA_CAP_LEN, /* __u32 length of captured packet */ |
48 | NFQA_SKB_INFO, /* __u32 skb meta information */ | ||
48 | 49 | ||
49 | __NFQA_MAX | 50 | __NFQA_MAX |
50 | }; | 51 | }; |
@@ -98,4 +99,10 @@ enum nfqnl_attr_config { | |||
98 | #define NFQA_CFG_F_CONNTRACK (1 << 1) | 99 | #define NFQA_CFG_F_CONNTRACK (1 << 1) |
99 | #define NFQA_CFG_F_MAX (1 << 2) | 100 | #define NFQA_CFG_F_MAX (1 << 2) |
100 | 101 | ||
102 | /* flags for NFQA_SKB_INFO */ | ||
103 | /* packet appears to have wrong checksums, but they are ok */ | ||
104 | #define NFQA_SKB_CSUMNOTREADY (1 << 0) | ||
105 | /* packet is GSO (i.e., exceeds device mtu) */ | ||
106 | #define NFQA_SKB_GSO (1 << 1) | ||
107 | |||
101 | #endif /* _NFNETLINK_QUEUE_H */ | 108 | #endif /* _NFNETLINK_QUEUE_H */ |
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index edbae4caf753..d052cd6da5d2 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c | |||
@@ -272,6 +272,18 @@ nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen) | |||
272 | skb_shinfo(to)->nr_frags = j; | 272 | skb_shinfo(to)->nr_frags = j; |
273 | } | 273 | } |
274 | 274 | ||
275 | static int nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet) | ||
276 | { | ||
277 | __u32 flags = 0; | ||
278 | |||
279 | if (packet->ip_summed == CHECKSUM_PARTIAL) | ||
280 | flags = NFQA_SKB_CSUMNOTREADY; | ||
281 | if (skb_is_gso(packet)) | ||
282 | flags |= NFQA_SKB_GSO; | ||
283 | |||
284 | return flags ? nla_put_be32(nlskb, NFQA_SKB_INFO, htonl(flags)) : 0; | ||
285 | } | ||
286 | |||
275 | static struct sk_buff * | 287 | static struct sk_buff * |
276 | nfqnl_build_packet_message(struct nfqnl_instance *queue, | 288 | nfqnl_build_packet_message(struct nfqnl_instance *queue, |
277 | struct nf_queue_entry *entry, | 289 | struct nf_queue_entry *entry, |
@@ -301,6 +313,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
301 | #endif | 313 | #endif |
302 | + nla_total_size(sizeof(u_int32_t)) /* mark */ | 314 | + nla_total_size(sizeof(u_int32_t)) /* mark */ |
303 | + nla_total_size(sizeof(struct nfqnl_msg_packet_hw)) | 315 | + nla_total_size(sizeof(struct nfqnl_msg_packet_hw)) |
316 | + nla_total_size(sizeof(u_int32_t)) /* skbinfo */ | ||
304 | + nla_total_size(sizeof(u_int32_t)); /* cap_len */ | 317 | + nla_total_size(sizeof(u_int32_t)); /* cap_len */ |
305 | 318 | ||
306 | if (entskb->tstamp.tv64) | 319 | if (entskb->tstamp.tv64) |
@@ -454,6 +467,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
454 | if (cap_len > 0 && nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len))) | 467 | if (cap_len > 0 && nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len))) |
455 | goto nla_put_failure; | 468 | goto nla_put_failure; |
456 | 469 | ||
470 | if (nfqnl_put_packet_info(skb, entskb)) | ||
471 | goto nla_put_failure; | ||
472 | |||
457 | if (data_len) { | 473 | if (data_len) { |
458 | struct nlattr *nla; | 474 | struct nlattr *nla; |
459 | 475 | ||