def str_to_bin_for_rt(route_target): rt = route_target.split(":") as_number = int(rt[0]) local_administrator = int(rt[1]) rt_tmp = BGPTwoOctetAsSpecificExtendedCommunity(subtype=2, as_number=as_number, local_administrator=local_administrator) bin_rt = rt_tmp.serialize() return bin_rt
def create_rt_extended_community(value, subtype=2): """ Creates an instance of the BGP Route Target Community (if "subtype=2") or Route Origin Community ("subtype=3"). :param value: String of Route Target or Route Origin value. :param subtype: Subtype of Extended Community. :return: An instance of Route Target or Route Origin Community. """ global_admin, local_admin = value.split(':') local_admin = int(local_admin) if global_admin.isdigit() and 0 <= int(global_admin) <= 0xffff: ext_com = BGPTwoOctetAsSpecificExtendedCommunity( subtype=subtype, as_number=int(global_admin), local_administrator=local_admin) elif global_admin.isdigit() and 0xffff < int(global_admin) <= 0xffffffff: ext_com = BGPFourOctetAsSpecificExtendedCommunity( subtype=subtype, as_number=int(global_admin), local_administrator=local_admin) elif ip.valid_ipv4(global_admin): ext_com = BGPIPv4AddressSpecificExtendedCommunity( subtype=subtype, ipv4_address=global_admin, local_administrator=local_admin) else: raise ValueError('Invalid Route Target or Route Origin value: %s' % value) return ext_com
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([]) 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 = rt.split(':') subtype = 3 communities.append( BGPTwoOctetAsSpecificExtendedCommunity( as_number=int(as_num), local_administrator=int(local_admin), subtype=subtype)) 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()) 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_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