def test_remove_default_next_hop(): 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) second_disagg_route = RibRoute(second_negative_disagg_prefix, S_SPF, [], second_negative_disagg_next_hops) rib.put_route(second_disagg_route) default_route_fail = RibRoute(default_prefix, S_SPF, ['S1', 'S3', 'S4']) rib.put_route(default_route_fail) # Test for default assert rib.destinations.get(default_prefix).best_route == default_route_fail assert rib.destinations.get(default_prefix).best_route.positive_next_hops == {'S1', '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', 'S3', 'S4'} assert rib.fib.routes[default_prefix].next_hops == default_route_fail.next_hops assert rib.fib.kernel.routes[default_prefix] == default_route_fail.next_hops # Test for 10.0.0.0/16 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 == {'S3', 'S4'} assert rib.fib.kernel.routes[first_negative_disagg_prefix] == first_disagg_route.next_hops # Test for 10.1.0.0/16 assert rib.destinations.get(second_negative_disagg_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(second_negative_disagg_prefix).best_route.negative_next_hops == {'S4'} assert rib.destinations.get(second_negative_disagg_prefix).best_route.next_hops == {'S1', 'S3'} assert rib.fib.kernel.routes[second_negative_disagg_prefix] == second_disagg_route.next_hops
def test_add_two_route_same_destination_with_subnet(): 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) # Test for default assert rib.destinations.get(default_prefix).best_route == best_default_route assert rib.destinations.get(default_prefix).best_route.positive_next_hops == {'S1', 'S2', 'S3'} 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'} assert rib.fib.routes[default_prefix].next_hops == best_default_route.next_hops assert rib.fib.kernel.routes[default_prefix] == best_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'} 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'} 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_add_default_route(): rib = Rib() default_route = RibRoute(default_prefix, S_SPF, default_next_hops) rib.put_route(default_route) assert rib.destinations.get(default_prefix).best_route == default_route 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_add_default_route(): rib = Rib() rib.add_route(default_prefix, default_next_hops) assert rib.destinations.get( default_prefix)._positive_next_hops == default_next_hops assert rib.destinations.get(default_prefix)._negative_next_hops == set() assert rib.destinations.get( default_prefix).get_next_hops == default_next_hops assert rib.fib.routes[default_prefix] == default_next_hops
def test_put_route(): fib = Fib() rib = Rib(fib) rib.put_route("4.0.0.0/8", ["nh1", "nh2"]) rib.put_route("3.3.0.0/16", ["nh1", "nh3"], ["nh4", "nh2"]) rib.put_route("4.1.1.0/24", [], ["nh1"]) rib.put_route("4.0.0.0/8", ["nh1", "nh3"]) assert str(rib) == ("3.3.0.0/16 -> nh1, ~nh2, nh3, ~nh4\n" "4.0.0.0/8 -> nh1, nh3\n" "4.1.1.0/24 -> ~nh1\n")
def test_get_repr(): fib = Fib() rib = Rib(fib) rib.put_route("2.0.0.0/8", ["nh1", "nh2"]) rib.put_route("2.2.2.0/24", ["nh1", "nh3"], ["nh4", "nh2"]) rib.put_route("1.1.1.1/32", [], ["nh1"]) rib.put_route("2.2.1.0/24", ["nh1", "nh3"]) assert str(rib) == ("1.1.1.1/32 -> ~nh1\n" "2.0.0.0/8 -> nh1, nh2\n" "2.2.1.0/24 -> nh1, nh3\n" "2.2.2.0/24 -> nh1, ~nh2, 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_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_subnet_disagg_to_first_negative_disagg(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(first_negative_disagg_prefix, first_negative_disagg_next_hops, disagg_type=False) rib.add_route(subnet_disagg_prefix, subnet_disagg_next_hops, disagg_type=False) assert rib.destinations.get( first_negative_disagg_prefix)._positive_next_hops == set() assert rib.destinations.get(first_negative_disagg_prefix)._negative_next_hops == \ first_negative_disagg_next_hops assert rib.destinations.get(first_negative_disagg_prefix).get_next_hops == \ default_next_hops - first_negative_disagg_next_hops assert rib.fib.routes[first_negative_disagg_prefix] == \ default_next_hops - first_negative_disagg_next_hops # test for disaggregated subnet assert rib.destinations.get( subnet_disagg_prefix)._positive_next_hops == set() assert rib.destinations.get( subnet_disagg_prefix)._negative_next_hops == subnet_disagg_next_hops assert rib.destinations.get(subnet_disagg_prefix).get_next_hops == \ default_next_hops - first_negative_disagg_next_hops - subnet_disagg_next_hops assert rib.fib.routes[subnet_disagg_prefix] == \ default_next_hops - first_negative_disagg_next_hops - subnet_disagg_next_hops
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 __init__(self): self.ribs = { '172.0.0.1': Rib(ip='172.0.0.1'), '172.0.0.2': Rib(ip='172.0.0.2'), '172.0.0.3': Rib(ip='172.0.0.3'), '172.0.0.4': Rib(ip='172.0.0.4'), } self.main_rib = Rib(ip=MAIN_BGP)
def test_add_subnet_disagg_recursive_unreachable(): 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) first_neg_unreach = RibRoute(first_negative_disagg_prefix, S_SPF, [], unreachable_negative_next_hops) rib.put_route(first_neg_unreach) 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', 'S2', 'S3', 'S4'} assert rib.destinations.get(first_negative_disagg_prefix).best_route.next_hops == set() assert rib.fib.routes[first_negative_disagg_prefix].next_hops == first_neg_unreach.next_hops assert rib.fib.kernel.routes[first_negative_disagg_prefix] == "unreachable" assert not rib.destinations.has_key(subnet_disagg_prefix) assert subnet_disagg_prefix not in rib.fib.routes
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_pos_neg_disagg_recursive(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(first_negative_disagg_prefix, first_negative_disagg_next_hops, disagg_type=False) rib.add_route(subnet_disagg_prefix, subnet_disagg_next_hops, disagg_type=False) rib.add_route(subnet_disagg_prefix, first_negative_disagg_next_hops) assert rib.destinations.get(subnet_disagg_prefix)._positive_next_hops == \ first_negative_disagg_next_hops assert rib.destinations.get(subnet_disagg_prefix)._negative_next_hops == \ subnet_disagg_next_hops assert rib.destinations.get(subnet_disagg_prefix).get_next_hops == \ default_next_hops - subnet_disagg_next_hops assert rib.fib.routes[ subnet_disagg_prefix] == default_next_hops - subnet_disagg_next_hops
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_neg_disagg_fib_unreachable_recover(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(unreachable_prefix, unreachable_next_hops, disagg_type=False) recovered_nodes = {"S3"} rib.delete_route(unreachable_prefix, recovered_nodes, disagg_type=False) assert rib.destinations.get( unreachable_prefix)._positive_next_hops == set() assert rib.destinations.get(unreachable_prefix)._negative_next_hops == \ unreachable_next_hops - recovered_nodes assert rib.destinations.get( unreachable_prefix).get_next_hops == recovered_nodes assert rib.fib.routes[unreachable_prefix] == recovered_nodes
def test_neg_disagg_fib_unreachable_recover(): rib = Rib() default_route = RibRoute(default_prefix, S_SPF, default_next_hops) rib.put_route(default_route) unreachable_route = RibRoute(unreachable_prefix, S_SPF, [], unreachable_negative_next_hops) rib.put_route(unreachable_route) unreachable_route_recover = RibRoute(unreachable_prefix, S_SPF, [], ['S1', 'S2', 'S4']) rib.put_route(unreachable_route_recover) assert rib.destinations.get(unreachable_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(unreachable_prefix).best_route.negative_next_hops == {'S1', 'S2', 'S4'} assert rib.destinations.get(unreachable_prefix).best_route.next_hops == {'S3'} assert rib.fib.routes[unreachable_prefix].next_hops == unreachable_route_recover.next_hops assert rib.fib.kernel.routes[unreachable_prefix] == {'S3'}
def test_pos_neg_disagg_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, ["S1"], subnet_negative_disagg_next_hops) rib.put_route(subnet_disagg_route) assert rib.destinations.get(subnet_disagg_prefix).best_route.positive_next_hops == {"S1"} 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] == {"S1", "S3", "S4"}
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_add_subnet_disagg_to_first_negative_disagg(): 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) 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_add_two_negative_disaggregation(): 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) second_disagg_route = RibRoute(second_negative_disagg_prefix, S_SPF, [], second_negative_disagg_next_hops) rib.put_route(second_disagg_route) assert rib.destinations.get(second_negative_disagg_prefix).best_route == second_disagg_route assert rib.destinations.get(second_negative_disagg_prefix).best_route.positive_next_hops == set() assert rib.destinations.get(second_negative_disagg_prefix).best_route.negative_next_hops == {'S4'} assert rib.destinations.get(second_negative_disagg_prefix).best_route.next_hops == {'S1', 'S2', 'S3'} assert rib.fib.routes[second_negative_disagg_prefix].next_hops == second_disagg_route.next_hops assert rib.fib.kernel.routes[second_negative_disagg_prefix] == second_disagg_route.next_hops
def test_remove_default_next_hop_with_subnet_disagg(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(first_negative_disagg_prefix, first_negative_disagg_next_hops, disagg_type=False) rib.add_route(subnet_disagg_prefix, subnet_disagg_next_hops, disagg_type=False) failed_next_hop = {"S3"} rib.delete_route(default_prefix, failed_next_hop) # test for default assert rib.destinations.get( default_prefix )._positive_next_hops == default_next_hops - failed_next_hop assert rib.destinations.get(default_prefix)._negative_next_hops == set() assert rib.destinations.get( default_prefix).get_next_hops == default_next_hops - failed_next_hop assert rib.fib.routes[ default_prefix] == default_next_hops - failed_next_hop # test for 10.0.0.0/16 assert rib.destinations.get( first_negative_disagg_prefix)._positive_next_hops == set() assert rib.destinations.get(first_negative_disagg_prefix)._negative_next_hops == \ first_negative_disagg_next_hops assert rib.destinations.get(first_negative_disagg_prefix).get_next_hops == \ default_next_hops - first_negative_disagg_next_hops - failed_next_hop assert rib.fib.routes[first_negative_disagg_prefix] == \ default_next_hops - first_negative_disagg_next_hops - failed_next_hop # test for 10.0.10.0/24 assert rib.destinations.get( subnet_disagg_prefix)._positive_next_hops == set() assert rib.destinations.get(subnet_disagg_prefix)._negative_next_hops == \ subnet_disagg_next_hops assert rib.destinations.get(subnet_disagg_prefix).get_next_hops == \ default_next_hops - first_negative_disagg_next_hops - subnet_disagg_next_hops - \ failed_next_hop assert rib.fib.routes[subnet_disagg_prefix] == \ default_next_hops - first_negative_disagg_next_hops - subnet_disagg_next_hops - \ failed_next_hop
def test_pos_neg_disagg(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(leaf_prefix, leaf_prefix_positive_next_hops) rib.add_route(leaf_prefix, leaf_prefix_negative_next_hops, disagg_type=False) assert rib.destinations.get( leaf_prefix)._positive_next_hops == leaf_prefix_positive_next_hops assert rib.destinations.get( leaf_prefix)._negative_next_hops == leaf_prefix_negative_next_hops assert rib.destinations.get( leaf_prefix).get_next_hops == leaf_prefix_positive_next_hops assert rib.fib.routes[leaf_prefix] == leaf_prefix_positive_next_hops
def test_add_subnet_disagg_recursive_unreachable(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(first_negative_disagg_prefix, first_negative_disagg_next_hops, disagg_type=False) rib.add_route(subnet_disagg_prefix, subnet_disagg_next_hops, disagg_type=False) unreachable_next_hops = default_next_hops - first_negative_disagg_next_hops rib.add_route(first_negative_disagg_prefix, unreachable_next_hops, disagg_type=False) assert rib.destinations.get( first_negative_disagg_prefix)._positive_next_hops == set() assert rib.destinations.get( first_negative_disagg_prefix)._negative_next_hops == default_next_hops assert rib.destinations.get( first_negative_disagg_prefix).get_next_hops == set() assert rib.fib.routes[first_negative_disagg_prefix] == "unreachable" assert not rib.destinations.has_key(subnet_disagg_prefix) assert subnet_disagg_prefix not in rib.fib.routes
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_add_two_negative_disaggregation(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(first_negative_disagg_prefix, first_negative_disagg_next_hops, disagg_type=False) rib.add_route(second_negative_disagg_prefix, second_negative_disagg_next_hops, disagg_type=False) assert rib.destinations.get( second_negative_disagg_prefix)._positive_next_hops == set() assert rib.destinations.get(second_negative_disagg_prefix)._negative_next_hops == \ second_negative_disagg_next_hops assert rib.destinations.get(second_negative_disagg_prefix).get_next_hops == \ default_next_hops - second_negative_disagg_next_hops assert rib.fib.routes[second_negative_disagg_prefix] == \ default_next_hops - second_negative_disagg_next_hops
def test_neg_disagg_fib_unreachable(): rib = Rib() rib.add_route(default_prefix, default_next_hops) rib.add_route(unreachable_prefix, unreachable_next_hops, disagg_type=False) assert rib.destinations.get( unreachable_prefix)._positive_next_hops == set() assert rib.destinations.get( unreachable_prefix)._negative_next_hops == unreachable_next_hops assert rib.destinations.get(unreachable_prefix).get_next_hops == set() assert rib.fib.routes[unreachable_prefix] == "unreachable"
def test_pos_neg_disagg(): rib = Rib() default_route = RibRoute(default_prefix, S_SPF, default_next_hops) rib.put_route(default_route) leaf_route = RibRoute(leaf_prefix, S_SPF, leaf_prefix_positive_next_hops, leaf_prefix_negative_next_hops) rib.put_route(leaf_route) assert rib.destinations.get(leaf_prefix).best_route.positive_next_hops == {"M4"} assert rib.destinations.get(leaf_prefix).best_route.negative_next_hops == {"M3"} assert rib.destinations.get(leaf_prefix).best_route.next_hops == {"S4", "S3", "M4", "S2", "S1"} assert rib.fib.routes[leaf_prefix].next_hops == leaf_route.next_hops assert rib.fib.kernel.routes[leaf_prefix] == {"S4", "S3", "M4", "S2", "S1"}
def test_add_two_route_same_destination(): 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) assert rib.destinations.get(default_prefix).best_route == best_default_route assert rib.destinations.get(default_prefix).best_route.positive_next_hops == {'S1'} assert rib.destinations.get(default_prefix).best_route.negative_next_hops == set() assert rib.destinations.get(default_prefix).best_route.next_hops == {'S1'} assert rib.fib.routes[default_prefix].next_hops == best_default_route.next_hops assert rib.fib.kernel.routes[default_prefix] == best_default_route.next_hops
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) == ("")
class Peer(object): def __init__(self): self.ribs = { '172.0.0.1': Rib(ip='172.0.0.1'), '172.0.0.2': Rib(ip='172.0.0.2'), '172.0.0.3': Rib(ip='172.0.0.3'), '172.0.0.4': Rib(ip='172.0.0.4'), } self.main_rib = Rib(ip=MAIN_BGP) def configs(): """Return config all routers""" pass def update(self, ip, route): updates = [] key = {} origin = None as_path = None med = None atomic_aggregate = None community = None route_list = [] if ('state' in route['neighbor'] and route['neighbor']['state']=='down'): # Delete all routes on RIB print "STATE: Peer %(ip)s is Down" % (route['neighbor']) self.rib.delete_all() if ('update' in route['neighbor']['message']): if ('attribute' in route['neighbor']['message']['update']): attribute = route['neighbor']['message']['update']['attribute'] origin = attribute['origin'] if 'origin' in attribute else '' temp_as_path = attribute['as-path'] if 'as-path' in attribute else '' as_path = ' '.join(map(str,temp_as_path)).replace('[','').replace(']','').replace(',','') med = attribute['med'] if 'med' in attribute else '' community = attribute['community'] if 'community' in attribute else '' communities = '' for c in community: communities += ':'.join(map(str,c)) + " " atomic_aggregate = attribute['atomic-aggregate'] if 'atomic-aggregate' in attribute else '' if ('announce' in route['neighbor']['message']['update']): announce = route['neighbor']['message']['update']['announce'] if ('ipv4 unicast' in announce): for next_hop in announce['ipv4 unicast'].keys(): for prefix in announce['ipv4 unicast'][next_hop].keys(): aux = {} aux['prefix'] = prefix aux['next_hop'] = next_hop aux['med'] = med if as_path: aux['as_path'] = str(as_path) if communities: aux['communities'] = communities if LOG: print "=> NEIGHBOR: %(ip)s" % route['neighbor'] print "=> ANNOUNCE: %(prefix)s" % (aux) print "=> NEXT_HOP: %(next_hop)s" % (aux) print "=> AS_PATH: %s" % (aux.get('as_path', None)) print "=> MED: %(med)s" % (aux) print "=> COMMUNITIES: %s" % (aux.get('communities', None)) # Add or Update Announce on Rib self.ribs[ip][prefix] = aux # Add Main RIB self.main_rib.update_neighbor(prefix, aux) # Read policy and announce route to others routers using VIP command = 'neighbor %s announce route %s next-hop %s' % ('172.0.0.2', aux['prefix'], aux['next_hop']) if len(as_path) > 1: command += ' as-path [ %s ]' % (as_path) if LOG: print "SENDING ANNOUNCE TO: %s" % ('172.0.0.2') print "ROUTE %(prefix)s NEXT_HOP %(next_hop)s" % (aux) print "COMMAND: %s" % (command) # Send rule to controller OpenFlow """ announced_peers = self.sdnrouter.db_peers.find() for a_peer in announced_peers: if a_peer['IP'] == route['neighbor']['ip']: break; else: for item in a_peer['prefix']: if(item['prefix'] == aux['prefix']): continue else: command = "neighbor %s announce route %(prefix)s next-hop %(next_hop)s" % (a_peer['IP'], aux) if as_path != "": command += " as-path [ %s ]" % (as_path) if LOG: print "SENDING ANNOUNCE TO: %s" % (a_peer['IP']) print "ROUTE %(prefix)s NEXT_HOP %(next_hop)s" % (aux) print "COMMAND: %s" % command #self.sdnrouter.server_ipc.send(AGENT_SERVER_CHANNEL, AGENT_ID, command) """ elif ('withdraw' in route['neighbor']['message']['update']): withdraw = route['neighbor']['message']['update']['withdraw'] if ('ipv4 unicast' in withdraw): for prefix in withdraw['ipv4 unicast'].keys(): self.rib.delete(prefix) #self.main_rib.delete_neighbor(prefix, route['neighbor']['ip']) #deleted_route = self.rib["input"][prefix] #self.rib["input"].delete(prefix) #self.rib["input"].commit() #route_list.append({'withdraw': deleted_route}) return route_list def process_notification(self,route): if ('shutdown' == route['notification']): pass def add_route(self, rib_name, prefix, attributes): pass def add_many_routes(self, rib_name, routes): pass def get_route(self, rib_name, prefix): pass def get_routes(self, rib_name, prefix): self.ribs[rib_name].get(prefix) def get_all_routes(self, rib_name): self.ribs[rib_name].get_all() def delete_route(self,rib_name,prefix): self.ribs[rib_name].delete(prefix) def delete_all_routes(self): for rib in self.ribs: self.ribs[rib].delete_all() self.main_rib.delete_all() def filter_route(self,rib_name,item,value): pass