示例#1
0
 def testHostsCompileSmall(self):
     topo, combined = linear_hosts((0, 1, 2, 3), (0, 1, 2, 3))
     slices = [s for s, _ in combined]
     policy = ((nc.inport(3, 3) |then| nc.forward(3, 1)) +
               (nc.inport(3, 3) |then| nc.forward(3, 2)) +
               (nc.inport(2, 3) |then| nc.forward(2, 2)))
     combined = [(slices[0], policy), (slices[1], nc.BottomPolicy())]
     compiled, _ = ec.compile_slices(topo, combined)
     self.assertIsNone(sat.one_per_edge(topo, compiled))
     self.assertTrue(sat.compiled_correctly(topo, policy, compiled))
示例#2
0
    def test_forwards(self):
        o = Header({'switch': 2}) |then| Action(2, [1])
        r = Header({'switch': 2}) |then| Action(2, [1])
        self.assertIsNone(sat.simulates_forwards(topo, o, r))
        self.assertIsNone(sat.simulates_forwards(topo, r, o))

        o = Header({'switch': 2, 'port': 2}) |then| Action(2, [1])
        r = Header({'switch': 2, 'port': 2}) |then| Action(2, [1])
        self.assertIsNone(sat.simulates_forwards(topo, o, r))
        self.assertIsNone(sat.simulates_forwards(topo, r, o))

        o = Header({'switch': 2, 'port': 2}) |then| Action(2, [1])
        r = Header({'switch': 2, 'port': 2, 'vlan': 2}) |then| Action(2, [1])
        self.assertIsNone(sat.simulates_forwards(topo, o, r))
        self.assertIsNone(sat.simulates_forwards(topo, r, o))

        o = Header({'switch': 2, 'port': 2}) |then| forward(2, 1)
        r = Header({'switch': 2, 'port': 2, 'vlan': 2}) |then| Action(2, [1], {'vlan': 2})
        self.assertIsNone(sat.simulates_forwards(topo, o, r))
        self.assertIsNone(sat.simulates_forwards(topo, r, o))

        o = Header({'switch': 0, 'port': 1}) |then| Action(0, [1])
        r = Header({'switch': 0, 'port': 1, 'vlan': 1}) |then| Action(0, [1], {'vlan': 1})
        self.assertIsNone(sat.simulates_forwards(topo, o, r))
        self.assertIsNone(sat.simulates_forwards(topo, r, o))

        o = Header({'switch': 0, 'port': 1, 'srcmac': 32432, 'dstmac': 324322}) |then| Action(0, [1])
        r = Header({'switch': 0, 'port': 1, 'srcmac': 32432, 'dstmac': 324322, 'vlan': 1}) |then| Action(0, [1], {'vlan': 1})
        self.assertIsNone(sat.simulates_forwards(topo, o, r))
        self.assertIsNone(sat.simulates_forwards(topo, r, o))
示例#3
0
def all_pairs_shortest_path(topo, hosts_only=False):
    """Construct all-pairs-shortest-path routing policy.

    Constructs an all-pairs shortest path routing policy for topo, using each
    switch or host id number as the source and destination mac address.

    Only make paths to hosts if hosts_only

    RETURNS: a policy that implements all-pairs shortest path
    """
    forwarding_trees = []
    for source in (topo.hosts() if hosts_only else topo.nodes()):
        # For each node, build the shortest paths to that node
        # We 'start' at the node because networkx forces us to.
        paths = nx.shortest_path(topo, source=source)
        # Build next-hop table
        next_hops = {}
        for dest, path in paths.items():
            # path is a list, starting at source and ending at dest.
            if dest is not source and topo.node[dest]['isSwitch']:
                next_hops[dest] = path[-2]
        policies = []
        for node, next_node in next_hops.items():
            out_port = topo.node[node]['ports'][next_node]
            policies.append(Header({'switch': node})
                            |then| forward(node, out_port))
        forwarding_trees.append(nary_policy_union(policies)
                                % Header({'dstmac': source}))
    return nary_policy_union(forwarding_trees)
示例#4
0
    def test_one_per_edge(self):
        topo = nxtopo.NXTopo()
        topo.add_switch(1)
        topo.add_switch(2)
        topo.add_switch(3)
        topo.add_switch(4)
        topo.add_switch(5)

        topo.add_link(1, 2)
        topo.add_link(2, 3)
        topo.add_link(3, 4)
        topo.add_link(4, 5)
        topo.finalize()

        r = (Header({'switch': 2, 'port': 1, 'vlan': 2}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2))
        self.assertIsNone(sat.one_per_edge(topo, r))
        self.assertIsNotNone(sat.one_per_edge(topo, r, field='srcmac'))

        r = (Header({'switch': 2, 'port': 1, 'vlan': 1}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 1}) |then| forward(3, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2))+\
            (Header({'switch': 4, 'port': 1, 'vlan': 2}) |then| forward(4, 2))
        self.assertIsNotNone(sat.one_per_edge(topo, r))
        self.assertIsNotNone(sat.one_per_edge(topo, r, field='srcmac'))
示例#5
0
def flood(topo, all_ports=False):
    """Construct a policy that floods packets out each port on each switch.

    if all_ports is set, even forward back out the port it came in.
    """
    switches = topo.switches()
    policies = []
    for switch in switches:
        ports = set(topo.node[switch]['port'].keys())
        for port in ports:
            # Make a copy of ports without this one
            if all_ports:
                other_ports = ports
            else:
                other_ports = ports.difference([port])
            for other_port in other_ports:
                pol = inport(switch, port) |then| forward(switch, other_port)
                policies.append(pol)
    return nary_policy_union(policies).reduce()
示例#6
0
    def test_compiled_correctly(self):
        o = Header({'switch': 2, 'port': 2, 'vlan': 2}) |then| Action(2, [1])
        r = Header({'switch': 2, 'port': 2, 'vlan': 2}) |then| Action(2, [1])
        self.assertTrue(sat.compiled_correctly(topo, o, r))

        o = Header({'switch': 2, 'port': 2}) |then| Action(2, [1])
        r = Header({'switch': 2, 'port': 2, 'vlan': 2}) |then| Action(2, [1])
        self.assertTrue(sat.compiled_correctly(topo, o, r))

        o = Header({'switch': 2, 'port': 2}) |then| forward(2, 1)
        r = Header({'switch': 2, 'port': 2, 'vlan': 2})\
            |then| Action(2, [1], {'vlan': 2})
        self.assertTrue(sat.compiled_correctly(topo, o, r))

        o = Header({'switch': 1, 'port': 1}) |then| Action(1, [1])
        r = Header({'switch': 1, 'port': 1, 'vlan': 1}) |then|\
            Action(1, [1], {'vlan': 1})
        self.assertTrue(sat.compiled_correctly(topo, o, r))

        o = Header({'switch': 1, 'port': 1, 'srcmac': 33, 'dstmac': 32})\
            |then| Action(1, [1])
        r = Header({'switch': 1, 'port': 1, 'srcmac': 33, 'dstmac': 32, 'vlan': 1})\
            |then| Action(1, [1], {'vlan': 1})
        self.assertTrue(sat.compiled_correctly(topo, o, r))
示例#7
0
    def test_simulates_forwards2(self):
        o = (Header({'switch': 2, 'port': 1}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1}) |then| forward(3, 2))
        r = (Header({'switch': 2, 'port': 1, 'vlan': 2}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2))
        self.assertIsNone(sat.simulates_forwards2(topo, o, r))
        self.assertIsNotNone(sat.simulates_forwards2(topo, o, r, field='srcmac'))

        o = (Header({'switch': 2, 'port': 1, 'vlan': 1}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 1}) |then| forward(3, 2))
        r = (Header({'switch': 2, 'port': 1, 'vlan': 2}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2))
        self.assertIsNone(sat.simulates_forwards2(topo, o, r))
        self.assertIsNotNone(sat.simulates_forwards2(topo, o, r, field='srcmac'))

        # This is the corner case that demonstrates that we need to restrict
        # compiled policies to only one vlan per slice.
        o = (Header({'switch': 2, 'port': 1}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1}) |then| forward(3, 2))+\
            (Header({'switch': 4, 'port': 1}) |then| forward(4, 2))
        r = (Header({'switch': 2, 'port': 1, 'vlan': 1}) |then| forward(2, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 1}) |then| forward(3, 2))+\
            (Header({'switch': 3, 'port': 1, 'vlan': 2}) |then| forward(3, 2))+\
            (Header({'switch': 4, 'port': 1, 'vlan': 2}) |then| forward(4, 2))
        self.assertIsNone(sat.simulates_forwards(topo, o, r))
        # NOTE: We would really like this to be a failure, but it isn't.
        # Therefore, for compiler correctness, we also need one vlan per edge.
        self.assertIsNone(sat.simulates_forwards2(topo, o, r))
        self.assertIsNotNone(sat.simulates_forwards2(topo, o, r, field='srcmac'))

        # And verify that the compilation test finds this failure
        self.assertFalse(sat.compiled_correctly(topo, o, r))