def test_prop_parent_pos_child_pos(): # Add a parent aggregate rioute and a child more specific route, each with only positive # next-hops. fib = Fib() rib = Rib(fib) # Install two routes into the RIB: rib.put_route("1.2.0.0/16", ["nh1", "nh2"]) # Parent aggregate route, positive nexthops rib.put_route("1.2.3.0/24", ["nh3", "nh4"]) # Child more specific route, positive nexthops # The RIB must contain the following routes: assert str(rib) == ("1.2.0.0/16 -> nh1, nh2\n" "1.2.3.0/24 -> nh3, nh4\n") # The FIB must contain the following routes: assert str(fib) == ("1.2.0.0/16 -> nh1, nh2\n" "1.2.3.0/24 -> nh3, nh4\n") # Delete the parent route from the RIB. rib.del_route("1.2.0.0/16") assert str(rib) == "1.2.3.0/24 -> nh3, nh4\n" # The corresponding route should be deleted from the FIB. assert str(fib) == "1.2.3.0/24 -> nh3, nh4\n" # Delete the child route from the RIB. rib.del_route("1.2.3.0/24") # The RIB must be empty. assert str(rib) == "" # The FIB must be empty. assert str(fib) == ""
def test_add_two_route_same_destination_with_subnet_and_remove_one(): rib = Rib() default_route = RibRoute(default_prefix, N_SPF, default_next_hops) rib.put_route(default_route) best_default_route = RibRoute(default_prefix, S_SPF, ["S1", "S2", "S3"]) rib.put_route(best_default_route) first_disagg_route = RibRoute(first_negative_disagg_prefix, S_SPF, [], first_negative_disagg_next_hops) rib.put_route(first_disagg_route) subnet_disagg_route = RibRoute(subnet_disagg_prefix, S_SPF, [], subnet_negative_disagg_next_hops) rib.put_route(subnet_disagg_route) rib.del_route(default_prefix, S_SPF) # Test for default assert rib.destinations.get(default_prefix).best_route == default_route assert rib.destinations.get(default_prefix).best_route.positive_next_hops == {'S1', 'S2', 'S3', 'S4'} assert rib.destinations.get(default_prefix).best_route.negative_next_hops == set() assert rib.destinations.get(default_prefix).best_route.next_hops == {'S1', 'S2', 'S3', 'S4'} assert rib.fib.routes[default_prefix].next_hops == default_route.next_hops assert rib.fib.kernel.routes[default_prefix] == default_route.next_hops # Test for 10.0.0.0/16 assert rib.destinations.get(first_negative_disagg_prefix).best_route == first_disagg_route assert rib.destinations.get(first_negative_disagg_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(first_negative_disagg_prefix).best_route.negative_next_hops == {'S1'} assert rib.destinations.get(first_negative_disagg_prefix).best_route.next_hops == {'S2', 'S3', 'S4'} assert rib.fib.routes[first_negative_disagg_prefix].next_hops == first_disagg_route.next_hops assert rib.fib.kernel.routes[first_negative_disagg_prefix] == first_disagg_route.next_hops # Test for 10.0.10.0/24 assert rib.destinations.get(subnet_disagg_prefix).best_route == subnet_disagg_route assert rib.destinations.get(subnet_disagg_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(subnet_disagg_prefix).best_route.negative_next_hops == {'S2'} assert rib.destinations.get(subnet_disagg_prefix).best_route.next_hops == {'S3', 'S4'} assert rib.fib.routes[subnet_disagg_prefix].next_hops == subnet_disagg_route.next_hops assert rib.fib.kernel.routes[subnet_disagg_prefix] == subnet_disagg_route.next_hops
def test_remove_default_route(): rib = Rib() default_route = RibRoute(default_prefix, S_SPF, default_next_hops) rib.put_route(default_route) first_disagg_route = RibRoute(first_negative_disagg_prefix, S_SPF, [], first_negative_disagg_next_hops) rib.put_route(first_disagg_route) subnet_disagg_route = RibRoute(subnet_disagg_prefix, S_SPF, [], subnet_negative_disagg_next_hops) rib.put_route(subnet_disagg_route) rib.del_route(default_prefix, S_SPF) # Test for default assert not rib.destinations.has_key(default_prefix) assert default_prefix not in rib.fib.routes assert default_prefix not in rib.fib.kernel.routes # Test for 10.0.0.0/16 assert rib.destinations.get(first_negative_disagg_prefix).parent_prefix_dest is None assert rib.destinations.get(first_negative_disagg_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(first_negative_disagg_prefix).best_route.negative_next_hops == {'S1'} assert rib.destinations.get(first_negative_disagg_prefix).best_route.next_hops == set() assert rib.fib.routes[first_negative_disagg_prefix].next_hops == set() assert rib.fib.kernel.routes[first_negative_disagg_prefix] == "unreachable" # Test for 10.0.10.0/24 assert rib.destinations.get(subnet_disagg_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(subnet_disagg_prefix).best_route.negative_next_hops == {'S2'} assert rib.destinations.get(subnet_disagg_prefix).best_route.next_hops == set() assert rib.fib.routes[subnet_disagg_prefix].next_hops == set() assert rib.fib.kernel.routes[subnet_disagg_prefix] == "unreachable"
def test_del_route(): fib = Fib() rib = Rib(fib) rib.put_route("4.0.0.0/8", ["nh1", "nh2"]) rib.put_route("5.5.0.0/16", ["nh3", "nh4"]) rib.del_route("4.0.0.0/8") rib.del_route("3.0.0.0/8") assert str(rib) == ("5.5.0.0/16 -> nh3, nh4\n")
def test_remove_superfluous_subnet(): rib = Rib() default_route = RibRoute(default_prefix, S_SPF, default_next_hops) rib.put_route(default_route) first_disagg_route = RibRoute(first_negative_disagg_prefix, S_SPF, [], first_negative_disagg_next_hops) rib.put_route(first_disagg_route) subnet_disagg_route = RibRoute(subnet_disagg_prefix, S_SPF, [], subnet_negative_disagg_next_hops) rib.put_route(subnet_disagg_route) rib.del_route(subnet_disagg_prefix, S_SPF) assert not rib.destinations.has_key(subnet_disagg_prefix) assert subnet_disagg_prefix not in rib.fib.routes assert subnet_disagg_prefix not in rib.fib.kernel.routes
def test_remove_best_route(): rib = Rib() default_route = RibRoute(default_prefix, N_SPF, default_next_hops) rib.put_route(default_route) best_default_route = RibRoute(default_prefix, S_SPF, ['S1']) rib.put_route(best_default_route) rib.del_route(default_prefix, S_SPF) assert rib.destinations.get(default_prefix).best_route == default_route assert rib.destinations.get(default_prefix).best_route.positive_next_hops == {'S1', 'S2', 'S3', 'S4'} assert rib.destinations.get(default_prefix).best_route.negative_next_hops == set() assert rib.destinations.get(default_prefix).best_route.next_hops == {'S1', 'S2', 'S3', 'S4'} assert rib.fib.routes[default_prefix].next_hops == default_route.next_hops assert rib.fib.kernel.routes[default_prefix] == default_route.next_hops
def test_prop_delete_nexthop_one_level(): # Test slide 58 in Pascal's "negative disaggregation" presentation. # Delete a nexthop from a parent route, and check that the computed complementary nexthops in # the child routes are properly updated. fib = Fib() rib = Rib(fib) # Install the following three routes into the RIB: rib.put_route("0.0.0.0/0", ["nh1", "nh2", "nh3", "nh4"]) # Parent default route rib.put_route("10.0.0.0/16", [], ["nh1"]) # First child, negative nexthop rib.put_route("10.1.0.0/16", [], ["nh4"]) # Second child, negative nexthop # The RIB must contain the following routes: assert str(rib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4\n" "10.0.0.0/16 -> ~nh1\n" "10.1.0.0/16 -> ~nh4\n") # The FIB must contain the following routes: assert str(fib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4\n" "10.0.0.0/16 -> nh2, nh3, nh4\n" "10.1.0.0/16 -> nh1, nh2, nh3\n") # Delete nexthop nh2 from the parent route 0.0.0.0/0 (by replacing the route with a new one # that has the reduced set of nexthops). rib.put_route("0.0.0.0/0", ["nh1", "nh3", "nh4"]) # The RIB must contain the following routes: assert str(rib) == ("0.0.0.0/0 -> nh1, nh3, nh4\n" # nh2 is gone "10.0.0.0/16 -> ~nh1\n" "10.1.0.0/16 -> ~nh4\n") # The FIB must contain the following routes: assert str(fib) == ("0.0.0.0/0 -> nh1, nh3, nh4\n" # nh2 is gone "10.0.0.0/16 -> nh3, nh4\n" # computed nh2 is gone "10.1.0.0/16 -> nh1, nh3\n") # computed nh2 is gone # Delete all routes from the RIB. rib.del_route("0.0.0.0/0") rib.del_route("10.0.0.0/16") rib.del_route("10.1.0.0/16") # The RIB must be empty. assert str(rib) == "" # The FIB must be empty. assert str(fib) == ""
def test_prop_mix_positive_negative(): # Child routes have mixture of positive and negative nexthops fib = Fib() rib = Rib(fib) # Install the following three routes into the RIB: rib.put_route("1.0.0.0/8", ["nh1", "nh2", "nh3"]) # Parent aggregate route rib.put_route("1.1.0.0/16", ["nh4"], ["nh1"]) # Child, positive and negative nexthop rib.put_route("1.1.1.0/24", ["nh5"], ["nh2"]) # Grandchild, positive and negative nexthop # The RIB must contain the following routes: assert str(rib) == ("1.0.0.0/8 -> nh1, nh2, nh3\n" "1.1.0.0/16 -> ~nh1, nh4\n" "1.1.1.0/24 -> ~nh2, nh5\n") # The FIB must contain the following routes: assert str(fib) == ("1.0.0.0/8 -> nh1, nh2, nh3\n" "1.1.0.0/16 -> nh2, nh3, nh4\n" "1.1.1.0/24 -> nh3, nh4, nh5\n") # Delete nexthop nh3 from the parent route 1.0.0.0/8 (by replacing the route with a new one # that has the reduced set of nexthops). rib.put_route("1.0.0.0/8", ["nh1", "nh2"]) # The RIB must contain the following routes: assert str(rib) == ("1.0.0.0/8 -> nh1, nh2\n" # nh3 is gone "1.1.0.0/16 -> ~nh1, nh4\n" "1.1.1.0/24 -> ~nh2, nh5\n") # The FIB must contain the following routes: assert str(fib) == ("1.0.0.0/8 -> nh1, nh2\n" # nh3 is gone "1.1.0.0/16 -> nh2, nh4\n" # computed nh3 is gone "1.1.1.0/24 -> nh4, nh5\n") # computed nh3 is gone # Delete all routes from the RIB. rib.del_route("1.0.0.0/8") rib.del_route("1.1.0.0/16") rib.del_route("1.1.1.0/24") # The RIB must be empty. assert str(rib) == "" # The FIB must be empty. assert str(fib) == ""
def test_remove_superfluous_subnet_recursive(): rib = Rib() default_route = RibRoute(default_prefix, S_SPF, default_next_hops) rib.put_route(default_route) first_disagg_route = RibRoute(first_negative_disagg_prefix, S_SPF, [], first_negative_disagg_next_hops) rib.put_route(first_disagg_route) subnet_disagg_route = RibRoute(subnet_disagg_prefix, S_SPF, [], subnet_negative_disagg_next_hops) rib.put_route(subnet_disagg_route) rib.del_route(first_negative_disagg_prefix, S_SPF) assert not rib.destinations.has_key(first_negative_disagg_prefix) assert first_negative_disagg_prefix not in rib.fib.routes assert first_negative_disagg_prefix not in rib.fib.kernel.routes assert rib.destinations.get(subnet_disagg_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(subnet_disagg_prefix).best_route.negative_next_hops == {'S2'} assert rib.destinations.get(subnet_disagg_prefix).best_route.next_hops == {'S1', 'S3', 'S4'} assert rib.fib.routes[subnet_disagg_prefix].next_hops == subnet_disagg_route.next_hops assert rib.fib.kernel.routes[subnet_disagg_prefix] == subnet_disagg_route.next_hops assert rib.destinations.get(subnet_disagg_prefix).parent_prefix_dest == rib.destinations.get(default_prefix)
def test_prop_two_children(): # Test slide 57 in Pascal's "negative disaggregation" presentation: # Add a parent aggregate with positive nexthops and two children with negative nexthops. fib = Fib() rib = Rib(fib) # Install the following routes into the RIB: rib.put_route("0.0.0.0/0", ["nh1", "nh2", "nh3", "nh4"]) # Parent default route rib.put_route("10.0.0.0/16", [], ["nh1"]) # First child route, negative nh rib.put_route("10.1.0.0/16", [], ["nh4"]) # Second child route, negative nh # The RIB must contain the following routes: assert str(rib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4\n" "10.0.0.0/16 -> ~nh1\n" "10.1.0.0/16 -> ~nh4\n") # The FIB must contain the following routes: assert str(fib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4\n" "10.0.0.0/16 -> nh2, nh3, nh4\n" "10.1.0.0/16 -> nh1, nh2, nh3\n") # Delete the parent route from the RIB. rib.del_route("0.0.0.0/0") # The RIB must contain the following routes: assert str(rib) == ("10.0.0.0/16 -> ~nh1\n" "10.1.0.0/16 -> ~nh4\n") # The FIB must contain the following routes (note: no nexthops, so discard routes): assert str(fib) == ("10.0.0.0/16 -> \n" "10.1.0.0/16 -> \n") # Delete both remaining child routes from the RIB. rib.del_route("10.0.0.0/16") rib.del_route("10.1.0.0/16") # The RIB must be empty. assert str(rib) == "" # The FIB must be empty. assert str(fib) == ""
def test_prop_one_child(): # Test slide 56 in Pascal's "negative disaggregation" presentation: # Add a parent aggregate with positive nexthops and one child with a negative nexthop. fib = Fib() rib = Rib(fib) # Install two routes into the RIB: one parent aggregate with four ECMP positive nexthops, and # one child more specific with one negative nexthop. rib.put_route("0.0.0.0/0", ["nh1", "nh2", "nh3", "nh4"]) # Parent default route rib.put_route("10.0.0.0/16", [], ["nh1"]) # Child route with negative nexthop # The RIB must contain the following routes: assert str(rib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4\n" "10.0.0.0/16 -> ~nh1\n") # The RIB must contain the following routes: assert str(fib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4\n" # Parent route, same as RIB "10.0.0.0/16 -> nh2, nh3, nh4\n") # Child route, complementary nhs # Delete the parent route from the RIB. rib.del_route("0.0.0.0/0") # The RIB must contain the following routes: assert str(rib) == "10.0.0.0/16 -> ~nh1\n" # The FIB must contain the following routes: assert str(fib) == "10.0.0.0/16 -> \n" # Delete the child route from the RIB. rib.del_route("10.0.0.0/16") # The RIB must be empty. assert str(rib) == "" # The FIB must be empty. assert str(fib) == ""
def test_prop_one_route_pos(): # Add a single route with only positive next-hops fib = Fib() rib = Rib(fib) # Install one route into the RIB: rib.put_route("1.2.3.0/24", ["nh1", "nh2"]) # A single route, positive nexthops # The RIB must contain the following route: assert str(rib) == ("1.2.3.0/24 -> nh1, nh2\n") # The FIB must contain the following route: assert str(fib) == ("1.2.3.0/24 -> nh1, nh2\n") # Delete the route from the RIB. rib.del_route("1.2.3.0/24") # The RIB must be empty. assert str(rib) == ("") # The FIB must be empty. assert str(fib) == ("")
def test_prop_nesting_with_siblings(): # Deep nesting of more specific routes using the following tree: # # 1.0.0.0/8 -> nh1, nh2, nh3, nh4, nh5, nh6, nh7 # | # +--- 1.1.0.0/16 -> ~nh1 # | | # | +--- 1.1.1.0/24 -> ~nh2 # | | # | +--- 1.1.2.0/24 -> ~nh3 # | # +--- 1.2.0.0/16 -> ~nh4 # | # +--- 1.2.1.0/24 -> ~nh5 # | # +--- 1.2.2.0/24 -> ~nh6 # # Note: we add the routes in a random order fib = Fib() rib = Rib(fib) # Install the following three routes into the RIB: rib.put_route("1.2.1.0/24", [], ["nh5"]) rib.put_route("1.1.2.0/24", [], ["nh3"]) rib.put_route("1.1.0.0/16", [], ["nh1"]) rib.put_route("1.1.1.0/24", [], ["nh2"]) rib.put_route("1.2.0.0/16", [], ["nh4"]) rib.put_route("1.0.0.0/8", ["nh1", "nh2", "nh3", "nh4", "nh5", "nh6", "nh7"]) rib.put_route("1.2.2.0/24", [], ["nh6"]) # The RIB must contain the following routes: assert str(rib) == ("1.0.0.0/8 -> nh1, nh2, nh3, nh4, nh5, nh6, nh7\n" "1.1.0.0/16 -> ~nh1\n" "1.1.1.0/24 -> ~nh2\n" "1.1.2.0/24 -> ~nh3\n" "1.2.0.0/16 -> ~nh4\n" "1.2.1.0/24 -> ~nh5\n" "1.2.2.0/24 -> ~nh6\n") # The FIB must contain the following routes: assert str(fib) == ("1.0.0.0/8 -> nh1, nh2, nh3, nh4, nh5, nh6, nh7\n" "1.1.0.0/16 -> nh2, nh3, nh4, nh5, nh6, nh7\n" "1.1.1.0/24 -> nh3, nh4, nh5, nh6, nh7\n" "1.1.2.0/24 -> nh2, nh4, nh5, nh6, nh7\n" "1.2.0.0/16 -> nh1, nh2, nh3, nh5, nh6, nh7\n" "1.2.1.0/24 -> nh1, nh2, nh3, nh6, nh7\n" "1.2.2.0/24 -> nh1, nh2, nh3, nh5, nh7\n") # Delete nexthop nh3 from the parent route 0.0.0.0/0. rib.put_route("1.0.0.0/8", ["nh1", "nh2", "nh4", "nh5", "nh6", "nh7"]) # The RIB must contain the following routes: assert str(rib) == ("1.0.0.0/8 -> nh1, nh2, nh4, nh5, nh6, nh7\n" "1.1.0.0/16 -> ~nh1\n" "1.1.1.0/24 -> ~nh2\n" "1.1.2.0/24 -> ~nh3\n" "1.2.0.0/16 -> ~nh4\n" "1.2.1.0/24 -> ~nh5\n" "1.2.2.0/24 -> ~nh6\n") # The FIB must contain the following routes: assert str(fib) == ("1.0.0.0/8 -> nh1, nh2, nh4, nh5, nh6, nh7\n" "1.1.0.0/16 -> nh2, nh4, nh5, nh6, nh7\n" "1.1.1.0/24 -> nh4, nh5, nh6, nh7\n" "1.1.2.0/24 -> nh2, nh4, nh5, nh6, nh7\n" "1.2.0.0/16 -> nh1, nh2, nh5, nh6, nh7\n" "1.2.1.0/24 -> nh1, nh2, nh6, nh7\n" "1.2.2.0/24 -> nh1, nh2, nh5, nh7\n") # Delete all routes from the RIB. rib.del_route("1.0.0.0/8") rib.del_route("1.1.0.0/16") rib.del_route("1.1.1.0/24") rib.del_route("1.1.2.0/24") rib.del_route("1.2.0.0/16") rib.del_route("1.2.1.0/24") rib.del_route("1.2.2.0/24") # The RIB must be empty. assert str(rib) == "" # The FIB must be empty. assert str(fib) == ""
def test_prop_deep_nesting(): # Deep nesting of more specific routes: parent, child, grand child, grand-grand child, ... fib = Fib() rib = Rib(fib) # Install the following three routes into the RIB: rib.put_route("0.0.0.0/0", ["nh1", "nh2", "nh3", "nh4", "nh5"]) # Parent rib.put_route("1.0.0.0/8", [], ["nh1"]) # Child rib.put_route("1.128.0.0/9", [], ["nh2"]) # Grand child rib.put_route("1.192.0.0/10", [], ["nh3"]) # Grand-grand child rib.put_route("1.224.0.0/11", [], ["nh4"]) # Grand-grand-grand child rib.put_route("1.240.0.0/12", [], ["nh5"]) # Grand-grand-grand-grand child # The RIB must contain the following routes: assert str(rib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4, nh5\n" "1.0.0.0/8 -> ~nh1\n" "1.128.0.0/9 -> ~nh2\n" "1.192.0.0/10 -> ~nh3\n" "1.224.0.0/11 -> ~nh4\n" "1.240.0.0/12 -> ~nh5\n") # The FIB must contain the following routes: assert str(fib) == ("0.0.0.0/0 -> nh1, nh2, nh3, nh4, nh5\n" "1.0.0.0/8 -> nh2, nh3, nh4, nh5\n" "1.128.0.0/9 -> nh3, nh4, nh5\n" "1.192.0.0/10 -> nh4, nh5\n" "1.224.0.0/11 -> nh5\n" "1.240.0.0/12 -> \n") # Delete nexthop nh3 from the parent route 0.0.0.0/0. rib.put_route("0.0.0.0/0", ["nh1", "nh2", "nh4", "nh5"]) # The RIB must contain the following routes: assert str(rib) == ("0.0.0.0/0 -> nh1, nh2, nh4, nh5\n" "1.0.0.0/8 -> ~nh1\n" "1.128.0.0/9 -> ~nh2\n" "1.192.0.0/10 -> ~nh3\n" "1.224.0.0/11 -> ~nh4\n" "1.240.0.0/12 -> ~nh5\n") # The FIB must contain the following routes: assert str(fib) == ("0.0.0.0/0 -> nh1, nh2, nh4, nh5\n" "1.0.0.0/8 -> nh2, nh4, nh5\n" "1.128.0.0/9 -> nh4, nh5\n" "1.192.0.0/10 -> nh4, nh5\n" "1.224.0.0/11 -> nh5\n" "1.240.0.0/12 -> \n") # Delete all routes from the RIB. rib.del_route("0.0.0.0/0") rib.del_route("1.0.0.0/8") rib.del_route("1.128.0.0/9") rib.del_route("1.192.0.0/10") rib.del_route("1.224.0.0/11") rib.del_route("1.240.0.0/12") # The RIB must be empty. assert str(rib) == "" # The FIB must be empty. assert str(fib) == ""
def test_prop_nesting_with_siblings(): # Deep nesting of more specific routes using the following tree: # # 1.0.0.0/8 -> S1, S2, S3, S4, S5, S6, S7 # | # +--- 1.1.0.0/16 -> ~S1 # | | # | +--- 1.1.1.0/24 -> ~S2 # | | # | +--- 1.1.2.0/24 -> ~S3 # | # +--- 1.2.0.0/16 -> ~S4 # | # +--- 1.2.1.0/24 -> ~S5 # | # +--- 1.2.2.0/24 -> ~S6 # # Note: we add the routes in a random order rib = Rib() rib.put_route(RibRoute("1.2.1.0/24", S_SPF, [], ["S5"])) rib.put_route(RibRoute("1.1.2.0/24", S_SPF, [], ["S3"])) rib.put_route(RibRoute("1.1.0.0/16", S_SPF, [], ['S1'])) rib.put_route(RibRoute("1.1.1.0/24", S_SPF, [], ['S2'])) rib.put_route(RibRoute("1.2.0.0/16", S_SPF, [], ['S4'])) rib.put_route(RibRoute("1.0.0.0/8", S_SPF, ['S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7'])) rib.put_route(RibRoute("1.2.2.0/24", S_SPF, [], ['S6'])) # Testing only rib, fib and kernel next hops assert rib.destinations.get('1.0.0.0/8').best_route.next_hops == {'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.0.0.0/8'].next_hops == {'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.0.0.0/8'] == {'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.1.0.0/16').best_route.negative_next_hops == {'S1'} assert rib.destinations.get('1.1.0.0/16').best_route.next_hops == {'S2', 'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.1.0.0/16'].next_hops == {'S2', 'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.1.0.0/16'] == {'S2', 'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.1.1.0/24').best_route.negative_next_hops == {'S2'} assert rib.destinations.get('1.1.1.0/24').best_route.next_hops == {'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.1.1.0/24'].next_hops == {'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.1.1.0/24'] == {'S3', 'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.1.2.0/24').best_route.negative_next_hops == {'S3'} assert rib.destinations.get('1.1.2.0/24').best_route.next_hops == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.1.2.0/24'].next_hops == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.1.2.0/24'] == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.2.0.0/16').best_route.negative_next_hops == {'S4'} assert rib.destinations.get('1.2.0.0/16').best_route.next_hops == {'S1', 'S2', 'S3', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.2.0.0/16'].next_hops == {'S1', 'S2', 'S3', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.2.0.0/16'] == {'S1', 'S2', 'S3', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.2.1.0/24').best_route.negative_next_hops == {'S5'} assert rib.destinations.get('1.2.1.0/24').best_route.next_hops == {'S1', 'S2', 'S3', 'S6', 'S7'} assert rib.fib.routes['1.2.1.0/24'].next_hops == {'S1', 'S2', 'S3', 'S6', 'S7'} assert rib.fib.kernel.routes['1.2.1.0/24'] == {'S1', 'S2', 'S3', 'S6', 'S7'} assert rib.destinations.get('1.2.2.0/24').best_route.negative_next_hops == {'S6'} assert rib.destinations.get('1.2.2.0/24').best_route.next_hops == {'S1', 'S2', 'S3', 'S5', 'S7'} assert rib.fib.routes['1.2.2.0/24'].next_hops == {'S1', 'S2', 'S3', 'S5', 'S7'} assert rib.fib.kernel.routes['1.2.2.0/24'] == {'S1', 'S2', 'S3', 'S5', 'S7'} # Delete nexthop S3 from the parent route 0.0.0.0/0. rib.put_route(RibRoute('1.0.0.0/8', S_SPF, ['S1', 'S2', 'S4', 'S5', 'S6', 'S7'])) # Testing only rib, fib and kernel next hops assert rib.destinations.get('1.0.0.0/8').best_route.next_hops == {'S1', 'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.0.0.0/8'].next_hops == {'S1', 'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.0.0.0/8'] == {'S1', 'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.1.0.0/16').best_route.negative_next_hops == {'S1'} assert rib.destinations.get('1.1.0.0/16').best_route.next_hops == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.1.0.0/16'].next_hops == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.1.0.0/16'] == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.1.1.0/24').best_route.negative_next_hops == {'S2'} assert rib.destinations.get('1.1.1.0/24').best_route.next_hops == {'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.1.1.0/24'].next_hops == {'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.1.1.0/24'] == {'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.1.2.0/24').best_route.negative_next_hops == {'S3'} assert rib.destinations.get('1.1.2.0/24').best_route.next_hops == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.1.2.0/24'].next_hops == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.1.2.0/24'] == {'S2', 'S4', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.2.0.0/16').best_route.negative_next_hops == {'S4'} assert rib.destinations.get('1.2.0.0/16').best_route.next_hops == {'S1', 'S2', 'S5', 'S6', 'S7'} assert rib.fib.routes['1.2.0.0/16'].next_hops == {'S1', 'S2', 'S5', 'S6', 'S7'} assert rib.fib.kernel.routes['1.2.0.0/16'] == {'S1', 'S2', 'S5', 'S6', 'S7'} assert rib.destinations.get('1.2.1.0/24').best_route.negative_next_hops == {'S5'} assert rib.destinations.get('1.2.1.0/24').best_route.next_hops == {'S1', 'S2', 'S6', 'S7'} assert rib.fib.routes['1.2.1.0/24'].next_hops == {'S1', 'S2', 'S6', 'S7'} assert rib.fib.kernel.routes['1.2.1.0/24'] == {'S1', 'S2', 'S6', 'S7'} assert rib.destinations.get('1.2.2.0/24').best_route.negative_next_hops == {'S6'} assert rib.destinations.get('1.2.2.0/24').best_route.next_hops == {'S1', 'S2', 'S5', 'S7'} assert rib.fib.routes['1.2.2.0/24'].next_hops == {'S1', 'S2', 'S5', 'S7'} assert rib.fib.kernel.routes['1.2.2.0/24'] == {'S1', 'S2', 'S5', 'S7'} # Delete all routes from the RIB. rib.del_route("1.0.0.0/8", S_SPF) rib.del_route("1.1.0.0/16", S_SPF) rib.del_route("1.1.1.0/24", S_SPF) rib.del_route("1.1.2.0/24", S_SPF) rib.del_route("1.2.0.0/16", S_SPF) rib.del_route("1.2.1.0/24", S_SPF) rib.del_route("1.2.2.0/24", S_SPF) assert not rib.destinations.keys() assert not rib.fib.routes.keys() assert not rib.fib.kernel.routes.keys()
def test_prop_deep_nesting(): # Deep nesting of more specific routes: parent, child, grand child, grand-grand child, ... rib = Rib() # Default route new_default_next_hops = ['S1', 'S2', 'S3', 'S4', 'S5'] new_default_route = RibRoute(default_prefix, S_SPF, new_default_next_hops) rib.put_route(new_default_route) # Child route child_prefix = '1.0.0.0/8' child_route = RibRoute(child_prefix, S_SPF, [], ['S1']) rib.put_route(child_route) # Grand child route g_child_prefix = '1.128.0.0/9' g_child_route = RibRoute(g_child_prefix, S_SPF, [], ['S2']) rib.put_route(g_child_route) # Grand-grand child route gg_child_prefix = '1.192.0.0/10' gg_child_route = RibRoute(gg_child_prefix, S_SPF, [], ['S3']) rib.put_route(gg_child_route) # Grand-grand-grand child route ggg_child_prefix = '1.224.0.0/11' ggg_child_route = RibRoute(ggg_child_prefix, S_SPF, [], ['S4']) rib.put_route(ggg_child_route) # Grand-grand-grand-grand child route gggg_child_prefix = '1.240.0.0/12' gggg_child_route = RibRoute(gggg_child_prefix, S_SPF, [], ['S5']) rib.put_route(gggg_child_route) # Default route asserts assert rib.destinations.get(default_prefix).best_route == new_default_route assert rib.destinations.get(default_prefix).best_route.next_hops == {'S1', 'S2', 'S3', 'S4', 'S5'} assert rib.fib.routes[default_prefix].next_hops == new_default_route.next_hops assert rib.fib.kernel.routes[default_prefix] == new_default_route.next_hops # Child route asserts assert rib.destinations.get(child_prefix).best_route == child_route assert rib.destinations.get(child_prefix).best_route.next_hops == {'S2', 'S3', 'S4', 'S5'} assert rib.fib.routes[child_prefix].next_hops == child_route.next_hops assert rib.fib.kernel.routes[child_prefix] == child_route.next_hops # Grand-child route asserts assert rib.destinations.get(g_child_prefix).best_route == g_child_route assert rib.destinations.get(g_child_prefix).best_route.next_hops == {'S3', 'S4', 'S5'} assert rib.fib.routes[g_child_prefix].next_hops == g_child_route.next_hops assert rib.fib.kernel.routes[g_child_prefix] == g_child_route.next_hops # Grand-grand child route asserts assert rib.destinations.get(gg_child_prefix).best_route == gg_child_route assert rib.destinations.get(gg_child_prefix).best_route.next_hops == {'S4', 'S5'} assert rib.fib.routes[gg_child_prefix].next_hops == gg_child_route.next_hops assert rib.fib.kernel.routes[gg_child_prefix] == gg_child_route.next_hops # Grand-grand-grand child route asserts assert rib.destinations.get(ggg_child_prefix).best_route == ggg_child_route assert rib.destinations.get(ggg_child_prefix).best_route.next_hops == {'S5'} assert rib.fib.routes[ggg_child_prefix].next_hops == ggg_child_route.next_hops assert rib.fib.kernel.routes[ggg_child_prefix] == ggg_child_route.next_hops # Grand-grand-grand-grand child route asserts assert rib.destinations.get(gggg_child_prefix).best_route == gggg_child_route assert rib.destinations.get(gggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gggg_child_prefix].next_hops == gggg_child_route.next_hops assert rib.fib.kernel.routes[gggg_child_prefix] == 'unreachable' # Delete S3 from default route new_default_route = RibRoute(default_prefix, S_SPF, ['S1', 'S2', 'S4', 'S5']) rib.put_route(new_default_route) # Default route asserts assert rib.destinations.get(default_prefix).best_route == new_default_route assert rib.destinations.get(default_prefix).best_route.next_hops == {'S1', 'S2', 'S4', 'S5'} assert rib.fib.routes[default_prefix].next_hops == new_default_route.next_hops assert rib.fib.kernel.routes[default_prefix] == new_default_route.next_hops # Child route asserts assert rib.destinations.get(child_prefix).best_route == child_route assert rib.destinations.get(child_prefix).best_route.next_hops == {'S2', 'S4', 'S5'} assert rib.fib.routes[child_prefix].next_hops == child_route.next_hops assert rib.fib.kernel.routes[child_prefix] == child_route.next_hops # Grand-child route asserts assert rib.destinations.get(g_child_prefix).best_route == g_child_route assert rib.destinations.get(g_child_prefix).best_route.next_hops == {'S4', 'S5'} assert rib.fib.routes[g_child_prefix].next_hops == g_child_route.next_hops assert rib.fib.kernel.routes[g_child_prefix] == g_child_route.next_hops # Grand-grand child route asserts assert rib.destinations.get(gg_child_prefix).best_route == gg_child_route assert rib.destinations.get(gg_child_prefix).best_route.next_hops == {'S4', 'S5'} assert rib.fib.routes[gg_child_prefix].next_hops == gg_child_route.next_hops assert rib.fib.kernel.routes[gg_child_prefix] == gg_child_route.next_hops # Grand-grand-grand child route asserts assert rib.destinations.get(ggg_child_prefix).best_route == ggg_child_route assert rib.destinations.get(ggg_child_prefix).best_route.next_hops == {'S5'} assert rib.fib.routes[ggg_child_prefix].next_hops == ggg_child_route.next_hops assert rib.fib.kernel.routes[ggg_child_prefix] == ggg_child_route.next_hops # Grand-grand-grand-grand child route asserts assert rib.destinations.get(gggg_child_prefix).best_route == gggg_child_route assert rib.destinations.get(gggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gggg_child_prefix].next_hops == gggg_child_route.next_hops assert rib.fib.kernel.routes[gggg_child_prefix] == 'unreachable' rib.del_route(default_prefix, S_SPF) # Default route asserts assert not rib.destinations.has_key(default_prefix) # Child route asserts assert rib.destinations.get(child_prefix).best_route == child_route assert rib.destinations.get(child_prefix).best_route.next_hops == set() assert rib.fib.routes[child_prefix].next_hops == set() assert rib.fib.kernel.routes[child_prefix] == 'unreachable' # Grand-child route asserts assert rib.destinations.get(g_child_prefix).best_route == g_child_route assert rib.destinations.get(g_child_prefix).best_route.next_hops == set() assert rib.fib.routes[g_child_prefix].next_hops == set() assert rib.fib.kernel.routes[g_child_prefix] == 'unreachable' # Grand-grand child route asserts assert rib.destinations.get(gg_child_prefix).best_route == gg_child_route assert rib.destinations.get(gg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gg_child_prefix] == 'unreachable' # Grand-grand-grand child route asserts assert rib.destinations.get(ggg_child_prefix).best_route == ggg_child_route assert rib.destinations.get(ggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[ggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[ggg_child_prefix] == 'unreachable' # Grand-grand-grand-grand child route asserts assert rib.destinations.get(gggg_child_prefix).best_route == gggg_child_route assert rib.destinations.get(gggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gggg_child_prefix] == 'unreachable' rib.del_route(child_prefix, S_SPF) # Child route asserts assert not rib.destinations.has_key(child_prefix) # Grand-child route asserts assert rib.destinations.get(g_child_prefix).best_route == g_child_route assert rib.destinations.get(g_child_prefix).best_route.next_hops == set() assert rib.fib.routes[g_child_prefix].next_hops == set() assert rib.fib.kernel.routes[g_child_prefix] == 'unreachable' # Grand-grand child route asserts assert rib.destinations.get(gg_child_prefix).best_route == gg_child_route assert rib.destinations.get(gg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gg_child_prefix] == 'unreachable' # Grand-grand-grand child route asserts assert rib.destinations.get(ggg_child_prefix).best_route == ggg_child_route assert rib.destinations.get(ggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[ggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[ggg_child_prefix] == 'unreachable' # Grand-grand-grand-grand child route asserts assert rib.destinations.get(gggg_child_prefix).best_route == gggg_child_route assert rib.destinations.get(gggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gggg_child_prefix] == 'unreachable' rib.del_route(g_child_prefix, S_SPF) # Grand-child route asserts assert not rib.destinations.has_key(g_child_prefix) # Grand-grand child route asserts assert rib.destinations.get(gg_child_prefix).best_route == gg_child_route assert rib.destinations.get(gg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gg_child_prefix] == 'unreachable' # Grand-grand-grand child route asserts assert rib.destinations.get(ggg_child_prefix).best_route == ggg_child_route assert rib.destinations.get(ggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[ggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[ggg_child_prefix] == 'unreachable' # Grand-grand-grand-grand child route asserts assert rib.destinations.get(gggg_child_prefix).best_route == gggg_child_route assert rib.destinations.get(gggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gggg_child_prefix] == 'unreachable' rib.del_route(gg_child_prefix, S_SPF) # Grand-child route asserts assert not rib.destinations.has_key(gg_child_prefix) # Grand-grand-grand child route asserts assert rib.destinations.get(ggg_child_prefix).best_route == ggg_child_route assert rib.destinations.get(ggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[ggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[ggg_child_prefix] == 'unreachable' # Grand-grand-grand-grand child route asserts assert rib.destinations.get(gggg_child_prefix).best_route == gggg_child_route assert rib.destinations.get(gggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gggg_child_prefix] == 'unreachable' rib.del_route(ggg_child_prefix, S_SPF) # Grand-child route asserts assert not rib.destinations.has_key(ggg_child_prefix) # Grand-grand-grand-grand child route asserts assert rib.destinations.get(gggg_child_prefix).best_route == gggg_child_route assert rib.destinations.get(gggg_child_prefix).best_route.next_hops == set() assert rib.fib.routes[gggg_child_prefix].next_hops == set() assert rib.fib.kernel.routes[gggg_child_prefix] == 'unreachable' rib.del_route(gggg_child_prefix, S_SPF) # Grand-grand-grand-grand child route asserts assert not rib.destinations.has_key(gggg_child_prefix) assert not rib.destinations.keys() assert not rib.fib.routes.keys() assert not rib.fib.kernel.routes.keys()