def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host): learn_connected_priority = self.route_priority + faucet_vip.network.prefixlen ofmsgs = [] ofmsgs.append( self.eth_src_table.flowmod( self.eth_src_table.match(eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, vlan=vlan), priority=self.route_priority, inst=[valve_of.goto_table(self.fib_table)])) ofmsgs.append( self.fib_table.flowmod(self.fib_table.match( eth_type=self.ETH_TYPE, vlan=vlan, nw_dst=faucet_vip_host), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) if self.proactive_learn: for routed_vlan in self._routed_vlans(vlan): ofmsgs.append( self.fib_table.flowmod( self.fib_table.match(eth_type=self.ETH_TYPE, vlan=routed_vlan, nw_dst=faucet_vip), priority=learn_connected_priority, inst=[valve_of.goto_table(self.vip_table)])) ofmsgs.append( self.vip_table.flowcontroller( self.vip_table.match(eth_type=self.ETH_TYPE), priority=priority - 1, max_len=self.MAX_LEN)) return ofmsgs
def build_acl(acl, vid=None): """Check that ACL can be built from config and mark mirror destinations.""" if acl.rules: null_dp = namedtuple('null_dp', 'ofproto') null_dp.ofproto = valve_of.ofp try: ofmsgs = valve_acl.build_acl_ofmsgs( [acl], self.wildcard_table, valve_of.goto_table(self.wildcard_table), valve_of.goto_table(self.wildcard_table), 2**16 - 1, self.meters, acl.exact_match, vlan_vid=vid) assert ofmsgs for ofmsg in ofmsgs: ofmsg.datapath = null_dp ofmsg.set_xid(0) ofmsg.serialize() except (AddrFormatError, KeyError, ValueError) as err: raise InvalidConfigError(err) for port_no in mirror_destinations: port = self.ports[port_no] port.output_only = True
def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host): learn_connected_priority = self.route_priority + faucet_vip.network.prefixlen faucet_mac = vlan.faucet_mac insts = [valve_of.goto_table(self.fib_table)] if self._global_routing(): vlan_mac = valve_packet.int_in_mac(faucet_mac, vlan.vid) insts = [valve_of.apply_actions([ valve_of.set_eth_dst(vlan_mac), valve_of.set_vlan_vid(self.global_vlan.vid)])] + insts ofmsgs = [] ofmsgs.append(self.eth_src_table.flowmod( self.eth_src_table.match(eth_type=self.ETH_TYPE, eth_dst=faucet_mac, vlan=vlan), priority=self.route_priority, inst=insts)) routed_vlans = self._routed_vlans(vlan) if self._global_routing(): vlan = self.global_vlan ofmsgs.append(self.fib_table.flowmod( self._route_match(vlan, faucet_vip_host), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) if self.proactive_learn and not faucet_vip.ip.is_link_local: for routed_vlan in routed_vlans: ofmsgs.append(self.fib_table.flowmod( self._route_match(routed_vlan, faucet_vip), priority=learn_connected_priority, inst=[valve_of.goto_table(self.vip_table)])) ofmsgs.append(self.vip_table.flowcontroller( self.vip_table.match(eth_type=self.ETH_TYPE), priority=priority-1, max_len=self.MAX_LEN)) return ofmsgs
def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host): ofmsgs = [] ofmsgs.append( self.eth_src_table.flowmod( self.eth_src_table.match(eth_type=valve_of.ether.ETH_TYPE_ARP, vlan=vlan), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) ofmsgs.append( self.vip_table.flowmod( self.vip_table.match(eth_type=valve_of.ether.ETH_TYPE_ARP), priority=priority, inst=[valve_of.goto_table(self.eth_dst_table)])) priority += 1 ofmsgs.append( self.vip_table.flowmod( self.vip_table.match(eth_type=valve_of.ether.ETH_TYPE_ARP, eth_dst=valve_of.mac.BROADCAST_STR), priority=priority, inst=[valve_of.goto_table(self.flood_table)])) priority += 1 ofmsgs.append( self.vip_table.flowcontroller(self.vip_table.match( eth_type=valve_of.ether.ETH_TYPE_ARP, nw_dst=faucet_vip_host), priority=priority, max_len=self.MAX_LEN)) return ofmsgs
def _add_faucet_vip_nd(self, vlan, priority, faucet_vip, faucet_vip_host): faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast( valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip)) controller_and_flood = [ valve_of.apply_actions([valve_of.output_controller()]), valve_of.goto_table(self.flood_table) ] ofmsgs = [] ofmsgs.append( self.vip_table.flowcontroller(self.vip_table.match( eth_type=self.ETH_TYPE, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST), priority=priority, max_len=self.MAX_LEN)) # IPv6 ND for FAUCET VIP ofmsgs.append( self.eth_src_table.flowmod( self.eth_src_table.match(eth_type=self.ETH_TYPE, eth_dst=faucet_vip_host_nd_mcast, vlan=vlan), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) ofmsgs.append( self.vip_table.flowmod(self.vip_table.match( eth_type=self.ETH_TYPE, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT), priority=priority, inst=controller_and_flood)) # IPv6 ND for connected hosts. ofmsgs.append( self.vip_table.flowcontroller(self.vip_table.match( eth_type=self.ETH_TYPE, eth_dst=vlan.faucet_mac, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT), priority=priority, max_len=self.MAX_LEN)) if faucet_vip.ip in valve_packet.IPV6_LINK_LOCAL: ofmsgs.append( self.eth_src_table.flowmod( self.eth_src_table.match( eth_type=self.ETH_TYPE, eth_dst=valve_packet.IPV6_ALL_ROUTERS_MCAST, vlan=vlan), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) ofmsgs.append( self.vip_table.flowmod(self.vip_table.match( eth_type=self.ETH_TYPE, nw_proto=valve_of.inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_ROUTER_SOLICIT), priority=priority, inst=controller_and_flood)) return ofmsgs
def build_acl_port_of_msgs(acl, vid, port_num, acl_table, goto_table, priority): """A Helper function for building Openflow Mod Messages for Port ACLs""" ofmsgs = None if acl.rules: ofmsgs = build_acl_ofmsgs( [acl], acl_table, [valve_of.goto_table(goto_table)], [valve_of.goto_table(goto_table)], priority, acl.meter, acl.exact_match, vlan_vid=vid, port_num=port_num) return ofmsgs
def build_acl_port_of_msgs(acl, vid, port_num, acl_table, goto_table): '''A Helper function for building Openflow Mod Messages for Port ACLs''' ofmsgs = None if acl.rules: ofmsgs = build_acl_ofmsgs( [acl], acl_table, [valve_of.goto_table(goto_table)], [valve_of.goto_table(goto_table)], 2 ** 16 - 1, acl.meter, acl.exact_match, vlan_vid=vid, port_num=port_num) return ofmsgs
def add_faucet_vip(self, vlan, faucet_vip): ofmsgs = [] max_prefixlen = faucet_vip.ip.max_prefixlen faucet_vip_host = self._host_from_faucet_vip(faucet_vip) priority = self.route_priority + max_prefixlen faucet_vip_host_nd_mcast = valve_packet.ipv6_link_eth_mcast( valve_packet.ipv6_solicited_node_from_ucast(faucet_vip.ip)) ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=self._eth_type(), vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, eth_dst=faucet_vip_host_nd_mcast, icmpv6_type=icmpv6.ND_NEIGHBOR_SOLICIT), priority=priority, inst=[ valve_of.apply_actions([valve_of.output_controller()]), valve_of.goto_table(self.flood_table)])) ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=self._eth_type(), eth_dst=self.faucet_mac, vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, icmpv6_type=icmpv6.ND_NEIGHBOR_ADVERT), priority=priority, inst=[valve_of.apply_actions([valve_of.output_controller()])])) # Initialize IPv6 FIB ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=self._eth_type(), eth_dst=self.faucet_mac, vlan=vlan), priority=self.route_priority, inst=[valve_of.goto_table(self.fib_table)])) ofmsgs.append(self.valve_flowcontroller( self.fib_table, self.valve_in_match( self.fib_table, eth_type=self._eth_type(), vlan=vlan, nw_proto=inet.IPPROTO_ICMPV6, nw_dst=faucet_vip_host, icmpv6_type=icmpv6.ICMPV6_ECHO_REQUEST), priority=priority)) return ofmsgs
def build(self, meters, vid, port_num): """Check that ACL can be built from config.""" class NullRyuDatapath: """Placeholder Ryu Datapath.""" ofproto = valve_of.ofp self.matches = {} self.set_fields = set() self.meter = False if self.rules: try: ofmsgs = valve_acl.build_acl_ofmsgs( [self], wildcard_table, valve_of.goto_table(wildcard_table), valve_of.goto_table(wildcard_table), 2**16 - 1, meters, self.exact_match, vlan_vid=vid, port_num=port_num) except (netaddr.core.AddrFormatError, KeyError, ValueError) as err: raise InvalidConfigError(err) test_config_condition(not ofmsgs, 'OF messages is empty') for ofmsg in ofmsgs: ofmsg.datapath = NullRyuDatapath() ofmsg.set_xid(0) try: ofmsg.serialize() except (KeyError, ValueError) as err: raise InvalidConfigError(err) except Exception as err: print(ofmsg) raise err if valve_of.is_flowmod(ofmsg): apply_actions = [] for inst in ofmsg.instructions: if valve_of.is_apply_actions(inst): apply_actions.extend(inst.actions) elif valve_of.is_meter(inst): self.meter = True for action in apply_actions: if valve_of.is_set_field(action): self.set_fields.add(action.key) for match, value in list(ofmsg.match.items()): has_mask = isinstance(value, (tuple, list)) if has_mask or match not in self.matches: self.matches[match] = has_mask return (self.matches, self.set_fields, self.meter)
def _add_vlan_flood_flow(self): """Add a flow to flood packets for unknown destinations.""" return [ self.dp.tables['eth_dst'].flowmod( priority=self.dp.low_priority, inst=[valve_of.goto_table(self.dp.tables['flood'])]) ]
def _add_controller_learn_flow(self): """Add a flow for controller to learn/add flows for destinations.""" return [ self.dp.tables['eth_src'].flowcontroller( priority=self.dp.low_priority, inst=[valve_of.goto_table(self.dp.tables['eth_dst'])]) ]
def add_faucet_vip(self, vlan, faucet_vip): ofmsgs = [] max_prefixlen = faucet_vip.ip.max_prefixlen faucet_vip_host = self._host_from_faucet_vip(faucet_vip) priority = self.route_priority + max_prefixlen ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=ether.ETH_TYPE_ARP, nw_dst=faucet_vip_host, vlan=vlan), priority=priority, inst=[valve_of.apply_actions([valve_of.output_controller()])])) # Initialize IPv4 FIB ofmsgs.append(self.valve_flowmod( self.eth_src_table, self.valve_in_match( self.eth_src_table, eth_type=self._eth_type(), eth_dst=self.faucet_mac, vlan=vlan), priority=self.route_priority, inst=[valve_of.goto_table(self.fib_table)])) ofmsgs.append(self.valve_flowcontroller( self.fib_table, self.valve_in_match( self.fib_table, vlan=vlan, eth_type=self._eth_type(), nw_proto=inet.IPPROTO_ICMP, nw_src=faucet_vip, nw_dst=faucet_vip_host), priority=priority)) return ofmsgs
def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated): ofmsgs = [] if is_updated: self.logger.info( 'Updating next hop for route %s via %s (%s) on VLAN %u' % (ip_dst, ip_gw, eth_dst, vlan.vid)) ofmsgs.extend(self._del_route_flows(vlan, ip_dst)) else: self.logger.info('Adding new route %s via %s (%s) on VLAN %u' % (ip_dst, ip_gw, eth_dst, vlan.vid)) if self.use_group_table: inst = [ valve_of.apply_actions([ valve_of.group_act( group_id=self._group_id_from_ip_gw(vlan, ip_gw)) ]) ] else: inst = [ valve_of.apply_actions(self._nexthop_actions(eth_dst, vlan)), valve_of.goto_table(self.eth_dst_table) ] for routed_vlan in self._routed_vlans(vlan): in_match = self._route_match(routed_vlan, ip_dst) ofmsgs.append( self.fib_table.flowmod(in_match, priority=self._route_priority(ip_dst), inst=inst)) return ofmsgs
def _port_add_vlan_tagged(self, port, vlan, forwarding_table, mirror_act): vlan_inst = [ valve_of.goto_table(forwarding_table) ] if mirror_act: vlan_inst = [valve_of.apply_actions(mirror_act)] + vlan_inst return self._port_add_vlan_rules(port, vlan, vlan_inst)
def build_flood_rules(self, vlan, modify=False): """Add flows to flood packets to unknown destinations on a VLAN.""" command = valve_of.ofp.OFPFC_ADD if modify: command = valve_of.ofp.OFPFC_MODIFY_STRICT # TODO: group tables for stacking ofmsgs = self._build_multiout_flood_rules(vlan, command) # Because stacking uses reflected broadcasts from the root, # don't try to learn broadcast sources from stacking ports. for port in self.stack_ports: ofmsgs.append(self.eth_src_table.flowdrop( self.eth_src_table.match( in_port=port.number, vlan=vlan, eth_dst=valve_packet.BRIDGE_GROUP_ADDRESS, eth_dst_mask=valve_packet.BRIDGE_GROUP_MASK), priority=self.bypass_priority+1)) for unicast_eth_dst, eth_dst, eth_dst_mask in self.FLOOD_DSTS: if unicast_eth_dst: continue for port in self.stack_ports: match = self.eth_src_table.match( in_port=port.number, vlan=vlan, eth_dst=eth_dst, eth_dst_mask=eth_dst_mask) ofmsgs.append(self.eth_src_table.flowmod( match=match, command=command, inst=[valve_of.goto_table(self.flood_table)], priority=self.bypass_priority)) return ofmsgs
def build(self, meters, vid, port_num): """Check that ACL can be built from config.""" class NullRyuDatapath: """Placeholder Ryu Datapath.""" ofproto = valve_of.ofp self.matches = {} self.set_fields = set() self.meter = False if self.rules: try: ofmsgs = valve_acl.build_acl_ofmsgs( [self], wildcard_table, [valve_of.goto_table(wildcard_table)], [valve_of.goto_table(wildcard_table)], 2**16-1, meters, self.exact_match, vlan_vid=vid, port_num=port_num) except (netaddr.core.AddrFormatError, KeyError, ValueError) as err: raise InvalidConfigError(err) test_config_condition(not ofmsgs, 'OF messages is empty') for ofmsg in ofmsgs: ofmsg.datapath = NullRyuDatapath() ofmsg.set_xid(0) try: ofmsg.serialize() except (KeyError, ValueError) as err: raise InvalidConfigError(err) except Exception as err: print(ofmsg) raise err if valve_of.is_flowmod(ofmsg): apply_actions = [] for inst in ofmsg.instructions: if valve_of.is_apply_actions(inst): apply_actions.extend(inst.actions) elif valve_of.is_meter(inst): self.meter = True for action in apply_actions: if valve_of.is_set_field(action): self.set_fields.add(action.key) for match, value in ofmsg.match.items(): has_mask = isinstance(value, (tuple, list)) if has_mask or match not in self.matches: self.matches[match] = has_mask return (self.matches, self.set_fields, self.meter)
def build_acl(acl, vid): """Check that ACL can be built from config and mark mirror destinations.""" matches = {} set_fields = set() meter = False if acl.rules: try: ofmsgs = valve_acl.build_acl_ofmsgs( [acl], self.wildcard_table, valve_of.goto_table(self.wildcard_table), valve_of.goto_table(self.wildcard_table), 2**16 - 1, self.meters, acl.exact_match, vlan_vid=vid) except (netaddr.core.AddrFormatError, KeyError, ValueError) as err: raise InvalidConfigError(err) test_config_condition(not ofmsgs, 'OF messages is empty') for ofmsg in ofmsgs: ofmsg.datapath = NullRyuDatapath() ofmsg.set_xid(0) try: ofmsg.serialize() except (KeyError, ValueError) as err: raise InvalidConfigError(err) if valve_of.is_flowmod(ofmsg): apply_actions = [] for inst in ofmsg.instructions: if valve_of.is_apply_actions(inst): apply_actions.extend(inst.actions) elif valve_of.is_meter(inst): meter = True for action in apply_actions: if valve_of.is_set_field(action): set_fields.add(action.key) for match, value in list(ofmsg.match.items()): has_mask = isinstance(value, (tuple, list)) if has_mask or match not in matches: matches[match] = has_mask for port_no in mirror_destinations: port = self.ports[port_no] port.output_only = True return (matches, set_fields, meter)
def _port_add_vlan_untagged(self, port, vlan, forwarding_table, mirror_act): push_vlan_act = mirror_act + valve_of.push_vlan_act(vlan.vid) push_vlan_inst = [ valve_of.apply_actions(push_vlan_act), valve_of.goto_table(forwarding_table) ] null_vlan = namedtuple('null_vlan', 'vid') null_vlan.vid = valve_of.ofp.OFPVID_NONE return self._port_add_vlan_rules(port, null_vlan, push_vlan_inst)
def build_acl(acl, vid=None): """Check that ACL can be built from config.""" assert valve_acl.build_acl_ofmsgs([acl], self.wildcard_table, valve_of.goto_table( self.wildcard_table), 2**16, self.meters, vlan_vid=vid)
def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host): ofmsgs = super(ValveIPv6RouteManager, self)._add_faucet_fib_to_vip( vlan, priority, faucet_vip, faucet_vip_host) faucet_vip_broadcast = ipaddress.IPv6Interface(faucet_vip.network.broadcast_address) ofmsgs.append(self.fib_table.flowmod( self.fib_table.match(eth_type=self.ETH_TYPE, vlan=vlan, nw_dst=faucet_vip_broadcast), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) return ofmsgs
def learn_host_on_vlan_port_flows(self, port, vlan, eth_src, delete_existing, src_rule_idle_timeout, src_rule_hard_timeout, dst_rule_idle_timeout): """Return flows that implement learning a host on a port.""" ofmsgs = [] if port.permanent_learn: # Antispoofing rule for this MAC. ofmsgs.append( self.eth_src_table.flowdrop(self.eth_src_table.match( vlan=vlan, eth_src=eth_src), priority=(self.host_priority - 2))) else: # Delete any existing entries for MAC. # TODO: for LAGs, don't delete entries in the same LAG. if delete_existing: ofmsgs.extend(self.delete_host_from_vlan(eth_src, vlan)) # Associate this MAC with source port. ofmsgs.append( self.eth_src_table.flowmod( self.eth_src_table.match(in_port=port.number, vlan=vlan, eth_src=eth_src), priority=(self.host_priority - 1), inst=[valve_of.goto_table(self.eth_dst_table)], hard_timeout=src_rule_hard_timeout, idle_timeout=src_rule_idle_timeout)) # Output packets for this MAC to specified port. ofmsgs.append( self.eth_dst_table.flowmod( self.eth_dst_table.match(vlan=vlan, eth_dst=eth_src), priority=self.host_priority, inst=[valve_of.apply_actions(vlan.output_port(port))], idle_timeout=dst_rule_idle_timeout)) # If port is in hairpin mode, install a special rule # that outputs packets destined to this MAC back out the same # port they came in (e.g. multiple hosts on same WiFi AP, # and FAUCET is switching between them on the same port). if port.hairpin: ofmsgs.append( self.eth_dst_table.flowmod( self.eth_dst_table.match(in_port=port.number, vlan=vlan, eth_dst=eth_src), priority=(self.host_priority + 1), inst=[ valve_of.apply_actions( vlan.output_port(port, hairpin=True)) ], idle_timeout=dst_rule_idle_timeout)) return ofmsgs
def _vlan_add_acl(self, vlan): ofmsgs = [] if vlan.acl_in: acl_table = self.dp.tables['vlan_acl'] acl_allow_inst = valve_of.goto_table(self.dp.tables['eth_src']) ofmsgs = valve_acl.build_acl_ofmsgs( [vlan.acl_in], acl_table, acl_allow_inst, self.dp.highest_priority, self.dp.meters, vlan.acl_in.exact_match, vlan_vid=vlan.vid) return ofmsgs
def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host): learn_connected_priority = self.route_priority + faucet_vip.network.prefixlen faucet_mac = vlan.faucet_mac insts = [valve_of.goto_table(self.fib_table)] if self._global_routing(): vlan_mac = faucet_mac.split(':')[:4] + [ '%x' % (vlan.vid >> 8), '%x' % (vlan.vid & 0xff) ] vlan_mac = ':'.join(vlan_mac) insts = [ valve_of.apply_actions([ valve_of.set_eth_dst(vlan_mac), valve_of.set_vlan_vid(self.global_vlan.vid) ]) ] + insts ofmsgs = [] ofmsgs.append( self.eth_src_table.flowmod(self.eth_src_table.match( eth_type=self.ETH_TYPE, eth_dst=faucet_mac, vlan=vlan), priority=self.route_priority, inst=insts)) routed_vlans = self._routed_vlans(vlan) if self._global_routing(): vlan = self.global_vlan ofmsgs.append( self.fib_table.flowmod(self._route_match(vlan, faucet_vip_host), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) if self.proactive_learn and faucet_vip.ip not in self.LINK_LOCAL: for routed_vlan in routed_vlans: ofmsgs.append( self.fib_table.flowmod( self._route_match(routed_vlan, faucet_vip), priority=learn_connected_priority, inst=[valve_of.goto_table(self.vip_table)])) ofmsgs.append( self.vip_table.flowcontroller( self.vip_table.match(eth_type=self.ETH_TYPE), priority=priority - 1, max_len=self.MAX_LEN)) return ofmsgs
def _add_faucet_fib_to_vip(self, vlan, priority, faucet_vip, faucet_vip_host): ofmsgs = super(ValveIPv6RouteManager, self)._add_faucet_fib_to_vip( vlan, priority, faucet_vip, faucet_vip_host) faucet_vip_broadcast = ipaddress.IPv6Interface(faucet_vip.network.broadcast_address) if self._global_routing(): vlan = self.global_vlan ofmsgs.append(self.fib_table.flowmod( self._route_match(vlan, faucet_vip_broadcast), priority=priority, inst=[valve_of.goto_table(self.vip_table)])) return ofmsgs
def build_acl(acl, vid=None): """Check that ACL can be built from config and mark mirror destinations.""" if acl.rules: try: assert valve_acl.build_acl_ofmsgs( [acl], self.wildcard_table, valve_of.goto_table(self.wildcard_table), 2**16, self.meters, acl.exact_match, vlan_vid=vid) except (AddrFormatError, ValueError) as err: raise InvalidConfigError(err) for port_no in acl.mirror_destinations: port = self.ports[port_no] port.mirror_destination = True
def build_acl(acl, vid=None): """Check that ACL can be built from config and mark mirror destinations.""" if acl.rules: try: ofmsgs = valve_acl.build_acl_ofmsgs( [acl], self.wildcard_table, valve_of.goto_table(self.wildcard_table), valve_of.goto_table(self.wildcard_table), 2**16 - 1, self.meters, acl.exact_match, vlan_vid=vid) test_config_condition(not ofmsgs, 'of messages is empty') for ofmsg in ofmsgs: ofmsg.datapath = NullRyuDatapath() ofmsg.set_xid(0) ofmsg.serialize() except (AddrFormatError, KeyError, ValueError) as err: raise InvalidConfigError(err) for port_no in mirror_destinations: port = self.ports[port_no] port.output_only = True
def _port_add_acl(self, port, cold_start=False): ofmsgs = [] acl_table = self.dp.tables['port_acl'] in_port_match = acl_table.match(in_port=port.number) if cold_start: ofmsgs.extend(acl_table.flowdel(in_port_match)) acl_allow_inst = valve_of.goto_table(self.dp.tables['vlan']) if port.acl_in: ofmsgs.extend(valve_acl.build_acl_ofmsgs( [port.acl_in], acl_table, acl_allow_inst, self.dp.highest_priority, self.dp.meters, port.acl_in.exact_match, port_num=port.number)) else: ofmsgs.append(acl_table.flowmod( in_port_match, priority=self.dp.highest_priority, inst=[acl_allow_inst])) return ofmsgs
def _add_resolved_route(self, vlan, ip_gw, ip_dst, eth_dst, is_updated): ofmsgs = [] if self.routers: in_match = self.valve_in_match( self.fib_table, vlan=AnyVlan(), eth_type=self._eth_type(), nw_dst=ip_dst) else: in_match = self.valve_in_match( self.fib_table, vlan=vlan, eth_type=self._eth_type(), nw_dst=ip_dst) prefixlen = ipaddress.ip_network(ip_dst).prefixlen priority = self.route_priority + prefixlen if is_updated: self.logger.info( 'Updating next hop for route %s via %s (%s)', ip_dst, ip_gw, eth_dst) ofmsgs.extend(self.valve_flowdel( self.fib_table, in_match, priority=priority)) else: self.logger.info( 'Adding new route %s via %s (%s)', ip_dst, ip_gw, eth_dst) if self.use_group_table: inst = [valve_of.apply_actions([valve_of.group_act( group_id=self.ip_gw_to_group_id[ip_gw])])] else: inst = [valve_of.apply_actions(self._nexthop_actions(eth_dst, vlan)), valve_of.goto_table(self.eth_dst_table)] ofmsgs.append(self.valve_flowmod( self.fib_table, in_match, priority=priority, inst=inst)) return ofmsgs
def goto_miss(self, next_table): """Add miss goto table instruction.""" assert next_table.name == self.table_config.miss_goto, ( '%s not configured as miss table in %s' % ( next_table.name, self.name)) return valve_of.goto_table(next_table)
def goto_this(self): return valve_of.goto_table(self)
def goto(self, next_table): """Add goto next table instruction.""" assert next_table.name in self.table_config.next_tables, ( '%s not configured as next table in %s' % (next_table.name, self.name)) return valve_of.goto_table(next_table)
def ports_add(self, port_nums, cold_start=False): """Handle the addition of ports. Args: port_num (list): list of port numbers. cold_start (bool): True if configuring datapath from scratch. Returns: list: OpenFlow messages, if any. """ ofmsgs = [] vlans_with_ports_added = set() eth_src_table = self.dp.tables['eth_src'] vlan_table = self.dp.tables['vlan'] for port_num in port_nums: if port_num not in self.dp.ports: self.logger.info( 'Ignoring port:%u not present in configuration file' % port_num) continue port = self.dp.ports[port_num] port.dyn_phys_up = True self.logger.info('%s up, configuring' % port) if not port.running(): continue # Port is a mirror destination; drop all input packets if port.mirror_destination: ofmsgs.append( vlan_table.flowdrop( match=vlan_table.match(in_port=port_num), priority=self.dp.highest_priority)) continue # Port has LACP processing enabled. if port.lacp: ofmsgs.extend(self.lacp_down(port)) # Add ACL if any. acl_ofmsgs = self._port_add_acl(port) ofmsgs.extend(acl_ofmsgs) port_vlans = port.vlans() # If this is a stacking port, accept all VLANs (came from another FAUCET) if port.stack is not None: ofmsgs.append( vlan_table.flowmod( match=vlan_table.match(in_port=port_num), priority=self.dp.low_priority, inst=[valve_of.goto_table(eth_src_table)])) port_vlans = list(self.dp.vlans.values()) else: mirror_act = [] # Add mirroring if any if port.mirror: mirror_act = [valve_of.output_port(port.mirror)] # Add port/to VLAN rules. ofmsgs.extend(self._port_add_vlans(port, mirror_act)) for vlan in port_vlans: vlans_with_ports_added.add(vlan) # Only update flooding rules if not cold starting. if not cold_start: for vlan in vlans_with_ports_added: ofmsgs.extend(self.flood_manager.build_flood_rules(vlan)) return ofmsgs
def goto_miss(self, next_table): """Add miss goto table instruction.""" assert next_table.name == self.table_config.miss_goto, ( '%s not configured as miss table in %s' % (next_table.name, self.name)) return valve_of.goto_table(next_table)
def goto(self, next_table): """Add goto next table instruction.""" assert next_table.name in self.table_config.next_tables, ( '%s not configured as next table in %s' % ( next_table.name, self.name)) return valve_of.goto_table(next_table)