hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/samples/bpf/xdp_adjust_tail_user.c
....@@ -13,23 +13,38 @@
1313 #include <stdio.h>
1414 #include <stdlib.h>
1515 #include <string.h>
16
+#include <net/if.h>
1617 #include <sys/resource.h>
1718 #include <arpa/inet.h>
1819 #include <netinet/ether.h>
1920 #include <unistd.h>
2021 #include <time.h>
21
-#include "bpf/bpf.h"
22
-#include "bpf/libbpf.h"
22
+#include <bpf/bpf.h>
23
+#include <bpf/libbpf.h>
2324
2425 #define STATS_INTERVAL_S 2U
26
+#define MAX_PCKT_SIZE 600
2527
2628 static int ifindex = -1;
27
-static __u32 xdp_flags;
29
+static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
30
+static __u32 prog_id;
2831
2932 static void int_exit(int sig)
3033 {
31
- if (ifindex > -1)
32
- bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
34
+ __u32 curr_prog_id = 0;
35
+
36
+ if (ifindex > -1) {
37
+ if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
38
+ printf("bpf_get_link_xdp_id failed\n");
39
+ exit(1);
40
+ }
41
+ if (prog_id == curr_prog_id)
42
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
43
+ else if (!curr_prog_id)
44
+ printf("couldn't find a prog id on a given iface\n");
45
+ else
46
+ printf("program on interface changed, not removing\n");
47
+ }
3348 exit(0);
3449 }
3550
....@@ -56,10 +71,12 @@
5671 printf("Start a XDP prog which send ICMP \"packet too big\" \n"
5772 "messages if ingress packet is bigger then MAX_SIZE bytes\n");
5873 printf("Usage: %s [...]\n", cmd);
59
- printf(" -i <ifindex> Interface Index\n");
74
+ printf(" -i <ifname|ifindex> Interface\n");
6075 printf(" -T <stop-after-X-seconds> Default: 0 (forever)\n");
76
+ printf(" -P <MAX_PCKT_SIZE> Default: %u\n", MAX_PCKT_SIZE);
6177 printf(" -S use skb-mode\n");
6278 printf(" -N enforce native mode\n");
79
+ printf(" -F force loading prog\n");
6380 printf(" -h Display this help\n");
6481 }
6582
....@@ -70,12 +87,16 @@
7087 .prog_type = BPF_PROG_TYPE_XDP,
7188 };
7289 unsigned char opt_flags[256] = {};
90
+ const char *optstr = "i:T:P:SNFh";
91
+ struct bpf_prog_info info = {};
92
+ __u32 info_len = sizeof(info);
7393 unsigned int kill_after_s = 0;
74
- const char *optstr = "i:T:SNh";
7594 int i, prog_fd, map_fd, opt;
7695 struct bpf_object *obj;
77
- struct bpf_map *map;
96
+ __u32 max_pckt_size = 0;
97
+ __u32 key = 0;
7898 char filename[256];
99
+ int err;
79100
80101 for (i = 0; i < strlen(optstr); i++)
81102 if (optstr[i] != 'h' && 'a' <= optstr[i] && optstr[i] <= 'z')
....@@ -85,16 +106,24 @@
85106
86107 switch (opt) {
87108 case 'i':
88
- ifindex = atoi(optarg);
109
+ ifindex = if_nametoindex(optarg);
110
+ if (!ifindex)
111
+ ifindex = atoi(optarg);
89112 break;
90113 case 'T':
91114 kill_after_s = atoi(optarg);
115
+ break;
116
+ case 'P':
117
+ max_pckt_size = atoi(optarg);
92118 break;
93119 case 'S':
94120 xdp_flags |= XDP_FLAGS_SKB_MODE;
95121 break;
96122 case 'N':
97
- xdp_flags |= XDP_FLAGS_DRV_MODE;
123
+ /* default, set below */
124
+ break;
125
+ case 'F':
126
+ xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
98127 break;
99128 default:
100129 usage(argv[0]);
....@@ -102,6 +131,9 @@
102131 }
103132 opt_flags[opt] = 0;
104133 }
134
+
135
+ if (!(xdp_flags & XDP_FLAGS_SKB_MODE))
136
+ xdp_flags |= XDP_FLAGS_DRV_MODE;
105137
106138 for (i = 0; i < strlen(optstr); i++) {
107139 if (opt_flags[(unsigned int)optstr[i]]) {
....@@ -116,21 +148,31 @@
116148 return 1;
117149 }
118150
151
+ if (!ifindex) {
152
+ fprintf(stderr, "Invalid ifname\n");
153
+ return 1;
154
+ }
155
+
119156 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
120157 prog_load_attr.file = filename;
121158
122159 if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
123160 return 1;
124161
125
- map = bpf_map__next(NULL, obj);
126
- if (!map) {
127
- printf("finding a map in obj file failed\n");
128
- return 1;
162
+ /* static global var 'max_pcktsz' is accessible from .data section */
163
+ if (max_pckt_size) {
164
+ map_fd = bpf_object__find_map_fd_by_name(obj, "xdp_adju.data");
165
+ if (map_fd < 0) {
166
+ printf("finding a max_pcktsz map in obj file failed\n");
167
+ return 1;
168
+ }
169
+ bpf_map_update_elem(map_fd, &key, &max_pckt_size, BPF_ANY);
129170 }
130
- map_fd = bpf_map__fd(map);
131171
132
- if (!prog_fd) {
133
- printf("load_bpf_file: %s\n", strerror(errno));
172
+ /* fetch icmpcnt map */
173
+ map_fd = bpf_object__find_map_fd_by_name(obj, "icmpcnt");
174
+ if (map_fd < 0) {
175
+ printf("finding a icmpcnt map in obj file failed\n");
134176 return 1;
135177 }
136178
....@@ -142,9 +184,15 @@
142184 return 1;
143185 }
144186
145
- poll_stats(map_fd, kill_after_s);
187
+ err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
188
+ if (err) {
189
+ printf("can't get prog info - %s\n", strerror(errno));
190
+ return 1;
191
+ }
192
+ prog_id = info.id;
146193
147
- bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
194
+ poll_stats(map_fd, kill_after_s);
195
+ int_exit(0);
148196
149197 return 0;
150198 }