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