hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/samples/bpf/xdp1_user.c
....@@ -1,8 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* Copyright (c) 2016 PLUMgrid
2
- *
3
- * This program is free software; you can redistribute it and/or
4
- * modify it under the terms of version 2 of the GNU General Public
5
- * License as published by the Free Software Foundation.
63 */
74 #include <linux/bpf.h>
85 #include <linux/if_link.h>
....@@ -15,17 +12,30 @@
1512 #include <unistd.h>
1613 #include <libgen.h>
1714 #include <sys/resource.h>
15
+#include <net/if.h>
1816
1917 #include "bpf_util.h"
20
-#include "bpf/bpf.h"
21
-#include "bpf/libbpf.h"
18
+#include <bpf/bpf.h>
19
+#include <bpf/libbpf.h>
2220
2321 static int ifindex;
24
-static __u32 xdp_flags;
22
+static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
23
+static __u32 prog_id;
2524
2625 static void int_exit(int sig)
2726 {
28
- bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
27
+ __u32 curr_prog_id = 0;
28
+
29
+ if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
30
+ printf("bpf_get_link_xdp_id failed\n");
31
+ exit(1);
32
+ }
33
+ if (prog_id == curr_prog_id)
34
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
35
+ else if (!curr_prog_id)
36
+ printf("couldn't find a prog id on a given interface\n");
37
+ else
38
+ printf("program on interface changed, not removing\n");
2939 exit(0);
3040 }
3141
....@@ -34,26 +44,24 @@
3444 static void poll_stats(int map_fd, int interval)
3545 {
3646 unsigned int nr_cpus = bpf_num_possible_cpus();
37
- const unsigned int nr_keys = 256;
38
- __u64 values[nr_cpus], prev[nr_keys][nr_cpus];
39
- __u32 key;
47
+ __u64 values[nr_cpus], prev[UINT8_MAX] = { 0 };
4048 int i;
4149
42
- memset(prev, 0, sizeof(prev));
43
-
4450 while (1) {
51
+ __u32 key = UINT32_MAX;
52
+
4553 sleep(interval);
4654
47
- for (key = 0; key < nr_keys; key++) {
55
+ while (bpf_map_get_next_key(map_fd, &key, &key) != -1) {
4856 __u64 sum = 0;
4957
5058 assert(bpf_map_lookup_elem(map_fd, &key, values) == 0);
5159 for (i = 0; i < nr_cpus; i++)
52
- sum += (values[i] - prev[key][i]);
53
- if (sum)
60
+ sum += values[i];
61
+ if (sum > prev[key])
5462 printf("proto %u: %10llu pkt/s\n",
55
- key, sum / interval);
56
- memcpy(prev[key], values, sizeof(values));
63
+ key, (sum - prev[key]) / interval);
64
+ prev[key] = sum;
5765 }
5866 }
5967 }
....@@ -61,10 +69,11 @@
6169 static void usage(const char *prog)
6270 {
6371 fprintf(stderr,
64
- "usage: %s [OPTS] IFINDEX\n\n"
72
+ "usage: %s [OPTS] IFACE\n\n"
6573 "OPTS:\n"
6674 " -S use skb-mode\n"
67
- " -N enforce native mode\n",
75
+ " -N enforce native mode\n"
76
+ " -F force loading prog\n",
6877 prog);
6978 }
7079
....@@ -74,11 +83,14 @@
7483 struct bpf_prog_load_attr prog_load_attr = {
7584 .prog_type = BPF_PROG_TYPE_XDP,
7685 };
77
- const char *optstr = "SN";
86
+ struct bpf_prog_info info = {};
87
+ __u32 info_len = sizeof(info);
88
+ const char *optstr = "FSN";
7889 int prog_fd, map_fd, opt;
7990 struct bpf_object *obj;
8091 struct bpf_map *map;
8192 char filename[256];
93
+ int err;
8294
8395 while ((opt = getopt(argc, argv, optstr)) != -1) {
8496 switch (opt) {
....@@ -86,13 +98,19 @@
8698 xdp_flags |= XDP_FLAGS_SKB_MODE;
8799 break;
88100 case 'N':
89
- xdp_flags |= XDP_FLAGS_DRV_MODE;
101
+ /* default, set below */
102
+ break;
103
+ case 'F':
104
+ xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
90105 break;
91106 default:
92107 usage(basename(argv[0]));
93108 return 1;
94109 }
95110 }
111
+
112
+ if (!(xdp_flags & XDP_FLAGS_SKB_MODE))
113
+ xdp_flags |= XDP_FLAGS_DRV_MODE;
96114
97115 if (optind == argc) {
98116 usage(basename(argv[0]));
....@@ -104,7 +122,11 @@
104122 return 1;
105123 }
106124
107
- ifindex = strtoul(argv[optind], NULL, 0);
125
+ ifindex = if_nametoindex(argv[optind]);
126
+ if (!ifindex) {
127
+ perror("if_nametoindex");
128
+ return 1;
129
+ }
108130
109131 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
110132 prog_load_attr.file = filename;
....@@ -120,7 +142,7 @@
120142 map_fd = bpf_map__fd(map);
121143
122144 if (!prog_fd) {
123
- printf("load_bpf_file: %s\n", strerror(errno));
145
+ printf("bpf_prog_load_xattr: %s\n", strerror(errno));
124146 return 1;
125147 }
126148
....@@ -132,6 +154,13 @@
132154 return 1;
133155 }
134156
157
+ err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
158
+ if (err) {
159
+ printf("can't get prog info - %s\n", strerror(errno));
160
+ return err;
161
+ }
162
+ prog_id = info.id;
163
+
135164 poll_stats(map_fd, 2);
136165
137166 return 0;