Path: blob/main/tests/sys/net/routing/test_rtsock_lladdr.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"2930static void31jump_vnet(struct rtsock_test_config *c, const atf_tc_t *tc)32{33char vnet_name[512];3435snprintf(vnet_name, sizeof(vnet_name), "vt-%s", atf_tc_get_ident(tc));36RLOG("jumping to %s", vnet_name);3738vnet_switch_one(vnet_name, c->ifname);3940/* Update ifindex cache */41c->ifindex = if_nametoindex(c->ifname);42}4344static inline struct rtsock_test_config *45presetup_ipv6(const atf_tc_t *tc)46{47struct rtsock_test_config *c;48int ret;4950c = config_setup(tc, NULL);5152jump_vnet(c, tc);5354ret = iface_turn_up(c->ifname);55ATF_REQUIRE_MSG(ret == 0, "Unable to turn up %s", c->ifname);56ret = iface_enable_ipv6(c->ifname);57ATF_REQUIRE_MSG(ret == 0, "Unable to enable IPv6 on %s", c->ifname);5859c->rtsock_fd = rtsock_setup_socket();6061return (c);62}6364static inline struct rtsock_test_config *65presetup_ipv4(const atf_tc_t *tc)66{67struct rtsock_test_config *c;68int ret;6970c = config_setup(tc, NULL);7172jump_vnet(c, tc);7374/* assumes ifconfig doing IFF_UP */75ret = iface_setup_addr(c->ifname, c->addr4_str, c->plen4);76ATF_REQUIRE_MSG(ret == 0, "ifconfig failed");7778c->rtsock_fd = rtsock_setup_socket();7980return (c);81}8283static void84prepare_route_message(struct rt_msghdr *rtm, int cmd, struct sockaddr *dst,85struct sockaddr *gw)86{8788rtsock_prepare_route_message(rtm, cmd, dst, NULL, gw);8990rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);91}9293/* TESTS */94#define DECLARE_TEST_VARS \95char buffer[2048], msg[512]; \96ssize_t len; \97int ret; \98struct rtsock_test_config *c; \99struct rt_msghdr *rtm = (struct rt_msghdr *)buffer; \100struct sockaddr *sa; \101\102103#define DECLARE_CLEANUP_VARS \104struct rtsock_test_config *c = config_setup(tc); \105\106107#define DESCRIBE_ROOT_TEST(_msg) config_describe_root_test(tc, _msg)108#define CLEANUP_AFTER_TEST config_generic_cleanup(tc)109110#define RTM_DECLARE_ROOT_TEST(_name, _descr) \111ATF_TC_WITH_CLEANUP(_name); \112ATF_TC_HEAD(_name, tc) \113{ \114DESCRIBE_ROOT_TEST(_descr); \115} \116ATF_TC_CLEANUP(_name, tc) \117{ \118CLEANUP_AFTER_TEST; \119}120121RTM_DECLARE_ROOT_TEST(rtm_add_v6_ll_lle_success, "Tests addition of link-local IPv6 ND entry");122ATF_TC_BODY(rtm_add_v6_ll_lle_success, tc)123{124DECLARE_TEST_VARS;125126c = presetup_ipv6(tc);127128char str_buf[128];129struct sockaddr_in6 sin6;130/* Interface here is optional. XXX: verify kernel side. */131char *v6addr = "fe80::4242:4242";132snprintf(str_buf, sizeof(str_buf), "%s%%%s", v6addr, c->ifname);133sa_convert_str_to_sa(str_buf, (struct sockaddr *)&sin6);134135struct sockaddr_dl ether;136snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);137sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);138139prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);140rtsock_send_rtm(c->rtsock_fd, rtm);141142/*143* Got message of size 240 on 2019-12-17 15:06:51144* RTM_ADD: Add Route: len 240, pid: 0, seq 0, errno 0, flags: <UP,HOST,DONE,LLINFO>145* sockaddrs: 0x3 <DST,GATEWAY>146* af=inet6 len=28 addr=fe80::4242:4242 scope_id=3 if_name=tap4242147* af=link len=54 sdl_index=3 if_name=tap4242 addr=52:54:00:14:E3:10148*/149150rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);151152sa = rtsock_find_rtm_sa(rtm, RTA_DST);153ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));154RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);155156sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);157int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;158ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);159RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);160161#if 0162/* Disable the check until https://reviews.freebsd.org/D22003 merge */163/* Some additional checks to verify kernel has filled in interface data */164struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;165RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_type > 0, "sdl_type not set");166#endif167}168169RTM_DECLARE_ROOT_TEST(rtm_add_v6_gu_lle_success, "Tests addition of global IPv6 ND entry");170ATF_TC_BODY(rtm_add_v6_gu_lle_success, tc)171{172DECLARE_TEST_VARS;173174c = presetup_ipv6(tc);175176char str_buf[128];177178struct sockaddr_in6 sin6;179sin6 = c->net6;180#define _s6_addr32 __u6_addr.__u6_addr32181sin6.sin6_addr._s6_addr32[3] = htonl(0x42424242);182#undef _s6_addr32183184struct sockaddr_dl ether;185snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);186sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);187188prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);189190rtsock_send_rtm(c->rtsock_fd, rtm);191192/*193* Got message of size 240 on 2019-12-17 14:56:43194* RTM_ADD: Add Route: len 240, pid: 0, seq 0, errno 0, flags: <UP,HOST,DONE,LLINFO>195* sockaddrs: 0x3 <DST,GATEWAY>196* af=inet6 len=28 addr=2001:db8::4242:4242197* af=link len=54 sdl_index=3 if_name=tap4242 addr=52:54:00:14:E3:10198*/199200/* XXX: where is uRPF?! this should fail */201202rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);203204sa = rtsock_find_rtm_sa(rtm, RTA_DST);205ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));206RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);207208sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);209int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;210ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);211RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);212213#if 0214/* Disable the check until https://reviews.freebsd.org/D22003 merge */215/* Some additional checks to verify kernel has filled in interface data */216struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;217RTSOCK_ATF_REQUIRE_MSG(rtm, sdl->sdl_type > 0, "sdl_type not set");218#endif219}220221RTM_DECLARE_ROOT_TEST(rtm_add_v4_gu_lle_success, "Tests addition of IPv4 ARP entry");222ATF_TC_BODY(rtm_add_v4_gu_lle_success, tc)223{224DECLARE_TEST_VARS;225226c = presetup_ipv4(tc);227228char str_buf[128];229230struct sockaddr_in sin;231sin = c->addr4;232/* Use the next IPv4 address after self */233sin.sin_addr.s_addr = htonl(ntohl(sin.sin_addr.s_addr) + 1);234235struct sockaddr_dl ether;236snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);237sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);238239prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin, (struct sockaddr *)ðer);240241len = rtsock_send_rtm(c->rtsock_fd, rtm);242243/*244* RTM_ADD: Add Route: len 224, pid: 43131, seq 42, errno 0, flags: <HOST,DONE,LLINFO,STATIC>245* sockaddrs: 0x3 <DST,GATEWAY>246* af=inet len=16 addr=192.0.2.2247* af=link len=54 sdl_index=3 if_name=tap4242 addr=52:54:00:14:E3:10248*/249250rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);251252sa = rtsock_find_rtm_sa(rtm, RTA_DST);253ret = sa_equal_msg(sa, (struct sockaddr *)&sin, msg, sizeof(msg));254RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);255256sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);257int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;258ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);259RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);260261/*262* TODO: Currently kernel code does not set sdl_type, contrary to IPv6.263*/264}265266RTM_DECLARE_ROOT_TEST(rtm_del_v6_ll_lle_success, "Tests removal of link-local IPv6 ND entry");267ATF_TC_BODY(rtm_del_v6_ll_lle_success, tc)268{269DECLARE_TEST_VARS;270271c = presetup_ipv6(tc);272273char str_buf[128];274275struct sockaddr_in6 sin6;276/* Interface here is optional. XXX: verify kernel side. */277char *v6addr = "fe80::4242:4242";278snprintf(str_buf, sizeof(str_buf), "%s%%%s", v6addr, c->ifname);279sa_convert_str_to_sa(str_buf, (struct sockaddr *)&sin6);280281struct sockaddr_dl ether;282snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);283sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);284285prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);286287rtsock_send_rtm(c->rtsock_fd, rtm);288289/* Successfully added an entry, let's try to remove it. */290prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);291292rtsock_send_rtm(c->rtsock_fd, rtm);293294rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);295296RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == RTM_DELETE, "rtm_type is not delete");297298sa = rtsock_find_rtm_sa(rtm, RTA_DST);299ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));300RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);301302sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);303int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;304ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);305RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);306307/*308* TODO: Currently kernel code does not set sdl_type on delete.309*/310}311312RTM_DECLARE_ROOT_TEST(rtm_del_v6_gu_lle_success, "Tests removal of global IPv6 ND entry");313ATF_TC_BODY(rtm_del_v6_gu_lle_success, tc)314{315DECLARE_TEST_VARS;316317c = presetup_ipv6(tc);318319char str_buf[128];320321struct sockaddr_in6 sin6;322sin6 = c->net6;323#define _s6_addr32 __u6_addr.__u6_addr32324sin6.sin6_addr._s6_addr32[3] = htonl(0x42424242);325#undef _s6_addr32326327struct sockaddr_dl ether;328snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);329sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);330331prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);332333len = rtsock_send_rtm(c->rtsock_fd, rtm);334335/* Successfully added an entry, let's try to remove it. */336prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&sin6, (struct sockaddr *)ðer);337338rtsock_send_rtm(c->rtsock_fd, rtm);339340rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);341342RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == RTM_DELETE, "rtm_type is not delete");343344sa = rtsock_find_rtm_sa(rtm, RTA_DST);345ret = sa_equal_msg(sa, (struct sockaddr *)&sin6, msg, sizeof(msg));346RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);347348sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);349int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;350ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);351RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);352353/*354* TODO: Currently kernel code does not set sdl_type on delete.355*/356}357358RTM_DECLARE_ROOT_TEST(rtm_del_v4_gu_lle_success, "Tests removal of IPv4 ARP entry");359ATF_TC_BODY(rtm_del_v4_gu_lle_success, tc)360{361DECLARE_TEST_VARS;362363c = presetup_ipv4(tc);364365char str_buf[128];366367struct sockaddr_in sin;368sin = c->addr4;369/* Use the next IPv4 address after self */370sin.sin_addr.s_addr = htonl(ntohl(sin.sin_addr.s_addr) + 1);371372struct sockaddr_dl ether;373snprintf(str_buf, sizeof(str_buf), "%s%%%s", c->remote_lladdr, c->ifname);374sa_convert_str_to_sa(str_buf, (struct sockaddr *)ðer);375376prepare_route_message(rtm, RTM_ADD, (struct sockaddr *)&sin, (struct sockaddr *)ðer);377378rtsock_send_rtm(c->rtsock_fd, rtm);379380/* We successfully added an entry, let's try to remove it. */381prepare_route_message(rtm, RTM_DELETE, (struct sockaddr *)&sin, (struct sockaddr *)ðer);382383rtsock_send_rtm(c->rtsock_fd, rtm);384385rtm = rtsock_read_rtm_reply(c->rtsock_fd, buffer, sizeof(buffer), rtm->rtm_seq);386387RTSOCK_ATF_REQUIRE_MSG(rtm, rtm->rtm_type == RTM_DELETE, "rtm_type is not delete");388389sa = rtsock_find_rtm_sa(rtm, RTA_DST);390ret = sa_equal_msg(sa, (struct sockaddr *)&sin, msg, sizeof(msg));391RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "DST sa diff: %s", msg);392393sa = rtsock_find_rtm_sa(rtm, RTA_GATEWAY);394int sa_flags = SA_F_IGNORE_IFNAME | SA_F_IGNORE_IFTYPE | SA_F_IGNORE_MEMCMP;395ret = sa_equal_msg_flags(sa, (struct sockaddr *)ðer, msg, sizeof(msg), sa_flags);396RTSOCK_ATF_REQUIRE_MSG(rtm, ret != 0, "GATEWAY sa diff: %s", msg);397398/*399* TODO: Currently kernel code does not set sdl_type, contrary to IPv6.400*/401}402403ATF_TP_ADD_TCS(tp)404{405ATF_TP_ADD_TC(tp, rtm_add_v6_ll_lle_success);406ATF_TP_ADD_TC(tp, rtm_add_v6_gu_lle_success);407ATF_TP_ADD_TC(tp, rtm_add_v4_gu_lle_success);408ATF_TP_ADD_TC(tp, rtm_del_v6_ll_lle_success);409ATF_TP_ADD_TC(tp, rtm_del_v6_gu_lle_success);410ATF_TP_ADD_TC(tp, rtm_del_v4_gu_lle_success);411412return (atf_no_error());413}414415416417418