|
103 | 103 | #include <errno.h>
|
104 | 104 | #include <unistd.h>
|
105 | 105 | #include <poll.h>
|
| 106 | +#include <linux/filter.h> |
106 | 107 | #include <linux/if.h>
|
107 | 108 | #include <linux/if_packet.h>
|
108 | 109 | #include <linux/if_ether.h>
|
@@ -601,6 +602,41 @@ bcmlu_tpacket_netif_bind(int sock_fd, bcmlu_tpacket_t *tp)
|
601 | 602 | SHR_FUNC_EXIT();
|
602 | 603 | }
|
603 | 604 |
|
| 605 | +static int |
| 606 | +bcmlu_tpacket_socket_install_filter(int sock_fd, bcmlu_tpacket_t *tp) |
| 607 | +{ |
| 608 | + // Set Berkeley Packet Filter (BPF) for the socket. The filters here are |
| 609 | + // copied directly from Stratum. No need to change anything here. |
| 610 | + const struct sock_filter filters[] = { |
| 611 | + // 0. Retrieve "packet type" (see <netpacket/packet.h> for types) from |
| 612 | + // linux-specific magical negative offset |
| 613 | + {0x28, 0, 0, 0xfffff004}, |
| 614 | + // 1. Branch if equal to 4 (PACKET_OUTGOING). Go to 2 if so, 3 otherwise. |
| 615 | + {0x15, 0, 1, 0x00000004}, |
| 616 | + // 2. Return 0 (ignore packet) |
| 617 | + {0x6, 0, 0, 0x00000000}, |
| 618 | + // 3. Return 65535 (capture entire packet) |
| 619 | + {0x6, 0, 0, 0x0000ffff}, |
| 620 | + }; |
| 621 | + const struct sock_fprog fprog = { |
| 622 | + sizeof(filters) / sizeof(filters[0]), |
| 623 | + (struct sock_filter*) filters, |
| 624 | + }; |
| 625 | + |
| 626 | + SHR_FUNC_ENTER(BSL_UNIT_UNKNOWN); |
| 627 | + SHR_NULL_CHECK(tp, SHR_E_PARAM); |
| 628 | + |
| 629 | + if (setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, |
| 630 | + sizeof(fprog)) < 0) { |
| 631 | + SHR_IF_ERR_MSG_EXIT |
| 632 | + (SHR_E_FAIL, |
| 633 | + (BSL_META_U(tp->unit, "setsockopt SO_ATTACH_FILTER error\n"))); |
| 634 | + } |
| 635 | + |
| 636 | +exit: |
| 637 | + SHR_FUNC_EXIT(); |
| 638 | +} |
| 639 | + |
604 | 640 | static int
|
605 | 641 | bcmlu_tpacket_socket_create(bcmlu_tpacket_t *tp)
|
606 | 642 | {
|
@@ -647,6 +683,10 @@ bcmlu_tpacket_socket_create(bcmlu_tpacket_t *tp)
|
647 | 683 | (BSL_META_U(tp->unit, "Open netif %s\n"), tp->netif.name));
|
648 | 684 | #endif
|
649 | 685 |
|
| 686 | + /*! Install BPF filter. */ |
| 687 | + SHR_IF_ERR_EXIT |
| 688 | + (bcmlu_tpacket_socket_install_filter(sock_fd, tp)); |
| 689 | + |
650 | 690 | /*! Bind socket to the netif. */
|
651 | 691 | SHR_IF_ERR_EXIT
|
652 | 692 | (bcmlu_tpacket_netif_bind(sock_fd, tp));
|
@@ -1043,6 +1083,7 @@ bcmlu_tpacket_packet_handle(bcmlu_tpacket_t *tp,
|
1043 | 1083 | data[17] == (rhdr->ethertype & 0xFF)) {
|
1044 | 1084 | if (data[18] != (rhdr->signature >> 8) ||
|
1045 | 1085 | data[19] != (rhdr->signature & 0xFF) ||
|
| 1086 | +// data[20] != BCMPKT_RCPU_OP_TX || |
1046 | 1087 | data[20] != BCMPKT_RCPU_OP_RX ||
|
1047 | 1088 | data[21] != BCMPKT_RCPU_F_MODHDR) {
|
1048 | 1089 | ring->rcpu_hdr_err++;
|
|
0 commit comments