From 9be74e71213ab2a8d449d1cc6cfa4d533fce0d0f Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Thu, 30 May 2013 18:11:08 +0200 Subject: ring: prepare setup_rx_ring_layout for support in v2/v3 Prepare setup_rx_ring_layout for both, v2 and v3. Also do some checks during compile time if offsets stay the same as we operate on different union mappings. Signed-off-by: Daniel Borkmann --- built_in.h | 4 ++++ netsniff-ng.c | 4 ++-- ring.h | 7 +++++++ ring_rx.c | 18 +++++++++++++----- ring_rx.h | 2 +- ring_tx.c | 4 +--- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/built_in.h b/built_in.h index fa2f0c8..ea81257 100644 --- a/built_in.h +++ b/built_in.h @@ -153,6 +153,10 @@ typedef uint8_t u8; # define build_bug_on_zero(e) (sizeof(char[1 - 2 * !!(e)]) - 1) #endif +#ifndef build_bug_on +# define build_bug_on(e) ((void)sizeof(char[1 - 2*!!(e)])) +#endif + #ifndef bug_on # define bug_on(cond) assert(!(cond)) #endif diff --git a/netsniff-ng.c b/netsniff-ng.c index 7070873..76fafed 100644 --- a/netsniff-ng.c +++ b/netsniff-ng.c @@ -372,7 +372,7 @@ static void receive_to_xmit(struct ctx *ctx) bpf_dump_all(&bpf_ops); bpf_attach_to_sock(rx_sock, &bpf_ops); - setup_rx_ring_layout(rx_sock, &rx_ring, size_in, ctx->jumbo); + setup_rx_ring_layout(rx_sock, &rx_ring, size_in, ctx->jumbo, false); create_rx_ring(rx_sock, &rx_ring, ctx->verbose); mmap_rx_ring(rx_sock, &rx_ring); alloc_rx_ring_frames(&rx_ring); @@ -851,7 +851,7 @@ static void recv_only_or_dump(struct ctx *ctx) set_sockopt_hwtimestamp(sock, ctx->device_in); - setup_rx_ring_layout(sock, &rx_ring, size, ctx->jumbo); + setup_rx_ring_layout(sock, &rx_ring, size, ctx->jumbo, false); create_rx_ring(sock, &rx_ring, ctx->verbose); mmap_rx_ring(sock, &rx_ring); alloc_rx_ring_frames(&rx_ring); diff --git a/ring.h b/ring.h index 5e47d37..f618a35 100644 --- a/ring.h +++ b/ring.h @@ -82,6 +82,13 @@ static inline unsigned int ring_frame_size(struct ring *ring) return ring->layout.tp_frame_size; } +static inline void ring_verify_layout(struct ring *ring) +{ + bug_on(ring->layout.tp_block_size < ring->layout.tp_frame_size); + bug_on((ring->layout.tp_block_size % ring->layout.tp_frame_size) != 0); + bug_on((ring->layout.tp_block_size % getpagesize()) != 0); +} + static inline void tpacket_hdr_clone(struct tpacket2_hdr *thdrd, struct tpacket2_hdr *thdrs) { diff --git a/ring_rx.c b/ring_rx.c index 27c87d3..12ce086 100644 --- a/ring_rx.c +++ b/ring_rx.c @@ -36,7 +36,7 @@ void destroy_rx_ring(int sock, struct ring *ring) } void setup_rx_ring_layout(int sock, struct ring *ring, unsigned int size, - int jumbo_support) + int jumbo_support, bool v3) { fmemset(&ring->layout, 0, sizeof(ring->layout)); @@ -50,17 +50,25 @@ void setup_rx_ring_layout(int sock, struct ring *ring, unsigned int size, ring->layout.tp_frame_nr = ring->layout.tp_block_size / ring->layout.tp_frame_size * ring->layout.tp_block_nr; + if (v3) { + /* Pass out, if this will ever change and we do crap on it! */ + build_bug_on(offsetof(struct tpacket_req, tp_frame_nr) != + offsetof(struct tpacket_req3, tp_frame_nr) && + sizeof(struct tpacket_req) != + offsetof(struct tpacket_req3, tp_retire_blk_tov)); + + set_sockopt_tpacket_v3(sock); + } else { + set_sockopt_tpacket_v2(sock); + } - bug_on(ring->layout.tp_block_size < ring->layout.tp_frame_size); - bug_on((ring->layout.tp_block_size % ring->layout.tp_frame_size) != 0); - bug_on((ring->layout.tp_block_size % getpagesize()) != 0); + ring_verify_layout(ring); } void create_rx_ring(int sock, struct ring *ring, int verbose) { int ret; - set_sockopt_tpacket_v2(sock); retry: ret = setsockopt(sock, SOL_PACKET, PACKET_RX_RING, &ring->layout, sizeof(ring->layout)); diff --git a/ring_rx.h b/ring_rx.h index 0e0478c..8556e3a 100644 --- a/ring_rx.h +++ b/ring_rx.h @@ -16,7 +16,7 @@ extern void mmap_rx_ring(int sock, struct ring *ring); extern void alloc_rx_ring_frames(struct ring *ring); extern void bind_rx_ring(int sock, struct ring *ring, int ifindex); extern void setup_rx_ring_layout(int sock, struct ring *ring, - unsigned int size, int jumbo_support); + unsigned int size, int jumbo_support, bool v3); static inline int user_may_pull_from_rx(struct tpacket2_hdr *hdr) { diff --git a/ring_tx.c b/ring_tx.c index f91f7f7..b7cde7e 100644 --- a/ring_tx.c +++ b/ring_tx.c @@ -61,9 +61,7 @@ void setup_tx_ring_layout(int sock, struct ring *ring, unsigned int size, ring->layout.tp_frame_size * ring->layout.tp_block_nr; - bug_on(ring->layout.tp_block_size < ring->layout.tp_frame_size); - bug_on((ring->layout.tp_block_size % ring->layout.tp_frame_size) != 0); - bug_on((ring->layout.tp_block_size % getpagesize()) != 0); + ring_verify_layout(ring); } void create_tx_ring(int sock, struct ring *ring, int verbose) -- cgit v1.2.3-54-g00ecf