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
Example #6
0
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")
Example #7
0
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
Example #9
0
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
Example #11
0
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")
Example #12
0
 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
Example #16
0
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
Example #26
0
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
Example #31
0
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) == ("")
Example #32
0
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