aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h2
-rw-r--r--net/netfilter/nfnetlink_queue_core.c16
2 files changed, 16 insertions, 2 deletions
diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index a2308ae5a73d..3a9b92147339 100644
--- a/include/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
@@ -105,5 +105,7 @@ enum nfqnl_attr_config {
105#define NFQA_SKB_CSUMNOTREADY (1 << 0) 105#define NFQA_SKB_CSUMNOTREADY (1 << 0)
106/* packet is GSO (i.e., exceeds device mtu) */ 106/* packet is GSO (i.e., exceeds device mtu) */
107#define NFQA_SKB_GSO (1 << 1) 107#define NFQA_SKB_GSO (1 << 1)
108/* csum not validated (incoming device doesn't support hw checksum, etc.) */
109#define NFQA_SKB_CSUM_NOTVERIFIED (1 << 2)
108 110
109#endif /* _NFNETLINK_QUEUE_H */ 111#endif /* _NFNETLINK_QUEUE_H */
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 299a48ae5dc9..971ea145ab3e 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -280,12 +280,17 @@ nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
280 skb_shinfo(to)->nr_frags = j; 280 skb_shinfo(to)->nr_frags = j;
281} 281}
282 282
283static int nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet) 283static int
284nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
285 bool csum_verify)
284{ 286{
285 __u32 flags = 0; 287 __u32 flags = 0;
286 288
287 if (packet->ip_summed == CHECKSUM_PARTIAL) 289 if (packet->ip_summed == CHECKSUM_PARTIAL)
288 flags = NFQA_SKB_CSUMNOTREADY; 290 flags = NFQA_SKB_CSUMNOTREADY;
291 else if (csum_verify)
292 flags = NFQA_SKB_CSUM_NOTVERIFIED;
293
289 if (skb_is_gso(packet)) 294 if (skb_is_gso(packet))
290 flags |= NFQA_SKB_GSO; 295 flags |= NFQA_SKB_GSO;
291 296
@@ -310,6 +315,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
310 struct net_device *outdev; 315 struct net_device *outdev;
311 struct nf_conn *ct = NULL; 316 struct nf_conn *ct = NULL;
312 enum ip_conntrack_info uninitialized_var(ctinfo); 317 enum ip_conntrack_info uninitialized_var(ctinfo);
318 bool csum_verify;
313 319
314 size = nlmsg_total_size(sizeof(struct nfgenmsg)) 320 size = nlmsg_total_size(sizeof(struct nfgenmsg))
315 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) 321 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -327,6 +333,12 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
327 if (entskb->tstamp.tv64) 333 if (entskb->tstamp.tv64)
328 size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)); 334 size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
329 335
336 if (entry->hook <= NF_INET_FORWARD ||
337 (entry->hook == NF_INET_POST_ROUTING && entskb->sk == NULL))
338 csum_verify = !skb_csum_unnecessary(entskb);
339 else
340 csum_verify = false;
341
330 outdev = entry->outdev; 342 outdev = entry->outdev;
331 343
332 switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) { 344 switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) {
@@ -476,7 +488,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
476 nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len))) 488 nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len)))
477 goto nla_put_failure; 489 goto nla_put_failure;
478 490
479 if (nfqnl_put_packet_info(skb, entskb)) 491 if (nfqnl_put_packet_info(skb, entskb, csum_verify))
480 goto nla_put_failure; 492 goto nla_put_failure;
481 493
482 if (data_len) { 494 if (data_len) {