Path: blob/main/tests/sys/net/routing/test_rtsock_l3.c
39604 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2019 Alexander V. Chernikov4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*/2627#include "rtsock_common.h"28#include "rtsock_config.h"29#include "sys/types.h"30#include <sys/time.h>31#include <sys/ioctl.h>3233#include "net/bpf.h"3435static void36jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)37{38char vnet_name[512];3940snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));41RLOG("jumping to %s", vnet_name);4243vnet_switch(vnet_name, c->ifnames, c->num_interfaces);4445/* Update ifindex cache */46c->ifindex = if_nametoindex(c->ifname);47}4849static inline struct rtsock_test_config *50presetup_ipv6_iface(const atf_tc_t *tc)51{52struct rtsock_test_config *c;53int ret;5455c = config_setup(tc, NULL);5657jump_vnet(c, tc);5859ret = iface_turn_up(c->ifname);60ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);6162ret = iface_enable_ipv6(c->ifname);63ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);64ATF_REQUIRE_ERRNO(0, true);6566return (c);67}6869static inline struct rtsock_test_config *70presetup_ipv6(const atf_tc_t *tc)71{72struct rtsock_test_config *c;73int ret;7475c = presetup_ipv6_iface(tc);7677ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);7879c->rtsock_fd = rtsock_setup_socket();80ATF_REQUIRE_ERRNO(0, true);8182return (c);83}8485static inline struct rtsock_test_config *86presetup_ipv4_iface(const atf_tc_t *tc)87{88struct rtsock_test_config *c;89int ret;9091c = config_setup(tc, NULL);92ATF_REQUIRE(c != NULL);9394jump_vnet(c, tc);9596ret = iface_turn_up(c->ifname);97ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);98ATF_REQUIRE_ERRNO(0, true);99100return (c);101}102103static inline struct rtsock_test_config *104presetup_ipv4(const atf_tc_t *tc)105{106struct rtsock_test_config *c;107int ret;108109c = presetup_ipv4_iface(tc);110111/* assumes ifconfig doing IFF_UP */112ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);113ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");114115c->rtsock_fd = rtsock_setup_socket();116ATF_REQUIRE_ERRNO(0, true);117118return (c);119}120121122static void123prepare_v4_network(struct rtsock_test_config *c, struct sockaddr_in *dst,124struct sockaddr_in *mask, struct sockaddr_in *gw)125{126/* Create IPv4 subnetwork with smaller prefix */127sa_fill_mask4(mask, c->plen4 + 1);128*dst = c->net4;129/* Calculate GW as last-net-address - 1 */130*gw = c->net4;131gw->sin_addr.s_addr = htonl((ntohl(c->net4.sin_addr.s_addr) | ~ntohl(c->mask4.sin_addr.s_addr)) - 1);132sa_print((struct sockaddr *)dst, 0);133sa_print((struct sockaddr *)mask, 0);134sa_print((struct sockaddr *)gw, 0);135}136137static void138prepare_v6_network(struct rtsock_test_config *c, struct sockaddr_in6 *dst,139struct sockaddr_in6 *mask, struct sockaddr_in6 *gw)140{141/* Create IPv6 subnetwork with smaller prefix */142sa_fill_mask6(mask, c->plen6 + 1);143*dst = c->net6;144/* Calculate GW as last-net-address - 1 */145*gw = c->net6;146#define _s6_addr32 __u6_addr.__u6_addr32147gw->sin6_addr._s6_addr32[0] = htonl((ntohl(gw->sin6_addr._s6_addr32[0]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[0])));148gw->sin6_addr._s6_addr32[1] = htonl((ntohl(gw->sin6_addr._s6_addr32[1]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[1])));149gw->sin6_addr._s6_addr32[2] = htonl((ntohl(gw->sin6_addr._s6_addr32[2]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[2])));150gw->sin6_addr._s6_addr32[3] = htonl((ntohl(gw->sin6_addr._s6_addr32[3]) | ~ntohl(c->mask6.sin6_addr._s6_addr32[3])) - 1);151#undef _s6_addr32152sa_print((struct sockaddr *)dst, 0);153sa_print((struct sockaddr *)mask, 0);154sa_print((struct sockaddr *)gw, 0);155}156157static void158prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,159struct sockaddr *mask, struct sockaddr *gw)160{161162rtsock_prepare_route_message(rtm, cmd, dst, mask, gw);163164if (cmd == RTM_ADD || cmd == RTM_CHANGE)165rtm->rtm_flags |= RTF_STATIC;166}167168static void169verify_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,170struct sockaddr *mask, struct sockaddr *gw)171{172char msg[512];173struct sockaddr *sa;174int ret;175176RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == cmd,177"expected %s message, got %d (%s)", rtsock_print_cmdtype(cmd),178rtm->rtm_type, rtsock_print_cmdtype(rtm->rtm_type));179RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_errno == 0,180"got got errno %d as message reply", rtm->rtm_errno);181RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->_rtm_spare1 == 0,182"expected rtm_spare==0, got %d", rtm->_rtm_spare1);183184/* kernel MAY return more sockaddrs, including RTA_IFP / RTA_IFA, so verify the needed ones */185if (dst != NULL) {186sa = rtsock_find_rtm_sa(rtm, RTA_DST);187RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "DST is not set");188ret = sa_equal_msg(sa, dst, msg, sizeof(msg));189RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);190}191192if (mask != NULL) {193sa = rtsock_find_rtm_sa(rtm, RTA_NETMASK);194RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "NETMASK is not set");195ret = sa_equal_msg(sa, mask, msg, sizeof(msg));196ret = 1;197RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "NETMASK sa diff: %s", msg);198}199200if (gw != NULL) {201sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);202RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");203ret = sa_equal_msg(sa, gw, msg, sizeof(msg));204RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);205}206}207208static void209verify_route_message_extra(struct rt_msghdr *rtm, int ifindex, int rtm_flags)210{211RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_index == ifindex,212"expected ifindex %d, got %d", ifindex, rtm->rtm_index);213214if (rtm->rtm_flags != rtm_flags) {215char got_flags[64], expected_flags[64];216rtsock_print_rtm_flags(got_flags, sizeof(got_flags),217rtm->rtm_flags);218rtsock_print_rtm_flags(expected_flags, sizeof(expected_flags),219rtm_flags);220221RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == rtm_flags,222"expected flags: 0x%X %s, got 0x%X %s",223rtm_flags, expected_flags,224rtm->rtm_flags, got_flags);225}226}227228static void229verify_link_gateway(struct rt_msghdr *rtm, int ifindex)230{231struct sockaddr *sa;232struct sockaddr_dl *sdl;233234sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);235RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");236RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);237sdl = (struct sockaddr_dl *)sa;238RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == ifindex, "GW ifindex is %d", sdl->sdl_index);239}240241/* TESTS */242243#define DECLARE_TEST_VARS \244char buffer[2048]; \245struct rtsock_test_config *c; \246struct rt_msghdr *rtm = (struct rt_msghdr *)buffer; \247struct sockaddr *sa; \248int ret; \249\250251#define DESCRIBE_ROOT_TEST(_msg) config_describe_root_test(tc, _msg)252#define CLEANUP_AFTER_TEST config_generic_cleanup(tc)253254#define RTM_DECLARE_ROOT_TEST(_name, _descr) \255ATF_TC_WITH_CLEANUP(_name); \256ATF_TC_HEAD(_name, tc) \257{ \258DESCRIBE_ROOT_TEST(_descr); \259} \260ATF_TC_CLEANUP(_name, tc) \261{ \262CLEANUP_AFTER_TEST; \263}264265ATF_TC_WITH_CLEANUP(rtm_get_v4_exact_success);266ATF_TC_HEAD(rtm_get_v4_exact_success, tc)267{268DESCRIBE_ROOT_TEST("Tests RTM_GET with exact prefix lookup on an interface prefix");269}270271ATF_TC_BODY(rtm_get_v4_exact_success, tc)272{273DECLARE_TEST_VARS;274275c = presetup_ipv4(tc);276277prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,278(struct sockaddr *)&c->mask4, NULL);279280rtsock_send_rtm(c->rtsock_fd, rtm);281282rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);283284/*285* RTM_GET: Report Metrics: len 240, pid: 45072, seq 42, errno 0, flags: <UP,DONE,PINNED>286* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>287* af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}288* af=link len=54 sdl_index=3 if_name=tap4242 hd={36, 12, 03, 00, 06, 00{49}}289* af=inet len=16 addr=255.255.255.0 hd={10, 02, FF{5}, 00{9}}290*/291292verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,293(struct sockaddr *)&c->mask4, NULL);294295verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);296297/* Explicitly verify gateway for the interface route */298verify_link_gateway(rtm, c->ifindex);299sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);300RTSOCK_ATF_REQUIRE_MSG(rtm, sa != NULL, "GATEWAY is not set");301RTSOCK_ATF_REQUIRE_MSG(rtm, sa->sa_family == AF_LINK, "GW sa family is %d", sa->sa_family);302struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;303RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_index == c->ifindex, "GW ifindex is %d", sdl->sdl_index);304}305306ATF_TC_CLEANUP(rtm_get_v4_exact_success, tc)307{308CLEANUP_AFTER_TEST;309}310311ATF_TC_WITH_CLEANUP(rtm_get_v4_lpm_success);312ATF_TC_HEAD(rtm_get_v4_lpm_success, tc)313{314DESCRIBE_ROOT_TEST("Tests RTM_GET with address lookup on an existing prefix");315}316317ATF_TC_BODY(rtm_get_v4_lpm_success, tc)318{319DECLARE_TEST_VARS;320321c = presetup_ipv4(tc);322323prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4, NULL, NULL);324325rtsock_send_rtm(c->rtsock_fd, rtm);326327rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);328329/*330* RTM_GET: Report Metrics: len 312, pid: 67074, seq 1, errno 0, flags:<UP,DONE,PINNED>331* locks: inits:332* sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>333* 10.0.0.0 link#1 255.255.255.0 vtnet0:52.54.0.42.f.ef 10.0.0.157334*/335336verify_route_message(rtm, RTM_GET, (struct sockaddr *)&c->net4,337(struct sockaddr *)&c->mask4, NULL);338339verify_route_message_extra(rtm, c->ifindex, RTF_UP | RTF_DONE | RTF_PINNED);340}341342ATF_TC_CLEANUP(rtm_get_v4_lpm_success, tc)343{344CLEANUP_AFTER_TEST;345}346347348ATF_TC_WITH_CLEANUP(rtm_get_v4_empty_dst_failure);349ATF_TC_HEAD(rtm_get_v4_empty_dst_failure, tc)350{351352DESCRIBE_ROOT_TEST("Tests RTM_GET with empty DST addr");353}354355ATF_TC_BODY(rtm_get_v4_empty_dst_failure, tc)356{357DECLARE_TEST_VARS;358struct rtsock_config_options co;359360bzero(&co, sizeof(co));361co.num_interfaces = 0;362363c = config_setup(tc,&co);364c->rtsock_fd = rtsock_setup_socket();365366rtsock_prepare_route_message(rtm, RTM_GET, NULL,367(struct sockaddr *)&c->mask4, NULL);368rtsock_update_rtm_len(rtm);369370ATF_CHECK_ERRNO(EINVAL, write(c->rtsock_fd, rtm, rtm->rtm_msglen) == -1);371}372373ATF_TC_CLEANUP(rtm_get_v4_empty_dst_failure, tc)374{375CLEANUP_AFTER_TEST;376}377378ATF_TC_WITH_CLEANUP(rtm_get_v4_hostbits_success);379ATF_TC_HEAD(rtm_get_v4_hostbits_success, tc)380{381DESCRIBE_ROOT_TEST("Tests RTM_GET with prefix with some hosts-bits set");382}383384ATF_TC_BODY(rtm_get_v4_hostbits_success, tc)385{386DECLARE_TEST_VARS;387388c = presetup_ipv4(tc);389390/* Q the same prefix */391rtsock_prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&c->addr4,392(struct sockaddr *)&c->mask4, NULL);393rtsock_update_rtm_len(rtm);394395ATF_REQUIRE_ERRNO(0, true);396ATF_CHECK_ERRNO(0, write(c->rtsock_fd, rtm, rtm->rtm_msglen) > 0);397}398399ATF_TC_CLEANUP(rtm_get_v4_hostbits_success, tc)400{401CLEANUP_AFTER_TEST;402}403404ATF_TC_WITH_CLEANUP(rtm_add_v4_gw_direct_success);405ATF_TC_HEAD(rtm_add_v4_gw_direct_success, tc)406{407DESCRIBE_ROOT_TEST("Tests IPv4 route addition with directly-reachable GW specified by IP");408}409410ATF_TC_BODY(rtm_add_v4_gw_direct_success, tc)411{412DECLARE_TEST_VARS;413414c = presetup_ipv4(tc);415416/* Create IPv4 subnetwork with smaller prefix */417struct sockaddr_in mask4;418struct sockaddr_in net4;419struct sockaddr_in gw4;420prepare_v4_network(c, &net4, &mask4, &gw4);421422prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,423(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);424425rtsock_send_rtm(c->rtsock_fd, rtm);426rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);427428/*429* RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>430* locks: inits:431* sockaddrs: <DST,GATEWAY,NETMASK>432* 192.0.2.0 192.0.2.254 255.255.255.128433*/434435verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,436(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);437verify_route_message_extra(rtm, c->ifindex,438RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);439}440441ATF_TC_CLEANUP(rtm_add_v4_gw_direct_success, tc)442{443CLEANUP_AFTER_TEST;444}445446RTM_DECLARE_ROOT_TEST(rtm_add_v4_no_rtf_host_success,447"Tests success with netmask sa and RTF_HOST inconsistency");448449ATF_TC_BODY(rtm_add_v4_no_rtf_host_success, tc)450{451DECLARE_TEST_VARS;452453c = presetup_ipv4(tc);454455/* Create IPv4 subnetwork with smaller prefix */456struct sockaddr_in mask4;457struct sockaddr_in net4;458struct sockaddr_in gw4;459prepare_v4_network(c, &net4, &mask4, &gw4);460461prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,462NULL, (struct sockaddr *)&gw4);463rtsock_update_rtm_len(rtm);464465/* RTF_HOST is NOT specified, while netmask is empty */466ATF_REQUIRE_ERRNO(0, true);467ATF_CHECK_ERRNO(0, write(c->rtsock_fd, rtm, rtm->rtm_msglen) > 0);468}469470ATF_TC_WITH_CLEANUP(rtm_del_v4_prefix_nogw_success);471ATF_TC_HEAD(rtm_del_v4_prefix_nogw_success, tc)472{473DESCRIBE_ROOT_TEST("Tests IPv4 route removal without specifying gateway");474}475476ATF_TC_BODY(rtm_del_v4_prefix_nogw_success, tc)477{478DECLARE_TEST_VARS;479480c = presetup_ipv4(tc);481482/* Create IPv4 subnetwork with smaller prefix */483struct sockaddr_in mask4;484struct sockaddr_in net4;485struct sockaddr_in gw4;486prepare_v4_network(c, &net4, &mask4, &gw4);487488prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,489(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);490491rtsock_send_rtm(c->rtsock_fd, rtm);492493/* Route has been added successfully, try to delete it */494prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,495(struct sockaddr *)&mask4, NULL);496497rtsock_send_rtm(c->rtsock_fd, rtm);498499rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);500501/*502* RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>503* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>504* af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}505* af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}506* af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}507*/508verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,509(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);510511verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);512}513514ATF_TC_CLEANUP(rtm_del_v4_prefix_nogw_success, tc)515{516CLEANUP_AFTER_TEST;517}518519RTM_DECLARE_ROOT_TEST(rtm_change_v4_gw_success,520"Tests IPv4 gateway change");521522ATF_TC_BODY(rtm_change_v4_gw_success, tc)523{524DECLARE_TEST_VARS;525struct rtsock_config_options co;526527bzero(&co, sizeof(co));528co.num_interfaces = 2;529530c = config_setup(tc, &co);531jump_vnet(c, tc);532533ret = iface_turn_up(c->ifnames[0]);534ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);535ret = iface_turn_up(c->ifnames[1]);536ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);537538ret = iface_setup_addr(c->ifnames[0], c->addr4_str, c->plen4);539ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");540541/* Use 198.51.100.0/24 "TEST-NET-2" for the second interface */542ret = iface_setup_addr(c->ifnames[1], "198.51.100.1", 24);543ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");544545c->rtsock_fd = rtsock_setup_socket();546547/* Create IPv4 subnetwork with smaller prefix */548struct sockaddr_in mask4;549struct sockaddr_in net4;550struct sockaddr_in gw4;551prepare_v4_network(c, &net4, &mask4, &gw4);552553prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,554(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);555556rtsock_send_rtm(c->rtsock_fd, rtm);557rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);558559verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,560(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);561562/* Change gateway to the one on desiding on the other interface */563inet_pton(AF_INET, "198.51.100.2", &gw4.sin_addr.s_addr);564prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,565(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);566rtsock_send_rtm(c->rtsock_fd, rtm);567568rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);569570verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,571(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);572573verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),574RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);575576/* Verify the change has actually taken place */577prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,578(struct sockaddr *)&mask4, NULL);579580rtsock_send_rtm(c->rtsock_fd, rtm);581582/*583* RTM_GET: len 200, pid: 3894, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>584* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>585* af=inet len=16 addr=192.0.2.0 hd={x10, x02, x00{2}, xC0, x00, x02, x00{9}}586* af=inet len=16 addr=198.51.100.2 hd={x10, x02, x00{2}, xC6, x33, x64, x02, x00{8}}587* af=inet len=16 addr=255.255.255.128 hd={x10, x02, xFF, xFF, xFF, xFF, xFF, x80, x00{8}}588*/589590rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);591verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),592RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);593594}595596RTM_DECLARE_ROOT_TEST(rtm_change_v4_mtu_success,597"Tests IPv4 path mtu change");598599ATF_TC_BODY(rtm_change_v4_mtu_success, tc)600{601DECLARE_TEST_VARS;602603unsigned long test_mtu = 1442;604605c = presetup_ipv4(tc);606607/* Create IPv4 subnetwork with smaller prefix */608struct sockaddr_in mask4;609struct sockaddr_in net4;610struct sockaddr_in gw4;611prepare_v4_network(c, &net4, &mask4, &gw4);612613prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,614(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);615616rtsock_send_rtm(c->rtsock_fd, rtm);617rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);618619/* Change MTU */620prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,621(struct sockaddr *)&mask4, NULL);622rtm->rtm_inits |= RTV_MTU;623rtm->rtm_rmx.rmx_mtu = test_mtu;624625rtsock_send_rtm(c->rtsock_fd, rtm);626rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);627628verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,629(struct sockaddr *)&mask4, NULL);630631RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,632"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);633634/* Verify the change has actually taken place */635prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,636(struct sockaddr *)&mask4, NULL);637638rtsock_send_rtm(c->rtsock_fd, rtm);639rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);640641RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,642"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);643}644645RTM_DECLARE_ROOT_TEST(rtm_change_v4_flags_success,646"Tests IPv4 path flags change");647648ATF_TC_BODY(rtm_change_v4_flags_success, tc)649{650DECLARE_TEST_VARS;651652uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;653uint32_t desired_flags;654655c = presetup_ipv4(tc);656657/* Create IPv4 subnetwork with smaller prefix */658struct sockaddr_in mask4;659struct sockaddr_in net4;660struct sockaddr_in gw4;661prepare_v4_network(c, &net4, &mask4, &gw4);662663prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,664(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);665666/* Set test flags during route addition */667desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;668rtm->rtm_flags |= test_flags;669rtsock_send_rtm(c->rtsock_fd, rtm);670rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);671672/* Change flags */673prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net4,674(struct sockaddr *)&mask4, NULL);675rtm->rtm_flags &= ~test_flags;676desired_flags &= ~test_flags;677678rtsock_send_rtm(c->rtsock_fd, rtm);679rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);680681/* Verify updated flags */682verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);683684/* Verify the change has actually taken place */685prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net4,686(struct sockaddr *)&mask4, NULL);687688rtsock_send_rtm(c->rtsock_fd, rtm);689rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);690691verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);692}693694695ATF_TC_WITH_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success);696ATF_TC_HEAD(rtm_add_v6_gu_gw_gu_direct_success, tc)697{698DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");699}700701ATF_TC_BODY(rtm_add_v6_gu_gw_gu_direct_success, tc)702{703DECLARE_TEST_VARS;704705c = presetup_ipv6(tc);706707/* Create IPv6 subnetwork with smaller prefix */708struct sockaddr_in6 mask6;709struct sockaddr_in6 net6;710struct sockaddr_in6 gw6;711prepare_v6_network(c, &net6, &mask6, &gw6);712713prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,714(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);715716rtsock_send_rtm(c->rtsock_fd, rtm);717rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);718719/*720* RTM_ADD: Add Route: len 200, pid: 46068, seq 42, errno 0, flags:<GATEWAY,DONE,STATIC>721* locks: inits:722* sockaddrs: <DST,GATEWAY,NETMASK>723* 192.0.2.0 192.0.2.254 255.255.255.128724*/725726verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,727(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);728729verify_route_message_extra(rtm, c->ifindex,730RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);731}732733ATF_TC_CLEANUP(rtm_add_v6_gu_gw_gu_direct_success, tc)734{735CLEANUP_AFTER_TEST;736}737738ATF_TC_WITH_CLEANUP(rtm_del_v6_gu_prefix_nogw_success);739ATF_TC_HEAD(rtm_del_v6_gu_prefix_nogw_success, tc)740{741742DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix removal without specifying gateway");743}744745ATF_TC_BODY(rtm_del_v6_gu_prefix_nogw_success, tc)746{747DECLARE_TEST_VARS;748749c = presetup_ipv6(tc);750751/* Create IPv6 subnetwork with smaller prefix */752struct sockaddr_in6 mask6;753struct sockaddr_in6 net6;754struct sockaddr_in6 gw6;755prepare_v6_network(c, &net6, &mask6, &gw6);756757prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,758(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);759760rtsock_send_rtm(c->rtsock_fd, rtm);761762/* Route has been added successfully, try to delete it */763prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,764(struct sockaddr *)&mask6, NULL);765766rtsock_send_rtm(c->rtsock_fd, rtm);767rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);768769/*770* RTM_DELETE: Delete Route: len 200, pid: 46417, seq 43, errno 0, flags: <GATEWAY,DONE,STATIC>771* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>772* af=inet len=16 addr=192.0.2.0 hd={10, 02, 00{2}, C0, 00, 02, 00{9}}773* af=inet len=16 addr=192.0.2.254 hd={10, 02, 00{2}, C0, 00, 02, FE, 00{8}}774* af=inet len=16 addr=255.255.255.128 hd={10, 02, FF{5}, 80, 00{8}}775*/776777verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,778(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);779verify_route_message_extra(rtm, c->ifindex, RTF_DONE | RTF_GATEWAY | RTF_STATIC);780}781782ATF_TC_CLEANUP(rtm_del_v6_gu_prefix_nogw_success, tc)783{784CLEANUP_AFTER_TEST;785}786787RTM_DECLARE_ROOT_TEST(rtm_change_v6_gw_success,788"Tests IPv6 gateway change");789790ATF_TC_BODY(rtm_change_v6_gw_success, tc)791{792DECLARE_TEST_VARS;793struct rtsock_config_options co;794795bzero(&co, sizeof(co));796co.num_interfaces = 2;797798c = config_setup(tc, &co);799jump_vnet(c, tc);800801ret = iface_turn_up(c->ifnames[0]);802ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[0]);803ret = iface_turn_up(c->ifnames[1]);804ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifnames[1]);805806ret = iface_enable_ipv6(c->ifnames[0]);807ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[0]);808ret = iface_enable_ipv6(c->ifnames[1]);809ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifnames[1]);810811ret = iface_setup_addr(c->ifnames[0], c->addr6_str, c->plen6);812ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");813814ret = iface_setup_addr(c->ifnames[1], "2001:DB8:4242::1", 64);815ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");816817c->rtsock_fd = rtsock_setup_socket();818819/* Create IPv6 subnetwork with smaller prefix */820struct sockaddr_in6 mask6;821struct sockaddr_in6 net6;822struct sockaddr_in6 gw6;823prepare_v6_network(c, &net6, &mask6, &gw6);824825prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,826(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);827828rtsock_send_rtm(c->rtsock_fd, rtm);829rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);830831verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,832(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);833834/* Change gateway to the one on residing on the other interface */835inet_pton(AF_INET6, "2001:DB8:4242::4242", &gw6.sin6_addr);836prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,837(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);838rtsock_send_rtm(c->rtsock_fd, rtm);839840rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);841842verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,843(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);844845verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),846RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);847848/* Verify the change has actually taken place */849prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,850(struct sockaddr *)&mask6, NULL);851852rtsock_send_rtm(c->rtsock_fd, rtm);853854/*855* RTM_GET: len 248, pid: 2268, seq 44, errno 0, flags: <UP,GATEWAY,DONE,STATIC>856* sockaddrs: 0x7 <DST,GATEWAY,NETMASK>857* af=inet6 len=28 addr=2001:db8:: hd={x1C, x1C, x00{6}, x20, x01, x0D, xB8, x00{16}}858* 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}}859* af=inet6 len=28 addr=ffff:ffff:8000:: hd={x1C, x1C, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, xFF, x80, x00{15}}860*/861862rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);863verify_route_message_extra(rtm, if_nametoindex(c->ifnames[1]),864RTF_UP | RTF_DONE | RTF_GATEWAY | RTF_STATIC);865}866867RTM_DECLARE_ROOT_TEST(rtm_change_v6_mtu_success,868"Tests IPv6 path mtu change");869870ATF_TC_BODY(rtm_change_v6_mtu_success, tc)871{872DECLARE_TEST_VARS;873874unsigned long test_mtu = 1442;875876c = presetup_ipv6(tc);877878/* Create IPv6 subnetwork with smaller prefix */879struct sockaddr_in6 mask6;880struct sockaddr_in6 net6;881struct sockaddr_in6 gw6;882prepare_v6_network(c, &net6, &mask6, &gw6);883884prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,885(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);886887/* Send route add */888rtsock_send_rtm(c->rtsock_fd, rtm);889rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);890891/* Change MTU */892prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,893(struct sockaddr *)&mask6, NULL);894rtm->rtm_inits |= RTV_MTU;895rtm->rtm_rmx.rmx_mtu = test_mtu;896897rtsock_send_rtm(c->rtsock_fd, rtm);898rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);899900verify_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,901(struct sockaddr *)&mask6, NULL);902903RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,904"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);905906/* Verify the change has actually taken place */907prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,908(struct sockaddr *)&mask6, NULL);909910rtsock_send_rtm(c->rtsock_fd, rtm);911rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);912913RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_rmx.rmx_mtu == test_mtu,914"expected mtu: %lu, got %lu", test_mtu, rtm->rtm_rmx.rmx_mtu);915}916917RTM_DECLARE_ROOT_TEST(rtm_change_v6_flags_success,918"Tests IPv6 path flags change");919920ATF_TC_BODY(rtm_change_v6_flags_success, tc)921{922DECLARE_TEST_VARS;923924uint32_t test_flags = RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_STATIC;925uint32_t desired_flags;926927c = presetup_ipv6(tc);928929/* Create IPv6 subnetwork with smaller prefix */930struct sockaddr_in6 mask6;931struct sockaddr_in6 net6;932struct sockaddr_in6 gw6;933prepare_v6_network(c, &net6, &mask6, &gw6);934935prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,936(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);937938/* Set test flags during route addition */939desired_flags = RTF_UP | RTF_DONE | RTF_GATEWAY | test_flags;940rtm->rtm_flags |= test_flags;941rtsock_send_rtm(c->rtsock_fd, rtm);942rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);943944/* Change flags */945prepare_route_message(rtm, RTM_CHANGE, (struct sockaddr *)&net6,946(struct sockaddr *)&mask6, NULL);947rtm->rtm_flags &= ~test_flags;948desired_flags &= ~test_flags;949950rtsock_send_rtm(c->rtsock_fd, rtm);951rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);952953/* Verify updated flags */954verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);955956/* Verify the change has actually taken place */957prepare_route_message(rtm, RTM_GET, (struct sockaddr *)&net6,958(struct sockaddr *)&mask6, NULL);959960rtsock_send_rtm(c->rtsock_fd, rtm);961rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);962963verify_route_message_extra(rtm, c->ifindex, desired_flags | RTF_DONE);964}965966ATF_TC_WITH_CLEANUP(rtm_add_v4_temporal1_success);967ATF_TC_HEAD(rtm_add_v4_temporal1_success, tc)968{969DESCRIBE_ROOT_TEST("Tests IPv4 route expiration with expire time set");970}971972ATF_TC_BODY(rtm_add_v4_temporal1_success, tc)973{974DECLARE_TEST_VARS;975976c = presetup_ipv4(tc);977978/* Create IPv4 subnetwork with smaller prefix */979struct sockaddr_in mask4;980struct sockaddr_in net4;981struct sockaddr_in gw4;982prepare_v4_network(c, &net4, &mask4, &gw4);983984prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net4,985(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);986987/* Set expire time to now */988struct timeval tv;989gettimeofday(&tv, NULL);990rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;991rtm->rtm_inits |= RTV_EXPIRE;992993rtsock_send_rtm(c->rtsock_fd, rtm);994rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);995ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");996RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");997998/* The next should be route deletion */999rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));10001001verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net4,1002(struct sockaddr *)&mask4, (struct sockaddr *)&gw4);10031004verify_route_message_extra(rtm, c->ifindex,1005RTF_DONE | RTF_GATEWAY | RTF_STATIC);1006}10071008ATF_TC_CLEANUP(rtm_add_v4_temporal1_success, tc)1009{1010CLEANUP_AFTER_TEST;1011}10121013ATF_TC_WITH_CLEANUP(rtm_add_v6_temporal1_success);1014ATF_TC_HEAD(rtm_add_v6_temporal1_success, tc)1015{1016DESCRIBE_ROOT_TEST("Tests IPv6 global unicast prefix addition with directly-reachable GU GW");1017}10181019ATF_TC_BODY(rtm_add_v6_temporal1_success, tc)1020{1021DECLARE_TEST_VARS;10221023c = presetup_ipv6(tc);10241025/* Create IPv6 subnetwork with smaller prefix */1026struct sockaddr_in6 mask6;1027struct sockaddr_in6 net6;1028struct sockaddr_in6 gw6;1029prepare_v6_network(c, &net6, &mask6, &gw6);10301031prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&net6,1032(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);10331034/* Set expire time to now */1035struct timeval tv;1036gettimeofday(&tv, NULL);1037rtm->rtm_rmx.rmx_expire = tv.tv_sec - 1;1038rtm->rtm_inits |= RTV_EXPIRE;10391040rtsock_send_rtm(c->rtsock_fd, rtm);1041rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);1042ATF_REQUIRE_MSG(rtm != NULL, "unable to get rtsock reply for RTM_ADD");1043RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_inits & RTV_EXPIRE, "RTV_EXPIRE not set");10441045/* The next should be route deletion */1046rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));10471048verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&net6,1049(struct sockaddr *)&mask6, (struct sockaddr *)&gw6);10501051verify_route_message_extra(rtm, c->ifindex,1052RTF_DONE | RTF_GATEWAY | RTF_STATIC);1053}10541055ATF_TC_CLEANUP(rtm_add_v6_temporal1_success, tc)1056{1057CLEANUP_AFTER_TEST;1058}10591060/* Interface address messages tests */10611062RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_hostroute_success,1063"Tests validness for /128 host route announce after ifaddr assignment");10641065ATF_TC_BODY(rtm_add_v6_gu_ifa_hostroute_success, tc)1066{1067DECLARE_TEST_VARS;10681069c = presetup_ipv6_iface(tc);10701071c->rtsock_fd = rtsock_setup_socket();10721073ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);10741075/*1076* There will be multiple.1077* RTM_ADD without llinfo.1078*/10791080while (true) {1081rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1082if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLINFO) == 0))1083break;1084}1085/* This should be a message for the host route */10861087verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->addr6, NULL, NULL);1088rtsock_validate_pid_kernel(rtm);1089/* No netmask should be set */1090RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");10911092/* gateway should be link sdl with ifindex of an address interface */1093verify_link_gateway(rtm, c->ifindex);10941095int expected_rt_flags = RTF_UP | RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;1096verify_route_message_extra(rtm, if_nametoindex("lo0"), expected_rt_flags);1097}10981099RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_prefixroute_success,1100"Tests validness for the prefix route announce after ifaddr assignment");11011102ATF_TC_BODY(rtm_add_v6_gu_ifa_prefixroute_success, tc)1103{1104DECLARE_TEST_VARS;11051106c = presetup_ipv6_iface(tc);11071108c->rtsock_fd = rtsock_setup_socket();11091110ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);11111112/*1113* Multiple RTM_ADD messages will be generated:1114* 1) lladdr mapping (RTF_LLDATA)1115* 2) host route (one w/o netmask)1116* 3) prefix route1117*/11181119while (true) {1120rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1121/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */1122if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))1123break;1124}11251126/* This should be a message for the prefix route */1127verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net6,1128(struct sockaddr *)&c->mask6, NULL);11291130/* gateway should be link sdl with ifindex of an address interface */1131verify_link_gateway(rtm, c->ifindex);11321133int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;1134verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);1135}11361137RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_ifa_ordered_success,1138"Tests ordering of the messages for IPv6 global unicast ifaddr assignment");11391140ATF_TC_BODY(rtm_add_v6_gu_ifa_ordered_success, tc)1141{1142DECLARE_TEST_VARS;11431144c = presetup_ipv6_iface(tc);11451146c->rtsock_fd = rtsock_setup_socket();11471148ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);11491150int count = 0, tries = 0;11511152enum msgtype {1153MSG_IFADDR,1154MSG_HOSTROUTE,1155MSG_PREFIXROUTE,1156MSG_MAX,1157};11581159int msg_array[MSG_MAX];11601161bzero(msg_array, sizeof(msg_array));11621163while (count < 3 && tries < 20) {1164rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1165tries++;1166/* Classify */1167if (rtm->rtm_type == RTM_NEWADDR) {1168RLOG("MSG_IFADDR: %d", count);1169msg_array[MSG_IFADDR] = count++;1170continue;1171}11721173/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */1174if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {1175RLOG("MSG_PREFIXROUTE: %d", count);1176msg_array[MSG_PREFIXROUTE] = count++;1177continue;1178}11791180if ((rtm->rtm_type == RTM_ADD) && ((rtm->rtm_flags & RTF_LLDATA) == 0)) {1181RLOG("MSG_HOSTROUTE: %d", count);1182msg_array[MSG_HOSTROUTE] = count++;1183continue;1184}11851186RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),1187tries);1188}11891190/* TODO: verify multicast */1191ATF_REQUIRE_MSG(count == 3, "Received only %d/3 messages", count);1192ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");1193}11941195RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_hostroute_success,1196"Tests validness for /128 host route removal after ifaddr removal");11971198ATF_TC_BODY(rtm_del_v6_gu_ifa_hostroute_success, tc)1199{1200DECLARE_TEST_VARS;12011202c = presetup_ipv6_iface(tc);12031204ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);12051206c->rtsock_fd = rtsock_setup_socket();12071208ret = iface_delete_addr(c->ifname, c->addr6_str);12091210while (true) {1211rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1212if ((rtm->rtm_type == RTM_DELETE) &&1213((rtm->rtm_flags & RTF_LLINFO) == 0) &&1214rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL)1215break;1216}1217/* This should be a message for the host route */12181219verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->addr6, NULL, NULL);1220rtsock_validate_pid_kernel(rtm);1221/* No netmask should be set */1222RTSOCK_ATF_REQUIRE_MSG(rtm, rtsock_find_rtm_sa(rtm, RTA_NETMASK) == NULL, "netmask is set");12231224/* gateway should be link sdl with ifindex of an address interface */1225verify_link_gateway(rtm, c->ifindex);12261227/* XXX: consider passing ifindex in rtm_index as done in RTM_ADD. */1228int expected_rt_flags = RTF_HOST | RTF_DONE | RTF_STATIC | RTF_PINNED;1229RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_flags == expected_rt_flags,1230"expected rtm flags: 0x%X, got 0x%X", expected_rt_flags, rtm->rtm_flags);1231}12321233RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_ifa_prefixroute_success,1234"Tests validness for the prefix route removal after ifaddr assignment");12351236ATF_TC_BODY(rtm_del_v6_gu_ifa_prefixroute_success, tc)1237{1238DECLARE_TEST_VARS;12391240c = presetup_ipv6_iface(tc);12411242ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);12431244c->rtsock_fd = rtsock_setup_socket();12451246ret = iface_delete_addr(c->ifname, c->addr6_str);12471248while (true) {1249rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1250/* Find RTM_DELETE with netmask - this should skip both host route and LLADDR */1251if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))1252break;1253}12541255/* This should be a message for the prefix route */1256verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net6,1257(struct sockaddr *)&c->mask6, NULL);12581259/* gateway should be link sdl with ifindex of an address interface */1260verify_link_gateway(rtm, c->ifindex);12611262int expected_rt_flags = RTF_DONE | RTF_PINNED;1263verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);1264}12651266RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_prefixroute_success,1267"Tests validness for the prefix route announce after ifaddr assignment");12681269ATF_TC_BODY(rtm_add_v4_gu_ifa_prefixroute_success, tc)1270{1271DECLARE_TEST_VARS;12721273c = presetup_ipv4_iface(tc);12741275c->rtsock_fd = rtsock_setup_socket();12761277ret = iface_setup_addr(c->ifname, c->addr6_str, c->plen6);12781279/*1280* Multiple RTM_ADD messages will be generated:1281* 1) lladdr mapping (RTF_LLDATA)1282* 3) prefix route1283*/12841285while (true) {1286rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1287/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */1288if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))1289break;1290}12911292/* This should be a message for the prefix route */1293verify_route_message(rtm, RTM_ADD, (struct sockaddr *)&c->net4,1294(struct sockaddr *)&c->mask4, NULL);12951296/* gateway should be link sdl with ifindex of an address interface */1297verify_link_gateway(rtm, c->ifindex);12981299int expected_rt_flags = RTF_UP | RTF_DONE | RTF_PINNED;1300verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);1301}13021303RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_ifa_ordered_success,1304"Tests ordering of the messages for IPv4 unicast ifaddr assignment");13051306ATF_TC_BODY(rtm_add_v4_gu_ifa_ordered_success, tc)1307{1308DECLARE_TEST_VARS;13091310c = presetup_ipv4_iface(tc);13111312c->rtsock_fd = rtsock_setup_socket();13131314ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);13151316int count = 0, tries = 0;13171318enum msgtype {1319MSG_IFADDR,1320MSG_PREFIXROUTE,1321MSG_MAX,1322};13231324int msg_array[MSG_MAX];13251326bzero(msg_array, sizeof(msg_array));13271328while (count < 2 && tries < 20) {1329rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1330tries++;1331/* Classify */1332if (rtm->rtm_type == RTM_NEWADDR) {1333RLOG("MSG_IFADDR: %d", count);1334msg_array[MSG_IFADDR] = count++;1335continue;1336}13371338/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */1339if ((rtm->rtm_type == RTM_ADD) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK))) {1340RLOG("MSG_PREFIXROUTE: %d", count);1341msg_array[MSG_PREFIXROUTE] = count++;1342continue;1343}13441345RLOG("skipping msg type %s, try: %d", rtsock_print_cmdtype(rtm->rtm_type),1346tries);1347}13481349/* TODO: verify multicast */1350ATF_REQUIRE_MSG(count == 2, "Received only %d/2 messages", count);1351ATF_REQUIRE_MSG(msg_array[MSG_IFADDR] == 0, "ifaddr message is not the first");1352}13531354RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_ifa_prefixroute_success,1355"Tests validness for the prefix route removal after ifaddr assignment");13561357ATF_TC_BODY(rtm_del_v4_gu_ifa_prefixroute_success, tc)1358{1359DECLARE_TEST_VARS;13601361c = presetup_ipv4_iface(tc);136213631364ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);13651366c->rtsock_fd = rtsock_setup_socket();13671368ret = iface_delete_addr(c->ifname, c->addr4_str);13691370while (true) {1371rtm = rtsock_read_rtm(c->rtsock_fd, buffer, sizeof(buffer));1372/* Find RTM_ADD with netmask - this should skip both host route and LLADDR */1373if ((rtm->rtm_type == RTM_DELETE) && (rtsock_find_rtm_sa(rtm, RTA_NETMASK)))1374break;1375}13761377/* This should be a message for the prefix route */1378verify_route_message(rtm, RTM_DELETE, (struct sockaddr *)&c->net4,1379(struct sockaddr *)&c->mask4, NULL);13801381/* gateway should be link sdl with ifindex of an address interface */1382verify_link_gateway(rtm, c->ifindex);13831384int expected_rt_flags = RTF_DONE | RTF_PINNED;1385verify_route_message_extra(rtm, c->ifindex, expected_rt_flags);1386}138713881389ATF_TP_ADD_TCS(tp)1390{1391ATF_TP_ADD_TC(tp, rtm_get_v4_exact_success);1392ATF_TP_ADD_TC(tp, rtm_get_v4_lpm_success);1393ATF_TP_ADD_TC(tp, rtm_get_v4_hostbits_success);1394ATF_TP_ADD_TC(tp, rtm_get_v4_empty_dst_failure);1395ATF_TP_ADD_TC(tp, rtm_add_v4_no_rtf_host_success);1396ATF_TP_ADD_TC(tp, rtm_add_v4_gw_direct_success);1397ATF_TP_ADD_TC(tp, rtm_del_v4_prefix_nogw_success);1398ATF_TP_ADD_TC(tp, rtm_add_v6_gu_gw_gu_direct_success);1399ATF_TP_ADD_TC(tp, rtm_del_v6_gu_prefix_nogw_success);1400ATF_TP_ADD_TC(tp, rtm_change_v4_gw_success);1401ATF_TP_ADD_TC(tp, rtm_change_v4_mtu_success);1402ATF_TP_ADD_TC(tp, rtm_change_v4_flags_success);1403ATF_TP_ADD_TC(tp, rtm_change_v6_gw_success);1404ATF_TP_ADD_TC(tp, rtm_change_v6_mtu_success);1405ATF_TP_ADD_TC(tp, rtm_change_v6_flags_success);1406/* ifaddr tests */1407ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_hostroute_success);1408ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_prefixroute_success);1409ATF_TP_ADD_TC(tp, rtm_add_v6_gu_ifa_ordered_success);1410ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_hostroute_success);1411ATF_TP_ADD_TC(tp, rtm_del_v6_gu_ifa_prefixroute_success);1412ATF_TP_ADD_TC(tp, rtm_add_v4_gu_ifa_ordered_success);1413ATF_TP_ADD_TC(tp, rtm_del_v4_gu_ifa_prefixroute_success);1414/* temporal routes */1415ATF_TP_ADD_TC(tp, rtm_add_v4_temporal1_success);1416ATF_TP_ADD_TC(tp, rtm_add_v6_temporal1_success);14171418return (atf_no_error());1419}1420142114221423