def termination_mac_flow(dpath, mod, ofctl): """ Termination MAC flow table. """ _LOG.debug("TERM MAC FLow: %d %s %s", dpath.id, mod, ofctl) cmd = fibcapi.flow_mod_cmd(mod.cmd, dpath.ofproto) entry = mod.term_mac match = ofmatch.Match().eth_type(entry.match.eth_type).eth_dst( entry.match.eth_dst) def _actions(): if not offlow.is_action_needed(dpath, cmd): return [] return [ofaction.goto_table(entry.goto_table)] flow = offlow.flow_mod(match=match, actions=_actions, writes=[], table_id=pb.FlowMod.TERM_MAC, priority=fibcapi.PRIORITY_LOW) ofctl.mod_flow_entry(dpath, flow, cmd)
def setup_policy_acl_flow(dpath, ofctl): """ Policy ACL flows when dp enter. """ matches = [ ofmatch.Match().eth_type(fibcapi.ETHTYPE_LACP), ofmatch.Match().eth_type(fibcapi.ETHTYPE_ARP), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV4).ip_proto(fibcapi.IPPROTO_ICMP4), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV6).ip_proto(fibcapi.IPPROTO_ICMP6), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV4).ip_proto(fibcapi.IPPROTO_OSPF), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV6).ip_proto(fibcapi.IPPROTO_OSPF), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV4).ip_proto(fibcapi.IPPROTO_TCP).tcp_src(fibcapi.TCPPORT_BGP), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV4).ip_proto(fibcapi.IPPROTO_TCP).tcp_dst(fibcapi.TCPPORT_BGP), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV6).ip_proto(fibcapi.IPPROTO_TCP).tcp_src(fibcapi.TCPPORT_BGP), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV6).ip_proto(fibcapi.IPPROTO_TCP).tcp_dst(fibcapi.TCPPORT_BGP), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV4).ip_proto(fibcapi.IPPROTO_TCP).tcp_src(fibcapi.TCPPORT_LDP), # ofmatch.Match().eth_type(fibcapi.ETHTYPE_IPV4).ip_proto(fibcapi.IPPROTO_TCP).tcp_dst(fibcapi.TCPPORT_LDP), ofmatch.Match().ip_dst(fibcapi.MCADDR_ALLROUTERS), ofmatch.Match().ip_dst(fibcapi.MCADDR_OSPF_HELLO), ofmatch.Match().ip_dst(fibcapi.MCADDR_OSPF_ALLDR), ] actions = [ofaction.output(dpath.ofproto.OFPP_CONTROLLER)] for match in matches: flow = offlow.flow_mod( match=match, actions=actions, writes=[], table_id=pb.FlowMod.POLICY_ACL, priority=fibcapi.PRIORITY_NORMAL, ) ofctl.mod_flow_entry(dpath, flow, dpath.ofproto.OFPFC_ADD)
def mpls1_flow(dpath, mod, ofctl, use_metadata=True): """ MPLS1 flow table. """ _LOG.debug("MPLS1 FLow: %d %s %s", dpath.id, mod, ofctl) cmd = fibcapi.flow_mod_cmd(mod.cmd, dpath.ofproto) entry = mod.mpls1 def _match(): match = ofmatch.Match() match.eth_type(fibcapi.ETHTYPE_MPLS) match.mpls_bos(entry.match.bos) match.mpls_label(entry.match.label) return match def _actions(): if not offlow.is_action_needed(dpath, cmd): return [] actions = [ ofaction.goto_table(entry.goto_table), ofaction.dec_mpls_ttl(), ] if entry.goto_table == pb.FlowMod.MPLS_TYPE: actions.append( ofaction.set_mpls_type(fibcapi.MPLSTYPE_PHP, use_metadata)) for action in entry.actions: if action.name == pb.MPLSFlow.Action.POP_LABEL: actions.append(ofaction.pop_mpls(action.value)) elif action.name == pb.MPLSFlow.Action.SET_VRF: actions.append(ofaction.set_vrf(action.value, use_metadata)) return actions def _writes(): if not offlow.is_action_needed(dpath, cmd): return [] if entry.g_type == pb.GroupMod.MPLS_INTERFACE: return [ ofaction.group(fibcapi.mpls_interface_group_id(entry.g_id)) ] if entry.g_type == pb.GroupMod.MPLS_SWAP: return [ofaction.group(fibcapi.mpls_label_group_id(5, entry.g_id))] if entry.g_type == pb.GroupMod.MPLS_FF: return [ofaction.group(fibcapi.mpls_ff_group_id(entry.g_id))] if entry.g_type == pb.GroupMod.MPLS_ECMP: return [ofaction.group(fibcapi.mpls_ecmp_group_id(entry.g_id))] return [] flow = offlow.flow_mod(match=_match, actions=_actions, writes=_writes, table_id=pb.FlowMod.MPLS1, priority=1) ofctl.mod_flow_entry(dpath, flow, cmd)
def setup_flow(dpath, mod, ofctl): """ Setup flows. """ _LOG.debug("Default FLow: %d %s", dpath.id, mod) ofp = dpath.ofproto # send whole packet to controller dpath.send_msg(offlow.set_sw_config(dpath)) # clear all flows/groups. dpath.send_msg(offlow.clear_all(dpath)) for msg in ofgroup.clear_all(dpath): dpath.send_msg(msg) # send all packet to controller flow = offlow.flow_mod( table_id=0, priority=0, match={}, actions=[ ofaction.output(ofp.OFPP_CONTROLLER), ], writes=[], ) ofctl.mod_flow_entry(dpath, flow, ofp.OFPFC_ADD)
def _add_table_miss_flows(dpath, ofctl): """ Table miss flows. """ tables = [ (pb.FlowMod.INGRESS_PORT, pb.FlowMod.VLAN, []), (pb.FlowMod.VLAN, pb.FlowMod.POLICY_ACL, [ofaction.clear_actions()]), (pb.FlowMod.TERM_MAC, pb.FlowMod.BRIDGING, []), (pb.FlowMod.MPLS0, pb.FlowMod.MPLS1, []), (pb.FlowMod.MPLS1, -1, [ofaction.clear_actions()]), (pb.FlowMod.MPLS2, -1, [ofaction.clear_actions()]), (pb.FlowMod.MPLS_L3_TYPE, -1, [ofaction.clear_actions()]), (pb.FlowMod.MPLS_LABEL_TRUST, pb.FlowMod.MPLS_TYPE, []), (pb.FlowMod.MPLS_TYPE, pb.FlowMod.POLICY_ACL, []), (pb.FlowMod.UNICAST_ROUTING, pb.FlowMod.POLICY_ACL, []), (pb.FlowMod.MULTICAST_ROUTING, pb.FlowMod.POLICY_ACL, []), (pb.FlowMod.BRIDGING, pb.FlowMod.POLICY_ACL, []), (pb.FlowMod.POLICY_ACL, -1, []), # (pb.FlowMod.POLICY_ACL, -1, [ofaction.output(dpath.ofproto.OFPP_CONTROLLER)]), ] for talbe_id, goto_table, actions in tables: if goto_table > 0: actions.append(ofaction.goto_table(goto_table)) flow = offlow.flow_mod( match={}, actions=actions, writes=[], table_id=talbe_id, priority=fibcapi.PRIORITY_DEFAULT, ) ofctl.mod_flow_entry(dpath, flow, dpath.ofproto.OFPFC_ADD) return
def policy_acl_flow(dpath, mod, ofctl, use_metadata=True): """ Policy ACL flow table. """ _LOG.debug("ACL FLow: %d %s", dpath.id, mod) entry = mod.acl if entry.match.in_port: # openflow mode: # send no flows for a port. # flows for a port are send by setup_flow(). return cmd = fibcapi.flow_mod_cmd(mod.cmd, dpath.ofproto) match = ofmatch.Match().ip_dst(entry.match.ip_dst).vrf( entry.match.vrf, use_metadata) def _actions(): if not offlow.is_action_needed(dpath, cmd): return [] return [ofaction.output(dpath.ofproto.OFPP_CONTROLLER)] flow = offlow.flow_mod(match=match, actions=_actions, writes=[], table_id=pb.FlowMod.POLICY_ACL, priority=fibcapi.PRIORITY_HIGH) ofctl.mod_flow_entry(dpath, flow, cmd)
def _lagopus_bugfix(dpath, ofctl): """ To avoid lagopus bug. """ flow = offlow.flow_mod( match=ofmatch.Match().eth_type(fibcapi.ETHTYPE_MPLS), actions=[], writes=[], table_id=pb.FlowMod.POLICY_ACL, priority=fibcapi.PRIORITY_HIGHEST, ) ofctl.mod_flow_entry(dpath, flow, dpath.ofproto.OFPFC_ADD)
def unicast_routing_flow(dpath, mod, ofctl, use_metadata=True): """ Create flow_mod for Unicast Routing flow table. """ _LOG.debug("Unicast Routing FLow: %d %s", dpath.id, mod) cmd = fibcapi.flow_mod_cmd(mod.cmd, dpath.ofproto) entry = mod.unicast match = ofmatch.Match().ip_dst(entry.match.ip_dst).vrf( entry.match.vrf, use_metadata) def _actions(): if not offlow.is_action_needed(dpath, cmd): return [] return [ofaction.goto_table(pb.FlowMod.POLICY_ACL)] def _writes(): if not offlow.is_action_needed(dpath, cmd): return [] writes = [ofaction.dec_nw_ttl()] if entry.g_type == pb.GroupMod.L3_UNICAST: writes.append( ofaction.group(fibcapi.l3_unicast_group_id(entry.g_id))) elif entry.g_type == pb.GroupMod.L3_ECMP: writes.append(ofaction.group(fibcapi.l3_ecmp_group_id(entry.g_id))) elif entry.g_type == pb.GroupMod.MPLS_L3_VPN: writes.append( ofaction.group(fibcapi.mpls_label_group_id(2, entry.g_id))) else: pass return writes def _priority_base(): if entry.g_type == pb.GroupMod.MPLS_L3_VPN: return fibcapi.PRIORITY_BASE_VPN return fibcapi.PRIORITY_BASE_UC priority = offlow.priority_for_ipaddr(entry.match.ip_dst, _priority_base()) flow = offlow.flow_mod(match=match, actions=_actions, writes=_writes, table_id=pb.FlowMod.UNICAST_ROUTING, priority=priority) ofctl.mod_flow_entry(dpath, flow, cmd)
def _add_mpls_l3_type_php_flows(dpath, ofctl): # L3 VPN Forward (IPv4) based on this label (PHP) flow = offlow.flow_mod( match=ofmatch.Match().eth_type(fibcapi.ETHTYPE_MPLS).mpls_type( fibcapi.MPLSTYPE_PHP, True), actions=[ ofaction.pop_mpls(fibcapi.ETHTYPE_IPV4), ofaction.goto_table(pb.FlowMod.MPLS_LABEL_TRUST), ], writes=[], table_id=pb.FlowMod.MPLS_L3_TYPE, priority=5, ) ofctl.mod_flow_entry(dpath, flow, dpath.ofproto.OFPFC_ADD) return
def _add_mpls_l3_type_l3vpn_flows(dpath, ofctl): # L3 VPN Route (IPv4 Unicast) flow = offlow.flow_mod( match=ofmatch.Match().eth_type(fibcapi.ETHTYPE_MPLS), actions=[ ofaction.set_mpls_type(fibcapi.MPLSTYPE_UNICAST, True), ofaction.pop_mpls(fibcapi.ETHTYPE_IPV4), ofaction.goto_table(pb.FlowMod.MPLS_LABEL_TRUST), ], writes=[], table_id=pb.FlowMod.MPLS_L3_TYPE, priority=1, ) ofctl.mod_flow_entry(dpath, flow, dpath.ofproto.OFPFC_ADD) return
def setup_term_mac_flow(dpath, ofctl): """ Termination MAC flow (for setup) """ matches = [ ofmatch.Match().eth_dst(fibcapi.HWADDR_MULTICAST4_MATCH).eth_type( fibcapi.ETHTYPE_IPV4), ofmatch.Match().eth_dst(fibcapi.HWADDR_MULTICAST6_MATCH).eth_type( fibcapi.ETHTYPE_IPV6), ] actions = [ofaction.goto_table(pb.FlowMod.MULTICAST_ROUTING)] for match in matches: flow = offlow.flow_mod( match=match, actions=actions, writes=[], table_id=pb.FlowMod.TERM_MAC, priority=2, ) ofctl.mod_flow_entry(dpath, flow, dpath.ofproto.OFPFC_ADD)
def vlan_flow(dpath, mod, ofctl, use_metadata=True): """ VLAN flow table. """ _LOG.debug("VLAN FLow: %d %s", dpath.id, mod) cmd = fibcapi.flow_mod_cmd(mod.cmd, dpath.ofproto) entry = mod.vlan def _match(): match = ofmatch.Match() match.in_port(entry.match.in_port) match.vlan_vid(entry.match.vid, entry.match.vid_mask) return match def _actions(): if not offlow.is_action_needed(dpath, cmd): return [] actions = [] for action in entry.actions: if action.name == pb.VLANFlow.Action.PUSH_VLAN: vlan_vid = action.value | fibcapi.OFPVID_PRESENT actions.append(ofaction.push_vlan(fibcapi.ETHTYPE_VLAN_Q)) actions.append(ofaction.set_field("vlan_vid", vlan_vid)) elif action.name == pb.VLANFlow.Action.SET_VRF: actions.append(ofaction.set_vrf(action.value, use_metadata)) actions.append(ofaction.goto_table(entry.goto_table)) return actions flow = offlow.flow_mod(match=_match, actions=_actions, writes=[], table_id=pb.FlowMod.VLAN, priority=3) ofctl.mod_flow_entry(dpath, flow, cmd)
def _add_mpls_type_flows(dpath, ofctl): """ MPLS Type builtin flows. """ datas = [ (fibcapi.MPLSTYPE_VPS, pb.FlowMod.POLICY_ACL), (fibcapi.MPLSTYPE_UNICAST, pb.FlowMod.UNICAST_ROUTING), (fibcapi.MPLSTYPE_MULTICAST, pb.FlowMod.MULTICAST_ROUTING), (fibcapi.MPLSTYPE_PHP, pb.FlowMod.POLICY_ACL), ] for mpls_type, goto_table in datas: flow = offlow.flow_mod( match=ofmatch.Match().mpls_type(mpls_type, True), actions=[ ofaction.goto_table(goto_table), ], writes=[], table_id=pb.FlowMod.MPLS_TYPE, priority=1, ) ofctl.mod_flow_entry(dpath, flow, dpath.ofproto.OFPFC_ADD) return