6
6
#include "test_skmsg_load_helpers.skel.h"
7
7
#include "test_sockmap_update.skel.h"
8
8
#include "test_sockmap_invalid_update.skel.h"
9
+ #include "bpf_iter_sockmap.skel.h"
10
+
11
+ #include "progs/bpf_iter_sockmap.h"
9
12
10
13
#define TCP_REPAIR 19 /* TCP sock is under repair right now */
11
14
@@ -193,6 +196,87 @@ static void test_sockmap_invalid_update(void)
193
196
test_sockmap_invalid_update__destroy (skel );
194
197
}
195
198
199
+ static void test_sockmap_copy (enum bpf_map_type map_type )
200
+ {
201
+ DECLARE_LIBBPF_OPTS (bpf_iter_attach_opts , opts );
202
+ int err , len , src_fd , iter_fd , duration ;
203
+ union bpf_iter_link_info linfo = {0 };
204
+ __s64 sock_fd [SOCKMAP_MAX_ENTRIES ];
205
+ __u32 i , num_sockets , max_elems ;
206
+ struct bpf_iter_sockmap * skel ;
207
+ struct bpf_map * src , * dst ;
208
+ struct bpf_link * link ;
209
+ char buf [64 ];
210
+
211
+ skel = bpf_iter_sockmap__open_and_load ();
212
+ if (CHECK (!skel , "bpf_iter_sockmap__open_and_load" , "skeleton open_and_load failed\n" ))
213
+ return ;
214
+
215
+ for (i = 0 ; i < ARRAY_SIZE (sock_fd ); i ++ )
216
+ sock_fd [i ] = -1 ;
217
+
218
+ /* Make sure we have at least one "empty" entry to test iteration of
219
+ * an empty slot in an array.
220
+ */
221
+ num_sockets = ARRAY_SIZE (sock_fd ) - 1 ;
222
+
223
+ if (map_type == BPF_MAP_TYPE_SOCKMAP ) {
224
+ src = skel -> maps .sockmap ;
225
+ max_elems = bpf_map__max_entries (src );
226
+ } else {
227
+ src = skel -> maps .sockhash ;
228
+ max_elems = num_sockets ;
229
+ }
230
+
231
+ dst = skel -> maps .dst ;
232
+ src_fd = bpf_map__fd (src );
233
+
234
+ for (i = 0 ; i < num_sockets ; i ++ ) {
235
+ sock_fd [i ] = connected_socket_v4 ();
236
+ if (CHECK (sock_fd [i ] == -1 , "connected_socket_v4" , "cannot connect\n" ))
237
+ goto out ;
238
+
239
+ err = bpf_map_update_elem (src_fd , & i , & sock_fd [i ], BPF_NOEXIST );
240
+ if (CHECK (err , "map_update" , "failed: %s\n" , strerror (errno )))
241
+ goto out ;
242
+ }
243
+
244
+ linfo .map .map_fd = src_fd ;
245
+ opts .link_info = & linfo ;
246
+ opts .link_info_len = sizeof (linfo );
247
+ link = bpf_program__attach_iter (skel -> progs .copy_sockmap , & opts );
248
+ if (CHECK (IS_ERR (link ), "attach_iter" , "attach_iter failed\n" ))
249
+ goto out ;
250
+
251
+ iter_fd = bpf_iter_create (bpf_link__fd (link ));
252
+ if (CHECK (iter_fd < 0 , "create_iter" , "create_iter failed\n" ))
253
+ goto free_link ;
254
+
255
+ /* do some tests */
256
+ while ((len = read (iter_fd , buf , sizeof (buf ))) > 0 )
257
+ ;
258
+ if (CHECK (len < 0 , "read" , "failed: %s\n" , strerror (errno )))
259
+ goto close_iter ;
260
+
261
+ /* test results */
262
+ if (CHECK (skel -> bss -> elems != max_elems , "elems" , "got %u expected %u\n" ,
263
+ skel -> bss -> elems , max_elems ))
264
+ goto close_iter ;
265
+
266
+ compare_cookies (src , dst );
267
+
268
+ close_iter :
269
+ close (iter_fd );
270
+ free_link :
271
+ bpf_link__destroy (link );
272
+ out :
273
+ for (i = 0 ; i < num_sockets ; i ++ ) {
274
+ if (sock_fd [i ] >= 0 )
275
+ close (sock_fd [i ]);
276
+ }
277
+ bpf_iter_sockmap__destroy (skel );
278
+ }
279
+
196
280
void test_sockmap_basic (void )
197
281
{
198
282
if (test__start_subtest ("sockmap create_update_free" ))
@@ -209,4 +293,8 @@ void test_sockmap_basic(void)
209
293
test_sockmap_update (BPF_MAP_TYPE_SOCKHASH );
210
294
if (test__start_subtest ("sockmap update in unsafe context" ))
211
295
test_sockmap_invalid_update ();
296
+ if (test__start_subtest ("sockmap copy" ))
297
+ test_sockmap_copy (BPF_MAP_TYPE_SOCKMAP );
298
+ if (test__start_subtest ("sockhash copy" ))
299
+ test_sockmap_copy (BPF_MAP_TYPE_SOCKHASH );
212
300
}
0 commit comments