示例#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_nary_union(self):
        loc1 = nc.inport(1, 1)
        loc2 = nc.inport(2, 2)
        loc3 = nc.inport(3, 3)

        union = nc.nary_union([loc1, loc2, loc3])
        self.assertTrue(union.match(blank_packet, (1,1)))
        self.assertTrue(union.match(blank_packet, (2,2)))
        self.assertTrue(union.match(blank_packet, (3,3)))
        self.assertFalse(union.match(blank_packet, (-1,-1)))
示例#3
0
    def test_prim_phys(self):
        switch_map = {1: 100}
        port_map = {(1,2): (100, 200), (1,3): (100, 300)}
        pred = nc.inport(1, 2)
        expected_pred = nc.inport(100, 200)

        action = nc.Action(1, ports=[2])
        expected_action = nc.Action(100, ports=[200])

        policy = pred |then| action
        expected_policy = expected_pred |then| expected_action

        phys_policy = policy.get_physical_rep(switch_map, port_map)
        self.assertEqual(expected_policy, phys_policy)
示例#4
0
    def test_difference_match(self):
        loc = nc.inport(1,1)
        field = nc.Header({'srcmac': 1})
        diff = loc - field

        self.assertTrue(diff.match(fields_neg, (1, 1)))
        self.assertFalse(diff.match(fields, (-1, -1)))
        self.assertFalse(diff.match(fields, (1, 1)))
        self.assertFalse(diff.match(fields_neg, (-1, -1)))
示例#5
0
    def test_intersection_match(self):
        loc = nc.inport(1,1)
        field = nc.Header({'srcmac': 1})
        inter = loc & field

        self.assertFalse(inter.match(fields_neg, (1, 1)))
        self.assertFalse(inter.match(fields, (-1, -1)))
        self.assertTrue(inter.match(fields, (1, 1)))
        self.assertFalse(inter.match(fields_neg, (-1, -1)))
示例#6
0
    def test_union_match(self):
        loc = nc.inport(1,1)
        field = nc.Header({'srcmac': 1})
        union = loc + field

        self.assertTrue(union.match(blank_packet, (1, 1)))

        self.assertTrue(union.match(fields_neg, (1, 1)))
        self.assertTrue(union.match(fields, (-1, -1)))
        self.assertTrue(union.match(fields, (1, 1)))
        self.assertFalse(union.match(fields_neg, (-1, -1)))
示例#7
0
 def test_intersect_headers(self):
     hd = nc.Header
     bot = nc.Bottom()
     pairs = [
              (bot, exact_header, nega_header),
              (bot, exact_header, hd({'srcmac': -1})),
              (bot, exact_header, zero_header),
              (exact_header, exact_header, empty_header),
              (bot, hd({'port': 1}), hd({'port': 2})),
              (bot, inport(1,1), inport(2,2)),
              (bot, hd({'switch': 1}), hd({'switch':2})),
              (hd({}), hd({}), hd({})),
              (hd({'switch': 1}), hd({'switch': 1}), hd({})),
              (hd({'switch': 1}), hd({'switch': 1}), hd({'switch': 1})),
              (hd({'port': 1}), hd({'port': 1}), hd({})),
              (hd({'port': 1}), hd({'port': 1}), hd({'port': 1})),
              (inport(1, 1), hd({'switch': 1}), hd({'port': 1})),
             ]
     for expected, h1, h2 in pairs:
         self.assertEqual(expected, nc.intersect_headers(h1, h2))
         self.assertEqual(expected, nc.intersect_headers(h2, h1))
示例#8
0
    def test_header_loc(self):
        switch = 3
        port = 7
        header = nc.inport(switch, port)
        self.assertTrue(header.match(blank_packet, (switch, port)))
        self.assertFalse(header.match(blank_packet, (switch+1, port)))
        self.assertFalse(header.match(blank_packet, (switch, port+1)))
        self.assertFalse(header.match(blank_packet, (switch+1, port+1)))

        switch_only = nc.Header({'switch': switch})
        self.assertTrue(switch_only.match(blank_packet, (switch, 3234)))
        self.assertFalse(switch_only.match(blank_packet, (switch+1, 3234)))

        port_only = nc.Header({'port': port})
        self.assertTrue(port_only.match(blank_packet, (2345, port)))
        self.assertFalse(port_only.match(blank_packet, (2345, port+1)))
示例#9
0
def internal_policy(topo, policy, symm_vlan):
    """Produce a list of policies for slic restricted to its vlan.

    This policy must also carry the vlan tags through the network as they
    change.  These policies handle all and only packets incident to switches
    over an internal edge, and includes stripping vlan tags off them as they
    leave the network.

    ARGS:
        policy:  Policy to restrict
        vlan:  {edge -> vlan}, symmetric

    RETURNS:
        a new policy object that is policy but restricted to its vlan.
    """

#    print '========================='
#    print '========================='
#    print policy
#    print '----'
    policies = []
    # incoming edge to s1.  Note that we only get internal edges
    for ((s1, p1), (s2, p2)), tag in symm_vlan.items():
        if s1 in topo.node:
            pred = (nc.inport(s1, p1) & nc.Header({'vlan': tag})).reduce()
            # For each outgoing edge from s1, set vlan to what's appropriate
            for (p_out, dst) in topo.node[s1]['port'].items():
                if ((s1, p_out), dst) in symm_vlan:
                    target_vlan = symm_vlan[((s1, p_out), dst)]
                else:
                    target_vlan = 0
#                print '%s:%s on %s -> %s on %s' % (s1, p1, tag, p_out, target_vlan)
#                print 'restrict with %s' % pred
                new_policy = (policy % pred).reduce()
#                print new_policy
                new_policy = modify_vlan_local(new_policy, (s1, p_out),
                                               target_vlan, this_port_only=True)
                new_policy = new_policy.reduce()
#                print 'vvv'
#                print new_policy
#                print '----'
                # modify_vlan_local does not create any new reduceables
                policies.append(new_policy)
    return policies
示例#10
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()
示例#11
0
    def test_header_phys(self):
        port_map = {(1,2):(5,10)}
        switch_map = {1:5}
        loc = nc.inport(1, 2)
        phys = loc.get_physical_predicate(switch_map, port_map)
        self.assertEquals(5, phys.fields['switch'])
        self.assertEquals(10, phys.fields['port'])

        loc = nc.Header({'switch': 1})
        phys = loc.get_physical_predicate(switch_map, port_map)
        self.assertEquals(5, phys.fields['switch'])
        self.assertNotIn('port', phys.fields)

        loc = nc.Header({'port': 2})
        self.assertRaises(nc.PhysicalException,
            loc.get_physical_predicate, switch_map, port_map)

        fields = nc.Header({'srcmac': 3})
        phys = fields.get_physical_predicate(switch_map, port_map)
        self.assertEquals(fields, phys)
示例#12
0
def multicast(topo, multicast_field='dstmac', multicast_value=0):
    """Construct a policy that multicasts packets to all nodes along the MST.

    Uses multicast_field:multicast_value to recognize multicast packets to send
    along the minimum spanning tree.
    """
    mst = nx.minimum_spanning_tree(topo)
    edges = set(mst.edges())
    for (n1, n2) in list(edges):
        edges.add((n2, n1))
    policies = []
    for node in topo.switches():
        ports = set()
        for switch, port in topo.node[node]['ports'].items():
            # If this link is in the MST
            if (node, switch) in edges:
                ports.add(port)
        for port in ports:
            others = ports.difference([port])
            policies.append(inport(node, port) |then| Action(node, others))
    return (nary_policy_union(policies)
            % Header({multicast_field: multicast_value}))
示例#13
0
def flood_observe(topo, label=None, all_ports=False):
    """Construct a policy that floods packets and observes at the leaves.

    Sequentially assigns labels if none is set.  Not thread-safe.
    """
    if label is None:
        global next_label
        label = next_label
        next_label += 1
    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|\
                      Action(switch, ports=[other_port], obs=[label])
                policies.append(pol)
    return nary_policy_union(policies).reduce()
示例#14
0
        a new policy object that is policy but restricted to its vlan.
    """
    vlan_predicate = nc.Header({'vlan': vlan})
    return policy % vlan_predicate

def external_predicate((switch, port), predicate):
    """Produce a predicate that matches predicate incoming on (switch, port).

    ARGS:
        (switch, port):  precise network location of incoming port
        predicate:  isolation predicate to satisfy

    RETURNS:
        Predicate object matching predicate on switch and port.
    """
    return nc.inport(switch, port) & predicate

def modify_vlan(policy, vlan):
    """Re-write all actions of policy to set vlan to vlan."""
    if isinstance(policy, nc.BottomPolicy):
        # Bottom policy, contains no actions
        return policy
    elif isinstance(policy, nc.PrimitivePolicy):
        policy = copy.deepcopy(policy)
        for action in policy.actions:
            action.modify['vlan'] = vlan
        return policy
    elif isinstance(policy, nc.PolicyUnion):
        left = modify_vlan(policy.left, vlan)
        right = modify_vlan(policy.right, vlan)
        return left + right
示例#15
0
 def testOutputOverlap(self):
     p1 = nc.inport(0, 1) |then| nc.Action(0, [2], {'vlan': 0, 'srcmac': 1})
     p2 = nc.inport(0, 1) |then| nc.Action(0, [2], {'vlan': 0, 'srcmac': 1})
     self.assertIsNotNone(sat.shared_outputs(p1, p2))
示例#16
0
# Tests for compile.py, which implements the slice compiler                    #
################################################################################
import compile as cp
import copy
import netcore as nc
from netcore import Action, inport, Header, then
import slicing
import unittest

a1 = Action(1, [1, 2, 3], {'srcmac':1})
a2 = Action(2, [2, 3], {'dstmac':2}, set([1, 2, 3]))
a3 = Action(3, [3], {'ethtype':3})
a4 = Action(3, [4, 5, 6], {'srcip':4})
a5 = Action(3, [3, 5, 6, 7], {'vlan':5})

p1 = inport(1, 0)
p2 = inport(2, 1) + inport(2, 3)
p3 = inport(3, 3) & Header({'srcmac': 1})
p4 = p3 - Header({'dstmac': 2})

l1 = p1 |then| a1
l2 = p2 |then| a2
l3 = p3 |then| a3
l4 = p4 |then| a4
l5 = (p1 & p4) |then| a5

big_policy = ((l3 + l4 + l5) % p2) + l2 + l1

def actions_of_policy(policy):
    if isinstance(policy, nc.PrimitivePolicy):
        return policy.actions