def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces vrf_None = None tl = TestLib(ctl, aliases) # Test that offloaded routes do have "offload" flag. with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d: with gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): sleep(30) ulip = onet2_ip(ctl, 0, [24, 64]) (r4,), _ = sw.get_routes("table 0 %s" % ipv4(ulip)) if "offload" not in r4["flags"]: tl.custom(sw, "ipip", "IPv4 encap route not offloaded") (r6,), _ = sw.get_routes("table 0 %s" % ipv6(ulip)) if "offload" not in r6["flags"]: tl.custom(sw, "ipip", "IPv6 encap route not offloaded") (dcr4,), _ = sw.get_routes("table local 1.2.3.4") if "offload" not in dcr4["flags"]: tl.custom(sw, "ipip", "IPv4 decap route not offloaded") sleep(5) (dcr4,), _ = sw.get_routes("table local 1.2.3.4") if "offload" in dcr4["flags"]: tl.custom(sw, "ipip", "IPv4 decap still flagged offloaded")
def quick_test(ipv4_fail, ipv6_fail): sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g1, count=25, fail_expected=ipv6_fail, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g1, count=25, fail_expected=ipv4_fail)
def quick_test(tun1_ipv4_fail, tun1_ipv6_fail, tun2_ipv4_fail, tun2_ipv6_fail): sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1_10, sg1, count=25, fail_expected=tun1_ipv6_fail, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1_10, sg1, count=25, fail_expected=tun1_ipv4_fail) ping_test(tl, m1, sw, ipv6(onet4_ip(ctl, 33, [])), m1_if1_20, None, count=25, fail_expected=tun2_ipv6_fail, ipv6=True) ping_test(tl, m1, sw, ipv4(onet4_ip(ctl, 33, [])), m1_if1_20, None, count=25, fail_expected=tun2_ipv4_fail)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) logging.info("=== Hierarchical configuration") with vrf(sw) as vrf_u, \ vrf(sw) as vrf_o: connect_host_ifaces(sw, sw_if1, vrf_o, sw_if2, vrf_u) sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf_u, "1.2.3.5") with encap_route(m2, vrf_None, 1, "ipip1", ip=ipv4): # - Set up encap route before decap route. # - Tear down encap route before decap route. logging.info("--- Dup, Eup, Edown, Ddown") with dummy(sw, vrf_u, ip=["1.2.3.4/32"]) as d, \ ipip(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g): sleep(30) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, require_fastpath=False)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) m2_gre3 = m2.get_interface("gre3") vrf_None = None tl = TestLib(ctl, aliases) # Test that non-IPIP traffic gets to slow path. with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4): sleep(30) ping_test(tl, m2, sw, "1.2.3.4", m2_if1, g, count=20) # Configure the wrong interface on M2 to test that the traffic gets trapped # to CPU. with encap_route(m2, vrf_None, 1, "gre3"): add_forward_route(sw, vrf_None, "1.2.3.5") with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: sleep(30) before_stats = sw_if2.link_stats()["rx_packets"] ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_gre3, g, count=20, fail_expected=True) after_stats = sw_if2.link_stats()["rx_packets"] delta = after_stats - before_stats if delta < 15: tl.custom(sw, "ipip", "Too few packets (%d) observed in slow path" % delta)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m1_if1.add_nhs_route(ipv6(onet2_ip(ctl, 0)), [ipv6(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) # Check the behavior when two tunnels with conflicting local addresses are # used. logging.info("=== Conflict in GRE local endpoint") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): add_forward_route(sw, vrf_None, "1.2.3.5") # Now create another tunnel whose local address conflicts with this one. # The original tunnel should keep working, even if it has to be # temporarily brought to slow path. with gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", key=3333) as g2, \ encap_route(sw, vrf_None, 4, g2, ip=ipv4), \ encap_route(sw, vrf_None, 4, g2, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True, require_fastpath=False) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, require_fastpath=False) # After the conflicting tunnel is gone, the traffic should again go # through fast path. sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True, require_fastpath=False) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, require_fastpath=False)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m1_if1.add_nhs_route(ipv6(onet2_ip(ctl, 0)), [ipv6(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) logging.info("=== Flat configuration in non-default VRF") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ vrf(sw) as vrf1, \ dummy(sw, vrf1, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf1, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf1, 2, g, ip=ipv4), \ encap_route(sw, vrf1, 2, g, ip=ipv6): connect_host_ifaces(sw, sw_if1, vrf1, sw_if2, vrf1) sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf1, "1.2.3.5") sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) logging.info("=== Flat configuration in default VRF") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6): sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf_None, "1.2.3.5") # - Set up encap route before decap route. # - Tear down encap route before decap route. logging.info("--- Eup, Dup, Edown, Ddown") with dummy(sw, vrf_None) as d, \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): sleep(5) d.set_addresses(["1.2.3.4/32"]) sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) # - Set up decap route before encap route. # - Tear down decap route before encap route. logging.info("--- Dup, Eup, Ddown, Edown") with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: with encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) d.set_addresses([]) g.set_addresses([]) logging.info("--- Bound device in flat config") with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d, \ gre(sw, d, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) logging.info("--- No dummy") with gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ip=["1.2.3.4/32"]) as g, \ encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts (m1_if1_10, m1_if1_20, m2_if1_10, m2_if1_20, sw_if1_10, sw_if1_20, sw_if2_10, sw_if2_20) = ifaces m1_if1_10.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m1_if1_10.add_nhs_route(ipv6(onet2_ip(ctl, 0)), [ipv6(onet1_ip(ctl, 1, []))]) m1_if1_20.add_nhs_route(ipv4(onet4_ip(ctl, 0)), [ipv4(onet3_ip(ctl, 1, []))]) m1_if1_20.add_nhs_route(ipv6(onet4_ip(ctl, 0)), [ipv6(onet3_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) # - Test migration of several tunnels tied to a single dummy. Have a # setup like below, and test end-to-end ping from 1.33 to 2.33, and # lack of end-to-end ping from 3.33 to 4.33. Then migrate d to svu2 # and test that 2.33 doesn't ping anymore, but 4.33 now does. # # +-- M1 ------------+ +-- SW -----------------------------+ # | | | +-- svo ------------------------+ | # | | | | sg1 1.2.3.4/31 | | # | 1.33/24 +-|----|-|-+ 1.1/24 + | | # | | | | | sg2 1.2.3.6/31 | | # | 3.33/24 +-|----|-|-+ 3.1/24 | + | | # +------------------+ | +-------------------------------+ | # | | | | # +-- M2 ------------+ | +-- svu1 -----------------------+ | # | | | | \ / | | # | 2.33/32 md1 + | | | \ / 1.2.3.4/32 | | # | 1.2.3.5/31 mg1 + | | | + sd 1.2.3.6/32 | | # | 99.2/24 +-|----|-|-+ 99.1/24 | | # | | | | | | # | | | +-------------------------------+ | # | | | | # | 4.33/32 md2 + | | +-- svu2 -----------------------+ | # | 1.2.3.7/31 mg2 + | | | | | # | 88.2/24 +-|----|-|-+ 88.1/24 | | # | | | +-------------------------------+ | # +------------------+ +-----------------------------------+ logging.info("--- Migrate bound device shared by several tunnels") with vrf(sw) as svo, \ vrf(sw) as svu1, \ vrf(sw) as svu2, \ \ encap_route(m2, vrf_None, 1, "mg1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "mg1", ip=ipv6), \ \ encap_route(m2, vrf_None, 3, "mg2", ip=ipv4), \ encap_route(m2, vrf_None, 3, "mg2", ip=ipv6), \ \ dummy(sw, svu1, ip=["1.2.3.4/32", "1.2.3.6/32"]) as sd, \ gre(sw, sd, svo, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as sg1, \ gre(sw, sd, svo, tos="inherit", local_ip="1.2.3.6", remote_ip="1.2.3.7") as sg2, \ encap_route(sw, svo, 2, sg1, ip=ipv4), \ encap_route(sw, svo, 2, sg1, ip=ipv6), \ encap_route(sw, svo, 4, sg2, ip=ipv4), \ encap_route(sw, svo, 4, sg2, ip=ipv6): connect_host_ifaces(sw, sw_if1_10, svo, sw_if2_10, svu1) refresh_addrs(sw, sw_if1_10) refresh_addrs(sw, sw_if2_10) connect_host_ifaces(sw, sw_if1_20, svo, sw_if2_20, svu2) refresh_addrs(sw, sw_if1_20) refresh_addrs(sw, sw_if2_20) add_forward_route(sw, svu1, "1.2.3.5", ipv4(unet1_ip(ctl, 2, []))) add_forward_route(sw, svu2, "1.2.3.7", ipv4(unet2_ip(ctl, 2, []))) add_forward_route(m2, vrf_None, "1.2.3.4", ipv4(unet1_ip(ctl, 1, []))) add_forward_route(m2, vrf_None, "1.2.3.6", ipv4(unet2_ip(ctl, 1, []))) def quick_test(tun1_ipv4_fail, tun1_ipv6_fail, tun2_ipv4_fail, tun2_ipv6_fail): sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1_10, sg1, count=25, fail_expected=tun1_ipv6_fail, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1_10, sg1, count=25, fail_expected=tun1_ipv4_fail) ping_test(tl, m1, sw, ipv6(onet4_ip(ctl, 33, [])), m1_if1_20, None, count=25, fail_expected=tun2_ipv6_fail, ipv6=True) ping_test(tl, m1, sw, ipv4(onet4_ip(ctl, 33, [])), m1_if1_20, None, count=25, fail_expected=tun2_ipv4_fail) sleep(30) quick_test(False, False, True, True) sw.run("ip l s dev %s master %s" % (sd.get_devname(), svu2)) sleep(5) quick_test(True, True, False, False) sw.run("ip l s dev %s master %s" % (sd.get_devname(), svu1)) sleep(5) quick_test(False, False, True, True) sw.run("ip l s dev %s master %s" % (sd.get_devname(), svu2)) sleep(5) quick_test(True, True, False, False) sw.run("ip l s dev %s nomaster" % sd.get_devname()) sleep(5) quick_test(True, True, True, True)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts (m1_if1_10, m1_if1_20, m2_if1_10, m2_if1_20, sw_if1_10, sw_if1_20, sw_if2_10, sw_if2_20) = ifaces m2_if1_10.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) logging.info("=== Decap-only flow tests") logging.info("--- default VRF") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4, src=ipv4(onet2_ip(ctl, 33, []))), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: with dummy(sw, vrf_None, ip=["1.2.3.4/32"]) as d: add_forward_route(sw, vrf_None, "1.2.3.5") sleep(30) ping_test(tl, m2, sw, ipv6(onet1_ip(ctl, 33, [])), m2_if1_10, g, ipv6=True) ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_if1_10, g) # Make sure that downing a tunnel makes the decap flow stop working. logging.info("--- set a tunnel down") g.set_link_down() sleep(5) ping_test(tl, m2, sw, ipv6(onet1_ip(ctl, 33, [])), m2_if1_10, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_if1_10, g, count=25, fail_expected=True) # `g' is now down, and no local decap route exists, because `d' went # away. Test adding an address directly to `g' and make sure that it # isn't offloaded. logging.info("--- add decap route to a down tunnel") g.set_addresses(["1.2.3.4/32"]) sleep(5) ping_test(tl, m2, sw, ipv6(onet1_ip(ctl, 33, [])), m2_if1_10, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_if1_10, g, count=25, fail_expected=True) # Now set the tunnel back up and test that it again all works. g.set_link_up() sleep(5) ping_test(tl, m2, sw, ipv6(onet1_ip(ctl, 33, [])), m2_if1_10, g, ipv6=True) ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_if1_10, g) with vrf(sw) as vrf_u, \ vrf(sw) as vrf_o, \ dummy(sw, vrf_u, ip=["1.2.3.4/32"]) as d, \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv4, src=ipv4(onet2_ip(ctl, 33, []))), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6): connect_host_ifaces(sw, sw_if1_10, vrf_o, sw_if2_10, vrf_u) refresh_addrs(sw, sw_if1_10) add_forward_route(sw, vrf_u, "1.2.3.5") with gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: logging.info("--- hierarchical configuration") sleep(30) ping_test(tl, m2, sw, ipv6(onet1_ip(ctl, 33, [])), m2_if1_10, g, ipv6=True) ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_if1_10, g) # Make sure that downing an underlay device doesn't make the decap # flow stop working. There is a complementary test in ipip-010 to # test that encap stops working. logging.info("--- set an underlay down") d.set_link_down() sleep(5) ping_test(tl, m2, sw, ipv6(onet1_ip(ctl, 33, [])), m2_if1_10, g, ipv6=True) ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_if1_10, g) # Make sure that when a newly-created tunnel has a down underlay, decap # still works. There's a complementary test in ipip-010 to test that # encap doesn't work in that scenario. logging.info("--- create tunnel with a down underlay") d.set_link_down( ) # Should be down already, but make this robust against # later coding changes. with gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: ping_test(tl, m2, sw, ipv6(onet1_ip(ctl, 33, [])), m2_if1_10, g, ipv6=True) ping_test(tl, m2, sw, ipv4(onet1_ip(ctl, 33, [])), m2_if1_10, g)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m1_if1.add_nhs_route(ipv6(onet2_ip(ctl, 0)), [ipv6(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) logging.info("=== Hierarchical configuration, 'ip t change'") with vrf(sw) as vrf_u, \ vrf(sw) as vrf_o, \ vrf(sw) as vrf3, \ dummy(sw, vrf_u, ip=["1.2.3.4/32"]) as d: connect_host_ifaces(sw, sw_if1, vrf_o, sw_if2, vrf_u) sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf_u, "1.2.3.5") logging.info("--- create tunnel with a down underlay") d.set_link_down() with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=100, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=100, fail_expected=True) d.set_link_up() logging.info("--- change of bound device") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ dummy(sw, vrf3, ip=["1.2.3.4/32"]) as d2, \ gre(sw, d2, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True) sw.run("ip t change name %s dev %s" % (g.get_devname(), d.get_devname())) sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) logging.info("--- bound device up/down") # Now change back to `d2', set `d' down and change to it again. # Traffic shouldn't flow. # There's a complementary test in ipip-006 to make sure that # decap-only flow still works even if bound device is down. sw.run("ip t change name %s dev %s" % (g.get_devname(), d2.get_devname())) d.set_link_down() sleep(5) sw.run("ip t change name %s dev %s" % (g.get_devname(), d.get_devname())) sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True) # Set `d' up while it's the bound device. Traffic should flow again. d.set_link_up() sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) # Set `d' down while it's the bound device. d.set_link_down() sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True) # Set `d' back up again to make sure it's stable. d.set_link_up() sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) logging.info("--- remote change") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.7") as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True) sw.run("ip t change name %s remote 1.2.3.5" % g.get_devname()) sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) logging.info("--- local change") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.6", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True) sw.run("ip t change name %s local 1.2.3.4" % g.get_devname()) sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) # IPv4 should go through g4, IPv6 through g6, but g4 starts out # misconfigured. Thus there's no conflict and both g4 and g6 are # offloaded. When the configuration of g4 is fixed, both tunnels are # forced to slow path, but now they both work. # There's a similar test in ipip-007 for VRF migration. logging.info("--- local change conflict") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ dummy(sw, vrf_u, ip=["1.2.3.6/32"]) as d4, \ gre(sw, d4, vrf_o, tos="inherit", local_ip="1.2.3.6", remote_ip="1.2.3.5") as g4, \ encap_route(sw, vrf_o, 2, g4, ip=ipv4), \ \ encap_route(m2, vrf_None, 1, "gre2", ip=ipv6), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ikey=2222, okey=1111) as g6, \ encap_route(sw, vrf_o, 2, g6, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g6, count=25, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g4, count=25, fail_expected=True) sw.run("ip t change name %s local 1.2.3.4" % g4.get_devname()) sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g6, ipv6=True, require_fastpath=False, require_slowpath=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g4, require_fastpath=False, require_slowpath=True) logging.info("--- ikey change") with encap_route(m2, vrf_None, 1, "gre2", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre2", ip=ipv6), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ikey=2, okey=1111) as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True) sw.run("ip t change name %s ikey 2222" % g.get_devname()) sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) logging.info("--- okey change") with encap_route(m2, vrf_None, 1, "gre2", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre2", ip=ipv6), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ikey=2222, okey=1) as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, fail_expected=True) sw.run("ip t change name %s okey 1111" % g.get_devname()) sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m1_if1.add_nhs_route(ipv6(onet2_ip(ctl, 0)), [ipv6(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) logging.info("=== UL migration") # - Test underlay migration: create a dummy in one VRF, then offload a # tunnel and move the dummy to another VRF. logging.info("--- Simple") with vrf(sw) as vrf_u, \ vrf(sw) as vrf_o: connect_host_ifaces(sw, sw_if1, vrf_o, sw_if2, vrf_u) sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf_u, "1.2.3.5") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6), \ dummy(sw, vrf_o, ip=["1.2.3.4/32"]) as d, \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sw.run("ip l set dev %s master %s" % (d.get_devname(), vrf_u)) tl.wait_for_if(ifaces) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) logging.info("=== OL migration") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6): sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf_None, "1.2.3.5") # N.B. overlay migration to non-default is tested implicitly by many, # many tests as the device is first created in default VRF, and only # then moved to the right VRF. So just test migration back outside. logging.info("--- To default") with vrf(sw) as vrf1, \ gre(sw, None, vrf1, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ip=["1.2.3.4/32"]) as g: sleep(5) sw.run("ip link set dev %s nomaster" % g.get_devname()) with encap_route(sw, vrf_None, 2, g, ip=ipv4), \ encap_route(sw, vrf_None, 2, g, ip=ipv6): tl.wait_for_if(ifaces) sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) # IPv4 should go through g4, IPv6 through g6, but g4 starts out in the # wrong VRF. Thus there's no conflict and both g4 and g6 are offloaded. # When the configuration of g4 is fixed, both tunnels are forced to slow # path, but now they both work. # There's a similar test in ipip-010 for local address change. logging.info("--- That causes local conflict") with vrf(sw) as vrf1, \ \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ gre(sw, None, vrf1, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ip=["1.2.3.4/32"]) as g4, \ \ encap_route(m2, vrf_None, 1, "gre2", ip=ipv6), \ gre(sw, None, vrf_None, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ikey=2222, okey=1111, ip=["1.2.3.4/32"]) as g6, \ encap_route(sw, vrf_None, 2, g6, ip=ipv6): route = encap_route(sw, vrf_None, 2, g4, ip=ipv4) route.do("add") sleep(60) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g6, count=25, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g4, count=25, fail_expected=True) sw.run("ip link set dev %s nomaster" % g4.get_devname()) # The VRF motion drops the encap route, so re-add it. route.do("add") sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g6, ipv6=True, require_fastpath=False, require_slowpath=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g4, require_fastpath=False, require_slowpath=True) route.do("del")
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, m2_mg, m2_v3, sw_if1, sw_if2 = ifaces m2.config("/proc/sys/net/ipv4/ip_forward", "1", netns="ns1") m2.config("/proc/sys/net/ipv4/ip_forward", "1", netns="ns2") m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m1_if1.add_nhs_route(ipv6(onet2_ip(ctl, 0)), [ipv6(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.5/32", [ipv4(unet2_ip(ctl, 2, []))]) m2_v3.add_nhs_route("1.2.3.4/32", [ipv4(unet2_ip(ctl, 1, []))]) m2_v3.add_nhs_route("1.2.3.5/32", [ipv4(unet3_ip(ctl, 2, []))]) m2_mg.add_nhs_route("1.2.3.4/32", [ipv4(unet3_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) logging.info("=== TTL tests") with vrf(sw) as vrf_u, \ vrf(sw) as vrf_o, \ dummy(sw, vrf_u, ip=["1.2.3.4/32"]) as d, \ encap_route(m2, vrf_None, 1, "mg", ip=ipv4), \ encap_route(m2, vrf_None, 1, "mg", ip=ipv6): connect_host_ifaces(sw, sw_if1, vrf_o, sw_if2, vrf_u) sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf_u, "1.2.3.5", via=ipv4(unet1_ip(ctl, 2, []))) # - Test that tunnel configured with TTL inherit actually copies the TTL # from the overlay packet. The topology is as follows: # # +-- M1 ----------------+ +-- M2 ----------------+ # | 1.33/24 +--|----. | | # | | | | 2.33/32 md + | # +----------------------+ | | 1.2.3.5/31 mg + | # +-- SW -------------------------+ | + 77.2 | # | | | | | | # | +-- ol vrf -----------------+ | | +-- ns2 -----------+ | # | | 1.2.3.4/31 g + | | | | | | 88.2 + | | # | | | 1.1/24 + | | | | + 77.1 | | | # | +---------------------------+ | | +------------------+ | # | | | | | | # | +-- ul vrf -----------------+ | | +-- ns1 -----------+ | # | | | +--|-|----|-|--+ | | | # | | 1.2.3.4/32 d + 99.1/24 | | | | 99.2/24 88.1 + | | # | +---------------------------+ | | +------------------+ | # +-------------------------------+ +----------------------+ # # The point of the test is that there are several next hops between # 1.2.3.4 and 1.2.3.5. If the tunnel is set to "ttl inherit", ping # with TTL of 3 (ping -t 3) never reaches the other endpoint, but ping # with TTL of 4 does. with dummy(sw, vrf_u) as d, \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): logging.info("--- TTL inherit") sleep(30) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, count=25, ttl=3, fail_expected=True) sleep(5) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, ttl=4) # - On the same topology, after offloading a tunnel with "ttl # inherit", set the tunnel to e.g. "ttl 64". Now the other # endpoint should become reachable again even with ping -t 3. Thus # we know that the tunnel was moved to slow path correcly (or the # TTL was reflected in the hardware, we don't care). logging.info("--- ip t change ttl") sw.run("ip t change name %s ttl 64" % g.get_devname()) sleep(5) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, ttl=3, require_fastpath=False)
def do_task(ctl, hosts, ifaces, aliases): m1, m2, sw = hosts m1_if1, m2_if1, sw_if1, sw_if2 = ifaces m1_if1.add_nhs_route(ipv4(onet2_ip(ctl, 0)), [ipv4(onet1_ip(ctl, 1, []))]) m1_if1.add_nhs_route(ipv6(onet2_ip(ctl, 0)), [ipv6(onet1_ip(ctl, 1, []))]) m2_if1.add_nhs_route("1.2.3.4/32", [ipv4(unet_ip(ctl, 1, []))]) vrf_None = None tl = TestLib(ctl, aliases) logging.info("=== Hierarchical configuration") with vrf(sw) as vrf_u, \ vrf(sw) as vrf_o: connect_host_ifaces(sw, sw_if1, vrf_o, sw_if2, vrf_u) sw_if1.reset() sw_if2.reset() add_forward_route(sw, vrf_u, "1.2.3.5") with encap_route(m2, vrf_None, 1, "gre1", ip=ipv4), \ encap_route(m2, vrf_None, 1, "gre1", ip=ipv6): # - Set up encap route before decap route. # - Tear down encap route before decap route. logging.info("--- Eup, Dup, Edown, Ddown") with dummy(sw, vrf_u) as d, \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(5) d.set_addresses(["1.2.3.4/32"]) sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) # - Set up decap route before encap route. # - Tear down decap route before encap route. logging.info("--- Dup, Eup, Ddown, Edown") with dummy(sw, vrf_u, ip=["1.2.3.4/32"]) as d, \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g: with encap_route(sw, vrf_o, 2, g, ip=ipv4), \ encap_route(sw, vrf_o, 2, g, ip=ipv6): sleep(30) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) d.set_addresses([]) g.set_addresses([]) # - Set up two tunnels and test route replacement. logging.info("--- Route replacement") with dummy(sw, vrf_u, ip=["1.2.3.6/32"]) as d1, \ gre(sw, d1, vrf_o, tos="inherit", local_ip="1.2.3.6", remote_ip="1.2.3.7") as g1, \ dummy(sw, vrf_u, ip=["1.2.3.4/32"]) as d2, \ gre(sw, d2, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g2: def quick_test(ipv4_fail, ipv6_fail): sleep(5) ping_test(tl, m1, sw, ipv6(onet2_ip(ctl, 33, [])), m1_if1, g1, count=25, fail_expected=ipv6_fail, ipv6=True) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g1, count=25, fail_expected=ipv4_fail) # Replacing IPv4 route should cause the IPv4 traffic to drop and # not affect the IPv6 one. encap_route(sw, vrf_o, 2, g2, ip=ipv6).do("add") encap_route(sw, vrf_o, 2, g1, ip=ipv4).do("add") quick_test(True, False) encap_route(sw, vrf_o, 2, g2, ip=ipv4).do("replace") quick_test(False, False) encap_route(sw, vrf_o, 2, g1, ip=ipv4).do("replace") quick_test(True, False) encap_route(sw, vrf_o, 2, g2, ip=ipv4).do("replace") quick_test(False, False) # And vice versa. encap_route(sw, vrf_o, 2, g1, ip=ipv6).do("replace") quick_test(False, True) encap_route(sw, vrf_o, 2, g2, ip=ipv6).do("replace") quick_test(False, False) encap_route(sw, vrf_o, 2, g1, ip=ipv6).do("replace") quick_test(False, True) encap_route(sw, vrf_o, 2, g2, ip=ipv6).do("replace") quick_test(False, False) # Done. encap_route(sw, vrf_o, 2, g2, ip=ipv4).do("del") encap_route(sw, vrf_o, 2, g2, ip=ipv6).do("del") with dummy(sw, vrf_u, ip=["1.2.3.4/32"]) as d: # - Test with ikey/okey. logging.info("--- ikey/okey") with encap_route(m2, vrf_None, 1, "gre2"), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", ikey=2222, okey=1111) as g, \ encap_route(sw, vrf_o, 2, g): sleep(30) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g) # - Slow path: non-inherit TOS. logging.info("--- non-inherit TOS (slow path)") with encap_route(m2, vrf_None, 1, "gre1"), \ gre(sw, d, vrf_o, tos="0x10", local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf_o, 2, g): sleep(30) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, require_fastpath=False) # - Slow path: csum-enabled tunnel. logging.info("--- checksum (slow path)") with encap_route(m2, vrf_None, 1, "gre3"), \ gre(sw, d, vrf_o, tos="inherit", local_ip="1.2.3.4", remote_ip="1.2.3.5", key=3333, csum=True) as g, \ encap_route(sw, vrf_o, 2, g): sleep(30) ping_test(tl, m1, sw, ipv4(onet2_ip(ctl, 33, [])), m1_if1, g, require_fastpath=False) # - Enable two dummy devices in different VRFs with the decap address. # The driver crashes on tunnel tear-down if it incorrectly assigned # both decaps to the same tunnel. logging.info("--- the same tunnel local address in two VRFs") with vrf(sw) as vrf3, \ dummy(sw, vrf_u) as d, \ gre(sw, d, vrf_o, local_ip="1.2.3.4", remote_ip="1.2.3.5") as g, \ encap_route(sw, vrf3, 2, g), \ dummy(sw, vrf3) as d3: sleep(5) d.set_addresses(["1.2.3.4/32"]) d3.set_addresses(["1.2.3.4/32"]) sleep(5)