mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-10-31 09:04:27 +00:00 
			
		
		
		
	bgpd: conditional advertisement - topotests
Router2# show ip bgp neighbors 10.10.20.3 json
!--- Output suppressed.
    "addressFamilyInfo":{
      "ipv4Unicast":{
        "updateGroupId":2,
        "subGroupId":2,
        "packetQueueLength":0,
        "inboundSoftConfigPermit":true,
        "commAttriSentToNbr":"extendedAndStandard",
        "advertiseMap":{
          "condition":"NON_EXIST",
          "conditionMap":"EXIST-MAP",
          "advertiseMap":"ADV-MAP",
          "advertiseStatus":"Withdraw"
        },
        "acceptedPrefixCounter":0,
        "sentPrefixCounter":2
      },
      "ipv6Unicast":{
        "inboundSoftConfigPermit":true,
        "commAttriSentToNbr":"extendedAndStandard",
        "advertiseMap":{
          "condition":"EXIST",
          "conditionMap":"ALLOW_ALL",
          "advertiseMap":"ALLOW_ALL",
          "advertiseStatus":"Advertise"
        },
        "acceptedPrefixCounter":0
      }
    },
!--- Output suppressed.
router@router:~/frr/tests/topotests/bgp_conditional_advertisement$ sudo pytest -s test_bgp_conditional_advertisement.py
[sudo] password for router:
mkdir: cannot create directory ‘/tmp/topotests’: File exists
2020-10-14 17:00:46,649 INFO: Running environment diagnostics
=========================================================================================== test session starts ============================================================================================
platform linux2 -- Python 2.7.17, pytest-4.6.11, py-1.9.0, pluggy-0.13.1
rootdir: /home/router/frr/tests/topotests, inifile: pytest.ini
collected 2 items
test_bgp_conditional_advertisement.py 2020-10-14 17:00:47,137 INFO: Testsuite start time: Wed Oct 14 17:00:47 2020
2020-10-14 17:00:47,137 INFO: ========================================
2020-10-14 17:00:47,138 INFO: Running setup_module to create topology
2020-10-14 17:00:48,711 INFO: loading topology: bgp_conditional_advertisement.test_bgp_conditional_advertisement
2020-10-14 17:00:48,712 INFO: starting topology: bgp_conditional_advertisement.test_bgp_conditional_advertisement
2020-10-14 17:00:49,042 INFO: r1: running version: 7.6-dev-MyOwnFRRVersion-gd77fe2dd0
2020-10-14 17:00:51,284 INFO: r2: running version: 7.6-dev-MyOwnFRRVersion-gd77fe2dd0
2020-10-14 17:00:53,582 INFO: r3: running version: 7.6-dev-MyOwnFRRVersion-gd77fe2dd0
2020-10-14 17:00:55,826 INFO: Running setup_module() done
2020-10-14 17:00:57,747 INFO: '_all_routes_advertised' polling started (interval 1 secs, maximum wait 130 secs)
2020-10-14 17:00:58,262 INFO: '_all_routes_advertised' succeeded after 0.52 seconds
2020-10-14 17:00:58,262 INFO: TC11: "router3" BGP convergence - PASSED!!!
2020-10-14 17:00:58,863 INFO: '_exist_map_routes_present' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:00:59,419 INFO: '_exist_map_routes_present' succeeded after 0.56 seconds
2020-10-14 17:00:59,419 INFO: TC21: exist-map routes present in "router2" BGP table - PASSED!!!
2020-10-14 17:01:00,017 INFO: '_exist_map_routes_not_present' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:02:00,192 INFO: '_exist_map_routes_not_present' succeeded after 60.18 seconds
2020-10-14 17:02:00,192 INFO: TC22: exist-map routes not present in "router2" BGP table - PASSED!!!
2020-10-14 17:02:00,736 INFO: '_non_exist_map_routes_not_present' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:02:59,215 INFO: '_non_exist_map_routes_not_present' succeeded after 58.48 seconds
2020-10-14 17:02:59,215 INFO: TC31: non-exist-map routes not present in "router2" BGP table - PASSED!!!
2020-10-14 17:02:59,968 INFO: '_non_exist_map_routes_present' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:03:59,300 INFO: '_non_exist_map_routes_present' succeeded after 59.33 seconds
2020-10-14 17:03:59,300 INFO: TC32: non-exist-map routes present in "router2" BGP table - PASSED!!!
2020-10-14 17:03:59,919 INFO: '_non_exist_map_no_condition_route_map' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:05:00,306 INFO: '_non_exist_map_no_condition_route_map' succeeded after 60.39 seconds
2020-10-14 17:05:00,306 INFO: TC41: non-exist-map route-map removed in "router2" - PASSED!!!
2020-10-14 17:05:01,024 INFO: '_exist_map_no_condition_route_map' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:05:59,405 INFO: '_exist_map_no_condition_route_map' succeeded after 58.38 seconds
2020-10-14 17:05:59,406 INFO: TC42: exist-map route-map removed in "router2" - PASSED!!!
2020-10-14 17:05:59,941 INFO: '_exist_map_routes_present_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:06:59,622 INFO: '_exist_map_routes_present_rmap_filter' succeeded after 59.68 seconds
2020-10-14 17:06:59,622 INFO: TC51: exist-map routes present with route-map filter - PASSED!!!
2020-10-14 17:07:00,150 INFO: '_exist_map_routes_present_no_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:07:00,688 INFO: '_exist_map_routes_present_no_rmap_filter' succeeded after 0.54 seconds
2020-10-14 17:07:00,688 INFO: TC52: exist-map routes present, no route-map filter - PASSED!!!
2020-10-14 17:07:01,229 INFO: '_non_exist_map_routes_present_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:07:01,767 INFO: '_non_exist_map_routes_present_rmap_filter' succeeded after 0.54 seconds
2020-10-14 17:07:01,767 INFO: TC53: non-exist-map routes present, with route-map filter - PASSED!!!
2020-10-14 17:07:02,321 INFO: '_non_exist_map_routes_present_no_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:08:00,419 INFO: '_non_exist_map_routes_present_no_rmap_filter' succeeded after 58.10 seconds
2020-10-14 17:08:00,419 INFO: TC54: non-exist-map routes present, no route-map filter - PASSED!!!
2020-10-14 17:08:01,485 INFO: '_exist_map_routes_not_present_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:08:02,039 INFO: '_exist_map_routes_not_present_rmap_filter' succeeded after 0.55 seconds
2020-10-14 17:08:02,039 INFO: TC61: exist-map routes not present, route-map filter - PASSED!!!
2020-10-14 17:08:02,568 INFO: '_exist_map_routes_not_present_no_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:08:59,147 INFO: '_exist_map_routes_not_present_no_rmap_filter' succeeded after 56.58 seconds
2020-10-14 17:08:59,147 INFO: TC62: exist-map routes not present, no route-map filter - PASSED!!!
2020-10-14 17:08:59,686 INFO: '_non_exist_map_routes_not_present_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:09:59,354 INFO: '_non_exist_map_routes_not_present_rmap_filter' succeeded after 59.67 seconds
2020-10-14 17:09:59,354 INFO: TC63: non-exist-map routes not present, route-map filter - PASSED!!!
2020-10-14 17:09:59,886 INFO: '_non_exist_map_routes_not_present_no_rmap_filter' polling started (interval 1 secs, maximum wait 90 secs)
2020-10-14 17:10:00,424 INFO: '_non_exist_map_routes_not_present_no_rmap_filter' succeeded after 0.54 seconds
2020-10-14 17:10:00,424 INFO: TC64: non-exist-map routes not present, no route-map filter - PASSED!!!
.2020-10-14 17:10:01,989 INFO: assert skipped at "bgp_conditional_advertisement.test_bgp_conditional_advertisement/test_memory_leak": Memory leak test/report is disabled
s2020-10-14 17:10:01,989 INFO: Running teardown_module to delete topology
2020-10-14 17:10:01,990 INFO: stopping topology: bgp_conditional_advertisement.test_bgp_conditional_advertisement
2020-10-14 17:10:01,990 INFO: stopping "s2"
2020-10-14 17:10:01,990 INFO: stopping "s1"
2020-10-14 17:10:01,993 INFO: r1: stopping bgpd
2020-10-14 17:10:01,995 INFO: r1: stopping staticd
2020-10-14 17:10:02,010 INFO: r1: stopping zebra
2020-10-14 17:10:02,013 INFO: r1: stopping bgpd
2020-10-14 17:10:02,015 INFO: r1: stopping zebra
2020-10-14 17:10:02,025 INFO: r1: waiting for daemons stopping: bgpd, zebra (0.1 seconds)
2020-10-14 17:10:02,143 INFO: r2: stopping bgpd
2020-10-14 17:10:02,147 INFO: r2: stopping staticd
2020-10-14 17:10:02,152 INFO: r2: stopping zebra
2020-10-14 17:10:02,156 INFO: r2: stopping bgpd
2020-10-14 17:10:02,164 INFO: r2: stopping zebra
2020-10-14 17:10:02,175 INFO: r2: waiting for daemons stopping: zebra (0.1 seconds)
2020-10-14 17:10:02,291 INFO: r3: stopping bgpd
2020-10-14 17:10:02,302 INFO: r3: stopping staticd
2020-10-14 17:10:02,309 INFO: r3: stopping zebra
2020-10-14 17:10:02,313 INFO: r3: stopping bgpd
2020-10-14 17:10:02,316 INFO: r3: stopping zebra
2020-10-14 17:10:02,323 INFO: r3: waiting for daemons stopping: zebra (0.1 seconds)
2020-10-14 17:10:03,615 INFO: Testsuite end time: Wed Oct 14 17:10:03 2020
2020-10-14 17:10:03,615 INFO: ========================================
================================================================================== 1 passed, 1 skipped in 556.55 seconds ===================================================================================
Signed-off-by: Madhuri Kuruganti <k.madhuri@samsung.com>
temp
Signed-off-by: Madhuri Kuruganti <k.madhuri@samsung.com>
			
			
This commit is contained in:
		
							parent
							
								
									52b8406259
								
							
						
					
					
						commit
						fa36596cbd
					
				| @ -222,11 +222,11 @@ static int bgp_conditional_adv_timer(struct thread *t) | ||||
| 			 * validation. | ||||
| 			 */ | ||||
| 			if (filter->advmap.condition == CONDITION_EXIST) | ||||
| 				filter->advmap.advertise = | ||||
| 				filter->advmap.update_type = | ||||
| 					(ret == RMAP_PERMITMATCH) ? ADVERTISE | ||||
| 								  : WITHDRAW; | ||||
| 			else | ||||
| 				filter->advmap.advertise = | ||||
| 				filter->advmap.update_type = | ||||
| 					(ret == RMAP_PERMITMATCH) ? WITHDRAW | ||||
| 								  : ADVERTISE; | ||||
| 
 | ||||
| @ -249,7 +249,7 @@ static int bgp_conditional_adv_timer(struct thread *t) | ||||
| 			/* Send update as per the conditional advertisement */ | ||||
| 			bgp_conditional_adv_routes(peer, afi, safi, table, | ||||
| 						   filter->advmap.amap, | ||||
| 						   filter->advmap.advertise); | ||||
| 						   filter->advmap.update_type); | ||||
| 		} | ||||
| 		peer->advmap_table_change = false; | ||||
| 	} | ||||
|  | ||||
| @ -10774,6 +10774,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, | ||||
| 	json_object *json_prefA = NULL; | ||||
| 	json_object *json_prefB = NULL; | ||||
| 	json_object *json_addr = NULL; | ||||
| 	json_object *json_advmap = NULL; | ||||
| 
 | ||||
| 	if (use_json) { | ||||
| 		json_addr = json_object_new_object(); | ||||
| @ -11048,6 +11049,26 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, | ||||
| 					       "selectiveUnsuppressRouteMap", | ||||
| 					       filter->usmap.name); | ||||
| 
 | ||||
| 		/* advertise-map */ | ||||
| 		if (filter->advmap.aname) { | ||||
| 			json_advmap = json_object_new_object(); | ||||
| 			json_object_string_add(json_advmap, "condition", | ||||
| 					       filter->advmap.condition | ||||
| 						       ? "EXIST" | ||||
| 						       : "NON_EXIST"); | ||||
| 			json_object_string_add(json_advmap, "conditionMap", | ||||
| 					       filter->advmap.cname); | ||||
| 			json_object_string_add(json_advmap, "advertiseMap", | ||||
| 					       filter->advmap.aname); | ||||
| 			json_object_string_add(json_advmap, "advertiseStatus", | ||||
| 					       filter->advmap.update_type | ||||
| 							       == ADVERTISE | ||||
| 						       ? "Advertise" | ||||
| 						       : "Withdraw"); | ||||
| 			json_object_object_add(json_addr, "advertiseMap", | ||||
| 					       json_advmap); | ||||
| 		} | ||||
| 
 | ||||
| 		/* Receive prefix count */ | ||||
| 		json_object_int_add(json_addr, "acceptedPrefixCounter", | ||||
| 				    p->pcount[afi][safi]); | ||||
| @ -11353,7 +11374,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, | ||||
| 				filter->advmap.cname, | ||||
| 				filter->advmap.amap ? "*" : "", | ||||
| 				filter->advmap.aname, | ||||
| 				filter->advmap.advertise == ADVERTISE | ||||
| 				filter->advmap.update_type == ADVERTISE | ||||
| 					? "Advertise" | ||||
| 					: "Withdraw"); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										113
									
								
								bgpd/bgpd.c
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								bgpd/bgpd.c
									
									
									
									
									
								
							| @ -6586,57 +6586,53 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void peer_update_rmap_filter_data(struct peer *peer, afi_t afi, | ||||
| 					 safi_t safi, const char *rmap_name1, | ||||
| 					 struct route_map *rmap1, | ||||
| 					 const char *rmap_name2, | ||||
| 					 struct route_map *rmap2, | ||||
| 					 uint8_t config_flags) | ||||
| static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi, | ||||
| 					     safi_t safi, const char *amap_name, | ||||
| 					     struct route_map *amap, | ||||
| 					     const char *cmap_name, | ||||
| 					     struct route_map *cmap, | ||||
| 					     bool condition, bool set) | ||||
| { | ||||
| 	struct bgp_filter *filter; | ||||
| 	bool filter_exists = false; | ||||
| 
 | ||||
| 	filter = &peer->filter[afi][safi]; | ||||
| 
 | ||||
| 	if (CHECK_FLAG(config_flags, BGP_PEER_ADVERTISE_MAP)) { | ||||
| 		/* advertise-map is already configured. */ | ||||
| 		if (filter->advmap.aname) { | ||||
| 			filter_exists = true; | ||||
| 			XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname); | ||||
| 			XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname); | ||||
| 		} | ||||
| 		route_map_counter_decrement(filter->advmap.amap); | ||||
| 	/* advertise-map is already configured. */ | ||||
| 	if (filter->advmap.aname) { | ||||
| 		filter_exists = true; | ||||
| 		XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname); | ||||
| 		XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname); | ||||
| 	} | ||||
| 
 | ||||
| 		/* Removed advertise-map configuration */ | ||||
| 		if (!CHECK_FLAG(config_flags, BGP_PEER_RMAP_SET)) { | ||||
| 			memset(filter, 0, sizeof(struct bgp_filter)); | ||||
| 	route_map_counter_decrement(filter->advmap.amap); | ||||
| 
 | ||||
| 			/* decrement condition_filter_count delete timer if
 | ||||
| 			 * this is the last advertise-map to be removed. | ||||
| 			 */ | ||||
| 			if (filter_exists) | ||||
| 				bgp_conditional_adv_disable(peer, afi, safi); | ||||
| 	/* Removed advertise-map configuration */ | ||||
| 	if (!set) { | ||||
| 		memset(filter, 0, sizeof(struct bgp_filter)); | ||||
| 
 | ||||
| 			return; | ||||
| 		} | ||||
| 		/* decrement condition_filter_count delete timer if
 | ||||
| 		 * this is the last advertise-map to be removed. | ||||
| 		 */ | ||||
| 		if (filter_exists) | ||||
| 			bgp_conditional_adv_disable(peer, afi, safi); | ||||
| 
 | ||||
| 		/* Update filter data with newly configured values. */ | ||||
| 		filter->advmap.aname = | ||||
| 			XSTRDUP(MTYPE_BGP_FILTER_NAME, rmap_name1); | ||||
| 		filter->advmap.cname = | ||||
| 			XSTRDUP(MTYPE_BGP_FILTER_NAME, rmap_name2); | ||||
| 		filter->advmap.amap = rmap1; | ||||
| 		filter->advmap.cmap = rmap2; | ||||
| 		filter->advmap.condition = | ||||
| 			CHECK_FLAG(config_flags, BGP_PEER_CONDITION_EXIST); | ||||
| 		route_map_counter_increment(filter->advmap.amap); | ||||
| 		peer->advmap_config_change[afi][safi] = true; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 		/* Increment condition_filter_count and/or create timer. */ | ||||
| 		if (!filter_exists) { | ||||
| 			filter->advmap.advertise = ADVERTISE; | ||||
| 			bgp_conditional_adv_enable(peer, afi, safi); | ||||
| 		} | ||||
| 	/* Update filter data with newly configured values. */ | ||||
| 	filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name); | ||||
| 	filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name); | ||||
| 	filter->advmap.amap = amap; | ||||
| 	filter->advmap.cmap = cmap; | ||||
| 	filter->advmap.condition = condition; | ||||
| 	route_map_counter_increment(filter->advmap.amap); | ||||
| 	peer->advmap_config_change[afi][safi] = true; | ||||
| 
 | ||||
| 	/* Increment condition_filter_count and/or create timer. */ | ||||
| 	if (!filter_exists) { | ||||
| 		filter->advmap.update_type = ADVERTISE; | ||||
| 		bgp_conditional_adv_enable(peer, afi, safi); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -6653,19 +6649,13 @@ int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi, | ||||
| 			   const char *condition_name, | ||||
| 			   struct route_map *condition_map, bool condition) | ||||
| { | ||||
| 	uint8_t config_flags = 0; | ||||
| 	struct peer *member; | ||||
| 	struct listnode *node, *nnode; | ||||
| 
 | ||||
| 	SET_FLAG(config_flags, BGP_PEER_RMAP_SET); | ||||
| 	SET_FLAG(config_flags, BGP_PEER_ADVERTISE_MAP); | ||||
| 	if (condition) | ||||
| 		SET_FLAG(config_flags, BGP_PEER_CONDITION_EXIST); | ||||
| 
 | ||||
| 	/* Set configuration on peer. */ | ||||
| 	peer_update_rmap_filter_data(peer, afi, safi, advertise_name, | ||||
| 				     advertise_map, condition_name, | ||||
| 				     condition_map, config_flags); | ||||
| 	peer_advertise_map_filter_update(peer, afi, safi, advertise_name, | ||||
| 					 advertise_map, condition_name, | ||||
| 					 condition_map, condition, true); | ||||
| 
 | ||||
| 	/* Check if handling a regular peer & Skip peer-group mechanics. */ | ||||
| 	if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { | ||||
| @ -6686,9 +6676,9 @@ int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi, | ||||
| 			continue; | ||||
| 
 | ||||
| 		/* Set configuration on peer-group member. */ | ||||
| 		peer_update_rmap_filter_data(member, afi, safi, advertise_name, | ||||
| 					     advertise_map, condition_name, | ||||
| 					     condition_map, config_flags); | ||||
| 		peer_advertise_map_filter_update( | ||||
| 			member, afi, safi, advertise_name, advertise_map, | ||||
| 			condition_name, condition_map, condition, true); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| @ -6701,13 +6691,12 @@ int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, | ||||
| 			     const char *condition_name, | ||||
| 			     struct route_map *condition_map, bool condition) | ||||
| { | ||||
| 	uint8_t config_flags = 0; | ||||
| 	struct peer *member; | ||||
| 	struct listnode *node, *nnode; | ||||
| 
 | ||||
| 	SET_FLAG(config_flags, BGP_PEER_ADVERTISE_MAP); | ||||
| 	if (condition) | ||||
| 		SET_FLAG(config_flags, BGP_PEER_CONDITION_EXIST); | ||||
| 	/* advertise-map is not configured */ | ||||
| 	if (!peer->filter[afi][safi].advmap.aname) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* Unset override-flag unconditionally. */ | ||||
| 	UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT], | ||||
| @ -6721,9 +6710,9 @@ int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, | ||||
| 		PEER_ATTR_INHERIT(peer, peer->group, | ||||
| 				  filter[afi][safi].advmap.amap); | ||||
| 	} else | ||||
| 		peer_update_rmap_filter_data(peer, afi, safi, advertise_name, | ||||
| 					     advertise_map, condition_name, | ||||
| 					     condition_map, config_flags); | ||||
| 		peer_advertise_map_filter_update( | ||||
| 			peer, afi, safi, advertise_name, advertise_map, | ||||
| 			condition_name, condition_map, condition, false); | ||||
| 
 | ||||
| 	/* Check if handling a regular peer and skip peer-group mechanics. */ | ||||
| 	if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { | ||||
| @ -6742,9 +6731,9 @@ int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, | ||||
| 			       PEER_FT_ADVERTISE_MAP)) | ||||
| 			continue; | ||||
| 		/* Remove configuration on peer-group member. */ | ||||
| 		peer_update_rmap_filter_data(member, afi, safi, advertise_name, | ||||
| 					     advertise_map, condition_name, | ||||
| 					     condition_map, config_flags); | ||||
| 		peer_advertise_map_filter_update( | ||||
| 			member, afi, safi, advertise_name, advertise_map, | ||||
| 			condition_name, condition_map, condition, false); | ||||
| 
 | ||||
| 		/* Process peer route updates. */ | ||||
| 		peer_on_policy_change(member, afi, safi, 1); | ||||
|  | ||||
							
								
								
									
										10
									
								
								bgpd/bgpd.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								bgpd/bgpd.h
									
									
									
									
									
								
							| @ -767,14 +767,6 @@ struct bgp_nexthop { | ||||
| #define CONDITION_NON_EXIST	false | ||||
| #define CONDITION_EXIST		true | ||||
| 
 | ||||
| /* BGP peer RMAP options */ | ||||
| #define BGP_PEER_ADVERTISE_MAP		(1 << 0) | ||||
| #define BGP_PEER_ROUTE_MAP		(1 << 1) | ||||
| #define BGP_PEER_UNSUPPRESS_MAP		(1 << 2) | ||||
| #define BGP_PEER_CONDITION_EXIST	(1 << 3) | ||||
| #define BGP_PEER_RMAP_DIRECTION		(1 << 4) | ||||
| #define BGP_PEER_RMAP_SET		(1 << 5) | ||||
| 
 | ||||
| enum update_type { WITHDRAW, ADVERTISE }; | ||||
| 
 | ||||
| #include "filter.h" | ||||
| @ -821,7 +813,7 @@ struct bgp_filter { | ||||
| 		char *cname; | ||||
| 		struct route_map *cmap; | ||||
| 
 | ||||
| 		enum update_type advertise; | ||||
| 		enum update_type update_type; | ||||
| 	} advmap; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										114
									
								
								doc/user/bgp.rst
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								doc/user/bgp.rst
									
									
									
									
									
								
							| @ -2633,16 +2633,22 @@ when the next instance of the BGP scanner occurs. | ||||
| .. index:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME | ||||
| .. clicmd:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME | ||||
| 
 | ||||
|    This command enables BGP scanner process to monitor route specified by | ||||
|    This command enables BGP scanner process to monitor routes specified by | ||||
|    exist-map or non-exist-map command in BGP table and conditionally advertises | ||||
|    the route specified by advertise-map command. | ||||
|    the routes specified by advertise-map command. | ||||
| 
 | ||||
| Sample Configuration | ||||
| ^^^^^^^^^^^^^^^^^^^^^ | ||||
| .. code-block:: frr | ||||
| 
 | ||||
|    interface enp0s9 | ||||
|     ip address 10.10.10.2/24 | ||||
|    ! | ||||
|    interface enp0s10 | ||||
|     ip address 10.10.20.2/24 | ||||
|    ! | ||||
|    interface lo | ||||
|    ip address 2.2.2.2/24 | ||||
|     ip address 203.0.113.1/32 | ||||
|    ! | ||||
|    router bgp 2 | ||||
|     bgp log-neighbor-changes | ||||
| @ -2651,125 +2657,131 @@ Sample Configuration | ||||
|     neighbor 10.10.20.3 remote-as 3 | ||||
|     ! | ||||
|     address-family ipv4 unicast | ||||
|      network 2.2.2.0/24 | ||||
|      network 20.20.0.0/16 | ||||
|      neighbor 10.10.10.1 soft-reconfiguration inbound | ||||
|      neighbor 10.10.10.1 advertise-map ADVERTISE non-exist-map CONDITION | ||||
|      neighbor 10.10.20.3 soft-reconfiguration inbound | ||||
|      neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP | ||||
|     exit-address-family | ||||
|    ! | ||||
|    access-list CONDITION seq 5 permit 3.3.3.0/24 | ||||
|    access-list ADVERTISE seq 5 permit 2.2.2.0/24 | ||||
|    ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32 | ||||
|    ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32 | ||||
|    ip prefix-list EXIST seq 5 permit 10.10.10.10/32 | ||||
|    ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0 | ||||
|    ip prefix-list IP1 seq 5 permit 10.139.224.0/20 | ||||
|    ! | ||||
|    route-map ADVERTISE permit 10 | ||||
|     match ip address ADVERTISE | ||||
|    bgp community-list standard DC-ROUTES seq 5 permit 64952:3008 | ||||
|    bgp community-list standard DC-ROUTES seq 10 permit 64671:501 | ||||
|    bgp community-list standard DC-ROUTES seq 15 permit 64950:3009 | ||||
|    bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200 | ||||
|    ! | ||||
|    route-map CONDITION permit 10 | ||||
|     match ip address CONDITION | ||||
|    route-map ADV-MAP permit 10 | ||||
|     match ip address prefix-list IP1 | ||||
|    ! | ||||
|    route-map ADV-MAP permit 20 | ||||
|     match community DC-ROUTES | ||||
|    ! | ||||
|    route-map EXIST-MAP permit 10 | ||||
|     match community DEFAULT-ROUTE | ||||
|     match ip address prefix-list DEFAULT-ROUTE | ||||
|    ! | ||||
| 
 | ||||
| Sample Output | ||||
| ^^^^^^^^^^^^^ | ||||
| 
 | ||||
| When 3.3.3.0/24 route is in R2'2 BGP rable, 2.2.2/0/24 is not adevrtised to R1. | ||||
| When default route is present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are not advertised to R3. | ||||
| 
 | ||||
| .. code-block:: frr | ||||
| 
 | ||||
|    Router2# show ip bgp | ||||
|    BGP table version is 24, local router ID is 128.16.16.1, vrf id 0 | ||||
|    BGP table version is 20, local router ID is 203.0.113.1, vrf id 0 | ||||
|    Default local pref 100, local AS 2 | ||||
|    Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath, | ||||
|                   i internal, r RIB-failure, S Stale, R Removed | ||||
|    Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self | ||||
|    Origin codes:  i - IGP, e - EGP, ? - incomplete | ||||
| 
 | ||||
|    Network             Next Hop            Metric LocPrf Weight Path | ||||
|    *> 1.1.1.0/24       10.10.10.1               0             0 1 i | ||||
|    *> 2.2.2.0/24       0.0.0.0                  0         32768 i | ||||
|    *> 3.3.3.0/24       10.10.20.3               0             0 3 i | ||||
|    *> 20.20.0.0/16     0.0.0.0                  0         32768 i | ||||
|       Network          Next Hop            Metric LocPrf Weight Path | ||||
|    *> 0.0.0.0/0        10.10.10.1               0             0 1 i | ||||
|    *> 10.139.224.0/20  10.10.10.1               0             0 1 ? | ||||
|    *> 192.0.2.1/32     10.10.10.1               0             0 1 i | ||||
|    *> 192.0.2.5/32     10.10.10.1               0             0 1 i | ||||
| 
 | ||||
|    Displayed  4 routes and 4 total paths | ||||
|    Router2# | ||||
| 
 | ||||
|    Router2# show ip bgp neighbors 10.10.10.1 | ||||
|    Router2# show ip bgp neighbors 10.10.20.3 | ||||
| 
 | ||||
|    !--- Output suppressed. | ||||
| 
 | ||||
|    For address family: IPv4 Unicast | ||||
|    Update group 5, subgroup 1 | ||||
|    Update group 7, subgroup 7 | ||||
|    Packet Queue length 0 | ||||
|    Inbound soft reconfiguration allowed | ||||
|    Community attribute sent to this neighbor(all) | ||||
|    Condition NON_EXIST, Condition-map *CONDITION, Advertise-map *ADVERTISE, status: Withdraw | ||||
|    1 accepted prefixes | ||||
|    Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Withdraw | ||||
|    0 accepted prefixes | ||||
| 
 | ||||
|    !--- Output suppressed. | ||||
| 
 | ||||
|    Router2# show ip bgp neighbors 10.10.10.1 advertised-routes | ||||
|    BGP table version is 24, local router ID is 128.16.16.1, vrf id 0 | ||||
|    Router2# show ip bgp neighbors 10.10.20.3 advertised-routes | ||||
|    BGP table version is 20, local router ID is 203.0.113.1, vrf id 0 | ||||
|    Default local pref 100, local AS 2 | ||||
|    Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath, | ||||
|                   i internal, r RIB-failure, S Stale, R Removed | ||||
|                i internal, r RIB-failure, S Stale, R Removed | ||||
|    Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self | ||||
|    Origin codes:  i - IGP, e - EGP, ? - incomplete | ||||
| 
 | ||||
|    Network          Next Hop            Metric LocPrf Weight Path | ||||
|    *> 1.1.1.0/24       0.0.0.0                                0 1 i | ||||
|    *> 3.3.3.0/24       0.0.0.0                                0 3 i | ||||
|    *> 20.20.0.0/16     0.0.0.0                  0         32768 i | ||||
|       Network          Next Hop            Metric LocPrf Weight Path | ||||
|    *> 0.0.0.0/0        0.0.0.0                                0 1 i | ||||
|    *> 192.0.2.5/32     0.0.0.0                                0 1 i | ||||
| 
 | ||||
|    Total number of prefixes 3 | ||||
|    Router2# | ||||
|    Total number of prefixes 2 | ||||
| 
 | ||||
| When 3.3.3.0/24 route is not in R2'2 BGP rable, 2.2.2/0/24 is adevrtised to R1. | ||||
| When default route is not present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are advertised to R3. | ||||
| 
 | ||||
| .. code-block:: frr | ||||
| 
 | ||||
|    Router2# show ip bgp | ||||
|    BGP table version is 25, local router ID is 128.16.16.1, vrf id 0 | ||||
|    BGP table version is 21, local router ID is 203.0.113.1, vrf id 0 | ||||
|    Default local pref 100, local AS 2 | ||||
|    Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath, | ||||
|                   i internal, r RIB-failure, S Stale, R Removed | ||||
|    Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self | ||||
|    Origin codes:  i - IGP, e - EGP, ? - incomplete | ||||
| 
 | ||||
|    Network             Next Hop            Metric LocPrf Weight Path | ||||
|    *> 1.1.1.0/24       10.10.10.1               0             0 1 i | ||||
|    *> 2.2.2.0/24       0.0.0.0                  0         32768 i | ||||
|    *> 20.20.0.0/16     0.0.0.0                  0         32768 i | ||||
|       Network          Next Hop            Metric LocPrf Weight Path | ||||
|    *> 10.139.224.0/20  10.10.10.1               0             0 1 ? | ||||
|    *> 192.0.2.1/32     10.10.10.1               0             0 1 i | ||||
|    *> 192.0.2.5/32     10.10.10.1               0             0 1 i | ||||
| 
 | ||||
|    Displayed  3 routes and 3 total paths | ||||
|    Router2# | ||||
| 
 | ||||
|    Router2# show ip bgp neighbors 10.10.10.1 | ||||
|    Router2# show ip bgp neighbors 10.10.20.3 | ||||
| 
 | ||||
|    !--- Output suppressed. | ||||
| 
 | ||||
|    For address family: IPv4 Unicast | ||||
|    Update group 5, subgroup 1 | ||||
|    Update group 7, subgroup 7 | ||||
|    Packet Queue length 0 | ||||
|    Inbound soft reconfiguration allowed | ||||
|    Community attribute sent to this neighbor(all) | ||||
|    Condition NON_EXIST, Condition-map *CONDITION, Advertise-map *ADVERTISE, status: Advertise | ||||
|    1 accepted prefixes | ||||
|    Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Advertise | ||||
|    0 accepted prefixes | ||||
| 
 | ||||
|    !--- Output suppressed. | ||||
| 
 | ||||
|    Router2# show ip bgp neighbors 10.10.10.1 advertised-routes | ||||
|    BGP table version is 25, local router ID is 128.16.16.1, vrf id 0 | ||||
|    Router2# show ip bgp neighbors 10.10.20.3 advertised-routes | ||||
|    BGP table version is 21, local router ID is 203.0.113.1, vrf id 0 | ||||
|    Default local pref 100, local AS 2 | ||||
|    Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath, | ||||
|                   i internal, r RIB-failure, S Stale, R Removed | ||||
|    Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self | ||||
|    Origin codes:  i - IGP, e - EGP, ? - incomplete | ||||
| 
 | ||||
|    Network             Next Hop            Metric LocPrf Weight Path | ||||
|    *> 1.1.1.0/24       0.0.0.0                                0 1 i | ||||
|    *> 2.2.2.0/24       0.0.0.0                  0         32768 i | ||||
|    *> 20.20.0.0/16     0.0.0.0                  0         32768 i | ||||
|       Network          Next Hop            Metric LocPrf Weight Path | ||||
|    *> 10.139.224.0/20  0.0.0.0                                0 1 ? | ||||
|    *> 192.0.2.1/32     0.0.0.0                                0 1 i | ||||
|    *> 192.0.2.5/32     0.0.0.0                                0 1 i | ||||
| 
 | ||||
|    Total number of prefixes 3 | ||||
|    Router2# | ||||
| 
 | ||||
| .. _bgp-debugging: | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										30
									
								
								tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| ! | ||||
| ip prefix-list CUST seq 5 permit 10.139.224.0/20 | ||||
| ip prefix-list DEFAULT seq 5 permit 0.0.0.0/0 | ||||
| ip prefix-list PL1 seq 5 permit 192.0.2.1/32 | ||||
| ! | ||||
| route-map CUST permit 10 | ||||
|  match ip address prefix-list CUST | ||||
|  set community 64671:501 | ||||
| ! | ||||
| route-map RM1 permit 10 | ||||
|  match ip address prefix-list PL1 | ||||
|  set community 64952:3008 | ||||
| ! | ||||
| route-map DEF permit 10 | ||||
|  match ip address prefix-list DEFAULT | ||||
|  set community 64848:3011 65011:200 65013:200 | ||||
| ! | ||||
| router bgp 1 | ||||
|  bgp log-neighbor-changes | ||||
|  no bgp ebgp-requires-policy | ||||
|  neighbor 10.10.10.2 remote-as 2 | ||||
|  ! | ||||
|  address-family ipv4 unicast | ||||
|   network 0.0.0.0/0 route-map DEF | ||||
|   network 192.0.2.1/32 route-map RM1 | ||||
|   network 192.0.2.5/32 | ||||
|   redistribute connected route-map CUST | ||||
|   neighbor 10.10.10.2 soft-reconfiguration inbound | ||||
|  exit-address-family | ||||
| ! | ||||
							
								
								
									
										19
									
								
								tests/topotests/bgp_conditional_advertisement/r1/zebra.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/topotests/bgp_conditional_advertisement/r1/zebra.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| ! | ||||
| hostname Router1 | ||||
| ! | ||||
| ip route 0.0.0.0/0 blackhole | ||||
| ip route 192.0.2.1/32 blackhole | ||||
| ip route 192.0.2.2/32 blackhole | ||||
| ip route 192.0.2.3/32 blackhole | ||||
| ip route 192.0.2.4/32 blackhole | ||||
| ip route 192.0.2.5/32 blackhole | ||||
| ! | ||||
| interface r1-eth0 | ||||
|  ip address 10.10.10.1/24 | ||||
| ! | ||||
| interface lo | ||||
|  ip address 10.139.224.1/20 | ||||
| ! | ||||
| ip forwarding | ||||
| ipv6 forwarding | ||||
| ! | ||||
							
								
								
									
										33
									
								
								tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| ! | ||||
| ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32 | ||||
| ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32 | ||||
| ip prefix-list EXIST seq 5 permit 10.10.10.10/32 | ||||
| ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0 | ||||
| ip prefix-list IP1 seq 5 permit 10.139.224.0/20 | ||||
| ! | ||||
| bgp community-list standard DC-ROUTES seq 5 permit 64952:3008 | ||||
| bgp community-list standard DC-ROUTES seq 10 permit 64671:501 | ||||
| bgp community-list standard DC-ROUTES seq 15 permit 64950:3009 | ||||
| bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200 | ||||
| ! | ||||
| route-map ADV-MAP permit 10 | ||||
|  match ip address prefix-list IP1 | ||||
| ! | ||||
| route-map ADV-MAP permit 20 | ||||
|  match community DC-ROUTES | ||||
| ! | ||||
| route-map EXIST-MAP permit 10 | ||||
|  match community DEFAULT-ROUTE | ||||
|  match ip address prefix-list DEFAULT-ROUTE | ||||
| ! | ||||
| router bgp 2 | ||||
|  bgp log-neighbor-changes | ||||
|  no bgp ebgp-requires-policy | ||||
|  neighbor 10.10.10.1 remote-as 1 | ||||
|  neighbor 10.10.20.3 remote-as 3 | ||||
|  ! | ||||
|  address-family ipv4 unicast | ||||
|   neighbor 10.10.10.1 soft-reconfiguration inbound | ||||
|   neighbor 10.10.20.3 soft-reconfiguration inbound | ||||
|  exit-address-family | ||||
| ! | ||||
							
								
								
									
										15
									
								
								tests/topotests/bgp_conditional_advertisement/r2/zebra.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/topotests/bgp_conditional_advertisement/r2/zebra.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| ! | ||||
| hostname Router2 | ||||
| ! | ||||
| interface r2-eth0 | ||||
|  ip address 10.10.10.2/24 | ||||
| ! | ||||
| interface r2-eth1 | ||||
|  ip address 10.10.20.2/24 | ||||
| ! | ||||
| interface lo | ||||
|  ip address 203.0.113.1/32 | ||||
| ! | ||||
| ip forwarding | ||||
| ipv6 forwarding | ||||
| ! | ||||
							
								
								
									
										11
									
								
								tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| ! | ||||
| router bgp 3 | ||||
|  bgp log-neighbor-changes | ||||
|  no bgp ebgp-requires-policy | ||||
|  neighbor 10.10.20.2 remote-as 2 | ||||
|  ! | ||||
|  address-family ipv4 unicast | ||||
|   neighbor 10.10.20.2 soft-reconfiguration inbound | ||||
|  exit-address-family | ||||
| ! | ||||
| 
 | ||||
							
								
								
									
										12
									
								
								tests/topotests/bgp_conditional_advertisement/r3/zebra.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tests/topotests/bgp_conditional_advertisement/r3/zebra.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| ! | ||||
| hostname Router3 | ||||
| ! | ||||
| interface r3-eth0 | ||||
|  ip address 10.10.20.3/24 | ||||
| ! | ||||
| interface lo | ||||
|  ip address 198.51.100.1/32 | ||||
| ! | ||||
| ip forwarding | ||||
| ipv6 forwarding | ||||
| ! | ||||
| @ -0,0 +1,585 @@ | ||||
| #!/usr/bin/env python | ||||
| 
 | ||||
| # | ||||
| # test_bgp_conditional_advertisement.py | ||||
| # Part of NetDEF Topology Tests | ||||
| # | ||||
| # Copyright (c) 2020 by | ||||
| # Network Device Education Foundation, Inc. ("NetDEF") | ||||
| # | ||||
| # Permission to use, copy, modify, and/or distribute this software | ||||
| # for any purpose with or without fee is hereby granted, provided | ||||
| # that the above copyright notice and this permission notice appear | ||||
| # in all copies. | ||||
| # | ||||
| # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES | ||||
| # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
| # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR | ||||
| # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY | ||||
| # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | ||||
| # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||||
| # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||||
| # OF THIS SOFTWARE. | ||||
| # | ||||
| 
 | ||||
| """ | ||||
| Test BGP conditional advertisement functionality. | ||||
| 
 | ||||
|     +--------+            +--------+            +--------+ | ||||
|     |        |            |        |            |        | | ||||
|     |   R1   |------------|   R2   |------------|   R3   | | ||||
|     |        |            |        |            |        | | ||||
|     +--------+            +--------+            +--------+ | ||||
| 
 | ||||
| R2 is DUT and peers with R1 and R3 in default bgp instance. | ||||
| 
 | ||||
| Following tests are covered under BGP conditional advertisement functionality. | ||||
| Conditional advertisement | ||||
| ------------------------- | ||||
| TC11: R3 BGP convergence, without advertise-map configuration. | ||||
|       All routes are advertised to R3. | ||||
| TC21: exist-map routes present in R2's BGP table. | ||||
|       advertise-map routes present in R2's BGP table are advertised to R3. | ||||
| TC22: exist-map routes not present in R2's BGP table | ||||
|       advertise-map routes present in R2's BGP table are withdrawn from R3. | ||||
| TC31: non-exist-map routes not present in R2's BGP table | ||||
|       advertise-map routes present in R2's BGP table are advertised to R3. | ||||
| TC32: non-exist-map routes present in R2's BGP table | ||||
|       advertise-map routes present in R2's BGP table are withdrawn from R3. | ||||
| TC41: non-exist-map route-map configuration removed in R2. | ||||
|       advertise-map routes present in R2's BGP table are advertised to R3. | ||||
| TC42: exist-map route-map configuration removed in R2 | ||||
|       advertise-map routes present in R2's BGP table are withdrawn from R3. | ||||
| 
 | ||||
| Conditional advertisement along with Route-map Filter | ||||
| ----------------------------------------------------- | ||||
| TC51: exist-map routes present in R2's BGP table, with route-map filter. | ||||
|       All routes are withdrawn from R3 except advertise-map routes. | ||||
| TC52: exist-map routes present in R2's BGP table, without route-map filter. | ||||
|       All routes are advertised to R3 including advertise-map routes. | ||||
| TC53: non-exist-map routes present in R2's BGP table, with route-map filter. | ||||
|       All routes are withdrawn from R3 including advertise-map routes. | ||||
| TC54: non-exist-map routes present in R2's BGP table, without route-map filter. | ||||
|       All routes are advertised to R3 except advertise-map routes. | ||||
| TC61: exist-map routes not present in R2's BGP table, with route-map filter. | ||||
|       All routes are withdrawn from R3 including advertise-map routes. | ||||
| TC62: exist-map routes not present in R2's BGP table, without route-map filter. | ||||
|       All routes are advertised to R3 except advertise-map routes. | ||||
| TC63: non-exist-map routes not present in R2's BGP table, with route-map filter. | ||||
|       All routes are withdrawn from R3 except advertise-map routes. | ||||
| TC64: non-exist-map routes not present in R2's BGP table, without route-map filter. | ||||
|       All routes are advertised to R3 including advertise-map routes. | ||||
| 
 | ||||
| 
 | ||||
| i.e. | ||||
| +----------------+-------------------------+------------------------+ | ||||
| |  Routes in     |  exist-map status       | advertise-map status   | | ||||
| |  BGP table     |                         |                        | | ||||
| +----------------+-------------------------+------------------------+ | ||||
| |  Present       |  Condition matched      | Advertise              | | ||||
| +----------------+-------------------------+------------------------+ | ||||
| |  Not Present   |  Condition not matched  | Withdrawn              | | ||||
| +----------------+-------------------------+------------------------+ | ||||
| |                |  non-exist-map status   | advertise-map status   | | ||||
| |                |                         |                        | | ||||
| +----------------+-------------------------+------------------------+ | ||||
| |  Present       |  Condition matched      | Withdrawn              | | ||||
| +----------------+-------------------------+------------------------+ | ||||
| |  Not Present   |  Condition not matched  | Advertise              | | ||||
| +----------------+-------------------------+------------------------+ | ||||
| Here in this topology, based on the default route presence in R2 and | ||||
| the configured condition-map (exist-map/non-exist-map) 10.139.224.0/20 | ||||
| will be either advertised/withdrawn to/from R3. | ||||
| """ | ||||
| 
 | ||||
| import os | ||||
| import sys | ||||
| import json | ||||
| import time | ||||
| import pytest | ||||
| import functools | ||||
| 
 | ||||
| CWD = os.path.dirname(os.path.realpath(__file__)) | ||||
| sys.path.append(os.path.join(CWD, "../")) | ||||
| 
 | ||||
| # pylint: disable=C0413 | ||||
| from lib import topotest | ||||
| from lib.topogen import Topogen, TopoRouter, get_topogen | ||||
| from lib.topolog import logger | ||||
| from mininet.topo import Topo | ||||
| 
 | ||||
| 
 | ||||
| class BgpConditionalAdvertisementTopo(Topo): | ||||
|     def build(self, *_args, **_opts): | ||||
|         tgen = get_topogen(self) | ||||
| 
 | ||||
|         r1 = tgen.add_router("r1") | ||||
|         r2 = tgen.add_router("r2") | ||||
|         r3 = tgen.add_router("r3") | ||||
| 
 | ||||
|         switch = tgen.add_switch("s1") | ||||
|         switch.add_link(r1) | ||||
|         switch.add_link(r2) | ||||
| 
 | ||||
|         switch = tgen.add_switch("s2") | ||||
|         switch.add_link(r2) | ||||
|         switch.add_link(r3) | ||||
| 
 | ||||
| 
 | ||||
| def setup_module(mod): | ||||
|     testsuite_run_time = time.asctime(time.localtime(time.time())) | ||||
|     logger.info("Testsuite start time: {}".format(testsuite_run_time)) | ||||
|     logger.info("=" * 40) | ||||
| 
 | ||||
|     logger.info("Running setup_module to create topology") | ||||
| 
 | ||||
|     tgen = Topogen(BgpConditionalAdvertisementTopo, mod.__name__) | ||||
|     tgen.start_topology() | ||||
| 
 | ||||
|     router_list = tgen.routers() | ||||
| 
 | ||||
|     for i, (rname, router) in enumerate(router_list.items(), 1): | ||||
|         router.load_config( | ||||
|             TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) | ||||
|         ) | ||||
|         router.load_config( | ||||
|             TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) | ||||
|         ) | ||||
| 
 | ||||
|     tgen.start_router() | ||||
| 
 | ||||
|     logger.info("Running setup_module() done") | ||||
| 
 | ||||
| 
 | ||||
| def teardown_module(mod): | ||||
|     """ | ||||
|     Teardown the pytest environment | ||||
|     * `mod`: module name | ||||
|     """ | ||||
| 
 | ||||
|     logger.info("Running teardown_module to delete topology") | ||||
| 
 | ||||
|     tgen = get_topogen() | ||||
|     tgen.stop_topology() | ||||
| 
 | ||||
|     logger.info( | ||||
|         "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) | ||||
|     ) | ||||
|     logger.info("=" * 40) | ||||
| 
 | ||||
| 
 | ||||
| def test_bgp_conditional_advertisement(): | ||||
|     """ | ||||
|     Test BGP conditional advertisement functionality. | ||||
|     """ | ||||
| 
 | ||||
|     tgen = get_topogen() | ||||
|     if tgen.routers_have_failure(): | ||||
|         pytest.skip(tgen.errors) | ||||
| 
 | ||||
|     router1 = tgen.gears["r1"] | ||||
|     router2 = tgen.gears["r2"] | ||||
|     router3 = tgen.gears["r3"] | ||||
| 
 | ||||
|     passed = "PASSED!!!" | ||||
|     failed = "FAILED!!!" | ||||
| 
 | ||||
|     def _all_routes_advertised(router): | ||||
|         output = json.loads(router.vtysh_cmd("show ip route json")) | ||||
|         expected = { | ||||
|             "0.0.0.0/0": [{"protocol": "bgp"}], | ||||
|             "192.0.2.1/32": [{"protocol": "bgp"}], | ||||
|             "192.0.2.5/32": [{"protocol": "bgp"}], | ||||
|             "10.139.224.0/20": [{"protocol": "bgp"}], | ||||
|         } | ||||
|         return topotest.json_cmp(output, expected) | ||||
| 
 | ||||
|     def _all_routes_withdrawn(router): | ||||
|         output = json.loads(router.vtysh_cmd("show ip route json")) | ||||
|         expected = { | ||||
|             "0.0.0.0/0": None, | ||||
|             "192.0.2.1/32": None, | ||||
|             "192.0.2.5/32": None, | ||||
|             "10.139.224.0/20": None, | ||||
|         } | ||||
|         return topotest.json_cmp(output, expected) | ||||
| 
 | ||||
|     def _exist_map_routes_present(router): | ||||
|         return _all_routes_advertised(router) | ||||
| 
 | ||||
|     def _exist_map_routes_not_present(router): | ||||
|         output = json.loads(router.vtysh_cmd("show ip route json")) | ||||
|         expected = { | ||||
|             "0.0.0.0/0": None, | ||||
|             "192.0.2.1/32": None, | ||||
|             "192.0.2.5/32": [{"protocol": "bgp"}], | ||||
|             "10.139.224.0/20": None, | ||||
|         } | ||||
|         return topotest.json_cmp(output, expected) | ||||
| 
 | ||||
|     def _non_exist_map_routes_present(router): | ||||
|         output = json.loads(router.vtysh_cmd("show ip route json")) | ||||
|         expected = { | ||||
|             "0.0.0.0/0": [{"protocol": "bgp"}], | ||||
|             "192.0.2.1/32": None, | ||||
|             "192.0.2.5/32": [{"protocol": "bgp"}], | ||||
|             "10.139.224.0/20": None, | ||||
|         } | ||||
|         return topotest.json_cmp(output, expected) | ||||
| 
 | ||||
|     def _non_exist_map_routes_not_present(router): | ||||
|         output = json.loads(router.vtysh_cmd("show ip route json")) | ||||
|         expected = { | ||||
|             "0.0.0.0/0": None, | ||||
|             "192.0.2.1/32": [{"protocol": "bgp"}], | ||||
|             "192.0.2.5/32": [{"protocol": "bgp"}], | ||||
|             "10.139.224.0/20": [{"protocol": "bgp"}], | ||||
|         } | ||||
|         return topotest.json_cmp(output, expected) | ||||
| 
 | ||||
|     def _exist_map_no_condition_route_map(router): | ||||
|         return _non_exist_map_routes_present(router) | ||||
| 
 | ||||
|     def _non_exist_map_no_condition_route_map(router): | ||||
|         return _all_routes_advertised(router) | ||||
| 
 | ||||
|     def _exist_map_routes_present_rmap_filter(router): | ||||
|         output = json.loads(router.vtysh_cmd("show ip route json")) | ||||
|         expected = { | ||||
|             "0.0.0.0/0": None, | ||||
|             "192.0.2.1/32": [{"protocol": "bgp"}], | ||||
|             "192.0.2.5/32": None, | ||||
|             "10.139.224.0/20": [{"protocol": "bgp"}], | ||||
|         } | ||||
|         return topotest.json_cmp(output, expected) | ||||
| 
 | ||||
|     def _exist_map_routes_present_no_rmap_filter(router): | ||||
|         return _all_routes_advertised(router) | ||||
| 
 | ||||
|     def _non_exist_map_routes_present_rmap_filter(router): | ||||
|         return _all_routes_withdrawn(router) | ||||
| 
 | ||||
|     def _non_exist_map_routes_present_no_rmap_filter(router): | ||||
|         return _non_exist_map_routes_present(router) | ||||
| 
 | ||||
|     def _exist_map_routes_not_present_rmap_filter(router): | ||||
|         return _all_routes_withdrawn(router) | ||||
| 
 | ||||
|     def _exist_map_routes_not_present_no_rmap_filter(router): | ||||
|         return _exist_map_routes_not_present(router) | ||||
| 
 | ||||
|     def _non_exist_map_routes_not_present_rmap_filter(router): | ||||
|         return _exist_map_routes_present_rmap_filter(router) | ||||
| 
 | ||||
|     def _non_exist_map_routes_not_present_no_rmap_filter(router): | ||||
|         return _non_exist_map_routes_not_present(router) | ||||
| 
 | ||||
|     # TC11: R3 BGP convergence, without advertise-map configuration. | ||||
|     # All routes are advertised to R3. | ||||
|     test_func = functools.partial(_all_routes_advertised, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=130, wait=1) | ||||
| 
 | ||||
|     msg = 'TC11: "router3" BGP convergence - ' | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC21: exist-map routes present in R2's BGP table. | ||||
|     # advertise-map routes present in R2's BGP table are advertised to R3. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 2 | ||||
|               address-family ipv4 unicast | ||||
|                neighbor 10.10.20.3 advertise-map ADV-MAP exist-map EXIST-MAP | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_exist_map_routes_present, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = 'TC21: exist-map routes present in "router2" BGP table - ' | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC22: exist-map routes not present in R2's BGP table | ||||
|     # advertise-map routes present in R2's BGP table are withdrawn from R3. | ||||
|     router1.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 1 | ||||
|               address-family ipv4 unicast | ||||
|                no network 0.0.0.0/0 route-map DEF | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_exist_map_routes_not_present, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = 'TC22: exist-map routes not present in "router2" BGP table - ' | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC31: non-exist-map routes not present in R2's BGP table | ||||
|     # advertise-map routes present in R2's BGP table are advertised to R3. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 2 | ||||
|               address-family ipv4 unicast | ||||
|                neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_non_exist_map_routes_not_present, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = 'TC31: non-exist-map routes not present in "router2" BGP table - ' | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC32: non-exist-map routes present in R2's BGP table | ||||
|     # advertise-map routes present in R2's BGP table are withdrawn from R3. | ||||
|     router1.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 1 | ||||
|               address-family ipv4 unicast | ||||
|                network 0.0.0.0/0 route-map DEF | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_non_exist_map_routes_present, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = 'TC32: non-exist-map routes present in "router2" BGP table - ' | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC41: non-exist-map route-map configuration removed in R2. | ||||
|     # advertise-map routes present in R2's BGP table are advertised to R3. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|            no route-map EXIST-MAP permit 10 | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_non_exist_map_no_condition_route_map, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = 'TC41: non-exist-map route-map removed in "router2" - ' | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC42: exist-map route-map configuration removed in R2 | ||||
|     # advertise-map routes present in R2's BGP table are withdrawn from R3. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 2 | ||||
|               address-family ipv4 unicast | ||||
|                neighbor 10.10.20.3 advertise-map ADV-MAP exist-map EXIST-MAP | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_exist_map_no_condition_route_map, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = 'TC42: exist-map route-map removed in "router2" - ' | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC51: exist-map routes present in R2's BGP table, with route-map filter. | ||||
|     # All routes are withdrawn from R3 except advertise-map routes. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|            route-map EXIST-MAP permit 10 | ||||
|             match community DEFAULT-ROUTE | ||||
|             match ip address prefix-list DEFAULT-ROUTE | ||||
|            ! | ||||
|            route-map RMAP deny 10 | ||||
|             match ip address prefix-list IP1 | ||||
|            ! | ||||
|            router bgp 2 | ||||
|             address-family ipv4 unicast | ||||
|              neighbor 10.10.20.3 route-map RMAP out | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_exist_map_routes_present_rmap_filter, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC51: exist-map routes present with route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC52: exist-map routes present in R2's BGP table, no route-map filter. | ||||
|     # All routes are advertised to R3 including advertise-map routes. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|            router bgp 2 | ||||
|             address-family ipv4 unicast | ||||
|              no neighbor 10.10.20.3 route-map RMAP out | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_exist_map_routes_present_no_rmap_filter, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC52: exist-map routes present, no route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC53: non-exist-map routes present in R2's BGP table, with route-map filter. | ||||
|     # All routes are withdrawn from R3 including advertise-map routes. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 2 | ||||
|               address-family ipv4 unicast | ||||
|                neighbor 10.10.20.3 route-map RMAP out | ||||
|                neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_non_exist_map_routes_present_rmap_filter, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC53: non-exist-map routes present, with route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC54: non-exist-map routes present in R2's BGP table, no route-map filter. | ||||
|     # All routes are advertised to R3 except advertise-map routes. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 2 | ||||
|               address-family ipv4 unicast | ||||
|                no neighbor 10.10.20.3 route-map RMAP out | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_non_exist_map_routes_present_no_rmap_filter, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC54: non-exist-map routes present, no route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC61: exist-map routes not present in R2's BGP table, with route-map filter. | ||||
|     # All routes are withdrawn from R3 including advertise-map routes. | ||||
|     router1.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|             router bgp 1 | ||||
|               address-family ipv4 unicast | ||||
|                no network 0.0.0.0/0 route-map DEF | ||||
|         """ | ||||
|     ) | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|            router bgp 2 | ||||
|             address-family ipv4 unicast | ||||
|              neighbor 10.10.20.3 route-map RMAP out | ||||
|              neighbor 10.10.20.3 advertise-map ADV-MAP exist-map EXIST-MAP | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_exist_map_routes_not_present_rmap_filter, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC61: exist-map routes not present, route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC62: exist-map routes not present in R2's BGP table, without route-map filter. | ||||
|     # All routes are advertised to R3 except advertise-map routes. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|            router bgp 2 | ||||
|             address-family ipv4 unicast | ||||
|              no neighbor 10.10.20.3 route-map RMAP out | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial(_exist_map_routes_not_present_no_rmap_filter, router3) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC62: exist-map routes not present, no route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC63: non-exist-map routes not present in R2's BGP table, with route-map filter. | ||||
|     # All routes are withdrawn from R3 except advertise-map routes. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|            router bgp 2 | ||||
|             address-family ipv4 unicast | ||||
|              neighbor 10.10.20.3 route-map RMAP out | ||||
|              neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial( | ||||
|         _non_exist_map_routes_not_present_rmap_filter, router3 | ||||
|     ) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC63: non-exist-map routes not present, route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
|     # TC64: non-exist-map routes not present in R2's BGP table, without route-map filter. | ||||
|     # All routes are advertised to R3 including advertise-map routes. | ||||
|     router2.vtysh_cmd( | ||||
|         """ | ||||
|           configure terminal | ||||
|            router bgp 2 | ||||
|             address-family ipv4 unicast | ||||
|              no neighbor 10.10.20.3 route-map RMAP out | ||||
|         """ | ||||
|     ) | ||||
| 
 | ||||
|     test_func = functools.partial( | ||||
|         _non_exist_map_routes_not_present_no_rmap_filter, router3 | ||||
|     ) | ||||
|     success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) | ||||
| 
 | ||||
|     msg = "TC64: non-exist-map routes not present, no route-map filter - " | ||||
|     assert result is None, msg + failed | ||||
| 
 | ||||
|     logger.info(msg + passed) | ||||
| 
 | ||||
| 
 | ||||
| def test_memory_leak(): | ||||
|     "Run the memory leak test and report results." | ||||
|     tgen = get_topogen() | ||||
|     if not tgen.is_memleak_enabled(): | ||||
|         pytest.skip("Memory leak test/report is disabled") | ||||
| 
 | ||||
|     tgen.report_memory_leaks() | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     args = ["-s"] + sys.argv[1:] | ||||
|     sys.exit(pytest.main(args)) | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Madhuri Kuruganti
						Madhuri Kuruganti