1775dc861SAlexander V. Chernikov /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3775dc861SAlexander V. Chernikov *
4775dc861SAlexander V. Chernikov * Copyright (c) 2019 Alexander V. Chernikov
5775dc861SAlexander V. Chernikov *
6775dc861SAlexander V. Chernikov * Redistribution and use in source and binary forms, with or without
7775dc861SAlexander V. Chernikov * modification, are permitted provided that the following conditions
8775dc861SAlexander V. Chernikov * are met:
9775dc861SAlexander V. Chernikov * 1. Redistributions of source code must retain the above copyright
10775dc861SAlexander V. Chernikov * notice, this list of conditions and the following disclaimer.
11775dc861SAlexander V. Chernikov * 2. Redistributions in binary form must reproduce the above copyright
12775dc861SAlexander V. Chernikov * notice, this list of conditions and the following disclaimer in the
13775dc861SAlexander V. Chernikov * documentation and/or other materials provided with the distribution.
14775dc861SAlexander V. Chernikov *
15775dc861SAlexander V. Chernikov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16775dc861SAlexander V. Chernikov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17775dc861SAlexander V. Chernikov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18775dc861SAlexander V. Chernikov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19775dc861SAlexander V. Chernikov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20775dc861SAlexander V. Chernikov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21775dc861SAlexander V. Chernikov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22775dc861SAlexander V. Chernikov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23775dc861SAlexander V. Chernikov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24775dc861SAlexander V. Chernikov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25775dc861SAlexander V. Chernikov * SUCH DAMAGE.
26775dc861SAlexander V. Chernikov */
27775dc861SAlexander V. Chernikov
28775dc861SAlexander V. Chernikov #include "rtsock_common.h"
29775dc861SAlexander V. Chernikov #include "rtsock_config.h"
30e02d3fe7SAlexander V. Chernikov #include "sys/types.h"
31e02d3fe7SAlexander V. Chernikov #include <sys/time.h>
32e02d3fe7SAlexander V. Chernikov #include <sys/ioctl.h>
33e02d3fe7SAlexander V. Chernikov
34e02d3fe7SAlexander V. Chernikov #include "net/bpf.h"
35775dc861SAlexander V. Chernikov
36ddc75076SAlexander V. Chernikov static void
jump_vnet(struct rtsock_test_config * c,const atf_tc_t * tc)37ddc75076SAlexander V. Chernikov jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
38ddc75076SAlexander V. Chernikov {
39ddc75076SAlexander V. Chernikov char vnet_name[512];
40ddc75076SAlexander V. Chernikov
41ddc75076SAlexander V. Chernikov snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
42ddc75076SAlexander V. Chernikov RLOG("jumping to %s", vnet_name);
43ddc75076SAlexander V. Chernikov
44272bd698SAlexander V. Chernikov vnet_switch(vnet_name, c->ifnames, c->num_interfaces);
45ddc75076SAlexander V. Chernikov
46ddc75076SAlexander V. Chernikov /* Update ifindex cache */
47ddc75076SAlexander V. Chernikov c->ifindex = if_nametoindex(c->ifname);
48ddc75076SAlexander V. Chernikov }
49ddc75076SAlexander V. Chernikov
50775dc861SAlexander V. Chernikov static inline struct rtsock_test_config *
presetup_ipv6_iface(const atf_tc_t * tc)51e02d3fe7SAlexander V. Chernikov presetup_ipv6_iface(const atf_tc_t *tc)
52775dc861SAlexander V. Chernikov {
53775dc861SAlexander V. Chernikov struct rtsock_test_config *c;
54775dc861SAlexander V. Chernikov int ret;
55775dc861SAlexander V. Chernikov
56272bd698SAlexander V. Chernikov c = config_setup(tc, NULL);
57775dc861SAlexander V. Chernikov
58ddc75076SAlexander V. Chernikov jump_vnet(c, tc);
59ddc75076SAlexander V. Chernikov
60775dc861SAlexander V. Chernikov ret = iface_turn_up(c->ifname);
61775dc861SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
62775dc861SAlexander V. Chernikov
63775dc861SAlexander V. Chernikov ret = iface_enable_ipv6(c->ifname);
64775dc861SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);
6567f2f67fSAlex Richardson ATF_REQUIRE_ERRNO(0, true);
66775dc861SAlexander V. Chernikov
67e02d3fe7SAlexander V. Chernikov return (c);
68e02d3fe7SAlexander V. Chernikov }
69e02d3fe7SAlexander V. Chernikov
70e02d3fe7SAlexander V. Chernikov static inline struct rtsock_test_config *
presetup_ipv6(const atf_tc_t * tc)71e02d3fe7SAlexander V. Chernikov presetup_ipv6(const atf_tc_t *tc)
72e02d3fe7SAlexander V. Chernikov {
73e02d3fe7SAlexander V. Chernikov struct rtsock_test_config *c;
74e02d3fe7SAlexander V. Chernikov int ret;
75e02d3fe7SAlexander V. Chernikov
76e02d3fe7SAlexander V. Chernikov c = presetup_ipv6_iface(tc);
77e02d3fe7SAlexander V. Chernikov
78775dc861SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
79775dc861SAlexander V. Chernikov
80775dc861SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
8167f2f67fSAlex Richardson ATF_REQUIRE_ERRNO(0, true);
82775dc861SAlexander V. Chernikov
83775dc861SAlexander V. Chernikov return (c);
84775dc861SAlexander V. Chernikov }
85775dc861SAlexander V. Chernikov
86775dc861SAlexander V. Chernikov static inline struct rtsock_test_config *
presetup_ipv4_iface(const atf_tc_t * tc)87e02d3fe7SAlexander V. Chernikov presetup_ipv4_iface(const atf_tc_t *tc)
88e02d3fe7SAlexander V. Chernikov {
89e02d3fe7SAlexander V. Chernikov struct rtsock_test_config *c;
90e02d3fe7SAlexander V. Chernikov int ret;
91e02d3fe7SAlexander V. Chernikov
92272bd698SAlexander V. Chernikov c = config_setup(tc, NULL);
9367f2f67fSAlex Richardson ATF_REQUIRE(c != NULL);
94e02d3fe7SAlexander V. Chernikov
95ddc75076SAlexander V. Chernikov jump_vnet(c, tc);
96ddc75076SAlexander V. Chernikov
97e02d3fe7SAlexander V. Chernikov ret = iface_turn_up(c->ifname);
98e02d3fe7SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
9967f2f67fSAlex Richardson ATF_REQUIRE_ERRNO(0, true);
100e02d3fe7SAlexander V. Chernikov
101e02d3fe7SAlexander V. Chernikov return (c);
102e02d3fe7SAlexander V. Chernikov }
103e02d3fe7SAlexander V. Chernikov
104e02d3fe7SAlexander V. Chernikov static inline struct rtsock_test_config *
presetup_ipv4(const atf_tc_t * tc)105775dc861SAlexander V. Chernikov presetup_ipv4(const atf_tc_t *tc)
106775dc861SAlexander V. Chernikov {
107775dc861SAlexander V. Chernikov struct rtsock_test_config *c;
108775dc861SAlexander V. Chernikov int ret;
109775dc861SAlexander V. Chernikov
110e02d3fe7SAlexander V. Chernikov c = presetup_ipv4_iface(tc);
111775dc861SAlexander V. Chernikov
112775dc861SAlexander V. Chernikov /* assumes ifconfig doing IFF_UP */
113775dc861SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
114775dc861SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
115775dc861SAlexander V. Chernikov
116775dc861SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
11767f2f67fSAlex Richardson ATF_REQUIRE_ERRNO(0, true);
118775dc861SAlexander V. Chernikov
119775dc861SAlexander V. Chernikov return (c);
120775dc861SAlexander V. Chernikov }
121775dc861SAlexander V. Chernikov
122775dc861SAlexander V. Chernikov
123775dc861SAlexander V. Chernikov static void
prepare_v4_network(struct rtsock_test_config * c,struct sockaddr_in * dst,struct sockaddr_in * mask,struct sockaddr_in * gw)124775dc861SAlexander V. Chernikov prepare_v4_network(struct rtsock_test_config *c, struct sockaddr_in *dst,
125775dc861SAlexander V. Chernikov struct sockaddr_in *mask, struct sockaddr_in *gw)
126775dc861SAlexander V. Chernikov {
127775dc861SAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
128775dc861SAlexander V. Chernikov sa_fill_mask4(mask, c->plen4 + 1);
129775dc861SAlexander V. Chernikov *dst = c->net4;
130775dc861SAlexander V. Chernikov /* Calculate GW as last-net-address - 1 */
131775dc861SAlexander V. Chernikov *gw = c->net4;
132775dc861SAlexander V. Chernikov gw->sin_addr.s_addr = htonl((ntohl(c->net4.sin_addr.s_addr) | ~ntohl(c->mask4.sin_addr.s_addr)) - 1);
133775dc861SAlexander V. Chernikov sa_print((struct sockaddr *)dst, 0);
134775dc861SAlexander V. Chernikov sa_print((struct sockaddr *)mask, 0);
135775dc861SAlexander V. Chernikov sa_print((struct sockaddr *)gw, 0);
136775dc861SAlexander V. Chernikov }
137775dc861SAlexander V. Chernikov
138775dc861SAlexander V. Chernikov static void
prepare_v6_network(struct rtsock_test_config * c,struct sockaddr_in6 * dst,struct sockaddr_in6 * mask,struct sockaddr_in6 * gw)139775dc861SAlexander V. Chernikov prepare_v6_network(struct rtsock_test_config *c, struct sockaddr_in6 *dst,
140775dc861SAlexander V. Chernikov struct sockaddr_in6 *mask, struct sockaddr_in6 *gw)
141775dc861SAlexander V. Chernikov {
142775dc861SAlexander V. Chernikov /* Create IPv6 subnetwork with smaller prefix */
143775dc861SAlexander V. Chernikov sa_fill_mask6(mask, c->plen6 + 1);
144775dc861SAlexander V. Chernikov *dst = c->net6;
145775dc861SAlexander V. Chernikov /* Calculate GW as last-net-address - 1 */
146775dc861SAlexander V. Chernikov *gw = c->net6;
147775dc861SAlexander V. Chernikov #define _s6_addr32 __u6_addr.__u6_addr32
148775dc861SAlexander V. Chernikov gw->sin6_addr._s6_addr32[0] = htonl((ntohl(gw->sin6_addr._s6_addr32[0]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[0])));
149775dc861SAlexander V. Chernikov gw->sin6_addr._s6_addr32[1] = htonl((ntohl(gw->sin6_addr._s6_addr32[1]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[1])));
150775dc861SAlexander V. Chernikov gw->sin6_addr._s6_addr32[2] = htonl((ntohl(gw->sin6_addr._s6_addr32[2]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[2])));
151775dc861SAlexander V. Chernikov gw->sin6_addr._s6_addr32[3] = htonl((ntohl(gw->sin6_addr._s6_addr32[3]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[3])) - 1);
152775dc861SAlexander V. Chernikov #undef _s6_addr32
153775dc861SAlexander V. Chernikov sa_print((struct sockaddr *)dst, 0);
154775dc861SAlexander V. Chernikov sa_print((struct sockaddr *)mask, 0);
155775dc861SAlexander V. Chernikov sa_print((struct sockaddr *)gw, 0);
156775dc861SAlexander V. Chernikov }
157775dc861SAlexander V. Chernikov
158775dc861SAlexander V. Chernikov static void
prepare_route_message(struct rt_msghdr * rtm,int cmd,struct sockaddr * dst,struct sockaddr * mask,struct sockaddr * gw)159775dc861SAlexander V. Chernikov prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
160775dc861SAlexander V. Chernikov struct sockaddr *mask, struct sockaddr *gw)
161775dc861SAlexander V. Chernikov {
162775dc861SAlexander V. Chernikov
163775dc861SAlexander V. Chernikov rtsock_prepare_route_message(rtm, cmd, dst, mask, gw);
164775dc861SAlexander V. Chernikov
165775dc861SAlexander V. Chernikov if (cmd == RTM_ADD || cmd == RTM_CHANGE)
166775dc861SAlexander V. Chernikov rtm->rtm_flags |= RTF_STATIC;
167775dc861SAlexander V. Chernikov }
168775dc861SAlexander V. Chernikov
169775dc861SAlexander V. Chernikov static void
verify_route_message(struct rt_msghdr * rtm,int cmd,struct sockaddr * dst,struct sockaddr * mask,struct sockaddr * gw)170775dc861SAlexander V. Chernikov verify_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
171775dc861SAlexander V. Chernikov struct sockaddr *mask, struct sockaddr *gw)
172775dc861SAlexander V. Chernikov {
173775dc861SAlexander V. Chernikov char msg[512];
174775dc861SAlexander V. Chernikov struct sockaddr *sa;
175775dc861SAlexander V. Chernikov int ret;
176775dc861SAlexander V. Chernikov
177775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == cmd,
178775dc861SAlexander V. Chernikov "expected %s message, got %d (%s)", rtsock_print_cmdtype(cmd),
179775dc861SAlexander V. Chernikov rtm->rtm_type, rtsock_print_cmdtype(rtm->rtm_type));
180775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_errno == 0,
181775dc861SAlexander V. Chernikov "got got errno %d as message reply", rtm->rtm_errno);
182775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->_rtm_spare1 == 0,
183775dc861SAlexander V. Chernikov "expected rtm_spare==0, got %d", rtm->_rtm_spare1);
184775dc861SAlexander V. Chernikov
185775dc861SAlexander V. Chernikov /* kernel MAY return more sockaddrs, including RTA_IFP / RTA_IFA, so verify the needed ones */
186775dc861SAlexander V. Chernikov if (dst != NULL) {
187775dc861SAlexander V. Chernikov sa = rtsock_find_rtm_sa(rtm, RTA_DST);
188775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "DST is not set");
189775dc861SAlexander V. Chernikov ret = sa_equal_msg(sa, dst, msg, sizeof(msg));
190775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
191775dc861SAlexander V. Chernikov }
192775dc861SAlexander V. Chernikov
193775dc861SAlexander V. Chernikov if (mask != NULL) {
194775dc861SAlexander V. Chernikov sa = rtsock_find_rtm_sa(rtm, RTA_NETMASK);
195775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "NETMASK is not set");
196775dc861SAlexander V. Chernikov ret = sa_equal_msg(sa, mask, msg, sizeof(msg));
19734a5582cSAlexander V. Chernikov ret = 1;
198775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "NETMASK sa diff: %s", msg);
199775dc861SAlexander V. Chernikov }
200775dc861SAlexander V. Chernikov
201775dc861SAlexander V. Chernikov if (gw != NULL) {
202775dc861SAlexander V. Chernikov sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
203775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
204775dc861SAlexander V. Chernikov ret = sa_equal_msg(sa, gw, msg, sizeof(msg));
205775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
206775dc861SAlexander V. Chernikov }
207775dc861SAlexander V. Chernikov }
208775dc861SAlexander V. Chernikov
209775dc861SAlexander V. Chernikov static void
verify_route_message_extra(struct rt_msghdr * rtm,int ifindex,int rtm_flags)210775dc861SAlexander V. Chernikov verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags)
211775dc861SAlexander V. Chernikov {
212775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex,
213775dc861SAlexander V. Chernikov "expected ifindex %d, got %d", ifindex, rtm->rtm_index);
214775dc861SAlexander V. Chernikov
215ac0bea76SAlexander V. Chernikov if (rtm->rtm_flags != rtm_flags) {
216ac0bea76SAlexander V. Chernikov char got_flags[64], expected_flags[64];
217ac0bea76SAlexander V. Chernikov rtsock_print_rtm_flags(got_flags, sizeof(got_flags),
218ac0bea76SAlexander V. Chernikov rtm->rtm_flags);
219ac0bea76SAlexander V. Chernikov rtsock_print_rtm_flags(expected_flags, sizeof(expected_flags),
220ac0bea76SAlexander V. Chernikov rtm_flags);
221ac0bea76SAlexander V. Chernikov
222775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == rtm_flags,
223ac0bea76SAlexander V. Chernikov "expected flags: 0x%X %s, got 0x%X %s",
224ac0bea76SAlexander V. Chernikov rtm_flags, expected_flags,
225ac0bea76SAlexander V. Chernikov rtm->rtm_flags, got_flags);
226ac0bea76SAlexander V. Chernikov }
227e02d3fe7SAlexander V. Chernikov }
228e02d3fe7SAlexander V. Chernikov
229e02d3fe7SAlexander V. Chernikov static void
verify_link_gateway(struct rt_msghdr * rtm,int ifindex)230e02d3fe7SAlexander V. Chernikov verify_link_gateway(struct rt_msghdr *rtm, int ifindex)
231e02d3fe7SAlexander V. Chernikov {
232e02d3fe7SAlexander V. Chernikov struct sockaddr *sa;
233e02d3fe7SAlexander V. Chernikov struct sockaddr_dl *sdl;
234e02d3fe7SAlexander V. Chernikov
235e02d3fe7SAlexander V. Chernikov sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
236e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
237e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);
238e02d3fe7SAlexander V. Chernikov sdl = (struct sockaddr_dl *)sa;
239e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == ifindex, "GW ifindex is %d", sdl->sdl_index);
240775dc861SAlexander V. Chernikov }
241775dc861SAlexander V. Chernikov
242775dc861SAlexander V. Chernikov /* TESTS */
243775dc861SAlexander V. Chernikov
244775dc861SAlexander V. Chernikov #define DECLARE_TEST_VARS \
245775dc861SAlexander V. Chernikov char buffer[2048]; \
246775dc861SAlexander V. Chernikov struct rtsock_test_config *c; \
247775dc861SAlexander V. Chernikov struct rt_msghdr *rtm = (struct rt_msghdr *)buffer; \
248775dc861SAlexander V. Chernikov struct sockaddr *sa; \
249775dc861SAlexander V. Chernikov int ret; \
250775dc861SAlexander V. Chernikov \
251775dc861SAlexander V. Chernikov
252775dc861SAlexander V. Chernikov #define DESCRIBE_ROOT_TEST(_msg) config_describe_root_test(tc, _msg)
253ddc75076SAlexander V. Chernikov #define CLEANUP_AFTER_TEST config_generic_cleanup(tc)
254775dc861SAlexander V. Chernikov
255e02d3fe7SAlexander V. Chernikov #define RTM_DECLARE_ROOT_TEST(_name, _descr) \
256e02d3fe7SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(_name); \
257e02d3fe7SAlexander V. Chernikov ATF_TC_HEAD(_name, tc) \
258e02d3fe7SAlexander V. Chernikov { \
259e02d3fe7SAlexander V. Chernikov DESCRIBE_ROOT_TEST(_descr); \
260e02d3fe7SAlexander V. Chernikov } \
261e02d3fe7SAlexander V. Chernikov ATF_TC_CLEANUP(_name, tc) \
262e02d3fe7SAlexander V. Chernikov { \
263e02d3fe7SAlexander V. Chernikov CLEANUP_AFTER_TEST; \
264e02d3fe7SAlexander V. Chernikov }
265775dc861SAlexander V. Chernikov
266775dc861SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_get_v4_exact_success);
ATF_TC_HEAD(rtm_get_v4_exact_success,tc)267775dc861SAlexander V. Chernikov ATF_TC_HEAD(rtm_get_v4_exact_success, tc)
268775dc861SAlexander V. Chernikov {
269775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests RTM_GET with exact prefix lookup on an interface prefix");
270775dc861SAlexander V. Chernikov }
271775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_get_v4_exact_success,tc)272775dc861SAlexander V. Chernikov ATF_TC_BODY(rtm_get_v4_exact_success, tc)
273775dc861SAlexander V. Chernikov {
274775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
275775dc861SAlexander V. Chernikov
276775dc861SAlexander V. Chernikov c = presetup_ipv4(tc);
277775dc861SAlexander V. Chernikov
278775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
279775dc861SAlexander V. Chernikov (struct sockaddr *)&c->mask4, NULL);
280775dc861SAlexander V. Chernikov
281775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
282775dc861SAlexander V. Chernikov
283775dc861SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
284775dc861SAlexander V. Chernikov
285775dc861SAlexander V. Chernikov /*
286775dc861SAlexander V. Chernikov * RTM_GET: Report Metrics: len 240, pid: 45072, seq 42, errno 0, flags: <UP,DONE,PINNED>
287775dc861SAlexander V. Chernikov * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
288775dc861SAlexander V. Chernikov * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
289775dc861SAlexander V. Chernikov * af=link len=54 sdl_index=3 if_name=tap4242 hd={36, 12, 03, 00, 06, 00{49}}
290775dc861SAlexander V. Chernikov * af=inet len=16 addr=255.255.255.0 hd={10, 02, FF{5}, 00{9}}
291775dc861SAlexander V. Chernikov */
292775dc861SAlexander V. Chernikov
293775dc861SAlexander V. Chernikov verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
294775dc861SAlexander V. Chernikov (struct sockaddr *)&c->mask4, NULL);
295775dc861SAlexander V. Chernikov
296775dc861SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
297775dc861SAlexander V. Chernikov
298775dc861SAlexander V. Chernikov /* Explicitly verify gateway for the interface route */
299e02d3fe7SAlexander V. Chernikov verify_link_gateway(rtm, c->ifindex);
300775dc861SAlexander V. Chernikov sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
301775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
302775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);
303775dc861SAlexander V. Chernikov struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
304775dc861SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == c->ifindex, "GW ifindex is %d", sdl->sdl_index);
305775dc861SAlexander V. Chernikov }
306775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_get_v4_exact_success,tc)307775dc861SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_get_v4_exact_success, tc)
308775dc861SAlexander V. Chernikov {
309775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
310775dc861SAlexander V. Chernikov }
311775dc861SAlexander V. Chernikov
312775dc861SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_get_v4_lpm_success);
ATF_TC_HEAD(rtm_get_v4_lpm_success,tc)313775dc861SAlexander V. Chernikov ATF_TC_HEAD(rtm_get_v4_lpm_success, tc)
314775dc861SAlexander V. Chernikov {
315775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests RTM_GET with address lookup on an existing prefix");
316775dc861SAlexander V. Chernikov }
317775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_get_v4_lpm_success,tc)318775dc861SAlexander V. Chernikov ATF_TC_BODY(rtm_get_v4_lpm_success, tc)
319775dc861SAlexander V. Chernikov {
320775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
321775dc861SAlexander V. Chernikov
322775dc861SAlexander V. Chernikov c = presetup_ipv4(tc);
323775dc861SAlexander V. Chernikov
324775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, NULL, NULL);
325775dc861SAlexander V. Chernikov
326775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
327775dc861SAlexander V. Chernikov
328e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
329775dc861SAlexander V. Chernikov
330775dc861SAlexander V. Chernikov /*
331775dc861SAlexander V. Chernikov * RTM_GET: Report Metrics: len 312, pid: 67074, seq 1, errno 0, flags:<UP,DONE,PINNED>
332775dc861SAlexander V. Chernikov * locks: inits:
333775dc861SAlexander V. Chernikov * sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
334775dc861SAlexander V. Chernikov * 10.0.0.0 link#1 255.255.255.0 vtnet0:52.54.0.42.f.ef 10.0.0.157
335775dc861SAlexander V. Chernikov */
336775dc861SAlexander V. Chernikov
337775dc861SAlexander V. Chernikov verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
338775dc861SAlexander V. Chernikov (struct sockaddr *)&c->mask4, NULL);
339775dc861SAlexander V. Chernikov
340775dc861SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
341775dc861SAlexander V. Chernikov }
342775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_get_v4_lpm_success,tc)343775dc861SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_get_v4_lpm_success, tc)
344775dc861SAlexander V. Chernikov {
345775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
346775dc861SAlexander V. Chernikov }
347775dc861SAlexander V. Chernikov
348775dc861SAlexander V. Chernikov
349775dc861SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_get_v4_empty_dst_failure);
ATF_TC_HEAD(rtm_get_v4_empty_dst_failure,tc)350775dc861SAlexander V. Chernikov ATF_TC_HEAD(rtm_get_v4_empty_dst_failure, tc)
351775dc861SAlexander V. Chernikov {
352775dc861SAlexander V. Chernikov
353775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests RTM_GET with empty DST addr");
354775dc861SAlexander V. Chernikov }
355775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_get_v4_empty_dst_failure,tc)356775dc861SAlexander V. Chernikov ATF_TC_BODY(rtm_get_v4_empty_dst_failure, tc)
357775dc861SAlexander V. Chernikov {
358775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
359272bd698SAlexander V. Chernikov struct rtsock_config_options co;
360775dc861SAlexander V. Chernikov
361272bd698SAlexander V. Chernikov bzero(&co, sizeof(co));
362272bd698SAlexander V. Chernikov co.num_interfaces = 0;
363272bd698SAlexander V. Chernikov
364272bd698SAlexander V. Chernikov c = config_setup(tc,&co);
365775dc861SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
366775dc861SAlexander V. Chernikov
367775dc861SAlexander V. Chernikov rtsock_prepare_route_message(rtm, RTM_GET, NULL,
368775dc861SAlexander V. Chernikov (struct sockaddr *)&c->mask4, NULL);
369775dc861SAlexander V. Chernikov rtsock_update_rtm_len(rtm);
370775dc861SAlexander V. Chernikov
37167f2f67fSAlex Richardson ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen) == -1);
372775dc861SAlexander V. Chernikov }
373775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure,tc)374775dc861SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure, tc)
375775dc861SAlexander V. Chernikov {
376775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
377775dc861SAlexander V. Chernikov }
378775dc861SAlexander V. Chernikov
37967f2f67fSAlex Richardson ATF_TC_WITH_CLEANUP(rtm_get_v4_hostbits_success);
ATF_TC_HEAD(rtm_get_v4_hostbits_success,tc)38067f2f67fSAlex Richardson ATF_TC_HEAD(rtm_get_v4_hostbits_success, tc)
381775dc861SAlexander V. Chernikov {
382775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests RTM_GET with prefix with some hosts-bits set");
383775dc861SAlexander V. Chernikov }
384775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_get_v4_hostbits_success,tc)38567f2f67fSAlex Richardson ATF_TC_BODY(rtm_get_v4_hostbits_success, tc)
386775dc861SAlexander V. Chernikov {
387775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
388775dc861SAlexander V. Chernikov
389775dc861SAlexander V. Chernikov c = presetup_ipv4(tc);
390775dc861SAlexander V. Chernikov
391775dc861SAlexander V. Chernikov /* Q the same prefix */
392775dc861SAlexander V. Chernikov rtsock_prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->addr4,
393775dc861SAlexander V. Chernikov (struct sockaddr *)&c->mask4, NULL);
394775dc861SAlexander V. Chernikov rtsock_update_rtm_len(rtm);
395775dc861SAlexander V. Chernikov
39667f2f67fSAlex Richardson ATF_REQUIRE_ERRNO(0, true);
39767f2f67fSAlex Richardson ATF_CHECK_ERRNO(0, write(c->rtsock_fd, rtm, rtm->rtm_msglen) > 0);
398775dc861SAlexander V. Chernikov }
399775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_get_v4_hostbits_success,tc)40067f2f67fSAlex Richardson ATF_TC_CLEANUP(rtm_get_v4_hostbits_success, tc)
401775dc861SAlexander V. Chernikov {
402775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
403775dc861SAlexander V. Chernikov }
404775dc861SAlexander V. Chernikov
405775dc861SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success);
ATF_TC_HEAD(rtm_add_v4_gw_direct_success,tc)406775dc861SAlexander V. Chernikov ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc)
407775dc861SAlexander V. Chernikov {
408775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP");
409775dc861SAlexander V. Chernikov }
410775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v4_gw_direct_success,tc)411775dc861SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc)
412775dc861SAlexander V. Chernikov {
413775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
414775dc861SAlexander V. Chernikov
415775dc861SAlexander V. Chernikov c = presetup_ipv4(tc);
416775dc861SAlexander V. Chernikov
417775dc861SAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
418775dc861SAlexander V. Chernikov struct sockaddr_in mask4;
419775dc861SAlexander V. Chernikov struct sockaddr_in net4;
420775dc861SAlexander V. Chernikov struct sockaddr_in gw4;
421775dc861SAlexander V. Chernikov prepare_v4_network(c, &net4, &mask4, &gw4);
422775dc861SAlexander V. Chernikov
423775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
424775dc861SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
425775dc861SAlexander V. Chernikov
426775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
427775dc861SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
428775dc861SAlexander V. Chernikov
429775dc861SAlexander V. Chernikov /*
430775dc861SAlexander V. Chernikov * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
431775dc861SAlexander V. Chernikov * locks: inits:
432775dc861SAlexander V. Chernikov * sockaddrs: <DST,GATEWAY,NETMASK>
433775dc861SAlexander V. Chernikov * 192.0.2.0 192.0.2.254 255.255.255.128
434775dc861SAlexander V. Chernikov */
435775dc861SAlexander V. Chernikov
436775dc861SAlexander V. Chernikov verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
437775dc861SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
4381b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex,
4391b95005eSAlexander V. Chernikov RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
440775dc861SAlexander V. Chernikov }
441775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success,tc)442775dc861SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc)
443775dc861SAlexander V. Chernikov {
444775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
445775dc861SAlexander V. Chernikov }
446775dc861SAlexander V. Chernikov
44767f2f67fSAlex Richardson RTM_DECLARE_ROOT_TEST(rtm_add_v4_no_rtf_host_success,
44867f2f67fSAlex Richardson "Tests success with netmask sa and RTF_HOST inconsistency");
4495676d488SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v4_no_rtf_host_success,tc)45067f2f67fSAlex Richardson ATF_TC_BODY(rtm_add_v4_no_rtf_host_success, tc)
4515676d488SAlexander V. Chernikov {
4525676d488SAlexander V. Chernikov DECLARE_TEST_VARS;
4535676d488SAlexander V. Chernikov
4545676d488SAlexander V. Chernikov c = presetup_ipv4(tc);
4555676d488SAlexander V. Chernikov
4565676d488SAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
4575676d488SAlexander V. Chernikov struct sockaddr_in mask4;
4585676d488SAlexander V. Chernikov struct sockaddr_in net4;
4595676d488SAlexander V. Chernikov struct sockaddr_in gw4;
4605676d488SAlexander V. Chernikov prepare_v4_network(c, &net4, &mask4, &gw4);
4615676d488SAlexander V. Chernikov
4625676d488SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
4635676d488SAlexander V. Chernikov NULL, (struct sockaddr *)&gw4);
4645676d488SAlexander V. Chernikov rtsock_update_rtm_len(rtm);
4655676d488SAlexander V. Chernikov
4665676d488SAlexander V. Chernikov /* RTF_HOST is NOT specified, while netmask is empty */
46767f2f67fSAlex Richardson ATF_REQUIRE_ERRNO(0, true);
46867f2f67fSAlex Richardson ATF_CHECK_ERRNO(0, write(c->rtsock_fd, rtm, rtm->rtm_msglen) > 0);
4695676d488SAlexander V. Chernikov }
4705676d488SAlexander V. Chernikov
471775dc861SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success);
ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success,tc)472775dc861SAlexander V. Chernikov ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc)
473775dc861SAlexander V. Chernikov {
474775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway");
475775dc861SAlexander V. Chernikov }
476775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_del_v4_prefix_nogw_success,tc)477775dc861SAlexander V. Chernikov ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, tc)
478775dc861SAlexander V. Chernikov {
479775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
480775dc861SAlexander V. Chernikov
481775dc861SAlexander V. Chernikov c = presetup_ipv4(tc);
482775dc861SAlexander V. Chernikov
483775dc861SAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
484775dc861SAlexander V. Chernikov struct sockaddr_in mask4;
485775dc861SAlexander V. Chernikov struct sockaddr_in net4;
486775dc861SAlexander V. Chernikov struct sockaddr_in gw4;
487775dc861SAlexander V. Chernikov prepare_v4_network(c, &net4, &mask4, &gw4);
488775dc861SAlexander V. Chernikov
489775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
490775dc861SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
491775dc861SAlexander V. Chernikov
492775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
493775dc861SAlexander V. Chernikov
494775dc861SAlexander V. Chernikov /* Route has been added successfully, try to delete it */
495775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
496775dc861SAlexander V. Chernikov (struct sockaddr *)&mask4, NULL);
497775dc861SAlexander V. Chernikov
498775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
499775dc861SAlexander V. Chernikov
500775dc861SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
501775dc861SAlexander V. Chernikov
502775dc861SAlexander V. Chernikov /*
503775dc861SAlexander V. Chernikov * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
504775dc861SAlexander V. Chernikov * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
505775dc861SAlexander V. Chernikov * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
506775dc861SAlexander V. Chernikov * af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
507775dc861SAlexander V. Chernikov * af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
508775dc861SAlexander V. Chernikov */
509775dc861SAlexander V. Chernikov verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
510775dc861SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
511775dc861SAlexander V. Chernikov
512775dc861SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
513775dc861SAlexander V. Chernikov }
514775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success,tc)515775dc861SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc)
516775dc861SAlexander V. Chernikov {
517775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
518775dc861SAlexander V. Chernikov }
519775dc861SAlexander V. Chernikov
520272bd698SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_change_v4_gw_success,
521272bd698SAlexander V. Chernikov "Tests IPv4 gateway change");
522272bd698SAlexander V. Chernikov
ATF_TC_BODY(rtm_change_v4_gw_success,tc)523272bd698SAlexander V. Chernikov ATF_TC_BODY(rtm_change_v4_gw_success, tc)
524272bd698SAlexander V. Chernikov {
525272bd698SAlexander V. Chernikov DECLARE_TEST_VARS;
526272bd698SAlexander V. Chernikov struct rtsock_config_options co;
527272bd698SAlexander V. Chernikov
528272bd698SAlexander V. Chernikov bzero(&co, sizeof(co));
529272bd698SAlexander V. Chernikov co.num_interfaces = 2;
530272bd698SAlexander V. Chernikov
531272bd698SAlexander V. Chernikov c = config_setup(tc, &co);
532272bd698SAlexander V. Chernikov jump_vnet(c, tc);
533272bd698SAlexander V. Chernikov
534272bd698SAlexander V. Chernikov ret = iface_turn_up(c->ifnames[0]);
535272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
536272bd698SAlexander V. Chernikov ret = iface_turn_up(c->ifnames[1]);
537272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
538272bd698SAlexander V. Chernikov
539272bd698SAlexander V. Chernikov ret = iface_setup_addr(c->ifnames[0], c->addr4_str, c->plen4);
540272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
541272bd698SAlexander V. Chernikov
542272bd698SAlexander V. Chernikov /* Use 198.51.100.0/24 "TEST-NET-2" for the second interface */
543272bd698SAlexander V. Chernikov ret = iface_setup_addr(c->ifnames[1], "198.51.100.1", 24);
544272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
545272bd698SAlexander V. Chernikov
546272bd698SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
547272bd698SAlexander V. Chernikov
548272bd698SAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
549272bd698SAlexander V. Chernikov struct sockaddr_in mask4;
550272bd698SAlexander V. Chernikov struct sockaddr_in net4;
551272bd698SAlexander V. Chernikov struct sockaddr_in gw4;
552272bd698SAlexander V. Chernikov prepare_v4_network(c, &net4, &mask4, &gw4);
553272bd698SAlexander V. Chernikov
554272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
555272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
556272bd698SAlexander V. Chernikov
557272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
558272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
559272bd698SAlexander V. Chernikov
560272bd698SAlexander V. Chernikov verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
561272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
562272bd698SAlexander V. Chernikov
563272bd698SAlexander V. Chernikov /* Change gateway to the one on desiding on the other interface */
564272bd698SAlexander V. Chernikov inet_pton(AF_INET, "198.51.100.2", &gw4.sin_addr.s_addr);
565272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
566272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
567272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
568272bd698SAlexander V. Chernikov
569272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
570272bd698SAlexander V. Chernikov
571272bd698SAlexander V. Chernikov verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
572272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
573272bd698SAlexander V. Chernikov
574272bd698SAlexander V. Chernikov verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
5751b95005eSAlexander V. Chernikov RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
576272bd698SAlexander V. Chernikov
577272bd698SAlexander V. Chernikov /* Verify the change has actually taken place */
578272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
579272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, NULL);
580272bd698SAlexander V. Chernikov
581272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
582272bd698SAlexander V. Chernikov
583272bd698SAlexander V. Chernikov /*
584272bd698SAlexander V. Chernikov * RTM_GET: len 200, pid: 3894, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
585272bd698SAlexander V. Chernikov * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
586272bd698SAlexander V. Chernikov * af=inet len=16 addr=192.0.2.0 hd={x10, x02, x00{2}, xC0, x00, x02, x00{9}}
587272bd698SAlexander V. Chernikov * af=inet len=16 addr=198.51.100.2 hd={x10, x02, x00{2}, xC6, x33, x64, x02, x00{8}}
588272bd698SAlexander V. Chernikov * af=inet len=16 addr=255.255.255.128 hd={x10, x02, xFF, xFF, xFF, xFF, xFF, x80, x00{8}}
589272bd698SAlexander V. Chernikov */
590272bd698SAlexander V. Chernikov
591272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
592272bd698SAlexander V. Chernikov verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
593272bd698SAlexander V. Chernikov RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
594272bd698SAlexander V. Chernikov
595272bd698SAlexander V. Chernikov }
596272bd698SAlexander V. Chernikov
597272bd698SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_change_v4_mtu_success,
598272bd698SAlexander V. Chernikov "Tests IPv4 path mtu change");
599272bd698SAlexander V. Chernikov
ATF_TC_BODY(rtm_change_v4_mtu_success,tc)600272bd698SAlexander V. Chernikov ATF_TC_BODY(rtm_change_v4_mtu_success, tc)
601272bd698SAlexander V. Chernikov {
602272bd698SAlexander V. Chernikov DECLARE_TEST_VARS;
603272bd698SAlexander V. Chernikov
604272bd698SAlexander V. Chernikov unsigned long test_mtu = 1442;
605272bd698SAlexander V. Chernikov
606272bd698SAlexander V. Chernikov c = presetup_ipv4(tc);
607272bd698SAlexander V. Chernikov
608272bd698SAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
609272bd698SAlexander V. Chernikov struct sockaddr_in mask4;
610272bd698SAlexander V. Chernikov struct sockaddr_in net4;
611272bd698SAlexander V. Chernikov struct sockaddr_in gw4;
612272bd698SAlexander V. Chernikov prepare_v4_network(c, &net4, &mask4, &gw4);
613272bd698SAlexander V. Chernikov
614272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
615272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
616272bd698SAlexander V. Chernikov
617272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
618272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
619272bd698SAlexander V. Chernikov
620272bd698SAlexander V. Chernikov /* Change MTU */
621272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
622272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, NULL);
623272bd698SAlexander V. Chernikov rtm->rtm_inits |= RTV_MTU;
624272bd698SAlexander V. Chernikov rtm->rtm_rmx.rmx_mtu = test_mtu;
625272bd698SAlexander V. Chernikov
626272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
627272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
628272bd698SAlexander V. Chernikov
629272bd698SAlexander V. Chernikov verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
630272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, NULL);
631272bd698SAlexander V. Chernikov
632272bd698SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
633272bd698SAlexander V. Chernikov "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
634272bd698SAlexander V. Chernikov
635272bd698SAlexander V. Chernikov /* Verify the change has actually taken place */
636272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
637272bd698SAlexander V. Chernikov (struct sockaddr *)&mask4, NULL);
638272bd698SAlexander V. Chernikov
639272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
640272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
641272bd698SAlexander V. Chernikov
642272bd698SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
643272bd698SAlexander V. Chernikov "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
644272bd698SAlexander V. Chernikov }
645272bd698SAlexander V. Chernikov
6461b95005eSAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_change_v4_flags_success,
6471b95005eSAlexander V. Chernikov "Tests IPv4 path flags change");
6481b95005eSAlexander V. Chernikov
ATF_TC_BODY(rtm_change_v4_flags_success,tc)6491b95005eSAlexander V. Chernikov ATF_TC_BODY(rtm_change_v4_flags_success, tc)
6501b95005eSAlexander V. Chernikov {
6511b95005eSAlexander V. Chernikov DECLARE_TEST_VARS;
6521b95005eSAlexander V. Chernikov
6531b95005eSAlexander V. Chernikov uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
6541b95005eSAlexander V. Chernikov uint32_t desired_flags;
6551b95005eSAlexander V. Chernikov
6561b95005eSAlexander V. Chernikov c = presetup_ipv4(tc);
6571b95005eSAlexander V. Chernikov
6581b95005eSAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
6591b95005eSAlexander V. Chernikov struct sockaddr_in mask4;
6601b95005eSAlexander V. Chernikov struct sockaddr_in net4;
6611b95005eSAlexander V. Chernikov struct sockaddr_in gw4;
6621b95005eSAlexander V. Chernikov prepare_v4_network(c, &net4, &mask4, &gw4);
6631b95005eSAlexander V. Chernikov
6641b95005eSAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
6651b95005eSAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
6661b95005eSAlexander V. Chernikov
6671b95005eSAlexander V. Chernikov /* Set test flags during route addition */
6681b95005eSAlexander V. Chernikov desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;
6691b95005eSAlexander V. Chernikov rtm->rtm_flags |= test_flags;
6701b95005eSAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
6711b95005eSAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
6721b95005eSAlexander V. Chernikov
6731b95005eSAlexander V. Chernikov /* Change flags */
6741b95005eSAlexander V. Chernikov prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
6751b95005eSAlexander V. Chernikov (struct sockaddr *)&mask4, NULL);
6761b95005eSAlexander V. Chernikov rtm->rtm_flags &= ~test_flags;
6771b95005eSAlexander V. Chernikov desired_flags &= ~test_flags;
6781b95005eSAlexander V. Chernikov
6791b95005eSAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
6801b95005eSAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
6811b95005eSAlexander V. Chernikov
6821b95005eSAlexander V. Chernikov /* Verify updated flags */
6831b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
6841b95005eSAlexander V. Chernikov
6851b95005eSAlexander V. Chernikov /* Verify the change has actually taken place */
6861b95005eSAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
6871b95005eSAlexander V. Chernikov (struct sockaddr *)&mask4, NULL);
6881b95005eSAlexander V. Chernikov
6891b95005eSAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
6901b95005eSAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
6911b95005eSAlexander V. Chernikov
6921b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
6931b95005eSAlexander V. Chernikov }
6941b95005eSAlexander V. Chernikov
695272bd698SAlexander V. Chernikov
696775dc861SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success);
ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success,tc)697775dc861SAlexander V. Chernikov ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc)
698775dc861SAlexander V. Chernikov {
699775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
700775dc861SAlexander V. Chernikov }
701775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success,tc)702775dc861SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc)
703775dc861SAlexander V. Chernikov {
704775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
705775dc861SAlexander V. Chernikov
706775dc861SAlexander V. Chernikov c = presetup_ipv6(tc);
707775dc861SAlexander V. Chernikov
708775dc861SAlexander V. Chernikov /* Create IPv6 subnetwork with smaller prefix */
709775dc861SAlexander V. Chernikov struct sockaddr_in6 mask6;
710775dc861SAlexander V. Chernikov struct sockaddr_in6 net6;
711775dc861SAlexander V. Chernikov struct sockaddr_in6 gw6;
712775dc861SAlexander V. Chernikov prepare_v6_network(c, &net6, &mask6, &gw6);
713775dc861SAlexander V. Chernikov
714775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
715775dc861SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
716775dc861SAlexander V. Chernikov
717775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
718775dc861SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
719775dc861SAlexander V. Chernikov
720775dc861SAlexander V. Chernikov /*
721775dc861SAlexander V. Chernikov * RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
722775dc861SAlexander V. Chernikov * locks: inits:
723775dc861SAlexander V. Chernikov * sockaddrs: <DST,GATEWAY,NETMASK>
724775dc861SAlexander V. Chernikov * 192.0.2.0 192.0.2.254 255.255.255.128
725775dc861SAlexander V. Chernikov */
726775dc861SAlexander V. Chernikov
727775dc861SAlexander V. Chernikov verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
728775dc861SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
729775dc861SAlexander V. Chernikov
7301b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex,
7311b95005eSAlexander V. Chernikov RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
732775dc861SAlexander V. Chernikov }
733775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success,tc)734775dc861SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc)
735775dc861SAlexander V. Chernikov {
736775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
737775dc861SAlexander V. Chernikov }
738775dc861SAlexander V. Chernikov
739775dc861SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success);
ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success,tc)740775dc861SAlexander V. Chernikov ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc)
741775dc861SAlexander V. Chernikov {
742775dc861SAlexander V. Chernikov
743775dc861SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway");
744775dc861SAlexander V. Chernikov }
745775dc861SAlexander V. Chernikov
ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success,tc)746775dc861SAlexander V. Chernikov ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc)
747775dc861SAlexander V. Chernikov {
748775dc861SAlexander V. Chernikov DECLARE_TEST_VARS;
749775dc861SAlexander V. Chernikov
750775dc861SAlexander V. Chernikov c = presetup_ipv6(tc);
751775dc861SAlexander V. Chernikov
752775dc861SAlexander V. Chernikov /* Create IPv6 subnetwork with smaller prefix */
753775dc861SAlexander V. Chernikov struct sockaddr_in6 mask6;
754775dc861SAlexander V. Chernikov struct sockaddr_in6 net6;
755775dc861SAlexander V. Chernikov struct sockaddr_in6 gw6;
756775dc861SAlexander V. Chernikov prepare_v6_network(c, &net6, &mask6, &gw6);
757775dc861SAlexander V. Chernikov
758775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
759775dc861SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
760775dc861SAlexander V. Chernikov
761775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
762775dc861SAlexander V. Chernikov
763775dc861SAlexander V. Chernikov /* Route has been added successfully, try to delete it */
764775dc861SAlexander V. Chernikov prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
765775dc861SAlexander V. Chernikov (struct sockaddr *)&mask6, NULL);
766775dc861SAlexander V. Chernikov
767775dc861SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
768775dc861SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
769775dc861SAlexander V. Chernikov
770775dc861SAlexander V. Chernikov /*
771775dc861SAlexander V. Chernikov * RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
772775dc861SAlexander V. Chernikov * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
773775dc861SAlexander V. Chernikov * af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
774775dc861SAlexander V. Chernikov * af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
775775dc861SAlexander V. Chernikov * af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
776775dc861SAlexander V. Chernikov */
777775dc861SAlexander V. Chernikov
778775dc861SAlexander V. Chernikov verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
779775dc861SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
780775dc861SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
781775dc861SAlexander V. Chernikov }
782775dc861SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success,tc)783775dc861SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc)
784775dc861SAlexander V. Chernikov {
785775dc861SAlexander V. Chernikov CLEANUP_AFTER_TEST;
786775dc861SAlexander V. Chernikov }
787775dc861SAlexander V. Chernikov
788272bd698SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_change_v6_gw_success,
789272bd698SAlexander V. Chernikov "Tests IPv6 gateway change");
790272bd698SAlexander V. Chernikov
ATF_TC_BODY(rtm_change_v6_gw_success,tc)791272bd698SAlexander V. Chernikov ATF_TC_BODY(rtm_change_v6_gw_success, tc)
792272bd698SAlexander V. Chernikov {
793272bd698SAlexander V. Chernikov DECLARE_TEST_VARS;
794272bd698SAlexander V. Chernikov struct rtsock_config_options co;
795272bd698SAlexander V. Chernikov
796272bd698SAlexander V. Chernikov bzero(&co, sizeof(co));
797272bd698SAlexander V. Chernikov co.num_interfaces = 2;
798272bd698SAlexander V. Chernikov
799272bd698SAlexander V. Chernikov c = config_setup(tc, &co);
800272bd698SAlexander V. Chernikov jump_vnet(c, tc);
801272bd698SAlexander V. Chernikov
802272bd698SAlexander V. Chernikov ret = iface_turn_up(c->ifnames[0]);
803272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
804272bd698SAlexander V. Chernikov ret = iface_turn_up(c->ifnames[1]);
805272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
806272bd698SAlexander V. Chernikov
807272bd698SAlexander V. Chernikov ret = iface_enable_ipv6(c->ifnames[0]);
808272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[0]);
809272bd698SAlexander V. Chernikov ret = iface_enable_ipv6(c->ifnames[1]);
810272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[1]);
811272bd698SAlexander V. Chernikov
812272bd698SAlexander V. Chernikov ret = iface_setup_addr(c->ifnames[0], c->addr6_str, c->plen6);
813272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
814272bd698SAlexander V. Chernikov
815272bd698SAlexander V. Chernikov ret = iface_setup_addr(c->ifnames[1], "2001:DB8:4242::1", 64);
816272bd698SAlexander V. Chernikov ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
817272bd698SAlexander V. Chernikov
818272bd698SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
819272bd698SAlexander V. Chernikov
820272bd698SAlexander V. Chernikov /* Create IPv6 subnetwork with smaller prefix */
821272bd698SAlexander V. Chernikov struct sockaddr_in6 mask6;
822272bd698SAlexander V. Chernikov struct sockaddr_in6 net6;
823272bd698SAlexander V. Chernikov struct sockaddr_in6 gw6;
824272bd698SAlexander V. Chernikov prepare_v6_network(c, &net6, &mask6, &gw6);
825272bd698SAlexander V. Chernikov
826272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
827272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
828272bd698SAlexander V. Chernikov
829272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
830272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
831272bd698SAlexander V. Chernikov
832272bd698SAlexander V. Chernikov verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
833272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
834272bd698SAlexander V. Chernikov
835272bd698SAlexander V. Chernikov /* Change gateway to the one on residing on the other interface */
836272bd698SAlexander V. Chernikov inet_pton(AF_INET6, "2001:DB8:4242::4242", &gw6.sin6_addr);
837272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
838272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
839272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
840272bd698SAlexander V. Chernikov
841272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
842272bd698SAlexander V. Chernikov
843272bd698SAlexander V. Chernikov verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
844272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
845272bd698SAlexander V. Chernikov
846272bd698SAlexander V. Chernikov verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
8471b95005eSAlexander V. Chernikov RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
848272bd698SAlexander V. Chernikov
849272bd698SAlexander V. Chernikov /* Verify the change has actually taken place */
850272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
851272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, NULL);
852272bd698SAlexander V. Chernikov
853272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
854272bd698SAlexander V. Chernikov
855272bd698SAlexander V. Chernikov /*
856272bd698SAlexander V. Chernikov * RTM_GET: len 248, pid: 2268, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
857272bd698SAlexander V. Chernikov * sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
858272bd698SAlexander V. Chernikov * af=inet6 len=28 addr=2001:db8:: hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x00{16}}
859272bd698SAlexander V. Chernikov * af=inet6 len=28 addr=2001:db8:4242::4242 hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x42, x42, x00{8}, x42, x42, x00{4}}
860272bd698SAlexander V. Chernikov * af=inet6 len=28 addr=ffff:ffff:8000:: hd={x1C, x1C, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x80, x00{15}}
861272bd698SAlexander V. Chernikov */
862272bd698SAlexander V. Chernikov
863272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
864272bd698SAlexander V. Chernikov verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
865272bd698SAlexander V. Chernikov RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
866272bd698SAlexander V. Chernikov }
867272bd698SAlexander V. Chernikov
868272bd698SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_change_v6_mtu_success,
869272bd698SAlexander V. Chernikov "Tests IPv6 path mtu change");
870272bd698SAlexander V. Chernikov
ATF_TC_BODY(rtm_change_v6_mtu_success,tc)871272bd698SAlexander V. Chernikov ATF_TC_BODY(rtm_change_v6_mtu_success, tc)
872272bd698SAlexander V. Chernikov {
873272bd698SAlexander V. Chernikov DECLARE_TEST_VARS;
874272bd698SAlexander V. Chernikov
875272bd698SAlexander V. Chernikov unsigned long test_mtu = 1442;
876272bd698SAlexander V. Chernikov
877272bd698SAlexander V. Chernikov c = presetup_ipv6(tc);
878272bd698SAlexander V. Chernikov
879272bd698SAlexander V. Chernikov /* Create IPv6 subnetwork with smaller prefix */
880272bd698SAlexander V. Chernikov struct sockaddr_in6 mask6;
881272bd698SAlexander V. Chernikov struct sockaddr_in6 net6;
882272bd698SAlexander V. Chernikov struct sockaddr_in6 gw6;
883272bd698SAlexander V. Chernikov prepare_v6_network(c, &net6, &mask6, &gw6);
884272bd698SAlexander V. Chernikov
885272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
886272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
887272bd698SAlexander V. Chernikov
888272bd698SAlexander V. Chernikov /* Send route add */
889272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
890272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
891272bd698SAlexander V. Chernikov
892272bd698SAlexander V. Chernikov /* Change MTU */
893272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
894272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, NULL);
895272bd698SAlexander V. Chernikov rtm->rtm_inits |= RTV_MTU;
896272bd698SAlexander V. Chernikov rtm->rtm_rmx.rmx_mtu = test_mtu;
897272bd698SAlexander V. Chernikov
898272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
899272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
900272bd698SAlexander V. Chernikov
901272bd698SAlexander V. Chernikov verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
902272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, NULL);
903272bd698SAlexander V. Chernikov
904272bd698SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
905272bd698SAlexander V. Chernikov "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
906272bd698SAlexander V. Chernikov
907272bd698SAlexander V. Chernikov /* Verify the change has actually taken place */
908272bd698SAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
909272bd698SAlexander V. Chernikov (struct sockaddr *)&mask6, NULL);
910272bd698SAlexander V. Chernikov
911272bd698SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
912272bd698SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
913272bd698SAlexander V. Chernikov
914272bd698SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
915272bd698SAlexander V. Chernikov "expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
916272bd698SAlexander V. Chernikov }
917272bd698SAlexander V. Chernikov
9181b95005eSAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_change_v6_flags_success,
9191b95005eSAlexander V. Chernikov "Tests IPv6 path flags change");
9201b95005eSAlexander V. Chernikov
ATF_TC_BODY(rtm_change_v6_flags_success,tc)9211b95005eSAlexander V. Chernikov ATF_TC_BODY(rtm_change_v6_flags_success, tc)
9221b95005eSAlexander V. Chernikov {
9231b95005eSAlexander V. Chernikov DECLARE_TEST_VARS;
9241b95005eSAlexander V. Chernikov
9251b95005eSAlexander V. Chernikov uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
9261b95005eSAlexander V. Chernikov uint32_t desired_flags;
9271b95005eSAlexander V. Chernikov
9281b95005eSAlexander V. Chernikov c = presetup_ipv6(tc);
9291b95005eSAlexander V. Chernikov
9301b95005eSAlexander V. Chernikov /* Create IPv6 subnetwork with smaller prefix */
9311b95005eSAlexander V. Chernikov struct sockaddr_in6 mask6;
9321b95005eSAlexander V. Chernikov struct sockaddr_in6 net6;
9331b95005eSAlexander V. Chernikov struct sockaddr_in6 gw6;
9341b95005eSAlexander V. Chernikov prepare_v6_network(c, &net6, &mask6, &gw6);
9351b95005eSAlexander V. Chernikov
9361b95005eSAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
9371b95005eSAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
9381b95005eSAlexander V. Chernikov
9391b95005eSAlexander V. Chernikov /* Set test flags during route addition */
9401b95005eSAlexander V. Chernikov desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;
9411b95005eSAlexander V. Chernikov rtm->rtm_flags |= test_flags;
9421b95005eSAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
9431b95005eSAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
9441b95005eSAlexander V. Chernikov
9451b95005eSAlexander V. Chernikov /* Change flags */
9461b95005eSAlexander V. Chernikov prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
9471b95005eSAlexander V. Chernikov (struct sockaddr *)&mask6, NULL);
9481b95005eSAlexander V. Chernikov rtm->rtm_flags &= ~test_flags;
9491b95005eSAlexander V. Chernikov desired_flags &= ~test_flags;
9501b95005eSAlexander V. Chernikov
9511b95005eSAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
9521b95005eSAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
9531b95005eSAlexander V. Chernikov
9541b95005eSAlexander V. Chernikov /* Verify updated flags */
9551b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
9561b95005eSAlexander V. Chernikov
9571b95005eSAlexander V. Chernikov /* Verify the change has actually taken place */
9581b95005eSAlexander V. Chernikov prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
9591b95005eSAlexander V. Chernikov (struct sockaddr *)&mask6, NULL);
9601b95005eSAlexander V. Chernikov
9611b95005eSAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
9621b95005eSAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
9631b95005eSAlexander V. Chernikov
9641b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
9651b95005eSAlexander V. Chernikov }
9661b95005eSAlexander V. Chernikov
967e02d3fe7SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success);
ATF_TC_HEAD(rtm_add_v4_temporal1_success,tc)968e02d3fe7SAlexander V. Chernikov ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc)
969e02d3fe7SAlexander V. Chernikov {
970e02d3fe7SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set");
971e02d3fe7SAlexander V. Chernikov }
972e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v4_temporal1_success,tc)973e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v4_temporal1_success, tc)
974e02d3fe7SAlexander V. Chernikov {
975e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
976e02d3fe7SAlexander V. Chernikov
977e02d3fe7SAlexander V. Chernikov c = presetup_ipv4(tc);
978e02d3fe7SAlexander V. Chernikov
979e02d3fe7SAlexander V. Chernikov /* Create IPv4 subnetwork with smaller prefix */
980e02d3fe7SAlexander V. Chernikov struct sockaddr_in mask4;
981e02d3fe7SAlexander V. Chernikov struct sockaddr_in net4;
982e02d3fe7SAlexander V. Chernikov struct sockaddr_in gw4;
983e02d3fe7SAlexander V. Chernikov prepare_v4_network(c, &net4, &mask4, &gw4);
984e02d3fe7SAlexander V. Chernikov
985e02d3fe7SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
986e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
987e02d3fe7SAlexander V. Chernikov
988e02d3fe7SAlexander V. Chernikov /* Set expire time to now */
989e02d3fe7SAlexander V. Chernikov struct timeval tv;
990e02d3fe7SAlexander V. Chernikov gettimeofday(&tv, NULL);
991e02d3fe7SAlexander V. Chernikov rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
992e02d3fe7SAlexander V. Chernikov rtm->rtm_inits |= RTV_EXPIRE;
993e02d3fe7SAlexander V. Chernikov
994e02d3fe7SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
995e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
996e02d3fe7SAlexander V. Chernikov ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
997e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
998e02d3fe7SAlexander V. Chernikov
999e02d3fe7SAlexander V. Chernikov /* The next should be route deletion */
1000e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1001e02d3fe7SAlexander V. Chernikov
1002e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
1003e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
1004e02d3fe7SAlexander V. Chernikov
10051b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex,
10061b95005eSAlexander V. Chernikov RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1007e02d3fe7SAlexander V. Chernikov }
1008e02d3fe7SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_add_v4_temporal1_success,tc)1009e02d3fe7SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc)
1010e02d3fe7SAlexander V. Chernikov {
1011e02d3fe7SAlexander V. Chernikov CLEANUP_AFTER_TEST;
1012e02d3fe7SAlexander V. Chernikov }
1013e02d3fe7SAlexander V. Chernikov
1014e02d3fe7SAlexander V. Chernikov ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success);
ATF_TC_HEAD(rtm_add_v6_temporal1_success,tc)1015e02d3fe7SAlexander V. Chernikov ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc)
1016e02d3fe7SAlexander V. Chernikov {
1017e02d3fe7SAlexander V. Chernikov DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
1018e02d3fe7SAlexander V. Chernikov }
1019e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v6_temporal1_success,tc)1020e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v6_temporal1_success, tc)
1021e02d3fe7SAlexander V. Chernikov {
1022e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1023e02d3fe7SAlexander V. Chernikov
1024e02d3fe7SAlexander V. Chernikov c = presetup_ipv6(tc);
1025e02d3fe7SAlexander V. Chernikov
1026e02d3fe7SAlexander V. Chernikov /* Create IPv6 subnetwork with smaller prefix */
1027e02d3fe7SAlexander V. Chernikov struct sockaddr_in6 mask6;
1028e02d3fe7SAlexander V. Chernikov struct sockaddr_in6 net6;
1029e02d3fe7SAlexander V. Chernikov struct sockaddr_in6 gw6;
1030e02d3fe7SAlexander V. Chernikov prepare_v6_network(c, &net6, &mask6, &gw6);
1031e02d3fe7SAlexander V. Chernikov
1032e02d3fe7SAlexander V. Chernikov prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
1033e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1034e02d3fe7SAlexander V. Chernikov
1035e02d3fe7SAlexander V. Chernikov /* Set expire time to now */
1036e02d3fe7SAlexander V. Chernikov struct timeval tv;
1037e02d3fe7SAlexander V. Chernikov gettimeofday(&tv, NULL);
1038e02d3fe7SAlexander V. Chernikov rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
1039e02d3fe7SAlexander V. Chernikov rtm->rtm_inits |= RTV_EXPIRE;
1040e02d3fe7SAlexander V. Chernikov
1041e02d3fe7SAlexander V. Chernikov rtsock_send_rtm(c->rtsock_fd, rtm);
1042e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
1043e02d3fe7SAlexander V. Chernikov ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
1044e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
1045e02d3fe7SAlexander V. Chernikov
1046e02d3fe7SAlexander V. Chernikov /* The next should be route deletion */
1047e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1048e02d3fe7SAlexander V. Chernikov
1049e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
1050e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1051e02d3fe7SAlexander V. Chernikov
10521b95005eSAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex,
10531b95005eSAlexander V. Chernikov RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1054e02d3fe7SAlexander V. Chernikov }
1055e02d3fe7SAlexander V. Chernikov
ATF_TC_CLEANUP(rtm_add_v6_temporal1_success,tc)1056e02d3fe7SAlexander V. Chernikov ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc)
1057e02d3fe7SAlexander V. Chernikov {
1058e02d3fe7SAlexander V. Chernikov CLEANUP_AFTER_TEST;
1059e02d3fe7SAlexander V. Chernikov }
1060e02d3fe7SAlexander V. Chernikov
1061e02d3fe7SAlexander V. Chernikov /* Interface address messages tests */
1062e02d3fe7SAlexander V. Chernikov
1063e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success,
1064e02d3fe7SAlexander V. Chernikov "Tests validness for /128 host route announce after ifaddr assignment");
1065e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success,tc)1066e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc)
1067e02d3fe7SAlexander V. Chernikov {
1068e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1069e02d3fe7SAlexander V. Chernikov
1070e02d3fe7SAlexander V. Chernikov c = presetup_ipv6_iface(tc);
1071e02d3fe7SAlexander V. Chernikov
1072e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1073e02d3fe7SAlexander V. Chernikov
1074e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1075e02d3fe7SAlexander V. Chernikov
1076e02d3fe7SAlexander V. Chernikov /*
1077e02d3fe7SAlexander V. Chernikov * There will be multiple.
1078e02d3fe7SAlexander V. Chernikov * RTM_ADD without llinfo.
1079e02d3fe7SAlexander V. Chernikov */
1080e02d3fe7SAlexander V. Chernikov
1081e02d3fe7SAlexander V. Chernikov while (true) {
1082e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1083e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0))
1084e02d3fe7SAlexander V. Chernikov break;
1085e02d3fe7SAlexander V. Chernikov }
1086e02d3fe7SAlexander V. Chernikov /* This should be a message for the host route */
1087e02d3fe7SAlexander V. Chernikov
1088e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->addr6, NULL, NULL);
1089e02d3fe7SAlexander V. Chernikov rtsock_validate_pid_kernel(rtm);
1090e02d3fe7SAlexander V. Chernikov /* No netmask should be set */
1091e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
1092e02d3fe7SAlexander V. Chernikov
1093e02d3fe7SAlexander V. Chernikov /* gateway should be link sdl with ifindex of an address interface */
1094e02d3fe7SAlexander V. Chernikov verify_link_gateway(rtm, c->ifindex);
1095e02d3fe7SAlexander V. Chernikov
1096e02d3fe7SAlexander V. Chernikov int expected_rt_flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
1097e02d3fe7SAlexander V. Chernikov verify_route_message_extra(rtm, if_nametoindex("lo0"), expected_rt_flags);
1098e02d3fe7SAlexander V. Chernikov }
1099e02d3fe7SAlexander V. Chernikov
1100e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success,
1101e02d3fe7SAlexander V. Chernikov "Tests validness for the prefix route announce after ifaddr assignment");
1102e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success,tc)1103e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc)
1104e02d3fe7SAlexander V. Chernikov {
1105e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1106e02d3fe7SAlexander V. Chernikov
1107e02d3fe7SAlexander V. Chernikov c = presetup_ipv6_iface(tc);
1108e02d3fe7SAlexander V. Chernikov
1109e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1110e02d3fe7SAlexander V. Chernikov
1111e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1112e02d3fe7SAlexander V. Chernikov
1113e02d3fe7SAlexander V. Chernikov /*
1114e02d3fe7SAlexander V. Chernikov * Multiple RTM_ADD messages will be generated:
1115e02d3fe7SAlexander V. Chernikov * 1) lladdr mapping (RTF_LLDATA)
1116e02d3fe7SAlexander V. Chernikov * 2) host route (one w/o netmask)
1117e02d3fe7SAlexander V. Chernikov * 3) prefix route
1118e02d3fe7SAlexander V. Chernikov */
1119e02d3fe7SAlexander V. Chernikov
1120e02d3fe7SAlexander V. Chernikov while (true) {
1121e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1122e02d3fe7SAlexander V. Chernikov /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1123e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1124e02d3fe7SAlexander V. Chernikov break;
1125e02d3fe7SAlexander V. Chernikov }
1126e02d3fe7SAlexander V. Chernikov
1127e02d3fe7SAlexander V. Chernikov /* This should be a message for the prefix route */
1128e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net6,
1129e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&c->mask6, NULL);
1130e02d3fe7SAlexander V. Chernikov
1131e02d3fe7SAlexander V. Chernikov /* gateway should be link sdl with ifindex of an address interface */
1132e02d3fe7SAlexander V. Chernikov verify_link_gateway(rtm, c->ifindex);
1133e02d3fe7SAlexander V. Chernikov
113481728a53SAlexander V. Chernikov int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1135e02d3fe7SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1136e02d3fe7SAlexander V. Chernikov }
1137e02d3fe7SAlexander V. Chernikov
1138e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success,
1139e02d3fe7SAlexander V. Chernikov "Tests ordering of the messages for IPv6 global unicast ifaddr assignment");
1140e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success,tc)1141e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc)
1142e02d3fe7SAlexander V. Chernikov {
1143e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1144e02d3fe7SAlexander V. Chernikov
1145e02d3fe7SAlexander V. Chernikov c = presetup_ipv6_iface(tc);
1146e02d3fe7SAlexander V. Chernikov
1147e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1148e02d3fe7SAlexander V. Chernikov
1149e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1150e02d3fe7SAlexander V. Chernikov
1151e02d3fe7SAlexander V. Chernikov int count = 0, tries = 0;
1152e02d3fe7SAlexander V. Chernikov
1153e02d3fe7SAlexander V. Chernikov enum msgtype {
1154e02d3fe7SAlexander V. Chernikov MSG_IFADDR,
1155e02d3fe7SAlexander V. Chernikov MSG_HOSTROUTE,
1156e02d3fe7SAlexander V. Chernikov MSG_PREFIXROUTE,
1157e02d3fe7SAlexander V. Chernikov MSG_MAX,
1158e02d3fe7SAlexander V. Chernikov };
1159e02d3fe7SAlexander V. Chernikov
1160e02d3fe7SAlexander V. Chernikov int msg_array[MSG_MAX];
1161e02d3fe7SAlexander V. Chernikov
1162e02d3fe7SAlexander V. Chernikov bzero(msg_array, sizeof(msg_array));
1163e02d3fe7SAlexander V. Chernikov
1164e02d3fe7SAlexander V. Chernikov while (count < 3 && tries < 20) {
1165e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1166e02d3fe7SAlexander V. Chernikov tries++;
1167e02d3fe7SAlexander V. Chernikov /* Classify */
1168e02d3fe7SAlexander V. Chernikov if (rtm->rtm_type == RTM_NEWADDR) {
1169e02d3fe7SAlexander V. Chernikov RLOG("MSG_IFADDR: %d", count);
1170e02d3fe7SAlexander V. Chernikov msg_array[MSG_IFADDR] = count++;
1171e02d3fe7SAlexander V. Chernikov continue;
1172e02d3fe7SAlexander V. Chernikov }
1173e02d3fe7SAlexander V. Chernikov
1174e02d3fe7SAlexander V. Chernikov /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1175e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1176e02d3fe7SAlexander V. Chernikov RLOG("MSG_PREFIXROUTE: %d", count);
1177e02d3fe7SAlexander V. Chernikov msg_array[MSG_PREFIXROUTE] = count++;
1178e02d3fe7SAlexander V. Chernikov continue;
1179e02d3fe7SAlexander V. Chernikov }
1180e02d3fe7SAlexander V. Chernikov
1181e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLDATA) == 0)) {
1182e02d3fe7SAlexander V. Chernikov RLOG("MSG_HOSTROUTE: %d", count);
1183e02d3fe7SAlexander V. Chernikov msg_array[MSG_HOSTROUTE] = count++;
1184e02d3fe7SAlexander V. Chernikov continue;
1185e02d3fe7SAlexander V. Chernikov }
1186e02d3fe7SAlexander V. Chernikov
1187e02d3fe7SAlexander V. Chernikov RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1188e02d3fe7SAlexander V. Chernikov tries);
1189e02d3fe7SAlexander V. Chernikov }
1190e02d3fe7SAlexander V. Chernikov
1191e02d3fe7SAlexander V. Chernikov /* TODO: verify multicast */
1192e02d3fe7SAlexander V. Chernikov ATF_REQUIRE_MSG(count == 3, "Received only %d/3 messages", count);
1193e02d3fe7SAlexander V. Chernikov ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1194e02d3fe7SAlexander V. Chernikov }
1195e02d3fe7SAlexander V. Chernikov
1196e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success,
1197e02d3fe7SAlexander V. Chernikov "Tests validness for /128 host route removal after ifaddr removal");
1198e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success,tc)1199e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc)
1200e02d3fe7SAlexander V. Chernikov {
1201e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1202e02d3fe7SAlexander V. Chernikov
1203e02d3fe7SAlexander V. Chernikov c = presetup_ipv6_iface(tc);
1204e02d3fe7SAlexander V. Chernikov
1205e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1206e02d3fe7SAlexander V. Chernikov
1207e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1208e02d3fe7SAlexander V. Chernikov
1209e02d3fe7SAlexander V. Chernikov ret = iface_delete_addr(c->ifname, c->addr6_str);
1210e02d3fe7SAlexander V. Chernikov
1211e02d3fe7SAlexander V. Chernikov while (true) {
1212e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1213e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_DELETE) &&
1214e02d3fe7SAlexander V. Chernikov ((rtm->rtm_flags & RTF_LLINFO) == 0) &&
1215e02d3fe7SAlexander V. Chernikov rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL)
1216e02d3fe7SAlexander V. Chernikov break;
1217e02d3fe7SAlexander V. Chernikov }
1218e02d3fe7SAlexander V. Chernikov /* This should be a message for the host route */
1219e02d3fe7SAlexander V. Chernikov
1220e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->addr6, NULL, NULL);
1221e02d3fe7SAlexander V. Chernikov rtsock_validate_pid_kernel(rtm);
1222e02d3fe7SAlexander V. Chernikov /* No netmask should be set */
1223e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
1224e02d3fe7SAlexander V. Chernikov
1225e02d3fe7SAlexander V. Chernikov /* gateway should be link sdl with ifindex of an address interface */
1226e02d3fe7SAlexander V. Chernikov verify_link_gateway(rtm, c->ifindex);
1227e02d3fe7SAlexander V. Chernikov
1228e02d3fe7SAlexander V. Chernikov /* XXX: consider passing ifindex in rtm_index as done in RTM_ADD. */
1229e02d3fe7SAlexander V. Chernikov int expected_rt_flags = RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
1230e02d3fe7SAlexander V. Chernikov RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == expected_rt_flags,
1231e02d3fe7SAlexander V. Chernikov "expected rtm flags: 0x%X, got 0x%X", expected_rt_flags, rtm->rtm_flags);
1232e02d3fe7SAlexander V. Chernikov }
1233e02d3fe7SAlexander V. Chernikov
1234e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success,
1235e02d3fe7SAlexander V. Chernikov "Tests validness for the prefix route removal after ifaddr assignment");
1236e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success,tc)1237e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc)
1238e02d3fe7SAlexander V. Chernikov {
1239e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1240e02d3fe7SAlexander V. Chernikov
1241e02d3fe7SAlexander V. Chernikov c = presetup_ipv6_iface(tc);
1242e02d3fe7SAlexander V. Chernikov
1243e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1244e02d3fe7SAlexander V. Chernikov
1245e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1246e02d3fe7SAlexander V. Chernikov
1247e02d3fe7SAlexander V. Chernikov ret = iface_delete_addr(c->ifname, c->addr6_str);
1248e02d3fe7SAlexander V. Chernikov
1249e02d3fe7SAlexander V. Chernikov while (true) {
1250e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1251e02d3fe7SAlexander V. Chernikov /* Find RTM_DELETE with netmask - this should skip both host route and LLADDR */
1252e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1253e02d3fe7SAlexander V. Chernikov break;
1254e02d3fe7SAlexander V. Chernikov }
1255e02d3fe7SAlexander V. Chernikov
1256e02d3fe7SAlexander V. Chernikov /* This should be a message for the prefix route */
1257e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net6,
1258e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&c->mask6, NULL);
1259e02d3fe7SAlexander V. Chernikov
1260e02d3fe7SAlexander V. Chernikov /* gateway should be link sdl with ifindex of an address interface */
1261e02d3fe7SAlexander V. Chernikov verify_link_gateway(rtm, c->ifindex);
1262e02d3fe7SAlexander V. Chernikov
126381728a53SAlexander V. Chernikov int expected_rt_flags = RTF_DONE | RTF_PINNED;
1264e02d3fe7SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1265e02d3fe7SAlexander V. Chernikov }
1266e02d3fe7SAlexander V. Chernikov
1267e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success,
1268e02d3fe7SAlexander V. Chernikov "Tests validness for the prefix route announce after ifaddr assignment");
1269e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success,tc)1270e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc)
1271e02d3fe7SAlexander V. Chernikov {
1272e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1273e02d3fe7SAlexander V. Chernikov
1274e02d3fe7SAlexander V. Chernikov c = presetup_ipv4_iface(tc);
1275e02d3fe7SAlexander V. Chernikov
1276e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1277e02d3fe7SAlexander V. Chernikov
1278e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1279e02d3fe7SAlexander V. Chernikov
1280e02d3fe7SAlexander V. Chernikov /*
1281e02d3fe7SAlexander V. Chernikov * Multiple RTM_ADD messages will be generated:
1282e02d3fe7SAlexander V. Chernikov * 1) lladdr mapping (RTF_LLDATA)
1283e02d3fe7SAlexander V. Chernikov * 3) prefix route
1284e02d3fe7SAlexander V. Chernikov */
1285e02d3fe7SAlexander V. Chernikov
1286e02d3fe7SAlexander V. Chernikov while (true) {
1287e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1288e02d3fe7SAlexander V. Chernikov /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1289e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1290e02d3fe7SAlexander V. Chernikov break;
1291e02d3fe7SAlexander V. Chernikov }
1292e02d3fe7SAlexander V. Chernikov
1293e02d3fe7SAlexander V. Chernikov /* This should be a message for the prefix route */
1294e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net4,
1295e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&c->mask4, NULL);
1296e02d3fe7SAlexander V. Chernikov
1297e02d3fe7SAlexander V. Chernikov /* gateway should be link sdl with ifindex of an address interface */
1298e02d3fe7SAlexander V. Chernikov verify_link_gateway(rtm, c->ifindex);
1299e02d3fe7SAlexander V. Chernikov
1300e02d3fe7SAlexander V. Chernikov int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1301e02d3fe7SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1302e02d3fe7SAlexander V. Chernikov }
1303e02d3fe7SAlexander V. Chernikov
1304e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success,
1305e02d3fe7SAlexander V. Chernikov "Tests ordering of the messages for IPv4 unicast ifaddr assignment");
1306e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success,tc)1307e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc)
1308e02d3fe7SAlexander V. Chernikov {
1309e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1310e02d3fe7SAlexander V. Chernikov
1311e02d3fe7SAlexander V. Chernikov c = presetup_ipv4_iface(tc);
1312e02d3fe7SAlexander V. Chernikov
1313e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1314e02d3fe7SAlexander V. Chernikov
1315e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1316e02d3fe7SAlexander V. Chernikov
1317e02d3fe7SAlexander V. Chernikov int count = 0, tries = 0;
1318e02d3fe7SAlexander V. Chernikov
1319e02d3fe7SAlexander V. Chernikov enum msgtype {
1320e02d3fe7SAlexander V. Chernikov MSG_IFADDR,
1321e02d3fe7SAlexander V. Chernikov MSG_PREFIXROUTE,
1322e02d3fe7SAlexander V. Chernikov MSG_MAX,
1323e02d3fe7SAlexander V. Chernikov };
1324e02d3fe7SAlexander V. Chernikov
1325e02d3fe7SAlexander V. Chernikov int msg_array[MSG_MAX];
1326e02d3fe7SAlexander V. Chernikov
1327e02d3fe7SAlexander V. Chernikov bzero(msg_array, sizeof(msg_array));
1328e02d3fe7SAlexander V. Chernikov
1329e02d3fe7SAlexander V. Chernikov while (count < 2 && tries < 20) {
1330e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1331e02d3fe7SAlexander V. Chernikov tries++;
1332e02d3fe7SAlexander V. Chernikov /* Classify */
1333e02d3fe7SAlexander V. Chernikov if (rtm->rtm_type == RTM_NEWADDR) {
1334e02d3fe7SAlexander V. Chernikov RLOG("MSG_IFADDR: %d", count);
1335e02d3fe7SAlexander V. Chernikov msg_array[MSG_IFADDR] = count++;
1336e02d3fe7SAlexander V. Chernikov continue;
1337e02d3fe7SAlexander V. Chernikov }
1338e02d3fe7SAlexander V. Chernikov
1339e02d3fe7SAlexander V. Chernikov /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1340e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1341e02d3fe7SAlexander V. Chernikov RLOG("MSG_PREFIXROUTE: %d", count);
1342e02d3fe7SAlexander V. Chernikov msg_array[MSG_PREFIXROUTE] = count++;
1343e02d3fe7SAlexander V. Chernikov continue;
1344e02d3fe7SAlexander V. Chernikov }
1345e02d3fe7SAlexander V. Chernikov
1346e02d3fe7SAlexander V. Chernikov RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1347e02d3fe7SAlexander V. Chernikov tries);
1348e02d3fe7SAlexander V. Chernikov }
1349e02d3fe7SAlexander V. Chernikov
1350e02d3fe7SAlexander V. Chernikov /* TODO: verify multicast */
1351e02d3fe7SAlexander V. Chernikov ATF_REQUIRE_MSG(count == 2, "Received only %d/2 messages", count);
1352e02d3fe7SAlexander V. Chernikov ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1353e02d3fe7SAlexander V. Chernikov }
1354e02d3fe7SAlexander V. Chernikov
1355e02d3fe7SAlexander V. Chernikov RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success,
1356e02d3fe7SAlexander V. Chernikov "Tests validness for the prefix route removal after ifaddr assignment");
1357e02d3fe7SAlexander V. Chernikov
ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success,tc)1358e02d3fe7SAlexander V. Chernikov ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc)
1359e02d3fe7SAlexander V. Chernikov {
1360e02d3fe7SAlexander V. Chernikov DECLARE_TEST_VARS;
1361e02d3fe7SAlexander V. Chernikov
1362e02d3fe7SAlexander V. Chernikov c = presetup_ipv4_iface(tc);
1363e02d3fe7SAlexander V. Chernikov
1364e02d3fe7SAlexander V. Chernikov
1365e02d3fe7SAlexander V. Chernikov ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1366e02d3fe7SAlexander V. Chernikov
1367e02d3fe7SAlexander V. Chernikov c->rtsock_fd = rtsock_setup_socket();
1368e02d3fe7SAlexander V. Chernikov
1369e02d3fe7SAlexander V. Chernikov ret = iface_delete_addr(c->ifname, c->addr4_str);
1370e02d3fe7SAlexander V. Chernikov
1371e02d3fe7SAlexander V. Chernikov while (true) {
1372e02d3fe7SAlexander V. Chernikov rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1373e02d3fe7SAlexander V. Chernikov /* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1374e02d3fe7SAlexander V. Chernikov if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1375e02d3fe7SAlexander V. Chernikov break;
1376e02d3fe7SAlexander V. Chernikov }
1377e02d3fe7SAlexander V. Chernikov
1378e02d3fe7SAlexander V. Chernikov /* This should be a message for the prefix route */
1379e02d3fe7SAlexander V. Chernikov verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net4,
1380e02d3fe7SAlexander V. Chernikov (struct sockaddr *)&c->mask4, NULL);
1381e02d3fe7SAlexander V. Chernikov
1382e02d3fe7SAlexander V. Chernikov /* gateway should be link sdl with ifindex of an address interface */
1383e02d3fe7SAlexander V. Chernikov verify_link_gateway(rtm, c->ifindex);
1384e02d3fe7SAlexander V. Chernikov
1385e02d3fe7SAlexander V. Chernikov int expected_rt_flags = RTF_DONE | RTF_PINNED;
1386e02d3fe7SAlexander V. Chernikov verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1387e02d3fe7SAlexander V. Chernikov }
1388775dc861SAlexander V. Chernikov
1389775dc861SAlexander V. Chernikov
ATF_TP_ADD_TCS(tp)1390775dc861SAlexander V. Chernikov ATF_TP_ADD_TCS(tp)
1391775dc861SAlexander V. Chernikov {
1392775dc861SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success);
1393775dc861SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success);
139467f2f67fSAlex Richardson ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_success);
1395775dc861SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure);
139667f2f67fSAlex Richardson ATF_TP_ADD_TC(tp, rtm_add_v4_no_rtf_host_success);
1397775dc861SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success);
1398775dc861SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success);
1399775dc861SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success);
1400775dc861SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success);
1401272bd698SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_change_v4_gw_success);
1402272bd698SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_change_v4_mtu_success);
14031b95005eSAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_change_v4_flags_success);
1404272bd698SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_change_v6_gw_success);
1405272bd698SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_change_v6_mtu_success);
14061b95005eSAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_change_v6_flags_success);
1407e02d3fe7SAlexander V. Chernikov /* ifaddr tests */
1408e02d3fe7SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success);
1409e02d3fe7SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success);
1410e02d3fe7SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_ordered_success);
1411e02d3fe7SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_hostroute_success);
1412e02d3fe7SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_prefixroute_success);
1413e02d3fe7SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v4_gu_ifa_ordered_success);
1414e02d3fe7SAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_del_v4_gu_ifa_prefixroute_success);
141534a5582cSAlexander V. Chernikov /* temporal routes */
141634a5582cSAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v4_temporal1_success);
141734a5582cSAlexander V. Chernikov ATF_TP_ADD_TC(tp, rtm_add_v6_temporal1_success);
1418775dc861SAlexander V. Chernikov
1419775dc861SAlexander V. Chernikov return (atf_no_error());
1420775dc861SAlexander V. Chernikov }
1421775dc861SAlexander V. Chernikov
1422