src: add new GSO handling capabilities
authorFlorian Westphal <fw@strlen.de>
Fri, 26 Apr 2013 08:21:16 +0000 (10:21 +0200)
committerr.kubiak <r.kubiak@samsung.com>
Mon, 16 Nov 2015 13:12:06 +0000 (14:12 +0100)
allows userspace to ask for large gso packets via nfqueue.

Signed-off-by: Florian Westphal <fw@strlen.de>
include/libnetfilter_queue/linux_nfnetlink_queue.h
include/linux/netfilter/nfnetlink_queue.h
src/libnetfilter_queue.c
src/nlmsg.c

index 58c8ca5..81a485b 100644 (file)
@@ -45,6 +45,10 @@ enum nfqnl_attr_type {
        NFQA_IFINDEX_PHYSOUTDEV,        /* u_int32_t ifindex */
        NFQA_HWADDR,                    /* nfqnl_msg_packet_hw */
        NFQA_PAYLOAD,                   /* opaque data payload */
+       NFQA_CT,                        /* nf_conntrack_netlink.h */
+       NFQA_CT_INFO,                   /* enum ip_conntrack_info */
+       NFQA_CAP_LEN,                   /* __u32 length of captured packet */
+       NFQA_SKB_INFO,                  /* __u32 skb meta information */
 
        __NFQA_MAX
 };
@@ -96,6 +100,13 @@ enum nfqnl_attr_config {
 /* Flags/options for NFQA_CFG_FLAGS */
 #define NFQA_CFG_F_FAIL_OPEN           (1 << 0)
 #define NFQA_CFG_F_CONNTRACK           (1 << 1)
-#define NFQA_CFG_F_MAX                 (1 << 2)
+#define NFQA_CFG_F_GSO                 (1 << 2)
+#define NFQA_CFG_F_MAX                 (1 << 3)
+
+/* flags for NFQA_SKB_INFO */
+/* packet appears to have wrong checksums, but they are ok */
+#define NFQA_SKB_CSUMNOTREADY (1 << 0)
+/* packet is GSO (i.e., exceeds device mtu) */
+#define NFQA_SKB_GSO (1 << 1)
 
 #endif /* _NFNETLINK_QUEUE_H */
index da44b33..a2308ae 100644 (file)
@@ -44,6 +44,8 @@ enum nfqnl_attr_type {
        NFQA_PAYLOAD,                   /* opaque data payload */
        NFQA_CT,                        /* nf_conntrack_netlink.h */
        NFQA_CT_INFO,                   /* enum ip_conntrack_info */
+       NFQA_CAP_LEN,                   /* __u32 length of captured packet */
+       NFQA_SKB_INFO,                  /* __u32 skb meta information */
 
        __NFQA_MAX
 };
@@ -80,19 +82,28 @@ struct nfqnl_msg_config_params {
        __u8    copy_mode;      /* enum nfqnl_config_mode */
 } __attribute__ ((packed));
 
-enum nfqnl_flags {
-       NFQNL_F_NONE            = 0,
-       NFQNL_F_CONNTRACK       = (1 << 0),
-};
 
 enum nfqnl_attr_config {
        NFQA_CFG_UNSPEC,
        NFQA_CFG_CMD,                   /* nfqnl_msg_config_cmd */
        NFQA_CFG_PARAMS,                /* nfqnl_msg_config_params */
        NFQA_CFG_QUEUE_MAXLEN,          /* __u32 */
-       NFQA_CFG_FLAGS,                 /* __u32 */
+       NFQA_CFG_MASK,                  /* identify which flags to change */
+       NFQA_CFG_FLAGS,                 /* value of these flags (__u32) */
        __NFQA_CFG_MAX
 };
 #define NFQA_CFG_MAX (__NFQA_CFG_MAX-1)
 
+/* Flags for NFQA_CFG_FLAGS */
+#define NFQA_CFG_F_FAIL_OPEN                   (1 << 0)
+#define NFQA_CFG_F_CONNTRACK                   (1 << 1)
+#define NFQA_CFG_F_GSO                         (1 << 2)
+#define NFQA_CFG_F_MAX                         (1 << 3)
+
+/* flags for NFQA_SKB_INFO */
+/* packet appears to have wrong checksums, but they are ok */
+#define NFQA_SKB_CSUMNOTREADY (1 << 0)
+/* packet is GSO (i.e., exceeds device mtu) */
+#define NFQA_SKB_GSO (1 << 1)
+
 #endif /* _NFNETLINK_QUEUE_H */
index bf944f0..6817957 100644 (file)
@@ -640,6 +640,23 @@ int nfq_set_mode(struct nfq_q_handle *qh,
  * - NFQA_CFG_F_CONNTRACK (requires Linux kernel >= 3.6): the kernel will
  *   include the Connection Tracking system information.
  *
+ * - NFQA_CFG_F_GSO (requires Linux kernel >= 3.10): the kernel will
+ *   not normalize offload packets, i.e. your application will need to
+ *   be able to handle packets larger than the mtu (up to 64k).
+ *
+ *   If your application validates checksums (e.g., tcp checksum),
+ *   then you must also check if the NFQA_SKB_INFO attribute is present.
+ *   If it is, you need to test the NFQA_SKB_CSUMNOTREADY bit:
+ * \verbatim
+       if (attr[NFQA_SKB_INFO]) {
+               uint32_t info = ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO]));
+               if (info & NFQA_SKB_CSUMNOTREADY)
+                       validate_checksums = false;
+       }
+\endverbatim
+ *  if this bit is set, the layer 3/4 checksums of the packet appear incorrect,
+ *  but are not (because they will be corrected later by the kernel).
+ *
  * Here's a little code snippet to show how to use this API:
  * \verbatim
        uint32_t flags = NFQA_CFG_F_FAIL_OPEN;
index 6c4a139..e7a30e0 100644 (file)
@@ -132,6 +132,8 @@ static int nfq_pkt_parse_attr_cb(const struct nlattr *attr, void *data)
        case NFQA_IFINDEX_OUTDEV:
        case NFQA_IFINDEX_PHYSINDEV:
        case NFQA_IFINDEX_PHYSOUTDEV:
+       case NFQA_CAP_LEN:
+       case NFQA_SKB_INFO:
                if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
                        return MNL_CB_ERROR;
                break;