#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>
  * @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)) {
                return -1;
        }
 
-       pair_udp_setfilter(fd);
        return fd;
 }
 
 
        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;
        }
 
        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);
        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();
        /* 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,