summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_interface.c47
-rw-r--r--babeld/babel_interface.h5
-rw-r--r--babeld/babel_main.c2
-rw-r--r--babeld/babel_zebra.c4
-rw-r--r--bfdd/ptm_adapter.c37
-rw-r--r--bgpd/bgp_bmp.c2
-rw-r--r--bgpd/bgp_evpn_vty.c39
-rw-r--r--bgpd/bgp_route.c28
-rw-r--r--bgpd/bgp_snmp.c2
-rw-r--r--bgpd/bgp_vty.c12
-rw-r--r--bgpd/bgp_zebra.c88
-rw-r--r--doc/user/zebra.rst7
-rw-r--r--eigrpd/eigrp_interface.c92
-rw-r--r--eigrpd/eigrp_interface.h1
-rw-r--r--eigrpd/eigrp_zebra.c147
-rw-r--r--include/linux/netlink.h4
-rw-r--r--include/linux/rtnetlink.h8
-rw-r--r--isisd/isis_circuit.c49
-rw-r--r--isisd/isis_circuit.h2
-rw-r--r--isisd/isis_pdu.c2
-rw-r--r--isisd/isis_zebra.c79
-rw-r--r--isisd/isis_zebra.h2
-rw-r--r--ldpd/ldp_zebra.c49
-rw-r--r--lib/if.c50
-rw-r--r--lib/if.h16
-rw-r--r--lib/printf/printf-pos.c6
-rw-r--r--lib/typesafe.c2
-rw-r--r--lib/zclient.c74
-rw-r--r--lib/zclient.h6
-rw-r--r--nhrpd/nhrp_interface.c38
-rw-r--r--nhrpd/nhrp_main.c2
-rw-r--r--nhrpd/nhrp_route.c4
-rw-r--r--nhrpd/nhrpd.h4
-rw-r--r--ospf6d/ospf6_interface.c54
-rw-r--r--ospf6d/ospf6_zebra.c55
-rw-r--r--ospfd/ospf_ase.c4
-rw-r--r--ospfd/ospf_interface.c127
-rw-r--r--ospfd/ospf_interface.h5
-rw-r--r--ospfd/ospf_lsa.c2
-rw-r--r--ospfd/ospf_zebra.c172
-rw-r--r--ospfd/ospf_zebra.h3
-rw-r--r--ospfd/ospfd.c1
-rw-r--r--pbrd/pbr_main.c2
-rw-r--r--pbrd/pbr_zebra.c40
-rw-r--r--pbrd/pbr_zebra.h6
-rw-r--r--pimd/pim_hello.c2
-rw-r--r--pimd/pim_iface.c166
-rw-r--r--pimd/pim_iface.h6
-rw-r--r--pimd/pim_main.c2
-rw-r--r--pimd/pim_zebra.c222
-rw-r--r--pimd/pim_zebra.h3
-rw-r--r--ripd/rip_interface.c49
-rw-r--r--ripd/rip_snmp.c2
-rw-r--r--ripd/rip_zebra.c4
-rw-r--r--ripngd/ripng_interface.c54
-rw-r--r--ripngd/ripng_zebra.c4
-rw-r--r--ripngd/ripngd.c2
-rw-r--r--sharpd/sharp_zebra.c127
-rw-r--r--staticd/static_zebra.c78
-rw-r--r--tests/lib/test_typelist.h2
-rw-r--r--tests/topotests/bgp-route-map/bgp_route_map_topo1.json187
-rwxr-xr-xtests/topotests/bgp-route-map/bgp_route_map_topo2.json316
-rwxr-xr-xtests/topotests/bgp-route-map/test_route_map_topo1.py1361
-rwxr-xr-xtests/topotests/bgp-route-map/test_route_map_topo2.py3916
-rwxr-xr-xtests/topotests/conftest.py6
-rw-r--r--tests/topotests/lib/bgp.py144
-rw-r--r--tests/topotests/lib/common_config.py458
-rw-r--r--tests/topotests/lib/topojson.py2
-rw-r--r--vrrpd/vrrp_vty.c1
-rw-r--r--vrrpd/vrrp_zebra.c70
-rw-r--r--vrrpd/vrrp_zebra.h5
-rw-r--r--zebra/if_netlink.c14
-rw-r--r--zebra/interface.c12
-rw-r--r--zebra/irdp.h10
-rw-r--r--zebra/redistribute.c21
-rw-r--r--zebra/rtadv.c4
-rw-r--r--zebra/zebra_rib.c12
-rw-r--r--zebra/zebra_vrf.c6
78 files changed, 7319 insertions, 1330 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c
index 0eeb9b2bbb..7f9a13c271 100644
--- a/babeld/babel_interface.c
+++ b/babeld/babel_interface.c
@@ -86,16 +86,10 @@ babel_interface_up (ZAPI_CALLBACK_ARGS)
}
int
-babel_interface_down (ZAPI_CALLBACK_ARGS)
+babel_ifp_down(struct interface *ifp)
{
- struct stream *s = NULL;
- struct interface *ifp = NULL;
-
debugf(BABEL_DEBUG_IF, "receive a 'interface down'");
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id); /* it updates iflist */
-
if (ifp == NULL) {
return 0;
}
@@ -104,45 +98,23 @@ babel_interface_down (ZAPI_CALLBACK_ARGS)
return 0;
}
-int
-babel_interface_add (ZAPI_CALLBACK_ARGS)
+int babel_ifp_create (struct interface *ifp)
{
- struct interface *ifp = NULL;
-
debugf(BABEL_DEBUG_IF, "receive a 'interface add'");
- /* read and add the interface in the iflist. */
- ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
-
- if (ifp == NULL) {
- return 0;
- }
-
interface_recalculate(ifp);
- return 0;
-}
+
+ return 0;
+ }
int
-babel_interface_delete (ZAPI_CALLBACK_ARGS)
+babel_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
debugf(BABEL_DEBUG_IF, "receive a 'interface delete'");
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id); /* it updates iflist */
-
- if (ifp == NULL)
- return 0;
-
if (IS_ENABLE(ifp))
interface_reset(ifp);
- /* To support pseudo interface do not free interface structure. */
- /* if_delete(ifp); */
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
@@ -1095,7 +1067,7 @@ DEFUN (show_babel_route_prefix,
vty_out (vty, "%% Malformed address\n");
return CMD_WARNING;
}
-
+
routes = route_stream(0);
if(routes) {
while(1) {
@@ -1260,6 +1232,11 @@ DEFUN (show_babel_parameters,
return CMD_SUCCESS;
}
+int babel_ifp_up(struct interface *ifp)
+{
+ return 0;
+}
+
void
babel_if_init(void)
{
diff --git a/babeld/babel_interface.h b/babeld/babel_interface.h
index d9e2745827..9833827927 100644
--- a/babeld/babel_interface.h
+++ b/babeld/babel_interface.h
@@ -121,6 +121,11 @@ int babel_interface_delete (int, struct zclient *, zebra_size_t, vrf_id_t);
int babel_interface_address_add (int, struct zclient *, zebra_size_t, vrf_id_t);
int babel_interface_address_delete (int, struct zclient *, zebra_size_t, vrf_id_t);
+int babel_ifp_create(struct interface *ifp);
+int babel_ifp_up(struct interface *ifp);
+int babel_ifp_down(struct interface *ifp);
+int babel_ifp_destroy(struct interface *ifp);
+
unsigned jitter(babel_interface_nfo *, int);
unsigned update_jitter(babel_interface_nfo *babel_ifp, int urgent);
/* return "true" if "address" is one of our ipv6 addresses */
diff --git a/babeld/babel_main.c b/babeld/babel_main.c
index a3f2b4e7d8..4bb8408157 100644
--- a/babeld/babel_main.c
+++ b/babeld/babel_main.c
@@ -202,6 +202,8 @@ main(int argc, char **argv)
babel_replace_by_null(STDIN_FILENO);
/* init some quagga's dependencies, and babeld's commands */
+ if_zapi_callbacks(babel_ifp_create, babel_ifp_up,
+ babel_ifp_down, babel_ifp_destroy);
babeld_quagga_init();
/* init zebra client's structure and it's commands */
/* this replace kernel_setup && kernel_setup_socket */
diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c
index d70823544a..5a336df7b5 100644
--- a/babeld/babel_zebra.c
+++ b/babeld/babel_zebra.c
@@ -240,10 +240,6 @@ void babelz_zebra_init(void)
zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
zclient->zebra_connected = babel_zebra_connected;
- zclient->interface_add = babel_interface_add;
- zclient->interface_delete = babel_interface_delete;
- zclient->interface_up = babel_interface_up;
- zclient->interface_down = babel_interface_down;
zclient->interface_address_add = babel_interface_address_add;
zclient->interface_address_delete = babel_interface_address_delete;
zclient->redistribute_route_add = babel_zebra_read_route;
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index ae6d04e77d..1b3219c235 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -673,33 +673,10 @@ void bfdd_sessions_disable_vrf(struct vrf *vrf)
}
}
-static int bfdd_interface_update(ZAPI_CALLBACK_ARGS)
+static int bfd_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
-
- /*
- * `zebra_interface_add_read` will handle the interface creation
- * on `lib/if.c`. We'll use that data structure instead of
- * rolling our own.
- */
- if (cmd == ZEBRA_INTERFACE_ADD) {
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return 0;
-
- bfdd_sessions_enable_interface(ifp);
- return 0;
- }
-
- /* Update interface information. */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return 0;
-
bfdd_sessions_disable_interface(ifp);
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
@@ -756,8 +733,16 @@ static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS)
return 0;
}
+static int bfd_ifp_create(struct interface *ifp)
+{
+ bfdd_sessions_enable_interface(ifp);
+
+ return 0;
+}
+
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
+ if_zapi_callbacks(bfd_ifp_create, NULL, NULL, bfd_ifp_destroy);
zclient = zclient_new(master, &zclient_options_default);
assert(zclient != NULL);
zclient_init(zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv);
@@ -772,10 +757,6 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
/* Send replay request on zebra connect. */
zclient->zebra_connected = bfdd_zebra_connected;
- /* Learn interfaces from zebra instead of the OS. */
- zclient->interface_add = bfdd_interface_update;
- zclient->interface_delete = bfdd_interface_update;
-
/* Learn about interface VRF. */
zclient->interface_vrf_update = bfdd_interface_vrf_update;
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index 551102151e..ff655048a8 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -1632,7 +1632,7 @@ static void bmp_active_connect(struct bmp_active *ba)
ba->hostname);
continue;
}
-
+
set_nonblocking(ba->socket);
res = sockunion_connect(ba->socket, &ba->addrs[ba->addrpos],
htons(ba->port), 0);
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 30380f6add..66681db520 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -1012,6 +1012,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
int header = 1;
char rd_str[BUFSIZ];
char buf[BUFSIZ];
+ int no_display;
unsigned long output_count = 0;
unsigned long total_count = 0;
@@ -1049,6 +1050,11 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
tbl_ver = table->version;
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm)) {
+ pi = bgp_node_get_bgp_path_info(rm);
+ if (pi == NULL)
+ continue;
+
+ no_display = 0;
if (use_json) {
json_array = json_object_new_array();
json_prefix_info = json_object_new_object();
@@ -1065,8 +1071,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
json_nroute = json_object_new_object();
}
- for (pi = bgp_node_get_bgp_path_info(rm); pi;
- pi = pi->next) {
+ for (; pi; pi = pi->next) {
total_count++;
if (type == bgp_show_type_neighbor) {
struct peer *peer = output_arg;
@@ -1101,16 +1106,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
vty_out(vty,
V4_HEADER_OVERLAY);
else {
- vty_out(vty,
- "BGP table version is %" PRIu64 ", local router ID is %s\n",
- tbl_ver,
- inet_ntoa(
- bgp->router_id));
- vty_out(vty,
- "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
- vty_out(vty,
- "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
- vty_out(vty, V4_HEADER);
+ bgp_evpn_show_route_header(vty, bgp, tbl_ver, NULL);
}
}
header = 0;
@@ -1172,18 +1168,23 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
}
if (option == SHOW_DISPLAY_TAGS)
- route_vty_out_tag(vty, &rm->p, pi, 0,
- SAFI_EVPN,
+ route_vty_out_tag(vty, &rm->p, pi,
+ no_display, SAFI_EVPN,
json_array);
else if (option == SHOW_DISPLAY_OVERLAY)
route_vty_out_overlay(vty, &rm->p, pi,
- 0, json_array);
+ no_display,
+ json_array);
else
- route_vty_out(vty, &rm->p, pi, 0,
- SAFI_EVPN, json_array);
- output_count++;
+ route_vty_out(vty, &rm->p, pi,
+ no_display, SAFI_EVPN,
+ json_array);
+ no_display = 1;
}
- rd_header = 0;
+
+ if (no_display)
+ output_count++;
+
if (use_json) {
json_object_object_add(json_prefix_info,
"paths", json_array);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 37360a559a..d083586c93 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6562,6 +6562,7 @@ DEFUN (aggregate_address_mask,
argv_find(argv, argc, "A.B.C.D", &idx);
char *prefix = argv[idx]->arg;
char *mask = argv[idx + 1]->arg;
+ bool rmap_found;
char *rmap = NULL;
int as_set =
argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
@@ -6570,8 +6571,8 @@ DEFUN (aggregate_address_mask,
? AGGREGATE_SUMMARY_ONLY
: 0;
- argv_find(argv, argc, "WORD", &idx);
- if (idx)
+ rmap_found = argv_find(argv, argc, "WORD", &idx);
+ if (rmap_found)
rmap = argv[idx]->arg;
char prefix_str[BUFSIZ];
@@ -6588,14 +6589,16 @@ DEFUN (aggregate_address_mask,
DEFUN (no_aggregate_address,
no_aggregate_address_cmd,
- "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
+ "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Generate AS set path information\n"
"Filter more specific routes from updates\n"
"Filter more specific routes from updates\n"
- "Generate AS set path information\n")
+ "Generate AS set path information\n"
+ "Apply route map to aggregate network\n"
+ "Name of route map\n")
{
int idx = 0;
argv_find(argv, argc, "A.B.C.D/M", &idx);
@@ -6605,7 +6608,7 @@ DEFUN (no_aggregate_address,
DEFUN (no_aggregate_address_mask,
no_aggregate_address_mask_cmd,
- "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
+ "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate address\n"
@@ -6613,7 +6616,9 @@ DEFUN (no_aggregate_address_mask,
"Generate AS set path information\n"
"Filter more specific routes from updates\n"
"Filter more specific routes from updates\n"
- "Generate AS set path information\n")
+ "Generate AS set path information\n"
+ "Apply route map to aggregate network\n"
+ "Name of route map\n")
{
int idx = 0;
argv_find(argv, argc, "A.B.C.D", &idx);
@@ -6647,6 +6652,7 @@ DEFUN (ipv6_aggregate_address,
argv_find(argv, argc, "X:X::X:X/M", &idx);
char *prefix = argv[idx]->arg;
char *rmap = NULL;
+ bool rmap_found;
int as_set =
argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
@@ -6655,8 +6661,8 @@ DEFUN (ipv6_aggregate_address,
? AGGREGATE_SUMMARY_ONLY
: 0;
- argv_find(argv, argc, "WORD", &idx);
- if (idx)
+ rmap_found = argv_find(argv, argc, "WORD", &idx);
+ if (rmap_found)
rmap = argv[idx]->arg;
return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
@@ -6665,14 +6671,16 @@ DEFUN (ipv6_aggregate_address,
DEFUN (no_ipv6_aggregate_address,
no_ipv6_aggregate_address_cmd,
- "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>]",
+ "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
"Generate AS set path information\n"
"Filter more specific routes from updates\n"
"Filter more specific routes from updates\n"
- "Generate AS set path information\n")
+ "Generate AS set path information\n"
+ "Apply route map to aggregate network\n"
+ "Name of route map\n")
{
int idx = 0;
argv_find(argv, argc, "X:X::X:X/M", &idx);
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c
index c266440899..f31f8cd31b 100644
--- a/bgpd/bgp_snmp.c
+++ b/bgpd/bgp_snmp.c
@@ -46,7 +46,7 @@
/* BGP TRAP. */
#define BGPESTABLISHED 1
-#define BGPBACKWARDTRANSITION 2
+#define BGPBACKWARDTRANSITION 2
/* BGP MIB bgpVersion. */
#define BGPVERSION 0
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 17bc83ed2e..f290b6cfb4 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -7918,7 +7918,7 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer,
msg_str);
}
- }
+ }
json_object_string_add(json_peer, "lastResetDueTo",
peer_down_str[(int)peer->last_reset]);
json_object_int_add(json_peer, "lastResetCode",
@@ -8003,7 +8003,7 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp,
false);
}
}
-
+
/* Show BGP peer's summary information. */
static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
@@ -8049,7 +8049,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
if (peer_dynamic_neighbor(peer))
dn_count++;
}
-
+
} else {
/* Loop over all neighbors that will be displayed to determine
* how many
@@ -8078,7 +8078,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
if (len > max_neighbor_width)
max_neighbor_width = len;
-
+
/* See if we have at least a single failed peer */
if (bgp_has_peer_failed(peer, afi, safi))
failed_count++;
@@ -8097,7 +8097,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
if (use_json) {
json_object_int_add(json, "failedPeersCount", 0);
json_object_int_add(json, "dynamicPeers", dn_count);
- json_object_int_add(json, "totalPeers", count);
+ json_object_int_add(json, "totalPeers", count);
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
@@ -8108,7 +8108,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
}
return CMD_SUCCESS;
}
-
+
count = 0; /* Reset the value as its used again */
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 71f7f6d0e3..de39e295ff 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -202,75 +202,36 @@ static void bgp_nbr_connected_delete(struct bgp *bgp, struct nbr_connected *ifc,
}
}
-/* Inteface addition message from zebra. */
-static int bgp_interface_add(ZAPI_CALLBACK_ARGS)
+static int bgp_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
struct bgp *bgp;
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (!ifp) // unexpected
- return 0;
-
- if (BGP_DEBUG(zebra, ZEBRA) && ifp)
- zlog_debug("Rx Intf add VRF %u IF %s", vrf_id, ifp->name);
-
- bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
-
- bgp_mac_add_mac_entry(ifp);
-
- bgp_update_interface_nbrs(bgp, ifp, ifp);
- return 0;
-}
-
-static int bgp_interface_delete(ZAPI_CALLBACK_ARGS)
-{
- struct stream *s;
- struct interface *ifp;
- struct bgp *bgp;
-
- bgp = bgp_lookup_by_vrf_id(vrf_id);
-
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
- if (!ifp) /* This may happen if we've just unregistered for a VRF. */
- return 0;
+ bgp = bgp_lookup_by_vrf_id(ifp->vrf_id);
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
+ zlog_debug("Rx Intf del VRF %u IF %s", bgp->vrf_id, ifp->name);
if (bgp)
bgp_update_interface_nbrs(bgp, ifp, NULL);
bgp_mac_del_mac_entry(ifp);
- if_set_index(ifp, IFINDEX_INTERNAL);
return 0;
}
-static int bgp_interface_up(ZAPI_CALLBACK_ARGS)
+static int bgp_ifp_up(struct interface *ifp)
{
- struct stream *s;
- struct interface *ifp;
struct connected *c;
struct nbr_connected *nc;
struct listnode *node, *nnode;
struct bgp *bgp;
- bgp = bgp_lookup_by_vrf_id(vrf_id);
-
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (!ifp)
- return 0;
+ bgp = bgp_lookup_by_vrf_id(ifp->vrf_id);
bgp_mac_add_mac_entry(ifp);
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name);
+ zlog_debug("Rx Intf up VRF %u IF %s", ifp->vrf_id, ifp->name);
if (!bgp)
return 0;
@@ -284,27 +245,20 @@ static int bgp_interface_up(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int bgp_interface_down(ZAPI_CALLBACK_ARGS)
+static int bgp_ifp_down(struct interface *ifp)
{
- struct stream *s;
- struct interface *ifp;
struct connected *c;
struct nbr_connected *nc;
struct listnode *node, *nnode;
struct bgp *bgp;
struct peer *peer;
- bgp = bgp_lookup_by_vrf_id(vrf_id);
-
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
- if (!ifp)
- return 0;
+ bgp = bgp_lookup_by_vrf_id(ifp->vrf_id);
bgp_mac_del_mac_entry(ifp);
if (BGP_DEBUG(zebra, ZEBRA))
- zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name);
+ zlog_debug("Rx Intf down VRF %u IF %s", ifp->vrf_id, ifp->name);
if (!bgp)
return 0;
@@ -2721,17 +2675,35 @@ stream_failure: /* for STREAM_GETX */
extern struct zebra_privs_t bgpd_privs;
+static int bgp_ifp_create(struct interface *ifp)
+{
+ struct bgp *bgp;
+
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("Rx Intf add VRF %u IF %s", ifp->vrf_id, ifp->name);
+
+ bgp = bgp_lookup_by_vrf_id(ifp->vrf_id);
+ if (!bgp)
+ return 0;
+
+ bgp_mac_add_mac_entry(ifp);
+
+ bgp_update_interface_nbrs(bgp, ifp, ifp);
+ return 0;
+}
+
void bgp_zebra_init(struct thread_master *master, unsigned short instance)
{
zclient_num_connects = 0;
+ if_zapi_callbacks(bgp_ifp_create, bgp_ifp_up,
+ bgp_ifp_down, bgp_ifp_destroy);
+
/* Set default values. */
zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
zclient->zebra_connected = bgp_zebra_connected;
zclient->router_id_update = bgp_router_id_update;
- zclient->interface_add = bgp_interface_add;
- zclient->interface_delete = bgp_interface_delete;
zclient->interface_address_add = bgp_interface_address_add;
zclient->interface_address_delete = bgp_interface_address_delete;
zclient->interface_nbr_address_add = bgp_interface_nbr_address_add;
@@ -2740,8 +2712,6 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance)
zclient->interface_vrf_update = bgp_interface_vrf_update;
zclient->redistribute_route_add = zebra_read_route;
zclient->redistribute_route_del = zebra_read_route;
- zclient->interface_up = bgp_interface_up;
- zclient->interface_down = bgp_interface_down;
zclient->nexthop_update = bgp_read_nexthop_update;
zclient->import_check_update = bgp_read_import_check_update;
zclient->fec_update = bgp_read_fec_update;
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index 5d2cfbc337..af465f6fd4 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -839,8 +839,11 @@ zebra Terminal Mode Commands
.. index:: show ipv6 route
.. clicmd:: show ipv6 route
-.. index:: show interface
-.. clicmd:: show interface
+.. index:: show interface [{vrf VRF|brief}]
+.. clicmd:: show interface [{vrf VRF|brief}]
+
+.. index:: show interface [{vrf all|brief}]
+.. clicmd:: show interface [{vrf all|brief}]
.. index:: show ip prefix-list [NAME]
.. clicmd:: show ip prefix-list [NAME]
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c
index fd1d3f5cb9..6294c0dd0f 100644
--- a/eigrpd/eigrp_interface.c
+++ b/eigrpd/eigrp_interface.c
@@ -54,6 +54,7 @@
#include "eigrpd/eigrp_topology.h"
#include "eigrpd/eigrp_memory.h"
#include "eigrpd/eigrp_fsm.h"
+#include "eigrpd/eigrp_dump.h"
struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp,
struct prefix *p)
@@ -122,10 +123,101 @@ int eigrp_if_delete_hook(struct interface *ifp)
return 0;
}
+static int eigrp_ifp_create(struct interface *ifp)
+{
+ struct eigrp_interface *ei = ifp->info;
+
+ if (!ei)
+ return 0;
+
+ ei->params.type = eigrp_default_iftype(ifp);
+
+ eigrp_if_update(ifp);
+
+ return 0;
+}
+
+static int eigrp_ifp_up(struct interface *ifp)
+{
+ /* Interface is already up. */
+ if (if_is_operative(ifp)) {
+ /* Temporarily keep ifp values. */
+ struct interface if_tmp;
+ memcpy(&if_tmp, ifp, sizeof(struct interface));
+
+ if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+ zlog_debug("Zebra: Interface[%s] state update.",
+ ifp->name);
+
+ if (if_tmp.bandwidth != ifp->bandwidth) {
+ if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+ zlog_debug(
+ "Zebra: Interface[%s] bandwidth change %d -> %d.",
+ ifp->name, if_tmp.bandwidth,
+ ifp->bandwidth);
+
+ // eigrp_if_recalculate_output_cost (ifp);
+ }
+
+ if (if_tmp.mtu != ifp->mtu) {
+ if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+ zlog_debug(
+ "Zebra: Interface[%s] MTU change %u -> %u.",
+ ifp->name, if_tmp.mtu, ifp->mtu);
+
+ /* Must reset the interface (simulate down/up) when MTU
+ * changes. */
+ eigrp_if_reset(ifp);
+ }
+ return 0;
+ }
+
+ if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+ zlog_debug("Zebra: Interface[%s] state change to up.",
+ ifp->name);
+
+ if (ifp->info)
+ eigrp_if_up(ifp->info);
+
+ return 0;
+}
+
+static int eigrp_ifp_down(struct interface *ifp)
+{
+ if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+ zlog_debug("Zebra: Interface[%s] state change to down.",
+ ifp->name);
+
+ if (ifp->info)
+ eigrp_if_down(ifp->info);
+
+ return 0;
+}
+
+static int eigrp_ifp_destroy(struct interface *ifp)
+{
+ if (if_is_up(ifp))
+ zlog_warn("Zebra: got delete of %s, but interface is still up",
+ ifp->name);
+
+ if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+ zlog_debug(
+ "Zebra: interface delete %s index %d flags %llx metric %d mtu %d",
+ ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
+ ifp->metric, ifp->mtu);
+
+ if (ifp->info)
+ eigrp_if_free(ifp->info, INTERFACE_DOWN_BY_ZEBRA);
+
+ return 0;
+}
+
struct list *eigrp_iflist;
void eigrp_if_init(void)
{
+ if_zapi_callbacks(eigrp_ifp_create, eigrp_ifp_up,
+ eigrp_ifp_down, eigrp_ifp_destroy);
/* Initialize Zebra interface data structure. */
// hook_register_prio(if_add, 0, eigrp_if_new);
hook_register_prio(if_del, 0, eigrp_if_delete_hook);
diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h
index a18b0b7015..1e66dafde2 100644
--- a/eigrpd/eigrp_interface.h
+++ b/eigrpd/eigrp_interface.h
@@ -63,5 +63,4 @@ extern uint32_t eigrp_scaled_to_bandwidth(uint32_t);
extern uint32_t eigrp_delay_to_scaled(uint32_t);
extern uint32_t eigrp_scaled_to_delay(uint32_t);
-
#endif /* ZEBRA_EIGRP_INTERFACE_H_ */
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 63cbe84ef2..9a0fdda0f9 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -53,14 +53,8 @@
#include "eigrpd/eigrp_topology.h"
#include "eigrpd/eigrp_fsm.h"
-static int eigrp_interface_add(ZAPI_CALLBACK_ARGS);
-static int eigrp_interface_delete(ZAPI_CALLBACK_ARGS);
static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS);
static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS);
-static int eigrp_interface_state_up(ZAPI_CALLBACK_ARGS);
-static int eigrp_interface_state_down(ZAPI_CALLBACK_ARGS);
-static struct interface *zebra_interface_if_lookup(struct stream *,
- vrf_id_t vrf_id);
static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS);
@@ -114,10 +108,6 @@ void eigrp_zebra_init(void)
zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
zclient->zebra_connected = eigrp_zebra_connected;
zclient->router_id_update = eigrp_router_id_update_zebra;
- zclient->interface_add = eigrp_interface_add;
- zclient->interface_delete = eigrp_interface_delete;
- zclient->interface_up = eigrp_interface_state_up;
- zclient->interface_down = eigrp_interface_state_down;
zclient->interface_address_add = eigrp_interface_address_add;
zclient->interface_address_delete = eigrp_interface_address_delete;
zclient->redistribute_route_add = eigrp_zebra_read_route;
@@ -151,56 +141,6 @@ static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS)
return 0;
}
-/* Inteface addition message from zebra. */
-static int eigrp_interface_add(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct eigrp_interface *ei;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (!ifp->info)
- return 0;
-
- ei = ifp->info;
-
- ei->params.type = eigrp_default_iftype(ifp);
-
- eigrp_if_update(ifp);
-
- return 0;
-}
-
-static int eigrp_interface_delete(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- /* zebra_interface_state_read () updates interface structure in iflist
- */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- if (if_is_up(ifp))
- zlog_warn("Zebra: got delete of %s, but interface is still up",
- ifp->name);
-
- if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
- zlog_debug(
- "Zebra: interface delete %s index %d flags %llx metric %d mtu %d",
- ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
- ifp->metric, ifp->mtu);
-
- if (ifp->info)
- eigrp_if_free(ifp->info, INTERFACE_DOWN_BY_ZEBRA);
-
- if_set_index(ifp, IFINDEX_INTERNAL);
- return 0;
-}
-
static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
@@ -254,93 +194,6 @@ static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int eigrp_interface_state_up(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_if_lookup(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- /* Interface is already up. */
- if (if_is_operative(ifp)) {
- /* Temporarily keep ifp values. */
- struct interface if_tmp;
- memcpy(&if_tmp, ifp, sizeof(struct interface));
-
- zebra_interface_if_set_value(zclient->ibuf, ifp);
-
- if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
- zlog_debug("Zebra: Interface[%s] state update.",
- ifp->name);
-
- if (if_tmp.bandwidth != ifp->bandwidth) {
- if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
- zlog_debug(
- "Zebra: Interface[%s] bandwidth change %d -> %d.",
- ifp->name, if_tmp.bandwidth,
- ifp->bandwidth);
-
- // eigrp_if_recalculate_output_cost (ifp);
- }
-
- if (if_tmp.mtu != ifp->mtu) {
- if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
- zlog_debug(
- "Zebra: Interface[%s] MTU change %u -> %u.",
- ifp->name, if_tmp.mtu, ifp->mtu);
-
- /* Must reset the interface (simulate down/up) when MTU
- * changes. */
- eigrp_if_reset(ifp);
- }
- return 0;
- }
-
- zebra_interface_if_set_value(zclient->ibuf, ifp);
-
- if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
- zlog_debug("Zebra: Interface[%s] state change to up.",
- ifp->name);
-
- if (ifp->info)
- eigrp_if_up(ifp->info);
-
- return 0;
-}
-
-static int eigrp_interface_state_down(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
- zlog_debug("Zebra: Interface[%s] state change to down.",
- ifp->name);
-
- if (ifp->info)
- eigrp_if_down(ifp->info);
-
- return 0;
-}
-
-static struct interface *zebra_interface_if_lookup(struct stream *s,
- vrf_id_t vrf_id)
-{
- char ifname_tmp[INTERFACE_NAMSIZ];
-
- /* Read interface name. */
- stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
-
- /* And look it up. */
- return if_lookup_by_name(ifname_tmp, vrf_id);
-}
-
void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
struct list *successors, uint32_t distance)
{
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 0a4d733177..750a36be67 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -16,7 +16,7 @@
#define NETLINK_SELINUX 7 /* SELinux event notifications */
#define NETLINK_ISCSI 8 /* Open-iSCSI */
#define NETLINK_AUDIT 9 /* auditing */
-#define NETLINK_FIB_LOOKUP 10
+#define NETLINK_FIB_LOOKUP 10
#define NETLINK_CONNECTOR 11
#define NETLINK_NETFILTER 12 /* netfilter subsystem */
#define NETLINK_IP6_FW 13
@@ -32,7 +32,7 @@
#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
-#define MAX_LINKS 32
+#define MAX_LINKS 32
struct sockaddr_nl {
__kernel_sa_family_t nl_family; /* AF_NETLINK */
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index ce2a623abb..eddbc04504 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -172,7 +172,7 @@ enum {
#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
-/*
+/*
Generic structure for encapsulation of optional route information.
It is reminiscent of sockaddr, but with sa_family replaced
with attribute type.
@@ -212,7 +212,7 @@ struct rtmsg {
unsigned char rtm_table; /* Routing table id */
unsigned char rtm_protocol; /* Routing protocol; see below */
- unsigned char rtm_scope; /* See below */
+ unsigned char rtm_scope; /* See below */
unsigned char rtm_type; /* See below */
unsigned rtm_flags;
@@ -523,7 +523,7 @@ struct ifinfomsg {
};
/********************************************************************
- * prefix information
+ * prefix information
****/
struct prefixmsg {
@@ -537,7 +537,7 @@ struct prefixmsg {
unsigned char prefix_pad3;
};
-enum
+enum
{
PREFIX_UNSPEC,
PREFIX_ADDRESS,
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 5da8e6ee9e..29fb725b04 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -61,6 +61,8 @@
DEFINE_QOBJ_TYPE(isis_circuit)
+DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp))
+
/*
* Prototypes.
*/
@@ -1389,6 +1391,51 @@ int isis_if_delete_hook(struct interface *ifp)
return 0;
}
+static int isis_ifp_create(struct interface *ifp)
+{
+ if (if_is_operative(ifp))
+ isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
+ ifp);
+
+ hook_call(isis_if_new_hook, ifp);
+
+ return 0;
+}
+
+static int isis_ifp_up(struct interface *ifp)
+{
+ isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
+
+ return 0;
+}
+
+static int isis_ifp_down(struct interface *ifp)
+{
+ struct isis_circuit *circuit;
+
+ circuit = isis_csm_state_change(IF_DOWN_FROM_Z,
+ circuit_scan_by_ifp(ifp), ifp);
+ if (circuit)
+ SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
+
+ return 0;
+}
+
+static int isis_ifp_destroy(struct interface *ifp)
+{
+ if (if_is_operative(ifp))
+ zlog_warn("Zebra: got delete of %s, but interface is still up",
+ ifp->name);
+
+ isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
+
+ /* Cannot call if_delete because we should retain the pseudo interface
+ in case there is configuration info attached to it. */
+ if_delete_retain(ifp);
+
+ return 0;
+}
+
void isis_circuit_init(void)
{
/* Initialize Zebra interface data structure */
@@ -1398,4 +1445,6 @@ void isis_circuit_init(void)
/* Install interface node */
install_node(&interface_node, isis_interface_config_write);
if_cmd_init();
+ if_zapi_callbacks(isis_ifp_create, isis_ifp_up,
+ isis_ifp_down, isis_ifp_destroy);
}
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index b77c8ce352..f677d3aded 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -32,6 +32,8 @@
#include "isis_constants.h"
#include "isis_common.h"
+DECLARE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp));
+
struct isis_lsp;
struct password {
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 46b013ddd0..a637ff003f 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -187,7 +187,7 @@ static int process_p2p_hello(struct iih_info *iih)
adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
}
- if (tw_adj && adj->threeway_state == ISIS_THREEWAY_DOWN)
+ if (tw_adj)
adj->ext_circuit_id = tw_adj->local_circuit_id;
/* 8.2.6 Monitoring point-to-point adjacencies */
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 39a2f6ef35..bdf6869f5c 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -53,8 +53,6 @@
struct zclient *zclient = NULL;
-DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp))
-
/* Router-id update message from zebra. */
static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
{
@@ -74,79 +72,6 @@ static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int isis_zebra_if_add(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (if_is_operative(ifp))
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
- ifp);
-
- hook_call(isis_if_new_hook, ifp);
-
- return 0;
-}
-
-static int isis_zebra_if_del(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (!ifp)
- return 0;
-
- if (if_is_operative(ifp))
- zlog_warn("Zebra: got delete of %s, but interface is still up",
- ifp->name);
-
- isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
-
- /* Cannot call if_delete because we should retain the pseudo interface
- in case there is configuration info attached to it. */
- if_delete_retain(ifp);
-
- if_set_index(ifp, IFINDEX_INTERNAL);
-
- return 0;
-}
-
-static int isis_zebra_if_state_up(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
-
- return 0;
-}
-
-static int isis_zebra_if_state_down(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct isis_circuit *circuit;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- circuit = isis_csm_state_change(IF_DOWN_FROM_Z,
- circuit_scan_by_ifp(ifp), ifp);
- if (circuit)
- SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
-
- return 0;
-}
-
static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
@@ -388,10 +313,6 @@ void isis_zebra_init(struct thread_master *master)
zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
zclient->zebra_connected = isis_zebra_connected;
zclient->router_id_update = isis_router_id_update_zebra;
- zclient->interface_add = isis_zebra_if_add;
- zclient->interface_delete = isis_zebra_if_del;
- zclient->interface_up = isis_zebra_if_state_up;
- zclient->interface_down = isis_zebra_if_state_down;
zclient->interface_address_add = isis_zebra_if_address_add;
zclient->interface_address_delete = isis_zebra_if_address_del;
zclient->interface_link_params = isis_zebra_link_params;
diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h
index 83a32108eb..d00f348c8e 100644
--- a/isisd/isis_zebra.h
+++ b/isisd/isis_zebra.h
@@ -24,8 +24,6 @@
extern struct zclient *zclient;
-DECLARE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp));
-
void isis_zebra_init(struct thread_master *);
void isis_zebra_stop(void);
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 884ae159be..4df1fc0304 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -39,9 +39,6 @@ static void ifc2kaddr(struct interface *, struct connected *,
struct kaddr *);
static int ldp_zebra_send_mpls_labels(int, struct kroute *);
static int ldp_router_id_update(ZAPI_CALLBACK_ARGS);
-static int ldp_interface_add(ZAPI_CALLBACK_ARGS);
-static int ldp_interface_delete(ZAPI_CALLBACK_ARGS);
-static int ldp_interface_status_change(ZAPI_CALLBACK_ARGS);
static int ldp_interface_address_add(ZAPI_CALLBACK_ARGS);
static int ldp_interface_address_delete(ZAPI_CALLBACK_ARGS);
static int ldp_zebra_read_route(ZAPI_CALLBACK_ARGS);
@@ -264,39 +261,27 @@ ldp_router_id_update(ZAPI_CALLBACK_ARGS)
}
static int
-ldp_interface_add(ZAPI_CALLBACK_ARGS)
+ldp_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
struct kif kif;
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
debug_zebra_in("interface add %s index %d mtu %d", ifp->name,
ifp->ifindex, ifp->mtu);
ifp2kif(ifp, &kif);
main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
- return (0);
+ return 0;
}
static int
-ldp_interface_delete(ZAPI_CALLBACK_ARGS)
+ldp_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
struct kif kif;
- /* zebra_interface_state_read() updates interface structure in iflist */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return (0);
-
debug_zebra_in("interface delete %s index %d mtu %d", ifp->name,
ifp->ifindex, ifp->mtu);
- /* To support pseudo interface do not free interface structure. */
- /* if_delete(ifp); */
- if_set_index(ifp, IFINDEX_INTERNAL);
-
ifp2kif(ifp, &kif);
main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
@@ -304,22 +289,13 @@ ldp_interface_delete(ZAPI_CALLBACK_ARGS)
}
static int
-ldp_interface_status_change(ZAPI_CALLBACK_ARGS)
+ldp_interface_status_change_helper(struct interface *ifp)
{
- struct interface *ifp;
struct listnode *node;
struct connected *ifc;
struct kif kif;
struct kaddr ka;
- /*
- * zebra_interface_state_read() updates interface structure in
- * iflist.
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return (0);
-
debug_zebra_in("interface %s state update", ifp->name);
ifp2kif(ifp, &kif);
@@ -342,6 +318,16 @@ ldp_interface_status_change(ZAPI_CALLBACK_ARGS)
return (0);
}
+static int ldp_ifp_up(struct interface *ifp)
+{
+ return ldp_interface_status_change_helper(ifp);
+}
+
+static int ldp_ifp_down(struct interface *ifp)
+{
+ return ldp_interface_status_change_helper(ifp);
+}
+
static int
ldp_interface_address_add(ZAPI_CALLBACK_ARGS)
{
@@ -535,6 +521,9 @@ extern struct zebra_privs_t ldpd_privs;
void
ldp_zebra_init(struct thread_master *master)
{
+ if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up,
+ ldp_ifp_down, ldp_ifp_destroy);
+
/* Set default values. */
zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
@@ -542,10 +531,6 @@ ldp_zebra_init(struct thread_master *master)
/* set callbacks */
zclient->zebra_connected = ldp_zebra_connected;
zclient->router_id_update = ldp_router_id_update;
- zclient->interface_add = ldp_interface_add;
- zclient->interface_delete = ldp_interface_delete;
- zclient->interface_up = ldp_interface_status_change;
- zclient->interface_down = ldp_interface_status_change;
zclient->interface_address_add = ldp_interface_address_add;
zclient->interface_address_delete = ldp_interface_address_delete;
zclient->redistribute_route_add = ldp_zebra_read_route;
diff --git a/lib/if.c b/lib/if.c
index fbab0004f9..f2b45512da 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -58,6 +58,13 @@ DEFINE_QOBJ_TYPE(interface)
DEFINE_HOOK(if_add, (struct interface * ifp), (ifp))
DEFINE_KOOH(if_del, (struct interface * ifp), (ifp))
+struct interface_master{
+ int (*create_hook)(struct interface *ifp);
+ int (*up_hook)(struct interface *ifp);
+ int (*down_hook)(struct interface *ifp);
+ int (*destroy_hook)(struct interface *ifp);
+} ifp_master = { 0, };
+
/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
* relationship between ifp1 and ifp2. Interface names consist of an
@@ -168,6 +175,34 @@ static struct interface *if_create_backend(const char *name, ifindex_t ifindex,
return ifp;
}
+void if_new_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.create_hook)
+ (*ifp_master.create_hook)(ifp);
+}
+
+void if_destroy_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.destroy_hook)
+ (*ifp_master.destroy_hook)(ifp);
+
+ if_set_index(ifp, IFINDEX_INTERNAL);
+ if (!ifp->configured)
+ if_delete(ifp);
+}
+
+void if_up_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.up_hook)
+ (*ifp_master.up_hook)(ifp);
+}
+
+void if_down_via_zapi(struct interface *ifp)
+{
+ if (ifp_master.down_hook)
+ (*ifp_master.down_hook)(ifp);
+}
+
struct interface *if_create(const char *name, vrf_id_t vrf_id)
{
return if_create_backend(name, IFINDEX_INTERNAL, vrf_id);
@@ -1367,6 +1402,17 @@ void if_cmd_init(void)
install_element(INTERFACE_NODE, &no_interface_desc_cmd);
}
+void if_zapi_callbacks(int (*create)(struct interface *ifp),
+ int (*up)(struct interface *ifp),
+ int (*down)(struct interface *ifp),
+ int (*destroy)(struct interface *ifp))
+{
+ ifp_master.create_hook = create;
+ ifp_master.up_hook = up;
+ ifp_master.down_hook = down;
+ ifp_master.destroy_hook = destroy;
+}
+
/* ------- Northbound callbacks ------- */
/*
@@ -1423,6 +1469,8 @@ static int lib_interface_create(enum nb_event event,
#else
ifp = if_get_by_name(ifname, vrf->vrf_id);
#endif /* SUNOS_5 */
+
+ ifp->configured = true;
nb_running_set_entry(dnode, ifp);
break;
}
@@ -1450,6 +1498,8 @@ static int lib_interface_destroy(enum nb_event event,
break;
case NB_EV_APPLY:
ifp = nb_running_unset_entry(dnode);
+
+ ifp->configured = false;
if_delete(ifp);
break;
}
diff --git a/lib/if.h b/lib/if.h
index e3ec278f9f..a3c6e9ff5b 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -293,6 +293,12 @@ struct interface {
struct route_node *node;
vrf_id_t vrf_id;
+ /*
+ * Has the end users entered `interface XXXX` from the cli in some
+ * fashion?
+ */
+ bool configured;
+
QOBJ_FIELDS
};
@@ -552,6 +558,16 @@ void if_link_params_free(struct interface *);
/* Northbound. */
extern void if_cmd_init(void);
+extern void if_zapi_callbacks(int (*create)(struct interface *ifp),
+ int (*up)(struct interface *ifp),
+ int (*down)(struct interface *ifp),
+ int (*destroy)(struct interface *ifp));
+
+extern void if_new_via_zapi(struct interface *ifp);
+extern void if_up_via_zapi(struct interface *ifp);
+extern void if_down_via_zapi(struct interface *ifp);
+extern void if_destroy_via_zapi(struct interface *ifp);
+
extern const struct frr_yang_module_info frr_interface_info;
#ifdef __cplusplus
diff --git a/lib/printf/printf-pos.c b/lib/printf/printf-pos.c
index 1f5f283e82..45e4f86229 100644
--- a/lib/printf/printf-pos.c
+++ b/lib/printf/printf-pos.c
@@ -98,7 +98,7 @@ inittypes(struct typetable *types)
types->table = types->stattable;
types->tablesize = STATIC_ARG_TBL_SIZE;
- types->tablemax = 0;
+ types->tablemax = 0;
types->nextarg = 1;
for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
types->table[n] = T_UNUSED;
@@ -106,7 +106,7 @@ inittypes(struct typetable *types)
/*
* struct typetable destructor.
- */
+ */
static inline void
freetypes(struct typetable *types)
{
@@ -255,7 +255,7 @@ addwaster(struct typetable *types, wchar_t **fmtp)
* initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
* It will be replaces with a malloc-ed one if it overflows.
* Returns 0 on success. On failure, returns nonzero and sets errno.
- */
+ */
int
_frr_find_arguments (const char *fmt0, va_list ap, union arg **argtable)
{
diff --git a/lib/typesafe.c b/lib/typesafe.c
index 7e5939d5b3..6635cf7506 100644
--- a/lib/typesafe.c
+++ b/lib/typesafe.c
@@ -473,7 +473,7 @@ void typesafe_heap_resize(struct heap_head *head, bool grow)
newsize &= ~(HEAP_NARY - 1);
if (newsize == head->arraysz)
return;
-
+
head->array = XREALLOC(MTYPE_HEAP_ARRAY, head->array,
newsize * sizeof(struct heap_item *));
head->arraysz = newsize;
diff --git a/lib/zclient.c b/lib/zclient.c
index 92a495ac61..91dbe30a09 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -49,6 +49,9 @@ enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
/* Prototype for event manager. */
static void zclient_event(enum event, struct zclient *);
+static void zebra_interface_if_set_value(struct stream *s,
+ struct interface *ifp);
+
struct zclient_options zclient_options_default = {.receive_notify = false};
struct sockaddr_storage zclient_addr;
@@ -1547,10 +1550,11 @@ static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
vrf_delete(vrf);
}
-struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
+static void zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
{
struct interface *ifp;
char ifname_tmp[INTERFACE_NAMSIZ];
+ struct stream *s = zclient->ibuf;
/* Read interface name. */
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
@@ -1560,15 +1564,14 @@ struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
zebra_interface_if_set_value(s, ifp);
- return ifp;
+ if_new_via_zapi(ifp);
}
/*
* Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
* from zebra server. The format of this message is the same as
- * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
- * comments for zebra_interface_add_read), except that no sockaddr_dl
- * is sent at the tail of the message.
+ * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
+ * except that no sockaddr_dl is sent at the tail of the message.
*/
struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
{
@@ -1592,6 +1595,46 @@ struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
return ifp;
}
+static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s = zclient->ibuf;
+
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (ifp == NULL)
+ return;
+
+ if_destroy_via_zapi(ifp);
+ return;
+}
+
+static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s = zclient->ibuf;
+
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (!ifp)
+ return;
+
+ if_up_via_zapi(ifp);
+}
+
+static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+ struct stream *s = zclient->ibuf;
+
+ ifp = zebra_interface_state_read(s, vrf_id);
+
+ if (!ifp)
+ return;
+
+ if_down_via_zapi(ifp);
+}
+
static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
{
@@ -1656,7 +1699,8 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
return ifp;
}
-void zebra_interface_if_set_value(struct stream *s, struct interface *ifp)
+static void zebra_interface_if_set_value(struct stream *s,
+ struct interface *ifp)
{
uint8_t link_params_status = 0;
ifindex_t old_ifindex;
@@ -1944,7 +1988,7 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s,
}
/* Fetch new VRF Id. */
- new_id = stream_getw(s);
+ new_id = stream_getl(s);
*new_vrf_id = new_id;
return ifp;
@@ -2789,14 +2833,10 @@ static int zclient_read(struct thread *thread)
zclient_vrf_delete(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_ADD:
- if (zclient->interface_add)
- (*zclient->interface_add)(command, zclient, length,
- vrf_id);
+ zclient_interface_add(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_DELETE:
- if (zclient->interface_delete)
- (*zclient->interface_delete)(command, zclient, length,
- vrf_id);
+ zclient_interface_delete(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_ADDRESS_ADD:
if (zclient->interface_address_add)
@@ -2824,14 +2864,10 @@ static int zclient_read(struct thread *thread)
command, zclient, length, vrf_id);
break;
case ZEBRA_INTERFACE_UP:
- if (zclient->interface_up)
- (*zclient->interface_up)(command, zclient, length,
- vrf_id);
+ zclient_interface_up(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_DOWN:
- if (zclient->interface_down)
- (*zclient->interface_down)(command, zclient, length,
- vrf_id);
+ zclient_interface_down(zclient, vrf_id);
break;
case ZEBRA_INTERFACE_VRF_UPDATE:
if (zclient->interface_vrf_update)
diff --git a/lib/zclient.h b/lib/zclient.h
index eb3c97b111..5f9edc36ff 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -240,10 +240,6 @@ struct zclient {
void (*zebra_connected)(struct zclient *);
void (*zebra_capabilities)(struct zclient_capabilities *cap);
int (*router_id_update)(ZAPI_CALLBACK_ARGS);
- int (*interface_add)(ZAPI_CALLBACK_ARGS);
- int (*interface_delete)(ZAPI_CALLBACK_ARGS);
- int (*interface_up)(ZAPI_CALLBACK_ARGS);
- int (*interface_down)(ZAPI_CALLBACK_ARGS);
int (*interface_address_add)(ZAPI_CALLBACK_ARGS);
int (*interface_address_delete)(ZAPI_CALLBACK_ARGS);
int (*interface_link_params)(ZAPI_CALLBACK_ARGS);
@@ -617,7 +613,6 @@ extern bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr);
extern void zclient_interface_set_master(struct zclient *client,
struct interface *master,
struct interface *slave);
-extern struct interface *zebra_interface_add_read(struct stream *, vrf_id_t);
extern struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t);
extern struct connected *zebra_interface_address_read(int, struct stream *,
vrf_id_t);
@@ -626,7 +621,6 @@ zebra_interface_nbr_address_read(int, struct stream *, vrf_id_t);
extern struct interface *zebra_interface_vrf_update_read(struct stream *s,
vrf_id_t vrf_id,
vrf_id_t *new_vrf_id);
-extern void zebra_interface_if_set_value(struct stream *, struct interface *);
extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid);
extern struct interface *zebra_interface_link_params_read(struct stream *s,
diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c
index 8f1ba14fe4..e4f614c7c4 100644
--- a/nhrpd/nhrp_interface.c
+++ b/nhrpd/nhrp_interface.c
@@ -296,15 +296,8 @@ void nhrp_interface_update(struct interface *ifp)
}
}
-int nhrp_interface_add(ZAPI_CALLBACK_ARGS)
+int nhrp_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- /* read and add the interface in the iflist. */
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return 0;
-
debugf(NHRP_DEBUG_IF, "if-add: %s, ifindex: %u, hw_type: %d %s",
ifp->name, ifp->ifindex, ifp->ll_type,
if_link_type_str(ifp->ll_type));
@@ -314,49 +307,28 @@ int nhrp_interface_add(ZAPI_CALLBACK_ARGS)
return 0;
}
-int nhrp_interface_delete(ZAPI_CALLBACK_ARGS)
+int nhrp_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
- if (ifp == NULL)
- return 0;
-
debugf(NHRP_DEBUG_IF, "if-delete: %s", ifp->name);
nhrp_interface_update(ifp);
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
-int nhrp_interface_up(ZAPI_CALLBACK_ARGS)
+int nhrp_ifp_up(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return 0;
-
debugf(NHRP_DEBUG_IF, "if-up: %s", ifp->name);
nhrp_interface_update_nbma(ifp);
return 0;
}
-int nhrp_interface_down(ZAPI_CALLBACK_ARGS)
+int nhrp_ifp_down(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return 0;
-
debugf(NHRP_DEBUG_IF, "if-down: %s", ifp->name);
nhrp_interface_update(ifp);
+
return 0;
}
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index 969638cd77..c6c83614ef 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -152,6 +152,8 @@ int main(int argc, char **argv)
nhrp_vc_init();
nhrp_packet_init();
vici_init();
+ if_zapi_callbacks(nhrp_ifp_create, nhrp_ifp_up,
+ nhrp_ifp_down, nhrp_ifp_destroy);
nhrp_zebra_init();
nhrp_shortcut_init();
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index a788eb2efb..cfca86a9bf 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -345,10 +345,6 @@ void nhrp_zebra_init(void)
zclient = zclient_new(master, &zclient_options_default);
zclient->zebra_connected = nhrp_zebra_connected;
- zclient->interface_add = nhrp_interface_add;
- zclient->interface_delete = nhrp_interface_delete;
- zclient->interface_up = nhrp_interface_up;
- zclient->interface_down = nhrp_interface_down;
zclient->interface_address_add = nhrp_interface_address_add;
zclient->interface_address_delete = nhrp_interface_address_delete;
zclient->redistribute_route_add = nhrp_route_read;
diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h
index 670c9f4f18..50746d9ad5 100644
--- a/nhrpd/nhrpd.h
+++ b/nhrpd/nhrpd.h
@@ -319,6 +319,10 @@ void nhrp_interface_notify_del(struct interface *ifp, struct notifier_block *n);
void nhrp_interface_set_protection(struct interface *ifp, const char *profile,
const char *fallback_profile);
void nhrp_interface_set_source(struct interface *ifp, const char *ifname);
+extern int nhrp_ifp_create(struct interface *ifp);
+extern int nhrp_ifp_up(struct interface *ifp);
+extern int nhrp_ifp_down(struct interface *ifp);
+extern int nhrp_ifp_destroy(struct interface *ifp);
int nhrp_nhs_add(struct interface *ifp, afi_t afi, union sockunion *proto_addr,
const char *nbma_fqdn);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 4d7c75a330..a56ba0a694 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -42,6 +42,7 @@
#include "ospf6_spf.h"
#include "ospf6d.h"
#include "ospf6_bfd.h"
+#include "ospf6_zebra.h"
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
DEFINE_QOBJ_TYPE(ospf6_interface)
@@ -1946,11 +1947,64 @@ static struct cmd_node interface_node = {
INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */
};
+static int ospf6_ifp_create(struct interface *ifp)
+{
+ if (IS_OSPF6_DEBUG_ZEBRA(RECV))
+ zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
+ ifp->ifindex, ifp->mtu6);
+ ospf6_interface_if_add(ifp);
+
+ return 0;
+}
+
+static int ospf6_ifp_up(struct interface *ifp)
+{
+ if (IS_OSPF6_DEBUG_ZEBRA(RECV))
+ zlog_debug(
+ "Zebra Interface state change: "
+ "%s index %d flags %llx metric %d mtu %d bandwidth %d",
+ ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
+ ifp->metric, ifp->mtu6, ifp->bandwidth);
+
+ ospf6_interface_state_update(ifp);
+
+ return 0;
+}
+
+static int ospf6_ifp_down(struct interface *ifp)
+{
+ if (IS_OSPF6_DEBUG_ZEBRA(RECV))
+ zlog_debug(
+ "Zebra Interface state change: "
+ "%s index %d flags %llx metric %d mtu %d bandwidth %d",
+ ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
+ ifp->metric, ifp->mtu6, ifp->bandwidth);
+
+ ospf6_interface_state_update(ifp);
+
+ return 0;
+}
+
+static int ospf6_ifp_destroy(struct interface *ifp)
+{
+ if (if_is_up(ifp))
+ zlog_warn("Zebra: got delete of %s, but interface is still up",
+ ifp->name);
+
+ if (IS_OSPF6_DEBUG_ZEBRA(RECV))
+ zlog_debug("Zebra Interface delete: %s index %d mtu %d",
+ ifp->name, ifp->ifindex, ifp->mtu6);
+
+ return 0;
+}
+
void ospf6_interface_init(void)
{
/* Install interface node. */
install_node(&interface_node, config_write_ospf6_interface);
if_cmd_init();
+ if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
+ ospf6_ifp_down, ospf6_ifp_destroy);
install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 8454016b2e..d8a6a39e1e 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -97,57 +97,6 @@ void ospf6_zebra_no_redistribute(int type)
AFI_IP6, type, 0, VRF_DEFAULT);
}
-/* Inteface addition message from zebra. */
-static int ospf6_zebra_if_add(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (IS_OSPF6_DEBUG_ZEBRA(RECV))
- zlog_debug("Zebra Interface add: %s index %d mtu %d", ifp->name,
- ifp->ifindex, ifp->mtu6);
- ospf6_interface_if_add(ifp);
- return 0;
-}
-
-static int ospf6_zebra_if_del(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- if (!(ifp = zebra_interface_state_read(zclient->ibuf, vrf_id)))
- return 0;
-
- if (if_is_up(ifp))
- zlog_warn("Zebra: got delete of %s, but interface is still up",
- ifp->name);
-
- if (IS_OSPF6_DEBUG_ZEBRA(RECV))
- zlog_debug("Zebra Interface delete: %s index %d mtu %d",
- ifp->name, ifp->ifindex, ifp->mtu6);
-
- if_set_index(ifp, IFINDEX_INTERNAL);
- return 0;
-}
-
-static int ospf6_zebra_if_state_update(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return 0;
-
- if (IS_OSPF6_DEBUG_ZEBRA(RECV))
- zlog_debug(
- "Zebra Interface state change: "
- "%s index %d flags %llx metric %d mtu %d bandwidth %d",
- ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
- ifp->metric, ifp->mtu6, ifp->bandwidth);
-
- ospf6_interface_state_update(ifp);
- return 0;
-}
-
static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
@@ -583,10 +532,6 @@ void ospf6_zebra_init(struct thread_master *master)
zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
zclient->zebra_connected = ospf6_zebra_connected;
zclient->router_id_update = ospf6_router_id_update_zebra;
- zclient->interface_add = ospf6_zebra_if_add;
- zclient->interface_delete = ospf6_zebra_if_del;
- zclient->interface_up = ospf6_zebra_if_state_update;
- zclient->interface_down = ospf6_zebra_if_state_update;
zclient->interface_address_add = ospf6_zebra_if_address_update_add;
zclient->interface_address_delete =
ospf6_zebra_if_address_update_delete;
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c
index 9492de544f..44244f651e 100644
--- a/ospfd/ospf_ase.c
+++ b/ospfd/ospf_ase.c
@@ -190,7 +190,7 @@ ospf_ase_calculate_asbr_route (struct ospf *ospf,
zlog_debug ("ospf_ase_calculate(): Originating router is not an ASBR");
return NULL;
}
-
+
if (al->e[0].fwd_addr.s_addr != 0)
{
if (IS_DEBUG_OSPF (lsa, LSA))
@@ -215,7 +215,7 @@ ospf_ase_calculate_asbr_route (struct ospf *ospf,
asbr.prefixlen = IPV4_MAX_BITLEN;
rn = route_node_match (rt_network, (struct prefix *) &asbr);
-
+
if (rn == NULL)
{
if (IS_DEBUG_OSPF (lsa, LSA))
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 3877708708..3407d1bad1 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -50,6 +50,8 @@
DEFINE_QOBJ_TYPE(ospf_interface)
DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd))
DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd))
+DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
+DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
int ospf_interface_neighbor_count(struct ospf_interface *oi)
{
@@ -1218,8 +1220,133 @@ uint8_t ospf_default_iftype(struct interface *ifp)
return OSPF_IFTYPE_BROADCAST;
}
+void ospf_if_interface(struct interface *ifp)
+{
+ hook_call(ospf_if_update, ifp);
+}
+
+static int ospf_ifp_create(struct interface *ifp)
+{
+ struct ospf *ospf = NULL;
+
+ if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+ zlog_debug(
+ "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d speed %u",
+ ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+ ifp->vrf_id, ifp->ifindex,
+ (unsigned long long)ifp->flags, ifp->metric, ifp->mtu,
+ ifp->speed);
+
+ assert(ifp->info);
+
+ if (IF_DEF_PARAMS(ifp)
+ && !OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) {
+ SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
+ IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
+ }
+
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ if (!ospf)
+ return 0;
+
+ ospf_if_recalculate_output_cost(ifp);
+
+ ospf_if_update(ospf, ifp);
+
+ hook_call(ospf_if_update, ifp);
+
+ return 0;
+}
+
+static int ospf_ifp_up(struct interface *ifp)
+{
+ struct ospf_interface *oi;
+ struct route_node *rn;
+
+ /* Interface is already up. */
+ if (if_is_operative(ifp)) {
+ /* Temporarily keep ifp values. */
+ struct interface if_tmp;
+ memcpy(&if_tmp, ifp, sizeof(struct interface));
+
+ if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+ zlog_debug(
+ "Zebra: Interface[%s] state update speed %u -> %u, bw %d -> %d",
+ ifp->name, if_tmp.speed, ifp->speed,
+ if_tmp.bandwidth, ifp->bandwidth);
+
+ ospf_if_recalculate_output_cost(ifp);
+
+ if (if_tmp.mtu != ifp->mtu) {
+ if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+ zlog_debug(
+ "Zebra: Interface[%s] MTU change %u -> %u.",
+ ifp->name, if_tmp.mtu, ifp->mtu);
+
+ /* Must reset the interface (simulate down/up) when MTU
+ * changes. */
+ ospf_if_reset(ifp);
+ }
+ return 0;
+ }
+
+ if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+ zlog_debug("Zebra: Interface[%s] state change to up.",
+ ifp->name);
+
+ for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
+ if ((oi = rn->info) == NULL)
+ continue;
+
+ ospf_if_up(oi);
+ }
+
+ return 0;
+}
+
+static int ospf_ifp_down(struct interface *ifp)
+{
+ struct ospf_interface *oi;
+ struct route_node *node;
+
+ if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+ zlog_debug("Zebra: Interface[%s] state change to down.",
+ ifp->name);
+
+ for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) {
+ if ((oi = node->info) == NULL)
+ continue;
+ ospf_if_down(oi);
+ }
+
+ return 0;
+}
+
+static int ospf_ifp_destroy(struct interface *ifp)
+{
+ struct route_node *rn;
+
+ if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+ zlog_debug(
+ "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+ ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+ ifp->vrf_id, ifp->ifindex,
+ (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
+
+ hook_call(ospf_if_delete, ifp);
+
+ for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
+ if (rn->info)
+ ospf_if_free((struct ospf_interface *)rn->info);
+
+ return 0;
+}
+
void ospf_if_init(void)
{
+ if_zapi_callbacks(ospf_ifp_create, ospf_ifp_up,
+ ospf_ifp_down, ospf_ifp_destroy);
+
/* Initialize Zebra interface data structure. */
hook_register_prio(if_add, 0, ospf_if_new_hook);
hook_register_prio(if_del, 0, ospf_if_delete_hook);
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index 0c903954d3..cde52dbb9e 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -321,7 +321,12 @@ extern int ospf_interface_neighbor_count(struct ospf_interface *oi);
state of the interface. */
extern void ospf_if_set_multicast(struct ospf_interface *);
+extern void ospf_if_interface(struct interface *ifp);
+
DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd))
DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd))
+DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
+DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
+
#endif /* _ZEBRA_OSPF_INTERFACE_H */
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index db41df7c47..5ab0927e71 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -2437,7 +2437,7 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_install(struct ospf *ospf,
#if 0
/* These don't exist yet... */
ospf_summary_incremental_update(new);
- /* Isn't this done by the above call?
+ /* Isn't this done by the above call?
- RFC 2328 Section 16.5 implies it should be */
/* ospf_ase_calculate_schedule(); */
#else /* #if 0 */
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index b478832d84..5678d545ba 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -55,9 +55,6 @@ DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
-DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
-DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
-
/* Zebra structure to hold current status. */
struct zclient *zclient = NULL;
@@ -97,167 +94,6 @@ static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
return 0;
}
-/* Inteface addition message from zebra. */
-static int ospf_interface_add(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp = NULL;
- struct ospf *ospf = NULL;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (ifp == NULL)
- return 0;
-
- if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug(
- "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d speed %u",
- ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
- ifp->vrf_id, ifp->ifindex,
- (unsigned long long)ifp->flags, ifp->metric, ifp->mtu,
- ifp->speed);
-
- assert(ifp->info);
-
- if (IF_DEF_PARAMS(ifp)
- && !OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) {
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
- IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
- }
-
- ospf = ospf_lookup_by_vrf_id(vrf_id);
- if (!ospf)
- return 0;
-
- ospf_if_recalculate_output_cost(ifp);
-
- ospf_if_update(ospf, ifp);
-
- hook_call(ospf_if_update, ifp);
-
- return 0;
-}
-
-static int ospf_interface_delete(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct stream *s;
- struct route_node *rn;
-
- s = zclient->ibuf;
- /* zebra_interface_state_read() updates interface structure in iflist */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug(
- "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
- ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
- ifp->vrf_id, ifp->ifindex,
- (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
-
- hook_call(ospf_if_delete, ifp);
-
- for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
- if (rn->info)
- ospf_if_free((struct ospf_interface *)rn->info);
-
- if_set_index(ifp, IFINDEX_INTERNAL);
- return 0;
-}
-
-static struct interface *zebra_interface_if_lookup(struct stream *s,
- vrf_id_t vrf_id)
-{
- char ifname_tmp[INTERFACE_NAMSIZ];
-
- /* Read interface name. */
- stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
-
- /* And look it up. */
- return if_lookup_by_name(ifname_tmp, vrf_id);
-}
-
-static int ospf_interface_state_up(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct ospf_interface *oi;
- struct route_node *rn;
-
- ifp = zebra_interface_if_lookup(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- /* Interface is already up. */
- if (if_is_operative(ifp)) {
- /* Temporarily keep ifp values. */
- struct interface if_tmp;
- memcpy(&if_tmp, ifp, sizeof(struct interface));
-
- zebra_interface_if_set_value(zclient->ibuf, ifp);
-
- if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug(
- "Zebra: Interface[%s] state update speed %u -> %u, bw %d -> %d",
- ifp->name, if_tmp.speed, ifp->speed,
- if_tmp.bandwidth, ifp->bandwidth);
-
- ospf_if_recalculate_output_cost(ifp);
-
- if (if_tmp.mtu != ifp->mtu) {
- if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug(
- "Zebra: Interface[%s] MTU change %u -> %u.",
- ifp->name, if_tmp.mtu, ifp->mtu);
-
- /* Must reset the interface (simulate down/up) when MTU
- * changes. */
- ospf_if_reset(ifp);
- }
- return 0;
- }
-
- zebra_interface_if_set_value(zclient->ibuf, ifp);
-
- if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug("Zebra: Interface[%s] state change to up.",
- ifp->name);
-
- for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
- if ((oi = rn->info) == NULL)
- continue;
-
- ospf_if_up(oi);
- }
-
- return 0;
-}
-
-static int ospf_interface_state_down(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct ospf_interface *oi;
- struct route_node *node;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug("Zebra: Interface[%s] state change to down.",
- ifp->name);
-
- for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) {
- if ((oi = node->info) == NULL)
- continue;
- ospf_if_down(oi);
- }
-
- return 0;
-}
-
static int ospf_interface_address_add(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
@@ -283,7 +119,7 @@ static int ospf_interface_address_add(ZAPI_CALLBACK_ARGS)
ospf_if_update(ospf, c->ifp);
- hook_call(ospf_if_update, c->ifp);
+ ospf_if_interface(c->ifp);
return 0;
}
@@ -325,7 +161,7 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS)
/* Call interface hook functions to clean up */
ospf_if_free(oi);
- hook_call(ospf_if_update, c->ifp);
+ ospf_if_interface(c->ifp);
connected_free(c);
@@ -1524,10 +1360,6 @@ void ospf_zebra_init(struct thread_master *master, unsigned short instance)
zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
zclient->zebra_connected = ospf_zebra_connected;
zclient->router_id_update = ospf_router_id_update_zebra;
- zclient->interface_add = ospf_interface_add;
- zclient->interface_delete = ospf_interface_delete;
- zclient->interface_up = ospf_interface_state_up;
- zclient->interface_down = ospf_interface_state_down;
zclient->interface_address_add = ospf_interface_address_add;
zclient->interface_address_delete = ospf_interface_address_delete;
zclient->interface_link_params = ospf_interface_link_params;
diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h
index 6737306532..d3f8a0380b 100644
--- a/ospfd/ospf_zebra.h
+++ b/ospfd/ospf_zebra.h
@@ -87,7 +87,4 @@ extern void ospf_zebra_init(struct thread_master *, unsigned short);
extern void ospf_zebra_vrf_register(struct ospf *ospf);
extern void ospf_zebra_vrf_deregister(struct ospf *ospf);
-DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
-DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
-
#endif /* _ZEBRA_OSPF_ZEBRA_H */
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index f4de255877..b12fa63723 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -1339,6 +1339,7 @@ void ospf_if_update(struct ospf *ospf, struct interface *ifp)
/* Update connected redistribute. */
update_redistributed(ospf, 1);
+
}
void ospf_remove_vls_through_area(struct ospf *ospf, struct ospf_area *area)
diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c
index 246d836acf..bb92703ae4 100644
--- a/pbrd/pbr_main.c
+++ b/pbrd/pbr_main.c
@@ -166,6 +166,8 @@ int main(int argc, char **argv, char **envp)
access_list_init();
pbr_nht_init();
pbr_map_init();
+ if_zapi_callbacks(pbr_ifp_create, pbr_ifp_up,
+ pbr_ifp_down, pbr_ifp_destroy);
pbr_zebra_init();
pbr_vty_init();
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index d74d0fcd23..2bba837389 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -59,15 +59,8 @@ struct pbr_interface *pbr_if_new(struct interface *ifp)
}
/* Inteface addition message from zebra. */
-static int interface_add(ZAPI_CALLBACK_ARGS)
+int pbr_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (!ifp)
- return 0;
-
DEBUGD(&pbr_dbg_zebra,
"%s: %s", __PRETTY_FUNCTION__, ifp->name);
@@ -79,24 +72,11 @@ static int interface_add(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int interface_delete(ZAPI_CALLBACK_ARGS)
+int pbr_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- /* zebra_interface_state_read () updates interface structure in iflist
- */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
DEBUGD(&pbr_dbg_zebra,
"%s: %s", __PRETTY_FUNCTION__, ifp->name);
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
@@ -133,12 +113,8 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int interface_state_up(ZAPI_CALLBACK_ARGS)
+int pbr_ifp_up(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
DEBUGD(&pbr_dbg_zebra,
"%s: %s is up", __PRETTY_FUNCTION__, ifp->name);
@@ -147,12 +123,8 @@ static int interface_state_up(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int interface_state_down(ZAPI_CALLBACK_ARGS)
+int pbr_ifp_down(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
DEBUGD(&pbr_dbg_zebra,
"%s: %s is down", __PRETTY_FUNCTION__, ifp->name);
@@ -447,10 +419,6 @@ void pbr_zebra_init(void)
zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs);
zclient->zebra_connected = zebra_connected;
- zclient->interface_add = interface_add;
- zclient->interface_delete = interface_delete;
- zclient->interface_up = interface_state_up;
- zclient->interface_down = interface_state_down;
zclient->interface_address_add = interface_address_add;
zclient->interface_address_delete = interface_address_delete;
zclient->route_notify_owner = route_notify_owner;
diff --git a/pbrd/pbr_zebra.h b/pbrd/pbr_zebra.h
index 4cbefe2636..d5d938021a 100644
--- a/pbrd/pbr_zebra.h
+++ b/pbrd/pbr_zebra.h
@@ -39,4 +39,10 @@ extern void pbr_send_pbr_map(struct pbr_map_sequence *pbrms,
struct pbr_map_interface *pmi, bool install);
extern struct pbr_interface *pbr_if_new(struct interface *ifp);
+
+extern int pbr_ifp_create(struct interface *ifp);
+extern int pbr_ifp_up(struct interface *ifp);
+extern int pbr_ifp_down(struct interface *ifp);
+extern int pbr_ifp_destroy(struct interface *ifp);
+
#endif
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 721d153d76..34c5eb43bc 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -104,7 +104,7 @@ static void tlv_trace(const char *label, const char *tlv_name,
char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_debug("%s: PIM hello option from %s on interface %s: %s",
- label,
+ label,
src_str, ifname,
tlv_name);
}
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index bdeda2d76b..bc8dedc4f6 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1526,3 +1526,169 @@ int pim_if_ifchannel_count(struct pim_interface *pim_ifp)
return count;
}
+
+int pim_ifp_create(struct interface *ifp)
+{
+ struct pim_instance *pim;
+
+ pim = pim_get_pim_instance(ifp->vrf_id);
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (if_is_operative(ifp)) {
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ /*
+ * If we have a pim_ifp already and this is an if_add
+ * that means that we probably have a vrf move event
+ * If that is the case, set the proper vrfness.
+ */
+ if (pim_ifp)
+ pim_ifp->pim = pim;
+ pim_if_addr_add_all(ifp);
+ }
+
+ /*
+ * If we are a vrf device that is up, open up the pim_socket for
+ * listening
+ * to incoming pim messages irrelevant if the user has configured us
+ * for pim or not.
+ */
+ if (pim_if_is_vrf_device(ifp)) {
+ struct pim_interface *pim_ifp;
+
+ if (!ifp->info) {
+ pim_ifp = pim_if_new(ifp, false, false, false,
+ false /*vxlan_term*/);
+ ifp->info = pim_ifp;
+ }
+
+ pim_sock_add(ifp);
+ }
+
+ if (!strncmp(ifp->name, PIM_VXLAN_TERM_DEV_NAME,
+ sizeof(PIM_VXLAN_TERM_DEV_NAME)))
+ pim_vxlan_add_term_dev(pim, ifp);
+
+ return 0;
+}
+
+int pim_ifp_up(struct interface *ifp)
+{
+ struct pim_instance *pim;
+ uint32_t table_id;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ pim = pim_get_pim_instance(ifp->vrf_id);
+ if (if_is_operative(ifp)) {
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ /*
+ * If we have a pim_ifp already and this is an if_add
+ * that means that we probably have a vrf move event
+ * If that is the case, set the proper vrfness.
+ */
+ if (pim_ifp)
+ pim_ifp->pim = pim;
+
+ /*
+ pim_if_addr_add_all() suffices for bringing up both IGMP and
+ PIM
+ */
+ pim_if_addr_add_all(ifp);
+ }
+
+ /*
+ * If we have a pimreg device callback and it's for a specific
+ * table set the master appropriately
+ */
+ if (sscanf(ifp->name, "pimreg%" SCNu32, &table_id) == 1) {
+ struct vrf *vrf;
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if ((table_id == vrf->data.l.table_id)
+ && (ifp->vrf_id != vrf->vrf_id)) {
+ struct interface *master = if_lookup_by_name(
+ vrf->name, vrf->vrf_id);
+
+ if (!master) {
+ zlog_debug(
+ "%s: Unable to find Master interface for %s",
+ __PRETTY_FUNCTION__, vrf->name);
+ return 0;
+ }
+ pim_zebra_interface_set_master(master, ifp);
+ }
+ }
+ }
+ return 0;
+}
+
+int pim_ifp_down(struct interface *ifp)
+{
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (!if_is_operative(ifp)) {
+ pim_ifchannel_delete_all(ifp);
+ /*
+ pim_if_addr_del_all() suffices for shutting down IGMP,
+ but not for shutting down PIM
+ */
+ pim_if_addr_del_all(ifp);
+
+ /*
+ pim_sock_delete() closes the socket, stops read and timer
+ threads,
+ and kills all neighbors.
+ */
+ if (ifp->info) {
+ pim_sock_delete(ifp, "link down");
+ }
+ }
+
+ if (ifp->info)
+ pim_if_del_vif(ifp);
+
+ return 0;
+}
+
+int pim_ifp_destroy(struct interface *ifp)
+{
+ struct pim_instance *pim;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ ifp->vrf_id, (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (!if_is_operative(ifp))
+ pim_if_addr_del_all(ifp);
+
+ pim = pim_get_pim_instance(ifp->vrf_id);
+ if (pim && pim->vxlan.term_if == ifp)
+ pim_vxlan_del_term_dev(pim);
+
+ return 0;
+}
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index 1c11e85705..1b76b52305 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -227,4 +227,10 @@ int pim_update_source_set(struct interface *ifp, struct in_addr source);
bool pim_if_is_vrf_device(struct interface *ifp);
int pim_if_ifchannel_count(struct pim_interface *pim_ifp);
+
+extern int pim_ifp_create(struct interface *ifp);
+extern int pim_ifp_up(struct interface *ifp);
+extern int pim_ifp_down(struct interface *ifp);
+extern int pim_ifp_destroy(struct interface *ifp);
+
#endif /* PIM_IFACE_H */
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 5a8991c4c0..6a7dbe769f 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -127,6 +127,8 @@ int main(int argc, char **argv, char **envp)
/*
* Initialize zclient "update" and "lookup" sockets
*/
+ if_zapi_callbacks(pim_ifp_create, pim_ifp_up,
+ pim_ifp_down, pim_ifp_destroy);
pim_zebra_init();
pim_bfd_init();
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 37cb12548c..dadcbbe65d 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -63,218 +63,6 @@ static int pim_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int pim_zebra_if_add(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct pim_instance *pim;
-
- /*
- zebra api adds/dels interfaces using the same call
- interface_add_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- pim = pim_get_pim_instance(vrf_id);
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug(
- "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
- (long)ifp->flags, ifp->metric, ifp->mtu,
- if_is_operative(ifp));
- }
-
- if (if_is_operative(ifp)) {
- struct pim_interface *pim_ifp;
-
- pim_ifp = ifp->info;
- /*
- * If we have a pim_ifp already and this is an if_add
- * that means that we probably have a vrf move event
- * If that is the case, set the proper vrfness.
- */
- if (pim_ifp)
- pim_ifp->pim = pim;
- pim_if_addr_add_all(ifp);
- }
-
- /*
- * If we are a vrf device that is up, open up the pim_socket for
- * listening
- * to incoming pim messages irrelevant if the user has configured us
- * for pim or not.
- */
- if (pim_if_is_vrf_device(ifp)) {
- struct pim_interface *pim_ifp;
-
- if (!ifp->info) {
- pim_ifp = pim_if_new(ifp, false, false, false,
- false /*vxlan_term*/);
- ifp->info = pim_ifp;
- }
-
- pim_sock_add(ifp);
- }
-
- if (!strncmp(ifp->name, PIM_VXLAN_TERM_DEV_NAME,
- sizeof(PIM_VXLAN_TERM_DEV_NAME)))
- pim_vxlan_add_term_dev(pim, ifp);
-
- return 0;
-}
-
-static int pim_zebra_if_del(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
- struct pim_instance *pim;
-
- /*
- zebra api adds/dels interfaces using the same call
- interface_add_read below, see comments in lib/zclient.c
-
- comments in lib/zclient.c seem to indicate that calling
- zebra_interface_add_read is the correct call, but that
- results in an attemted out of bounds read which causes
- pimd to assert. Other clients use zebra_interface_state_read
- and it appears to work just fine.
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug(
- "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
- (long)ifp->flags, ifp->metric, ifp->mtu,
- if_is_operative(ifp));
- }
-
- if (!if_is_operative(ifp))
- pim_if_addr_del_all(ifp);
-
- if_set_index(ifp, IFINDEX_INTERNAL);
-
- pim = pim_get_pim_instance(vrf_id);
- if (pim && pim->vxlan.term_if == ifp)
- pim_vxlan_del_term_dev(pim);
-
- return 0;
-}
-
-static int pim_zebra_if_state_up(ZAPI_CALLBACK_ARGS)
-{
- struct pim_instance *pim;
- struct interface *ifp;
- uint32_t table_id;
-
- /*
- zebra api notifies interface up/down events by using the same call
- zebra_interface_state_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug(
- "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
- (long)ifp->flags, ifp->metric, ifp->mtu,
- if_is_operative(ifp));
- }
-
- pim = pim_get_pim_instance(vrf_id);
- if (if_is_operative(ifp)) {
- struct pim_interface *pim_ifp;
-
- pim_ifp = ifp->info;
- /*
- * If we have a pim_ifp already and this is an if_add
- * that means that we probably have a vrf move event
- * If that is the case, set the proper vrfness.
- */
- if (pim_ifp)
- pim_ifp->pim = pim;
-
- /*
- pim_if_addr_add_all() suffices for bringing up both IGMP and
- PIM
- */
- pim_if_addr_add_all(ifp);
- }
-
- /*
- * If we have a pimreg device callback and it's for a specific
- * table set the master appropriately
- */
- if (sscanf(ifp->name, "pimreg%" SCNu32, &table_id) == 1) {
- struct vrf *vrf;
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if ((table_id == vrf->data.l.table_id)
- && (ifp->vrf_id != vrf->vrf_id)) {
- struct interface *master = if_lookup_by_name(
- vrf->name, vrf->vrf_id);
-
- if (!master) {
- zlog_debug(
- "%s: Unable to find Master interface for %s",
- __PRETTY_FUNCTION__, vrf->name);
- return 0;
- }
- zclient_interface_set_master(zclient, master,
- ifp);
- }
- }
- }
- return 0;
-}
-
-static int pim_zebra_if_state_down(ZAPI_CALLBACK_ARGS)
-{
- struct interface *ifp;
-
- /*
- zebra api notifies interface up/down events by using the same call
- zebra_interface_state_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug(
- "%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id,
- (long)ifp->flags, ifp->metric, ifp->mtu,
- if_is_operative(ifp));
- }
-
- if (!if_is_operative(ifp)) {
- pim_ifchannel_delete_all(ifp);
- /*
- pim_if_addr_del_all() suffices for shutting down IGMP,
- but not for shutting down PIM
- */
- pim_if_addr_del_all(ifp);
-
- /*
- pim_sock_delete() closes the socket, stops read and timer
- threads,
- and kills all neighbors.
- */
- if (ifp->info) {
- pim_sock_delete(ifp, "link down");
- }
- }
-
- if (ifp->info)
- pim_if_del_vif(ifp);
-
- return 0;
-}
-
static int pim_zebra_interface_vrf_update(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
@@ -793,10 +581,6 @@ void pim_zebra_init(void)
zclient->zebra_capabilities = pim_zebra_capabilities;
zclient->zebra_connected = pim_zebra_connected;
zclient->router_id_update = pim_router_id_update_zebra;
- zclient->interface_add = pim_zebra_if_add;
- zclient->interface_delete = pim_zebra_if_del;
- zclient->interface_up = pim_zebra_if_state_up;
- zclient->interface_down = pim_zebra_if_state_down;
zclient->interface_address_add = pim_zebra_if_address_add;
zclient->interface_address_delete = pim_zebra_if_address_del;
zclient->interface_vrf_update = pim_zebra_interface_vrf_update;
@@ -1246,3 +1030,9 @@ struct zclient *pim_zebra_zclient_get(void)
else
return NULL;
}
+
+void pim_zebra_interface_set_master(struct interface *vrf,
+ struct interface *ifp)
+{
+ zclient_interface_set_master(zclient, vrf, ifp);
+}
diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h
index c9ed89863c..0f216cf5c9 100644
--- a/pimd/pim_zebra.h
+++ b/pimd/pim_zebra.h
@@ -51,4 +51,7 @@ void pim_zebra_update_all_interfaces(struct pim_instance *pim);
void pim_zebra_upstream_rpf_changed(struct pim_instance *pim,
struct pim_upstream *up,
struct pim_rpf *old);
+
+void pim_zebra_interface_set_master(struct interface *vrf,
+ struct interface *ifp);
#endif /* PIM_ZEBRA_H */
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 80561f350b..3173277ba7 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -346,20 +346,8 @@ int if_check_address(struct rip *rip, struct in_addr addr)
}
/* Inteface link down message processing. */
-int rip_interface_down(ZAPI_CALLBACK_ARGS)
+static int rip_ifp_down(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
-
- /* zebra_interface_state_read() updates interface structure in
- iflist. */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
rip_interface_sync(ifp);
rip_if_down(ifp);
@@ -373,17 +361,8 @@ int rip_interface_down(ZAPI_CALLBACK_ARGS)
}
/* Inteface link up message processing */
-int rip_interface_up(ZAPI_CALLBACK_ARGS)
+static int rip_ifp_up(struct interface *ifp)
{
- struct interface *ifp;
-
- /* zebra_interface_state_read () updates interface structure in
- iflist. */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
if (IS_RIP_DEBUG_ZEBRA)
zlog_debug(
"interface %s vrf %u index %d flags %#llx metric %d mtu %d is up",
@@ -405,11 +384,8 @@ int rip_interface_up(ZAPI_CALLBACK_ARGS)
}
/* Inteface addition message from zebra. */
-int rip_interface_add(ZAPI_CALLBACK_ARGS)
+static int rip_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
rip_interface_sync(ifp);
if (IS_RIP_DEBUG_ZEBRA)
@@ -435,19 +411,8 @@ int rip_interface_add(ZAPI_CALLBACK_ARGS)
return 0;
}
-int rip_interface_delete(ZAPI_CALLBACK_ARGS)
+static int rip_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
-
- s = zclient->ibuf;
- /* zebra_interface_state_read() updates interface structure in iflist */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
rip_interface_sync(ifp);
if (if_is_up(ifp)) {
rip_if_down(ifp);
@@ -458,10 +423,6 @@ int rip_interface_delete(ZAPI_CALLBACK_ARGS)
ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
- /* To support pseudo interface do not free interface structure. */
- /* if_delete(ifp); */
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
@@ -1263,4 +1224,6 @@ void rip_if_init(void)
/* Install interface node. */
install_node(&interface_node, rip_interface_config_write);
if_cmd_init();
+ if_zapi_callbacks(rip_ifp_create, rip_ifp_up,
+ rip_ifp_down, rip_ifp_destroy);
}
diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c
index 5a6b71fbaa..7260a40b19 100644
--- a/ripd/rip_snmp.c
+++ b/ripd/rip_snmp.c
@@ -551,7 +551,7 @@ static uint8_t *rip2PeerTable(struct variable *v, oid name[], size_t *length,
return (uint8_t *)&domain;
case RIP2PEERLASTUPDATE:
-#if 0
+#if 0
/* We don't know the SNMP agent startup time. We have two choices here:
* - assume ripd startup time equals SNMP agent startup time
* - don't support this variable, at all
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 0c88cb202b..90ee667f05 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -238,12 +238,8 @@ void rip_zclient_init(struct thread_master *master)
zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
zclient->zebra_connected = rip_zebra_connected;
- zclient->interface_add = rip_interface_add;
- zclient->interface_delete = rip_interface_delete;
zclient->interface_address_add = rip_interface_address_add;
zclient->interface_address_delete = rip_interface_address_delete;
- zclient->interface_up = rip_interface_up;
- zclient->interface_down = rip_interface_down;
zclient->interface_vrf_update = rip_interface_vrf_update;
zclient->redistribute_route_add = rip_zebra_read_route;
zclient->redistribute_route_del = rip_zebra_read_route;
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 9ed9dc28fe..9209a76460 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -43,10 +43,10 @@
/* If RFC2133 definition is used. */
#ifndef IPV6_JOIN_GROUP
-#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
+#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
#endif
#ifndef IPV6_LEAVE_GROUP
-#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
+#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#endif
DEFINE_MTYPE_STATIC(RIPNGD, RIPNG_IF, "ripng interface")
@@ -196,19 +196,8 @@ static int ripng_if_down(struct interface *ifp)
}
/* Inteface link up message processing. */
-int ripng_interface_up(ZAPI_CALLBACK_ARGS)
+static int ripng_ifp_up(struct interface *ifp)
{
- struct stream *s;
- struct interface *ifp;
-
- /* zebra_interface_state_read() updates interface structure in iflist.
- */
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
if (IS_RIPNG_DEBUG_ZEBRA)
zlog_debug(
"interface up %s vrf %u index %d flags %llx metric %d mtu %d",
@@ -230,19 +219,8 @@ int ripng_interface_up(ZAPI_CALLBACK_ARGS)
}
/* Inteface link down message processing. */
-int ripng_interface_down(ZAPI_CALLBACK_ARGS)
+static int ripng_ifp_down(struct interface *ifp)
{
- struct stream *s;
- struct interface *ifp;
-
- /* zebra_interface_state_read() updates interface structure in iflist.
- */
- s = zclient->ibuf;
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
ripng_interface_sync(ifp);
ripng_if_down(ifp);
@@ -256,11 +234,8 @@ int ripng_interface_down(ZAPI_CALLBACK_ARGS)
}
/* Inteface addition message from zebra. */
-int ripng_interface_add(ZAPI_CALLBACK_ARGS)
+static int ripng_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
ripng_interface_sync(ifp);
if (IS_RIPNG_DEBUG_ZEBRA)
@@ -281,19 +256,8 @@ int ripng_interface_add(ZAPI_CALLBACK_ARGS)
return 0;
}
-int ripng_interface_delete(ZAPI_CALLBACK_ARGS)
+static int ripng_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- /* zebra_interface_state_read() updates interface structure in iflist
- */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
ripng_interface_sync(ifp);
if (if_is_up(ifp)) {
ripng_if_down(ifp);
@@ -304,10 +268,6 @@ int ripng_interface_delete(ZAPI_CALLBACK_ARGS)
ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
- /* To support pseudo interface do not free interface structure. */
- /* if_delete(ifp); */
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
@@ -999,4 +959,6 @@ void ripng_if_init(void)
/* Install interface node. */
install_node(&interface_node, interface_config_write);
if_cmd_init();
+ if_zapi_callbacks(ripng_ifp_create, ripng_ifp_up,
+ ripng_ifp_down, ripng_ifp_destroy);
}
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index a557a90c82..fa61d69caa 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -242,10 +242,6 @@ void zebra_init(struct thread_master *master)
zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
zclient->zebra_connected = ripng_zebra_connected;
- zclient->interface_up = ripng_interface_up;
- zclient->interface_down = ripng_interface_down;
- zclient->interface_add = ripng_interface_add;
- zclient->interface_delete = ripng_interface_delete;
zclient->interface_address_add = ripng_interface_address_add;
zclient->interface_address_delete = ripng_interface_address_delete;
zclient->interface_vrf_update = ripng_interface_vrf_update;
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index ef4e474737..ad2ddd0dba 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -2361,7 +2361,7 @@ DEFUN (show_ipv6_protocols,
return CMD_SUCCESS;
vty_out (vty, "Routing Protocol is \"ripng\"\n");
-
+
vty_out (vty, "Sending updates every %ld seconds, next due in %d seconds\n",
ripng->update_time, 0);
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 6263f429ea..da2aa2f539 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -46,51 +46,19 @@ struct zclient *zclient = NULL;
/* For registering threads. */
extern struct thread_master *master;
-static struct interface *zebra_interface_if_lookup(struct stream *s)
-{
- char ifname_tmp[INTERFACE_NAMSIZ];
-
- /* Read interface name. */
- stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
-
- /* And look it up. */
- return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
-}
-
/* Inteface addition message from zebra. */
-static int interface_add(ZAPI_CALLBACK_ARGS)
+static int sharp_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (!ifp->info)
- return 0;
-
return 0;
}
-static int interface_delete(ZAPI_CALLBACK_ARGS)
+static int sharp_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- /* zebra_interface_state_read () updates interface structure in iflist
- */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
static int interface_address_add(ZAPI_CALLBACK_ARGS)
{
-
zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
return 0;
@@ -109,19 +77,13 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int interface_state_up(ZAPI_CALLBACK_ARGS)
+static int sharp_ifp_up(struct interface *ifp)
{
-
- zebra_interface_if_lookup(zclient->ibuf);
-
return 0;
}
-static int interface_state_down(ZAPI_CALLBACK_ARGS)
+static int sharp_ifp_down(struct interface *ifp)
{
-
- zebra_interface_state_read(zclient->ibuf, vrf_id);
-
return 0;
}
@@ -243,6 +205,15 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS)
static void zebra_connected(struct zclient *zclient)
{
zclient_send_reg_requests(zclient, VRF_DEFAULT);
+
+ /*
+ * Do not actually turn this on yet
+ * This is just the start of the infrastructure needed here
+ * This can be fixed at a later time.
+ *
+ * zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
+ * ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
+ */
}
void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
@@ -338,28 +309,13 @@ void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import,
__PRETTY_FUNCTION__);
}
-static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS)
+static int sharp_debug_nexthops(struct zapi_route *api)
{
- struct sharp_nh_tracker *nht;
- struct zapi_route nhr;
- char buf[PREFIX_STRLEN];
int i;
+ char buf[PREFIX_STRLEN];
- if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
- zlog_warn("%s: Decode of update failed", __PRETTY_FUNCTION__);
-
- return 0;
- }
-
- zlog_debug("Received update for %s",
- prefix2str(&nhr.prefix, buf, sizeof(buf)));
-
- nht = sharp_nh_tracker_get(&nhr.prefix);
- nht->nhop_num = nhr.nexthop_num;
- nht->updates++;
-
- for (i = 0; i < nhr.nexthop_num; i++) {
- struct zapi_nexthop *znh = &nhr.nexthops[i];
+ for (i = 0; i < api->nexthop_num; i++) {
+ struct zapi_nexthop *znh = &api->nexthops[i];
switch (znh->type) {
case NEXTHOP_TYPE_IPV4_IFINDEX:
@@ -389,6 +345,45 @@ static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS)
break;
}
}
+
+ return i;
+}
+static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS)
+{
+ struct sharp_nh_tracker *nht;
+ struct zapi_route nhr;
+
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ zlog_warn("%s: Decode of update failed", __PRETTY_FUNCTION__);
+
+ return 0;
+ }
+
+ zlog_debug("Received update for %pFX", &nhr.prefix);
+
+ nht = sharp_nh_tracker_get(&nhr.prefix);
+ nht->nhop_num = nhr.nexthop_num;
+ nht->updates++;
+
+ sharp_debug_nexthops(&nhr);
+
+ return 0;
+}
+
+static int sharp_redistribute_route(ZAPI_CALLBACK_ARGS)
+{
+ struct zapi_route api;
+
+ if (zapi_route_decode(zclient->ibuf, &api) < 0)
+ zlog_warn("%s: Decode of redistribute failed: %d",
+ __PRETTY_FUNCTION__,
+ ZEBRA_REDISTRIBUTE_ROUTE_ADD);
+
+ zlog_debug("%s: %pFX (%s)", zserv_command_string(cmd),
+ &api.prefix, zebra_route_string(api.type));
+
+ sharp_debug_nexthops(&api);
+
return 0;
}
@@ -398,17 +393,19 @@ void sharp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = true};
+ if_zapi_callbacks(sharp_ifp_create, sharp_ifp_up,
+ sharp_ifp_down, sharp_ifp_destroy);
+
zclient = zclient_new(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
zclient->zebra_connected = zebra_connected;
- zclient->interface_add = interface_add;
- zclient->interface_delete = interface_delete;
- zclient->interface_up = interface_state_up;
- zclient->interface_down = interface_state_down;
zclient->interface_address_add = interface_address_add;
zclient->interface_address_delete = interface_address_delete;
zclient->route_notify_owner = route_notify_owner;
zclient->nexthop_update = sharp_nexthop_update;
zclient->import_check_update = sharp_nexthop_update;
+
+ zclient->redistribute_route_add = sharp_redistribute_route;
+ zclient->redistribute_route_del = sharp_redistribute_route;
}
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 2944cdad32..976f892efb 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -49,46 +49,16 @@ bool debug;
struct zclient *zclient;
static struct hash *static_nht_hash;
-static struct interface *zebra_interface_if_lookup(struct stream *s)
-{
- char ifname_tmp[INTERFACE_NAMSIZ];
-
- /* Read interface name. */
- stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
-
- /* And look it up. */
- return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
-}
-
/* Inteface addition message from zebra. */
-static int interface_add(ZAPI_CALLBACK_ARGS)
+static int static_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (!ifp)
- return 0;
-
static_ifindex_update(ifp, true);
+
return 0;
}
-static int interface_delete(ZAPI_CALLBACK_ARGS)
+static int static_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
- struct stream *s;
-
- s = zclient->ibuf;
- /* zebra_interface_state_read () updates interface structure in iflist
- */
- ifp = zebra_interface_state_read(s, vrf_id);
-
- if (ifp == NULL)
- return 0;
-
- if_set_index(ifp, IFINDEX_INTERNAL);
-
static_ifindex_update(ifp, false);
return 0;
}
@@ -113,37 +83,25 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int interface_state_up(ZAPI_CALLBACK_ARGS)
+static int static_ifp_up(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_if_lookup(zclient->ibuf);
-
- if (ifp) {
- if (if_is_vrf(ifp)) {
- struct static_vrf *svrf =
- static_vrf_lookup_by_id(vrf_id);
+ if (if_is_vrf(ifp)) {
+ struct static_vrf *svrf = static_vrf_lookup_by_id(ifp->vrf_id);
- static_fixup_vrf_ids(svrf);
- static_config_install_delayed_routes(svrf);
- }
-
- /* Install any static reliant on this interface coming up */
- static_install_intf_nh(ifp);
- static_ifindex_update(ifp, true);
+ static_fixup_vrf_ids(svrf);
+ static_config_install_delayed_routes(svrf);
}
+ /* Install any static reliant on this interface coming up */
+ static_install_intf_nh(ifp);
+ static_ifindex_update(ifp, true);
+
return 0;
}
-static int interface_state_down(ZAPI_CALLBACK_ARGS)
+static int static_ifp_down(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (ifp)
- static_ifindex_update(ifp, false);
+ static_ifindex_update(ifp, false);
return 0;
}
@@ -504,19 +462,19 @@ extern void static_zebra_route_add(struct route_node *rn,
ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
zclient, &api);
}
+
void static_zebra_init(void)
{
struct zclient_options opt = { .receive_notify = true };
+ if_zapi_callbacks(static_ifp_create, static_ifp_up,
+ static_ifp_down, static_ifp_destroy);
+
zclient = zclient_new(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
zclient->zebra_capabilities = static_zebra_capabilities;
zclient->zebra_connected = zebra_connected;
- zclient->interface_add = interface_add;
- zclient->interface_delete = interface_delete;
- zclient->interface_up = interface_state_up;
- zclient->interface_down = interface_state_down;
zclient->interface_address_add = interface_address_add;
zclient->interface_address_delete = interface_address_delete;
zclient->route_notify_owner = route_notify_owner;
diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h
index 7ff210cae3..f20bbc52d9 100644
--- a/tests/lib/test_typelist.h
+++ b/tests/lib/test_typelist.h
@@ -280,7 +280,7 @@ static void concat(test_, TYPE)(void)
assert(!tmp || tmp->val >= j);
} else
assert(gteq == list_first(&head));
-
+
if (gteq)
assert(gteq->val >= j);
}
diff --git a/tests/topotests/bgp-route-map/bgp_route_map_topo1.json b/tests/topotests/bgp-route-map/bgp_route_map_topo1.json
new file mode 100644
index 0000000000..e89263961d
--- /dev/null
+++ b/tests/topotests/bgp-route-map/bgp_route_map_topo1.json
@@ -0,0 +1,187 @@
+{
+ "address_types": ["ipv4","ipv6"],
+ "ipv4base":"10.0.0.0",
+ "ipv4mask":30,
+ "ipv6base":"fd00::",
+ "ipv6mask":64,
+ "link_ip_start":{"ipv4":"10.0.0.0", "v4mask":30, "ipv6":"fd00::", "v6mask":64},
+ "lo_prefix":{"ipv4":"1.0.", "v4mask":32, "ipv6":"2001:DB8:F::", "v6mask":128},
+ "routers":{
+ "r1":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r2":{"ipv4":"auto", "ipv6":"auto"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r2":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1":{"ipv4":"auto", "ipv6":"auto"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r3":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1":{"ipv4":"auto", "ipv6":"auto"},
+ "r2":{"ipv4":"auto", "ipv6":"auto"},
+ "r4":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r4":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"200",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp-route-map/bgp_route_map_topo2.json b/tests/topotests/bgp-route-map/bgp_route_map_topo2.json
new file mode 100755
index 0000000000..c22a4c3ea7
--- /dev/null
+++ b/tests/topotests/bgp-route-map/bgp_route_map_topo2.json
@@ -0,0 +1,316 @@
+{
+ "address_types": ["ipv4", "ipv6"],
+ "ipv4base": "10.0.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {
+ "ipv4": "10.0.0.0",
+ "v4mask": 30,
+ "ipv6": "fd00::",
+ "v6mask": 64
+ },
+ "lo_prefix": {
+ "ipv4": "1.0.",
+ "v4mask": 32,
+ "ipv6": "2001:DB8:F::",
+ "v6mask": 128
+ },
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r2": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ },
+ "redistribute": [{
+ "redist_type": "static"
+ },
+ {
+ "redist_type": "connected"
+ }
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ },
+ "redistribute": [{
+ "redist_type": "static"
+ },
+ {
+ "redist_type": "connected"
+ }
+ ]
+ }
+ }
+ }
+ },
+
+ "static_routes": [{
+ "network": "10.0.20.1/32",
+ "no_of_ip": 2,
+ "next_hop": "10.0.0.2"
+ },
+ {
+ "network": "1::1/128",
+ "no_of_ip": 2,
+ "next_hop": "fd00::2"
+ }]
+ },
+ "r2": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r3": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r1": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r2": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r4": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ },
+ "r5": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r2": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {}
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r4": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "200",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r5": {
+ "links": {
+ "lo": {
+ "ipv4": "auto",
+ "ipv6": "auto",
+ "type": "loopback"
+ },
+ "r3": {
+ "ipv4": "auto",
+ "ipv6": "auto"
+ }
+ },
+ "bgp": {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r5": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r5": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp-route-map/test_route_map_topo1.py b/tests/topotests/bgp-route-map/test_route_map_topo1.py
new file mode 100755
index 0000000000..86ec6c82d2
--- /dev/null
+++ b/tests/topotests/bgp-route-map/test_route_map_topo1.py
@@ -0,0 +1,1361 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2019 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# 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 VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE 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.
+#
+
+#################################
+# TOPOLOGY
+#################################
+"""
+
+ +-------+
+ +------- | R2 |
+ | +-------+
+ | |
+ +-------+ |
+ | R1 | |
+ +-------+ |
+ | |
+ | +-------+ +-------+
+ +---------- | R3 |----------| R4 |
+ +-------+ +-------+
+
+"""
+
+#################################
+# TEST SUMMARY
+#################################
+"""
+Following tests are covered to test route-map functionality:
+TC_34:
+ Verify if route-maps is applied in both inbound and
+ outbound direction to same neighbor/interface.
+TC_36:
+ Test permit/deny statements operation in route-maps with a
+ permutation and combination of permit/deny in prefix-lists
+TC_35:
+ Test multiple sequence numbers in a single route-map for different
+ match/set clauses.
+TC_37:
+ Test add/remove route-maps with multiple set
+ clauses and without any match statement.(Set only)
+TC_38:
+ Test add/remove route-maps with multiple match
+ clauses and without any set statement.(Match only)
+"""
+
+import sys
+import json
+import time
+import pytest
+import inspect
+import os
+from time import sleep
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, get_topogen
+from mininet.topo import Topo
+
+# Required to instantiate the topology builder class.
+from lib.topojson import *
+from lib.common_config import (
+ start_topology, write_test_header,
+ write_test_footer, verify_bgp_community,
+ verify_rib, delete_route_maps, create_bgp_community_lists,
+ interface_status, create_route_maps, create_prefix_lists,
+ verify_route_maps, check_address_types,
+ shutdown_bringup_interface, verify_prefix_lists, reset_config_on_routers)
+from lib.topolog import logger
+from lib.bgp import (
+ verify_bgp_convergence, create_router_bgp,
+ clear_bgp_and_verify, verify_bgp_attributes)
+from lib.topojson import build_topo_from_json, build_config_from_json
+
+
+# Global variables
+bgp_convergence = False
+BGP_CONVERGENCE = False
+ADDR_TYPES = check_address_types()
+# Reading the data from JSON File for topology and configuration creation
+jsonFile = "{}/bgp_route_map_topo1.json".format(CWD)
+try:
+ with open(jsonFile, 'r') as topoJson:
+ topo = json.load(topoJson)
+except IOError:
+ assert False, "Could not read file {}".format(jsonFile)
+
+# Global variables
+bgp_convergence = False
+NETWORK = {
+ "ipv4": ["11.0.20.1/32", "20.0.20.1/32"],
+ "ipv6": ["1::1/128", "2::1/128"]
+}
+MASK = {"ipv4": "32", "ipv6": "128"}
+NEXT_HOP = {
+ "ipv4": "10.0.0.2",
+ "ipv6": "fd00::2"
+}
+ADDR_TYPES = check_address_types()
+
+
+class CreateTopo(Topo):
+ """
+ Test topology builder
+
+
+ * `Topo`: Topology object
+ """
+
+ def build(self, *_args, **_opts):
+ """Build function"""
+ tgen = get_topogen(self)
+
+ # Building topology from json file
+ build_topo_from_json(tgen, topo)
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+ global ADDR_TYPES
+ 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")
+
+ # This function initiates the topology build with Topogen...
+ tgen = Topogen(CreateTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Checking BGP convergence
+ global bgp_convergence
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Api call verify whether BGP is converged
+ bgp_convergence = verify_bgp_convergence(tgen, topo)
+ assert bgp_convergence is True, ("setup_module :Failed \n Error:"
+ " {}".format(bgp_convergence))
+
+ logger.info("Running setup_module() done")
+
+
+def teardown_module():
+ """
+ Teardown the pytest environment
+
+ * `mod`: module name
+ """
+
+ logger.info("Running teardown_module to delete topology")
+
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ tgen.stop_topology()
+
+ logger.info("Testsuite end time: {}".
+ format(time.asctime(time.localtime(time.time()))))
+ logger.info("=" * 40)
+
+
+def test_route_map_inbound_outbound_same_neighbor_p0(request):
+ """
+ TC_34:
+ Verify if route-maps is applied in both inbound and
+ outbound direction to same neighbor/interface.
+ """
+
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[adt][0],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt],
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_dict_2 = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": NETWORK[adt][1],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt],
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_5 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_dict_2 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "action": "permit",
+ "network": NETWORK["ipv4"][0]
+ }],
+ "pf_list_2_ipv4": [{
+ "seqid": 10,
+ "action": "permit",
+ "network": NETWORK["ipv4"][1]
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "action": "permit",
+ "network": NETWORK["ipv6"][0]
+ }],
+ "pf_list_2_ipv6": [{
+ "seqid": 100,
+ "action": "permit",
+ "network": NETWORK["ipv6"][1]
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_6 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ }
+ }],
+ "rmap_match_tag_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_2_{}".format(addr_type)
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_7 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_tag_1_ipv4",
+ "direction": "in"},
+ {"name":
+ "rmap_match_tag_1_ipv4",
+ "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_tag_1_ipv6",
+ "direction": "in"},
+ {"name":
+ "rmap_match_tag_1_ipv6",
+ "direction": "out"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for adt in ADDR_TYPES:
+ # Verifying RIB routes
+ dut = "r3"
+ protocol = "bgp"
+ input_dict_2 = {
+ "r4": {
+ "static_routes": [
+ {
+ "network": [NETWORK[adt][1]],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt]
+ }
+ ]
+ }
+ }
+
+ result = verify_rib(tgen, adt, dut, input_dict_2, protocol=protocol)
+ assert result is not True, "Testcase {} : Failed \n"
+ "Expected behavior: routes are not present in rib \n"
+ "Error: {}".format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = "r4"
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": [NETWORK[adt][0]],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt]
+ }
+ ]
+ }
+ }
+ result = verify_rib(tgen, adt, dut, input_dict, protocol=protocol)
+ assert result is not True, "Testcase {} : Failed \n "
+ "Expected behavior: routes are not present in rib \n "
+ "Error: {}".format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+@pytest.mark.parametrize("prefix_action, rmap_action", [("permit", "permit"),
+ ("permit", "deny"), ("deny", "permit"),
+ ("deny", "deny")])
+def test_route_map_with_action_values_combination_of_prefix_action_p0(
+ request, prefix_action, rmap_action):
+ """
+ TC_36:
+ Test permit/deny statements operation in route-maps with a permutation and
+ combination of permit/deny in prefix-lists
+ """
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ # Don"t run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[adt][0],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt]
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Permit in perfix list and route-map
+ input_dict_2 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": prefix_action
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": prefix_action
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": rmap_action,
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_7 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {"name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "in"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ dut = "r3"
+ protocol = "bgp"
+ input_dict_2 = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": [NETWORK[adt][0]],
+ "no_of_ip": 9,
+ "next_hop": NEXT_HOP[adt],
+ }
+ ]
+ }
+ }
+
+ result = verify_rib(tgen, adt, dut, input_dict_2, protocol=protocol)
+ if "deny" in [prefix_action, rmap_action]:
+ assert result is not True, "Testcase {} : Failed \n Error: {}".\
+ format(tc_name, result)
+ else:
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+
+def test_route_map_multiple_seq_different_match_set_clause_p0(request):
+ """
+ TC_35:
+ Test multiple sequence numbers in a single route-map for different
+ match/set clauses.
+ """
+
+ tgen = get_topogen()
+ # test case name
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [{
+ "network": NETWORK[adt][0],
+ "no_of_ip": 1,
+ "next_hop": NEXT_HOP[adt]
+ }]
+ }
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": "permit"
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [
+ {
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_2_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "aspath": {
+ "as_num": 500
+ }
+ }
+ },
+ {
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_2_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ },
+ {
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for adt in ADDR_TYPES:
+ # Verifying RIB routes
+ dut = "r3"
+ protocol = "bgp"
+ input_dict = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_list1": [{
+ "set": {
+ "med": 50,
+ }
+ }],
+ }
+ }
+ }
+
+ static_routes = [NETWORK[adt][0]]
+
+ time.sleep(2)
+ result = verify_bgp_attributes(tgen, adt, dut, static_routes,
+ "rmap_match_pf_list1", input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ dut = "r4"
+ result = verify_bgp_attributes(tgen, adt, dut, static_routes,
+ "rmap_match_pf_list1", input_dict)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ logger.info("Testcase " + tc_name + " :Passed \n")
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_map_set_only_no_match_p0(request):
+ """
+ TC_37:
+ Test add/remove route-maps with multiple set
+ clauses and without any match statement.(Set only)
+ """
+
+ tgen = get_topogen()
+ # test case name
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [{
+ "network": NETWORK[adt][0],
+ "no_of_ip": 1,
+ "next_hop": NEXT_HOP[adt]
+ }]
+ }
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1": [
+ {
+ "action": "permit",
+ "set": {
+ "med": 50,
+ "localpref": 150,
+ "weight": 4000
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rmap_match_pf_1",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ time.sleep(2)
+ for adt in ADDR_TYPES:
+ input_dict_4 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1": [
+ {
+ "action": "permit",
+ "set": {
+ "med": 50,
+ }
+ }
+ ]
+ }
+ }
+ }
+ # Verifying RIB routes
+ static_routes = [NETWORK[adt][0]]
+ result = verify_bgp_attributes(tgen, adt, "r3", static_routes,
+ "rmap_match_pf_1", input_dict_3)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ result = verify_bgp_attributes(tgen, adt, "r4", static_routes,
+ "rmap_match_pf_1", input_dict_4)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ logger.info("Testcase " + tc_name + " :Passed \n")
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_map_match_only_no_set_p0(request):
+ """
+ TC_38:
+ Test add/remove route-maps with multiple match
+ clauses and without any set statement.(Match only)
+ """
+
+ tgen = get_topogen()
+ # test case name
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+
+ for adt in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [{
+ "network": NETWORK[adt][0],
+ "no_of_ip": 1,
+ "next_hop": NEXT_HOP[adt]
+ }]
+ }
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ "r1": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": "permit"
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "set": {
+ "med": 50,
+ "localpref": 150,
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ "r1": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_5 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "pf_list_1_ipv4": [{
+ "seqid": 10,
+ "network": "any",
+ "action": "permit"
+ }]
+ },
+ "ipv6": {
+ "pf_list_1_ipv6": [{
+ "seqid": 100,
+ "network": "any",
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_5)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_6 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_list_1_{}".format(addr_type)
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_7 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": "out"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for adt in ADDR_TYPES:
+ # Verifying RIB routes
+ static_routes = [NETWORK[adt][0]]
+ result = verify_bgp_attributes(tgen, adt, "r3", static_routes,
+ "rmap_match_pf_1", input_dict_3)
+ assert result is True, "Test case {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
+
+
diff --git a/tests/topotests/bgp-route-map/test_route_map_topo2.py b/tests/topotests/bgp-route-map/test_route_map_topo2.py
new file mode 100755
index 0000000000..7009fc97ce
--- /dev/null
+++ b/tests/topotests/bgp-route-map/test_route_map_topo2.py
@@ -0,0 +1,3916 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2019 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# 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 VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE 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.
+#
+
+"""Following tests are covered to test route-map functionality.
+TC_57:
+ Create route map to match prefix-list and permit inbound
+ and outbound prefixes and set criteria on match
+TC_52:
+ Test modify set/match clauses in a route-map to see
+ if it takes immediate effect.
+TC_61:
+ Delete the route maps.
+TC_50_1:
+ Test modify/remove prefix-lists referenced by a
+ route-map for match statement.
+TC_50_1:
+ Remove prefix-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+TC_51:
+ Add and remove community-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+TC_45:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical OR-ed of multiple match statements)
+TC_44:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical AND of multiple match statements)
+TC_41:
+ Test add/remove route-maps to specific neighbor and see if
+ it takes effect as intended
+TC_56:
+ Test clear BGP sessions and interface flaps to see if
+ route-map properties are intact.
+TC_46:
+ Verify if a blank sequence number can be create(without any
+ match/set clause) and check if it allows all the traffic/prefixes
+TC_48:
+ Create route map setting local preference and weight to eBGP peeer
+ and metric to ibgp peer and verifying it should not get advertised
+TC_43:
+ Test multiple set statements as part of a route-map's
+ single sequence number.
+TC_54:
+ Verify route-maps continue clause functionality.
+TC_55:
+ Verify route-maps goto clause functionality.
+TC_53:
+ Verify route-maps call clause functionality.
+TC_58:
+ Create route map deny inbound and outbound prefixes on
+ match prefix list and set criteria on match
+TC_59:
+ Create route map to permit inbound prefixes with filter
+ match tag and set criteria
+TC_60
+ Create route map to deny outbound prefixes with filter match tag,
+ and set criteria
+"""
+
+#################################
+# TOPOLOGY
+#################################
+"""
+
+ +-------+
+ +--------- | R2 |
+ | +-------+
+ |iBGP |
+ +-------+ |
+ | R1 | |iBGP
+ +-------+ |
+ | |
+ | iBGP +-------+ eBGP +-------+
+ +---------- | R3 |----------| R4 |
+ +-------+ +-------+
+ |
+ |eBGP
+ |
+ +-------+
+ | R5 |
+ +-------+
+
+
+"""
+
+import sys
+import json
+import time
+import pytest
+import inspect
+import os
+from time import sleep
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, get_topogen
+from mininet.topo import Topo
+
+# Required to instantiate the topology builder class.
+from lib.common_config import (
+ start_topology, write_test_header,
+ write_test_footer, create_static_routes,
+ verify_rib, delete_route_maps, create_bgp_community_lists,
+ interface_status, create_route_maps, create_prefix_lists,
+ verify_route_maps, check_address_types, verify_bgp_community,
+ shutdown_bringup_interface, verify_prefix_lists, reset_config_on_routers)
+from lib.topolog import logger
+from lib.bgp import (
+ verify_bgp_convergence, create_router_bgp,
+ clear_bgp_and_verify, verify_bgp_attributes)
+from lib.topojson import build_topo_from_json, build_config_from_json
+
+# Reading the data from JSON File for topology and configuration creation
+jsonFile = "{}/bgp_route_map_topo2.json".format(CWD)
+
+try:
+ with open(jsonFile, 'r') as topoJson:
+ topo = json.load(topoJson)
+except IOError:
+ assert False, "Could not read file {}".format(jsonFile)
+
+# Global variables
+# Global variables
+bgp_convergence = False
+NETWORK = {
+ "ipv4": ["11.0.20.1/32", "11.0.20.2/32"],
+ "ipv6": ["2::1/128", "2::2/128"]
+}
+
+bgp_convergence = False
+BGP_CONVERGENCE = False
+ADDR_TYPES = check_address_types()
+
+
+class BGPRmapTopo(Topo):
+ """BGPRmapTopo.
+
+ BGPRmap topology 1
+ * `Topo`: Topology object
+ """
+
+ def build(self, *_args, **_opts):
+ """Build function."""
+ tgen = get_topogen(self)
+
+ # Building topology and configuration from json file
+ build_topo_from_json(tgen, topo)
+
+
+def setup_module(mod):
+ """setup_module.
+
+ Set up the pytest environment
+ * `mod`: module name
+ """
+ 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")
+
+ # This function initiates the topology build with Topogen...
+ tgen = Topogen(BGPRmapTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ # Checking BGP convergence
+ global bgp_convergence
+ global ADDR_TYPES
+
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Api call verify whether BGP is converged
+ bgp_convergence = verify_bgp_convergence(tgen, topo)
+ assert bgp_convergence is True, ('setup_module :Failed \n Error:'
+ ' {}'.format(bgp_convergence))
+ logger.info("Running setup_module() done")
+
+
+def teardown_module(mod):
+ """teardown_module.
+
+ Teardown the pytest environment.
+ * `mod`: module name
+ """
+ logger.info("Running teardown_module to delete topology")
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ tgen.stop_topology()
+
+ logger.info("Testsuite end time: {}".format(
+ time.asctime(time.localtime(time.time()))))
+ logger.info("="*40)
+
+
+#####################################################
+# Tests starting
+#####################################################
+
+
+def test_rmap_match_prefix_list_permit_in_and_outbound_prefixes_p0():
+ """
+ TC: 57
+ Create route map to match prefix-list and permit inbound
+ and outbound prefixes and set criteria on match
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ }
+ }
+ }
+ }
+
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ for addr_type in ADDR_TYPES:
+ # Create route map
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ },
+ ],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ },
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ result4 = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result4 = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ result4 = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_modify_set_match_clauses_in_rmap_p0():
+ """
+ TC_52:
+ Test modify set/match clauses in a route-map to see
+ if it takes immediate effect.
+ """
+
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }],
+ 'pf_list_2_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }],
+ 'pf_list_2_ipv6': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result4 = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ # dual stack changes
+ for addr_type in ADDR_TYPES:
+ result4 = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result4 is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result4)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Modify set/match clause of in-used route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 1000,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 2000
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_delete_route_maps_p1():
+ """
+ TC_61:
+ Delete the route maps.
+ """
+
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "tag": "4001"
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Delete route maps
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ 'r3': {
+ 'route_maps': ['rmap_match_tag_1_{}'.format(addr_type)]
+ }
+ }
+ result = delete_route_maps(tgen, input_dict)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_route_maps(tgen, input_dict)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_modify_prefix_list_referenced_by_rmap_p0():
+ """
+ TC_50_1:
+ Test modify/remove prefix-lists referenced by a
+ route-map for match statement.
+ """
+
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit',
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Modify ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ sleep(5)
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_remove_prefix_list_referenced_by_rmap_p0():
+ """
+ TC_50_1:
+ Remove prefix-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ for addr_type in ADDR_TYPES:
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Remove/Delete prefix list
+ input_dict_3 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit',
+ 'delete': True
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit',
+ 'delete': True
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_prefix_lists(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Api call to clear bgp, so config changes would be reflected
+ dut = 'r3'
+ result = clear_bgp_and_verify(tgen, topo, dut)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_add_and_remove_community_list_referenced_by_rmap_p0():
+ """
+ TC_51:
+ Add and remove community-list referencec by route-map match cluase
+ and verifying it reflecting as intended
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Creating configuration from JSON
+ # build_config_from_json(tgen, topo)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_5 = {
+ "r1": {
+ "route_maps": {
+ "rm_r1_out_{}".format(addr_type): [{
+ "action": "permit",
+ "set": {
+ "large_community": {"num": "1:1:1 1:2:3 2:1:1 2:2:2"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_6 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name": "rm_r1_out_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name": "rm_r1_out_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create standard large commumity-list
+ input_dict_1 = {
+ "r3": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "rmap_lcomm_{}".format(addr_type),
+ "value": "1:1:1 1:2:3 2:1:1 2:2:2",
+ "large": True
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create route map
+ input_dict_2 = {
+ "r3": {
+ "route_maps": {
+ "rm_r3_in_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type : {
+ "large-community-list": {"id": "rmap_lcomm_"+
+ addr_type}
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_3 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rm_r3_in_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name": "rm_r3_in_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_3)
+
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ sleep(5)
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verify large-community-list
+ dut = 'r3'
+ networks = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ input_dict_4 = {
+ 'largeCommunity': '1:1:1 1:2:3 2:1:1 2:2:2'
+ }
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_community(tgen, addr_type, dut, networks[
+ addr_type],input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_multiple_match_statement_in_route_map_logical_ORed_p0():
+ """
+ TC_45:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical OR-ed of multiple match statements)
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Api call to advertise networks
+ input_dict_nw1 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '10.0.30.1/32'}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '1::1/128'}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_nw1)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Api call to advertise networks
+ input_dict_nw2 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '20.0.30.1/32'}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "advertise_networks": [
+ {"network": '2::1/128'}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_nw2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_2_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_2_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ input_dict_3_addr_type ={}
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150
+ }
+ }]
+ }
+ }
+ }
+ input_dict_3_addr_type[addr_type] = input_dict_3
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 200
+ }
+ }]
+ }
+ }
+ }
+ input_dict_3_addr_type[addr_type] = input_dict_3
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_6 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.30.1/32"],
+ "ipv6": ["1::1/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3_addr_type[addr_type])
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ routes = {
+ "ipv4": ["20.0.30.1/32"],
+ "ipv6": ["2::1/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_multiple_match_statement_in_route_map_logical_ANDed():
+ """
+ TC_44:
+ Test multiple match statements as part of a route-map's single
+ sequence number. (Logical AND of multiple match statements)
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_5 = {
+ "r1": {
+ "route_maps": {
+ "rm_r1_out_{}".format(addr_type): [{
+ "action": "permit",
+ "set": {
+ "large_community": {
+ "num": "1:1:1 1:2:3 2:1:1 2:2:2"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_5)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ for addr_type in ADDR_TYPES:
+ input_dict_6 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rm_r1_out_{}".format(addr_type),
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_6)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create standard large commumity-list
+ input_dict_1 = {
+ "r3": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "rmap_lcomm_{}".format(addr_type),
+ "value": "1:1:1 1:2:3 2:1:1 2:2:2",
+ "large": True
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ # Create route map
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type : {
+ "large_community_list": {"id": "rmap_lcomm_"+
+ addr_type}
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ # Configure neighbor for route map
+ for addr_type in ADDR_TYPES:
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_{}".format(addr_type),
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ # sleep(10)
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_add_remove_rmap_to_specific_neighbor_p0():
+ """
+ TC_41:
+ Test add/remove route-maps to specific neighbor and see if
+ it takes effect as intended
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'deny'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : \n'
+ 'Expected Behavior: Routes are not present in RIB \n'
+ ' Error: {}'.format(
+ tc_name, result)
+
+ # Remove applied rmap from neighbor
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in',
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in',
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_clear_bgp_and_flap_interface_to_verify_rmap_properties_p0():
+ """
+ TC_56:
+ Test clear BGP sessions and interface flaps to see if
+ route-map properties are intact.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # clear bgp, so config changes would be reflected
+ dut = 'r3'
+ result = clear_bgp_and_verify(tgen, topo, dut)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Flap interface to see if route-map properties are intact
+ # Shutdown interface
+ dut = "r3"
+ intf = "r3-r1-eth0"
+ shutdown_bringup_interface(tgen, dut, intf, False)
+
+ sleep(5)
+
+ # Bringup interface
+ dut = "r3"
+ intf = "r3-r1-eth0"
+ shutdown_bringup_interface(tgen, dut, intf, True)
+
+ # Verify BGP convergence once interface is up
+ result = verify_bgp_convergence(tgen, topo)
+ assert result is True, (
+ 'setup_module :Failed \n Error:' ' {}'.format(result))
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_rmap_without_match_and_set_clause_p0():
+ """
+ TC_46:
+ Verify if a blank sequence number can be create(without any
+ match/set clause) and check if it allows all the traffic/prefixes
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_no_match_set_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '5'
+ }],
+ "rmap_no_match_set_2_{}".format(addr_type): [{
+ "action": "deny",
+ 'seq_id': '5'
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_no_match_set_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_set_localpref_weight_to_ebgp_and_med_to_ibgp_peers_p0():
+ """
+ TC_48:
+ Create route map setting local preference and weight to eBGP peeer
+ and metric to ibgp peer and verifying it should not get advertised
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3_addr_type ={}
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(
+ addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(
+ addr_type)
+ }},
+ "set": {
+ "localpref": 150
+ }
+ }],
+ "rmap_match_pf_3_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(
+ addr_type)
+ }},
+ "set": {
+ "weight": 1000
+ }
+ }]
+ }
+ }
+ }
+ input_dict_3_addr_type[addr_type] = input_dict_3
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_3_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ },
+ "r5": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_3_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ rmap_name = "rmap_match_pf_1"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r4'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ rmap_name = "rmap_match_pf_2"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3_addr_type[addr_type])
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: Attributes are not set \n'
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r5'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+ # Verifying BGP set attributes
+ dut = 'r5'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+
+ rmap_name = "rmap_match_pf_3"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_3_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3_addr_type[addr_type])
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: Attributes are not set \n'
+ 'Error: {}'.format(
+ tc_name, result)
+
+ logger.info("Expected behaviour: {}".format(result))
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_multiple_set_on_single_sequence_in_rmap_p0():
+ """
+ TC_43:
+ Test multiple set statements as part of a route-map's
+ single sequence number.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100,
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+
+ rmap_name = "rmap_match_pf_1"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_maps_with_continue_clause_p0():
+ """
+ TC_54:
+ Verify route-maps continue clause functionality.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '10',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150
+ },
+ "continue": "30"
+ },
+ {
+ "action": "permit",
+ 'seq_id': '20',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 200
+ }
+ },
+ {
+ "action": "permit",
+ 'seq_id': '30',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 100
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ rmap_name = "rmap_match_pf_1"
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ seq_id = {
+ "ipv4": ["10", "30"],
+ "ipv6": ["10", "30"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3, seq_id[addr_type])
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_maps_with_goto_clause_p0():
+ """
+ TC_55:
+ Verify route-maps goto clause functionality.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ 'seq_id': '10',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "goto": "30"
+ },
+ {
+ "action": "permit",
+ 'seq_id': '20',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 100
+ }
+ },
+ {
+ "action": "permit",
+ 'seq_id': '30',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 200
+ }
+ }
+ ]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ rmap_name = "rmap_match_pf_1"
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ seq_id = {
+ "ipv4": ["10", "30"],
+ "ipv6": ["10", "30"]
+ }
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[
+ addr_type],rmap_name, input_dict_3, seq_id[addr_type])
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_route_maps_with_call_clause_p0():
+ """
+ TC_53:
+ Verify route-maps call clause functionality.
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150
+ },
+ "call": "rmap_match_pf_2_{}".format(addr_type)
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 200
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv6",
+ "direction": 'in'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying BGP set attributes
+ dut = 'r3'
+ routes = {
+ "ipv4": ["10.0.20.1/32", "10.0.20.2/32"],
+ "ipv6": ["1::1/128", "1::2/128"]
+ }
+ rmap_name = "rmap_match_pf_1"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_1_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ rmap_name = "rmap_match_pf_2"
+ for addr_type in ADDR_TYPES:
+ rmap_name = "rmap_match_pf_2_{}".format(addr_type)
+ result = verify_bgp_attributes(tgen, addr_type, dut, routes[addr_type],
+ rmap_name, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_create_rmap_match_prefix_list_to_deny_in_and_outbound_prefixes_p0():
+ """
+ TC_58:
+ Create route map deny inbound and outbound prefixes on
+ match prefix list and set criteria on match
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ # Create ip prefix list
+ input_dict_2 = {
+ 'r3': {
+ 'prefix_lists': {
+ 'ipv4': {
+ 'pf_list_1_ipv4': [{
+ 'seqid': 10,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ },
+ 'ipv6': {
+ 'pf_list_1_ipv6': [{
+ 'seqid': 100,
+ 'network': 'any',
+ 'action': 'permit'
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Create route map
+ for addr_type in ADDR_TYPES:
+ input_dict_3 = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 150,
+ }
+ }],
+ "rmap_match_pf_2_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r3': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_1_ipv4",
+ "direction": 'in'
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [{
+ "name":
+ "rmap_match_pf_2_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+ input_dict = topo["routers"]
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r4'
+ protocol = 'bgp'
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behaviour: routes are not present \n '
+ 'Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_create_rmap_to_match_tag_permit_inbound_prefixes_p0():
+ """
+ TC_59:
+ Create route map to permit inbound prefixes with filter
+ match tag and set criteria
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ for addr_type in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "tag": "4001"
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+
+def test_create_rmap_to_match_tag_deny_outbound_prefixes_p0():
+ """
+ TC_60
+ Create route map to deny outbound prefixes with filter match tag,
+ and set criteria
+ """
+ tgen = get_topogen()
+ global bgp_convergence
+
+ if bgp_convergence is not True:
+ pytest.skip('skipped because of BGP Convergence failure')
+
+ # test case name
+ tc_name = inspect.stack()[0][3]
+ write_test_header(tc_name)
+ reset_config_on_routers(tgen)
+
+ for addr_type in ADDR_TYPES:
+ # Create Static routes
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Api call to redistribute static routes
+ input_dict_1 = {
+ "r1": {
+ "bgp": {
+ "local_as": 100,
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "redistribute": [
+ {"redist_type": "static"},
+ {"redist_type": "connected"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ # Create route map
+ input_dict_3 = {
+ "r1": {
+ "route_maps": {
+ "rmap_match_tag_1_{}".format(addr_type): [{
+ "action": "deny",
+ "match": {
+ addr_type: {
+ "tag": "4001"
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_3)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Configure neighbor for route map
+ input_dict_4 = {
+ 'r1': {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv4",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1": {
+ "route_maps": [{
+ "name":
+ "rmap_match_tag_1_ipv6",
+ "direction": 'out'
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_4)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ # Verifying RIB routes
+ dut = 'r3'
+ protocol = 'bgp'
+
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type],
+ "next_hop": "Null0",
+ "tag": 4001
+ }
+ ]
+ }
+ }
+ result = verify_rib(tgen, addr_type, dut, input_dict,
+ protocol=protocol)
+ assert result is not True, 'Testcase {} : Failed \n'
+ 'Expected behavior: routes are denied \n Error: {}'.format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+ # Uncomment next line for debugging
+ # tgen.mininet_cli()
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/conftest.py b/tests/topotests/conftest.py
index 49e48ba927..76b0ab017e 100755
--- a/tests/topotests/conftest.py
+++ b/tests/topotests/conftest.py
@@ -74,3 +74,9 @@ def pytest_runtest_makereport(item, call):
parent._previousfailed = item
logger.error('assert failed at "{}/{}": {}'.format(
modname, item.name, call.excinfo.value))
+
+ # (topogen) Set topology error to avoid advancing in the test.
+ tgen = get_topogen()
+ if tgen is not None:
+ # This will cause topogen to report error on `routers_have_failure`.
+ tgen.set_error('{}/{}'.format(modname, item.name))
diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py
index c05e14a95e..bfc34c25e4 100644
--- a/tests/topotests/lib/bgp.py
+++ b/tests/topotests/lib/bgp.py
@@ -1229,6 +1229,150 @@ def verify_bgp_timers_and_functionality(tgen, topo, input_dict):
return True
+@retry(attempts=3, wait=4, return_is_str=True)
+def verify_bgp_attributes(tgen, addr_type, dut, static_routes, rmap_name,
+ input_dict, seq_id=None):
+ """
+ API will verify BGP attributes set by Route-map for given prefix and
+ DUT. it will run "show bgp ipv4/ipv6 {prefix_address} json" command
+ in DUT to verify BGP attributes set by route-map, Set attributes
+ values will be read from input_dict and verified with command output.
+
+ * `tgen`: topogen object
+ * `addr_type` : ip type, ipv4/ipv6
+ * `dut`: Device Under Test
+ * `static_routes`: Static Routes for which BGP set attributes needs to be
+ verified
+ * `rmap_name`: route map name for which set criteria needs to be verified
+ * `input_dict`: defines for which router, AS numbers needs
+ * `seq_id`: sequence number of rmap, default is None
+
+ Usage
+ -----
+ input_dict = {
+ "r3": {
+ "route_maps": {
+ "rmap_match_pf_1_ipv4": [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "localpref": 150,
+ "weight": 100
+ }
+ }],
+ "rmap_match_pf_2_ipv6": [{
+ "action": "permit",
+ 'seq_id': '5',
+ "match": {
+ addr_type: {
+ "prefix_lists": "pf_list_1_" + addr_type
+ }
+ },
+ "set": {
+ "med": 50
+ }
+ }]
+ }
+ }
+ }
+ result = verify_bgp_attributes(tgen, 'ipv4', "r1", "10.0.20.1/32",
+ rmap_match_pf_1_ipv4, input_dict)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.debug("Entering lib API: verify_bgp_attributes()")
+ for router, rnode in tgen.routers().iteritems():
+ if router != dut:
+ continue
+
+ logger.info('Verifying BGP set attributes for dut {}:'.format(router))
+
+ for static_route in static_routes:
+ cmd = "show bgp {} {} json".format(addr_type, static_route)
+ show_bgp_json = run_frr_cmd(rnode, cmd, isjson=True)
+ print("show_bgp_json $$$$$", show_bgp_json)
+
+ dict_to_test = []
+ tmp_list = []
+ for rmap_router in input_dict.keys():
+ for rmap, values in input_dict[rmap_router][
+ "route_maps"].items():
+ print("rmap == rmap_name $$$$1", rmap, rmap_name)
+ if rmap == rmap_name:
+ print("rmap == rmap_name $$$$", rmap, rmap_name)
+ dict_to_test = values
+ for rmap_dict in values:
+ if seq_id is not None:
+ if type(seq_id) is not list:
+ seq_id = [seq_id]
+
+ if "seq_id" in rmap_dict:
+ rmap_seq_id = \
+ rmap_dict["seq_id"]
+ for _seq_id in seq_id:
+ if _seq_id == rmap_seq_id:
+ tmp_list.append(rmap_dict)
+ if tmp_list:
+ dict_to_test = tmp_list
+
+ print("dict_to_test $$$$", dict_to_test)
+ for rmap_dict in dict_to_test:
+ if "set" in rmap_dict:
+ for criteria in rmap_dict["set"].keys():
+ if criteria not in show_bgp_json[
+ "paths"][0]:
+ errormsg = ("BGP attribute: {}"
+ " is not found in"
+ " cli: {} output "
+ "in router {}".
+ format(criteria,
+ cmd,
+ router))
+ return errormsg
+
+ if rmap_dict["set"][criteria] == \
+ show_bgp_json["paths"][0][
+ criteria]:
+ logger.info("Verifying BGP "
+ "attribute {} for"
+ " route: {} in "
+ "router: {}, found"
+ " expected value:"
+ " {}".
+ format(criteria,
+ static_route,
+ dut,
+ rmap_dict[
+ "set"][
+ criteria]))
+ else:
+ errormsg = \
+ ("Failed: Verifying BGP "
+ "attribute {} for route:"
+ " {} in router: {}, "
+ " expected value: {} but"
+ " found: {}".
+ format(criteria,
+ static_route,
+ dut,
+ rmap_dict["set"]
+ [criteria],
+ show_bgp_json[
+ 'paths'][
+ 0][criteria]))
+ return errormsg
+
+ logger.debug("Exiting lib API: verify_bgp_attributes()")
+ return True
+
@retry(attempts=3, wait=2, return_is_str=True)
def verify_best_path_as_per_bgp_attribute(tgen, addr_type, router, input_dict,
attribute):
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index f2d33f94ae..ba8a4cb0f4 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -21,6 +21,7 @@
from collections import OrderedDict
from datetime import datetime
from time import sleep
+from copy import deepcopy
from subprocess import call
from subprocess import STDOUT as SUB_STDOUT
from subprocess import PIPE as SUB_PIPE
@@ -208,6 +209,7 @@ def create_common_configuration(tgen, router, data, config_type=None,
"interface_config": "! Interfaces Config\n",
"static_route": "! Static Route Config\n",
"prefix_list": "! Prefix List Config\n",
+ "bgp_community_list": "! Community List Config\n",
"route_maps": "! Route Maps Config\n",
"bgp": "! BGP Config\n"
})
@@ -547,13 +549,11 @@ def generate_ips(network, no_of_ips):
Returns list of IPs.
based on start_ip and no_of_ips
- * `network` : from here the ip will start generating, start_ip will be
- first ip
+ * `network` : from here the ip will start generating,
+ start_ip will be
* `no_of_ips` : these many IPs will be generated
-
- Limitation: It will generate IPs only for ip_mask 32
-
"""
+
ipaddress_list = []
if type(network) is not list:
network = [network]
@@ -893,6 +893,7 @@ def create_static_routes(tgen, input_dict, build=False):
"""
result = False
logger.debug("Entering lib API: create_static_routes()")
+ input_dict = deepcopy(input_dict)
try:
for router in input_dict.keys():
if "static_routes" not in input_dict[router]:
@@ -918,16 +919,21 @@ def create_static_routes(tgen, input_dict, build=False):
next_hop = static_route["next_hop"]
network = static_route["network"]
- ip_list = generate_ips([network], no_of_ip)
+ if type(network) is not list:
+ network = [network]
+
+ ip_list = generate_ips(network, no_of_ip)
for ip in ip_list:
addr_type = validate_ip_address(ip)
+
if addr_type == "ipv4":
cmd = "ip route {} {}".format(ip, next_hop)
else:
cmd = "ipv6 route {} {}".format(ip, next_hop)
if tag:
- cmd = "{} {}".format(cmd, str(tag))
+ cmd = "{} tag {}".format(cmd, str(tag))
+
if admin_distance:
cmd = "{} {}".format(cmd, admin_distance)
@@ -1112,11 +1118,11 @@ def create_route_maps(tgen, input_dict, build=False):
"prefix_list": "pf_list_1"
}
- "large-community-list": "{
+ "large-community-list": {
"id": "community_1",
"exact_match": True
}
- "community": {
+ "community_list": {
"id": "community_2",
"exact_match": True
}
@@ -1152,12 +1158,11 @@ def create_route_maps(tgen, input_dict, build=False):
result = False
logger.debug("Entering lib API: create_route_maps()")
-
+ input_dict = deepcopy(input_dict)
try:
for router in input_dict.keys():
if "route_maps" not in input_dict[router]:
- errormsg = "route_maps not present in input_dict"
- logger.debug(errormsg)
+ logger.debug("route_maps not present in input_dict")
continue
rmap_data = []
for rmap_name, rmap_value in \
@@ -1187,10 +1192,41 @@ def create_route_maps(tgen, input_dict, build=False):
rmap_name, rmap_action, seq_id
))
+ if "continue" in rmap_dict:
+ continue_to = rmap_dict["continue"]
+ if continue_to:
+ rmap_data.append("on-match goto {}".
+ format(continue_to))
+ else:
+ logger.error("In continue, 'route-map entry "
+ "sequence number' is not provided")
+ return False
+
+ if "goto" in rmap_dict:
+ go_to = rmap_dict["goto"]
+ if go_to:
+ rmap_data.append("on-match goto {}".
+ format(go_to))
+ else:
+ logger.error("In goto, 'Goto Clause number' is not"
+ " provided")
+ return False
+
+ if "call" in rmap_dict:
+ call_rmap = rmap_dict["call"]
+ if call_rmap:
+ rmap_data.append("call {}".
+ format(call_rmap))
+ else:
+ logger.error("In call, 'destination Route-Map' is"
+ " not provided")
+ return False
+
# Verifying if SET criteria is defined
if "set" in rmap_dict:
set_data = rmap_dict["set"]
-
+ ipv4_data = set_data.setdefault("ipv4", {})
+ ipv6_data = set_data.setdefault("ipv6", {})
local_preference = set_data.setdefault("localpref",
None)
metric = set_data.setdefault("med", None)
@@ -1199,7 +1235,10 @@ def create_route_maps(tgen, input_dict, build=False):
community = set_data.setdefault("community", {})
large_community = set_data.setdefault(
"large_community", {})
+ large_comm_list = set_data.setdefault(
+ "large_comm_list", {})
set_action = set_data.setdefault("set_action", None)
+ nexthop = set_data.setdefault("nexthop", None)
# Local Preference
if local_preference:
@@ -1243,42 +1282,84 @@ def create_route_maps(tgen, input_dict, build=False):
rmap_data.append(cmd)
else:
- logger.errror("In large_community, AS Num not"
- " provided")
+ logger.error("In large_community, AS Num not"
+ " provided")
+ return False
+ if large_comm_list:
+ id = large_comm_list.setdefault("id", None)
+ del_comm = large_comm_list.setdefault("delete",
+ None)
+ if id:
+ cmd = "set large-comm-list {}".format(id)
+ if del_comm:
+ cmd = "{} delete".format(cmd)
+
+ rmap_data.append(cmd)
+ else:
+ logger.error("In large_comm_list 'id' not"
+ " provided")
return False
# Weight
if weight:
- rmap_data.append("set weight {}".format(
+ rmap_data.append("set weight {} \n".format(
weight))
-
+ if ipv6_data:
+ nexthop = ipv6_data.setdefault("nexthop",None)
+ if nexthop:
+ rmap_data.append("set ipv6 next-hop \
+ {}".format(nexthop))
# Adding MATCH and SET sequence to RMAP if defined
if "match" in rmap_dict:
match_data = rmap_dict["match"]
ipv4_data = match_data.setdefault("ipv4", {})
ipv6_data = match_data.setdefault("ipv6", {})
- community = match_data.setdefault("community-list",
- {})
+ community = match_data.setdefault(
+ "community_list",{})
large_community = match_data.setdefault(
- "large-community-list", {}
+ "large_community", {}
+ )
+ large_community_list = match_data.setdefault(
+ "large_community_list", {}
)
- tag = match_data.setdefault("tag", None)
if ipv4_data:
- prefix_name = ipv4_data.setdefault("prefix_lists",
- None)
+ # fetch prefix list data from rmap
+ prefix_name = \
+ ipv4_data.setdefault("prefix_lists",
+ None)
if prefix_name:
- rmap_data.append("match ip address prefix-list"
- " {}".format(prefix_name))
+ rmap_data.append("match ip address"
+ " prefix-list {}".format(prefix_name))
+
+ # fetch tag data from rmap
+ tag = ipv4_data.setdefault("tag", None)
+ if tag:
+ rmap_data.append("match tag {}".format(tag))
+
+ # fetch large community data from rmap
+ large_community_list = ipv4_data.setdefault(
+ "large_community_list",{})
+ large_community = match_data.setdefault(
+ "large_community", {})
+
if ipv6_data:
prefix_name = ipv6_data.setdefault("prefix_lists",
None)
if prefix_name:
- rmap_data.append("match ipv6 address "
- "prefix-list {}".
- format(prefix_name))
- if tag:
- rmap_data.append("match tag {}".format(tag))
+ rmap_data.append("match ipv6 address"
+ " prefix-list {}".format(prefix_name))
+
+ # fetch tag data from rmap
+ tag = ipv6_data.setdefault("tag", None)
+ if tag:
+ rmap_data.append("match tag {}".format(tag))
+
+ # fetch large community data from rmap
+ large_community_list = ipv6_data.setdefault(
+ "large_community_list",{})
+ large_community = match_data.setdefault(
+ "large_community", {})
if community:
if "id" not in community:
@@ -1293,10 +1374,9 @@ def create_route_maps(tgen, input_dict, build=False):
cmd = "{} exact-match".format(cmd)
rmap_data.append(cmd)
-
if large_community:
if "id" not in large_community:
- logger.error("'num' is mandatory for "
+ logger.error("'id' is mandatory for "
"large-community-list in match "
"criteria")
return False
@@ -1306,7 +1386,19 @@ def create_route_maps(tgen, input_dict, build=False):
"exact_match", False)
if exact_match:
cmd = "{} exact-match".format(cmd)
-
+ rmap_data.append(cmd)
+ if large_community_list:
+ if "id" not in large_community_list:
+ logger.error("'id' is mandatory for "
+ "large-community-list in match "
+ "criteria")
+ return False
+ cmd = "match large-community {}".format(
+ large_community_list["id"])
+ exact_match = large_community_list.setdefault(
+ "exact_match", False)
+ if exact_match:
+ cmd = "{} exact-match".format(cmd)
rmap_data.append(cmd)
result = create_common_configuration(tgen, router,
@@ -1320,10 +1412,178 @@ def create_route_maps(tgen, input_dict, build=False):
logger.error(errormsg)
return errormsg
- logger.debug("Exiting lib API: create_prefix_lists()")
+ logger.debug("Exiting lib API: create_route_maps()")
+ return result
+
+
+def delete_route_maps(tgen, input_dict):
+ """
+ Delete ip route maps from device
+
+ * `tgen` : Topogen object
+ * `input_dict` : for which router,
+ route map has to be deleted
+
+ Usage
+ -----
+ # Delete route-map rmap_1 and rmap_2 from router r1
+ input_dict = {
+ "r1": {
+ "route_maps": ["rmap_1", "rmap__2"]
+ }
+ }
+ result = delete_route_maps("ipv4", input_dict)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+ logger.info("Entering lib API: delete_route_maps()")
+
+ for router in input_dict.keys():
+ route_maps = input_dict[router]["route_maps"][:]
+ rmap_data = input_dict[router]
+ rmap_data["route_maps"] = {}
+ for route_map_name in route_maps:
+ rmap_data["route_maps"].update({
+ route_map_name:
+ [{
+ "delete": True
+ }]
+ })
+
+ return create_route_maps(tgen, input_dict)
+
+
+def create_bgp_community_lists(tgen, input_dict, build=False):
+ """
+ Create bgp community-list or large-community-list on the devices as per
+ the arguments passed. Takes list of communities in input.
+
+ Parameters
+ ----------
+ * `tgen` : Topogen object
+ * `input_dict` : Input dict data, required when configuring from testcase
+ * `build` : Only for initial setup phase this is set as True.
+ Usage
+ -----
+ input_dict_1 = {
+ "r3": {
+ "bgp_community_lists": [
+ {
+ "community_type": "standard",
+ "action": "permit",
+ "name": "rmap_lcomm_{}".format(addr_type),
+ "value": "1:1:1 1:2:3 2:1:1 2:2:2",
+ "large": True
+ }
+ ]
+ }
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_1)
+ """
+
+ result = False
+ logger.debug("Entering lib API: create_bgp_community_lists()")
+ input_dict = deepcopy(input_dict)
+ try:
+ for router in input_dict.keys():
+ if "bgp_community_lists" not in input_dict[router]:
+ errormsg = "bgp_community_lists not present in input_dict"
+ logger.debug(errormsg)
+ continue
+
+ config_data = []
+
+ community_list = input_dict[router]["bgp_community_lists"]
+ for community_dict in community_list:
+ del_action = community_dict.setdefault("delete", False)
+ community_type = community_dict.setdefault("community_type",
+ None)
+ action = community_dict.setdefault("action", None)
+ value = community_dict.setdefault("value", '')
+ large = community_dict.setdefault("large", None)
+ name = community_dict.setdefault("name", None)
+ if large:
+ cmd = "bgp large-community-list"
+ else:
+ cmd = "bgp community-list"
+
+ if not large and not (community_type and action and value):
+ errormsg = "community_type, action and value are " \
+ "required in bgp_community_list"
+ logger.error(errormsg)
+ return False
+
+ try:
+ community_type = int(community_type)
+ cmd = "{} {} {} {}".format(cmd, community_type, action,
+ value)
+ except ValueError:
+
+ cmd = "{} {} {} {} {}".format(
+ cmd, community_type, name, action, value)
+
+ if del_action:
+ cmd = "no {}".format(cmd)
+
+ config_data.append(cmd)
+
+ result = create_common_configuration(tgen, router, config_data,
+ "bgp_community_list",
+ build=build)
+
+ except InvalidCLIError:
+ # Traceback
+ errormsg = traceback.format_exc()
+ logger.error(errormsg)
+ return errormsg
+
+ logger.debug("Exiting lib API: create_bgp_community_lists()")
return result
+def shutdown_bringup_interface(tgen, dut, intf_name, ifaceaction=False):
+ """
+ Shutdown or bringup router's interface "
+
+ * `tgen` : Topogen object
+ * `dut` : Device under test
+ * `intf_name` : Interface name to be shut/no shut
+ * `ifaceaction` : Action, to shut/no shut interface,
+ by default is False
+
+ Usage
+ -----
+ dut = "r3"
+ intf = "r3-r1-eth0"
+ # Shut down ineterface
+ shutdown_bringup_interface(tgen, dut, intf, False)
+
+ # Bring up ineterface
+ shutdown_bringup_interface(tgen, dut, intf, True)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ from topotest import interface_set_status
+ router_list = tgen.routers()
+ if ifaceaction:
+ logger.info("Bringing up interface : {}".format(intf_name))
+ else:
+ logger.info("Shutting down interface : {}".format(intf_name))
+
+ interface_set_status(router_list[dut], intf_name,
+ ifaceaction)
+
+ if ifaceaction:
+ # Disabling v6 link local once interfac comes up back
+ disable_v6_link_local(tgen, dut, intf_name=intf_name)
+
+
#############################################
# Verification APIs
#############################################
@@ -1625,5 +1885,133 @@ def verify_prefix_lists(tgen, input_dict):
logger.info("Prefix list %s is/are not present in the router"
" from router %s", prefix_list, router)
- logger.debug("Exiting lib API: verify_prefix_lissts()")
+ logger.debug("Exiting lib API: verify_prefix_lists()")
+ return True
+
+
+@retry(attempts=2, wait=4, return_is_str=True, initial_wait=2)
+def verify_route_maps(tgen, input_dict):
+ """
+ Running "show route-map" command and verifying given route-map
+ is present in router.
+ Parameters
+ ----------
+ * `tgen` : topogen object
+ * `input_dict`: data to verify prefix lists
+ Usage
+ -----
+ # To verify rmap_1 and rmap_2 are present in router r1
+ input_dict = {
+ "r1": {
+ "route_maps": ["rmap_1", "rmap_2"]
+ }
+ }
+ result = verify_route_maps(tgen, input_dict)
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.debug("Entering lib API: verify_route_maps()")
+
+ for router in input_dict.keys():
+ if router not in tgen.routers():
+ continue
+
+ rnode = tgen.routers()[router]
+ # Show ip route-map
+ show_route_maps = rnode.vtysh_cmd("show route-map")
+
+ # Verify route-map is deleted
+ route_maps = input_dict[router]["route_maps"]
+ for route_map in route_maps:
+ if route_map in show_route_maps:
+ errormsg = ("Route map {} is not deleted from router"
+ " {}".format(route_map, router))
+ return errormsg
+
+ logger.info("Route map %s is/are deleted successfully from"
+ " router %s", route_maps, router)
+
+ logger.debug("Exiting lib API: verify_route_maps()")
+ return True
+
+
+@retry(attempts=3, wait=4, return_is_str=True)
+def verify_bgp_community(tgen, addr_type, router, network, input_dict=None):
+ """
+ API to veiryf BGP large community is attached in route for any given
+ DUT by running "show bgp ipv4/6 {route address} json" command.
+
+ Parameters
+ ----------
+ * `tgen`: topogen object
+ * `addr_type` : ip type, ipv4/ipv6
+ * `dut`: Device Under Test
+ * `network`: network for which set criteria needs to be verified
+ * `input_dict`: having details like - for which router, community and
+ values needs to be verified
+ Usage
+ -----
+ networks = ["200.50.2.0/32"]
+ input_dict = {
+ "largeCommunity": "2:1:1 2:2:2 2:3:3 2:4:4 2:5:5"
+ }
+ result = verify_bgp_community(tgen, "ipv4", dut, network, input_dict=None)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.info("Entering lib API: verify_bgp_community()")
+ if router not in tgen.routers():
+ return False
+
+ rnode = tgen.routers()[router]
+
+ logger.debug("Verifying BGP community attributes on dut %s: for %s "
+ "network %s", router, addr_type, network)
+
+ for net in network:
+ cmd = "show bgp {} {} json".format(addr_type, net)
+ show_bgp_json = rnode.vtysh_cmd(cmd, isjson=True)
+ logger.info(show_bgp_json)
+ if "paths" not in show_bgp_json:
+ return "Prefix {} not found in BGP table of router: {}". \
+ format(net, router)
+
+ as_paths = show_bgp_json["paths"]
+ found = False
+ for i in range(len(as_paths)):
+ if "largeCommunity" in show_bgp_json["paths"][i] or \
+ "community" in show_bgp_json["paths"][i]:
+ found = True
+ logger.info("Large Community attribute is found for route:"
+ " %s in router: %s", net, router)
+ if input_dict is not None:
+ for criteria, comm_val in input_dict.items():
+ show_val = show_bgp_json["paths"][i][criteria][
+ "string"]
+ if comm_val == show_val:
+ logger.info("Verifying BGP %s for prefix: %s"
+ " in router: %s, found expected"
+ " value: %s", criteria, net, router,
+ comm_val)
+ else:
+ errormsg = "Failed: Verifying BGP attribute" \
+ " {} for route: {} in router: {}" \
+ ", expected value: {} but found" \
+ ": {}".format(
+ criteria, net, router, comm_val,
+ show_val)
+ return errormsg
+
+ if not found:
+ errormsg = (
+ "Large Community attribute is not found for route: "
+ "{} in router: {} ".format(net, router))
+ return errormsg
+
+ logger.debug("Exiting lib API: verify_bgp_community()")
return True
diff --git a/tests/topotests/lib/topojson.py b/tests/topotests/lib/topojson.py
index 7a00fe4c50..fff5a1e82f 100644
--- a/tests/topotests/lib/topojson.py
+++ b/tests/topotests/lib/topojson.py
@@ -35,6 +35,7 @@ from lib.common_config import (
create_static_routes,
create_prefix_lists,
create_route_maps,
+ create_bgp_community_lists
)
from lib.bgp import create_router_bgp
@@ -179,6 +180,7 @@ def build_config_from_json(tgen, topo, save_bkup=True):
("links", create_interfaces_cfg),
("static_routes", create_static_routes),
("prefix_lists", create_prefix_lists),
+ ("bgp_community_list", create_bgp_community_lists),
("route_maps", create_route_maps),
("bgp", create_router_bgp)
])
diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c
index 2dc3d3f8a3..f71b343140 100644
--- a/vrrpd/vrrp_vty.c
+++ b/vrrpd/vrrp_vty.c
@@ -30,6 +30,7 @@
#include "vrrp.h"
#include "vrrp_debug.h"
#include "vrrp_vty.h"
+#include "vrrp_zebra.h"
#ifndef VTYSH_EXTRACT_PL
#include "vrrpd/vrrp_vty_clippy.c"
#endif
diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c
index 72b77c1313..a6c575f8da 100644
--- a/vrrpd/vrrp_zebra.c
+++ b/vrrpd/vrrp_zebra.c
@@ -80,83 +80,36 @@ static int vrrp_router_id_update_zebra(int command, struct zclient *zclient,
return 0;
}
-static int vrrp_zebra_if_add(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+int vrrp_ifp_create(struct interface *ifp)
{
- struct interface *ifp;
-
- /*
- * zebra api adds/dels interfaces using the same call
- * interface_add_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
-
- if (!ifp)
- return 0;
-
- vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
+ vrrp_zebra_debug_if_state(ifp, ifp->vrf_id, __func__);
vrrp_if_add(ifp);
return 0;
}
-static int vrrp_zebra_if_del(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+int vrrp_ifp_destroy(struct interface *ifp)
{
- struct interface *ifp;
-
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (!ifp)
- return 0;
-
- vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
+ vrrp_zebra_debug_if_state(ifp, ifp->vrf_id, __func__);
vrrp_if_del(ifp);
- if_set_index(ifp, IFINDEX_INTERNAL);
-
return 0;
}
-static int vrrp_zebra_if_state_up(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+int vrrp_ifp_up(struct interface *ifp)
{
- struct interface *ifp;
-
- /*
- * zebra api notifies interface up/down events by using the same call
- * zebra_interface_state_read below, see comments in lib/zclient.c ifp =
- * zebra_interface_state_read(zclient->ibuf, vrf_id);
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (!ifp)
- return 0;
-
- vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
+ vrrp_zebra_debug_if_state(ifp, ifp->vrf_id, __func__);
vrrp_if_up(ifp);
return 0;
}
-static int vrrp_zebra_if_state_down(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+int vrrp_ifp_down(struct interface *ifp)
{
- struct interface *ifp;
-
- /*
- * zebra api notifies interface up/down events by using the same call
- * zebra_interface_state_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
-
- if (!ifp)
- return 0;
-
- vrrp_zebra_debug_if_state(ifp, vrf_id, __func__);
+ vrrp_zebra_debug_if_state(ifp, ifp->vrf_id, __func__);
vrrp_if_down(ifp);
@@ -238,15 +191,14 @@ int vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
void vrrp_zebra_init(void)
{
+ if_zapi_callbacks(vrrp_ifp_create, vrrp_ifp_up,
+ vrrp_ifp_down, vrrp_ifp_destroy);
+
/* Socket for receiving updates from Zebra daemon */
zclient = zclient_new(master, &zclient_options_default);
zclient->zebra_connected = vrrp_zebra_connected;
zclient->router_id_update = vrrp_router_id_update_zebra;
- zclient->interface_add = vrrp_zebra_if_add;
- zclient->interface_delete = vrrp_zebra_if_del;
- zclient->interface_up = vrrp_zebra_if_state_up;
- zclient->interface_down = vrrp_zebra_if_state_down;
zclient->interface_address_add = vrrp_zebra_if_address_add;
zclient->interface_address_delete = vrrp_zebra_if_address_del;
diff --git a/vrrpd/vrrp_zebra.h b/vrrpd/vrrp_zebra.h
index 84bcba23c1..02d7055b86 100644
--- a/vrrpd/vrrp_zebra.h
+++ b/vrrpd/vrrp_zebra.h
@@ -29,4 +29,9 @@ extern void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable);
extern int vrrp_zclient_send_interface_protodown(struct interface *ifp,
bool down);
+extern int vrrp_ifp_create(struct interface *ifp);
+extern int vrrp_ifp_up(struct interface *ifp);
+extern int vrrp_ifp_down(struct interface *ifp);
+extern int vrrp_ifp_destroy(struct interface *ifp);
+
#endif /* __VRRP_ZEBRA_H__ */
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 59ab8c9d33..35cb3a6f5f 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -1385,6 +1385,13 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave)
zebra_l2if_update_bond_slave(ifp, bond_ifindex);
}
+
+ zif = ifp->info;
+ if (zif) {
+ XFREE(MTYPE_TMP, zif->desc);
+ if (desc)
+ zif->desc = XSTRDUP(MTYPE_TMP, desc);
+ }
} else {
/* Delete interface notification from kernel */
if (ifp == NULL) {
@@ -1411,13 +1418,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if_delete_update(ifp);
}
- zif = ifp->info;
- if (zif) {
- XFREE(MTYPE_TMP, zif->desc);
- if (desc)
- zif->desc = XSTRDUP(MTYPE_TMP, desc);
- }
-
return 0;
}
diff --git a/zebra/interface.c b/zebra/interface.c
index a724006e27..ef03cf87f6 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -778,6 +778,13 @@ void if_delete_update(struct interface *ifp)
memset(&zif->brslave_info, 0,
sizeof(struct zebra_l2info_brslave));
}
+
+ if (!ifp->configured) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("interface %s is being deleted from the system",
+ ifp->name);
+ if_delete(ifp);
+ }
}
/* VRF change for an interface */
@@ -3207,6 +3214,11 @@ void zebra_if_init(void)
install_node(&interface_node, if_config_write);
install_node(&link_params_node, NULL);
if_cmd_init();
+ /*
+ * This is *intentionally* setting this to NULL, signaling
+ * that interface creation for zebra acts differently
+ */
+ if_zapi_callbacks(NULL, NULL, NULL, NULL);
install_element(VIEW_NODE, &show_interface_cmd);
install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
diff --git a/zebra/irdp.h b/zebra/irdp.h
index ff4ab8dfbd..c1ea34f3aa 100644
--- a/zebra/irdp.h
+++ b/zebra/irdp.h
@@ -51,7 +51,7 @@ extern "C" {
#endif /* INADDR_ALLRTRS_GROUP */
/* Default irdp packet interval */
-#define IRDP_DEFAULT_INTERVAL 300
+#define IRDP_DEFAULT_INTERVAL 300
/* Router constants from RFC1256 */
#define MAX_INITIAL_ADVERT_INTERVAL 16
@@ -123,10 +123,10 @@ struct irdp_interface {
#define IF_ACTIVE (1<<0) /* ICMP Active */
#define IF_BROADCAST (1<<1) /* 255.255.255.255 */
#define IF_SOLICIT (1<<2) /* Solicit active */
-#define IF_DEBUG_MESSAGES (1<<3)
-#define IF_DEBUG_PACKET (1<<4)
-#define IF_DEBUG_MISC (1<<5)
-#define IF_SHUTDOWN (1<<6)
+#define IF_DEBUG_MESSAGES (1<<3)
+#define IF_DEBUG_PACKET (1<<4)
+#define IF_DEBUG_MISC (1<<5)
+#define IF_SHUTDOWN (1<<6)
struct interface *ifp;
struct thread *t_advertise;
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 227226b5f9..0dc9de0c59 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -263,8 +263,11 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
}
/* Add DISTANCE_INFINITY check. */
- if (old_re && (old_re->distance == DISTANCE_INFINITY))
+ if (old_re && (old_re->distance == DISTANCE_INFINITY)) {
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug("\tSkipping due to Infinite Distance");
return;
+ }
afi = family2afi(p->family);
if (!afi) {
@@ -310,14 +313,14 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
/* Send a delete for the 'old' re to any subscribed client. */
if (old_re
- && ((old_re->instance
- && redist_check_instance(
- &client->mi_redist[afi]
- [old_re->type],
- old_re->instance))
- || vrf_bitmap_check(
- client->redist[afi][old_re->type],
- old_re->vrf_id))) {
+ && (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
+ old_re->vrf_id)
+ || (old_re->instance
+ && redist_check_instance(
+ &client->mi_redist[afi][old_re->type],
+ old_re->instance))
+ || vrf_bitmap_check(client->redist[afi][old_re->type],
+ old_re->vrf_id))) {
zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
client, p, src_p, old_re);
}
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index b084fb99ca..2228fcfd3f 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -58,10 +58,10 @@ DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix")
/* If RFC2133 definition is used. */
#ifndef IPV6_JOIN_GROUP
-#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
+#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
#endif
#ifndef IPV6_LEAVE_GROUP
-#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
+#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#endif
#define ALLNODE "ff02::1"
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index fef54d5828..4a726b3e07 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1046,14 +1046,18 @@ static struct route_entry *rib_choose_best(struct route_entry *current,
struct nexthop *nexthop = NULL;
for (ALL_NEXTHOPS(alternate->ng, nexthop)) {
- if (if_is_loopback_or_vrf(if_lookup_by_index(
- nexthop->ifindex, alternate->vrf_id)))
+ struct interface *ifp = if_lookup_by_index(
+ nexthop->ifindex, alternate->vrf_id);
+
+ if (ifp && if_is_loopback_or_vrf(ifp))
return alternate;
}
for (ALL_NEXTHOPS(current->ng, nexthop)) {
- if (if_is_loopback_or_vrf(if_lookup_by_index(
- nexthop->ifindex, current->vrf_id)))
+ struct interface *ifp = if_lookup_by_index(
+ nexthop->ifindex, current->vrf_id);
+
+ if (ifp && if_is_loopback_or_vrf(ifp))
return current;
}
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 4f1868311c..f425c0e49e 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -487,7 +487,11 @@ static int vrf_config_write(struct vty *vty)
if (zvrf_id(zvrf) == VRF_DEFAULT) {
if (zvrf->l3vni)
- vty_out(vty, "vni %u\n", zvrf->l3vni);
+ vty_out(vty, "vni %u%s\n", zvrf->l3vni,
+ is_l3vni_for_prefix_routes_only(
+ zvrf->l3vni)
+ ? " prefix-routes-only"
+ : "");
if (zvrf->zebra_rnh_ip_default_route)
vty_out(vty, "ip nht resolve-via-default\n");