aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2013-06-29 08:15:47 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2013-06-30 12:15:48 -0400
commit496e4ae7dc944faa1721bfda7e9d834d5611a874 (patch)
tree7543efa6dbd1432ac7afa0ad641773bc3737e722 /net
parent8b4d14d8eb36874daf159d33dcccd4746a6f3189 (diff)
netfilter: nf_queue: add NFQA_SKB_CSUM_NOTVERIFIED info flag
The common case is that TCP/IP checksums have already been verified, e.g. by hardware (rx checksum offload), or conntrack. Userspace can use this flag to determine when the checksum has not been validated yet. If the flag is set, this doesn't necessarily mean that the packet has an invalid checksum, e.g. if NIC doesn't support rx checksum. Userspace that sucessfully enabled NFQA_CFG_F_GSO queue feature flag can infer that IP/TCP checksum has already been validated if either the SKB_INFO attribute is not present or the NFQA_SKB_CSUM_NOTVERIFIED flag is unset. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nfnetlink_queue_core.c16
1 files changed, 14 insertions, 2 deletions
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) {