~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/tcp_ao/seq-ext.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* Check that after SEQ number wrap-around:
  3  * 1. SEQ-extension has upper bytes set
  4  * 2. TCP conneciton is alive and no TCPAOBad segments
  5  * In order to test (2), the test doesn't just adjust seq number for a queue
  6  * on a connected socket, but migrates it to another sk+port number, so
  7  * that there won't be any delayed packets that will fail to verify
  8  * with the new SEQ numbers.
  9  */
 10 #include <inttypes.h>
 11 #include "aolib.h"
 12 
 13 const unsigned int nr_packets = 1000;
 14 const unsigned int msg_len = 1000;
 15 const unsigned int quota = nr_packets * msg_len;
 16 unsigned int client_new_port;
 17 
 18 /* Move them closer to roll-over */
 19 static void test_adjust_seqs(struct tcp_sock_state *img,
 20                              struct tcp_ao_repair *ao_img,
 21                              bool server)
 22 {
 23         uint32_t new_seq1, new_seq2;
 24 
 25         /* make them roll-over during quota, but on different segments */
 26         if (server) {
 27                 new_seq1 = ((uint32_t)-1) - msg_len;
 28                 new_seq2 = ((uint32_t)-1) - (quota - 2 * msg_len);
 29         } else {
 30                 new_seq1 = ((uint32_t)-1) - (quota - 2 * msg_len);
 31                 new_seq2 = ((uint32_t)-1) - msg_len;
 32         }
 33 
 34         img->in.seq = new_seq1;
 35         img->trw.snd_wl1 = img->in.seq - msg_len;
 36         img->out.seq = new_seq2;
 37         img->trw.rcv_wup = img->in.seq;
 38 }
 39 
 40 static int test_sk_restore(struct tcp_sock_state *img,
 41                            struct tcp_ao_repair *ao_img, sockaddr_af *saddr,
 42                            const union tcp_addr daddr, unsigned int dport,
 43                            struct tcp_ao_counters *cnt)
 44 {
 45         int sk;
 46 
 47         sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
 48         if (sk < 0)
 49                 test_error("socket()");
 50 
 51         test_enable_repair(sk);
 52         test_sock_restore(sk, img, saddr, daddr, dport);
 53         if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0, daddr, -1, 100, 100))
 54                 test_error("setsockopt(TCP_AO_ADD_KEY)");
 55         test_ao_restore(sk, ao_img);
 56 
 57         if (test_get_tcp_ao_counters(sk, cnt))
 58                 test_error("test_get_tcp_ao_counters()");
 59 
 60         test_disable_repair(sk);
 61         test_sock_state_free(img);
 62         return sk;
 63 }
 64 
 65 static void *server_fn(void *arg)
 66 {
 67         uint64_t before_good, after_good, after_bad;
 68         struct tcp_ao_counters ao1, ao2;
 69         struct tcp_sock_state img;
 70         struct tcp_ao_repair ao_img;
 71         sockaddr_af saddr;
 72         ssize_t bytes;
 73         int sk, lsk;
 74 
 75         lsk = test_listen_socket(this_ip_addr, test_server_port, 1);
 76 
 77         if (test_add_key(lsk, DEFAULT_TEST_PASSWORD, this_ip_dest, -1, 100, 100))
 78                 test_error("setsockopt(TCP_AO_ADD_KEY)");
 79 
 80         synchronize_threads(); /* 1: MKT added => connect() */
 81 
 82         if (test_wait_fd(lsk, TEST_TIMEOUT_SEC, 0))
 83                 test_error("test_wait_fd()");
 84 
 85         sk = accept(lsk, NULL, NULL);
 86         if (sk < 0)
 87                 test_error("accept()");
 88 
 89         synchronize_threads(); /* 2: accepted => send data */
 90         close(lsk);
 91 
 92         bytes = test_server_run(sk, quota, TEST_TIMEOUT_SEC);
 93         if (bytes != quota) {
 94                 if (bytes > 0)
 95                         test_fail("server served: %zd", bytes);
 96                 else
 97                         test_fail("server returned: %zd", bytes);
 98                 goto out;
 99         }
100 
101         before_good = netstat_get_one("TCPAOGood", NULL);
102 
103         synchronize_threads(); /* 3: restore the connection on another port */
104 
105         test_enable_repair(sk);
106         test_sock_checkpoint(sk, &img, &saddr);
107         test_ao_checkpoint(sk, &ao_img);
108         test_kill_sk(sk);
109 #ifdef IPV6_TEST
110         saddr.sin6_port = htons(ntohs(saddr.sin6_port) + 1);
111 #else
112         saddr.sin_port = htons(ntohs(saddr.sin_port) + 1);
113 #endif
114         test_adjust_seqs(&img, &ao_img, true);
115         synchronize_threads(); /* 4: dump finished */
116         sk = test_sk_restore(&img, &ao_img, &saddr, this_ip_dest,
117                              client_new_port, &ao1);
118 
119         synchronize_threads(); /* 5: verify counters during SEQ-number rollover */
120         bytes = test_server_run(sk, quota, TEST_TIMEOUT_SEC);
121         if (bytes != quota) {
122                 if (bytes > 0)
123                         test_fail("server served: %zd", bytes);
124                 else
125                         test_fail("server returned: %zd", bytes);
126         } else {
127                 test_ok("server alive");
128         }
129 
130         if (test_get_tcp_ao_counters(sk, &ao2))
131                 test_error("test_get_tcp_ao_counters()");
132         after_good = netstat_get_one("TCPAOGood", NULL);
133 
134         test_tcp_ao_counters_cmp(NULL, &ao1, &ao2, TEST_CNT_GOOD);
135 
136         if (after_good <= before_good) {
137                 test_fail("TCPAOGood counter did not increase: %zu <= %zu",
138                           after_good, before_good);
139         } else {
140                 test_ok("TCPAOGood counter increased %zu => %zu",
141                         before_good, after_good);
142         }
143         after_bad = netstat_get_one("TCPAOBad", NULL);
144         if (after_bad)
145                 test_fail("TCPAOBad counter is non-zero: %zu", after_bad);
146         else
147                 test_ok("TCPAOBad counter didn't increase");
148         test_enable_repair(sk);
149         test_ao_checkpoint(sk, &ao_img);
150         if (ao_img.snd_sne && ao_img.rcv_sne) {
151                 test_ok("SEQ extension incremented: %u/%u",
152                         ao_img.snd_sne, ao_img.rcv_sne);
153         } else {
154                 test_fail("SEQ extension was not incremented: %u/%u",
155                           ao_img.snd_sne, ao_img.rcv_sne);
156         }
157 
158         synchronize_threads(); /* 6: verified => closed */
159 out:
160         close(sk);
161         return NULL;
162 }
163 
164 static void *client_fn(void *arg)
165 {
166         uint64_t before_good, after_good, after_bad;
167         struct tcp_ao_counters ao1, ao2;
168         struct tcp_sock_state img;
169         struct tcp_ao_repair ao_img;
170         sockaddr_af saddr;
171         int sk;
172 
173         sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
174         if (sk < 0)
175                 test_error("socket()");
176 
177         if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, -1, 100, 100))
178                 test_error("setsockopt(TCP_AO_ADD_KEY)");
179 
180         synchronize_threads(); /* 1: MKT added => connect() */
181         if (test_connect_socket(sk, this_ip_dest, test_server_port) <= 0)
182                 test_error("failed to connect()");
183 
184         synchronize_threads(); /* 2: accepted => send data */
185         if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC)) {
186                 test_fail("pre-migrate verify failed");
187                 return NULL;
188         }
189 
190         before_good = netstat_get_one("TCPAOGood", NULL);
191 
192         synchronize_threads(); /* 3: restore the connection on another port */
193         test_enable_repair(sk);
194         test_sock_checkpoint(sk, &img, &saddr);
195         test_ao_checkpoint(sk, &ao_img);
196         test_kill_sk(sk);
197 #ifdef IPV6_TEST
198         client_new_port = ntohs(saddr.sin6_port) + 1;
199         saddr.sin6_port = htons(ntohs(saddr.sin6_port) + 1);
200 #else
201         client_new_port = ntohs(saddr.sin_port) + 1;
202         saddr.sin_port = htons(ntohs(saddr.sin_port) + 1);
203 #endif
204         test_adjust_seqs(&img, &ao_img, false);
205         synchronize_threads(); /* 4: dump finished */
206         sk = test_sk_restore(&img, &ao_img, &saddr, this_ip_dest,
207                              test_server_port + 1, &ao1);
208 
209         synchronize_threads(); /* 5: verify counters during SEQ-number rollover */
210         if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC))
211                 test_fail("post-migrate verify failed");
212         else
213                 test_ok("post-migrate connection alive");
214 
215         if (test_get_tcp_ao_counters(sk, &ao2))
216                 test_error("test_get_tcp_ao_counters()");
217         after_good = netstat_get_one("TCPAOGood", NULL);
218 
219         test_tcp_ao_counters_cmp(NULL, &ao1, &ao2, TEST_CNT_GOOD);
220 
221         if (after_good <= before_good) {
222                 test_fail("TCPAOGood counter did not increase: %zu <= %zu",
223                           after_good, before_good);
224         } else {
225                 test_ok("TCPAOGood counter increased %zu => %zu",
226                         before_good, after_good);
227         }
228         after_bad = netstat_get_one("TCPAOBad", NULL);
229         if (after_bad)
230                 test_fail("TCPAOBad counter is non-zero: %zu", after_bad);
231         else
232                 test_ok("TCPAOBad counter didn't increase");
233 
234         synchronize_threads(); /* 6: verified => closed */
235         close(sk);
236 
237         synchronize_threads(); /* don't race to exit: let server exit() */
238         return NULL;
239 }
240 
241 int main(int argc, char *argv[])
242 {
243         test_init(7, server_fn, client_fn);
244         return 0;
245 }
246 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php