xref: /freebsd/tests/sys/net/routing/rtsock_config.h (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2019 Alexander V. Chernikov
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #ifndef _NET_ROUTING_RTSOCK_CONFIG_H_
31 #define _NET_ROUTING_RTSOCK_CONFIG_H_
32 
33 struct rtsock_test_config {
34 	int ifindex;
35 	char net4_str[INET_ADDRSTRLEN];
36 	char addr4_str[INET_ADDRSTRLEN];
37 	char net6_str[INET6_ADDRSTRLEN];
38 	char addr6_str[INET6_ADDRSTRLEN];
39 	struct sockaddr_in net4;
40 	struct sockaddr_in mask4;
41 	struct sockaddr_in addr4;
42 	struct sockaddr_in6 net6;
43 	struct sockaddr_in6 mask6;
44 	struct sockaddr_in6 addr6;
45 	int plen4;
46 	int plen6;
47 	char *remote_lladdr;
48 	char *ifname;
49 	bool autocreated_interface;
50 	int rtsock_fd;
51 };
52 
53 struct rtsock_test_config *
54 config_setup_base(const atf_tc_t *tc)
55 {
56 	struct rtsock_test_config *c;
57 
58 	c = calloc(1, sizeof(struct rtsock_test_config));
59 	c->rtsock_fd = -1;
60 
61 	return c;
62 }
63 
64 struct rtsock_test_config *
65 config_setup(const atf_tc_t *tc)
66 {
67 	struct rtsock_test_config *c;
68 	char buf[64], *s;
69 	const char *key;
70 	int mask;
71 
72 	c = config_setup_base(tc);
73 
74 	key = atf_tc_get_config_var_wd(tc, "rtsock.v4prefix", "192.0.2.0/24");
75 	strlcpy(buf, key, sizeof(buf));
76 	if ((s = strchr(buf, '/')) == NULL)
77 		return (NULL);
78 	*s++ = '\0';
79 	mask = strtol(s, NULL, 10);
80 	if (mask < 0 || mask > 32)
81 		return (NULL);
82 	c->plen4 = mask;
83 	inet_pton(AF_INET, buf, &c->net4.sin_addr);
84 
85 	c->net4.sin_len = sizeof(struct sockaddr_in);
86 	c->net4.sin_family = AF_INET;
87 	c->addr4.sin_len = sizeof(struct sockaddr_in);
88 	c->addr4.sin_family = AF_INET;
89 
90 	sa_fill_mask4(&c->mask4, c->plen4);
91 
92 	/* Fill in interface IPv4 address. Assume the first address in net */
93 	c->addr4.sin_addr.s_addr = htonl(ntohl(c->net4.sin_addr.s_addr) + 1);
94 	inet_ntop(AF_INET, &c->net4.sin_addr, c->net4_str, INET_ADDRSTRLEN);
95 	inet_ntop(AF_INET, &c->addr4.sin_addr, c->addr4_str, INET_ADDRSTRLEN);
96 
97 	key = atf_tc_get_config_var_wd(tc, "rtsock.v6prefix", "2001:DB8::/32");
98 	strlcpy(buf, key, sizeof(buf));
99 	if ((s = strchr(buf, '/')) == NULL)
100 		return (NULL);
101 	*s++ = '\0';
102 	mask = strtol(s, NULL, 10);
103 	if (mask < 0 || mask > 128)
104 		return (NULL);
105 	c->plen6 = mask;
106 
107 	inet_pton(AF_INET6, buf, &c->net6.sin6_addr);
108 
109 	c->net6.sin6_len = sizeof(struct sockaddr_in6);
110 	c->net6.sin6_family = AF_INET6;
111 	c->addr6.sin6_len = sizeof(struct sockaddr_in6);
112 	c->addr6.sin6_family = AF_INET6;
113 
114 	sa_fill_mask6(&c->mask6, c->plen6);
115 
116 	/* Fill in interface IPv6 address. Assume the first address in net */
117 	memcpy(&c->addr6.sin6_addr, &c->net6.sin6_addr, sizeof(struct in6_addr));
118 #define _s6_addr32 __u6_addr.__u6_addr32
119 	c->addr6.sin6_addr._s6_addr32[3] = htonl(ntohl(c->net6.sin6_addr._s6_addr32[3]) + 1);
120 #undef _s6_addr32
121 	inet_ntop(AF_INET6, &c->net6.sin6_addr, c->net6_str, INET6_ADDRSTRLEN);
122 	inet_ntop(AF_INET6, &c->addr6.sin6_addr, c->addr6_str, INET6_ADDRSTRLEN);
123 
124 	c->ifname = strdup(atf_tc_get_config_var_wd(tc, "rtsock.ifname", "tap4242"));
125 	c->autocreated_interface = atf_tc_get_config_var_as_bool_wd(tc, "rtsock.create_interface", true);
126 
127 	if (c->autocreated_interface && (if_nametoindex(c->ifname) == 0))
128        	{
129 		/* create our own interface */
130 		char new_ifname[IFNAMSIZ];
131 		strlcpy(new_ifname, c->ifname, sizeof(new_ifname));
132 		int ret = iface_create_cloned(new_ifname);
133 		ATF_REQUIRE_MSG(ret != 0, "tap interface creation failed: %s", strerror(errno));
134 		c->ifname = strdup(new_ifname);
135 	}
136 	c->ifindex = if_nametoindex(c->ifname);
137 	ATF_REQUIRE_MSG(c->ifindex != 0, "inteface %s not found", c->ifname);
138 
139 	c->remote_lladdr = strdup(atf_tc_get_config_var_wd(tc,
140 	    "rtsock.remote_lladdr", "00:00:5E:00:53:42"));
141 
142 	return (c);
143 }
144 
145 void
146 config_generic_cleanup(struct rtsock_test_config *c)
147 {
148 	if (c->ifname != NULL && c->autocreated_interface) {
149 		iface_destroy(c->ifname);
150 		free(c->ifname);
151 		c->ifname = NULL;
152 	}
153 }
154 
155 void
156 config_describe_root_test(atf_tc_t *tc, char *test_descr)
157 {
158 
159 	atf_tc_set_md_var(tc, "descr", test_descr);
160 	// Adding/deleting prefix requires root privileges
161 	atf_tc_set_md_var(tc, "require.user", "root");
162 }
163 
164 #endif
165