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; }
int main(int argc, char **argv) { unsigned char opt_flags[256] = {}; unsigned int kill_after_s = 0; const char *optstr = "i:a:p:s:d:m:T:P:SNh"; int min_port = 0, max_port = 0; struct iptnl_info tnl = {}; struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; struct vip vip = {}; char filename[256]; int opt; int i; tnl.family = AF_UNSPEC; vip.protocol = IPPROTO_TCP; for (i = 0; i < strlen(optstr); i++) if (optstr[i] != 'h' && 'a' <= optstr[i] && optstr[i] <= 'z') opt_flags[(unsigned char)optstr[i]] = 1; while ((opt = getopt(argc, argv, optstr)) != -1) { unsigned short family; unsigned int *v6; switch (opt) { case 'i': ifindex = atoi(optarg); break; case 'a': vip.family = parse_ipstr(optarg, vip.daddr.v6); if (vip.family == AF_UNSPEC) return 1; break; case 'p': if (parse_ports(optarg, &min_port, &max_port)) return 1; break; case 'P': vip.protocol = atoi(optarg); break; case 's': case 'd': if (opt == 's') v6 = tnl.saddr.v6; else v6 = tnl.daddr.v6; family = parse_ipstr(optarg, v6); if (family == AF_UNSPEC) return 1; if (tnl.family == AF_UNSPEC) { tnl.family = family; } else if (tnl.family != family) { fprintf(stderr, "The IP version of the src and dst addresses used in the IP encapsulation does not match\n"); return 1; } break; case 'm': if (!ether_aton_r(optarg, (struct ether_addr *)tnl.dmac)) { fprintf(stderr, "Invalid mac address:%s\n", optarg); return 1; } break; case 'T': kill_after_s = atoi(optarg); break; case 'S': xdp_flags |= XDP_FLAGS_SKB_MODE; break; case 'N': xdp_flags |= XDP_FLAGS_DRV_MODE; break; default: usage(argv[0]); return 1; } opt_flags[opt] = 0; } for (i = 0; i < strlen(optstr); i++) { if (opt_flags[(unsigned int)optstr[i]]) { fprintf(stderr, "Missing argument -%c\n", optstr[i]); usage(argv[0]); return 1; } } if (setrlimit(RLIMIT_MEMLOCK, &r)) { perror("setrlimit(RLIMIT_MEMLOCK, RLIM_INFINITY)"); return 1; } 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; } signal(SIGINT, int_exit); signal(SIGTERM, int_exit); while (min_port <= max_port) { vip.dport = htons(min_port++); if (bpf_map_update_elem(map_fd[1], &vip, &tnl, BPF_NOEXIST)) { perror("bpf_map_update_elem(&vip2tnl)"); return 1; } } if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) { printf("link set xdp fd failed\n"); return 1; } poll_stats(kill_after_s); bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); return 0; }
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; }