def _sequence_actions(self, a1, as2): from pyretic.core.language import modify, drop, identity, Controller, CountBucket, DerivedPolicy while isinstance(a1, DerivedPolicy): a1 = a1.policy # TODO: be uniform about returning copied or modified objects. new_actions = [] if a1 == drop: return [drop] elif a1 == identity: return as2 elif a1 == Controller or isinstance(a1, CountBucket): return [a1] elif isinstance(a1, modify): for a2 in as2: while isinstance(a2, DerivedPolicy): a2 = a2.policy new_a1 = modify(**a1.map.copy()) if a2 == drop: new_actions.append(drop) elif a2 == Controller or isinstance(a2, CountBucket): new_actions.append(a2) elif a2 == identity: new_actions.append(new_a1) elif isinstance(a2, modify): new_a1.map.update(a2.map) new_actions.append(new_a1) elif isinstance(a2, fwd): new_a1.map['outport'] = a2.outport new_actions.append(new_a1) else: raise TypeError return new_actions else: raise TypeError
def _sequence_actions(a1, as2): while isinstance(a1, DerivedPolicy): a1 = a1.policy # TODO: be uniform about returning copied or modified objects. if a1 == Controller or isinstance(a1, CountBucket): return {a1} elif a1 == identity: return copy.copy(as2) elif isinstance(a1, modify): new_actions = set() for a2 in as2: while isinstance(a2, DerivedPolicy): a2 = a2.policy if a2 == Controller or isinstance(a2, CountBucket): new_actions.add(a2) elif a2 == identity: new_actions.add(a1) elif isinstance(a2, modify): new_a1 = modify(**a1.map.copy()) new_a1.map.update(a2.map) new_actions.add(new_a1) else: raise TypeError return new_actions else: raise TypeError
def _sequence_actions(self, a1, as2): from pyretic.core.language import modify, drop, identity, Controller, CountBucket, DerivedPolicy while isinstance(a1, DerivedPolicy): a1 = a1.policy # TODO: be uniform about returning copied or modified objects. new_actions = [] if a1 == drop: return [drop] elif a1 == identity: return as2 elif a1 == Controller or isinstance(a1, CountBucket): return [a1] elif isinstance(a1, modify): for a2 in as2: while isinstance(a2, DerivedPolicy): a2 = a2.policy new_a1 = modify(**a1.map.copy()) if a2 == drop: new_actions.append(drop) elif a2 == Controller or isinstance(a2, CountBucket): new_actions.append(a2) elif a2 == identity: new_actions.append(new_a1) elif isinstance(a2, modify): new_a1.map.update(a2.map) new_actions.append(new_a1) elif isinstance(a2, fwd): new_a1.map["outport"] = a2.outport new_actions.append(new_a1) else: raise TypeError return new_actions else: raise TypeError
def adjust_vlan_fields(mat, acts): """Since netKAT is lazy about adding modifications whenever there is a match on the same value, we add the matched value again whenever exactly one of the vlan ID or PCP fields is missing. Setting both ID and PCP is required by the pox_client to ensure simple and correct operation of the metadata register. """ from pyretic.core.language import modify new_acts = [] for act in acts: new_act = act if isinstance(act, modify): m = copy.copy(act.map) if 'vlan_id' in m and not 'vlan_pcp' in m: assert 'vlan_pcp' in mat.map m['vlan_pcp'] = mat.map['vlan_pcp'] new_act = modify(**m) elif 'vlan_pcp' in m and not 'vlan_id' in m: assert 'vlan_id' in mat.map m['vlan_id'] = mat.map['vlan_id'] new_act = modify(**m) new_acts.append(new_act) return set(new_acts)
def _sequence_actions(a1, as2): from pyretic.core.language import (match, modify, drop, identity, Controller, CountBucket, DerivedPolicy, PathBucket) from pyretic.lib.netflow import NetflowBucket while isinstance(a1, DerivedPolicy): a1 = a1.policy # TODO: be uniform about returning copied or modified objects. if (a1 == Controller or isinstance(a1, CountBucket) or isinstance(a1, PathBucket) or isinstance(a1, NetflowBucket)): return {a1} elif a1 == identity: return copy.copy(as2) elif isinstance(a1, modify): new_actions = set() for a2 in as2: while isinstance(a2, DerivedPolicy): a2 = a2.policy if (a2 == Controller or isinstance(a2, CountBucket) or isinstance(a2, PathBucket) or isinstance(a2, NetflowBucket)): new_actions.add(a2) elif a2 == identity: new_actions.add(a1) elif isinstance(a2, modify): new_a1_map = a1.map.copy() new_a1_map.update(a2.map) new_actions.add(modify(**new_a1_map)) # TODO(ngsrinivas): remove later if no issues # new_a1 = modify(**a1.map.copy()) # new_a1.map.update(a2.map) # new_actions.add(new_a1) else: raise TypeError return new_actions else: raise TypeError
def create_action(action, multistage): from pyretic.core.language import (modify, Controller, identity) if len(action) == 0: return set() else: res = set() for act_list in action: mod_dict = {} for act in act_list: if act[0] == "Modify": hdr_field = act[1][0][3:] if hdr_field == "Vlan" or hdr_field == "VlanPcp": hdr_field = 'dl' + hdr_field else: hdr_field = hdr_field[0].lower() + hdr_field[1:] hdr_field = field_map[hdr_field] value = act[1][1] if hdr_field == 'srcmac' or hdr_field == 'dstmac': value = MAC(value) mod_dict[hdr_field] = value elif act[0] == "Output": outout_seen = True out_info = act[1] if out_info['type'] == 'physical': mod_dict['port'] = out_info['port'] elif out_info['type'] == 'controller': res.add(Controller) elif out_info['type'] == 'inport' and not multistage: mod_dict['port'] = OFPP_IN_PORT if len(mod_dict) > 0: res.add(modify(**mod_dict)) if len(res) == 0: res.add(identity) return res
def create_action(action, multistage, vlan_offset_nbits): """ Return value: (action list, suspicious_vlan_bool) """ from pyretic.core.language import (modify, Controller, identity) if len(action) == 0: return (set(), False) else: res = set() suspicious_vlan = False for act_list in action: mod_dict = {} vlan_processed = False vlans_processed = False for act in act_list: if act[0] == "Modify": hdr_field = act[1][0][3:] if hdr_field == "Vlan" or hdr_field == "VlanPcp": hdr_field = 'dl' + hdr_field else: hdr_field = hdr_field[0].lower() + hdr_field[1:] hdr_field = field_map[hdr_field] value = act[1][1] if hdr_field == 'srcmac' or hdr_field == 'dstmac': value = MAC(value) mod_dict[hdr_field] = value elif hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp': mod_dict[hdr_field] = value if vlan_processed: """ Only write both values to None if *both* vlan id and pcp fields contain respective None values. """ if (mod_dict['vlan_pcp'] == VLAN_PCP_NONE_VALUE and mod_dict['vlan_id'] == VLAN_NONE_VALUE): mod_dict['vlan_pcp'] = None mod_dict['vlan_id'] = None vlans_processed = True vlan_processed = True else: mod_dict[hdr_field] = value # Add auxiliary information for VLAN modifications if hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp': mod_dict['vlan_offset'] = vlan_offset_nbits[ 'vlan_offset'] mod_dict['vlan_nbits'] = vlan_offset_nbits[ 'vlan_nbits'] mod_dict['vlan_total_stages'] = vlan_offset_nbits[ 'vlan_total_stages'] elif act[0] == "Output": outout_seen = True out_info = act[1] if out_info['type'] == 'physical': mod_dict['port'] = out_info['port'] elif out_info['type'] == 'controller': res.add(Controller) elif out_info['type'] == 'inport' and not multistage: mod_dict['port'] = OFPP_IN_PORT if len(mod_dict) > 0: if (((not 'vlan_id' in mod_dict) and 'vlan_pcp' in mod_dict) or ((not 'vlan_pcp' in mod_dict) and 'vlan_id' in mod_dict)): suspicious_vlan = True res.add(modify(**mod_dict)) if len(res) == 0: res.add(identity) return (res, suspicious_vlan)
def create_action(action, multistage, vlan_offset_nbits): """ Return value: (action list, suspicious_vlan_bool) """ from pyretic.core.language import (modify, Controller, identity) if len(action) == 0: return (set(), False) else: res = set() suspicious_vlan = False for act_list in action: mod_dict = {} vlan_processed = False vlans_processed = False for act in act_list: if act[0] == "Modify": hdr_field = act[1][0][3:] if hdr_field == "Vlan" or hdr_field == "VlanPcp": hdr_field = 'dl' + hdr_field else: hdr_field = hdr_field[0].lower() + hdr_field[1:] hdr_field = field_map[hdr_field] value = act[1][1] if hdr_field == 'srcmac' or hdr_field == 'dstmac': value = MAC(value) mod_dict[hdr_field] = value elif hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp': mod_dict[hdr_field] = value if vlan_processed: """ Only write both values to None if *both* vlan id and pcp fields contain respective None values. """ if (mod_dict['vlan_pcp'] == VLAN_PCP_NONE_VALUE and mod_dict['vlan_id'] == VLAN_NONE_VALUE): mod_dict['vlan_pcp'] = None mod_dict['vlan_id'] = None vlans_processed = True vlan_processed = True else: mod_dict[hdr_field] = value # Add auxiliary information for VLAN modifications if hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp': mod_dict['vlan_offset'] = vlan_offset_nbits['vlan_offset'] mod_dict['vlan_nbits'] = vlan_offset_nbits['vlan_nbits'] mod_dict['vlan_total_stages'] = vlan_offset_nbits['vlan_total_stages'] elif act[0] == "Output": outout_seen = True out_info = act[1] if out_info['type'] == 'physical': mod_dict['port'] = out_info['port'] elif out_info['type'] == 'controller': res.add(Controller) elif out_info['type'] == 'inport' and not multistage: mod_dict['port'] = OFPP_IN_PORT if len(mod_dict) > 0: if (((not 'vlan_id' in mod_dict) and 'vlan_pcp' in mod_dict) or ((not 'vlan_pcp' in mod_dict) and 'vlan_id' in mod_dict)): suspicious_vlan = True res.add(modify(**mod_dict)) if len(res) == 0: res.add(identity) return (res, suspicious_vlan)