4
4
* Tests for sockmap/sockhash holding kTLS sockets.
5
5
*/
6
6
7
+ #include <netinet/tcp.h>
7
8
#include "test_progs.h"
8
9
9
10
#define MAX_TEST_NAME 80
@@ -92,9 +93,78 @@ static void test_sockmap_ktls_disconnect_after_delete(int family, int map)
92
93
close (srv );
93
94
}
94
95
96
+ static void test_sockmap_ktls_update_fails_when_sock_has_ulp (int family , int map )
97
+ {
98
+ struct sockaddr_storage addr = {};
99
+ socklen_t len = sizeof (addr );
100
+ struct sockaddr_in6 * v6 ;
101
+ struct sockaddr_in * v4 ;
102
+ int err , s , zero = 0 ;
103
+
104
+ switch (family ) {
105
+ case AF_INET :
106
+ v4 = (struct sockaddr_in * )& addr ;
107
+ v4 -> sin_family = AF_INET ;
108
+ break ;
109
+ case AF_INET6 :
110
+ v6 = (struct sockaddr_in6 * )& addr ;
111
+ v6 -> sin6_family = AF_INET6 ;
112
+ break ;
113
+ default :
114
+ PRINT_FAIL ("unsupported socket family %d" , family );
115
+ return ;
116
+ }
117
+
118
+ s = socket (family , SOCK_STREAM , 0 );
119
+ if (!ASSERT_GE (s , 0 , "socket" ))
120
+ return ;
121
+
122
+ err = bind (s , (struct sockaddr * )& addr , len );
123
+ if (!ASSERT_OK (err , "bind" ))
124
+ goto close ;
125
+
126
+ err = getsockname (s , (struct sockaddr * )& addr , & len );
127
+ if (!ASSERT_OK (err , "getsockname" ))
128
+ goto close ;
129
+
130
+ err = connect (s , (struct sockaddr * )& addr , len );
131
+ if (!ASSERT_OK (err , "connect" ))
132
+ goto close ;
133
+
134
+ /* save sk->sk_prot and set it to tls_prots */
135
+ err = setsockopt (s , IPPROTO_TCP , TCP_ULP , "tls" , strlen ("tls" ));
136
+ if (!ASSERT_OK (err , "setsockopt(TCP_ULP)" ))
137
+ goto close ;
138
+
139
+ /* sockmap update should not affect saved sk_prot */
140
+ err = bpf_map_update_elem (map , & zero , & s , BPF_ANY );
141
+ if (!ASSERT_ERR (err , "sockmap update elem" ))
142
+ goto close ;
143
+
144
+ /* call sk->sk_prot->setsockopt to dispatch to saved sk_prot */
145
+ err = setsockopt (s , IPPROTO_TCP , TCP_NODELAY , & zero , sizeof (zero ));
146
+ ASSERT_OK (err , "setsockopt(TCP_NODELAY)" );
147
+
148
+ close :
149
+ close (s );
150
+ }
151
+
152
+ static const char * fmt_test_name (const char * subtest_name , int family ,
153
+ enum bpf_map_type map_type )
154
+ {
155
+ const char * map_type_str = BPF_MAP_TYPE_SOCKMAP ? "SOCKMAP" : "SOCKHASH" ;
156
+ const char * family_str = AF_INET ? "IPv4" : "IPv6" ;
157
+ static char test_name [MAX_TEST_NAME ];
158
+
159
+ snprintf (test_name , MAX_TEST_NAME ,
160
+ "sockmap_ktls %s %s %s" ,
161
+ subtest_name , family_str , map_type_str );
162
+
163
+ return test_name ;
164
+ }
165
+
95
166
static void run_tests (int family , enum bpf_map_type map_type )
96
167
{
97
- char test_name [MAX_TEST_NAME ];
98
168
int map ;
99
169
100
170
map = bpf_map_create (map_type , NULL , sizeof (int ), sizeof (int ), 1 , NULL );
@@ -103,14 +173,10 @@ static void run_tests(int family, enum bpf_map_type map_type)
103
173
return ;
104
174
}
105
175
106
- snprintf (test_name , MAX_TEST_NAME ,
107
- "sockmap_ktls disconnect_after_delete %s %s" ,
108
- family == AF_INET ? "IPv4" : "IPv6" ,
109
- map_type == BPF_MAP_TYPE_SOCKMAP ? "SOCKMAP" : "SOCKHASH" );
110
- if (!test__start_subtest (test_name ))
111
- return ;
112
-
113
- test_sockmap_ktls_disconnect_after_delete (family , map );
176
+ if (test__start_subtest (fmt_test_name ("disconnect_after_delete" , family , map_type )))
177
+ test_sockmap_ktls_disconnect_after_delete (family , map );
178
+ if (test__start_subtest (fmt_test_name ("update_fails_when_sock_has_ulp" , family , map_type )))
179
+ test_sockmap_ktls_update_fails_when_sock_has_ulp (family , map );
114
180
115
181
close (map );
116
182
}
0 commit comments