in bpf/xdpsock_user.c [1885:2024]
int main(int argc, char **argv)
{
struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
struct __user_cap_data_struct data[2] = { { 0 } };
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
bool rx = false, tx = false;
struct sched_param schparam;
struct xsk_umem_info *umem;
struct bpf_object *obj;
int xsks_map_fd = 0;
pthread_t pt;
int i, ret;
void *bufs;
parse_command_line(argc, argv);
if (opt_reduced_cap) {
if (capget(&hdr, data) < 0)
fprintf(stderr, "Error getting capabilities\n");
data->effective &= CAP_TO_MASK(CAP_NET_RAW);
data->permitted &= CAP_TO_MASK(CAP_NET_RAW);
if (capset(&hdr, data) < 0)
fprintf(stderr, "Setting capabilities failed\n");
if (capget(&hdr, data) < 0) {
fprintf(stderr, "Error getting capabilities\n");
} else {
fprintf(stderr, "Capabilities EFF %x Caps INH %x Caps Per %x\n",
data[0].effective, data[0].inheritable, data[0].permitted);
fprintf(stderr, "Capabilities EFF %x Caps INH %x Caps Per %x\n",
data[1].effective, data[1].inheritable, data[1].permitted);
}
} else {
if (setrlimit(RLIMIT_MEMLOCK, &r)) {
fprintf(stderr, "ERROR: setrlimit(RLIMIT_MEMLOCK) \"%s\"\n",
strerror(errno));
exit(EXIT_FAILURE);
}
if (opt_num_xsks > 1)
load_xdp_program(argv, &obj);
}
/* Reserve memory for the umem. Use hugepages if unaligned chunk mode */
bufs = mmap(NULL, NUM_FRAMES * opt_xsk_frame_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | opt_mmap_flags, -1, 0);
if (bufs == MAP_FAILED) {
printf("ERROR: mmap failed\n");
exit(EXIT_FAILURE);
}
/* Create sockets... */
umem = xsk_configure_umem(bufs, NUM_FRAMES * opt_xsk_frame_size);
if (opt_bench == BENCH_RXDROP || opt_bench == BENCH_L2FWD) {
rx = true;
xsk_populate_fill_ring(umem);
}
if (opt_bench == BENCH_L2FWD || opt_bench == BENCH_TXONLY)
tx = true;
for (i = 0; i < opt_num_xsks; i++)
xsks[num_socks++] = xsk_configure_socket(umem, rx, tx);
for (i = 0; i < opt_num_xsks; i++)
apply_setsockopt(xsks[i]);
if (opt_bench == BENCH_TXONLY) {
if (opt_tstamp && opt_pkt_size < PKTGEN_SIZE_MIN)
opt_pkt_size = PKTGEN_SIZE_MIN;
gen_eth_hdr_data();
for (i = 0; i < NUM_FRAMES; i++)
gen_eth_frame(umem, i * opt_xsk_frame_size);
}
if (opt_num_xsks > 1 && opt_bench != BENCH_TXONLY)
enter_xsks_into_map(obj);
if (opt_reduced_cap) {
ret = recv_xsks_map_fd(&xsks_map_fd);
if (ret) {
fprintf(stderr, "Error %d receiving xsks_map_fd\n", ret);
exit_with_error(ret);
}
if (xsks[0]->xsk) {
ret = xsk_socket__update_xskmap(xsks[0]->xsk, xsks_map_fd);
if (ret) {
fprintf(stderr, "Update of BPF map failed(%d)\n", ret);
exit_with_error(ret);
}
}
}
signal(SIGINT, int_exit);
signal(SIGTERM, int_exit);
signal(SIGABRT, int_exit);
setlocale(LC_ALL, "");
if (!opt_quiet) {
ret = pthread_create(&pt, NULL, poller, NULL);
if (ret)
exit_with_error(ret);
}
prev_time = get_nsecs();
start_time = prev_time;
/* Configure sched priority for better wake-up accuracy */
memset(&schparam, 0, sizeof(schparam));
schparam.sched_priority = opt_schprio;
ret = sched_setscheduler(0, opt_schpolicy, &schparam);
if (ret) {
fprintf(stderr, "Error(%d) in setting priority(%d): %s\n",
errno, opt_schprio, strerror(errno));
goto out;
}
if (opt_bench == BENCH_RXDROP)
rx_drop_all();
else if (opt_bench == BENCH_TXONLY)
tx_only_all();
else
l2fwd_all();
out:
benchmark_done = true;
if (!opt_quiet)
pthread_join(pt, NULL);
xdpsock_cleanup();
munmap(bufs, NUM_FRAMES * opt_xsk_frame_size);
return 0;
}