def _build_group_flood_rules(self, vlan, modify, command): """Build flooding rules for a VLAN using groups.""" _, vlan_flood_acts = self._build_flood_rule_for_vlan( vlan, None, None, None, False, command) group_id = vlan.vid group = self.groups.get_entry( group_id, valve_of.build_group_flood_buckets(vlan_flood_acts)) groups_by_unicast_eth = {False: group, True: group} ofmsgs = [] # Only configure unicast flooding group if has different output # actions to non unicast flooding. _, unicast_eth_vlan_flood_acts = self._build_flood_rule_for_vlan( vlan, None, None, None, True, command) unicast_eth_vlan_flood_acts, unicast_output_ports, _ = valve_of.output_non_output_actions( unicast_eth_vlan_flood_acts) vlan_flood_acts, vlan_output_ports, _ = valve_of.output_non_output_actions( vlan_flood_acts) if unicast_output_ports != vlan_output_ports: group_id += valve_of.VLAN_GROUP_OFFSET group = self.groups.get_entry( group_id, valve_of.build_group_flood_buckets( unicast_eth_vlan_flood_acts)) groups_by_unicast_eth[True] = group for group in groups_by_unicast_eth.values(): if modify: ofmsgs.append(group.modify()) else: ofmsgs.extend(group.add()) for unicast_eth_dst, eth_type, eth_dst, eth_dst_mask in self.flood_dsts: if unicast_eth_dst and not vlan.unicast_flood: continue group = groups_by_unicast_eth[unicast_eth_dst] match = self.flood_table.match(vlan=vlan, eth_type=eth_type, eth_dst=eth_dst, eth_dst_mask=eth_dst_mask) flood_priority = self._vlan_flood_priority(eth_type, eth_dst_mask) ofmsgs.append( self.flood_table.flowmod( match=match, command=command, inst=[ valve_of.apply_actions( [valve_of.group_act(group.group_id)]) ], priority=flood_priority)) return ofmsgs
def _build_flood_acts_for_port(self, vlan, exclude_unicast, port, # pylint: disable=too-many-arguments exclude_all_external=False, exclude_restricted_bcast_arpnd=False): flood_acts = () port_output_ports = [] port_non_output_acts = [] if port.dyn_phys_up: if exclude_restricted_bcast_arpnd: flood_acts = self._build_flood_rule_actions( vlan, exclude_unicast, port, exclude_all_external, port.restricted_bcast_arpnd) else: flood_acts = self._build_flood_rule_actions( vlan, exclude_unicast, port, exclude_all_external, False) (flood_acts, port_output_ports, port_non_output_acts) = valve_of.output_non_output_actions(flood_acts) if not port_output_ports: flood_acts = () port_non_output_acts = () return (flood_acts, port_output_ports, port_non_output_acts)
def _build_mask_flood_rules(self, vlan, eth_type, eth_dst, eth_dst_mask, # pylint: disable=too-many-arguments exclude_unicast, exclude_restricted_bcast_arpnd, command, cold_start): ofmsgs = [] if self.combinatorial_port_flood: for port in self._vlan_all_ports(vlan, exclude_unicast): flood_acts, _, _ = self._build_flood_acts_for_port( vlan, exclude_unicast, port, exclude_restricted_bcast_arpnd=exclude_restricted_bcast_arpnd) if flood_acts: ofmsgs.append(self._build_flood_rule_for_port( vlan, eth_type, eth_dst, eth_dst_mask, command, port, flood_acts)) else: vlan_flood_ofmsg, vlan_flood_acts = self._build_flood_rule_for_vlan( vlan, eth_type, eth_dst, eth_dst_mask, exclude_unicast, command) if not self.use_group_table: ofmsgs.append(vlan_flood_ofmsg) (flood_acts, vlan_output_ports, vlan_non_output_acts) = valve_of.output_non_output_actions(vlan_flood_acts) for port in self._vlan_all_ports(vlan, exclude_unicast): (flood_acts, port_output_ports, port_non_output_acts) = self._build_flood_acts_for_port( vlan, exclude_unicast, port, exclude_restricted_bcast_arpnd=exclude_restricted_bcast_arpnd) if not flood_acts: continue if (vlan_output_ports - set([port.number]) == port_output_ports and vlan_non_output_acts == port_non_output_acts): # Delete a potentially existing port specific flow # TODO: optimize, avoid generating delete for port if no existing flow. if not cold_start: flood_priority, match = self._build_flood_match_priority( port, vlan, eth_type, eth_dst, eth_dst_mask, add_match=None) ofmsgs.append(self.flood_table.flowdel( match=match, priority=flood_priority)) else: ofmsgs.append(self._build_flood_rule_for_port( vlan, eth_type, eth_dst, eth_dst_mask, command, port, flood_acts)) return ofmsgs