def insert_vrf_path(self, ip_nlri, next_hop=None, gen_lbl=False, is_withdraw=False): assert ip_nlri pattrs = None label_list = [] vrf_conf = self.vrf_conf if not is_withdraw: # Create a dictionary for path-attrs. pattrs = OrderedDict() # MpReachNlri and/or MpUnReachNlri attribute info. is contained # in the path. Hence we do not add these attributes here. from ryu.services.protocols.bgp.core import EXPECTED_ORIGIN pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( EXPECTED_ORIGIN) pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = \ BGPPathAttributeExtendedCommunities( rt_list=vrf_conf.export_rts, soo_list=vrf_conf.soo_list) if vrf_conf.multi_exit_disc: pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = \ BGPPathAttributeMultiExitDisc(vrf_conf.multi_exit_disc) table_manager = self._core_service.table_manager if gen_lbl and next_hop: # Label per next_hop demands we use a different label # per next_hop. Here connected interfaces are advertised per # VRF. label_key = (vrf_conf.route_dist, next_hop) nh_label = table_manager.get_nexthop_label(label_key) if not nh_label: nh_label = table_manager.get_next_vpnv4_label() table_manager.set_nexthop_label(label_key, nh_label) label_list.append(nh_label) elif gen_lbl: # If we do not have next_hop, get a new label. label_list.append(table_manager.get_next_vpnv4_label()) puid = self.VRF_PATH_CLASS.create_puid(vrf_conf.route_dist, ip_nlri.prefix) path = self.VRF_PATH_CLASS(puid, None, ip_nlri, 0, pattrs=pattrs, nexthop=next_hop, label_list=label_list, is_withdraw=is_withdraw) # Insert the path into VRF table, get affected destination so that we # can process it further. eff_dest = self.insert(path) # Enqueue the eff_dest for further processing. self._signal_bus.dest_changed(eff_dest) return label_list
def insert_vrffs_path(self, nlri, communities, is_withdraw=False): assert nlri assert isinstance(communities, list) vrf_conf = self.vrf_conf from ryu.services.protocols.bgp.core import EXPECTED_ORIGIN pattrs = OrderedDict() pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin(EXPECTED_ORIGIN) pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) for rt in vrf_conf.export_rts: communities.append(create_rt_extended_community(rt, 2)) for soo in vrf_conf.soo_list: communities.append(create_rt_extended_community(soo, 3)) pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = ( BGPPathAttributeExtendedCommunities(communities=communities)) puid = self.VRF_PATH_CLASS.create_puid(vrf_conf.route_dist, nlri.prefix) path = self.VRF_PATH_CLASS(puid, None, nlri, 0, pattrs=pattrs, is_withdraw=is_withdraw) # Insert the path into VRF table, get affected destination so that we # can process it further. eff_dest = self.insert(path) # Enqueue the eff_dest for further processing. self._signal_bus.dest_changed(eff_dest)
def update_flowspec_global_table(self, flowspec_family, rules, actions=None, is_withdraw=False): """Update a BGP route in the Global table for Flow Specification. ``flowspec_family`` specifies one of the Flow Specification family name. ``rules`` specifies NLRIs of Flow Specification as a dictionary type value. `` actions`` specifies Traffic Filtering Actions of Flow Specification as a dictionary type value. If `is_withdraw` is False, which is the default, add a BGP route to the Global table. If `is_withdraw` is True, remove a BGP route from the Global table. """ from ryu.services.protocols.bgp.core import BgpCoreError from ryu.services.protocols.bgp.api.prefix import FLOWSPEC_FAMILY_IPV4 src_ver_num = 1 peer = None # set mandatory path attributes origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP) aspath = BGPPathAttributeAsPath([[]]) pathattrs = OrderedDict() pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath if flowspec_family == FLOWSPEC_FAMILY_IPV4: _nlri = FlowSpecIPv4NLRI.from_user(**rules) p = IPv4FlowSpecPath try: communities = create_v4flowspec_actions(actions) except ValueError as e: raise BgpCoreError(desc=str(e)) if communities: pathattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = ( BGPPathAttributeExtendedCommunities( communities=communities)) else: raise BgpCoreError(desc='Unsupported flowspec family %s' % flowspec_family) new_path = p(peer, _nlri, src_ver_num, pattrs=pathattrs, is_withdraw=is_withdraw) # add to global table and propagates to neighbors self.learn_path(new_path)
def insert_vrf_path(self, nlri, next_hop=None, gen_lbl=False, is_withdraw=False, **kwargs): assert nlri pattrs = None label_list = [] vrf_conf = self.vrf_conf if not is_withdraw: table_manager = self._core_service.table_manager if gen_lbl and next_hop: # Label per next_hop demands we use a different label # per next_hop. Here connected interfaces are advertised per # VRF. label_key = (vrf_conf.route_dist, next_hop) nh_label = table_manager.get_nexthop_label(label_key) if not nh_label: nh_label = table_manager.get_next_vpnv4_label() table_manager.set_nexthop_label(label_key, nh_label) label_list.append(nh_label) elif gen_lbl: # If we do not have next_hop, get a new label. label_list.append(table_manager.get_next_vpnv4_label()) # Set MPLS labels with the generated labels if gen_lbl and isinstance(nlri, EvpnMacIPAdvertisementNLRI): nlri.mpls_labels = label_list[:2] elif gen_lbl and isinstance(nlri, EvpnIpPrefixNLRI): nlri.mpls_label = label_list[0] # Create a dictionary for path-attrs. pattrs = OrderedDict() # MpReachNlri and/or MpUnReachNlri attribute info. is contained # in the path. Hence we do not add these attributes here. from ryu.services.protocols.bgp.core import EXPECTED_ORIGIN pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( EXPECTED_ORIGIN) pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) communities = [] # Set ES-Import Route Target if isinstance(nlri, EvpnEthernetSegmentNLRI): subtype = 2 es_import = nlri.esi.mac_addr communities.append( BGPEvpnEsImportRTExtendedCommunity(subtype=subtype, es_import=es_import)) for rt in vrf_conf.export_rts: communities.append(create_rt_extended_community(rt, 2)) for soo in vrf_conf.soo_list: communities.append(create_rt_extended_community(soo, 3)) # Set Tunnel Encapsulation Attribute tunnel_type = kwargs.get('tunnel_type', None) if tunnel_type: communities.append( BGPEncapsulationExtendedCommunity.from_str(tunnel_type)) # Set ESI Label Extended Community redundancy_mode = kwargs.get('redundancy_mode', None) if redundancy_mode is not None: subtype = 1 flags = 0 from ryu.services.protocols.bgp.api.prefix import ( REDUNDANCY_MODE_SINGLE_ACTIVE) if redundancy_mode == REDUNDANCY_MODE_SINGLE_ACTIVE: flags |= BGPEvpnEsiLabelExtendedCommunity.SINGLE_ACTIVE_BIT vni = kwargs.get('vni', None) if vni is not None: communities.append( BGPEvpnEsiLabelExtendedCommunity(subtype=subtype, flags=flags, vni=vni)) else: communities.append( BGPEvpnEsiLabelExtendedCommunity( subtype=subtype, flags=flags, mpls_label=label_list[0])) pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = \ BGPPathAttributeExtendedCommunities(communities=communities) if vrf_conf.multi_exit_disc: pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = \ BGPPathAttributeMultiExitDisc(vrf_conf.multi_exit_disc) # Set PMSI Tunnel Attribute pmsi_tunnel_type = kwargs.get('pmsi_tunnel_type', None) if pmsi_tunnel_type is not None: from ryu.services.protocols.bgp.api.prefix import ( PMSI_TYPE_INGRESS_REP) if pmsi_tunnel_type == PMSI_TYPE_INGRESS_REP: tunnel_id = PmsiTunnelIdIngressReplication( tunnel_endpoint_ip=self._core_service.router_id) else: # pmsi_tunnel_type == PMSI_TYPE_NO_TUNNEL_INFO tunnel_id = None pattrs[BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE] = \ BGPPathAttributePmsiTunnel(pmsi_flags=0, tunnel_type=pmsi_tunnel_type, tunnel_id=tunnel_id, vni=kwargs.get('vni', None)) puid = self.VRF_PATH_CLASS.create_puid(vrf_conf.route_dist, nlri.prefix) path = self.VRF_PATH_CLASS(puid, None, nlri, 0, pattrs=pattrs, nexthop=next_hop, label_list=label_list, is_withdraw=is_withdraw) # Insert the path into VRF table, get affected destination so that we # can process it further. eff_dest = self.insert(path) # Enqueue the eff_dest for further processing. self._signal_bus.dest_changed(eff_dest) return label_list
def insert_vrf_path(self, nlri, next_hop=None, gen_lbl=False, is_withdraw=False, **kwargs): assert nlri pattrs = None label_list = [] vrf_conf = self.vrf_conf if not is_withdraw: # Create a dictionary for path-attrs. pattrs = OrderedDict() # MpReachNlri and/or MpUnReachNlri attribute info. is contained # in the path. Hence we do not add these attributes here. from ryu.services.protocols.bgp.core import EXPECTED_ORIGIN pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( EXPECTED_ORIGIN) pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) communities = [] for rt in vrf_conf.export_rts: as_num, local_admin = rt.split(':') subtype = 2 communities.append( BGPTwoOctetAsSpecificExtendedCommunity( as_number=int(as_num), local_administrator=int(local_admin), subtype=subtype)) for soo in vrf_conf.soo_list: as_num, local_admin = soo.split(':') subtype = 3 communities.append( BGPTwoOctetAsSpecificExtendedCommunity( as_number=int(as_num), local_administrator=int(local_admin), subtype=subtype)) # Set Tunnel Encapsulation Attribute tunnel_type = kwargs.get('tunnel_type', None) if tunnel_type: communities.append( BGPEncapsulationExtendedCommunity.from_str(tunnel_type)) pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = \ BGPPathAttributeExtendedCommunities(communities=communities) if vrf_conf.multi_exit_disc: pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = \ BGPPathAttributeMultiExitDisc(vrf_conf.multi_exit_disc) table_manager = self._core_service.table_manager if gen_lbl and next_hop: # Label per next_hop demands we use a different label # per next_hop. Here connected interfaces are advertised per # VRF. label_key = (vrf_conf.route_dist, next_hop) nh_label = table_manager.get_nexthop_label(label_key) if not nh_label: nh_label = table_manager.get_next_vpnv4_label() table_manager.set_nexthop_label(label_key, nh_label) label_list.append(nh_label) elif gen_lbl: # If we do not have next_hop, get a new label. label_list.append(table_manager.get_next_vpnv4_label()) # Set PMSI Tunnel Attribute pmsi_tunnel_type = kwargs.get('pmsi_tunnel_type', None) if pmsi_tunnel_type is not None: from ryu.services.protocols.bgp.api.prefix import ( PMSI_TYPE_INGRESS_REP) if pmsi_tunnel_type == PMSI_TYPE_INGRESS_REP: tunnel_id = PmsiTunnelIdIngressReplication( tunnel_endpoint_ip=self._core_service.router_id) else: # pmsi_tunnel_type == PMSI_TYPE_NO_TUNNEL_INFO tunnel_id = None pattrs[BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE] = \ BGPPathAttributePmsiTunnel(pmsi_flags=0, tunnel_type=pmsi_tunnel_type, tunnel_id=tunnel_id) # Set MPLS labels with the generated labels if gen_lbl and isinstance(nlri, EvpnMacIPAdvertisementNLRI): nlri.mpls_labels = label_list[:2] puid = self.VRF_PATH_CLASS.create_puid(vrf_conf.route_dist, nlri.prefix) path = self.VRF_PATH_CLASS(puid, None, nlri, 0, pattrs=pattrs, nexthop=next_hop, label_list=label_list, is_withdraw=is_withdraw) # Insert the path into VRF table, get affected destination so that we # can process it further. eff_dest = self.insert(path) # Enqueue the eff_dest for further processing. self._signal_bus.dest_changed(eff_dest) return label_list