Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / selftests / net / tcp_ao / self-connect.c
blob3ecd2b58de6a396dfa559fd10a6a00f64b4daf83
1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dmitry Safonov <dima@arista.com> */
3 #include <inttypes.h>
4 #include "aolib.h"
6 static union tcp_addr local_addr;
8 static void __setup_lo_intf(const char *lo_intf,
9 const char *addr_str, uint8_t prefix)
11 if (inet_pton(TEST_FAMILY, addr_str, &local_addr) != 1)
12 test_error("Can't convert local ip address");
14 if (ip_addr_add(lo_intf, TEST_FAMILY, local_addr, prefix))
15 test_error("Failed to add %s ip address", lo_intf);
17 if (link_set_up(lo_intf))
18 test_error("Failed to bring %s up", lo_intf);
21 static void setup_lo_intf(const char *lo_intf)
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
30 static void tcp_self_connect(const char *tst, unsigned int port,
31 bool different_keyids, bool check_restore)
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;
42 tcp_addr_to_sockaddr_in(&addr, &local_addr, htons(port));
44 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
45 if (sk < 0)
46 test_error("socket()");
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)");
58 if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0)
59 test_error("bind()");
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()");
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()");
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;
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);
87 netstat_free(ns_after);
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;
96 if (test_tcp_ao_counters_cmp(tst, &before_ao, &after_ao, TEST_CNT_GOOD)) {
97 close(sk);
98 return;
101 if (!check_restore) {
102 test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64,
103 tst, before_aogood, after_aogood);
104 close(sk);
105 return;
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);
118 sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
119 if (sk < 0)
120 test_error("socket()");
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)");
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;
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;
155 test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64,
156 tst, before_aogood, after_aogood);
159 static void *client_fn(void *arg)
161 unsigned int port = test_server_port;
163 setup_lo_intf("lo");
165 tcp_self_connect("self-connect(same keyids)", port++, false, false);
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 */
181 return NULL;
184 int main(int argc, char *argv[])
186 test_init(5, client_fn, NULL);
187 return 0;