static void int_exit(int sig) { set_link_xdp_fd(ifindex_in, -1, xdp_flags); if (ifindex_out_xdp_dummy_attached) set_link_xdp_fd(ifindex_out, -1, xdp_flags); exit(0); }
int main(int ac, char **argv) { char filename[256]; snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); if (ac != 2) { printf("usage: %s IFINDEX\n", argv[0]); return 1; } ifindex = strtoul(argv[1], NULL, 0); if (load_bpf_file(filename)) { printf("%s", bpf_log_buf); return 1; } if (!prog_fd[0]) { printf("load_bpf_file: %s\n", strerror(errno)); return 1; } signal(SIGINT, int_exit); if (set_link_xdp_fd(ifindex, prog_fd[0]) < 0) { printf("link set xdp fd failed\n"); return 1; } poll_stats(2); return 0; }
static void int_exit(int sig) { fprintf(stderr, "Interrupted: Removing XDP program on ifindex:%d device:%s\n", ifindex, ifname); if (ifindex > -1) set_link_xdp_fd(ifindex, -1, xdp_flags); exit(EXIT_OK); }
static void remove_xdp_program(int ifindex, const char *ifname, __u32 xdp_flags) { int i; fprintf(stderr, "Removing XDP program on ifindex:%d device:%s\n", ifindex, ifname); if (ifindex > -1) set_link_xdp_fd(ifindex, -1, xdp_flags); /* Remove all exported map file */ for (i = 0; i < NR_MAPS; i++) { const char *file = map_idx_to_export_filename(i); if (unlink(file) < 0) { printf("WARN: cannot rm map(%s) file:%s err(%d):%s\n", map_data[i].name, file, errno, strerror(errno)); } } }
int main(int argc, char **argv) { const char *optstr = "SN"; char filename[256]; int ret, opt, key = 0; while ((opt = getopt(argc, argv, optstr)) != -1) { switch (opt) { case 'S': xdp_flags |= XDP_FLAGS_SKB_MODE; break; case 'N': xdp_flags |= XDP_FLAGS_DRV_MODE; break; default: usage(basename(argv[0])); return 1; } } if (optind == argc) { printf("usage: %s IFINDEX_IN IFINDEX_OUT\n", argv[0]); return 1; } ifindex_in = strtoul(argv[optind], NULL, 0); ifindex_out = strtoul(argv[optind + 1], NULL, 0); printf("input: %d output: %d\n", ifindex_in, ifindex_out); snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); if (load_bpf_file(filename)) { printf("%s", bpf_log_buf); return 1; } if (!prog_fd[0]) { printf("load_bpf_file: %s\n", strerror(errno)); return 1; } if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) { printf("ERROR: link set xdp fd failed on %d\n", ifindex_in); return 1; } /* Loading dummy XDP prog on out-device */ if (set_link_xdp_fd(ifindex_out, prog_fd[1], (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { printf("WARN: link set xdp fd failed on %d\n", ifindex_out); ifindex_out_xdp_dummy_attached = false; } signal(SIGINT, int_exit); signal(SIGTERM, int_exit); printf("map[0] (vports) = %i, map[1] (map) = %i, map[2] (count) = %i\n", map_fd[0], map_fd[1], map_fd[2]); /* populate virtual to physical port map */ ret = bpf_map_update_elem(map_fd[0], &key, &ifindex_out, 0); if (ret) { perror("bpf_update_elem"); goto out; } poll_stats(2, ifindex_out); out: return 0; }
static void int_exit(int sig) { set_link_xdp_fd(ifindex, -1); exit(0); }
int main(int argc, char **argv) { struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; bool rm_xdp_prog = false; struct passwd *pwd = NULL; __u32 xdp_flags = 0; char filename[256]; int longindex = 0; uid_t owner = -1; /* -1 result in no-change of owner */ gid_t group = -1; int opt; snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); /* Parse commands line args */ while ((opt = getopt_long(argc, argv, "hSrqd:", long_options, &longindex)) != -1) { switch (opt) { case 'q': verbose = 0; break; case 'r': rm_xdp_prog = true; break; case 'o': /* extract owner and group from username */ if (!(pwd = getpwnam(optarg))) { fprintf(stderr, "ERR: unknown owner:%s err(%d):%s\n", optarg, errno, strerror(errno)); goto error; } owner = pwd->pw_uid; group = pwd->pw_gid; break; case 'd': if (strlen(optarg) >= IF_NAMESIZE) { fprintf(stderr, "ERR: --dev name too long\n"); goto error; } ifname = (char *)&ifname_buf; strncpy(ifname, optarg, IF_NAMESIZE); ifindex = if_nametoindex(ifname); if (ifindex == 0) { fprintf(stderr, "ERR: --dev name unknown err(%d):%s\n", errno, strerror(errno)); goto error; } break; case 'S': xdp_flags |= XDP_FLAGS_SKB_MODE; break; case 'h': error: default: usage(argv); return EXIT_FAIL_OPTION; } } /* Required options */ if (ifindex == -1) { printf("ERR: required option --dev missing"); usage(argv); return EXIT_FAIL_OPTION; } if (rm_xdp_prog) { remove_xdp_program(ifindex, ifname, xdp_flags); return EXIT_OK; } if (verbose) { printf("Documentation:\n%s\n", __doc__); printf(" - Attached to device:%s (ifindex:%d)\n", ifname, ifindex); } /* Increase resource limits */ if (setrlimit(RLIMIT_MEMLOCK, &r)) { perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)"); return 1; } /* Load bpf-ELF file with callback for loading maps via filesystem */ if (load_bpf_file_fixup_map(filename, pre_load_maps_via_fs)) { fprintf(stderr, "ERR in load_bpf_file(): %s", bpf_log_buf); return EXIT_FAIL; } if (!prog_fd[0]) { printf("load_bpf_file: %s\n", strerror(errno)); return 1; } /* Export maps that were not loaded from filesystem */ export_maps(); if (owner >= 0) chown_maps(owner, group); if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) { printf("link set xdp fd failed\n"); return EXIT_FAIL_XDP; } /* Add something to the map as a test */ blacklist_modify(map_fd[0], "198.18.50.3", ACTION_ADD); blacklist_port_modify(map_fd[2], map_fd[4], 80, ACTION_ADD, IPPROTO_UDP); return EXIT_OK; }