88#include "test_sockmap_invalid_update.skel.h"
99#include "bpf_iter_sockmap.skel.h"
1010
11- #include "progs/bpf_iter_sockmap.h"
12-
1311#define TCP_REPAIR 19/* TCP sock is under repair right now */
1412
1513#define TCP_REPAIR_ON 1
@@ -50,6 +48,37 @@ static int connected_socket_v4(void)
5048return -1 ;
5149}
5250
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+
5382/* Create a map, populate it with one socket, and free the map. */
5483static void test_sockmap_create_update_free (enum bpf_map_type map_type )
5584{
@@ -109,9 +138,9 @@ static void test_skmsg_helpers(enum bpf_map_type map_type)
109138static void test_sockmap_update (enum bpf_map_type map_type )
110139{
111140struct bpf_prog_test_run_attr tattr ;
112- int err , prog , src , dst , duration = 0 ;
141+ int err , prog , src , duration = 0 ;
113142struct test_sockmap_update * skel ;
114- __u64 src_cookie , dst_cookie ;
143+ struct bpf_map * dst_map ;
115144const __u32 zero = 0 ;
116145char dummy [14 ] = {0 };
117146__s64 sk ;
@@ -127,18 +156,14 @@ static void test_sockmap_update(enum bpf_map_type map_type)
127156prog = bpf_program__fd (skel -> progs .copy_sock_map );
128157src = bpf_map__fd (skel -> maps .src );
129158if (map_type == BPF_MAP_TYPE_SOCKMAP )
130- dst = bpf_map__fd ( skel -> maps .dst_sock_map ) ;
159+ dst_map = skel -> maps .dst_sock_map ;
131160else
132- dst = bpf_map__fd ( skel -> maps .dst_sock_hash ) ;
161+ dst_map = skel -> maps .dst_sock_hash ;
133162
134163err = bpf_map_update_elem (src , & zero , & sk , BPF_NOEXIST );
135164if (CHECK (err , "update_elem(src)" , "errno=%u\n" , errno ))
136165goto out ;
137166
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-
142167tattr = (struct bpf_prog_test_run_attr ){
143168.prog_fd = prog ,
144169.repeat = 1 ,
@@ -151,12 +176,7 @@ static void test_sockmap_update(enum bpf_map_type map_type)
151176 "errno=%u retval=%u\n" , errno , tattr .retval ))
152177goto out ;
153178
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 );
160180
161181out :
162182test_sockmap_update__destroy (skel );
@@ -174,14 +194,14 @@ static void test_sockmap_invalid_update(void)
174194test_sockmap_invalid_update__destroy (skel );
175195}
176196
177- static void test_sockmap_iter (enum bpf_map_type map_type )
197+ static void test_sockmap_copy (enum bpf_map_type map_type )
178198{
179199DECLARE_LIBBPF_OPTS (bpf_iter_attach_opts , opts );
180200int err , len , src_fd , iter_fd , duration = 0 ;
181201union 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 ;
184203struct bpf_iter_sockmap * skel ;
204+ __s64 * sock_fd = NULL ;
185205struct bpf_link * link ;
186206struct bpf_map * src ;
187207char buf [64 ];
@@ -190,22 +210,23 @@ static void test_sockmap_iter(enum bpf_map_type map_type)
190210if (CHECK (!skel , "bpf_iter_sockmap__open_and_load" , "skeleton open_and_load failed\n" ))
191211return ;
192212
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-
201213if (map_type == BPF_MAP_TYPE_SOCKMAP ) {
202214src = 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 ;
204217} else {
205218src = skel -> maps .sockhash ;
206- max_elems = num_sockets ;
219+ num_elems = bpf_map__max_entries (src ) - 1 ;
220+ num_sockets = num_elems ;
207221}
208222
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+
209230src_fd = bpf_map__fd (src );
210231
211232for (i = 0 ; i < num_sockets ; i ++ ) {
@@ -221,7 +242,7 @@ static void test_sockmap_iter(enum bpf_map_type map_type)
221242linfo .map .map_fd = src_fd ;
222243opts .link_info = & linfo ;
223244opts .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 );
225246if (CHECK (IS_ERR (link ), "attach_iter" , "attach_iter failed\n" ))
226247goto out ;
227248
@@ -236,23 +257,26 @@ static void test_sockmap_iter(enum bpf_map_type map_type)
236257goto close_iter ;
237258
238259/* 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 ))
241262goto close_iter ;
242263
243264if (CHECK (skel -> bss -> socks != num_sockets , "socks" , "got %u expected %u\n" ,
244265 skel -> bss -> socks , num_sockets ))
245266goto close_iter ;
246267
268+ compare_cookies (src , skel -> maps .dst );
269+
247270close_iter :
248271close (iter_fd );
249272free_link :
250273bpf_link__destroy (link );
251274out :
252- for (i = 0 ; i < num_sockets ; i ++ ) {
275+ for (i = 0 ; sock_fd && i < num_sockets ; i ++ )
253276if (sock_fd [i ] >= 0 )
254277close (sock_fd [i ]);
255- }
278+ if (sock_fd )
279+ free (sock_fd );
256280bpf_iter_sockmap__destroy (skel );
257281}
258282
@@ -272,8 +296,8 @@ void test_sockmap_basic(void)
272296test_sockmap_update (BPF_MAP_TYPE_SOCKHASH );
273297if (test__start_subtest ("sockmap update in unsafe context" ))
274298test_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 );
279303}
0 commit comments