aboutsummaryrefslogtreecommitdiff
path: root/net/psock_tpacket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/psock_tpacket.c')
-rw-r--r--net/psock_tpacket.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/net/psock_tpacket.c b/net/psock_tpacket.c
index 24adf70..c41b586 100644
--- a/net/psock_tpacket.c
+++ b/net/psock_tpacket.c
@@ -1,7 +1,6 @@
/*
* Copyright 2013 Red Hat, Inc.
* Author: Daniel Borkmann <dborkman@redhat.com>
- * Chetan Loke <loke.chetan@gmail.com> (TPACKET_V3 usage example)
*
* A basic test of packet socket's TPACKET_V1/TPACKET_V2/TPACKET_V3 behavior.
*
@@ -72,8 +71,18 @@
# define __align_tpacket(x) __attribute__((aligned(TPACKET_ALIGN(x))))
#endif
-#define NUM_PACKETS 100
+#define BLOCK_STATUS(x) ((x)->h1.block_status)
+#define BLOCK_NUM_PKTS(x) ((x)->h1.num_pkts)
+#define BLOCK_O2FP(x) ((x)->h1.offset_to_first_pkt)
+#define BLOCK_LEN(x) ((x)->h1.blk_len)
+#define BLOCK_SNUM(x) ((x)->h1.seq_num)
+#define BLOCK_O2PRIV(x) ((x)->offset_to_priv)
+#define BLOCK_PRIV(x) ((void *) ((uint8_t *) (x) + BLOCK_O2PRIV(x)))
+#define BLOCK_HDR_LEN (ALIGN_8(sizeof(struct block_desc)))
#define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1))
+#define BLOCK_PLUS_PRIV(sz_pri) (BLOCK_HDR_LEN + ALIGN_8((sz_pri)))
+
+#define NUM_PACKETS 100
struct ring {
struct iovec *rd;
@@ -467,30 +476,41 @@ static uint64_t __v3_prev_block_seq_num = 0;
void __v3_test_block_seq_num(struct block_desc *pbd)
{
- if (__v3_prev_block_seq_num + 1 != pbd->h1.seq_num) {
+ if (__v3_prev_block_seq_num + 1 != BLOCK_SNUM(pbd)) {
fprintf(stderr, "\nprev_block_seq_num:%"PRIu64", expected "
"seq:%"PRIu64" != actual seq:%"PRIu64"\n",
__v3_prev_block_seq_num, __v3_prev_block_seq_num + 1,
- (uint64_t) pbd->h1.seq_num);
+ (uint64_t) BLOCK_SNUM(pbd));
exit(1);
}
- __v3_prev_block_seq_num = pbd->h1.seq_num;
+ __v3_prev_block_seq_num = BLOCK_SNUM(pbd);
}
static void __v3_test_block_len(struct block_desc *pbd, uint32_t bytes, int block_num)
{
- if (pbd->h1.num_pkts && bytes != pbd->h1.blk_len) {
- fprintf(stderr, "\nblock:%u with %upackets, expected "
- "len:%u != actual len:%u\n", block_num,
- pbd->h1.num_pkts, bytes, pbd->h1.blk_len);
- exit(1);
+ if (BLOCK_NUM_PKTS(pbd)) {
+ if (bytes != BLOCK_LEN(pbd)) {
+ fprintf(stderr, "\nblock:%u with %upackets, expected "
+ "len:%u != actual len:%u\n", block_num,
+ BLOCK_NUM_PKTS(pbd), bytes, BLOCK_LEN(pbd));
+ exit(1);
+ }
+ } else {
+ if (BLOCK_LEN(pbd) != BLOCK_PLUS_PRIV(13)) {
+ fprintf(stderr, "\nblock:%u, expected len:%lu != "
+ "actual len:%u\n", block_num, BLOCK_HDR_LEN,
+ BLOCK_LEN(pbd));
+ exit(1);
+ }
}
}
static void __v3_test_block_header(struct block_desc *pbd, const int block_num)
{
- if ((pbd->h1.block_status & TP_STATUS_USER) == 0) {
+ uint32_t block_status = BLOCK_STATUS(pbd);
+
+ if ((block_status & TP_STATUS_USER) == 0) {
fprintf(stderr, "\nblock %u: not in TP_STATUS_USER\n", block_num);
exit(1);
}
@@ -500,15 +520,14 @@ static void __v3_test_block_header(struct block_desc *pbd, const int block_num)
static void __v3_walk_block(struct block_desc *pbd, const int block_num)
{
- int num_pkts = pbd->h1.num_pkts, i;
- unsigned long bytes = 0, bytes_with_padding = ALIGN_8(sizeof(*pbd));
+ int num_pkts = BLOCK_NUM_PKTS(pbd), i;
+ unsigned long bytes = 0;
+ unsigned long bytes_with_padding = BLOCK_PLUS_PRIV(13);
struct tpacket3_hdr *ppd;
__v3_test_block_header(pbd, block_num);
- ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd +
- pbd->h1.offset_to_first_pkt);
-
+ ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd + BLOCK_O2FP(pbd));
for (i = 0; i < num_pkts; ++i) {
bytes += ppd->tp_snaplen;
@@ -532,7 +551,7 @@ static void __v3_walk_block(struct block_desc *pbd, const int block_num)
void __v3_flush_block(struct block_desc *pbd)
{
- pbd->h1.block_status = TP_STATUS_KERNEL;
+ BLOCK_STATUS(pbd) = TP_STATUS_KERNEL;
__sync_synchronize();
}
@@ -558,7 +577,7 @@ static void walk_v3_rx(int sock, struct ring *ring)
while (total_packets < NUM_PACKETS * 2) {
pbd = (struct block_desc *) ring->rd[block_num].iov_base;
- while ((pbd->h1.block_status & TP_STATUS_USER) == 0)
+ while ((BLOCK_STATUS(pbd) & TP_STATUS_USER) == 0)
poll(&pfd, 1, 1);
__v3_walk_block(pbd, block_num);
@@ -605,8 +624,8 @@ static void __v1_v2_fill(struct ring *ring, unsigned int blocks)
static void __v3_fill(struct ring *ring, unsigned int blocks)
{
ring->req3.tp_retire_blk_tov = 64;
- ring->req3.tp_sizeof_priv = 0;
- ring->req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
+ ring->req3.tp_sizeof_priv = 13;
+ ring->req3.tp_feature_req_word |= TP_FT_REQ_FILL_RXHASH;
ring->req3.tp_block_size = getpagesize() << 2;
ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7;