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!"
Beispiel #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 _test_update_global_table(self, learn_path_mock, prefix, next_hop,
                                  is_withdraw, expected_next_hop):
        # Prepare test data
        origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP)
        aspath = BGPPathAttributeAsPath([[]])
        pathattrs = OrderedDict()
        pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin
        pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath
        pathattrs = str(pathattrs)

        # Instantiate TableCoreManager
        tbl_mng = table_manager.TableCoreManager(None, None)

        # Test
        tbl_mng.update_global_table(
            prefix=prefix,
            next_hop=next_hop,
            is_withdraw=is_withdraw,
        )

        # Check
        call_args_list = learn_path_mock.call_args_list
        ok_(len(call_args_list) == 1)  # learn_path should be called once
        args, kwargs = call_args_list[0]
        ok_(len(kwargs) == 0)  # no keyword argument
        output_path = args[0]
        eq_(None, output_path.source)
        eq_(prefix, output_path.nlri.prefix)
        eq_(pathattrs, str(output_path.pathattr_map))
        eq_(expected_next_hop, output_path.nexthop)
        eq_(is_withdraw, output_path.is_withdraw)
    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)
Beispiel #5
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
Beispiel #6
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 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)
Beispiel #8
0
    def _add_rt_nlri_for_as(self, rtc_as, route_target, is_withdraw=False):
        from ryu.services.protocols.bgp.core import EXPECTED_ORIGIN
        rt_nlri = RouteTargetMembershipNLRI(rtc_as, route_target)
        # Create a dictionary for path-attrs.
        pattrs = OrderedDict()
        if not is_withdraw:
            # MpReachNlri and/or MpUnReachNlri attribute info. is contained
            # in the path. Hence we do not add these attributes here.
            pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin(
                EXPECTED_ORIGIN)
            pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([])

        # Create Path instance and initialize appropriately.
        path = RtcPath(None, rt_nlri, 0, is_withdraw=is_withdraw,
                       pattrs=pattrs)
        tm = self._core_service.table_manager
        tm.learn_path(path)
Beispiel #9
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)
Beispiel #11
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
Beispiel #12
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