summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMadhuri Kuruganti <k.madhuri@samsung.com>2020-10-14 01:44:27 +0530
committerMadhuri Kuruganti <k.madhuri@samsung.com>2020-10-27 16:15:36 +0530
commitfa36596cbd4206b59411036d6df8c6dcec88c4b8 (patch)
tree895e84d9501cbc9c6d2b7f932e8ea39b2b032de7
parent52b8406259b3a3a6855069f9cd4948e61325bdb0 (diff)
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>
-rw-r--r--bgpd/bgp_conditional_adv.c6
-rw-r--r--bgpd/bgp_vty.c23
-rw-r--r--bgpd/bgpd.c115
-rw-r--r--bgpd/bgpd.h10
-rw-r--r--doc/user/bgp.rst114
-rw-r--r--tests/topotests/bgp_conditional_advertisement/__init__.py0
-rw-r--r--tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf30
-rw-r--r--tests/topotests/bgp_conditional_advertisement/r1/zebra.conf19
-rw-r--r--tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf33
-rw-r--r--tests/topotests/bgp_conditional_advertisement/r2/zebra.conf15
-rw-r--r--tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf11
-rw-r--r--tests/topotests/bgp_conditional_advertisement/r3/zebra.conf12
-rw-r--r--tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py585
13 files changed, 846 insertions, 127 deletions
diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c
index 07b3b4143b..521c8056f5 100644
--- a/bgpd/bgp_conditional_adv.c
+++ b/bgpd/bgp_conditional_adv.c
@@ -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;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 17a4411c82..bb202718ac 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -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");
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 0e8970d685..db72eb1775 100644
--- a/bgpd/bgpd.c
+++ b/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;
-
- /* Increment condition_filter_count and/or create timer. */
- if (!filter_exists) {
- filter->advmap.advertise = ADVERTISE;
- bgp_conditional_adv_enable(peer, afi, safi);
- }
+ return;
+ }
+
+ /* 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);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 39efab2899..4eb5bdd018 100644
--- a/bgpd/bgpd.h
+++ b/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;
};
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index f79d33a260..339be7f4d6 100644
--- a/doc/user/bgp.rst
+++ b/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
+ !
+ 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 ADVERTISE permit 10
- match ip address ADVERTISE
+ route-map ADV-MAP permit 10
+ match ip address prefix-list IP1
!
- route-map CONDITION permit 10
- match ip address CONDITION
+ 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:
diff --git a/tests/topotests/bgp_conditional_advertisement/__init__.py b/tests/topotests/bgp_conditional_advertisement/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/__init__.py
diff --git a/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf
new file mode 100644
index 0000000000..633d1832fd
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf
@@ -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
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf
new file mode 100644
index 0000000000..bb887e41ad
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf
@@ -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
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf
new file mode 100644
index 0000000000..c8f4357f99
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf
@@ -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
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf
new file mode 100644
index 0000000000..434ab68e3c
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf
@@ -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
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf
new file mode 100644
index 0000000000..2f4f5068d8
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf
@@ -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
+!
+
diff --git a/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf
new file mode 100644
index 0000000000..0dadfdb3a9
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf
@@ -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
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py
new file mode 100644
index 0000000000..e509882448
--- /dev/null
+++ b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py
@@ -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))