Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
def clone_path_and_update_med_for_target_neighbor(path, med):
    assert path and med
    route_family = path.route_family
    if route_family not in _ROUTE_FAMILY_TO_PATH_MAP.keys():
        raise ValueError('Clone is not supported for address-family %s' %
                         route_family)
    path_cls = _ROUTE_FAMILY_TO_PATH_MAP.get(route_family)
    pattrs = path.pathattr_map
    pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = BGPPathAttributeMultiExitDisc(med)
    return path_cls(
        path.source, path.nlri, path.source_version_num,
        pattrs=pattrs, nexthop=path.nexthop,
        is_withdraw=path.is_withdraw,
        med_set_by_target_neighbor=True
    )
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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