From: Björn Töpel <bjorn.to...@intel.com>

This patch adds the necessary AF_PACKET V4 structures for usage from
userspace. AF_PACKET V4 is a new interface optimized for high
performance packet processing.

Signed-off-by: Björn Töpel <bjorn.to...@intel.com>
---
 include/uapi/linux/if_packet.h | 65 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h
index 4df96a7dd4fa..8eabcd1b370a 100644
--- a/include/uapi/linux/if_packet.h
+++ b/include/uapi/linux/if_packet.h
@@ -56,6 +56,8 @@ struct sockaddr_ll {
 #define PACKET_QDISC_BYPASS            20
 #define PACKET_ROLLOVER_STATS          21
 #define PACKET_FANOUT_DATA             22
+#define PACKET_MEMREG                  23
+#define PACKET_ZEROCOPY                        24
 
 #define PACKET_FANOUT_HASH             0
 #define PACKET_FANOUT_LB               1
@@ -243,13 +245,35 @@ struct tpacket_block_desc {
        union tpacket_bd_header_u hdr;
 };
 
+#define TP4_DESC_KERNEL        0x0080 /* The descriptor is owned by the kernel 
*/
+#define TP4_PKT_CONT   1 /* The packet continues in the next descriptor */
+
+struct tpacket4_desc {
+       __u32 idx;
+       __u32 len;
+       __u16 offset;
+       __u8  error; /* an errno */
+       __u8  flags;
+       __u8  padding[4];
+};
+
+struct tpacket4_queue {
+       struct tpacket4_desc *ring;
+
+       unsigned int avail_idx;
+       unsigned int last_used_idx;
+       unsigned int num_free;
+       unsigned int ring_mask;
+};
+
 #define TPACKET2_HDRLEN                (TPACKET_ALIGN(sizeof(struct 
tpacket2_hdr)) + sizeof(struct sockaddr_ll))
 #define TPACKET3_HDRLEN                (TPACKET_ALIGN(sizeof(struct 
tpacket3_hdr)) + sizeof(struct sockaddr_ll))
 
 enum tpacket_versions {
        TPACKET_V1,
        TPACKET_V2,
-       TPACKET_V3
+       TPACKET_V3,
+       TPACKET_V4
 };
 
 /*
@@ -282,9 +306,26 @@ struct tpacket_req3 {
        unsigned int    tp_feature_req_word;
 };
 
+/* V4 frame structure
+ *
+ * The v4 frame is contained within a frame defined by
+ * PACKET_MEMREG/struct tpacket_memreg_req. Each frame is frame_size
+ * bytes, and laid out as following:
+ *
+ * - Start.
+ * - Gap, at least data_headroom (from struct tpacket_memreg_req),
+ *   chosen so that packet data (Start+data) is at least 64B aligned.
+ */
+
+struct tpacket_req4 {
+       int             mr_fd;   /* File descriptor for registered buffers */
+       unsigned int    desc_nr; /* Number of entries in descriptor ring */
+};
+
 union tpacket_req_u {
        struct tpacket_req      req;
        struct tpacket_req3     req3;
+       struct tpacket_req4     req4;
 };
 
 struct packet_mreq {
@@ -294,6 +335,28 @@ struct packet_mreq {
        unsigned char   mr_address[8];
 };
 
+/*
+ * struct tpacket_memreg_req is used in conjunction with PACKET_MEMREG
+ * to register user memory which should be used to store the packet
+ * data.
+ *
+ * There are some constraints for the memory being registered:
+ * - The memory area has to be memory page size aligned.
+ * - The frame size has to be a power of 2.
+ * - The frame size cannot be smaller than 2048B.
+ * - The frame size cannot be larger than the memory page size.
+ *
+ * Corollary: The number of frames that can be stored is
+ * len / frame_size.
+ *
+ */
+struct tpacket_memreg_req {
+       unsigned long   addr;           /* Start of packet data area */
+       unsigned long   len;            /* Length of packet data area */
+       unsigned int    frame_size;     /* Frame size */
+       unsigned int    data_headroom;  /* Frame head room */
+};
+
 #define PACKET_MR_MULTICAST    0
 #define PACKET_MR_PROMISC      1
 #define PACKET_MR_ALLMULTI     2
-- 
2.11.0

Reply via email to