|
@@ -50,6 +50,7 @@
|
|
|
#include <linux/filter.h>
|
|
|
#include <linux/bpf.h>
|
|
|
#include <linux/if_packet.h>
|
|
|
+#include <net/if.h>
|
|
|
#include <net/ethernet.h>
|
|
|
#include <netinet/ip.h>
|
|
|
#include <netinet/udp.h>
|
|
@@ -73,14 +74,29 @@
|
|
|
* @return -1 if mode is bad, a valid socket otherwise */
|
|
|
static int sock_fanout_open(uint16_t typeflags, uint16_t group_id)
|
|
|
{
|
|
|
+ struct sockaddr_ll addr = {0};
|
|
|
int fd, val;
|
|
|
|
|
|
- fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
|
|
|
+ fd = socket(PF_PACKET, SOCK_RAW, 0);
|
|
|
if (fd < 0) {
|
|
|
perror("socket packet");
|
|
|
exit(1);
|
|
|
}
|
|
|
|
|
|
+ pair_udp_setfilter(fd);
|
|
|
+
|
|
|
+ addr.sll_family = AF_PACKET;
|
|
|
+ addr.sll_protocol = htons(ETH_P_IP);
|
|
|
+ addr.sll_ifindex = if_nametoindex("lo");
|
|
|
+ if (addr.sll_ifindex == 0) {
|
|
|
+ perror("if_nametoindex");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ if (bind(fd, (void *) &addr, sizeof(addr))) {
|
|
|
+ perror("bind packet");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+
|
|
|
val = (((int) typeflags) << 16) | group_id;
|
|
|
if (setsockopt(fd, SOL_PACKET, PACKET_FANOUT, &val, sizeof(val))) {
|
|
|
if (close(fd)) {
|
|
@@ -90,7 +106,6 @@ static int sock_fanout_open(uint16_t typeflags, uint16_t group_id)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- pair_udp_setfilter(fd);
|
|
|
return fd;
|
|
|
}
|
|
|
|
|
@@ -229,7 +244,7 @@ static int sock_fanout_read(int fds[], char *rings[], const int expect[])
|
|
|
|
|
|
if ((!(ret[0] == expect[0] && ret[1] == expect[1])) &&
|
|
|
(!(ret[0] == expect[1] && ret[1] == expect[0]))) {
|
|
|
- fprintf(stderr, "ERROR: incorrect queue lengths\n");
|
|
|
+ fprintf(stderr, "warning: incorrect queue lengths\n");
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -348,7 +363,8 @@ static int test_datapath(uint16_t typeflags, int port_off,
|
|
|
uint8_t type = typeflags & 0xFF;
|
|
|
int fds[2], fds_udp[2][2], ret;
|
|
|
|
|
|
- fprintf(stderr, "test: datapath 0x%hx\n", typeflags);
|
|
|
+ fprintf(stderr, "\ntest: datapath 0x%hx ports %hu,%hu\n",
|
|
|
+ typeflags, PORT_BASE, PORT_BASE + port_off);
|
|
|
|
|
|
fds[0] = sock_fanout_open(typeflags, 0);
|
|
|
fds[1] = sock_fanout_open(typeflags, 0);
|
|
@@ -419,7 +435,7 @@ int main(int argc, char **argv)
|
|
|
const int expect_cpu1[2][2] = { { 0, 20 }, { 0, 20 } };
|
|
|
const int expect_bpf[2][2] = { { 15, 5 }, { 15, 20 } };
|
|
|
const int expect_uniqueid[2][2] = { { 20, 20}, { 20, 20 } };
|
|
|
- int port_off = 2, tries = 5, ret;
|
|
|
+ int port_off = 2, tries = 20, ret;
|
|
|
|
|
|
test_control_single();
|
|
|
test_control_group();
|
|
@@ -428,10 +444,14 @@ int main(int argc, char **argv)
|
|
|
/* find a set of ports that do not collide onto the same socket */
|
|
|
ret = test_datapath(PACKET_FANOUT_HASH, port_off,
|
|
|
expect_hash[0], expect_hash[1]);
|
|
|
- while (ret && tries--) {
|
|
|
+ while (ret) {
|
|
|
fprintf(stderr, "info: trying alternate ports (%d)\n", tries);
|
|
|
ret = test_datapath(PACKET_FANOUT_HASH, ++port_off,
|
|
|
expect_hash[0], expect_hash[1]);
|
|
|
+ if (!--tries) {
|
|
|
+ fprintf(stderr, "too many collisions\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
ret |= test_datapath(PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_ROLLOVER,
|