// SPDX-License-Identifier: GPL-2.0 /* * Test functionality of BPF filters with SO_REUSEPORT. This program creates * an SO_REUSEPORT receiver group containing one socket per CPU core. It then * creates a BPF program that will select a socket from this group based * on the core id that receives the packet. The sending code artificially * moves itself to run on different core ids and sends one message from * each core. Since these packets are delivered over loopback, they should * arrive on the same core that sent them. The receiving code then ensures * that the packet was received on the socket for the corresponding core id. * This entire process is done for several different core id permutations * and for each IPv4/IPv6 and TCP/UDP combination.
*/
memset(&cpu_set, 0, sizeof(cpu_set));
CPU_SET(cpu_id, &cpu_set); if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0)
error(1, errno, "failed to pin to cpu");
fd = socket(family, proto, 0); if (fd < 0)
error(1, errno, "failed to create send socket");
if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)))
error(1, errno, "failed to bind send socket");
if (connect(fd, (struct sockaddr *)&daddr, sizeof(daddr)))
error(1, errno, "failed to connect send socket");
if (send(fd, "a", 1, 0) < 0)
error(1, errno, "failed to send message");
close(fd);
}
static void receive_on_cpu(int *rcv_fd, int len, int epfd, int cpu_id, int proto)
{ struct epoll_event ev; int i, fd; char buf[8];
i = epoll_wait(epfd, &ev, 1, -1); if (i < 0)
error(1, errno, "epoll_wait failed");
if (proto == SOCK_STREAM) {
fd = accept(ev.data.fd, NULL, NULL); if (fd < 0)
error(1, errno, "failed to accept");
i = recv(fd, buf, sizeof(buf), 0);
close(fd);
} else {
i = recv(ev.data.fd, buf, sizeof(buf), 0);
}
if (i < 0)
error(1, errno, "failed to recv");
for (i = 0; i < len; ++i) if (ev.data.fd == rcv_fd[i]) break; if (i == len)
error(1, 0, "failed to find socket");
fprintf(stderr, "send cpu %d, receive socket %d\n", cpu_id, i); if (cpu_id != i)
error(1, 0, "cpu id/receive socket mismatch");
}
staticvoid test(int *rcv_fd, int len, int family, int proto)
{ struct epoll_event ev; int epfd, cpu;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.