1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020 Cloudflare
3 
4 #include "test_progs.h"
5 
6 #define TCP_REPAIR		19	/* TCP sock is under repair right now */
7 
8 #define TCP_REPAIR_ON		1
9 #define TCP_REPAIR_OFF_NO_WP	-1	/* Turn off without window probes */
10 
11 static int connected_socket_v4(void)
12 {
13 	struct sockaddr_in addr = {
14 		.sin_family = AF_INET,
15 		.sin_port = htons(80),
16 		.sin_addr = { inet_addr("127.0.0.1") },
17 	};
18 	socklen_t len = sizeof(addr);
19 	int s, repair, err;
20 
21 	s = socket(AF_INET, SOCK_STREAM, 0);
22 	if (CHECK_FAIL(s == -1))
23 		goto error;
24 
25 	repair = TCP_REPAIR_ON;
26 	err = setsockopt(s, SOL_TCP, TCP_REPAIR, &repair, sizeof(repair));
27 	if (CHECK_FAIL(err))
28 		goto error;
29 
30 	err = connect(s, (struct sockaddr *)&addr, len);
31 	if (CHECK_FAIL(err))
32 		goto error;
33 
34 	repair = TCP_REPAIR_OFF_NO_WP;
35 	err = setsockopt(s, SOL_TCP, TCP_REPAIR, &repair, sizeof(repair));
36 	if (CHECK_FAIL(err))
37 		goto error;
38 
39 	return s;
40 error:
41 	perror(__func__);
42 	close(s);
43 	return -1;
44 }
45 
46 /* Create a map, populate it with one socket, and free the map. */
47 static void test_sockmap_create_update_free(enum bpf_map_type map_type)
48 {
49 	const int zero = 0;
50 	int s, map, err;
51 
52 	s = connected_socket_v4();
53 	if (CHECK_FAIL(s == -1))
54 		return;
55 
56 	map = bpf_create_map(map_type, sizeof(int), sizeof(int), 1, 0);
57 	if (CHECK_FAIL(map == -1)) {
58 		perror("bpf_create_map");
59 		goto out;
60 	}
61 
62 	err = bpf_map_update_elem(map, &zero, &s, BPF_NOEXIST);
63 	if (CHECK_FAIL(err)) {
64 		perror("bpf_map_update");
65 		goto out;
66 	}
67 
68 out:
69 	close(map);
70 	close(s);
71 }
72 
73 void test_sockmap_basic(void)
74 {
75 	if (test__start_subtest("sockmap create_update_free"))
76 		test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP);
77 	if (test__start_subtest("sockhash create_update_free"))
78 		test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKHASH);
79 }
80