]> Git Repo - J-linux.git/blob - tools/testing/selftests/net/tcp_ao/self-connect.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / net / tcp_ao / self-connect.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dmitry Safonov <[email protected]> */
3 #include <inttypes.h>
4 #include "aolib.h"
5
6 static union tcp_addr local_addr;
7
8 static void __setup_lo_intf(const char *lo_intf,
9                             const char *addr_str, uint8_t prefix)
10 {
11         if (inet_pton(TEST_FAMILY, addr_str, &local_addr) != 1)
12                 test_error("Can't convert local ip address");
13
14         if (ip_addr_add(lo_intf, TEST_FAMILY, local_addr, prefix))
15                 test_error("Failed to add %s ip address", lo_intf);
16
17         if (link_set_up(lo_intf))
18                 test_error("Failed to bring %s up", lo_intf);
19 }
20
21 static void setup_lo_intf(const char *lo_intf)
22 {
23 #ifdef IPV6_TEST
24         __setup_lo_intf(lo_intf, "::1", 128);
25 #else
26         __setup_lo_intf(lo_intf, "127.0.0.1", 8);
27 #endif
28 }
29
30 static void tcp_self_connect(const char *tst, unsigned int port,
31                              bool different_keyids, bool check_restore)
32 {
33         struct tcp_ao_counters before_ao, after_ao;
34         uint64_t before_aogood, after_aogood;
35         struct netstat *ns_before, *ns_after;
36         const size_t nr_packets = 20;
37         struct tcp_ao_repair ao_img;
38         struct tcp_sock_state img;
39         sockaddr_af addr;
40         int sk;
41
42         tcp_addr_to_sockaddr_in(&addr, &local_addr, htons(port));
43
44         sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
45         if (sk < 0)
46                 test_error("socket()");
47
48         if (different_keyids) {
49                 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 5, 7))
50                         test_error("setsockopt(TCP_AO_ADD_KEY)");
51                 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 7, 5))
52                         test_error("setsockopt(TCP_AO_ADD_KEY)");
53         } else {
54                 if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 100, 100))
55                         test_error("setsockopt(TCP_AO_ADD_KEY)");
56         }
57
58         if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0)
59                 test_error("bind()");
60
61         ns_before = netstat_read();
62         before_aogood = netstat_get(ns_before, "TCPAOGood", NULL);
63         if (test_get_tcp_ao_counters(sk, &before_ao))
64                 test_error("test_get_tcp_ao_counters()");
65
66         if (__test_connect_socket(sk, "lo", (struct sockaddr *)&addr,
67                                   sizeof(addr), TEST_TIMEOUT_SEC) < 0) {
68                 ns_after = netstat_read();
69                 netstat_print_diff(ns_before, ns_after);
70                 test_error("failed to connect()");
71         }
72
73         if (test_client_verify(sk, 100, nr_packets, TEST_TIMEOUT_SEC)) {
74                 test_fail("%s: tcp connection verify failed", tst);
75                 close(sk);
76                 return;
77         }
78
79         ns_after = netstat_read();
80         after_aogood = netstat_get(ns_after, "TCPAOGood", NULL);
81         if (test_get_tcp_ao_counters(sk, &after_ao))
82                 test_error("test_get_tcp_ao_counters()");
83         if (!check_restore) {
84                 /* to debug: netstat_print_diff(ns_before, ns_after); */
85                 netstat_free(ns_before);
86         }
87         netstat_free(ns_after);
88
89         if (after_aogood <= before_aogood) {
90                 test_fail("%s: TCPAOGood counter mismatch: %" PRIu64 " <= %" PRIu64,
91                           tst, after_aogood, before_aogood);
92                 close(sk);
93                 return;
94         }
95
96         if (test_tcp_ao_counters_cmp(tst, &before_ao, &after_ao, TEST_CNT_GOOD)) {
97                 close(sk);
98                 return;
99         }
100
101         if (!check_restore) {
102                 test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64,
103                                 tst, before_aogood, after_aogood);
104                 close(sk);
105                 return;
106         }
107
108         test_enable_repair(sk);
109         test_sock_checkpoint(sk, &img, &addr);
110 #ifdef IPV6_TEST
111         addr.sin6_port = htons(port + 1);
112 #else
113         addr.sin_port = htons(port + 1);
114 #endif
115         test_ao_checkpoint(sk, &ao_img);
116         test_kill_sk(sk);
117
118         sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
119         if (sk < 0)
120                 test_error("socket()");
121
122         test_enable_repair(sk);
123         __test_sock_restore(sk, "lo", &img, &addr, &addr, sizeof(addr));
124         if (different_keyids) {
125                 if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0,
126                                           local_addr, -1, 7, 5))
127                         test_error("setsockopt(TCP_AO_ADD_KEY)");
128                 if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0,
129                                           local_addr, -1, 5, 7))
130                         test_error("setsockopt(TCP_AO_ADD_KEY)");
131         } else {
132                 if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0,
133                                           local_addr, -1, 100, 100))
134                         test_error("setsockopt(TCP_AO_ADD_KEY)");
135         }
136         test_ao_restore(sk, &ao_img);
137         test_disable_repair(sk);
138         test_sock_state_free(&img);
139         if (test_client_verify(sk, 100, nr_packets, TEST_TIMEOUT_SEC)) {
140                 test_fail("%s: tcp connection verify failed", tst);
141                 close(sk);
142                 return;
143         }
144         ns_after = netstat_read();
145         after_aogood = netstat_get(ns_after, "TCPAOGood", NULL);
146         /* to debug: netstat_print_diff(ns_before, ns_after); */
147         netstat_free(ns_before);
148         netstat_free(ns_after);
149         close(sk);
150         if (after_aogood <= before_aogood) {
151                 test_fail("%s: TCPAOGood counter mismatch: %" PRIu64 " <= %" PRIu64,
152                           tst, after_aogood, before_aogood);
153                 return;
154         }
155         test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64,
156                         tst, before_aogood, after_aogood);
157 }
158
159 static void *client_fn(void *arg)
160 {
161         unsigned int port = test_server_port;
162
163         setup_lo_intf("lo");
164
165         tcp_self_connect("self-connect(same keyids)", port++, false, false);
166
167         /* expecting rnext to change based on the first segment RNext != Current */
168         trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, local_addr, local_addr,
169                               port, port, 0, -1, -1, -1, -1, -1, 7, 5, -1);
170         tcp_self_connect("self-connect(different keyids)", port++, true, false);
171         tcp_self_connect("self-connect(restore)", port, false, true);
172         port += 2; /* restore test restores over different port */
173         trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, local_addr, local_addr,
174                               port, port, 0, -1, -1, -1, -1, -1, 7, 5, -1);
175         /* intentionally on restore they are added to the socket in different order */
176         trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, local_addr, local_addr,
177                               port + 1, port + 1, 0, -1, -1, -1, -1, -1, 5, 7, -1);
178         tcp_self_connect("self-connect(restore, different keyids)", port, true, true);
179         port += 2; /* restore test restores over different port */
180
181         return NULL;
182 }
183
184 int main(int argc, char *argv[])
185 {
186         test_init(5, client_fn, NULL);
187         return 0;
188 }
This page took 0.036408 seconds and 4 git commands to generate.