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