Exemple #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
    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)
Exemple #3
0
    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
Exemple #5
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