xref: /freebsd/tests/sys/net/routing/rtsock_config.h (revision 783d3ff6d7fae619db8a7990b8a6387de0c677b5)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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 
28 #ifndef _NET_ROUTING_RTSOCK_CONFIG_H_
29 #define _NET_ROUTING_RTSOCK_CONFIG_H_
30 
31 #include "params.h"
32 
33 struct rtsock_config_options {
34 	int num_interfaces;	/* number of interfaces to create */
35 };
36 
37 struct rtsock_test_config {
38 	int ifindex;
39 	char net4_str[INET_ADDRSTRLEN];
40 	char addr4_str[INET_ADDRSTRLEN];
41 	char net6_str[INET6_ADDRSTRLEN];
42 	char addr6_str[INET6_ADDRSTRLEN];
43 	struct sockaddr_in net4;
44 	struct sockaddr_in mask4;
45 	struct sockaddr_in addr4;
46 	struct sockaddr_in6 net6;
47 	struct sockaddr_in6 mask6;
48 	struct sockaddr_in6 addr6;
49 	int plen4;
50 	int plen6;
51 	char *remote_lladdr;
52 	char *ifname;
53 	char **ifnames;
54 	bool autocreated_interface;
55 	int rtsock_fd;
56 	int num_interfaces;
57 };
58 
59 struct rtsock_test_config *
60 config_setup(const atf_tc_t *tc, struct rtsock_config_options *co)
61 {
62 	struct rtsock_config_options default_co;
63 	struct rtsock_test_config *c;
64 	char buf[64], *s;
65 	const char *key;
66 	int mask;
67 
68 	if (co == NULL) {
69 		bzero(&default_co, sizeof(default_co));
70 		co = &default_co;
71 		co->num_interfaces = 1;
72 	}
73 
74 	c = calloc(1, sizeof(struct rtsock_test_config));
75 	c->rtsock_fd = -1;
76 
77 	key = atf_tc_get_config_var_wd(tc, "rtsock.v4prefix", "192.0.2.0/24");
78 	strlcpy(buf, key, sizeof(buf));
79 	if ((s = strchr(buf, '/')) == NULL)
80 		return (NULL);
81 	*s++ = '\0';
82 	mask = strtol(s, NULL, 10);
83 	if (mask < 0 || mask > 32)
84 		return (NULL);
85 	c->plen4 = mask;
86 	inet_pton(AF_INET, buf, &c->net4.sin_addr);
87 
88 	c->net4.sin_len = sizeof(struct sockaddr_in);
89 	c->net4.sin_family = AF_INET;
90 	c->addr4.sin_len = sizeof(struct sockaddr_in);
91 	c->addr4.sin_family = AF_INET;
92 
93 	sa_fill_mask4(&c->mask4, c->plen4);
94 
95 	/* Fill in interface IPv4 address. Assume the first address in net */
96 	c->addr4.sin_addr.s_addr = htonl(ntohl(c->net4.sin_addr.s_addr) + 1);
97 	inet_ntop(AF_INET, &c->net4.sin_addr, c->net4_str, INET_ADDRSTRLEN);
98 	inet_ntop(AF_INET, &c->addr4.sin_addr, c->addr4_str, INET_ADDRSTRLEN);
99 
100 	key = atf_tc_get_config_var_wd(tc, "rtsock.v6prefix", "2001:DB8::/32");
101 	strlcpy(buf, key, sizeof(buf));
102 	if ((s = strchr(buf, '/')) == NULL)
103 		return (NULL);
104 	*s++ = '\0';
105 	mask = strtol(s, NULL, 10);
106 	if (mask < 0 || mask > 128)
107 		return (NULL);
108 	c->plen6 = mask;
109 
110 	inet_pton(AF_INET6, buf, &c->net6.sin6_addr);
111 
112 	c->net6.sin6_len = sizeof(struct sockaddr_in6);
113 	c->net6.sin6_family = AF_INET6;
114 	c->addr6.sin6_len = sizeof(struct sockaddr_in6);
115 	c->addr6.sin6_family = AF_INET6;
116 
117 	sa_fill_mask6(&c->mask6, c->plen6);
118 
119 	/* Fill in interface IPv6 address. Assume the first address in net */
120 	memcpy(&c->addr6.sin6_addr, &c->net6.sin6_addr, sizeof(struct in6_addr));
121 #define _s6_addr32 __u6_addr.__u6_addr32
122 	c->addr6.sin6_addr._s6_addr32[3] = htonl(ntohl(c->net6.sin6_addr._s6_addr32[3]) + 1);
123 #undef _s6_addr32
124 	inet_ntop(AF_INET6, &c->net6.sin6_addr, c->net6_str, INET6_ADDRSTRLEN);
125 	inet_ntop(AF_INET6, &c->addr6.sin6_addr, c->addr6_str, INET6_ADDRSTRLEN);
126 
127 	ATF_CHECK_ERRNO(0, true);
128 
129 	if (co->num_interfaces > 0) {
130 		/* Try loading if_epair and if that fails skip the test. */
131 		kldload("if_epair");
132 		ATF_REQUIRE_KERNEL_MODULE("if_epair");
133 		/* Clear errno for the following tests. */
134 		errno = 0;
135 
136 		c->ifnames = calloc(co->num_interfaces, sizeof(char *));
137 		for (int i = 0; i < co->num_interfaces; i++)
138 			c->ifnames[i] = iface_create("epair");
139 
140 		c->ifname = c->ifnames[0];
141 		c->ifindex = if_nametoindex(c->ifname);
142 		ATF_REQUIRE_MSG(c->ifindex != 0, "interface %s not found",
143 		    c->ifname);
144 	}
145 	c->num_interfaces = co->num_interfaces;
146 
147 	c->remote_lladdr = strdup(atf_tc_get_config_var_wd(tc,
148 	    "rtsock.remote_lladdr", "00:00:5E:00:53:42"));
149 
150 	return (c);
151 }
152 
153 void
154 config_generic_cleanup(const atf_tc_t *tc)
155 {
156 	const char *srcdir = atf_tc_get_config_var(tc, "srcdir");
157 	char cmd[512];
158 	int ret;
159 
160 	snprintf(cmd, sizeof(cmd), "%s/generic_cleanup.sh", srcdir);
161 	ret = system(cmd);
162 	if (ret != 0)
163 		RLOG("'%s' failed, error %d", cmd, ret);
164 }
165 
166 void
167 config_describe_root_test(atf_tc_t *tc, char *test_descr)
168 {
169 
170 	atf_tc_set_md_var(tc, "descr", test_descr);
171 	// Adding/deleting prefix requires root privileges
172 	atf_tc_set_md_var(tc, "require.user", "root");
173 }
174 
175 #endif
176