Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/net/routing/test_rtsock_l3.c
39604 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2019 Alexander V. Chernikov
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include "rtsock_common.h"
29
#include "rtsock_config.h"
30
#include "sys/types.h"
31
#include <sys/time.h>
32
#include <sys/ioctl.h>
33
34
#include "net/bpf.h"
35
36
static void
37
jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)
38
{
39
char vnet_name[512];
40
41
snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));
42
RLOG("jumping to %s", vnet_name);
43
44
vnet_switch(vnet_name, c->ifnames, c->num_interfaces);
45
46
/* Update ifindex cache */
47
c->ifindex = if_nametoindex(c->ifname);
48
}
49
50
static inline struct rtsock_test_config *
51
presetup_ipv6_iface(const atf_tc_t *tc)
52
{
53
struct rtsock_test_config *c;
54
int ret;
55
56
c = config_setup(tc, NULL);
57
58
jump_vnet(c, tc);
59
60
ret = iface_turn_up(c->ifname);
61
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
62
63
ret = iface_enable_ipv6(c->ifname);
64
ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);
65
ATF_REQUIRE_ERRNO(0, true);
66
67
return (c);
68
}
69
70
static inline struct rtsock_test_config *
71
presetup_ipv6(const atf_tc_t *tc)
72
{
73
struct rtsock_test_config *c;
74
int ret;
75
76
c = presetup_ipv6_iface(tc);
77
78
ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
79
80
c->rtsock_fd = rtsock_setup_socket();
81
ATF_REQUIRE_ERRNO(0, true);
82
83
return (c);
84
}
85
86
static inline struct rtsock_test_config *
87
presetup_ipv4_iface(const atf_tc_t *tc)
88
{
89
struct rtsock_test_config *c;
90
int ret;
91
92
c = config_setup(tc, NULL);
93
ATF_REQUIRE(c != NULL);
94
95
jump_vnet(c, tc);
96
97
ret = iface_turn_up(c->ifname);
98
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);
99
ATF_REQUIRE_ERRNO(0, true);
100
101
return (c);
102
}
103
104
static inline struct rtsock_test_config *
105
presetup_ipv4(const atf_tc_t *tc)
106
{
107
struct rtsock_test_config *c;
108
int ret;
109
110
c = presetup_ipv4_iface(tc);
111
112
/* assumes ifconfig doing IFF_UP */
113
ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
114
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
115
116
c->rtsock_fd = rtsock_setup_socket();
117
ATF_REQUIRE_ERRNO(0, true);
118
119
return (c);
120
}
121
122
123
static void
124
prepare_v4_network(struct rtsock_test_config *c, struct sockaddr_in *dst,
125
struct sockaddr_in *mask, struct sockaddr_in *gw)
126
{
127
/* Create IPv4 subnetwork with smaller prefix */
128
sa_fill_mask4(mask, c->plen4 + 1);
129
*dst = c->net4;
130
/* Calculate GW as last-net-address - 1 */
131
*gw = c->net4;
132
gw->sin_addr.s_addr = htonl((ntohl(c->net4.sin_addr.s_addr) | ~ntohl(c->mask4.sin_addr.s_addr)) - 1);
133
sa_print((struct sockaddr *)dst, 0);
134
sa_print((struct sockaddr *)mask, 0);
135
sa_print((struct sockaddr *)gw, 0);
136
}
137
138
static void
139
prepare_v6_network(struct rtsock_test_config *c, struct sockaddr_in6 *dst,
140
struct sockaddr_in6 *mask, struct sockaddr_in6 *gw)
141
{
142
/* Create IPv6 subnetwork with smaller prefix */
143
sa_fill_mask6(mask, c->plen6 + 1);
144
*dst = c->net6;
145
/* Calculate GW as last-net-address - 1 */
146
*gw = c->net6;
147
#define _s6_addr32 __u6_addr.__u6_addr32
148
gw->sin6_addr._s6_addr32[0] = htonl((ntohl(gw->sin6_addr._s6_addr32[0]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[0])));
149
gw->sin6_addr._s6_addr32[1] = htonl((ntohl(gw->sin6_addr._s6_addr32[1]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[1])));
150
gw->sin6_addr._s6_addr32[2] = htonl((ntohl(gw->sin6_addr._s6_addr32[2]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[2])));
151
gw->sin6_addr._s6_addr32[3] = htonl((ntohl(gw->sin6_addr._s6_addr32[3]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[3])) - 1);
152
#undef _s6_addr32
153
sa_print((struct sockaddr *)dst, 0);
154
sa_print((struct sockaddr *)mask, 0);
155
sa_print((struct sockaddr *)gw, 0);
156
}
157
158
static void
159
prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
160
struct sockaddr *mask, struct sockaddr *gw)
161
{
162
163
rtsock_prepare_route_message(rtm, cmd, dst, mask, gw);
164
165
if (cmd == RTM_ADD || cmd == RTM_CHANGE)
166
rtm->rtm_flags |= RTF_STATIC;
167
}
168
169
static void
170
verify_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,
171
struct sockaddr *mask, struct sockaddr *gw)
172
{
173
char msg[512];
174
struct sockaddr *sa;
175
int ret;
176
177
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == cmd,
178
"expected %s message, got %d (%s)", rtsock_print_cmdtype(cmd),
179
rtm->rtm_type, rtsock_print_cmdtype(rtm->rtm_type));
180
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_errno == 0,
181
"got got errno %d as message reply", rtm->rtm_errno);
182
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->_rtm_spare1 == 0,
183
"expected rtm_spare==0, got %d", rtm->_rtm_spare1);
184
185
/* kernel MAY return more sockaddrs, including RTA_IFP / RTA_IFA, so verify the needed ones */
186
if (dst != NULL) {
187
sa = rtsock_find_rtm_sa(rtm, RTA_DST);
188
RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "DST is not set");
189
ret = sa_equal_msg(sa, dst, msg, sizeof(msg));
190
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);
191
}
192
193
if (mask != NULL) {
194
sa = rtsock_find_rtm_sa(rtm, RTA_NETMASK);
195
RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "NETMASK is not set");
196
ret = sa_equal_msg(sa, mask, msg, sizeof(msg));
197
ret = 1;
198
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "NETMASK sa diff: %s", msg);
199
}
200
201
if (gw != NULL) {
202
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
203
RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
204
ret = sa_equal_msg(sa, gw, msg, sizeof(msg));
205
RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);
206
}
207
}
208
209
static void
210
verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags)
211
{
212
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex,
213
"expected ifindex %d, got %d", ifindex, rtm->rtm_index);
214
215
if (rtm->rtm_flags != rtm_flags) {
216
char got_flags[64], expected_flags[64];
217
rtsock_print_rtm_flags(got_flags, sizeof(got_flags),
218
rtm->rtm_flags);
219
rtsock_print_rtm_flags(expected_flags, sizeof(expected_flags),
220
rtm_flags);
221
222
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == rtm_flags,
223
"expected flags: 0x%X %s, got 0x%X %s",
224
rtm_flags, expected_flags,
225
rtm->rtm_flags, got_flags);
226
}
227
}
228
229
static void
230
verify_link_gateway(struct rt_msghdr *rtm, int ifindex)
231
{
232
struct sockaddr *sa;
233
struct sockaddr_dl *sdl;
234
235
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
236
RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
237
RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);
238
sdl = (struct sockaddr_dl *)sa;
239
RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == ifindex, "GW ifindex is %d", sdl->sdl_index);
240
}
241
242
/* TESTS */
243
244
#define DECLARE_TEST_VARS \
245
char buffer[2048]; \
246
struct rtsock_test_config *c; \
247
struct rt_msghdr *rtm = (struct rt_msghdr *)buffer; \
248
struct sockaddr *sa; \
249
int ret; \
250
\
251
252
#define DESCRIBE_ROOT_TEST(_msg) config_describe_root_test(tc, _msg)
253
#define CLEANUP_AFTER_TEST config_generic_cleanup(tc)
254
255
#define RTM_DECLARE_ROOT_TEST(_name, _descr) \
256
ATF_TC_WITH_CLEANUP(_name); \
257
ATF_TC_HEAD(_name, tc) \
258
{ \
259
DESCRIBE_ROOT_TEST(_descr); \
260
} \
261
ATF_TC_CLEANUP(_name, tc) \
262
{ \
263
CLEANUP_AFTER_TEST; \
264
}
265
266
ATF_TC_WITH_CLEANUP(rtm_get_v4_exact_success);
267
ATF_TC_HEAD(rtm_get_v4_exact_success, tc)
268
{
269
DESCRIBE_ROOT_TEST("Tests RTM_GET with exact prefix lookup on an interface prefix");
270
}
271
272
ATF_TC_BODY(rtm_get_v4_exact_success, tc)
273
{
274
DECLARE_TEST_VARS;
275
276
c = presetup_ipv4(tc);
277
278
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
279
(struct sockaddr *)&c->mask4, NULL);
280
281
rtsock_send_rtm(c->rtsock_fd, rtm);
282
283
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
284
285
/*
286
* RTM_GET: Report Metrics: len 240, pid: 45072, seq 42, errno 0, flags: <UP,DONE,PINNED>
287
* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
288
* af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
289
* af=link len=54 sdl_index=3 if_name=tap4242 hd={36, 12, 03, 00, 06, 00{49}}
290
* af=inet len=16 addr=255.255.255.0 hd={10, 02, FF{5}, 00{9}}
291
*/
292
293
verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
294
(struct sockaddr *)&c->mask4, NULL);
295
296
verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
297
298
/* Explicitly verify gateway for the interface route */
299
verify_link_gateway(rtm, c->ifindex);
300
sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);
301
RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");
302
RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);
303
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
304
RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == c->ifindex, "GW ifindex is %d", sdl->sdl_index);
305
}
306
307
ATF_TC_CLEANUP(rtm_get_v4_exact_success, tc)
308
{
309
CLEANUP_AFTER_TEST;
310
}
311
312
ATF_TC_WITH_CLEANUP(rtm_get_v4_lpm_success);
313
ATF_TC_HEAD(rtm_get_v4_lpm_success, tc)
314
{
315
DESCRIBE_ROOT_TEST("Tests RTM_GET with address lookup on an existing prefix");
316
}
317
318
ATF_TC_BODY(rtm_get_v4_lpm_success, tc)
319
{
320
DECLARE_TEST_VARS;
321
322
c = presetup_ipv4(tc);
323
324
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, NULL, NULL);
325
326
rtsock_send_rtm(c->rtsock_fd, rtm);
327
328
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
329
330
/*
331
* RTM_GET: Report Metrics: len 312, pid: 67074, seq 1, errno 0, flags:<UP,DONE,PINNED>
332
* locks: inits:
333
* sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
334
* 10.0.0.0 link#1 255.255.255.0 vtnet0:52.54.0.42.f.ef 10.0.0.157
335
*/
336
337
verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,
338
(struct sockaddr *)&c->mask4, NULL);
339
340
verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);
341
}
342
343
ATF_TC_CLEANUP(rtm_get_v4_lpm_success, tc)
344
{
345
CLEANUP_AFTER_TEST;
346
}
347
348
349
ATF_TC_WITH_CLEANUP(rtm_get_v4_empty_dst_failure);
350
ATF_TC_HEAD(rtm_get_v4_empty_dst_failure, tc)
351
{
352
353
DESCRIBE_ROOT_TEST("Tests RTM_GET with empty DST addr");
354
}
355
356
ATF_TC_BODY(rtm_get_v4_empty_dst_failure, tc)
357
{
358
DECLARE_TEST_VARS;
359
struct rtsock_config_options co;
360
361
bzero(&co, sizeof(co));
362
co.num_interfaces = 0;
363
364
c = config_setup(tc,&co);
365
c->rtsock_fd = rtsock_setup_socket();
366
367
rtsock_prepare_route_message(rtm, RTM_GET, NULL,
368
(struct sockaddr *)&c->mask4, NULL);
369
rtsock_update_rtm_len(rtm);
370
371
ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen) == -1);
372
}
373
374
ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure, tc)
375
{
376
CLEANUP_AFTER_TEST;
377
}
378
379
ATF_TC_WITH_CLEANUP(rtm_get_v4_hostbits_success);
380
ATF_TC_HEAD(rtm_get_v4_hostbits_success, tc)
381
{
382
DESCRIBE_ROOT_TEST("Tests RTM_GET with prefix with some hosts-bits set");
383
}
384
385
ATF_TC_BODY(rtm_get_v4_hostbits_success, tc)
386
{
387
DECLARE_TEST_VARS;
388
389
c = presetup_ipv4(tc);
390
391
/* Q the same prefix */
392
rtsock_prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->addr4,
393
(struct sockaddr *)&c->mask4, NULL);
394
rtsock_update_rtm_len(rtm);
395
396
ATF_REQUIRE_ERRNO(0, true);
397
ATF_CHECK_ERRNO(0, write(c->rtsock_fd, rtm, rtm->rtm_msglen) > 0);
398
}
399
400
ATF_TC_CLEANUP(rtm_get_v4_hostbits_success, tc)
401
{
402
CLEANUP_AFTER_TEST;
403
}
404
405
ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success);
406
ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc)
407
{
408
DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP");
409
}
410
411
ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc)
412
{
413
DECLARE_TEST_VARS;
414
415
c = presetup_ipv4(tc);
416
417
/* Create IPv4 subnetwork with smaller prefix */
418
struct sockaddr_in mask4;
419
struct sockaddr_in net4;
420
struct sockaddr_in gw4;
421
prepare_v4_network(c, &net4, &mask4, &gw4);
422
423
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
424
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
425
426
rtsock_send_rtm(c->rtsock_fd, rtm);
427
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
428
429
/*
430
* RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
431
* locks: inits:
432
* sockaddrs: <DST,GATEWAY,NETMASK>
433
* 192.0.2.0 192.0.2.254 255.255.255.128
434
*/
435
436
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
437
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
438
verify_route_message_extra(rtm, c->ifindex,
439
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
440
}
441
442
ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc)
443
{
444
CLEANUP_AFTER_TEST;
445
}
446
447
RTM_DECLARE_ROOT_TEST(rtm_add_v4_no_rtf_host_success,
448
"Tests success with netmask sa and RTF_HOST inconsistency");
449
450
ATF_TC_BODY(rtm_add_v4_no_rtf_host_success, tc)
451
{
452
DECLARE_TEST_VARS;
453
454
c = presetup_ipv4(tc);
455
456
/* Create IPv4 subnetwork with smaller prefix */
457
struct sockaddr_in mask4;
458
struct sockaddr_in net4;
459
struct sockaddr_in gw4;
460
prepare_v4_network(c, &net4, &mask4, &gw4);
461
462
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
463
NULL, (struct sockaddr *)&gw4);
464
rtsock_update_rtm_len(rtm);
465
466
/* RTF_HOST is NOT specified, while netmask is empty */
467
ATF_REQUIRE_ERRNO(0, true);
468
ATF_CHECK_ERRNO(0, write(c->rtsock_fd, rtm, rtm->rtm_msglen) > 0);
469
}
470
471
ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success);
472
ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc)
473
{
474
DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway");
475
}
476
477
ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, tc)
478
{
479
DECLARE_TEST_VARS;
480
481
c = presetup_ipv4(tc);
482
483
/* Create IPv4 subnetwork with smaller prefix */
484
struct sockaddr_in mask4;
485
struct sockaddr_in net4;
486
struct sockaddr_in gw4;
487
prepare_v4_network(c, &net4, &mask4, &gw4);
488
489
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
490
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
491
492
rtsock_send_rtm(c->rtsock_fd, rtm);
493
494
/* Route has been added successfully, try to delete it */
495
prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
496
(struct sockaddr *)&mask4, NULL);
497
498
rtsock_send_rtm(c->rtsock_fd, rtm);
499
500
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
501
502
/*
503
* RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
504
* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
505
* af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
506
* af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
507
* af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
508
*/
509
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
510
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
511
512
verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
513
}
514
515
ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc)
516
{
517
CLEANUP_AFTER_TEST;
518
}
519
520
RTM_DECLARE_ROOT_TEST(rtm_change_v4_gw_success,
521
"Tests IPv4 gateway change");
522
523
ATF_TC_BODY(rtm_change_v4_gw_success, tc)
524
{
525
DECLARE_TEST_VARS;
526
struct rtsock_config_options co;
527
528
bzero(&co, sizeof(co));
529
co.num_interfaces = 2;
530
531
c = config_setup(tc, &co);
532
jump_vnet(c, tc);
533
534
ret = iface_turn_up(c->ifnames[0]);
535
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
536
ret = iface_turn_up(c->ifnames[1]);
537
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
538
539
ret = iface_setup_addr(c->ifnames[0], c->addr4_str, c->plen4);
540
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
541
542
/* Use 198.51.100.0/24 "TEST-NET-2" for the second interface */
543
ret = iface_setup_addr(c->ifnames[1], "198.51.100.1", 24);
544
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
545
546
c->rtsock_fd = rtsock_setup_socket();
547
548
/* Create IPv4 subnetwork with smaller prefix */
549
struct sockaddr_in mask4;
550
struct sockaddr_in net4;
551
struct sockaddr_in gw4;
552
prepare_v4_network(c, &net4, &mask4, &gw4);
553
554
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
555
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
556
557
rtsock_send_rtm(c->rtsock_fd, rtm);
558
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
559
560
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
561
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
562
563
/* Change gateway to the one on desiding on the other interface */
564
inet_pton(AF_INET, "198.51.100.2", &gw4.sin_addr.s_addr);
565
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
566
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
567
rtsock_send_rtm(c->rtsock_fd, rtm);
568
569
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
570
571
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
572
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
573
574
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
575
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
576
577
/* Verify the change has actually taken place */
578
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
579
(struct sockaddr *)&mask4, NULL);
580
581
rtsock_send_rtm(c->rtsock_fd, rtm);
582
583
/*
584
* RTM_GET: len 200, pid: 3894, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
585
* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
586
* af=inet len=16 addr=192.0.2.0 hd={x10, x02, x00{2}, xC0, x00, x02, x00{9}}
587
* af=inet len=16 addr=198.51.100.2 hd={x10, x02, x00{2}, xC6, x33, x64, x02, x00{8}}
588
* af=inet len=16 addr=255.255.255.128 hd={x10, x02, xFF, xFF, xFF, xFF, xFF, x80, x00{8}}
589
*/
590
591
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
592
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
593
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
594
595
}
596
597
RTM_DECLARE_ROOT_TEST(rtm_change_v4_mtu_success,
598
"Tests IPv4 path mtu change");
599
600
ATF_TC_BODY(rtm_change_v4_mtu_success, tc)
601
{
602
DECLARE_TEST_VARS;
603
604
unsigned long test_mtu = 1442;
605
606
c = presetup_ipv4(tc);
607
608
/* Create IPv4 subnetwork with smaller prefix */
609
struct sockaddr_in mask4;
610
struct sockaddr_in net4;
611
struct sockaddr_in gw4;
612
prepare_v4_network(c, &net4, &mask4, &gw4);
613
614
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
615
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
616
617
rtsock_send_rtm(c->rtsock_fd, rtm);
618
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
619
620
/* Change MTU */
621
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
622
(struct sockaddr *)&mask4, NULL);
623
rtm->rtm_inits |= RTV_MTU;
624
rtm->rtm_rmx.rmx_mtu = test_mtu;
625
626
rtsock_send_rtm(c->rtsock_fd, rtm);
627
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
628
629
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
630
(struct sockaddr *)&mask4, NULL);
631
632
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
633
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
634
635
/* Verify the change has actually taken place */
636
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
637
(struct sockaddr *)&mask4, NULL);
638
639
rtsock_send_rtm(c->rtsock_fd, rtm);
640
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
641
642
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
643
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
644
}
645
646
RTM_DECLARE_ROOT_TEST(rtm_change_v4_flags_success,
647
"Tests IPv4 path flags change");
648
649
ATF_TC_BODY(rtm_change_v4_flags_success, tc)
650
{
651
DECLARE_TEST_VARS;
652
653
uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
654
uint32_t desired_flags;
655
656
c = presetup_ipv4(tc);
657
658
/* Create IPv4 subnetwork with smaller prefix */
659
struct sockaddr_in mask4;
660
struct sockaddr_in net4;
661
struct sockaddr_in gw4;
662
prepare_v4_network(c, &net4, &mask4, &gw4);
663
664
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
665
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
666
667
/* Set test flags during route addition */
668
desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;
669
rtm->rtm_flags |= test_flags;
670
rtsock_send_rtm(c->rtsock_fd, rtm);
671
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
672
673
/* Change flags */
674
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,
675
(struct sockaddr *)&mask4, NULL);
676
rtm->rtm_flags &= ~test_flags;
677
desired_flags &= ~test_flags;
678
679
rtsock_send_rtm(c->rtsock_fd, rtm);
680
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
681
682
/* Verify updated flags */
683
verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
684
685
/* Verify the change has actually taken place */
686
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,
687
(struct sockaddr *)&mask4, NULL);
688
689
rtsock_send_rtm(c->rtsock_fd, rtm);
690
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
691
692
verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
693
}
694
695
696
ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success);
697
ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc)
698
{
699
DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
700
}
701
702
ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc)
703
{
704
DECLARE_TEST_VARS;
705
706
c = presetup_ipv6(tc);
707
708
/* Create IPv6 subnetwork with smaller prefix */
709
struct sockaddr_in6 mask6;
710
struct sockaddr_in6 net6;
711
struct sockaddr_in6 gw6;
712
prepare_v6_network(c, &net6, &mask6, &gw6);
713
714
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
715
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
716
717
rtsock_send_rtm(c->rtsock_fd, rtm);
718
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
719
720
/*
721
* RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>
722
* locks: inits:
723
* sockaddrs: <DST,GATEWAY,NETMASK>
724
* 192.0.2.0 192.0.2.254 255.255.255.128
725
*/
726
727
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
728
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
729
730
verify_route_message_extra(rtm, c->ifindex,
731
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
732
}
733
734
ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc)
735
{
736
CLEANUP_AFTER_TEST;
737
}
738
739
ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success);
740
ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc)
741
{
742
743
DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway");
744
}
745
746
ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc)
747
{
748
DECLARE_TEST_VARS;
749
750
c = presetup_ipv6(tc);
751
752
/* Create IPv6 subnetwork with smaller prefix */
753
struct sockaddr_in6 mask6;
754
struct sockaddr_in6 net6;
755
struct sockaddr_in6 gw6;
756
prepare_v6_network(c, &net6, &mask6, &gw6);
757
758
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
759
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
760
761
rtsock_send_rtm(c->rtsock_fd, rtm);
762
763
/* Route has been added successfully, try to delete it */
764
prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
765
(struct sockaddr *)&mask6, NULL);
766
767
rtsock_send_rtm(c->rtsock_fd, rtm);
768
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
769
770
/*
771
* RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>
772
* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
773
* af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}
774
* af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}
775
* af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}
776
*/
777
778
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
779
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
780
verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);
781
}
782
783
ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc)
784
{
785
CLEANUP_AFTER_TEST;
786
}
787
788
RTM_DECLARE_ROOT_TEST(rtm_change_v6_gw_success,
789
"Tests IPv6 gateway change");
790
791
ATF_TC_BODY(rtm_change_v6_gw_success, tc)
792
{
793
DECLARE_TEST_VARS;
794
struct rtsock_config_options co;
795
796
bzero(&co, sizeof(co));
797
co.num_interfaces = 2;
798
799
c = config_setup(tc, &co);
800
jump_vnet(c, tc);
801
802
ret = iface_turn_up(c->ifnames[0]);
803
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);
804
ret = iface_turn_up(c->ifnames[1]);
805
ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);
806
807
ret = iface_enable_ipv6(c->ifnames[0]);
808
ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[0]);
809
ret = iface_enable_ipv6(c->ifnames[1]);
810
ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[1]);
811
812
ret = iface_setup_addr(c->ifnames[0], c->addr6_str, c->plen6);
813
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
814
815
ret = iface_setup_addr(c->ifnames[1], "2001:DB8:4242::1", 64);
816
ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");
817
818
c->rtsock_fd = rtsock_setup_socket();
819
820
/* Create IPv6 subnetwork with smaller prefix */
821
struct sockaddr_in6 mask6;
822
struct sockaddr_in6 net6;
823
struct sockaddr_in6 gw6;
824
prepare_v6_network(c, &net6, &mask6, &gw6);
825
826
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
827
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
828
829
rtsock_send_rtm(c->rtsock_fd, rtm);
830
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
831
832
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
833
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
834
835
/* Change gateway to the one on residing on the other interface */
836
inet_pton(AF_INET6, "2001:DB8:4242::4242", &gw6.sin6_addr);
837
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
838
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
839
rtsock_send_rtm(c->rtsock_fd, rtm);
840
841
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
842
843
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
844
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
845
846
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
847
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
848
849
/* Verify the change has actually taken place */
850
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
851
(struct sockaddr *)&mask6, NULL);
852
853
rtsock_send_rtm(c->rtsock_fd, rtm);
854
855
/*
856
* RTM_GET: len 248, pid: 2268, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>
857
* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>
858
* af=inet6 len=28 addr=2001:db8:: hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x00{16}}
859
* 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}}
860
* af=inet6 len=28 addr=ffff:ffff:8000:: hd={x1C, x1C, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x80, x00{15}}
861
*/
862
863
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
864
verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),
865
RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);
866
}
867
868
RTM_DECLARE_ROOT_TEST(rtm_change_v6_mtu_success,
869
"Tests IPv6 path mtu change");
870
871
ATF_TC_BODY(rtm_change_v6_mtu_success, tc)
872
{
873
DECLARE_TEST_VARS;
874
875
unsigned long test_mtu = 1442;
876
877
c = presetup_ipv6(tc);
878
879
/* Create IPv6 subnetwork with smaller prefix */
880
struct sockaddr_in6 mask6;
881
struct sockaddr_in6 net6;
882
struct sockaddr_in6 gw6;
883
prepare_v6_network(c, &net6, &mask6, &gw6);
884
885
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
886
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
887
888
/* Send route add */
889
rtsock_send_rtm(c->rtsock_fd, rtm);
890
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
891
892
/* Change MTU */
893
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
894
(struct sockaddr *)&mask6, NULL);
895
rtm->rtm_inits |= RTV_MTU;
896
rtm->rtm_rmx.rmx_mtu = test_mtu;
897
898
rtsock_send_rtm(c->rtsock_fd, rtm);
899
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
900
901
verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
902
(struct sockaddr *)&mask6, NULL);
903
904
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
905
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
906
907
/* Verify the change has actually taken place */
908
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
909
(struct sockaddr *)&mask6, NULL);
910
911
rtsock_send_rtm(c->rtsock_fd, rtm);
912
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
913
914
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,
915
"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);
916
}
917
918
RTM_DECLARE_ROOT_TEST(rtm_change_v6_flags_success,
919
"Tests IPv6 path flags change");
920
921
ATF_TC_BODY(rtm_change_v6_flags_success, tc)
922
{
923
DECLARE_TEST_VARS;
924
925
uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;
926
uint32_t desired_flags;
927
928
c = presetup_ipv6(tc);
929
930
/* Create IPv6 subnetwork with smaller prefix */
931
struct sockaddr_in6 mask6;
932
struct sockaddr_in6 net6;
933
struct sockaddr_in6 gw6;
934
prepare_v6_network(c, &net6, &mask6, &gw6);
935
936
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
937
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
938
939
/* Set test flags during route addition */
940
desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;
941
rtm->rtm_flags |= test_flags;
942
rtsock_send_rtm(c->rtsock_fd, rtm);
943
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
944
945
/* Change flags */
946
prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,
947
(struct sockaddr *)&mask6, NULL);
948
rtm->rtm_flags &= ~test_flags;
949
desired_flags &= ~test_flags;
950
951
rtsock_send_rtm(c->rtsock_fd, rtm);
952
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
953
954
/* Verify updated flags */
955
verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
956
957
/* Verify the change has actually taken place */
958
prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,
959
(struct sockaddr *)&mask6, NULL);
960
961
rtsock_send_rtm(c->rtsock_fd, rtm);
962
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
963
964
verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);
965
}
966
967
ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success);
968
ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc)
969
{
970
DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set");
971
}
972
973
ATF_TC_BODY(rtm_add_v4_temporal1_success, tc)
974
{
975
DECLARE_TEST_VARS;
976
977
c = presetup_ipv4(tc);
978
979
/* Create IPv4 subnetwork with smaller prefix */
980
struct sockaddr_in mask4;
981
struct sockaddr_in net4;
982
struct sockaddr_in gw4;
983
prepare_v4_network(c, &net4, &mask4, &gw4);
984
985
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,
986
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
987
988
/* Set expire time to now */
989
struct timeval tv;
990
gettimeofday(&tv, NULL);
991
rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
992
rtm->rtm_inits |= RTV_EXPIRE;
993
994
rtsock_send_rtm(c->rtsock_fd, rtm);
995
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
996
ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
997
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
998
999
/* The next should be route deletion */
1000
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1001
1002
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,
1003
(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);
1004
1005
verify_route_message_extra(rtm, c->ifindex,
1006
RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1007
}
1008
1009
ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc)
1010
{
1011
CLEANUP_AFTER_TEST;
1012
}
1013
1014
ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success);
1015
ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc)
1016
{
1017
DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");
1018
}
1019
1020
ATF_TC_BODY(rtm_add_v6_temporal1_success, tc)
1021
{
1022
DECLARE_TEST_VARS;
1023
1024
c = presetup_ipv6(tc);
1025
1026
/* Create IPv6 subnetwork with smaller prefix */
1027
struct sockaddr_in6 mask6;
1028
struct sockaddr_in6 net6;
1029
struct sockaddr_in6 gw6;
1030
prepare_v6_network(c, &net6, &mask6, &gw6);
1031
1032
prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,
1033
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1034
1035
/* Set expire time to now */
1036
struct timeval tv;
1037
gettimeofday(&tv, NULL);
1038
rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;
1039
rtm->rtm_inits |= RTV_EXPIRE;
1040
1041
rtsock_send_rtm(c->rtsock_fd, rtm);
1042
rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);
1043
ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");
1044
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");
1045
1046
/* The next should be route deletion */
1047
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1048
1049
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,
1050
(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);
1051
1052
verify_route_message_extra(rtm, c->ifindex,
1053
RTF_DONE | RTF_GATEWAY | RTF_STATIC);
1054
}
1055
1056
ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc)
1057
{
1058
CLEANUP_AFTER_TEST;
1059
}
1060
1061
/* Interface address messages tests */
1062
1063
RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success,
1064
"Tests validness for /128 host route announce after ifaddr assignment");
1065
1066
ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc)
1067
{
1068
DECLARE_TEST_VARS;
1069
1070
c = presetup_ipv6_iface(tc);
1071
1072
c->rtsock_fd = rtsock_setup_socket();
1073
1074
ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1075
1076
/*
1077
* There will be multiple.
1078
* RTM_ADD without llinfo.
1079
*/
1080
1081
while (true) {
1082
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1083
if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0))
1084
break;
1085
}
1086
/* This should be a message for the host route */
1087
1088
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->addr6, NULL, NULL);
1089
rtsock_validate_pid_kernel(rtm);
1090
/* No netmask should be set */
1091
RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
1092
1093
/* gateway should be link sdl with ifindex of an address interface */
1094
verify_link_gateway(rtm, c->ifindex);
1095
1096
int expected_rt_flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
1097
verify_route_message_extra(rtm, if_nametoindex("lo0"), expected_rt_flags);
1098
}
1099
1100
RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success,
1101
"Tests validness for the prefix route announce after ifaddr assignment");
1102
1103
ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc)
1104
{
1105
DECLARE_TEST_VARS;
1106
1107
c = presetup_ipv6_iface(tc);
1108
1109
c->rtsock_fd = rtsock_setup_socket();
1110
1111
ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1112
1113
/*
1114
* Multiple RTM_ADD messages will be generated:
1115
* 1) lladdr mapping (RTF_LLDATA)
1116
* 2) host route (one w/o netmask)
1117
* 3) prefix route
1118
*/
1119
1120
while (true) {
1121
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1122
/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1123
if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1124
break;
1125
}
1126
1127
/* This should be a message for the prefix route */
1128
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net6,
1129
(struct sockaddr *)&c->mask6, NULL);
1130
1131
/* gateway should be link sdl with ifindex of an address interface */
1132
verify_link_gateway(rtm, c->ifindex);
1133
1134
int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1135
verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1136
}
1137
1138
RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success,
1139
"Tests ordering of the messages for IPv6 global unicast ifaddr assignment");
1140
1141
ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc)
1142
{
1143
DECLARE_TEST_VARS;
1144
1145
c = presetup_ipv6_iface(tc);
1146
1147
c->rtsock_fd = rtsock_setup_socket();
1148
1149
ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1150
1151
int count = 0, tries = 0;
1152
1153
enum msgtype {
1154
MSG_IFADDR,
1155
MSG_HOSTROUTE,
1156
MSG_PREFIXROUTE,
1157
MSG_MAX,
1158
};
1159
1160
int msg_array[MSG_MAX];
1161
1162
bzero(msg_array, sizeof(msg_array));
1163
1164
while (count < 3 && tries < 20) {
1165
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1166
tries++;
1167
/* Classify */
1168
if (rtm->rtm_type == RTM_NEWADDR) {
1169
RLOG("MSG_IFADDR: %d", count);
1170
msg_array[MSG_IFADDR] = count++;
1171
continue;
1172
}
1173
1174
/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1175
if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1176
RLOG("MSG_PREFIXROUTE: %d", count);
1177
msg_array[MSG_PREFIXROUTE] = count++;
1178
continue;
1179
}
1180
1181
if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLDATA) == 0)) {
1182
RLOG("MSG_HOSTROUTE: %d", count);
1183
msg_array[MSG_HOSTROUTE] = count++;
1184
continue;
1185
}
1186
1187
RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1188
tries);
1189
}
1190
1191
/* TODO: verify multicast */
1192
ATF_REQUIRE_MSG(count == 3, "Received only %d/3 messages", count);
1193
ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1194
}
1195
1196
RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success,
1197
"Tests validness for /128 host route removal after ifaddr removal");
1198
1199
ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc)
1200
{
1201
DECLARE_TEST_VARS;
1202
1203
c = presetup_ipv6_iface(tc);
1204
1205
ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1206
1207
c->rtsock_fd = rtsock_setup_socket();
1208
1209
ret = iface_delete_addr(c->ifname, c->addr6_str);
1210
1211
while (true) {
1212
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1213
if ((rtm->rtm_type == RTM_DELETE) &&
1214
((rtm->rtm_flags & RTF_LLINFO) == 0) &&
1215
rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL)
1216
break;
1217
}
1218
/* This should be a message for the host route */
1219
1220
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->addr6, NULL, NULL);
1221
rtsock_validate_pid_kernel(rtm);
1222
/* No netmask should be set */
1223
RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");
1224
1225
/* gateway should be link sdl with ifindex of an address interface */
1226
verify_link_gateway(rtm, c->ifindex);
1227
1228
/* XXX: consider passing ifindex in rtm_index as done in RTM_ADD. */
1229
int expected_rt_flags = RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;
1230
RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == expected_rt_flags,
1231
"expected rtm flags: 0x%X, got 0x%X", expected_rt_flags, rtm->rtm_flags);
1232
}
1233
1234
RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success,
1235
"Tests validness for the prefix route removal after ifaddr assignment");
1236
1237
ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc)
1238
{
1239
DECLARE_TEST_VARS;
1240
1241
c = presetup_ipv6_iface(tc);
1242
1243
ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1244
1245
c->rtsock_fd = rtsock_setup_socket();
1246
1247
ret = iface_delete_addr(c->ifname, c->addr6_str);
1248
1249
while (true) {
1250
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1251
/* Find RTM_DELETE with netmask - this should skip both host route and LLADDR */
1252
if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1253
break;
1254
}
1255
1256
/* This should be a message for the prefix route */
1257
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net6,
1258
(struct sockaddr *)&c->mask6, NULL);
1259
1260
/* gateway should be link sdl with ifindex of an address interface */
1261
verify_link_gateway(rtm, c->ifindex);
1262
1263
int expected_rt_flags = RTF_DONE | RTF_PINNED;
1264
verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1265
}
1266
1267
RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success,
1268
"Tests validness for the prefix route announce after ifaddr assignment");
1269
1270
ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc)
1271
{
1272
DECLARE_TEST_VARS;
1273
1274
c = presetup_ipv4_iface(tc);
1275
1276
c->rtsock_fd = rtsock_setup_socket();
1277
1278
ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);
1279
1280
/*
1281
* Multiple RTM_ADD messages will be generated:
1282
* 1) lladdr mapping (RTF_LLDATA)
1283
* 3) prefix route
1284
*/
1285
1286
while (true) {
1287
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1288
/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1289
if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1290
break;
1291
}
1292
1293
/* This should be a message for the prefix route */
1294
verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net4,
1295
(struct sockaddr *)&c->mask4, NULL);
1296
1297
/* gateway should be link sdl with ifindex of an address interface */
1298
verify_link_gateway(rtm, c->ifindex);
1299
1300
int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;
1301
verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1302
}
1303
1304
RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success,
1305
"Tests ordering of the messages for IPv4 unicast ifaddr assignment");
1306
1307
ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc)
1308
{
1309
DECLARE_TEST_VARS;
1310
1311
c = presetup_ipv4_iface(tc);
1312
1313
c->rtsock_fd = rtsock_setup_socket();
1314
1315
ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1316
1317
int count = 0, tries = 0;
1318
1319
enum msgtype {
1320
MSG_IFADDR,
1321
MSG_PREFIXROUTE,
1322
MSG_MAX,
1323
};
1324
1325
int msg_array[MSG_MAX];
1326
1327
bzero(msg_array, sizeof(msg_array));
1328
1329
while (count < 2 && tries < 20) {
1330
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1331
tries++;
1332
/* Classify */
1333
if (rtm->rtm_type == RTM_NEWADDR) {
1334
RLOG("MSG_IFADDR: %d", count);
1335
msg_array[MSG_IFADDR] = count++;
1336
continue;
1337
}
1338
1339
/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1340
if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {
1341
RLOG("MSG_PREFIXROUTE: %d", count);
1342
msg_array[MSG_PREFIXROUTE] = count++;
1343
continue;
1344
}
1345
1346
RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),
1347
tries);
1348
}
1349
1350
/* TODO: verify multicast */
1351
ATF_REQUIRE_MSG(count == 2, "Received only %d/2 messages", count);
1352
ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");
1353
}
1354
1355
RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success,
1356
"Tests validness for the prefix route removal after ifaddr assignment");
1357
1358
ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc)
1359
{
1360
DECLARE_TEST_VARS;
1361
1362
c = presetup_ipv4_iface(tc);
1363
1364
1365
ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);
1366
1367
c->rtsock_fd = rtsock_setup_socket();
1368
1369
ret = iface_delete_addr(c->ifname, c->addr4_str);
1370
1371
while (true) {
1372
rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));
1373
/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */
1374
if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))
1375
break;
1376
}
1377
1378
/* This should be a message for the prefix route */
1379
verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net4,
1380
(struct sockaddr *)&c->mask4, NULL);
1381
1382
/* gateway should be link sdl with ifindex of an address interface */
1383
verify_link_gateway(rtm, c->ifindex);
1384
1385
int expected_rt_flags = RTF_DONE | RTF_PINNED;
1386
verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);
1387
}
1388
1389
1390
ATF_TP_ADD_TCS(tp)
1391
{
1392
ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success);
1393
ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success);
1394
ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_success);
1395
ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure);
1396
ATF_TP_ADD_TC(tp, rtm_add_v4_no_rtf_host_success);
1397
ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success);
1398
ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success);
1399
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success);
1400
ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success);
1401
ATF_TP_ADD_TC(tp, rtm_change_v4_gw_success);
1402
ATF_TP_ADD_TC(tp, rtm_change_v4_mtu_success);
1403
ATF_TP_ADD_TC(tp, rtm_change_v4_flags_success);
1404
ATF_TP_ADD_TC(tp, rtm_change_v6_gw_success);
1405
ATF_TP_ADD_TC(tp, rtm_change_v6_mtu_success);
1406
ATF_TP_ADD_TC(tp, rtm_change_v6_flags_success);
1407
/* ifaddr tests */
1408
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success);
1409
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success);
1410
ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_ordered_success);
1411
ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_hostroute_success);
1412
ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_prefixroute_success);
1413
ATF_TP_ADD_TC(tp, rtm_add_v4_gu_ifa_ordered_success);
1414
ATF_TP_ADD_TC(tp, rtm_del_v4_gu_ifa_prefixroute_success);
1415
/* temporal routes */
1416
ATF_TP_ADD_TC(tp, rtm_add_v4_temporal1_success);
1417
ATF_TP_ADD_TC(tp, rtm_add_v6_temporal1_success);
1418
1419
return (atf_no_error());
1420
}
1421
1422
1423