summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-05-30 18:11:08 +0200
committerDaniel Borkmann <dborkman@redhat.com>2013-05-30 18:11:08 +0200
commit9be74e71213ab2a8d449d1cc6cfa4d533fce0d0f (patch)
treeff2981355231f8f59917d1d5bab55a6f1e1ba5d1
parentc3fec06db030445563d3945eec6320afa9a3db62 (diff)
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 <dborkman@redhat.com>
-rw-r--r--built_in.h4
-rw-r--r--netsniff-ng.c4
-rw-r--r--ring.h7
-rw-r--r--ring_rx.c18
-rw-r--r--ring_rx.h2
-rw-r--r--ring_tx.c4
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)