17064c94aSAlexander V. Chernikovimport ipaddress 2*badcb3fdSAlexander V. Chernikovimport socket 37064c94aSAlexander V. Chernikov 47064c94aSAlexander V. Chernikovimport pytest 5*badcb3fdSAlexander V. Chernikovfrom atf_python.sys.net.rtsock import RtConst 6*badcb3fdSAlexander V. Chernikovfrom atf_python.sys.net.rtsock import Rtsock 7*badcb3fdSAlexander V. Chernikovfrom atf_python.sys.net.rtsock import RtsockRtMessage 8*badcb3fdSAlexander V. Chernikovfrom atf_python.sys.net.rtsock import SaHelper 97064c94aSAlexander V. Chernikovfrom atf_python.sys.net.tools import ToolsHelper 10*badcb3fdSAlexander V. Chernikovfrom atf_python.sys.net.vnet import SingleVnetTestTemplate 117064c94aSAlexander V. Chernikovfrom atf_python.sys.net.vnet import VnetTestTemplate 127064c94aSAlexander V. Chernikov 137064c94aSAlexander V. Chernikov 147064c94aSAlexander V. Chernikovclass TestIfOps(VnetTestTemplate): 157064c94aSAlexander V. Chernikov TOPOLOGY = { 167064c94aSAlexander V. Chernikov "vnet1": {"ifaces": ["if1", "if2"]}, 177064c94aSAlexander V. Chernikov "if1": {"prefixes4": [], "prefixes6": []}, 187064c94aSAlexander V. Chernikov "if2": {"prefixes4": [], "prefixes6": []}, 197064c94aSAlexander V. Chernikov } 207064c94aSAlexander V. Chernikov 217064c94aSAlexander V. Chernikov @pytest.mark.parametrize("family", ["inet", "inet6"]) 227064c94aSAlexander V. Chernikov @pytest.mark.require_user("root") 237064c94aSAlexander V. Chernikov def test_change_prefix_route(self, family): 247064c94aSAlexander V. Chernikov """Tests that prefix route changes to the new one upon addr deletion""" 257064c94aSAlexander V. Chernikov vnet = self.vnet_map["vnet1"] 267064c94aSAlexander V. Chernikov first_iface = vnet.iface_alias_map["if1"] 277064c94aSAlexander V. Chernikov second_iface = vnet.iface_alias_map["if2"] 287064c94aSAlexander V. Chernikov if family == "inet": 297064c94aSAlexander V. Chernikov first_addr = ipaddress.ip_interface("192.0.2.1/24") 307064c94aSAlexander V. Chernikov second_addr = ipaddress.ip_interface("192.0.2.2/24") 317064c94aSAlexander V. Chernikov else: 327064c94aSAlexander V. Chernikov first_addr = ipaddress.ip_interface("2001:db8::1/64") 337064c94aSAlexander V. Chernikov second_addr = ipaddress.ip_interface("2001:db8::2/64") 347064c94aSAlexander V. Chernikov 357064c94aSAlexander V. Chernikov first_iface.setup_addr(str(first_addr)) 367064c94aSAlexander V. Chernikov second_iface.setup_addr(str(second_addr)) 377064c94aSAlexander V. Chernikov 387064c94aSAlexander V. Chernikov # At this time prefix should be pointing to the first interface 397064c94aSAlexander V. Chernikov routes = ToolsHelper.get_routes(family) 407064c94aSAlexander V. Chernikov px = [r for r in routes if r["destination"] == str(first_addr.network)][0] 417064c94aSAlexander V. Chernikov assert px["interface-name"] == first_iface.name 427064c94aSAlexander V. Chernikov 437064c94aSAlexander V. Chernikov # Now delete address from the first interface and verify switchover 447064c94aSAlexander V. Chernikov first_iface.delete_addr(first_addr.ip) 457064c94aSAlexander V. Chernikov 467064c94aSAlexander V. Chernikov routes = ToolsHelper.get_routes(family) 477064c94aSAlexander V. Chernikov px = [r for r in routes if r["destination"] == str(first_addr.network)][0] 487064c94aSAlexander V. Chernikov assert px["interface-name"] == second_iface.name 497064c94aSAlexander V. Chernikov 507064c94aSAlexander V. Chernikov @pytest.mark.parametrize( 517064c94aSAlexander V. Chernikov "family", 527064c94aSAlexander V. Chernikov [ 537064c94aSAlexander V. Chernikov "inet", 547064c94aSAlexander V. Chernikov pytest.param("inet6", marks=pytest.mark.xfail(reason="currently fails")), 557064c94aSAlexander V. Chernikov ], 567064c94aSAlexander V. Chernikov ) 577064c94aSAlexander V. Chernikov @pytest.mark.require_user("root") 587064c94aSAlexander V. Chernikov def test_change_prefix_route_same_iface(self, family): 597064c94aSAlexander V. Chernikov """Tests that prefix route changes to the new ifa upon addr deletion""" 607064c94aSAlexander V. Chernikov vnet = self.vnet_map["vnet1"] 617064c94aSAlexander V. Chernikov first_iface = vnet.iface_alias_map["if1"] 627064c94aSAlexander V. Chernikov 637064c94aSAlexander V. Chernikov if family == "inet": 647064c94aSAlexander V. Chernikov first_addr = ipaddress.ip_interface("192.0.2.1/24") 657064c94aSAlexander V. Chernikov second_addr = ipaddress.ip_interface("192.0.2.2/24") 667064c94aSAlexander V. Chernikov else: 677064c94aSAlexander V. Chernikov first_addr = ipaddress.ip_interface("2001:db8::1/64") 687064c94aSAlexander V. Chernikov second_addr = ipaddress.ip_interface("2001:db8::2/64") 697064c94aSAlexander V. Chernikov 707064c94aSAlexander V. Chernikov first_iface.setup_addr(str(first_addr)) 717064c94aSAlexander V. Chernikov first_iface.setup_addr(str(second_addr)) 727064c94aSAlexander V. Chernikov 737064c94aSAlexander V. Chernikov # At this time prefix should be pointing to the first interface 747064c94aSAlexander V. Chernikov routes = ToolsHelper.get_routes(family) 757064c94aSAlexander V. Chernikov px = [r for r in routes if r["destination"] == str(first_addr.network)][0] 767064c94aSAlexander V. Chernikov assert px["interface-name"] == first_iface.name 777064c94aSAlexander V. Chernikov 787064c94aSAlexander V. Chernikov # Now delete address from the first interface and verify switchover 797064c94aSAlexander V. Chernikov first_iface.delete_addr(str(first_addr.ip)) 807064c94aSAlexander V. Chernikov 817064c94aSAlexander V. Chernikov routes = ToolsHelper.get_routes(family) 827064c94aSAlexander V. Chernikov px = [r for r in routes if r["destination"] == str(first_addr.network)][0] 837064c94aSAlexander V. Chernikov nhop_kidx = px["nhop"] 847064c94aSAlexander V. Chernikov assert px["interface-name"] == first_iface.name 857064c94aSAlexander V. Chernikov nhops = ToolsHelper.get_nhops(family) 867064c94aSAlexander V. Chernikov nh = [nh for nh in nhops if nh["index"] == nhop_kidx][0] 877064c94aSAlexander V. Chernikov assert nh["ifa"] == str(second_addr.ip) 88*badcb3fdSAlexander V. Chernikov 89*badcb3fdSAlexander V. Chernikov 90*badcb3fdSAlexander V. Chernikovclass TestRouteCornerCase1(SingleVnetTestTemplate): 91*badcb3fdSAlexander V. Chernikov @pytest.mark.parametrize("family", ["inet", "inet6"]) 92*badcb3fdSAlexander V. Chernikov @pytest.mark.require_user("root") 93*badcb3fdSAlexander V. Chernikov def test_add_direct_route_p2p_wo_ifa(self, family): 94*badcb3fdSAlexander V. Chernikov 95*badcb3fdSAlexander V. Chernikov tun_ifname = ToolsHelper.get_output("/sbin/ifconfig tun create").rstrip() 96*badcb3fdSAlexander V. Chernikov tun_ifindex = socket.if_nametoindex(tun_ifname) 97*badcb3fdSAlexander V. Chernikov assert tun_ifindex > 0 98*badcb3fdSAlexander V. Chernikov rtsock = Rtsock() 99*badcb3fdSAlexander V. Chernikov 100*badcb3fdSAlexander V. Chernikov if family == "inet": 101*badcb3fdSAlexander V. Chernikov prefix = "172.16.0.0/12" 102*badcb3fdSAlexander V. Chernikov else: 103*badcb3fdSAlexander V. Chernikov prefix = "2a02:6b8::/64" 104*badcb3fdSAlexander V. Chernikov IFT_ETHER = 0x06 105*badcb3fdSAlexander V. Chernikov gw_link = SaHelper.link_sa(ifindex=tun_ifindex, iftype=IFT_ETHER) 106*badcb3fdSAlexander V. Chernikov 107*badcb3fdSAlexander V. Chernikov msg = rtsock.new_rtm_add(prefix, gw_link) 108*badcb3fdSAlexander V. Chernikov msg.add_link_attr(RtConst.RTA_IFP, tun_ifindex) 109*badcb3fdSAlexander V. Chernikov rtsock.write_message(msg) 110*badcb3fdSAlexander V. Chernikov 111*badcb3fdSAlexander V. Chernikov data = rtsock.read_data(msg.rtm_seq) 112*badcb3fdSAlexander V. Chernikov msg_in = RtsockRtMessage.from_bytes(data) 113*badcb3fdSAlexander V. Chernikov msg_in.print_in_message() 114*badcb3fdSAlexander V. Chernikov 115*badcb3fdSAlexander V. Chernikov desired_sa = { 116*badcb3fdSAlexander V. Chernikov RtConst.RTA_DST: msg.get_sa(RtConst.RTA_DST), 117*badcb3fdSAlexander V. Chernikov RtConst.RTA_NETMASK: msg.get_sa(RtConst.RTA_NETMASK), 118*badcb3fdSAlexander V. Chernikov } 119*badcb3fdSAlexander V. Chernikov 120*badcb3fdSAlexander V. Chernikov msg_in.verify(msg.rtm_type, desired_sa) 121