aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h7
-rw-r--r--net/netfilter/nfnetlink_queue_core.c16
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
275static 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
275static struct sk_buff * 287static struct sk_buff *
276nfqnl_build_packet_message(struct nfqnl_instance *queue, 288nfqnl_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