8
8
#include "test_sockmap_invalid_update.skel.h"
9
9
#include "bpf_iter_sockmap.skel.h"
10
10
11
- #include "progs/bpf_iter_sockmap.h"
12
-
13
11
#define TCP_REPAIR 19 /* TCP sock is under repair right now */
14
12
15
13
#define TCP_REPAIR_ON 1
@@ -50,6 +48,37 @@ static int connected_socket_v4(void)
50
48
return -1 ;
51
49
}
52
50
51
+ static void compare_cookies (struct bpf_map * src , struct bpf_map * dst )
52
+ {
53
+ __u32 i , max_entries = bpf_map__max_entries (src );
54
+ int err , duration = 0 , src_fd , dst_fd ;
55
+
56
+ src_fd = bpf_map__fd (src );
57
+ dst_fd = bpf_map__fd (dst );
58
+
59
+ for (i = 0 ; i < max_entries ; i ++ ) {
60
+ __u64 src_cookie , dst_cookie ;
61
+
62
+ err = bpf_map_lookup_elem (src_fd , & i , & src_cookie );
63
+ if (err && errno == ENOENT ) {
64
+ err = bpf_map_lookup_elem (dst_fd , & i , & dst_cookie );
65
+ CHECK (!err , "map_lookup_elem(dst)" , "element %u not deleted\n" , i );
66
+ CHECK (err && errno != ENOENT , "map_lookup_elem(dst)" , "%s\n" ,
67
+ strerror (errno ));
68
+ continue ;
69
+ }
70
+ if (CHECK (err , "lookup_elem(src)" , "%s\n" , strerror (errno )))
71
+ continue ;
72
+
73
+ err = bpf_map_lookup_elem (dst_fd , & i , & dst_cookie );
74
+ if (CHECK (err , "lookup_elem(dst)" , "%s\n" , strerror (errno )))
75
+ continue ;
76
+
77
+ CHECK (dst_cookie != src_cookie , "cookie mismatch" ,
78
+ "%llu != %llu (pos %u)\n" , dst_cookie , src_cookie , i );
79
+ }
80
+ }
81
+
53
82
/* Create a map, populate it with one socket, and free the map. */
54
83
static void test_sockmap_create_update_free (enum bpf_map_type map_type )
55
84
{
@@ -109,9 +138,9 @@ static void test_skmsg_helpers(enum bpf_map_type map_type)
109
138
static void test_sockmap_update (enum bpf_map_type map_type )
110
139
{
111
140
struct bpf_prog_test_run_attr tattr ;
112
- int err , prog , src , dst , duration = 0 ;
141
+ int err , prog , src , duration = 0 ;
113
142
struct test_sockmap_update * skel ;
114
- __u64 src_cookie , dst_cookie ;
143
+ struct bpf_map * dst_map ;
115
144
const __u32 zero = 0 ;
116
145
char dummy [14 ] = {0 };
117
146
__s64 sk ;
@@ -127,18 +156,14 @@ static void test_sockmap_update(enum bpf_map_type map_type)
127
156
prog = bpf_program__fd (skel -> progs .copy_sock_map );
128
157
src = bpf_map__fd (skel -> maps .src );
129
158
if (map_type == BPF_MAP_TYPE_SOCKMAP )
130
- dst = bpf_map__fd ( skel -> maps .dst_sock_map ) ;
159
+ dst_map = skel -> maps .dst_sock_map ;
131
160
else
132
- dst = bpf_map__fd ( skel -> maps .dst_sock_hash ) ;
161
+ dst_map = skel -> maps .dst_sock_hash ;
133
162
134
163
err = bpf_map_update_elem (src , & zero , & sk , BPF_NOEXIST );
135
164
if (CHECK (err , "update_elem(src)" , "errno=%u\n" , errno ))
136
165
goto out ;
137
166
138
- err = bpf_map_lookup_elem (src , & zero , & src_cookie );
139
- if (CHECK (err , "lookup_elem(src, cookie)" , "errno=%u\n" , errno ))
140
- goto out ;
141
-
142
167
tattr = (struct bpf_prog_test_run_attr ){
143
168
.prog_fd = prog ,
144
169
.repeat = 1 ,
@@ -151,12 +176,7 @@ static void test_sockmap_update(enum bpf_map_type map_type)
151
176
"errno=%u retval=%u\n" , errno , tattr .retval ))
152
177
goto out ;
153
178
154
- err = bpf_map_lookup_elem (dst , & zero , & dst_cookie );
155
- if (CHECK (err , "lookup_elem(dst, cookie)" , "errno=%u\n" , errno ))
156
- goto out ;
157
-
158
- CHECK (dst_cookie != src_cookie , "cookie mismatch" , "%llu != %llu\n" ,
159
- dst_cookie , src_cookie );
179
+ compare_cookies (skel -> maps .src , dst_map );
160
180
161
181
out :
162
182
test_sockmap_update__destroy (skel );
@@ -174,14 +194,14 @@ static void test_sockmap_invalid_update(void)
174
194
test_sockmap_invalid_update__destroy (skel );
175
195
}
176
196
177
- static void test_sockmap_iter (enum bpf_map_type map_type )
197
+ static void test_sockmap_copy (enum bpf_map_type map_type )
178
198
{
179
199
DECLARE_LIBBPF_OPTS (bpf_iter_attach_opts , opts );
180
200
int err , len , src_fd , iter_fd , duration = 0 ;
181
201
union bpf_iter_link_info linfo = {0 };
182
- __s64 sock_fd [SOCKMAP_MAX_ENTRIES ];
183
- __u32 i , num_sockets , max_elems ;
202
+ __u32 i , num_sockets , num_elems ;
184
203
struct bpf_iter_sockmap * skel ;
204
+ __s64 * sock_fd = NULL ;
185
205
struct bpf_link * link ;
186
206
struct bpf_map * src ;
187
207
char buf [64 ];
@@ -190,22 +210,23 @@ static void test_sockmap_iter(enum bpf_map_type map_type)
190
210
if (CHECK (!skel , "bpf_iter_sockmap__open_and_load" , "skeleton open_and_load failed\n" ))
191
211
return ;
192
212
193
- for (i = 0 ; i < ARRAY_SIZE (sock_fd ); i ++ )
194
- sock_fd [i ] = -1 ;
195
-
196
- /* Make sure we have at least one "empty" entry to test iteration of
197
- * an empty slot.
198
- */
199
- num_sockets = ARRAY_SIZE (sock_fd ) - 1 ;
200
-
201
213
if (map_type == BPF_MAP_TYPE_SOCKMAP ) {
202
214
src = skel -> maps .sockmap ;
203
- max_elems = bpf_map__max_entries (src );
215
+ num_elems = bpf_map__max_entries (src );
216
+ num_sockets = num_elems - 1 ;
204
217
} else {
205
218
src = skel -> maps .sockhash ;
206
- max_elems = num_sockets ;
219
+ num_elems = bpf_map__max_entries (src ) - 1 ;
220
+ num_sockets = num_elems ;
207
221
}
208
222
223
+ sock_fd = calloc (num_sockets , sizeof (* sock_fd ));
224
+ if (CHECK (!sock_fd , "calloc(sock_fd)" , "failed to allocate\n" ))
225
+ goto out ;
226
+
227
+ for (i = 0 ; i < num_sockets ; i ++ )
228
+ sock_fd [i ] = -1 ;
229
+
209
230
src_fd = bpf_map__fd (src );
210
231
211
232
for (i = 0 ; i < num_sockets ; i ++ ) {
@@ -221,7 +242,7 @@ static void test_sockmap_iter(enum bpf_map_type map_type)
221
242
linfo .map .map_fd = src_fd ;
222
243
opts .link_info = & linfo ;
223
244
opts .link_info_len = sizeof (linfo );
224
- link = bpf_program__attach_iter (skel -> progs .count_elems , & opts );
245
+ link = bpf_program__attach_iter (skel -> progs .copy , & opts );
225
246
if (CHECK (IS_ERR (link ), "attach_iter" , "attach_iter failed\n" ))
226
247
goto out ;
227
248
@@ -236,23 +257,26 @@ static void test_sockmap_iter(enum bpf_map_type map_type)
236
257
goto close_iter ;
237
258
238
259
/* test results */
239
- if (CHECK (skel -> bss -> elems != max_elems , "elems" , "got %u expected %u\n" ,
240
- skel -> bss -> elems , max_elems ))
260
+ if (CHECK (skel -> bss -> elems != num_elems , "elems" , "got %u expected %u\n" ,
261
+ skel -> bss -> elems , num_elems ))
241
262
goto close_iter ;
242
263
243
264
if (CHECK (skel -> bss -> socks != num_sockets , "socks" , "got %u expected %u\n" ,
244
265
skel -> bss -> socks , num_sockets ))
245
266
goto close_iter ;
246
267
268
+ compare_cookies (src , skel -> maps .dst );
269
+
247
270
close_iter :
248
271
close (iter_fd );
249
272
free_link :
250
273
bpf_link__destroy (link );
251
274
out :
252
- for (i = 0 ; i < num_sockets ; i ++ ) {
275
+ for (i = 0 ; sock_fd && i < num_sockets ; i ++ )
253
276
if (sock_fd [i ] >= 0 )
254
277
close (sock_fd [i ]);
255
- }
278
+ if (sock_fd )
279
+ free (sock_fd );
256
280
bpf_iter_sockmap__destroy (skel );
257
281
}
258
282
@@ -272,8 +296,8 @@ void test_sockmap_basic(void)
272
296
test_sockmap_update (BPF_MAP_TYPE_SOCKHASH );
273
297
if (test__start_subtest ("sockmap update in unsafe context" ))
274
298
test_sockmap_invalid_update ();
275
- if (test__start_subtest ("sockmap iter " ))
276
- test_sockmap_iter (BPF_MAP_TYPE_SOCKMAP );
277
- if (test__start_subtest ("sockhash iter " ))
278
- test_sockmap_iter (BPF_MAP_TYPE_SOCKHASH );
299
+ if (test__start_subtest ("sockmap copy " ))
300
+ test_sockmap_copy (BPF_MAP_TYPE_SOCKMAP );
301
+ if (test__start_subtest ("sockhash copy " ))
302
+ test_sockmap_copy (BPF_MAP_TYPE_SOCKHASH );
279
303
}
0 commit comments