From 2f39b007d5382d01fc424e22b8e1a3681c2bc8cf Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 31 May 2013 11:18:36 +0200 Subject: ring: implement setup of tpacket v3 ring Implement ring setup routines and structures for TPACKET_V3. Signed-off-by: Daniel Borkmann --- ring.h | 18 ++++++++++++++++++ ring_rx.c | 10 +++++++--- ring_rx.h | 5 +++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ring.h b/ring.h index f618a35..7590223 100644 --- a/ring.h +++ b/ring.h @@ -45,6 +45,7 @@ struct ring { union { struct tpacket_req layout; struct tpacket_req3 layout3; + uint8_t raw; }; }; @@ -113,6 +114,18 @@ static inline void __set_sockopt_tpacket(int sock, int val) panic("Cannot set tpacketv2!\n"); } +static inline int __get_sockopt_tpacket(int sock) +{ + int val, ret; + socklen_t len = sizeof(val); + + ret = getsockopt(sock, SOL_PACKET, PACKET_VERSION, &val, &len); + if (ret) + panic("Cannot set tpacketv2!\n"); + + return val; +} + static inline void set_sockopt_tpacket_v2(int sock) { __set_sockopt_tpacket(sock, TPACKET_V2); @@ -123,4 +136,9 @@ static inline void set_sockopt_tpacket_v3(int sock) __set_sockopt_tpacket(sock, TPACKET_V3); } +static inline int get_sockopt_tpacket(int sock) +{ + return __get_sockopt_tpacket(sock); +} + #endif /* RING_H */ diff --git a/ring_rx.c b/ring_rx.c index fc735cc..a3d8e4d 100644 --- a/ring_rx.c +++ b/ring_rx.c @@ -57,6 +57,10 @@ void setup_rx_ring_layout(int sock, struct ring *ring, unsigned int size, sizeof(struct tpacket_req) != offsetof(struct tpacket_req3, tp_retire_blk_tov)); + ring->layout3.tp_retire_blk_tov = 0; + ring->layout3.tp_sizeof_priv = 0; + ring->layout3.tp_feature_req_word = 0; + set_sockopt_tpacket_v3(sock); } else { set_sockopt_tpacket_v2(sock); @@ -68,10 +72,11 @@ void setup_rx_ring_layout(int sock, struct ring *ring, unsigned int size, void create_rx_ring(int sock, struct ring *ring, int verbose) { int ret; + bool v3 = get_sockopt_tpacket(sock) == TPACKET_V3; retry: - ret = setsockopt(sock, SOL_PACKET, PACKET_RX_RING, &ring->layout, - sizeof(ring->layout)); + ret = setsockopt(sock, SOL_PACKET, PACKET_RX_RING, &ring->raw, + v3 ? sizeof(ring->layout3) : sizeof(ring->layout)); if (errno == ENOMEM && ring->layout.tp_block_nr > 1) { ring->layout.tp_block_nr >>= 1; ring->layout.tp_frame_nr = ring->layout.tp_block_size / @@ -79,7 +84,6 @@ retry: ring->layout.tp_block_nr; goto retry; } - if (ret < 0) panic("Cannot allocate RX_RING!\n"); diff --git a/ring_rx.h b/ring_rx.h index b1114a6..0a2701f 100644 --- a/ring_rx.h +++ b/ring_rx.h @@ -23,6 +23,11 @@ static inline int user_may_pull_from_rx(struct tpacket2_hdr *hdr) return ((hdr->tp_status & TP_STATUS_USER) == TP_STATUS_USER); } +static inline int user_may_pull_from_rx_block(struct block_desc *pbd) +{ + return ((pbd->h1.block_status & TP_STATUS_USER) == TP_STATUS_USER); +} + static inline void kernel_may_pull_from_rx(struct tpacket2_hdr *hdr) { hdr->tp_status = TP_STATUS_KERNEL; -- cgit v1.2.3-54-g00ecf