1818 * AF_UNIX, SOCK_DGRAM
1919 * AF_VSOCK, SOCK_STREAM
2020 * AF_VSOCK, SOCK_SEQPACKET
21+ * x
22+ * SK_REDIRECT
23+ * SK_DROP
24+ * SK_PASS
2125 */
2226
2327#include <errno.h>
6569 */
6670#define UNSUPPORTED_RACY_VERD _BITUL(1)
6771
72+ /* Mark for an immediate SK_DROP/SK_PASS, i.e. BPF program will not redirect.
73+ */
74+ #define NO_REDIRECT _BITUL(2)
75+
6876enum prog_type {
6977 SK_MSG_EGRESS ,
7078 SK_MSG_INGRESS ,
@@ -154,8 +162,9 @@ static void fail_recv(const char *prefix, int fd, int more_flags)
154162 FAIL ("%s: unexpected success: retval=%zd" , prefix , n );
155163}
156164
157- static void handle_unsupported (int sd_send , int sd_peer , int sd_in , int sd_out ,
158- int sd_recv , int map_verd , int status )
165+ static void handle_unsupported (int sd_send , int send_flags , int sd_peer ,
166+ int sd_in , int sd_out , int sd_recv ,
167+ int map_verd , int status )
159168{
160169 unsigned int drop , pass ;
161170 char recv_buf ;
@@ -171,7 +180,7 @@ static void handle_unsupported(int sd_send, int sd_peer, int sd_in, int sd_out,
171180 goto get_verdict ;
172181 }
173182
174- if (pass != 0 ) {
183+ if (pass && !( status & NO_REDIRECT ) ) {
175184 FAIL ("unsupported: wanted verdict pass 0, have %u" , pass );
176185 return ;
177186 }
@@ -237,14 +246,14 @@ static void test_send_recv(int sd_send, int send_flags, int sd_peer, int sd_in,
237246 FAIL ("incomplete send" );
238247 if (n < 0 ) {
239248 /* sk_msg redirect combo not supported? */
240- if (status & SUPPORTED || errno != EACCES )
249+ if (errno != EACCES )
241250 FAIL_ERRNO ("send" );
242251 goto out ;
243252 }
244253
245- if (!(status & SUPPORTED )) {
246- handle_unsupported (sd_send , sd_peer , sd_in , sd_out , sd_recv ,
247- maps -> verd , status );
254+ if (!(status & SUPPORTED ) || ( status & NO_REDIRECT ) ) {
255+ handle_unsupported (sd_send , send_flags , sd_peer , sd_in , sd_out ,
256+ sd_recv , maps -> verd , status );
248257 goto out ;
249258 }
250259
@@ -326,9 +335,10 @@ static int is_redir_supported(enum prog_type type, const char *in,
326335static int get_support_status (enum prog_type type , const char * in ,
327336 const char * out )
328337{
329- int status = is_redir_supported (type , in , out );
338+ int status = in ? is_redir_supported (type , in , out ) : 0 ;
330339
331- if (type == SK_SKB_INGRESS && strstarts (out , "v_" ))
340+ if ((type == SK_SKB_INGRESS || type == SK_SKB_EGRESS ) &&
341+ strstarts (out , "v_" ))
332342 status |= UNSUPPORTED_RACY_VERD ;
333343
334344 return status ;
@@ -370,6 +380,41 @@ static void test_redir(enum bpf_map_type type, struct redir_spec *redir,
370380 status );
371381}
372382
383+ static void test_verdict (enum bpf_map_type type , struct redir_spec * redir ,
384+ struct maps * maps , struct socket_spec * s_in ,
385+ enum sk_action action )
386+ {
387+ int fd_in , fd_out , fd_send , fd_peer , fd_recv , flags , status ;
388+ char s [MAX_TEST_NAME ];
389+ const char * s_str ;
390+
391+ fd_in = s_in -> in [0 ];
392+ fd_out = s_in -> in [1 ];
393+ fd_send = s_in -> in [redir -> idx_send ];
394+ fd_peer = s_in -> in [redir -> idx_send ^ 1 ];
395+ fd_recv = s_in -> in [redir -> idx_send ^ 1 ];
396+ flags = s_in -> send_flags ;
397+
398+ s_str = socket_kind_to_str (fd_in );
399+ status = get_support_status (redir -> prog_type , NULL , s_str );
400+ status |= NO_REDIRECT ;
401+
402+ snprintf (s , sizeof (s ),
403+ "%-4s %-17s %-7s %-5s%6s" ,
404+ /* hash sk_skb-to-ingress u_str pass (OOB) */
405+ type == BPF_MAP_TYPE_SOCKMAP ? "map" : "hash" ,
406+ redir -> name ,
407+ s_str ,
408+ action == SK_PASS ? "pass" : "drop" ,
409+ flags & MSG_OOB ? "(OOB)" : "" );
410+
411+ if (!test__start_subtest (s ))
412+ return ;
413+
414+ test_send_recv (fd_send , flags , fd_peer , fd_in , fd_out , fd_recv , maps ,
415+ status );
416+ }
417+
373418static void test_sockets (enum bpf_map_type type , struct redir_spec * redir ,
374419 struct maps * maps , int * skel_redir_type )
375420{
@@ -413,6 +458,17 @@ static void test_sockets(enum bpf_map_type type, struct redir_spec *redir,
413458 test_redir (type , redir , maps , in , out );
414459 }
415460 }
461+
462+ /* No redirect: SK_DROP */
463+ * skel_redir_type = __MAX_BPF_MAP_TYPE + SK_DROP ;
464+ for (s = sockets ; s < sockets + ARRAY_SIZE (sockets ); s ++ )
465+ test_verdict (type , redir , maps , s , SK_DROP );
466+
467+ /* No redirect: SK_PASS */
468+ * skel_redir_type = __MAX_BPF_MAP_TYPE + SK_PASS ;
469+ for (s = sockets ; s < sockets + ARRAY_SIZE (sockets ); s ++ )
470+ test_verdict (type , redir , maps , s , SK_PASS );
471+
416472out :
417473 while (-- s >= sockets )
418474 socket_spec_close (s );
0 commit comments