def _nexthop_group_buckets(self, vlan, port, eth_src): actions = self._nexthop_actions(eth_src, vlan) if not vlan.port_is_tagged(port): actions.append(valve_of.pop_vlan()) actions.append(valve_of.output_port(port.number)) buckets = [valve_of.bucket(actions=actions)] return buckets
def add_port(self, port): """Add flows to allow coprocessor to inject or output packets.""" ofmsgs = [] if port.coprocessor: ofmsgs.append( self.vlan_table.flowmod( self.vlan_table.match(in_port=port.number), priority=self.low_priority, inst=(self.vlan_table.goto(self.copro_table), ))) ofmsgs.append( self.eth_src_table.flowmod( match=self.eth_src_table.match(in_port=port.number), priority=self.high_priority, inst=(self.eth_src_table.goto(self.output_table), ))) # TODO: add additional output port strategies (eg. MPLS) and tagged ports vlan_vid_base = port.coprocessor.get('vlan_vid_base', 0) for port_number in self.ports: inst = (valve_of.apply_actions( (valve_of.pop_vlan(), valve_of.output_port(port_number))), ) vid = vlan_vid_base + port_number vlan = OFVLAN(str(vid), vid) match = self.copro_table.match(vlan=vlan) ofmsgs.append( self.copro_table.flowmod(match=match, priority=self.high_priority, inst=inst)) return ofmsgs
def output_port(self, port, hairpin=False): actions = port.mirror_actions() if self.port_is_untagged(port): actions.append(valve_of.pop_vlan()) if hairpin: actions.append(valve_of.output_port(valve_of.OFP_IN_PORT)) else: actions.append(valve_of.output_port(port.number)) return actions
def output_port(self, port, hairpin=False): actions = port.mirror_actions() if self.port_is_untagged(port): actions.append(valve_of.pop_vlan()) if hairpin: actions.append(valve_of.output_port(valve_of.OFP_IN_PORT)) else: actions.append(valve_of.output_port(port.number)) return actions
def _build_flood_local_rule_actions(self, vlan, exclude_unicast, in_port): flood_acts = [] tagged_ports = vlan.tagged_flood_ports(exclude_unicast) flood_acts.extend(self._build_flood_port_outputs( tagged_ports, in_port)) untagged_ports = vlan.untagged_flood_ports(exclude_unicast) if untagged_ports: flood_acts.append(valve_of.pop_vlan()) flood_acts.extend(self._build_flood_port_outputs( untagged_ports, in_port)) return flood_acts
def output_port(self, port, hairpin=False, output_table=None, loop_protect_field=None): actions = port.mirror_actions() if self.port_is_untagged(port): actions.append(valve_of.pop_vlan()) elif loop_protect_field is not None: actions.append(output_table.set_field(**{STACK_LOOP_PROTECT_FIELD: loop_protect_field})) if hairpin: actions.append(valve_of.output_port(valve_of.OFP_IN_PORT)) else: actions.append(valve_of.output_port(port.number)) return actions
def build_port_out_inst(self, vlan, port): dst_act = [] if not vlan.port_is_tagged(port.number) and port.stack is None: dst_act.append(valve_of.pop_vlan()) dst_act.append(valve_of.output_port(port.number)) if port.mirror is not None: mirror_acts = [valve_of.output_port(port.mirror)] dst_act.extend(mirror_acts) return [valve_of.apply_actions(dst_act)]
def _build_group_buckets(self, vlan, unicast_flood): buckets = [] for port in vlan.tagged_flood_ports(unicast_flood): buckets.append(valve_of.bucket( actions=[valve_of.output_port(port.number)])) for port in vlan.untagged_flood_ports(unicast_flood): buckets.append(valve_of.bucket( actions=[ valve_of.pop_vlan(), valve_of.output_port(port.number)])) return buckets
def _add_egress_table_rule(self, port, vlan, pop_vlan=True): metadata, metadata_mask = faucet_md.get_egress_metadata( port.number, vlan.vid) actions = copy.copy(port.mirror_actions()) if pop_vlan: actions.append(valve_of.pop_vlan()) actions.append(valve_of.output_port(port.number)) inst = (valve_of.apply_actions(tuple(actions)), ) return self.egress_table.flowmod(self.egress_table.match( vlan=vlan, metadata=metadata, metadata_mask=metadata_mask), priority=self.dp.high_priority, inst=inst)
def output_port(self, port, hairpin=False): actions = [] # If port should mirror add output to mirror ports if port.mirror is not None: for mirror_port in port.mirror: actions.append(valve_of.output_port(mirror_port)) if self.port_is_untagged(port): actions.append(valve_of.pop_vlan()) if hairpin: actions.append(valve_of.output_port(valve_of.OFP_IN_PORT)) else: actions.append(valve_of.output_port(port.number)) return actions
def build_ordered_output_actions(acl_table, output_list, tunnel_rules=None, source_id=None): """Build actions from ordered ACL output list""" output_actions = [] output_ports = [] output_ofmsgs = [] output_inst = [] for action in output_list: for key, value in action.items(): if key == 'pop_vlans': for _ in range(value): output_actions.append(valve_of.pop_vlan()) if key == 'vlan_vid': output_actions.extend(push_vlan(acl_table, value)) if key == 'swap_vid': output_actions.append(acl_table.set_vlan_vid(value)) if key == 'vlan_vids': for vlan_vid in value: output_actions.extend(push_vlan(acl_table, vlan_vid)) if key == 'set_fields': for set_field in value: output_actions.append(acl_table.set_field(**set_field)) if key == 'port': output_ports.append(value) output_actions.append(valve_of.output_port(value)) if key == 'ports': for output_port in value: output_ports.append(output_port) output_actions.append(valve_of.output_port(output_port)) if key == 'failover': group_id = value['group_id'] buckets = [] for port in value['ports']: buckets.append( valve_of.bucket(watch_port=port, actions=[valve_of.output_port(port)])) output_ofmsgs.extend( valve_of.groupadd_ff(group_id=group_id, buckets=buckets)) output_actions.append(valve_of.group_act(group_id=group_id)) if key == 'tunnel' and tunnel_rules and source_id is not None: source_rule = tunnel_rules[value][source_id] _, tunnel_actions, tunnel_ofmsgs, tunnel_inst = build_output_actions( acl_table, source_rule) output_actions.extend(tunnel_actions) output_ofmsgs.extend(tunnel_ofmsgs) output_inst.extend(tunnel_inst) if key == 'goto': output_inst.append(valve_of.goto_table_id(value)) return (output_ports, output_actions, output_ofmsgs, output_inst)
def build_port_out_inst(self, vlan, port, port_number=None): """Return instructions to output a packet on a given port.""" if port_number is None: port_number = port.number dst_act = [] if not vlan.port_is_tagged(port) and port.stack is None: dst_act.append(valve_of.pop_vlan()) dst_act.append(valve_of.output_port(port_number)) if port.mirror is not None: mirror_acts = [valve_of.output_port(port.mirror)] dst_act.extend(mirror_acts) return [valve_of.apply_actions(dst_act)]
def rewrite_vlan(output_dict): vlan_actions = [] if 'pop_vlans' in output_dict: for _ in range(output_dict['pop_vlans']): vlan_actions.append(valve_of.pop_vlan()) # if vlan tag is specified, push it. if 'vlan_vid' in output_dict: vlan_actions.extend( valve_of.push_vlan_act(output_dict['vlan_vid'])) # or, if a list, push them all (all with type Q). elif 'vlan_vids' in output_dict: for vid in output_dict['vlan_vids']: vlan_actions.extend(valve_of.push_vlan_act(vid)) return vlan_actions
def output_port(self, port, hairpin=False, output_table=None, loop_protect_field=None): actions = port.mirror_actions() if self.port_is_untagged(port): actions.append(valve_of.pop_vlan()) elif loop_protect_field is not None: actions.append( output_table.set_field( **{STACK_LOOP_PROTECT_FIELD: loop_protect_field})) if hairpin: actions.append(valve_of.output_port(valve_of.OFP_IN_PORT)) else: actions.append(valve_of.output_port(port.number)) return actions
def rewrite_vlan(output_dict): """Implement actions to rewrite VLAN headers.""" vlan_actions = [] if 'pop_vlans' in output_dict: for _ in range(output_dict['pop_vlans']): vlan_actions.append(valve_of.pop_vlan()) # if vlan tag is specified, push it. if 'vlan_vid' in output_dict: vlan_actions.extend(push_vlan(output_dict['vlan_vid'])) # swap existing VID elif 'swap_vid' in output_dict: vlan_actions.append(valve_of.set_vlan_vid(output_dict['swap_vid'])) # or, if a list, push them all (all with type Q). elif 'vlan_vids' in output_dict: for vlan_vid in output_dict['vlan_vids']: vlan_actions.extend(push_vlan(vlan_vid)) return vlan_actions
def _add_egress_table_rule(self, port, vlan, pop_vlan=True): metadata, metadata_mask = faucet_md.get_egress_metadata( port.number, vlan.vid) actions = copy.copy(port.mirror_actions()) if pop_vlan: actions.append(valve_of.pop_vlan()) actions.append(valve_of.output_port(port.number)) inst = [valve_of.apply_actions(actions)] return self.egress_table.flowmod( self.egress_table.match( vlan=vlan, metadata=metadata, metadata_mask=metadata_mask ), priority=self.dp.high_priority, inst=inst )
def rewrite_vlan(acl_table, output_dict): """Implement actions to rewrite VLAN headers.""" vlan_actions = [] if 'pop_vlans' in output_dict: for _ in range(output_dict['pop_vlans']): vlan_actions.append(valve_of.pop_vlan()) # if vlan tag is specified, push it. if 'vlan_vid' in output_dict: vlan_actions.extend(push_vlan(acl_table, output_dict['vlan_vid'])) # swap existing VID elif 'swap_vid' in output_dict: vlan_actions.append( acl_table.set_vlan_vid(output_dict['swap_vid'])) # or, if a list, push them all (all with type Q). elif 'vlan_vids' in output_dict: for vlan_vid in output_dict['vlan_vids']: vlan_actions.extend(push_vlan(acl_table, vlan_vid)) return vlan_actions
def output_port(self, port, hairpin=False, output_table=None, external_forwarding_requested=None): actions = [] if self.port_is_untagged(port): actions.append(valve_of.pop_vlan()) # Packet is mirrored, as the receiving host sees it (without a tag). actions.extend(port.mirror_actions()) else: actions.extend(port.mirror_actions()) if external_forwarding_requested is not None: if external_forwarding_requested: actions.append(output_table.set_external_forwarding_requested()) else: actions.append(output_table.set_no_external_forwarding_requested()) if hairpin: actions.append(valve_of.output_port(valve_of.OFP_IN_PORT)) else: actions.append(valve_of.output_port(port.number)) return actions
def _output_non_output_actions(flood_acts): output_ports = set() all_nonoutput_actions = set() deduped_acts = [] # avoid dedupe_ofmsgs() here, as it's expensive - most of the time we are comparing # port numbers as integers which is much cheaper. for act in flood_acts: if valve_of.is_output(act): if act.port in output_ports: continue output_ports.add(act.port) else: str_act = str(act) if str_act in all_nonoutput_actions: continue all_nonoutput_actions.add(str_act) deduped_acts.append(act) nonoutput_actions = all_nonoutput_actions - set([str(valve_of.pop_vlan())]) return (deduped_acts, output_ports, nonoutput_actions)
def _output_non_output_actions(flood_acts): output_ports = set() all_nonoutput_actions = set() deduped_acts = [] # avoid dedupe_ofmsgs() here, as it's expensive - most of the time we are comparing # port numbers as integers which is much cheaper. for act in flood_acts: if valve_of.is_output(act): if act.port in output_ports: continue output_ports.add(act.port) else: str_act = str(act) if str_act in all_nonoutput_actions: continue all_nonoutput_actions.add(str_act) deduped_acts.append(act) nonoutput_actions = all_nonoutput_actions - set([str(valve_of.pop_vlan())]) return (deduped_acts, output_ports, nonoutput_actions)
def output_port(self, port, hairpin=False, output_table=None, loop_protect_field=None): actions = [] if self.port_is_untagged(port): actions.append(valve_of.pop_vlan()) # Packet is mirrored, as the receiving host sees it (without a tag). actions.extend(port.mirror_actions()) else: actions.extend(port.mirror_actions()) if loop_protect_field is not None: actions.append( output_table.set_field( **{STACK_LOOP_PROTECT_FIELD: loop_protect_field})) if hairpin: actions.append(valve_of.output_port(valve_of.OFP_IN_PORT)) else: actions.append(valve_of.output_port(port.number)) return actions