diff options
-rw-r--r-- | tools/testing/selftests/net/psock_tpacket.c | 59 |
1 files changed, 20 insertions, 39 deletions
diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c index c41b58640a05..24adf709bd9d 100644 --- a/tools/testing/selftests/net/psock_tpacket.c +++ b/tools/testing/selftests/net/psock_tpacket.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2013 Red Hat, Inc. | 2 | * Copyright 2013 Red Hat, Inc. |
3 | * Author: Daniel Borkmann <dborkman@redhat.com> | 3 | * Author: Daniel Borkmann <dborkman@redhat.com> |
4 | * Chetan Loke <loke.chetan@gmail.com> (TPACKET_V3 usage example) | ||
4 | * | 5 | * |
5 | * A basic test of packet socket's TPACKET_V1/TPACKET_V2/TPACKET_V3 behavior. | 6 | * A basic test of packet socket's TPACKET_V1/TPACKET_V2/TPACKET_V3 behavior. |
6 | * | 7 | * |
@@ -71,18 +72,8 @@ | |||
71 | # define __align_tpacket(x) __attribute__((aligned(TPACKET_ALIGN(x)))) | 72 | # define __align_tpacket(x) __attribute__((aligned(TPACKET_ALIGN(x)))) |
72 | #endif | 73 | #endif |
73 | 74 | ||
74 | #define BLOCK_STATUS(x) ((x)->h1.block_status) | ||
75 | #define BLOCK_NUM_PKTS(x) ((x)->h1.num_pkts) | ||
76 | #define BLOCK_O2FP(x) ((x)->h1.offset_to_first_pkt) | ||
77 | #define BLOCK_LEN(x) ((x)->h1.blk_len) | ||
78 | #define BLOCK_SNUM(x) ((x)->h1.seq_num) | ||
79 | #define BLOCK_O2PRIV(x) ((x)->offset_to_priv) | ||
80 | #define BLOCK_PRIV(x) ((void *) ((uint8_t *) (x) + BLOCK_O2PRIV(x))) | ||
81 | #define BLOCK_HDR_LEN (ALIGN_8(sizeof(struct block_desc))) | ||
82 | #define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1)) | ||
83 | #define BLOCK_PLUS_PRIV(sz_pri) (BLOCK_HDR_LEN + ALIGN_8((sz_pri))) | ||
84 | |||
85 | #define NUM_PACKETS 100 | 75 | #define NUM_PACKETS 100 |
76 | #define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1)) | ||
86 | 77 | ||
87 | struct ring { | 78 | struct ring { |
88 | struct iovec *rd; | 79 | struct iovec *rd; |
@@ -476,41 +467,30 @@ static uint64_t __v3_prev_block_seq_num = 0; | |||
476 | 467 | ||
477 | void __v3_test_block_seq_num(struct block_desc *pbd) | 468 | void __v3_test_block_seq_num(struct block_desc *pbd) |
478 | { | 469 | { |
479 | if (__v3_prev_block_seq_num + 1 != BLOCK_SNUM(pbd)) { | 470 | if (__v3_prev_block_seq_num + 1 != pbd->h1.seq_num) { |
480 | fprintf(stderr, "\nprev_block_seq_num:%"PRIu64", expected " | 471 | fprintf(stderr, "\nprev_block_seq_num:%"PRIu64", expected " |
481 | "seq:%"PRIu64" != actual seq:%"PRIu64"\n", | 472 | "seq:%"PRIu64" != actual seq:%"PRIu64"\n", |
482 | __v3_prev_block_seq_num, __v3_prev_block_seq_num + 1, | 473 | __v3_prev_block_seq_num, __v3_prev_block_seq_num + 1, |
483 | (uint64_t) BLOCK_SNUM(pbd)); | 474 | (uint64_t) pbd->h1.seq_num); |
484 | exit(1); | 475 | exit(1); |
485 | } | 476 | } |
486 | 477 | ||
487 | __v3_prev_block_seq_num = BLOCK_SNUM(pbd); | 478 | __v3_prev_block_seq_num = pbd->h1.seq_num; |
488 | } | 479 | } |
489 | 480 | ||
490 | static void __v3_test_block_len(struct block_desc *pbd, uint32_t bytes, int block_num) | 481 | static void __v3_test_block_len(struct block_desc *pbd, uint32_t bytes, int block_num) |
491 | { | 482 | { |
492 | if (BLOCK_NUM_PKTS(pbd)) { | 483 | if (pbd->h1.num_pkts && bytes != pbd->h1.blk_len) { |
493 | if (bytes != BLOCK_LEN(pbd)) { | 484 | fprintf(stderr, "\nblock:%u with %upackets, expected " |
494 | fprintf(stderr, "\nblock:%u with %upackets, expected " | 485 | "len:%u != actual len:%u\n", block_num, |
495 | "len:%u != actual len:%u\n", block_num, | 486 | pbd->h1.num_pkts, bytes, pbd->h1.blk_len); |
496 | BLOCK_NUM_PKTS(pbd), bytes, BLOCK_LEN(pbd)); | 487 | exit(1); |
497 | exit(1); | ||
498 | } | ||
499 | } else { | ||
500 | if (BLOCK_LEN(pbd) != BLOCK_PLUS_PRIV(13)) { | ||
501 | fprintf(stderr, "\nblock:%u, expected len:%lu != " | ||
502 | "actual len:%u\n", block_num, BLOCK_HDR_LEN, | ||
503 | BLOCK_LEN(pbd)); | ||
504 | exit(1); | ||
505 | } | ||
506 | } | 488 | } |
507 | } | 489 | } |
508 | 490 | ||
509 | static void __v3_test_block_header(struct block_desc *pbd, const int block_num) | 491 | static void __v3_test_block_header(struct block_desc *pbd, const int block_num) |
510 | { | 492 | { |
511 | uint32_t block_status = BLOCK_STATUS(pbd); | 493 | if ((pbd->h1.block_status & TP_STATUS_USER) == 0) { |
512 | |||
513 | if ((block_status & TP_STATUS_USER) == 0) { | ||
514 | fprintf(stderr, "\nblock %u: not in TP_STATUS_USER\n", block_num); | 494 | fprintf(stderr, "\nblock %u: not in TP_STATUS_USER\n", block_num); |
515 | exit(1); | 495 | exit(1); |
516 | } | 496 | } |
@@ -520,14 +500,15 @@ static void __v3_test_block_header(struct block_desc *pbd, const int block_num) | |||
520 | 500 | ||
521 | static void __v3_walk_block(struct block_desc *pbd, const int block_num) | 501 | static void __v3_walk_block(struct block_desc *pbd, const int block_num) |
522 | { | 502 | { |
523 | int num_pkts = BLOCK_NUM_PKTS(pbd), i; | 503 | int num_pkts = pbd->h1.num_pkts, i; |
524 | unsigned long bytes = 0; | 504 | unsigned long bytes = 0, bytes_with_padding = ALIGN_8(sizeof(*pbd)); |
525 | unsigned long bytes_with_padding = BLOCK_PLUS_PRIV(13); | ||
526 | struct tpacket3_hdr *ppd; | 505 | struct tpacket3_hdr *ppd; |
527 | 506 | ||
528 | __v3_test_block_header(pbd, block_num); | 507 | __v3_test_block_header(pbd, block_num); |
529 | 508 | ||
530 | ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd + BLOCK_O2FP(pbd)); | 509 | ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd + |
510 | pbd->h1.offset_to_first_pkt); | ||
511 | |||
531 | for (i = 0; i < num_pkts; ++i) { | 512 | for (i = 0; i < num_pkts; ++i) { |
532 | bytes += ppd->tp_snaplen; | 513 | bytes += ppd->tp_snaplen; |
533 | 514 | ||
@@ -551,7 +532,7 @@ static void __v3_walk_block(struct block_desc *pbd, const int block_num) | |||
551 | 532 | ||
552 | void __v3_flush_block(struct block_desc *pbd) | 533 | void __v3_flush_block(struct block_desc *pbd) |
553 | { | 534 | { |
554 | BLOCK_STATUS(pbd) = TP_STATUS_KERNEL; | 535 | pbd->h1.block_status = TP_STATUS_KERNEL; |
555 | __sync_synchronize(); | 536 | __sync_synchronize(); |
556 | } | 537 | } |
557 | 538 | ||
@@ -577,7 +558,7 @@ static void walk_v3_rx(int sock, struct ring *ring) | |||
577 | while (total_packets < NUM_PACKETS * 2) { | 558 | while (total_packets < NUM_PACKETS * 2) { |
578 | pbd = (struct block_desc *) ring->rd[block_num].iov_base; | 559 | pbd = (struct block_desc *) ring->rd[block_num].iov_base; |
579 | 560 | ||
580 | while ((BLOCK_STATUS(pbd) & TP_STATUS_USER) == 0) | 561 | while ((pbd->h1.block_status & TP_STATUS_USER) == 0) |
581 | poll(&pfd, 1, 1); | 562 | poll(&pfd, 1, 1); |
582 | 563 | ||
583 | __v3_walk_block(pbd, block_num); | 564 | __v3_walk_block(pbd, block_num); |
@@ -624,8 +605,8 @@ static void __v1_v2_fill(struct ring *ring, unsigned int blocks) | |||
624 | static void __v3_fill(struct ring *ring, unsigned int blocks) | 605 | static void __v3_fill(struct ring *ring, unsigned int blocks) |
625 | { | 606 | { |
626 | ring->req3.tp_retire_blk_tov = 64; | 607 | ring->req3.tp_retire_blk_tov = 64; |
627 | ring->req3.tp_sizeof_priv = 13; | 608 | ring->req3.tp_sizeof_priv = 0; |
628 | ring->req3.tp_feature_req_word |= TP_FT_REQ_FILL_RXHASH; | 609 | ring->req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH; |
629 | 610 | ||
630 | ring->req3.tp_block_size = getpagesize() << 2; | 611 | ring->req3.tp_block_size = getpagesize() << 2; |
631 | ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7; | 612 | ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7; |