def get_vlan_info(p): """Collect vlan stage information from matches/modifications in the policy. Returns a set of tuples, where each tuple is of the form (offset, nbits, total_stages) that occurred in the policy. In general there should be at most one element in this set! """ from pyretic.core.language import (parallel, sequential, DerivedPolicy, match, modify, _match, _modify) if isinstance(p, match) or isinstance(p, modify): fmap = (_match(**p.map).map if isinstance(p, match) else _modify( **p.map).map) if 'vlan_id' in fmap: if 'vlan_offset' not in fmap: print "Invalid fmap:", fmap print p return set([(fmap['vlan_offset'], fmap['vlan_nbits'], fmap['vlan_total_stages'])]) else: return set() elif isinstance(p, parallel) or isinstance(p, sequential): return reduce(lambda acc, x: acc | get_vlan_info(x), p.policies, set()) elif isinstance(p, DerivedPolicy): return get_vlan_info(p.policy) else: return set()
def get_vlan_info(p): """Collect vlan stage information from matches/modifications in the policy. Returns a set of tuples, where each tuple is of the form (offset, nbits, total_stages) that occurred in the policy. In general there should be at most one element in this set! """ from pyretic.core.language import (parallel, sequential, DerivedPolicy, match, modify, _match, _modify) if isinstance(p, match) or isinstance(p, modify): fmap = (_match(**p.map).map if isinstance(p, match) else _modify(**p.map).map) if 'vlan_id' in fmap: if 'vlan_offset' not in fmap: print "Invalid fmap:", fmap print p return set([(fmap['vlan_offset'], fmap['vlan_nbits'], fmap['vlan_total_stages'])]) else: return set() elif isinstance(p, parallel) or isinstance(p, sequential): return reduce(lambda acc, x: acc | get_vlan_info(x), p.policies, set()) elif isinstance(p, DerivedPolicy): return get_vlan_info(p.policy) else: return set()
def set_field_prereqs(p): """ Set pre-requisite fields for netkat/openflow in match dictionary. """ from pyretic.core.language import _match, union iptype_list = [('ethtype', IP_TYPE)] ethtype_list = [('ethtype', IP_TYPE), ('ethtype', ARP_TYPE)] ipproto_list = [('protocol', TCP_TYPE), ('protocol', UDP_TYPE)] ''' Check and set various pairs in the current list of field=value maps. ''' fmaps = [copy.copy(dict(_match(**p.map).map))] fmaps = reduce(lambda acc, x: acc + x, map(lambda m: check_tp_prereqs(m, iptype_list), fmaps), []) fmaps = reduce(lambda acc, x: acc + x, map(lambda m: check_ip_proto_prereq(m, iptype_list), fmaps), []) fmaps = reduce(lambda acc, x: acc + x, map(lambda m: check_ip_prereqs(m, ethtype_list), fmaps), []) assert len(fmaps) >= 1 if len(fmaps) > 1: return to_pred(union([_match(m) for m in fmaps])) else: return match_to_pred(fmaps[0])
def set_field_prereqs(p): """ Set pre-requisite fields for netkat/openflow in match dictionary. """ from pyretic.core.language import _match, union iptype_list = [('ethtype', IP_TYPE)] ethtype_list = [('ethtype', IP_TYPE), ('ethtype', ARP_TYPE)] ipproto_list = [('protocol', TCP_TYPE), ('protocol', UDP_TYPE)] ''' Check and set various pairs in the current list of field=value maps. ''' fmaps = [copy.copy(dict(_match(**p.map).map))] fmaps = reduce(lambda acc, x: acc + x, map(lambda m: check_tp_prereqs(m, iptype_list), fmaps), []) fmaps = reduce(lambda acc, x: acc+ x, map(lambda m: check_ip_proto_prereq(m, iptype_list), fmaps), []) fmaps = reduce(lambda acc, x: acc + x, map(lambda m: check_ip_prereqs(m, ethtype_list), fmaps), []) assert len(fmaps) >= 1 if len(fmaps) > 1: return to_pred(union([_match(m) for m in fmaps])) else: return match_to_pred(fmaps[0])
def reachability_inport_outheader(hsf, portids, sw_ports, insw, inport, outmatch, no_vlan=False): """Function that runs reachability from a given inport to a given output header space, represented by the `match` in outmatch. """ from pyretic.core.language import _match in_port = portids[(insw,inport)] outmat_map = dict(_match(**outmatch.map).map) outmat_wc = get_match_wc(hsf, outmat_map) outports = [] if 'switch' in outmat_map: outports_lst = get_ports(hsf, portids, sw_ports, outmat_map, outmat_map['switch']) else: outports_lst = reduce(lambda acc, sw: acc + get_ports(hsf, portids, sw_ports, outmat_map, sw), sw_ports.keys(), []) outports_str = reduce(lambda acc, x: acc + ' ' + str(x), outports_lst, '') inmat_wc = get_match_wc(hsf, {}) if no_vlan: inmat_wc = get_match_wc(hsf, {'vlan_id': 0, 'vlan_pcp': 0}) ih_str = '-ih %s' % wildcard_to_str(inmat_wc) if no_vlan else '' reachability_cmd = "%s %s -oh %s %d %s" % (PYRETIC_BINARY, ih_str, wildcard_to_str(outmat_wc), in_port, outports_str) try: result = subprocess.check_output(shlex.split(reachability_cmd), cwd=HSL_C_FOLDER) except subprocess.CalledProcessError as e: print "Could not run pyretic reachability on the inputs!" print e.returncode print e.output result = '' return result