14962445melifaro/*-
24962445melifaro * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
34962445melifaro *
44962445melifaro * Copyright (c) 2019 Alexander V. Chernikov
54962445melifaro *
64962445melifaro * Redistribution and use in source and binary forms, with or without
74962445melifaro * modification, are permitted provided that the following conditions
84962445melifaro * are met:
94962445melifaro * 1. Redistributions of source code must retain the above copyright
104962445melifaro *    notice, this list of conditions and the following disclaimer.
114962445melifaro * 2. Redistributions in binary form must reproduce the above copyright
124962445melifaro *    notice, this list of conditions and the following disclaimer in the
134962445melifaro *    documentation and/or other materials provided with the distribution.
144962445melifaro *
154962445melifaro * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
164962445melifaro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
174962445melifaro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
184962445melifaro * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
194962445melifaro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
204962445melifaro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
214962445melifaro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
224962445melifaro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
234962445melifaro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
244962445melifaro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
254962445melifaro * SUCH DAMAGE.
264962445melifaro *
274962445melifaro * $FreeBSD$
284962445melifaro */
294962445melifaro
304962445melifaro#ifndef _NET_ROUTING_RTSOCK_CONFIG_H_
314962445melifaro#define _NET_ROUTING_RTSOCK_CONFIG_H_
324962445melifaro
33b832076melifaro#include "params.h"
34b832076melifaro
355a596a5melifarostruct rtsock_config_options {
365a596a5melifaro	int num_interfaces;	/* number of interfaces to create */
375a596a5melifaro};
385a596a5melifaro
394962445melifarostruct rtsock_test_config {
404962445melifaro	int ifindex;
414962445melifaro	char net4_str[INET_ADDRSTRLEN];
424962445melifaro	char addr4_str[INET_ADDRSTRLEN];
434962445melifaro	char net6_str[INET6_ADDRSTRLEN];
444962445melifaro	char addr6_str[INET6_ADDRSTRLEN];
454962445melifaro	struct sockaddr_in net4;
464962445melifaro	struct sockaddr_in mask4;
474962445melifaro	struct sockaddr_in addr4;
484962445melifaro	struct sockaddr_in6 net6;
494962445melifaro	struct sockaddr_in6 mask6;
504962445melifaro	struct sockaddr_in6 addr6;
514962445melifaro	int plen4;
524962445melifaro	int plen6;
534962445melifaro	char *remote_lladdr;
544962445melifaro	char *ifname;
555a596a5melifaro	char **ifnames;
564962445melifaro	bool autocreated_interface;
574962445melifaro	int rtsock_fd;
585a596a5melifaro	int num_interfaces;
594962445melifaro};
604962445melifaro
614962445melifarostruct rtsock_test_config *
625a596a5melifaroconfig_setup(const atf_tc_t *tc, struct rtsock_config_options *co)
634962445melifaro{
645a596a5melifaro	struct rtsock_config_options default_co;
654962445melifaro	struct rtsock_test_config *c;
664962445melifaro	char buf[64], *s;
674962445melifaro	const char *key;
684962445melifaro	int mask;
694962445melifaro
705a596a5melifaro	if (co == NULL) {
715a596a5melifaro		bzero(&default_co, sizeof(default_co));
725a596a5melifaro		co = &default_co;
735a596a5melifaro		co->num_interfaces = 1;
745a596a5melifaro	}
755a596a5melifaro
765a596a5melifaro	c = calloc(1, sizeof(struct rtsock_test_config));
775a596a5melifaro	c->rtsock_fd = -1;
784962445melifaro
794962445melifaro	key = atf_tc_get_config_var_wd(tc, "rtsock.v4prefix", "192.0.2.0/24");
804962445melifaro	strlcpy(buf, key, sizeof(buf));
814962445melifaro	if ((s = strchr(buf, '/')) == NULL)
824962445melifaro		return (NULL);
834962445melifaro	*s++ = '\0';
844962445melifaro	mask = strtol(s, NULL, 10);
854962445melifaro	if (mask < 0 || mask > 32)
864962445melifaro		return (NULL);
874962445melifaro	c->plen4 = mask;
884962445melifaro	inet_pton(AF_INET, buf, &c->net4.sin_addr);
894962445melifaro
904962445melifaro	c->net4.sin_len = sizeof(struct sockaddr_in);
914962445melifaro	c->net4.sin_family = AF_INET;
924962445melifaro	c->addr4.sin_len = sizeof(struct sockaddr_in);
934962445melifaro	c->addr4.sin_family = AF_INET;
944962445melifaro
954962445melifaro	sa_fill_mask4(&c->mask4, c->plen4);
964962445melifaro
974962445melifaro	/* Fill in interface IPv4 address. Assume the first address in net */
984962445melifaro	c->addr4.sin_addr.s_addr = htonl(ntohl(c->net4.sin_addr.s_addr) + 1);
994962445melifaro	inet_ntop(AF_INET, &c->net4.sin_addr, c->net4_str, INET_ADDRSTRLEN);
1004962445melifaro	inet_ntop(AF_INET, &c->addr4.sin_addr, c->addr4_str, INET_ADDRSTRLEN);
1014962445melifaro
1024962445melifaro	key = atf_tc_get_config_var_wd(tc, "rtsock.v6prefix", "2001:DB8::/32");
1034962445melifaro	strlcpy(buf, key, sizeof(buf));
1044962445melifaro	if ((s = strchr(buf, '/')) == NULL)
1054962445melifaro		return (NULL);
1064962445melifaro	*s++ = '\0';
1074962445melifaro	mask = strtol(s, NULL, 10);
1084962445melifaro	if (mask < 0 || mask > 128)
1094962445melifaro		return (NULL);
1104962445melifaro	c->plen6 = mask;
1114962445melifaro
1124962445melifaro	inet_pton(AF_INET6, buf, &c->net6.sin6_addr);
1134962445melifaro
1144962445melifaro	c->net6.sin6_len = sizeof(struct sockaddr_in6);
1154962445melifaro	c->net6.sin6_family = AF_INET6;
1164962445melifaro	c->addr6.sin6_len = sizeof(struct sockaddr_in6);
1174962445melifaro	c->addr6.sin6_family = AF_INET6;
1184962445melifaro
1194962445melifaro	sa_fill_mask6(&c->mask6, c->plen6);
1204962445melifaro
1214962445melifaro	/* Fill in interface IPv6 address. Assume the first address in net */
1224962445melifaro	memcpy(&c->addr6.sin6_addr, &c->net6.sin6_addr, sizeof(struct in6_addr));
1234962445melifaro#define _s6_addr32 __u6_addr.__u6_addr32
1244962445melifaro	c->addr6.sin6_addr._s6_addr32[3] = htonl(ntohl(c->net6.sin6_addr._s6_addr32[3]) + 1);
1254962445melifaro#undef _s6_addr32
1264962445melifaro	inet_ntop(AF_INET6, &c->net6.sin6_addr, c->net6_str, INET6_ADDRSTRLEN);
1274962445melifaro	inet_ntop(AF_INET6, &c->addr6.sin6_addr, c->addr6_str, INET6_ADDRSTRLEN);
1284962445melifaro
1295a596a5melifaro	if (co->num_interfaces > 0) {
1305a596a5melifaro		c->ifnames = calloc(co->num_interfaces, sizeof(char *));
1315a596a5melifaro		for (int i = 0; i < co->num_interfaces; i++)
1325a596a5melifaro			c->ifnames[i] = iface_create("epair");
1335a596a5melifaro
1345a596a5melifaro		c->ifname = c->ifnames[0];
1355a596a5melifaro		c->ifindex = if_nametoindex(c->ifname);
1365a596a5melifaro		ATF_REQUIRE_MSG(c->ifindex != 0, "interface %s not found",
1375a596a5melifaro		    c->ifname);
1384962445melifaro	}
1395a596a5melifaro	c->num_interfaces = co->num_interfaces;
1404962445melifaro
1414962445melifaro	c->remote_lladdr = strdup(atf_tc_get_config_var_wd(tc,
1424962445melifaro	    "rtsock.remote_lladdr", "00:00:5E:00:53:42"));
1434962445melifaro
1444962445melifaro	return (c);
1454962445melifaro}
1464962445melifaro
1474962445melifarovoid
148b832076melifaroconfig_generic_cleanup(const atf_tc_t *tc)
1494962445melifaro{
150b832076melifaro	const char *srcdir = atf_tc_get_config_var(tc, "srcdir");
151b832076melifaro	char cmd[512];
152b832076melifaro	int ret;
153b832076melifaro
154b832076melifaro	/* XXX: sleep 100ms to avoid epair qflush panic */
155b832076melifaro	usleep(1000 * 100);
156b832076melifaro	snprintf(cmd, sizeof(cmd), "%s/generic_cleanup.sh", srcdir);
157b832076melifaro	ret = system(cmd);
158b832076melifaro	if (ret != 0)
159b832076melifaro		RLOG("'%s' failed, error %d", cmd, ret);
1604962445melifaro}
1614962445melifaro
1624962445melifarovoid
1634962445melifaroconfig_describe_root_test(atf_tc_t *tc, char *test_descr)
1644962445melifaro{
1654962445melifaro
1664962445melifaro	atf_tc_set_md_var(tc, "descr", test_descr);
1674962445melifaro	// Adding/deleting prefix requires root privileges
1684962445melifaro	atf_tc_set_md_var(tc, "require.user", "root");
1694962445melifaro}
1704962445melifaro
1714962445melifaro#endif
172