def external_policy(slic, policy, symm_vlan): """Produce a policy that moves packets along external ports into the vlan. Just restricting packets to the vlan means that packets can never enter the slice. To let packets enter, we need to make another copy of the policy, restrict it to only entrances, and change the actions to add the vlan. We also set packets leaving the network immediately back to 0 ARGS: slic: Slice to produce this policy for policy: Policy to restrict vlan: {edge -> vlan}, symmetric on edges: (0, 1): v => (1, 0): v. RETURNS: A policy that moves packets incoming to external ports into the vlan, but only if they satisfy the slice's isolation predicates. """ policies = [] for (s, p), pred in slic.edge_policy.items(): if edge_of_port(slic.l_topo, (s, p)) in symm_vlan: # symm_vlan contains all the internal edges to the slice. # Since we only care about incident external edges, if we're # considering an internal edge, we don't want to add any predicates. # In principle, there shouldn't be any of these pass else: # An external edge ext_pred = external_predicate((s, p), pred) & VLAN0 for (p_out, dst) in slic.l_topo.node[s]['port'].items(): if ((s, p_out), dst) in symm_vlan: # it's an internal edge target_vlan = symm_vlan[((s, p_out), dst)] new_policy = (policy % ext_pred).reduce() # modify_vlan_local does not create any new reduceables new_policy = modify_vlan_local(new_policy, (s, p_out), target_vlan, this_port_only=True) new_policy = new_policy.reduce() if new_policy != nc.BottomPolicy(): policies.append(new_policy) else: # outgoing, set it to 0 new_policy = (policy % ext_pred).reduce() new_policy = modify_vlan_local(new_policy, (s, p_out), 0, this_port_only=True) new_policy = new_policy.reduce() if new_policy != nc.BottomPolicy(): policies.append(new_policy) return policies
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