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!"
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)
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 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)
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)
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 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
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