def run(gobgpd_addr, vrf_name, prefix, nexthop):
    channel = implementations.insecure_channel(gobgpd_addr, 50051)
    with gobgp_pb2.beta_create_GobgpApi_stub(channel) as stub:

        subnet = IPNetwork(prefix)
        ipaddr = subnet.ip
        masklen = subnet.prefixlen

        nlri = IPAddrPrefix(addr=ipaddr, length=masklen)
        bin_nlri = nlri.serialize()

        nexthop = BGPPathAttributeNextHop(value=nexthop)
        bin_nexthop = nexthop.serialize()

        origin = BGPPathAttributeOrigin(value=2)
        bin_origin = origin.serialize()

        pattrs = []
        pattrs.append(str(bin_nexthop))
        pattrs.append(str(bin_origin))

        path = {}
        path['nlri'] = str(bin_nlri)
        path['pattrs'] = pattrs

        uuid = stub.ModPath(gobgp_pb2.ModPathArguments(resource=Resource_VRF, name=vrf_name, path=path), _TIMEOUT_SECONDS)

        if uuid:
            print "Success!"
        else:
            print "Error!"
Esempio n. 2
0
    def add_to_global_table(self, prefix, nexthop=None, is_withdraw=False):
        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

        net = netaddr.IPNetwork(prefix)
        ip = str(net.ip)
        masklen = net.prefixlen
        if netaddr.valid_ipv4(ip):
            _nlri = IPAddrPrefix(masklen, ip)
            if nexthop is None:
                nexthop = '0.0.0.0'
            p = Ipv4Path
        else:
            _nlri = IP6AddrPrefix(masklen, ip)
            if nexthop is None:
                nexthop = '::'
            p = Ipv6Path

        new_path = p(peer,
                     _nlri,
                     src_ver_num,
                     pattrs=pathattrs,
                     nexthop=nexthop,
                     is_withdraw=is_withdraw)

        # add to global ipv4 table and propagates to neighbors
        self.learn_path(new_path)
def run(gobgpd_addr, routefamily):
    channel = implementations.insecure_channel(gobgpd_addr, 50051)
    with gobgp_pb2.beta_create_GobgpApi_stub(channel) as stub:

        ribs = stub.MonitorBestChanged(gobgp_pb2.Arguments(family=routefamily),
                                                           _TIMEOUT_SECONDS)

        for rib in ribs:
            paths_target = rib.paths
            for path_target in paths_target:
                nlri = IPAddrPrefix.parser(path_target.nlri)
                print "----------------------------"
                print (" Rib.prefix     : %s" % nlri[0].prefix)
                for pattr in path_target.pattrs:
                    path_attr = _PathAttribute.parser(pattr)
                    if isinstance(path_attr[0], BGPPathAttributeOrigin):
                        print (" Rib.origin     : %s" % path_attr[0].value)
                    elif isinstance(path_attr[0], BGPPathAttributeAsPath):
                        if path_attr[0].type == 2:
                            print(" Rib.aspath     : %s" % path_attr[0].value)
                        else:
                            print(" Rib.aspath     : ???")
                    elif isinstance(path_attr[0], BGPPathAttributeMultiExitDisc):
                        print (" Rib.med        : %s" % path_attr[0].value)
                    elif isinstance(path_attr[0], BGPPathAttributeNextHop):
                        print (" Rib.nexthop    : %s" % path_attr[0].value)
                    elif isinstance(path_attr[0], BGPPathAttributeCommunities):
                        for community in path_attr[0].communities:
                            print(" Rib.community  : %s" % community)

                print (" Rib.is_withdraw : %s" % path_target.is_withdraw)
    def modpath(self,gobgpd_addr,originate_path_list):
        channel = implementations.insecure_channel(gobgpd_addr, 50051)
        with gobgp_pb2.beta_create_GobgpApi_stub(channel) as stub:
            paths = []
            for originate_path in originate_path_list:
                pattrs = []
                path = {}
                subnet = IPNetwork(originate_path['route'])
                ver = subnet.version
                addr = subnet.ip
                mask = subnet.prefixlen
                if ver == 4:
                    nlri = IPAddrPrefix(addr=addr, length=mask)
                    nexthop = BGPPathAttributeNextHop(value=originate_path['next_hop'])
                else :
                    nlri = IP6AddrPrefix(addr=addr, length=mask)
                    nexthop = BGPPathAttributeMpReachNLRI(next_hop = originate_path['next_hop'],nlri = [nlri],afi = AFI_IPV6 , safi = SAFI_UNICAST)

                bin_nlri = nlri.serialize()
                bin_nexthop = nexthop.serialize()

                pattrs.append(str(bin_nexthop))

                origin = BGPPathAttributeOrigin(value=ORIGIN)
                bin_origin = origin.serialize()
                pattrs.append(str(bin_origin))

                if originate_path['community'] :
                    community_set = self.community_convert(originate_path['community'])
                    communities = BGPPathAttributeCommunities(communities=community_set)
                    bin_communities = communities.serialize()
                    pattrs.append(str(bin_communities))

                #as_path = BGPPathAttributeAs4Path(value=[[1234,1111]])
                #bin_as_path = as_path.serialize()
                #pattrs.append(str(bin_as_path))

                path['nlri'] = str(bin_nlri)
                path['pattrs'] = pattrs

                paths.append(path)

            args = []
            args.append(gobgp_pb2.ModPathsArguments(resource=Resource_GLOBAL, paths=paths))
            ret = stub.ModPaths(args, _TIMEOUT_SECONDS)
Esempio n. 5
0
    def add_to_vrf(self, route_dist, prefix, next_hop, route_family):
        """Adds `prefix` to VRF identified by `route_dist` with given
         `next_hop`.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError

        assert route_dist and prefix and next_hop
        if route_family not in (VRF_RF_IPV4, VRF_RF_IPV6):
            raise ValueError('Given route_family %s is not supported.' %
                             route_family)

        vrf_table = None
        table_id = (route_dist, route_family)
        if route_family == VRF_RF_IPV4:
            vrf_table = self._tables.get(table_id)
            if vrf_table is None:
                raise BgpCoreError(desc='VRF table for RD: %s does not '
                                        'exist.' % route_dist)
            if not is_valid_ipv4_prefix(prefix) or not is_valid_ipv4(next_hop):
                raise BgpCoreError(desc='Invalid Ipv4 prefix or nexthop.')
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        elif route_family == VRF_RF_IPV6:
            vrf_table = self._tables.get(table_id)
            if vrf_table is None:
                raise BgpCoreError(desc='VRF table for RD: %s does not '
                                        'exist.' % route_dist)
            if not is_valid_ipv6_prefix(prefix) or not is_valid_ipv6(next_hop):
                raise BgpCoreError(desc='Invalid Ipv6 prefix or nexthop.')
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip6)

        return vrf_table.insert_vrf_path(
            prefix, next_hop=next_hop,
            gen_lbl=True
        )
Esempio n. 6
0
    def add_to_vrf(self, route_dist, prefix, next_hop, route_family):
        """Adds `prefix` to VRF identified by `route_dist` with given
         `next_hop`.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError

        assert route_dist and prefix and next_hop
        if route_family not in (VRF_RF_IPV4, VRF_RF_IPV6):
            raise ValueError('Given route_family %s is not supported.' %
                             route_family)

        vrf_table = None
        table_id = (route_dist, route_family)
        if route_family == VRF_RF_IPV4:
            vrf_table = self._tables.get(table_id)
            if vrf_table is None:
                raise BgpCoreError(desc='VRF table for RD: %s does not '
                                        'exist.' % route_dist)
            if not is_valid_ipv4_prefix(prefix) or not is_valid_ipv4(next_hop):
                raise BgpCoreError(desc='Invalid Ipv4 prefix or nexthop.')
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        elif route_family == VRF_RF_IPV6:
            vrf_table = self._tables.get(table_id)
            if vrf_table is None:
                raise BgpCoreError(desc='VRF table for RD: %s does not '
                                        'exist.' % route_dist)
            if not is_valid_ipv6_prefix(prefix) or not is_valid_ipv6(next_hop):
                raise BgpCoreError(desc='Invalid Ipv6 prefix or nexthop.')
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip6)

        return vrf_table.insert_vrf_path(
            prefix, next_hop=next_hop,
            gen_lbl=True
        )
    def test_update_vrf_table_invalid_route_family(self):
        # Prepare test data
        route_dist = '65000:100'
        ip_network = '192.168.0.0'
        ip_prefix_len = 24
        prefix_str = '%s/%d' % (ip_network, ip_prefix_len)
        prefix_inst = IPAddrPrefix(ip_prefix_len, ip_network)
        next_hop = '10.0.0.1'
        route_family = 'foobar'  # invalid
        route_type = None  # should be ignored
        kwargs = {}  # should be ignored

        self._test_update_vrf_table(prefix_inst, route_dist, prefix_str,
                                    next_hop, route_family, route_type,
                                    **kwargs)
Esempio n. 8
0
    def remove_from_vrf(self, route_dist, prefix, route_family):
        """Removes `prefix` from VRF identified by `route_dist`.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError
        # Validate given
        if route_family not in (VRF_RF_IPV4, VRF_RF_IPV6):
            raise BgpCoreError(desc='Unsupported route family %s' %
                               route_family)
        val_ipv4 = route_family == VRF_RF_IPV4\
            and is_valid_ipv4_prefix(prefix)
        val_ipv6 = route_family == VRF_RF_IPV6\
            and is_valid_ipv6_prefix(prefix)

        if not val_ipv4 and not val_ipv6:
            raise BgpCoreError(desc='Invalid prefix or nexthop.')

        table_id = (route_dist, route_family)
        if route_family == VRF_RF_IPV4:
            vrf_table = self._tables.get(table_id)
            if not vrf_table:
                raise BgpCoreError(desc='Vrf for route distinguisher %s does '
                                   'not exist.' % route_dist)
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        else:
            vrf_table = self._tables.get(table_id)
            if not vrf_table:
                raise BgpCoreError(desc='Vrf for route distinguisher %s does '
                                   'not exist.' % route_dist)
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip6)
            # We do not check if we have a path to given prefix, we issue
        # withdrawal. Hence multiple withdrawals have not side effect.
        return vrf_table.insert_vrf_path(prefix, is_withdraw=True)
Esempio n. 9
0
    def remove_from_vrf(self, route_dist, prefix, route_family):
        """Removes `prefix` from VRF identified by `route_dist`.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError
        # Validate given
        if route_family not in (VRF_RF_IPV4, VRF_RF_IPV6):
            raise BgpCoreError(desc='Unsupported route family %s' %
                                    route_family)
        val_ipv4 = route_family == VRF_RF_IPV4\
            and is_valid_ipv4_prefix(prefix)
        val_ipv6 = route_family == VRF_RF_IPV6\
            and is_valid_ipv6_prefix(prefix)

        if not val_ipv4 and not val_ipv6:
            raise BgpCoreError(desc='Invalid prefix or nexthop.')

        table_id = (route_dist, route_family)
        if route_family == VRF_RF_IPV4:
            vrf_table = self._tables.get(table_id)
            if not vrf_table:
                raise BgpCoreError(desc='Vrf for route distinguisher %s does '
                                        'not exist.' % route_dist)
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        else:
            vrf_table = self._tables.get(table_id)
            if not vrf_table:
                raise BgpCoreError(desc='Vrf for route distinguisher %s does '
                                        'not exist.' % route_dist)
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip)
            # We do not check if we have a path to given prefix, we issue
        # withdrawal. Hence multiple withdrawals have not side effect.
        return vrf_table.insert_vrf_path(prefix, is_withdraw=True)
    def test_update_vrf_table_ipv4_withdraw(self):
        # Prepare test data
        route_dist = '65000:100'
        ip_network = '192.168.0.0'
        ip_prefix_len = 24
        prefix_str = '%s/%d' % (ip_network, ip_prefix_len)
        prefix_inst = IPAddrPrefix(ip_prefix_len, ip_network)
        next_hop = '10.0.0.1'
        route_family = VRF_RF_IPV4
        route_type = None  # should be ignored
        kwargs = {}  # should be ignored

        self._test_update_vrf_table(prefix_inst, route_dist, prefix_str,
                                    next_hop, route_family, route_type,
                                    is_withdraw=True, **kwargs)
Esempio n. 11
0
 def monitor_bestpath_chenged(self, arguments):
     ribs = self.g_conn.MonitorBestChanged(api.Arguments(**arguments),
                                           self.monitor_timeout)
     for rib in ribs:
         for path in rib.paths:
             nlri = IPAddrPrefix.parser(path.nlri)
             prefix = nlri[0].prefix
             log.debug(
                 'Recv bgp route from gobgp: prefix={0}, withdraw={1}'.
                 format(prefix, path.is_withdraw))
             bgp_path = {
                 'prefix': prefix,
                 'metric': 0,
                 'is_withdraw': path.is_withdraw
             }
             bgp_pathattr = {
                 'BGP_uptime': '',
                 'BGP_iBGP': '',
                 'BGP_flags': '',
                 'BGP_internal': '',
                 'BGP_loc_pref': '0'
             }
             for pattr in path.pattrs:
                 path_attr = _PathAttribute.parser(pattr)
                 if isinstance(path_attr[0], BGPPathAttributeOrigin):
                     origin = path_attr[0].value
                     if origin == 0:
                         bgp_pathattr['BGP_origin'] = 'i'
                     elif origin == 1:
                         bgp_pathattr['BGP_origin'] = 'e'
                     else:
                         bgp_pathattr['BGP_origin'] = '?'
                 elif isinstance(path_attr[0], BGPPathAttributeAsPath):
                     if path_attr[0].type == 2:
                         bgp_pathattr['BGP_AS_path'] = '{0}'.format(
                             path_attr[0].value[0][0])
                 elif isinstance(path_attr[0],
                                 BGPPathAttributeMultiExitDisc):
                     bgp_path['BGP_MED'] = path_attr[0].value
                 elif isinstance(path_attr[0], BGPPathAttributeNextHop):
                     bgp_path['nexthop'] = path_attr[0].value
                 elif isinstance(path_attr[0], BGPPathAttributeCommunities):
                     communities = []
                     for community in path_attr[0].communities:
                         communities.append(community)
                     bgp_pathattr['BGP_Community'] = ','.join(communities)
             bgp_path['bgp_pathattr'] = bgp_pathattr
             self.o_hdr.mod_bgp_path(bgp_path)
Esempio n. 12
0
    def add_to_ipv4_global_table(self, prefix, is_withdraw=False):
        ip, masklen = prefix.split('/')
        _nlri = IPAddrPrefix(int(masklen), ip)
        src_ver_num = 1
        peer = None
        # set mandatory path attributes
        nexthop = '0.0.0.0'
        origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP)
        aspath = BGPPathAttributeAsPath([[]])

        pathattrs = OrderedDict()
        pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin
        pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath

        new_path = Ipv4Path(peer, _nlri, src_ver_num,
                            pattrs=pathattrs, nexthop=nexthop,
                            is_withdraw=is_withdraw)
        # add to global ipv4 table and propagates to neighbors
        self.learn_path(new_path)
    def update_global_table(self, prefix, next_hop=None, is_withdraw=False):
        """Update a BGP route in the Global table for the given `prefix`
        with the given `next_hop`.

        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.
        """
        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

        net = netaddr.IPNetwork(prefix)
        addr = str(net.ip)
        masklen = net.prefixlen
        if ip.valid_ipv4(addr):
            _nlri = IPAddrPrefix(masklen, addr)
            if next_hop is None:
                next_hop = '0.0.0.0'
            p = Ipv4Path
        else:
            _nlri = IP6AddrPrefix(masklen, addr)
            if next_hop is None:
                next_hop = '::'
            p = Ipv6Path

        new_path = p(peer,
                     _nlri,
                     src_ver_num,
                     pattrs=pathattrs,
                     nexthop=next_hop,
                     is_withdraw=is_withdraw)

        # add to global table and propagates to neighbors
        self.learn_path(new_path)
    def update_vrf_table(self,
                         route_dist,
                         prefix=None,
                         next_hop=None,
                         route_family=None,
                         route_type=None,
                         tunnel_type=None,
                         is_withdraw=False,
                         redundancy_mode=None,
                         pmsi_tunnel_type=None,
                         **kwargs):
        """Update a BGP route in the VRF table identified by `route_dist`
        with the given `next_hop`.

        If `is_withdraw` is False, which is the default, add a BGP route
        to the VRF table identified by `route_dist` with the given
        `next_hop`.
        If `is_withdraw` is True, remove a BGP route from the VRF table
        and the given `next_hop` is ignored.

        If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs`
        are required to construct EVPN NLRI and `prefix` is ignored.

        ``redundancy_mode`` specifies a redundancy mode type.

`       `pmsi_tunnel_type` specifies the type of the PMSI tunnel attribute
         used to encode the multicast tunnel identifier.
        This field is advertised only if route_type is
        EVPN_MULTICAST_ETAG_ROUTE.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError

        assert route_dist

        if is_withdraw:
            gen_lbl = False
            next_hop = None
        else:
            gen_lbl = True
            if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)):
                raise BgpCoreError(desc='Invalid IPv4/IPv6 nexthop: %s' %
                                   next_hop)

        vrf_table = self._tables.get((route_dist, route_family))
        if vrf_table is None:
            raise BgpCoreError(
                desc='VRF table  does not exist: route_dist=%s, '
                'route_family=%s' % (route_dist, route_family))

        vni = kwargs.get('vni', None)

        if route_family == VRF_RF_IPV4:
            if not is_valid_ipv4_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix)
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        elif route_family == VRF_RF_IPV6:
            if not is_valid_ipv6_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix)
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip6)
        elif route_family == VRF_RF_L2_EVPN:
            assert route_type
            if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME:
                # MPLS labels will be assigned automatically
                kwargs['mpls_labels'] = []
            if route_type == EvpnInclusiveMulticastEthernetTagNLRI.ROUTE_TYPE_NAME:
                # Inclusive Multicast Ethernet Tag Route does not have "vni",
                # omit "vni" from "kwargs" here.
                vni = kwargs.pop('vni', None)
            subclass = EvpnNLRI._lookup_type_name(route_type)
            kwargs['route_dist'] = route_dist
            esi = kwargs.get('esi', None)
            if esi is not None:
                if isinstance(esi, dict):
                    esi_type = esi.get('type', 0)
                    esi_class = EvpnEsi._lookup_type(esi_type)
                    kwargs['esi'] = esi_class.from_jsondict(esi)
                else:  # isinstance(esi, numbers.Integral)
                    kwargs['esi'] = EvpnArbitraryEsi(
                        type_desc.Int9.from_user(esi))
            if vni is not None:
                # Disable to generate MPLS labels,
                # because encapsulation type is not MPLS.
                from ryu.services.protocols.bgp.api.prefix import (
                    TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE)
                assert tunnel_type in [
                    None, TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE
                ]
                gen_lbl = False
            prefix = subclass(**kwargs)
        else:
            raise BgpCoreError(desc='Unsupported route family %s' %
                               route_family)

        # We do not check if we have a path to given prefix, we issue
        # withdrawal. Hence multiple withdrawals have not side effect.
        return vrf_table.insert_vrf_path(nlri=prefix,
                                         next_hop=next_hop,
                                         gen_lbl=gen_lbl,
                                         is_withdraw=is_withdraw,
                                         redundancy_mode=redundancy_mode,
                                         vni=vni,
                                         tunnel_type=tunnel_type,
                                         pmsi_tunnel_type=pmsi_tunnel_type)
Esempio n. 15
0
    def update_vrf_table(self,
                         route_dist,
                         prefix=None,
                         next_hop=None,
                         route_family=None,
                         route_type=None,
                         tunnel_type=None,
                         is_withdraw=False,
                         **kwargs):
        """Update a BGP route in the VRF table identified by `route_dist`
        with the given `next_hop`.

        If `is_withdraw` is False, which is the default, add a BGP route
        to the VRF table identified by `route_dist` with the given
        `next_hop`.
        If `is_withdraw` is True, remove a BGP route from the VRF table
        and the given `next_hop` is ignored.

        If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs`
        are required to construct EVPN NLRI and `prefix` is ignored.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError

        assert route_dist

        if is_withdraw:
            gen_lbl = False
            next_hop = None
        else:
            gen_lbl = True
            if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)):
                raise BgpCoreError(desc='Invalid IPv4/IPv6 nexthop: %s' %
                                   next_hop)

        vrf_table = self._tables.get((route_dist, route_family))
        if vrf_table is None:
            raise BgpCoreError(
                desc='VRF table  does not exist: route_dist=%s, '
                'route_family=%s' % (route_dist, route_family))

        if route_family == VRF_RF_IPV4:
            if not is_valid_ipv4_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix)
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        elif route_family == VRF_RF_IPV6:
            if not is_valid_ipv6_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix)
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip6)
        elif route_family == VRF_RF_L2_EVPN:
            assert route_type
            if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME:
                # MPLS labels will be assigned automatically
                kwargs['mpls_labels'] = []
            subclass = EvpnNLRI._lookup_type_name(route_type)
            kwargs['route_dist'] = route_dist
            esi = kwargs.get('esi', None)
            if esi is not None:
                # Note: Currently, we support arbitrary 9-octet ESI value only.
                kwargs['esi'] = EvpnArbitraryEsi(type_desc.Int9.from_user(esi))
            if 'vni' in kwargs:
                # Disable to generate MPLS labels, because encapsulation type
                # is not MPLS.
                from ryu.services.protocols.bgp.api.prefix import (
                    TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE)
                assert tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]
                gen_lbl = False
            prefix = subclass(**kwargs)
        else:
            raise BgpCoreError(desc='Unsupported route family %s' %
                               route_family)

        # We do not check if we have a path to given prefix, we issue
        # withdrawal. Hence multiple withdrawals have not side effect.
        return vrf_table.insert_vrf_path(nlri=prefix,
                                         next_hop=next_hop,
                                         gen_lbl=gen_lbl,
                                         is_withdraw=is_withdraw,
                                         tunnel_type=tunnel_type)
Esempio n. 16
0
    def update_vrf_table(self, route_dist, prefix=None, next_hop=None,
                         route_family=None, route_type=None, tunnel_type=None,
                         is_withdraw=False, **kwargs):
        """Update a BGP route in the VRF table identified by `route_dist`
        with the given `next_hop`.

        If `is_withdraw` is False, which is the default, add a BGP route
        to the VRF table identified by `route_dist` with the given
        `next_hop`.
        If `is_withdraw` is True, remove a BGP route from the VRF table
        and the given `next_hop` is ignored.

        If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs`
        are required to construct EVPN NLRI and `prefix` is ignored.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError

        assert route_dist

        if is_withdraw:
            gen_lbl = False
            next_hop = None
        else:
            gen_lbl = True
            if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)):
                raise BgpCoreError(
                    desc='Invalid IPv4/IPv6 nexthop: %s' % next_hop)

        vrf_table = self._tables.get((route_dist, route_family))
        if vrf_table is None:
            raise BgpCoreError(
                desc='VRF table  does not exist: route_dist=%s, '
                     'route_family=%s' % (route_dist, route_family))

        if route_family == VRF_RF_IPV4:
            if not is_valid_ipv4_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix)
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        elif route_family == VRF_RF_IPV6:
            if not is_valid_ipv6_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix)
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip6)
        elif route_family == VRF_RF_L2_EVPN:
            assert route_type
            if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME:
                # MPLS labels will be assigned automatically
                kwargs['mpls_labels'] = []
            subclass = EvpnNLRI._lookup_type_name(route_type)
            kwargs['route_dist'] = route_dist
            esi = kwargs.get('esi', None)
            if esi is not None:
                # Note: Currently, we support arbitrary 9-octet ESI value only.
                kwargs['esi'] = EvpnArbitraryEsi(type_desc.Int9.from_user(esi))
            if 'vni' in kwargs:
                # Disable to generate MPLS labels, because encapsulation type
                # is not MPLS.
                from ryu.services.protocols.bgp.api.prefix import (
                    TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE)
                assert tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]
                gen_lbl = False
            prefix = subclass(**kwargs)
        else:
            raise BgpCoreError(
                desc='Unsupported route family %s' % route_family)

        # We do not check if we have a path to given prefix, we issue
        # withdrawal. Hence multiple withdrawals have not side effect.
        return vrf_table.insert_vrf_path(
            nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl,
            is_withdraw=is_withdraw, tunnel_type=tunnel_type)
Esempio n. 17
0
    def update_vrf_table(self, route_dist, prefix=None, next_hop=None,
                         route_family=None, route_type=None, tunnel_type=None,
                         is_withdraw=False, redundancy_mode=None,
                         pmsi_tunnel_type=None, **kwargs):
        """Update a BGP route in the VRF table identified by `route_dist`
        with the given `next_hop`.

        If `is_withdraw` is False, which is the default, add a BGP route
        to the VRF table identified by `route_dist` with the given
        `next_hop`.
        If `is_withdraw` is True, remove a BGP route from the VRF table
        and the given `next_hop` is ignored.

        If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs`
        are required to construct EVPN NLRI and `prefix` is ignored.

        ``redundancy_mode`` specifies a redundancy mode type.

`       `pmsi_tunnel_type` specifies the type of the PMSI tunnel attribute
         used to encode the multicast tunnel identifier.
        This field is advertised only if route_type is
        EVPN_MULTICAST_ETAG_ROUTE.

        Returns assigned VPN label.
        """
        from ryu.services.protocols.bgp.core import BgpCoreError

        assert route_dist

        if is_withdraw:
            gen_lbl = False
            next_hop = None
        else:
            gen_lbl = True
            if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)):
                raise BgpCoreError(
                    desc='Invalid IPv4/IPv6 nexthop: %s' % next_hop)

        vrf_table = self._tables.get((route_dist, route_family))
        if vrf_table is None:
            raise BgpCoreError(
                desc='VRF table  does not exist: route_dist=%s, '
                     'route_family=%s' % (route_dist, route_family))

        vni = kwargs.get('vni', None)

        if route_family == VRF_RF_IPV4:
            if not is_valid_ipv4_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix)
            ip, masklen = prefix.split('/')
            prefix = IPAddrPrefix(int(masklen), ip)
        elif route_family == VRF_RF_IPV6:
            if not is_valid_ipv6_prefix(prefix):
                raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix)
            ip6, masklen = prefix.split('/')
            prefix = IP6AddrPrefix(int(masklen), ip6)
        elif route_family == VRF_RF_L2_EVPN:
            assert route_type
            if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME:
                # MPLS labels will be assigned automatically
                kwargs['mpls_labels'] = []
            subclass = EvpnNLRI._lookup_type_name(route_type)
            kwargs['route_dist'] = route_dist
            esi = kwargs.get('esi', None)
            if esi is not None:
                if isinstance(esi, dict):
                    esi_type = esi.get('type', 0)
                    esi_class = EvpnEsi._lookup_type(esi_type)
                    kwargs['esi'] = esi_class.from_jsondict(esi)
                else:  # isinstance(esi, numbers.Integral)
                    kwargs['esi'] = EvpnArbitraryEsi(
                        type_desc.Int9.from_user(esi))
            if vni is not None:
                # Disable to generate MPLS labels,
                # because encapsulation type is not MPLS.
                from ryu.services.protocols.bgp.api.prefix import (
                    TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE)
                assert tunnel_type in [
                    None, TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]
                gen_lbl = False
            prefix = subclass(**kwargs)
        else:
            raise BgpCoreError(
                desc='Unsupported route family %s' % route_family)

        # We do not check if we have a path to given prefix, we issue
        # withdrawal. Hence multiple withdrawals have not side effect.
        return vrf_table.insert_vrf_path(
            nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl,
            is_withdraw=is_withdraw, redundancy_mode=redundancy_mode,
            vni=vni, tunnel_type=tunnel_type,
            pmsi_tunnel_type=pmsi_tunnel_type)