#define NFQA_SKB_CSUMNOTREADY (1 << 0)
 /* packet is GSO (i.e., exceeds device mtu) */
 #define NFQA_SKB_GSO (1 << 1)
+/* csum not validated (incoming device doesn't support hw checksum, etc.) */
+#define NFQA_SKB_CSUM_NOTVERIFIED (1 << 2)
 
 #endif /* _NFNETLINK_QUEUE_H */
 
        skb_shinfo(to)->nr_frags = j;
 }
 
-static int nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet)
+static int
+nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
+                     bool csum_verify)
 {
        __u32 flags = 0;
 
        if (packet->ip_summed == CHECKSUM_PARTIAL)
                flags = NFQA_SKB_CSUMNOTREADY;
+       else if (csum_verify)
+               flags = NFQA_SKB_CSUM_NOTVERIFIED;
+
        if (skb_is_gso(packet))
                flags |= NFQA_SKB_GSO;
 
        struct net_device *outdev;
        struct nf_conn *ct = NULL;
        enum ip_conntrack_info uninitialized_var(ctinfo);
+       bool csum_verify;
 
        size =    nlmsg_total_size(sizeof(struct nfgenmsg))
                + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
        if (entskb->tstamp.tv64)
                size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
 
+       if (entry->hook <= NF_INET_FORWARD ||
+          (entry->hook == NF_INET_POST_ROUTING && entskb->sk == NULL))
+               csum_verify = !skb_csum_unnecessary(entskb);
+       else
+               csum_verify = false;
+
        outdev = entry->outdev;
 
        switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) {
            nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len)))
                goto nla_put_failure;
 
-       if (nfqnl_put_packet_info(skb, entskb))
+       if (nfqnl_put_packet_info(skb, entskb, csum_verify))
                goto nla_put_failure;
 
        if (data_len) {