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