diff options
177 files changed, 4080 insertions, 2225 deletions
diff --git a/babeld/.gitignore b/babeld/.gitignore index fbdb90f677..71ef6786c7 100644 --- a/babeld/.gitignore +++ b/babeld/.gitignore @@ -4,5 +4,4 @@ !LICENCE !Makefile !subdir.am -!babeld.conf.sample !.gitignore diff --git a/babeld/babeld.conf.sample b/babeld/babeld.conf.sample deleted file mode 100644 index a77453a734..0000000000 --- a/babeld/babeld.conf.sample +++ /dev/null @@ -1,30 +0,0 @@ -debug babel common -!debug babel kernel -!debug babel filter -!debug babel timeout -!debug babel interface -!debug babel route -!debug babel all - -router babel -! network wlan0 -! network eth0 -! redistribute ipv4 kernel -! no redistribute ipv6 static - -! The defaults are fine for a wireless interface - -!interface wlan0 - -! A few optimisation tweaks are optional but recommended on a wired interface -! Disable link quality estimation, enable split horizon processing, and -! increase the hello and update intervals. - -!interface eth0 -! babel wired -! babel split-horizon -! babel hello-interval 12000 -! babel update-interval 36000 - -! log file /var/log/quagga/babeld.log -log stdout diff --git a/babeld/subdir.am b/babeld/subdir.am index 8e5b46350d..c9b6959fca 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -5,7 +5,6 @@ if BABELD noinst_LIBRARIES += babeld/libbabel.a sbin_PROGRAMS += babeld/babeld -dist_examples_DATA += babeld/babeld.conf.sample vtysh_scan += \ babeld/babel_interface.c \ babeld/babel_zebra.c \ diff --git a/bfdd/bfdd.conf.sample b/bfdd/bfdd.conf.sample deleted file mode 100644 index 9981e262bc..0000000000 --- a/bfdd/bfdd.conf.sample +++ /dev/null @@ -1,5 +0,0 @@ -password zebra -! -log stdout -! -line vty diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c index 42ed587f20..6ec724d80c 100644 --- a/bfdd/bfdd_cli.c +++ b/bfdd/bfdd_cli.c @@ -273,11 +273,8 @@ DEFPY_YANG( void bfd_cli_show_shutdown(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - if (show_defaults) - vty_out(vty, " no shutdown\n"); - else - vty_out(vty, " %sshutdown\n", - yang_dnode_get_bool(dnode, NULL) ? "" : "no "); + vty_out(vty, " %sshutdown\n", + yang_dnode_get_bool(dnode, NULL) ? "" : "no "); } DEFPY_YANG( @@ -294,11 +291,8 @@ DEFPY_YANG( void bfd_cli_show_passive(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - if (show_defaults) - vty_out(vty, " no passive-mode\n"); - else - vty_out(vty, " %spassive-mode\n", - yang_dnode_get_bool(dnode, NULL) ? "" : "no "); + vty_out(vty, " %spassive-mode\n", + yang_dnode_get_bool(dnode, NULL) ? "" : "no "); } DEFPY_YANG( @@ -335,11 +329,7 @@ DEFPY_YANG( void bfd_cli_show_minimum_ttl(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - if (show_defaults) - vty_out(vty, " minimum-ttl 254\n"); - else - vty_out(vty, " minimum-ttl %s\n", - yang_dnode_get_string(dnode, NULL)); + vty_out(vty, " minimum-ttl %s\n", yang_dnode_get_string(dnode, NULL)); } DEFPY_YANG( @@ -356,12 +346,8 @@ DEFPY_YANG( void bfd_cli_show_mult(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - if (show_defaults) - vty_out(vty, " detect-multiplier %d\n", - BFD_DEFDETECTMULT); - else - vty_out(vty, " detect-multiplier %s\n", - yang_dnode_get_string(dnode, NULL)); + vty_out(vty, " detect-multiplier %s\n", + yang_dnode_get_string(dnode, NULL)); } DEFPY_YANG( @@ -382,15 +368,9 @@ DEFPY_YANG( void bfd_cli_show_rx(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - uint32_t value; + uint32_t value = yang_dnode_get_uint32(dnode, NULL); - if (show_defaults) - vty_out(vty, " receive-interval %d\n", - BFD_DEFREQUIREDMINRX); - else { - value = yang_dnode_get_uint32(dnode, NULL); - vty_out(vty, " receive-interval %u\n", value / 1000); - } + vty_out(vty, " receive-interval %u\n", value / 1000); } DEFPY_YANG( @@ -411,15 +391,9 @@ DEFPY_YANG( void bfd_cli_show_tx(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - uint32_t value; + uint32_t value = yang_dnode_get_uint32(dnode, NULL); - if (show_defaults) - vty_out(vty, " transmit-interval %d\n", - BFD_DEFDESIREDMINTX); - else { - value = yang_dnode_get_uint32(dnode, NULL); - vty_out(vty, " transmit-interval %u\n", value / 1000); - } + vty_out(vty, " transmit-interval %u\n", value / 1000); } DEFPY_YANG( @@ -445,11 +419,8 @@ DEFPY_YANG( void bfd_cli_show_echo(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - if (show_defaults) - vty_out(vty, " no echo-mode\n"); - else - vty_out(vty, " %secho-mode\n", - yang_dnode_get_bool(dnode, NULL) ? "" : "no "); + vty_out(vty, " %secho-mode\n", + yang_dnode_get_bool(dnode, NULL) ? "" : "no "); } DEFPY_YANG( @@ -498,15 +469,9 @@ DEFPY_YANG( void bfd_cli_show_desired_echo_transmission_interval(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - uint32_t value; + uint32_t value = yang_dnode_get_uint32(dnode, NULL); - if (show_defaults) - vty_out(vty, " echo transmit-interval %d\n", - BFD_DEF_DES_MIN_ECHO_TX); - else { - value = yang_dnode_get_uint32(dnode, NULL); - vty_out(vty, " echo transmit-interval %u\n", value / 1000); - } + vty_out(vty, " echo transmit-interval %u\n", value / 1000); } DEFPY_YANG( @@ -538,19 +503,12 @@ DEFPY_YANG( void bfd_cli_show_required_echo_receive_interval(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - uint32_t value; - - if (show_defaults) - vty_out(vty, " echo receive-interval %d\n", - BFD_DEF_REQ_MIN_ECHO_RX); - else { - value = yang_dnode_get_uint32(dnode, NULL); - if (value) - vty_out(vty, " echo receive-interval %u\n", - value / 1000); - else - vty_out(vty, " echo receive-interval disabled\n"); - } + uint32_t value = yang_dnode_get_uint32(dnode, NULL); + + if (value) + vty_out(vty, " echo receive-interval %u\n", value / 1000); + else + vty_out(vty, " echo receive-interval disabled\n"); } /* diff --git a/bfdd/subdir.am b/bfdd/subdir.am index e572d4a3c0..8d35b933d7 100644 --- a/bfdd/subdir.am +++ b/bfdd/subdir.am @@ -5,7 +5,6 @@ if BFDD noinst_LIBRARIES += bfdd/libbfd.a sbin_PROGRAMS += bfdd/bfdd -dist_examples_DATA += bfdd/bfdd.conf.sample vtysh_scan += bfdd/bfdd_vty.c vtysh_scan += bfdd/bfdd_cli.c vtysh_daemons += bfdd diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index f658b0d0f0..71e4b56a00 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -3734,7 +3734,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, struct aspath *aspath; int send_as4_path = 0; int send_as4_aggregator = 0; - int use32bit = (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0; + bool use32bit = CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV); if (!bgp) bgp = peer->bgp; diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index f1bdcc8bb4..958d7cf0ed 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -424,8 +424,7 @@ void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer, void bgp_bfd_show_info(struct vty *vty, const struct peer *peer, json_object *json_neigh) { - if (peer->bfd_config->session) - bfd_sess_show(vty, json_neigh, peer->bfd_config->session); + bfd_sess_show(vty, json_neigh, peer->bfd_config->session); } DEFUN (neighbor_bfd, diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 381e6f082b..ed8a6a9506 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -3452,12 +3452,6 @@ DEFUN (no_bgp_evpn_advertise_default_gw, if (!bgp) return CMD_WARNING; - if (!EVPN_ENABLED(bgp)) { - vty_out(vty, - "This command is only supported under the EVPN VRF\n"); - return CMD_WARNING; - } - evpn_unset_advertise_default_gw(bgp, NULL); return CMD_SUCCESS; @@ -3718,16 +3712,16 @@ DEFPY(bgp_evpn_advertise_svi_ip, if (!bgp) return CMD_WARNING; - if (!EVPN_ENABLED(bgp)) { - vty_out(vty, - "This command is only supported under EVPN VRF\n"); - return CMD_WARNING; - } - if (no) evpn_set_advertise_svi_macip(bgp, NULL, 0); - else + else { + if (!EVPN_ENABLED(bgp)) { + vty_out(vty, + "This command is only supported under EVPN VRF\n"); + return CMD_WARNING; + } evpn_set_advertise_svi_macip(bgp, NULL, 1); + } return CMD_SUCCESS; } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index a902c63dea..62fed931f9 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1417,7 +1417,6 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */ struct bgp *bgp_vpn, /* from */ afi_t afi) { - struct prefix_rd prd; struct bgp_dest *pdest; safi_t safi = SAFI_MPLS_VPN; @@ -1428,16 +1427,10 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */ */ for (pdest = bgp_table_top(bgp_vpn->rib[afi][safi]); pdest; pdest = bgp_route_next(pdest)) { - const struct prefix *p = bgp_dest_get_prefix(pdest); struct bgp_table *table; struct bgp_dest *bn; struct bgp_path_info *bpi; - memset(&prd, 0, sizeof(prd)); - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - memcpy(prd.val, &p->u.val, 8); - /* This is the per-RD table of prefixes */ table = bgp_dest_get_bgp_table_info(pdest); diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c index f65a4be677..2547439499 100644 --- a/bgpd/bgp_nb.c +++ b/bgpd/bgp_nb.c @@ -7406,6 +7406,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client", .cbs = { .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify, @@ -10004,6 +10074,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify, diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h index eb7725d3dd..57f379b6cc 100644 --- a/bgpd/bgp_nb.h +++ b/bgpd/bgp_nb.h @@ -3325,6 +3325,48 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( @@ -4529,6 +4571,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_server_route_ struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index 2351e7f1a3..5a88bd08d9 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -21848,8 +21848,7 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); } return NB_OK; @@ -21863,8 +21862,7 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config case NB_EV_PREPARE: case NB_EV_ABORT: case NB_EV_APPLY: - /* TODO: implement me. */ - break; + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); } return NB_OK; @@ -22992,8 +22990,7 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_p case NB_EV_ABORT: return NB_OK; case NB_EV_APPLY: - bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); - break; + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); } return NB_OK; @@ -35539,6 +35536,350 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfi /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client */ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( @@ -47032,6 +47373,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguratio /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( @@ -47570,7 +48251,7 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rm case NB_EV_ABORT: break; case NB_EV_APPLY: - return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); } return NB_OK; @@ -47604,7 +48285,7 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_pl case NB_EV_ABORT: break; case NB_EV_APPLY: - return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); } return NB_OK; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index a1c85757d4..1e465d2620 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1390,7 +1390,6 @@ DEFUN_YANG_NOSH(router_bgp, NB_OP_MODIFY, "true"); } - nb_cli_pending_commit_check(vty); ret = nb_cli_apply_changes(vty, base_xpath); if (ret == CMD_SUCCESS) { VTY_PUSH_XPATH(BGP_NODE, base_xpath); @@ -1399,6 +1398,7 @@ DEFUN_YANG_NOSH(router_bgp, * For backward compatibility with old commands we still * need to use the qobj infrastructure. */ + nb_cli_pending_commit_check(vty); bgp = bgp_lookup(as, name); if (bgp) VTY_PUSH_CONTEXT(BGP_NODE, bgp); @@ -3990,7 +3990,7 @@ void cli_show_router_global_neighbor_config(struct vty *vty, DEFUN_YANG(bgp_listen_limit, bgp_listen_limit_cmd, - "bgp listen limit (1-5000)", + "bgp listen limit (1-65535)", "BGP specific commands\n" "BGP Dynamic Neighbors listen commands\n" "Maximum number of BGP Dynamic Neighbors that can be created\n" @@ -4007,7 +4007,7 @@ DEFUN_YANG(bgp_listen_limit, DEFUN_YANG(no_bgp_listen_limit, no_bgp_listen_limit_cmd, - "no bgp listen limit [(1-5000)]", + "no bgp listen limit [(1-65535)]", NO_STR "BGP specific commands\n" "BGP Dynamic Neighbors listen commands\n" diff --git a/bgpd/bgpd.conf.sample b/bgpd/bgpd.conf.sample deleted file mode 100644 index 1fb4f1600b..0000000000 --- a/bgpd/bgpd.conf.sample +++ /dev/null @@ -1,31 +0,0 @@ -! -*- bgp -*- -! -! BGPd sample configuration file -! -! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $ -! -hostname bgpd -password zebra -!enable password please-set-at-here -! -! -router bgp 7675 -! bgp router-id 10.0.0.1 -! network 10.0.0.0/8 -! neighbor 10.0.0.2 remote-as 7675 -! neighbor 10.0.0.2 ebgp-multihop -! -! address-family ipv4 unicast -! neighbor 10.0.0.2 route-map set-nexthop out -! neighbor 10.0.0.2 next-hop-self -! exit-address-family -! -! access-list all permit any -! -!route-map set-nexthop permit 10 -! match ip address all -! set ip next-hop 10.0.0.1 -! -!log file bgpd.log -! -log stdout diff --git a/bgpd/bgpd.conf.vnc.sample b/bgpd/bgpd.conf.vnc.sample deleted file mode 100644 index a8a2dc5fa0..0000000000 --- a/bgpd/bgpd.conf.vnc.sample +++ /dev/null @@ -1,91 +0,0 @@ -hostname H192.1.1.1 -password zebra -#enable password zebra -log stdout notifications -log monitor notifications -#debug bgp - -line vty -exec-timeout 1000 -exit - - -router bgp 64512 - - # Must set a router-id if no zebra (default 0.0.0.0) - bgp router-id 192.1.1.1 - - neighbor 192.1.1.2 remote-as 64512 - neighbor 192.1.1.2 description H192.1.1.2 - neighbor 192.1.1.2 update-source 192.1.1.1 - neighbor 192.1.1.2 advertisement-interval 1 - - neighbor 192.1.1.3 remote-as 64512 - neighbor 192.1.1.3 description H192.1.1.3 - neighbor 192.1.1.3 update-source 192.1.1.1 - neighbor 192.1.1.3 advertisement-interval 1 - - address-family ipv4 unicast - no neighbor 192.1.1.2 activate - no neighbor 192.1.1.3 activate - - address-family vpnv4 - neighbor 192.1.1.2 activate - neighbor 192.1.1.3 activate - exit-address-family - - address-family vpnv6 - neighbor 192.1.1.2 activate - neighbor 192.1.1.3 activate - exit-address-family - - vnc defaults - rd auto:vn:5226 - response-lifetime 45 - rt both 1000:1 1000:2 - exit-vnc - - vnc nve-group group1 - prefix vn 172.16.0.0/16 - exit-vnc - - vnc nve-group red - prefix vn 10.0.0.0/8 - rd auto:vn:10 - rt both 1000:10 - exit-vnc - - vnc nve-group blue - prefix vn 20.0.0.0/8 - rd auto:vn:20 - rt both 1000:20 - exit-vnc - - vnc nve-group green - prefix vn 30.0.0.0/8 - rd auto:vn:20 - rt both 1000:30 - exit-vnc - - vnc nve-group rfc4291v6c - prefix vn ::ac10:0/112 - rd auto:vn:5227 - rt both 2000:1 - exit-vnc - - vnc nve-group rfc4291v6m - prefix vn ::ffff:ac10:0/112 - rd auto:vn:5528 - rt both 3000:1 - exit-vnc - - vnc nve-group rfc6052v6 - prefix vn 64:ff9b::ac10:0/112 - rd auto:vn:5529 - rt both 4000:1 - exit-vnc - -exit - - - diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 3f5f4ce4a1..51134dc8c5 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1824,7 +1824,7 @@ struct bgp_nlri { /* BGP Dynamic Neighbors feature */ #define BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT 100 #define BGP_DYNAMIC_NEIGHBORS_LIMIT_MIN 1 -#define BGP_DYNAMIC_NEIGHBORS_LIMIT_MAX 5000 +#define BGP_DYNAMIC_NEIGHBORS_LIMIT_MAX 65535 /* Flag for peer_clear_soft(). */ enum bgp_clear_type { diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 583d1cd207..07e71ba601 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -6,11 +6,6 @@ if BGPD noinst_LIBRARIES += bgpd/libbgp.a sbin_PROGRAMS += bgpd/bgpd noinst_PROGRAMS += bgpd/bgp_btoa -dist_examples_DATA += \ - bgpd/bgpd.conf.sample \ - bgpd/bgpd.conf.sample2 \ - bgpd/bgpd.conf.vnc.sample \ - # end vtysh_scan += \ bgpd/bgp_bfd.c \ bgpd/bgp_debug.c \ diff --git a/debian/frr.dirs b/debian/frr.dirs index 9e592e370c..e3832d10a1 100644 --- a/debian/frr.dirs +++ b/debian/frr.dirs @@ -2,7 +2,6 @@ etc/frr/ etc/iproute2/rt_protos.d/ etc/logrotate.d/ usr/share/doc/frr/ -usr/share/doc/frr/examples/ usr/share/lintian/overrides/ usr/share/yang/ var/log/frr/ diff --git a/debian/frr.install b/debian/frr.install index 9972b579f0..48263222f8 100644 --- a/debian/frr.install +++ b/debian/frr.install @@ -1,5 +1,6 @@ debian/frr.conf usr/lib/tmpfiles.d etc/ +tools/etc/frr/frr.conf etc/frr/ tools/frr-reload usr/lib/frr/ usr/bin/mtracebis usr/bin/vtysh @@ -16,6 +17,5 @@ usr/lib/frr/*.sh usr/lib/frr/*d usr/lib/frr/watchfrr usr/lib/frr/zebra -usr/share/doc/frr/examples usr/share/man/ usr/share/yang/ diff --git a/debian/rules b/debian/rules index 25ae04261d..93d0cdb2a0 100755 --- a/debian/rules +++ b/debian/rules @@ -43,7 +43,6 @@ export PYTHON=python3 override_dh_auto_configure: $(shell dpkg-buildflags --export=sh); \ dh_auto_configure -- \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ --localstatedir=/var/run/frr \ --sbindir=/usr/lib/frr \ --sysconfdir=/etc/frr \ @@ -92,8 +91,6 @@ endif cp -r tools/etc/* debian/tmp/etc/ -rm debian/tmp/etc/frr/daemons.conf - sed -e 's#^!log file #!log file /var/log/frr/#' -i debian/tmp/usr/share/doc/frr/examples/*sample* - # drop dev-only files find debian/tmp -name '*.la' -o -name '*.a' -o -name 'lib*.so' | xargs rm -f rm -rf debian/tmp/usr/include diff --git a/doc/developer/building-frr-for-alpine.rst b/doc/developer/building-frr-for-alpine.rst index f88fc7bfdc..68e58c9d76 100644 --- a/doc/developer/building-frr-for-alpine.rst +++ b/doc/developer/building-frr-for-alpine.rst @@ -85,8 +85,6 @@ startup. To configure by hand: docker exec -it frr /bin/sh vi /etc/frr/daemons - cp /etc/frr/zebra.conf.sample /etc/frr/zebra.conf - vi /etc/frr/zebra.conf /etc/init.d/frr start Or, to configure the daemons using /etc/frr from a host volume, put the diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index 2a6d2dda34..a86566dbb0 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -480,6 +480,15 @@ Some things to keep in mind: - Avoid including unstable data in your test: don't rely on link-local addresses or ifindex values, for example, because these can change from run to run. +- Using sleep is almost never appropriate to wait for some convergence + event as the sole item done. As an example: if the test resets the peers + in BGP, the test should look for the peers reconverging instead of just + sleeping an arbitrary amount of time and continuing on. It is ok to + use sleep in a tight loop with appropriate show commands to ensure that + the protocol reaches the desired state. This should be bounded by + appropriate timeouts for the protocol in question though. See + verify_bgp_convergence as a good example of this. If you are having + troubles figuring out what to look for, please do not be afraid to ask. Topotest File Hierarchy diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index abdbea5a9c..b4ddec10c9 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -500,10 +500,22 @@ made. For example, a change in :file:`bgpd/rfapi` would be formatted as:: The first line should be no longer than 50 characters. Subsequent lines should be wrapped to 72 characters. +The purpose of commit messages is to briefly summarize what the commit is +changing. Therefore, the extended summary portion should be in the form of an +English paragraph. Brief examples of program output are acceptable but if +present should be short (on the order of 10 lines) and clearly demonstrate what +has changed. The goal should be that someone with only passing familiarity with +the code in question can understand what is being changed. + +Commit messages consisting entirely of program output are *unacceptable*. These +do not describe the behavior changed. For example, putting VTYSH output or the +result of test runs as the sole content of commit messages is unacceptable. + You must also sign off on your commit. .. seealso:: :ref:`signing-off` + Source File Header ------------------ diff --git a/doc/user/babeld.rst b/doc/user/babeld.rst index e6d4aa5c97..c8015bb7e5 100644 --- a/doc/user/babeld.rst +++ b/doc/user/babeld.rst @@ -233,3 +233,41 @@ Babel debugging commands .. note:: If you have compiled with the ``NO_DEBUG`` flag, then these commands aren't available. + + +Babel sample configuration file +=============================== + +.. code-block:: frr + + debug babel common + !debug babel kernel + !debug babel filter + !debug babel timeout + !debug babel interface + !debug babel route + !debug babel all + + router babel + ! network wlan0 + ! network eth0 + ! redistribute ipv4 kernel + ! no redistribute ipv6 static + + ! The defaults are fine for a wireless interface + + !interface wlan0 + + ! A few optimisation tweaks are optional but recommended on a wired interface + ! Disable link quality estimation, enable split horizon processing, and + ! increase the hello and update intervals. + + !interface eth0 + ! babel wired + ! babel split-horizon + ! babel hello-interval 12000 + ! babel update-interval 36000 + + ! log file /var/log/quagga/babeld.log + log stdout + diff --git a/doc/user/basic.rst b/doc/user/basic.rst index 5cbd3692dc..519f30d5e6 100644 --- a/doc/user/basic.rst +++ b/doc/user/basic.rst @@ -444,7 +444,7 @@ Terminal Mode Commands Shows the current log filters applied to each daemon. -.. clicmd:: show memory +.. clicmd:: show memory [DAEMON] Show information on how much memory is used for which specific things in |PACKAGE_NAME|. Output may vary depending on system capabilities but will @@ -502,7 +502,8 @@ Terminal Mode Commands the column may be missing if system support is not available. When executing this command from ``vtysh``, each of the daemons' memory - usage is printed sequentially. + usage is printed sequentially. You can specify the daemon's name to print + only its memory usage. .. clicmd:: show history @@ -513,32 +514,43 @@ Terminal Mode Commands Send a message to all logging destinations that are enabled for messages of the given severity. -.. clicmd:: find COMMAND... +.. clicmd:: find REGEX... - This command performs a simple substring search across all defined commands - in all modes. As an example, suppose you're in enable mode and can't - remember where the command to turn OSPF segment routing on is: + This command performs a regex search across all defined commands in all + modes. As an example, suppose you're in enable mode and can't remember where + the command to turn OSPF segment routing on is: :: frr# find segment-routing on (ospf) segment-routing on + (isis) segment-routing on + The CLI mode is displayed next to each command. In this example, :clicmd:`segment-routing on` is under the `router ospf` mode. - Similarly, suppose you want a listing of all commands that contain "l2vpn": + Similarly, suppose you want a listing of all commands that contain "l2vpn" + and "neighbor": :: - frr# find l2vpn - (view) show [ip] bgp l2vpn evpn [json] - (view) show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json] - (view) show [ip] bgp l2vpn evpn all neighbors A.B.C.D advertised-routes [json] - (view) show [ip] bgp l2vpn evpn all neighbors A.B.C.D routes [json] - (view) show [ip] bgp l2vpn evpn all overlay + frr# find l2vpn.*neighbor + (view) show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json] + (view) show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> routes [json] + (view) show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json] + (view) show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors <A.B.C.D|X:X::X:X|WORD> routes [json] ... + + Note that when entering spaces as part of a regex specification, repeated + spaces will be compressed into a single space for matching purposes. This is + a consequence of spaces being used to delimit CLI tokens. If you need to + match more than one space, use the ``\s`` escape. + + POSIX Extended Regular Expressions are supported. + + .. _common-show-commands: .. clicmd:: show thread cpu [r|w|t|e|x] diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 5d3f4f0e7e..7d8d84d6a0 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1363,6 +1363,15 @@ Defining Peers ``net.core.optmem_max`` to allow the kernel to allocate the necessary option memory. +.. clicmd:: bgp listen limit <1-65535> + + Define the maximum number of peers accepted for one BGP instance. This + limit is set to 100 by default. Increasing this value will really be + possible if more file descriptors are available in the BGP process. This + value is defined by the underlying system (ulimit value), and can be + overriden by `--limit-fds`. More information is available in chapter + (:ref:`common-invocation-options`). + .. clicmd:: coalesce-time (0-4294967295) The time in milliseconds that BGP will delay before deciding what peers @@ -1615,6 +1624,16 @@ Configuring Peers peer in question. This number is between 0 and 600 seconds, with the default advertisement interval being 0. +.. clicmd:: neighbor PEER timers (0-65535) (0-65535) + + Set keepalive and hold timers for a neighbor. The first value is keepalive + and the second is hold time. + +.. clicmd:: neighbor PEER connect (1-65535) + + Set connect timer for a neighbor. The connect timer controls how long BGP + waits between connection attempts to a neighbor. + .. clicmd:: neighbor PEER timers delayopen (1-240) This command allows the user enable the diff --git a/doc/user/eigrpd.rst b/doc/user/eigrpd.rst index 88d289d27e..573e2ca2e4 100644 --- a/doc/user/eigrpd.rst +++ b/doc/user/eigrpd.rst @@ -183,3 +183,18 @@ Debug for EIGRP protocol. ``show debugging eigrp`` will show all information currently set for eigrpd debug. + +Sample configuration +==================== + +.. code-block:: frr + + hostname eigrpd + password zebra + enable password please-set-at-here + ! + router eigrp 4453 + network 192.168.1.0/24 + ! + log stdout + diff --git a/doc/user/fabricd.rst b/doc/user/fabricd.rst index 611bc1caaa..48d264f30e 100644 --- a/doc/user/fabricd.rst +++ b/doc/user/fabricd.rst @@ -60,7 +60,6 @@ in the configuration: .. clicmd:: set-overload-bit - Set overload bit to avoid any transit traffic. .. clicmd:: purge-originator @@ -256,9 +255,8 @@ Debugging OpenFabric Print which OpenFabric debug levels are active. - -OpenFabric configuration example -================================ +Sample configuration +==================== A simple example: @@ -281,3 +279,26 @@ A simple example: ! router openfabric 1 net 49.0000.0000.0001.00 + + +Alternative example: + +.. code-block:: frr + + hostname fabricd + + router openfabric DEAD + net 47.0023.0000.0003.0300.0100.0102.0304.0506.00 + lsp-lifetime 65535 + + hostname isisd-router + domain-password foobar + + interface eth0 + ip router openfabric DEAD + openfabric hello-interval 5 + openfabric lsp-interval 1000 + + ! -- optional + openfabric retransmit-interval 10 + openfabric retransmit-throttle-interval diff --git a/doc/user/ldpd.rst b/doc/user/ldpd.rst index 3e662b14d8..a6b3d9d97f 100644 --- a/doc/user/ldpd.rst +++ b/doc/user/ldpd.rst @@ -242,8 +242,9 @@ LDP debugging commands - ``messages`` - ``zebra`` -LDP Example Configuration -========================= + +Sample configuration +==================== Below configuration gives a typical MPLS configuration of a device located in a MPLS backbone. LDP is enabled on two interfaces and will attempt to peer with @@ -306,3 +307,45 @@ that traffic to that destination will be applied. O>* 10.200.0.0/24 [110/210] via 10.115.0.1, eth2, label 17, 00:00:15 north-vm# + +Additional example demonstrating use of some miscellaneous config options: + +.. code-block:: frr + + interface eth0 + ! + interface eth1 + ! + interface lo + ! + mpls ldp + dual-stack cisco-interop + neighbor 10.0.1.5 password opensourcerouting + neighbor 172.16.0.1 password opensourcerouting + ! + address-family ipv4 + discovery transport-address 10.0.1.1 + label local advertise explicit-null + ! + interface eth0 + ! + interface eth1 + ! + ! + address-family ipv6 + discovery transport-address 2001:db8::1 + ! + interface eth1 + ! + ! + ! + l2vpn ENG type vpls + bridge br0 + member interface eth2 + ! + member pseudowire mpw0 + neighbor lsr-id 1.1.1.1 + pw-id 100 + ! + ! + diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst index 17251e11ac..43c0f62ea3 100644 --- a/doc/user/ospf6d.rst +++ b/doc/user/ospf6d.rst @@ -243,8 +243,9 @@ Showing OSPF6 information JSON object, with each router having "cost", "isLeafNode" and "children" as arguments. -OSPF6 Configuration Examples -============================ + +Sample configuration +==================== Example of ospf6d configured on one interface and area: @@ -258,3 +259,53 @@ Example of ospf6d configured on one interface and area: area 0.0.0.0 range 2001:770:105:2::/64 interface eth0 area 0.0.0.0 ! + + +Larger example with policy and various options set: + + +.. code-block:: frr + + debug ospf6 neighbor state + ! + interface fxp0 + ipv6 ospf6 cost 1 + ipv6 ospf6 hello-interval 10 + ipv6 ospf6 dead-interval 40 + ipv6 ospf6 retransmit-interval 5 + ipv6 ospf6 priority 0 + ipv6 ospf6 transmit-delay 1 + ipv6 ospf6 instance-id 0 + ! + interface lo0 + ipv6 ospf6 cost 1 + ipv6 ospf6 hello-interval 10 + ipv6 ospf6 dead-interval 40 + ipv6 ospf6 retransmit-interval 5 + ipv6 ospf6 priority 1 + ipv6 ospf6 transmit-delay 1 + ipv6 ospf6 instance-id 0 + ! + router ospf6 + router-id 255.1.1.1 + redistribute static route-map static-ospf6 + interface fxp0 area 0.0.0.0 + ! + access-list access4 permit 127.0.0.1/32 + ! + ipv6 access-list access6 permit 3ffe:501::/32 + ipv6 access-list access6 permit 2001:200::/48 + ipv6 access-list access6 permit ::1/128 + ! + ipv6 prefix-list test-prefix seq 1000 deny any + ! + route-map static-ospf6 permit 10 + match ipv6 address prefix-list test-prefix + set metric-type type-2 + set metric 2000 + ! + line vty + access-class access4 + ipv6 access-class access6 + exec-timeout 0 0 + ! diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index 85b6007f36..800530901e 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -280,7 +280,7 @@ To start OSPF process you have to specify the OSPF router. This command enables or disables sending ARP requests to update neighbor table entries. It speeds up convergence for /32 networks on a P2P - connection. + connection. This feature is enabled by default. @@ -1089,8 +1089,9 @@ Debugging OSPF Debug commnd to enable/disable external route summarisation specific debugs. -OSPF Configuration Examples -=========================== + +Sample Configuration +==================== A simple example, with MD5 authentication enabled: diff --git a/doc/user/overview.rst b/doc/user/overview.rst index b4f56260c9..efe64b72f0 100644 --- a/doc/user/overview.rst +++ b/doc/user/overview.rst @@ -58,6 +58,33 @@ routes to Internet exchanges running full Internet tables. FRR runs on all modern \*NIX operating systems, including Linux and the BSDs. Feature support varies by platform; see the :ref:`feature-matrix`. +System Requirements +------------------- + +System resources needed by FRR are highly dependent on workload. Routing +software performance is particularly susceptible to external factors such as: + +* Kernel networking stack +* Physical NIC +* Peer behavior +* Routing information scale + +Because of these factors - especially the last one - it's difficult to lay out +resource requirements. + +To put this in perspective, FRR can be run on very low resource systems such as +SBCs, provided it is not stressed too much. If you want to set up 4 Raspberry +Pis to play with BGP or OSPF, it should work fine. If you ask a FRR to process +a complete internet routing table on a Raspberry Pi, you will be disappointed. +However, given enough resources, FRR ought to be capable of acting as a core IX +router. Such a use case requires at least 4gb of memory and a recent quad-core +server processor at a minimum. + +If you are new to networking, an important thing to remember is that FRR is +control plane software. It does not itself forward packets - it exchanges +information with peers about how to forward packets. Forwarding plane +performance largely depends on choice of NIC / ASIC. + System Architecture ------------------- diff --git a/doc/user/pathd.rst b/doc/user/pathd.rst index fe50a5e7eb..5fc3837839 100644 --- a/doc/user/pathd.rst +++ b/doc/user/pathd.rst @@ -395,3 +395,52 @@ learned through BGP using route-maps: ! In this case, the SR Policy with color `1` and endpoint `1.1.1.1` is selected. + + +Sample configuration +==================== + +.. code-block:: frr + + ! Default pathd configuration sample + ! + password frr + log stdout + + segment-routing + traffic-eng + segment-list test1 + index 10 mpls label 123 + index 20 mpls label 456 + ! + segment-list test2 + index 10 mpls label 321 + index 20 mpls label 654 + ! + policy color 1 endpoint 1.1.1.1 + name one + binding-sid 100 + candidate-path preference 100 name test1 explicit segment-list test1 + candidate-path preference 200 name test2 explicit segment-list test2 + ! + policy color 2 endpoint 2.2.2.2 + name two + binding-sid 101 + candidate-path preference 100 name def explicit segment-list test2 + candidate-path preference 200 name dyn dynamic + bandwidth 12345 + metric bound abc 16 required + metric te 10 + ! + ! + pcep + pcc-peer PCE1 + address ip 127.0.0.1 + sr-draft07 + ! + pcc + peer PCE1 + ! + ! + ! + diff --git a/doc/user/pbr.rst b/doc/user/pbr.rst index 14a05a69d7..77134a7704 100644 --- a/doc/user/pbr.rst +++ b/doc/user/pbr.rst @@ -290,3 +290,22 @@ kernel that points to a table to use for forwarding once the rule matches. The creation of a nexthop or nexthop-group is translated to a default route in a table with the nexthops specified as the nexthops for the default route. + +Sample configuration +==================== + +.. code-block:: frr + + nexthop-group TEST + nexthop 4.5.6.7 + nexthop 5.6.7.8 + ! + pbr-map BLUE seq 100 + match dst-ip 9.9.9.0/24 + match src-ip 10.10.10.0/24 + set nexthop-group TEST + ! + int swp1 + pbr-policy BLUE + + diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 86716b49a4..6b7cae2c5d 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -656,3 +656,34 @@ setup. This is existing PIM configuration: - Enable pim on the underlay L3 interface via the "ip pim" command. - Configure RPs for the BUM multicast group range. - Ensure the PIM is enabled on the lo of the VTEPs and the RP. + + +Sample configuration +==================== + +.. code-block:: frr + + debug igmp + debug pim + debug pim zebra + + ! You may want to enable ssmpingd for troubleshooting + ! See http://www.venaas.no/multicast/ssmping/ + ! + ip ssmpingd 1.1.1.1 + ip ssmpingd 2.2.2.2 + + ! HINTS: + ! - Enable "ip pim ssm" on the interface directly attached to the + ! multicast source host (if this is the first-hop router) + ! - Enable "ip pim ssm" on pim-routers-facing interfaces + ! - Enable "ip igmp" on IGMPv3-hosts-facing interfaces + ! - In order to inject IGMPv3 local membership information in the + ! PIM protocol state, enable both "ip pim ssm" and "ip igmp" on + ! the same interface; otherwise PIM won't advertise + ! IGMPv3-learned membership to other PIM routers + + interface eth0 + ip pim ssm + ip igmp + diff --git a/doc/user/ripd.rst b/doc/user/ripd.rst index cba93e0d84..83c8c93b1c 100644 --- a/doc/user/ripd.rst +++ b/doc/user/ripd.rst @@ -539,3 +539,21 @@ Debug for RIP protocol. Shows all information currently set for ripd debug. + +Sample configuration +==================== + +.. code-block:: frr + + + debug rip events + debug rip packet + + router rip + network 11.0.0.0/8 + network eth0 + route 10.0.0.0/8 + distribute-list private-only in eth0 + + access-list private-only permit 10.0.0.0/8 + access-list private-only deny any diff --git a/doc/user/ripngd.rst b/doc/user/ripngd.rst index 0387e36305..b273eb3bfa 100644 --- a/doc/user/ripngd.rst +++ b/doc/user/ripngd.rst @@ -71,3 +71,19 @@ ripngd Filtering Commands distribute-list local-only out sit1 + +Sample configuration +==================== + +.. code-block:: frr + + debug ripng events + debug ripng packet + + router ripng + network sit1 + route 3ffe:506::0/32 + distribute-list local-only out sit1 + + ipv6 access-list local-only permit 3ffe:506::0/32 + ipv6 access-list local-only deny any diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index e5cd1de201..205b25e53e 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1020,3 +1020,68 @@ For protocols requiring an IPv6 router-id, the following commands are available: .. clicmd:: show ipv6 router-id [vrf NAME] Display the user configured IPv6 router-id. + + +Debugging +========= + +.. clicmd:: debug zebra mpls [detailed] + + MPLS-related events and information. + +.. clicmd:: debug zebra events + + Zebra events + +.. clicmd:: debug zebra nht [detailed] + + Nexthop-tracking / reachability information + +.. clicmd:: debug zebra vxlan + + VxLAN (EVPN) events + +.. clicmd:: debug zebra pseudowires + + Pseudowire events. + +.. clicmd:: debug zebra packet [<recv|send>] [detail] + + ZAPI message and packet details + +.. clicmd:: debug zebra kernel + + Kernel / OS events. + +.. clicmd:: debug zebra kernel msgdump [<recv|send>] + + Raw OS (netlink) message details. + +.. clicmd:: debug zebra rib [detailed] + + RIB events. + +.. clicmd:: debug zebra fpm + + FPM (forwarding-plane manager) events. + +.. clicmd:: debug zebra dplane [detailed] + + Dataplane / FIB events. + +.. clicmd:: debug zebra pbr + + PBR (policy-based routing) events. + +.. clicmd:: debug zebra mlag + + MLAG events. + +.. clicmd:: debug zebra evpn mh <es|mac|neigh|nh> + + EVPN multi-hop events. + +.. clicmd:: debug zebra nexthop [detail] + + Nexthop and nexthop-group events. + diff --git a/eigrpd/eigrpd.conf.sample b/eigrpd/eigrpd.conf.sample deleted file mode 100644 index 662e667d3f..0000000000 --- a/eigrpd/eigrpd.conf.sample +++ /dev/null @@ -1,13 +0,0 @@ -! -*- eigrpd -*- -! -! EIGRPDd sample configuration file -! -! -hostname eigrpd -password zebra -!enable password please-set-at-here -! -!router eigrp 4453 -! network 192.168.1.0/24 -! -log stdout diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index ba9445acb9..82873a4960 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -5,7 +5,6 @@ if EIGRPD noinst_LIBRARIES += eigrpd/libeigrp.a sbin_PROGRAMS += eigrpd/eigrpd -dist_examples_DATA += eigrpd/eigrpd.conf.sample vtysh_scan += \ eigrpd/eigrp_cli.c \ eigrpd/eigrp_dump.c \ diff --git a/isisd/fabricd.conf.sample b/isisd/fabricd.conf.sample deleted file mode 100644 index be9e33ba62..0000000000 --- a/isisd/fabricd.conf.sample +++ /dev/null @@ -1,27 +0,0 @@ -! -*- openfabric -*- -! -! fabricd sample configuration file -! -hostname fabricd -password foo -enable password foo -log stdout -!log file /tmp/fabricd.log -! -! -router openfabric DEAD - net 47.0023.0000.0003.0300.0100.0102.0304.0506.00 -! lsp-lifetime 65535 - -! hostname isisd-router -! domain-password foobar - -interface eth0 - ip router openfabric DEAD -! openfabric hello-interval 5 -! openfabric lsp-interval 1000 - -! -- optional -! openfabric retransmit-interval 10 -! openfabric retransmit-throttle-interval -! diff --git a/isisd/isisd.conf.sample b/isisd/isisd.conf.sample deleted file mode 100644 index 47b15953fd..0000000000 --- a/isisd/isisd.conf.sample +++ /dev/null @@ -1,39 +0,0 @@ -! -*- isis -*- -! -! ISISd sample configuration file -! -hostname isisd -password foo -enable password foo -log stdout -!log file /tmp/isisd.log -! -! -router isis DEAD - net 47.0023.0000.0003.0300.0100.0102.0304.0506.00 -! is-type level-1 - -! -- set the lifetime either for level-1, level-2 or both -! lsp-lifetime level-1 65535 -! lsp-lifetime level-2 65535 -! lsp-lifetime 65535 - -! hostname isisd-router -! area-password foobar -! domain-password foobar - -interface eth0 - ip router isis DEAD -! isis hello-interval 5 -! isis lsp-interval 1000 - -! -- optional -! isis circuit-type level-1 -! isis password lallaa level-1 -! isis metric 1 level-1 -! isis csnp-interval 5 level-1 -! isis retransmit-interval 10 -! isis retransmit-throttle-interval -! isis hello-multiplier 2 level-1 -! isis priority 64 -! diff --git a/isisd/subdir.am b/isisd/subdir.am index 4cefe6e10b..11bae41657 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -5,7 +5,6 @@ if ISISD noinst_LIBRARIES += isisd/libisis.a sbin_PROGRAMS += isisd/isisd -dist_examples_DATA += isisd/isisd.conf.sample vtysh_scan += \ isisd/isis_cli.c \ isisd/isis_ldp_sync.c \ @@ -26,7 +25,6 @@ endif if FABRICD noinst_LIBRARIES += isisd/libfabric.a sbin_PROGRAMS += isisd/fabricd -dist_examples_DATA += isisd/fabricd.conf.sample if !ISISD vtysh_scan += \ isisd/isis_cli.c \ diff --git a/ldpd/ldpd.conf.sample b/ldpd/ldpd.conf.sample deleted file mode 100644 index 49da35c284..0000000000 --- a/ldpd/ldpd.conf.sample +++ /dev/null @@ -1,46 +0,0 @@ -! -*- ldp -*- -! -! LDPd sample configuration file -! -hostname ldpd -password zebra -log stdout -! -interface eth0 -! -interface eth1 -! -interface lo -! -mpls ldp - dual-stack cisco-interop - neighbor 10.0.1.5 password opensourcerouting - neighbor 172.16.0.1 password opensourcerouting - ! - address-family ipv4 - discovery transport-address 10.0.1.1 - label local advertise explicit-null - ! - interface eth0 - ! - interface eth1 - ! - ! - address-family ipv6 - discovery transport-address 2001:db8::1 - ! - interface eth1 - ! - ! -! -l2vpn ENG type vpls - bridge br0 - member interface eth2 - ! - member pseudowire mpw0 - neighbor lsr-id 1.1.1.1 - pw-id 100 - ! -! -line vty -! diff --git a/ldpd/subdir.am b/ldpd/subdir.am index aa9b751bcc..5fc3847c6d 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -5,7 +5,6 @@ if LDPD noinst_LIBRARIES += ldpd/libldp.a sbin_PROGRAMS += ldpd/ldpd -dist_examples_DATA += ldpd/ldpd.conf.sample vtysh_scan += ldpd/ldp_vty_cmds.c vtysh_daemons += ldpd man8 += $(MANBUILD)/frr-ldpd.8 @@ -988,6 +988,9 @@ void bfd_sess_show(struct vty *vty, struct json_object *json, json_object *json_bfd = NULL; char time_buf[64]; + if (!bsp) + return; + /* Show type. */ if (json) { json_bfd = json_object_new_object(); diff --git a/lib/command.c b/lib/command.c index 770e2fc5ac..d2798b5002 100644 --- a/lib/command.c +++ b/lib/command.c @@ -2226,18 +2226,19 @@ DEFUN (no_banner_motd, DEFUN(find, find_cmd, - "find REGEX", + "find REGEX...", "Find CLI command matching a regular expression\n" "Search pattern (POSIX regex)\n") { - char *pattern = argv[1]->arg; const struct cmd_node *node; const struct cmd_element *cli; vector clis; regex_t exp = {}; + char *pattern = argv_concat(argv, argc, 1); int cr = regcomp(&exp, pattern, REG_NOSUB | REG_EXTENDED); + XFREE(MTYPE_TMP, pattern); if (cr != 0) { switch (cr) { diff --git a/lib/elf_py.c b/lib/elf_py.c index d26e443b82..b47aa3d795 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -1032,7 +1032,7 @@ static char *elfdata_strptr(Elf_Data *data, size_t offset) static void elffile_add_dynreloc(struct elffile *w, Elf_Data *reldata, size_t entries, Elf_Data *symdata, - Elf_Data *strdata) + Elf_Data *strdata, Elf_Type typ) { size_t i; @@ -1041,12 +1041,59 @@ static void elffile_add_dynreloc(struct elffile *w, Elf_Data *reldata, size_t symidx; GElf_Rela *rela; GElf_Sym *sym; + GElf_Addr rel_offs = 0; relw = (struct elfreloc *)typeobj_elfreloc.tp_alloc( &typeobj_elfreloc, 0); relw->ef = w; - rela = relw->rela = gelf_getrela(reldata, i, &relw->_rela); + if (typ == ELF_T_REL) { + GElf_Rel _rel, *rel; + GElf_Addr offs; + + rel = gelf_getrel(reldata, i, &_rel); + relw->rela = &relw->_rela; + relw->rela->r_offset = rel->r_offset; + relw->rela->r_info = rel->r_info; + relw->rela->r_addend = 0; + relw->relative = true; + + /* REL uses the pointer contents itself instead of the + * RELA addend field :( ... theoretically this could + * be some weird platform specific encoding, but since + * we only care about data relocations it should + * always be a pointer... + */ + if (elffile_virt2file(w, rel->r_offset, &offs)) { + Elf_Data *ptr, *conv; + GElf_Addr tmp; + Elf_Data mem = { + .d_buf = (void *)&tmp, + .d_type = ELF_T_ADDR, + .d_version = EV_CURRENT, + .d_size = sizeof(tmp), + .d_off = 0, + .d_align = 0, + }; + + ptr = elf_getdata_rawchunk(w->elf, offs, + w->elfclass / 8, + ELF_T_ADDR); + + conv = gelf_xlatetom(w->elf, &mem, ptr, + w->mmap[EI_DATA]); + if (conv) { + memcpy(&rel_offs, conv->d_buf, + conv->d_size); + + relw->relative = false; + relw->rela->r_addend = rel_offs; + } + } + } else + relw->rela = gelf_getrela(reldata, i, &relw->_rela); + + rela = relw->rela; symidx = relw->symidx = GELF_R_SYM(rela->r_info); sym = relw->sym = gelf_getsym(symdata, symidx, &relw->_sym); if (sym) { @@ -1062,9 +1109,16 @@ static void elffile_add_dynreloc(struct elffile *w, Elf_Data *reldata, relw->st_value = 0; } - debugf("dynreloc @ %016llx sym %5llu %016llx %s\n", - (long long)rela->r_offset, (unsigned long long)symidx, - (long long)rela->r_addend, relw->symname); + if (typ == ELF_T_RELA) + debugf("dynrela @ %016llx sym %5llu %016llx %s\n", + (long long)rela->r_offset, + (unsigned long long)symidx, + (long long)rela->r_addend, relw->symname); + else + debugf("dynrel @ %016llx sym %5llu (%016llx) %s\n", + (long long)rela->r_offset, + (unsigned long long)symidx, + (unsigned long long)rel_offs, relw->symname); elfrelocs_add(&w->dynrelocs, relw); } @@ -1166,8 +1220,10 @@ static PyObject *elffile_load(PyTypeObject *type, PyObject *args, Elf_Data *dyndata = elf_getdata_rawchunk(w->elf, phdr->p_offset, phdr->p_filesz, ELF_T_DYN); - GElf_Addr dynrela = 0, symtab = 0, strtab = 0; - size_t dynrelasz = 0, dynrelaent = 0, strsz = 0; + GElf_Addr dynrela = 0, dynrel = 0, symtab = 0, strtab = 0; + size_t dynrelasz = 0, dynrelaent = 0; + size_t dynrelsz = 0, dynrelent = 0; + size_t strsz = 0; GElf_Dyn _dyn, *dyn; for (size_t j = 0;; j++) { @@ -1198,16 +1254,20 @@ static PyObject *elffile_load(PyTypeObject *type, PyObject *args, dynrelaent = dyn->d_un.d_val; break; + case DT_REL: + dynrel = dyn->d_un.d_ptr; + break; case DT_RELSZ: - if (dyn->d_un.d_val) - fprintf(stderr, - "WARNING: ignoring non-empty DT_REL!\n"); + dynrelsz = dyn->d_un.d_val; + break; + case DT_RELENT: + dynrelent = dyn->d_un.d_val; break; } } GElf_Addr offset; - Elf_Data *symdata = NULL, *strdata = NULL, *reladata = NULL; + Elf_Data *symdata = NULL, *strdata = NULL; if (elffile_virt2file(w, symtab, &offset)) symdata = elf_getdata_rawchunk(w->elf, offset, @@ -1217,19 +1277,37 @@ static PyObject *elffile_load(PyTypeObject *type, PyObject *args, strdata = elf_getdata_rawchunk(w->elf, offset, strsz, ELF_T_BYTE); - if (!dynrela || !dynrelasz || !dynrelaent) - continue; + size_t c; - if (!elffile_virt2file(w, dynrela, &offset)) - continue; + if (dynrela && dynrelasz && dynrelaent + && elffile_virt2file(w, dynrela, &offset)) { + Elf_Data *reladata = NULL; - debugf("dynrela @%llx/%llx+%llx\n", (long long)dynrela, - (long long)offset, (long long)dynrelasz); + debugf("dynrela @%llx/%llx+%llx\n", (long long)dynrela, + (long long)offset, (long long)dynrelasz); - reladata = elf_getdata_rawchunk(w->elf, offset, dynrelasz, - ELF_T_RELA); - elffile_add_dynreloc(w, reladata, dynrelasz / dynrelaent, - symdata, strdata); + reladata = elf_getdata_rawchunk(w->elf, offset, + dynrelasz, ELF_T_RELA); + + c = dynrelasz / dynrelaent; + elffile_add_dynreloc(w, reladata, c, symdata, strdata, + ELF_T_RELA); + } + + if (dynrel && dynrelsz && dynrelent + && elffile_virt2file(w, dynrel, &offset)) { + Elf_Data *reldata = NULL; + + debugf("dynrel @%llx/%llx+%llx\n", (long long)dynrel, + (long long)offset, (long long)dynrelsz); + + reldata = elf_getdata_rawchunk(w->elf, offset, dynrelsz, + ELF_T_REL); + + c = dynrelsz / dynrelent; + elffile_add_dynreloc(w, reldata, c, symdata, strdata, + ELF_T_REL); + } } #endif diff --git a/lib/prefix.c b/lib/prefix.c index 141d564606..7dbb5f07f0 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1198,15 +1198,6 @@ int netmask_str2prefix_str(const char *net_str, const char *mask_str, return 1; } -/* Utility function for making IPv6 address string. */ -const char *inet6_ntoa(struct in6_addr addr) -{ - static char buf[INET6_ADDRSTRLEN]; - - inet_ntop(AF_INET6, &addr, buf, INET6_ADDRSTRLEN); - return buf; -} - /* converts to internal representation of mac address * returns 1 on success, 0 otherwise * format accepted: AA:BB:CC:DD:EE:FF diff --git a/lib/prefix.h b/lib/prefix.h index b2f3b0592f..d7ee1b8e4c 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -504,8 +504,6 @@ extern void apply_mask_ipv6(struct prefix_ipv6 *); extern int ip6_masklen(struct in6_addr); extern void masklen2ip6(const int, struct in6_addr *); -extern const char *inet6_ntoa(struct in6_addr); - extern int is_zero_mac(const struct ethaddr *mac); extern bool is_mcast_mac(const struct ethaddr *mac); extern bool is_bcast_mac(const struct ethaddr *mac); diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c index 4de8e220ce..bcf0e2168c 100644 --- a/nhrpd/nhrp_cache.c +++ b/nhrpd/nhrp_cache.c @@ -212,7 +212,8 @@ static int nhrp_cache_do_timeout(struct thread *t) c->t_timeout = NULL; if (c->cur.type != NHRP_CACHE_INVALID) - nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL); + nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL, + NULL); return 0; } @@ -301,7 +302,8 @@ static void nhrp_cache_peer_notifier(struct notifier_block *n, case NOTIFY_PEER_DOWN: case NOTIFY_PEER_IFCONFIG_CHANGED: notifier_call(&c->notifier_list, NOTIFY_CACHE_DOWN); - nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL); + nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL, + NULL); break; case NOTIFY_PEER_NBMA_CHANGING: if (c->cur.type == NHRP_CACHE_DYNAMIC) @@ -422,7 +424,8 @@ static void nhrp_cache_newpeer_notifier(struct notifier_block *n, int nhrp_cache_update_binding(struct nhrp_cache *c, enum nhrp_cache_type type, int holding_time, struct nhrp_peer *p, - uint32_t mtu, union sockunion *nbma_oa) + uint32_t mtu, union sockunion *nbma_oa, + union sockunion *nbma_claimed) { char buf[2][SU_ADDRSTRLEN]; @@ -464,6 +467,12 @@ int nhrp_cache_update_binding(struct nhrp_cache *c, enum nhrp_cache_type type, memset(&c->cur.remote_nbma_natoa, 0, sizeof(c->cur.remote_nbma_natoa)); + if (nbma_claimed) + c->cur.remote_nbma_claimed = *nbma_claimed; + else + memset(&c->cur.remote_nbma_claimed, 0, + sizeof(c->cur.remote_nbma_claimed)); + nhrp_peer_unref(p); } else { debugf(NHRP_DEBUG_COMMON, @@ -474,9 +483,13 @@ int nhrp_cache_update_binding(struct nhrp_cache *c, enum nhrp_cache_type type, c->new.type = type; c->new.peer = p; c->new.mtu = mtu; + c->new.holding_time = holding_time; if (nbma_oa) c->new.remote_nbma_natoa = *nbma_oa; + if (nbma_claimed) + c->new.remote_nbma_claimed = *nbma_claimed; + if (holding_time > 0) c->new.expires = monotime(NULL) + holding_time; else if (holding_time < 0) diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index a64708d88e..a6880054fd 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -255,7 +255,7 @@ static void nhrp_interface_update_address(struct interface *ifp, afi_t afi, nc = nhrp_cache_get(ifp, &if_ad->addr, 0); if (nc) nhrp_cache_update_binding(nc, NHRP_CACHE_LOCAL, -1, - NULL, 0, NULL); + NULL, 0, NULL, NULL); } debugf(NHRP_DEBUG_KERNEL, "%s: IPv%d address changed to %s", ifp->name, @@ -267,7 +267,7 @@ static void nhrp_interface_update_address(struct interface *ifp, afi_t afi, nc = nhrp_cache_get(ifp, &addr, 1); if (nc) nhrp_cache_update_binding(nc, NHRP_CACHE_LOCAL, 0, NULL, - 0, NULL); + 0, NULL, NULL); } notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_ADDRESS_CHANGED); @@ -364,7 +364,7 @@ static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc, if (c && c->map) { nhrp_cache_update_binding( c, c->cur.type, -1, - nhrp_peer_get(ifp, &nbma_addr), 0, NULL); + nhrp_peer_get(ifp, &nbma_addr), 0, NULL, NULL); } return; } @@ -375,11 +375,11 @@ static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc, c->map = 1; if (cc->type == NHRP_CACHE_LOCAL) nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0, - NULL); + NULL, NULL); else { nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0, nhrp_peer_get(ifp, &cc->nbma), 0, - NULL); + NULL, NULL); } } diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c index 1689facbcf..9dfaf073d8 100644 --- a/nhrpd/nhrp_nhs.c +++ b/nhrpd/nhrp_nhs.c @@ -32,7 +32,8 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg) struct nhrp_cie_header *cie; struct nhrp_cache *c; struct zbuf extpl; - union sockunion cie_nbma, cie_proto, *proto; + union sockunion cie_nbma, cie_nbma_nhs, cie_proto, cie_proto_nhs, + *proto; int ok = 0, holdtime; unsigned short mtu = 0; @@ -66,6 +67,7 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg) /* Parse extensions */ sockunion_family(&nifp->nat_nbma) = AF_UNSPEC; + sockunion_family(&cie_nbma_nhs) = AF_UNSPEC; while ((ext = nhrp_ext_pull(&p->extensions, &extpl)) != NULL) { switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) { case NHRP_EXTENSION_NAT_ADDRESS: @@ -79,6 +81,11 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg) ifp->name, &nifp->nbma); } break; + case NHRP_EXTENSION_RESPONDER_ADDRESS: + /* NHS adds its own record as responder address */ + nhrp_cie_pull(&extpl, p->hdr, &cie_nbma_nhs, + &cie_proto_nhs); + break; } } @@ -96,7 +103,8 @@ static void nhrp_reg_reply(struct nhrp_reqid *reqid, void *arg) c = nhrp_cache_get(ifp, &p->dst_proto, 1); if (c) nhrp_cache_update_binding(c, NHRP_CACHE_NHS, holdtime, - nhrp_peer_ref(r->peer), mtu, NULL); + nhrp_peer_ref(r->peer), mtu, NULL, + &cie_nbma_nhs); } static int nhrp_reg_timeout(struct thread *t) @@ -111,7 +119,7 @@ static int nhrp_reg_timeout(struct thread *t) c = nhrp_cache_get(r->nhs->ifp, &r->proto_addr, 0); if (c) nhrp_cache_update_binding(c, NHRP_CACHE_NHS, -1, NULL, - 0, NULL); + 0, NULL, NULL); sockunion_family(&r->proto_addr) = AF_UNSPEC; } @@ -162,7 +170,7 @@ static int nhrp_reg_send_req(struct thread *t) struct interface *ifp = nhs->ifp; struct nhrp_interface *nifp = ifp->info; struct nhrp_afi_data *if_ad = &nifp->afi[nhs->afi]; - union sockunion *dst_proto; + union sockunion *dst_proto, nhs_proto; struct zbuf *zb; struct nhrp_packet_header *hdr; struct nhrp_extension_header *ext; @@ -207,17 +215,34 @@ static int nhrp_reg_send_req(struct thread *t) /* FIXME: push CIE for each local protocol address */ cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, NULL, NULL); /* RFC2332 5.2.1 if unique is set then prefix length must be 0xff */ - cie->prefix_length = (if_ad->flags & NHRP_IFF_REG_NO_UNIQUE) ? 8 * sockunion_get_addrlen(dst_proto) : 0xff; + cie->prefix_length = (if_ad->flags & NHRP_IFF_REG_NO_UNIQUE) + ? 8 * sockunion_get_addrlen(dst_proto) + : 0xff; cie->holding_time = htons(if_ad->holdtime); cie->mtu = htons(if_ad->mtu); nhrp_ext_request(zb, hdr, ifp); /* Cisco NAT detection extension */ + if (sockunion_family(&r->proto_addr) != AF_UNSPEC) { + nhs_proto = r->proto_addr; + } else if (sockunion_family(&nhs->proto_addr) != AF_UNSPEC) { + nhs_proto = nhs->proto_addr; + } else { + /* cisco magic: If NHS is not known then use all 0s as + * client protocol address in NAT Extension header + */ + memset(&nhs_proto, 0, sizeof(nhs_proto)); + sockunion_family(&nhs_proto) = afi2family(nhs->afi); + } + hdr->flags |= htons(NHRP_FLAG_REGISTRATION_NAT); ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS); - cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &nifp->nbma, &if_ad->addr); + /* push NHS details */ + cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &r->peer->vc->remote.nbma, + &nhs_proto); cie->prefix_length = 8 * sockunion_get_addrlen(&if_ad->addr); + cie->mtu = htons(if_ad->mtu); nhrp_ext_complete(zb, ext); nhrp_packet_complete(zb, hdr); @@ -442,3 +467,29 @@ void nhrp_nhs_foreach(struct interface *ifp, afi_t afi, cb(nhs, 0, ctx); } } + +int nhrp_nhs_match_ip(union sockunion *in_ip, struct nhrp_interface *nifp) +{ + int i; + struct nhrp_nhs *nhs; + struct nhrp_registration *reg; + + for (i = 0; i < AFI_MAX; i++) { + list_for_each_entry(nhs, &nifp->afi[i].nhslist_head, + nhslist_entry) + { + if (!list_empty(&nhs->reglist_head)) { + list_for_each_entry(reg, &nhs->reglist_head, + reglist_entry) + { + if (!sockunion_cmp( + in_ip, + ®->peer->vc->remote + .nbma)) + return 1; + } + } + } + } + return 0; +} diff --git a/nhrpd/nhrp_packet.c b/nhrpd/nhrp_packet.c index a983aa71bc..fd77533c89 100644 --- a/nhrpd/nhrp_packet.c +++ b/nhrpd/nhrp_packet.c @@ -268,6 +268,7 @@ int nhrp_ext_reply(struct zbuf *zb, struct nhrp_packet_header *hdr, &ad->addr); if (!cie) goto err; + cie->mtu = htons(ad->mtu); cie->holding_time = htons(ad->holdtime); break; default: diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index af352c68ee..c1f615d0a9 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -47,6 +47,7 @@ static void nhrp_peer_check_delete(struct nhrp_peer *p) p->ref, &p->vc->remote.nbma, &p->vc->local.nbma); THREAD_OFF(p->t_fallback); + THREAD_OFF(p->t_timer); hash_release(nifp->peer_hash, p); nhrp_interface_notify_del(p->ifp, &p->ifp_notifier); nhrp_vc_notify_del(p->vc, &p->vc_notifier); @@ -182,8 +183,7 @@ static void *nhrp_peer_create(void *data) .ref = 0, .ifp = key->ifp, .vc = key->vc, - .notifier_list = - NOTIFIER_LIST_INITIALIZER(&p->notifier_list), + .notifier_list = NOTIFIER_LIST_INITIALIZER(&p->notifier_list), }; nhrp_vc_notify_add(p->vc, &p->vc_notifier, nhrp_peer_vc_notify); nhrp_interface_notify_add(p->ifp, &p->ifp_notifier, @@ -283,6 +283,30 @@ static int nhrp_peer_request_timeout(struct thread *t) return 0; } +static int nhrp_peer_defer_vici_request(struct thread *t) +{ + struct nhrp_peer *p = THREAD_ARG(t); + struct nhrp_vc *vc = p->vc; + struct interface *ifp = p->ifp; + struct nhrp_interface *nifp = ifp->info; + + THREAD_OFF(p->t_timer); + + if (p->online) { + debugf(NHRP_DEBUG_COMMON, + "IPsec connection to %pSU already established", + &vc->remote.nbma); + } else { + vici_request_vc(nifp->ipsec_profile, &vc->local.nbma, + &vc->remote.nbma, p->prio); + thread_add_timer( + master, nhrp_peer_request_timeout, p, + (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30, + &p->t_fallback); + } + return 0; +} + int nhrp_peer_check(struct nhrp_peer *p, int establish) { struct nhrp_vc *vc = p->vc; @@ -304,11 +328,25 @@ int nhrp_peer_check(struct nhrp_peer *p, int establish) p->prio = establish > 1; p->requested = 1; - vici_request_vc(nifp->ipsec_profile, &vc->local.nbma, &vc->remote.nbma, - p->prio); - thread_add_timer(master, nhrp_peer_request_timeout, p, - (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30, - &p->t_fallback); + + /* All NHRP registration requests are prioritized */ + if (p->prio) { + vici_request_vc(nifp->ipsec_profile, &vc->local.nbma, + &vc->remote.nbma, p->prio); + thread_add_timer( + master, nhrp_peer_request_timeout, p, + (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30, + &p->t_fallback); + } else { + /* Maximum timeout is 1 second */ + int r_time_ms = rand() % 1000; + + debugf(NHRP_DEBUG_COMMON, + "Initiating IPsec connection request to %pSU after %d ms:", + &vc->remote.nbma, r_time_ms); + thread_add_timer_msec(master, nhrp_peer_defer_vici_request, + p, r_time_ms, &p->t_timer); + } return 0; } @@ -341,6 +379,60 @@ void nhrp_peer_send(struct nhrp_peer *p, struct zbuf *zb) zbuf_reset(zb); } +static void nhrp_process_nat_extension(struct nhrp_packet_parser *pp, + union sockunion *proto, + union sockunion *cie_nbma) +{ + union sockunion cie_proto; + struct zbuf payload; + struct nhrp_extension_header *ext; + struct zbuf *extensions; + + if (!cie_nbma) + return; + + sockunion_family(cie_nbma) = AF_UNSPEC; + + if (!proto || sockunion_family(proto) == AF_UNSPEC) + return; + + /* Handle extensions */ + extensions = zbuf_alloc(zbuf_used(&pp->extensions)); + if (extensions) { + zbuf_copy_peek(extensions, &pp->extensions, + zbuf_used(&pp->extensions)); + while ((ext = nhrp_ext_pull(extensions, &payload)) != NULL) { + switch (htons(ext->type) + & ~NHRP_EXTENSION_FLAG_COMPULSORY) { + case NHRP_EXTENSION_NAT_ADDRESS: + /* Process the NBMA and proto address in NAT + * extension and update the cache without which + * the neighbor table in the kernel contains the + * source NBMA address which is not reachable + * since it is behind a NAT device + */ + debugf(NHRP_DEBUG_COMMON, + "shortcut res_resp: Processing NAT Extension for %pSU", + proto); + while (nhrp_cie_pull(&payload, pp->hdr, + cie_nbma, &cie_proto)) { + if (sockunion_family(&cie_proto) + == AF_UNSPEC) + continue; + + if (!sockunion_cmp(proto, &cie_proto)) { + debugf(NHRP_DEBUG_COMMON, + "cie_nbma for proto %pSU is %pSU", + proto, cie_nbma); + break; + } + } + } + } + zbuf_free(extensions); + } +} + static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp) { struct interface *ifp = pp->ifp; @@ -349,12 +441,12 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp) struct nhrp_cie_header *cie; struct nhrp_extension_header *ext; struct nhrp_cache *c; - union sockunion cie_nbma, cie_proto, *proto_addr, *nbma_addr; + union sockunion cie_nbma, cie_nbma_nat, cie_proto, *proto_addr, + *nbma_addr, *claimed_nbma_addr; int holdtime, prefix_len, hostprefix_len; struct nhrp_interface *nifp = ifp->info; struct nhrp_peer *peer; size_t paylen; - char buf[SU_ADDRSTRLEN]; if (!(pp->if_ad->flags & NHRP_IFF_SHORTCUT)) { debugf(NHRP_DEBUG_COMMON, "Shortcuts disabled"); @@ -406,9 +498,41 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp) proto_addr = (sockunion_family(&cie_proto) == AF_UNSPEC) ? &pp->src_proto : &cie_proto; - nbma_addr = (sockunion_family(&cie_nbma) == AF_UNSPEC) - ? &pp->src_nbma - : &cie_nbma; + + /* Check for this proto_addr in NHRP_NAT_EXTENSION */ + nhrp_process_nat_extension(pp, proto_addr, &cie_nbma_nat); + + if (sockunion_family(&cie_nbma_nat) == AF_UNSPEC) { + /* It may be possible that this resolution reply is + * coming directly from NATTED Spoke and there is not + * NAT Extension present + */ + debugf(NHRP_DEBUG_COMMON, + "shortcut res_rep: No NAT Extension for %pSU", + proto_addr); + + if (!sockunion_same(&pp->src_nbma, + &pp->peer->vc->remote.nbma) + && !nhrp_nhs_match_ip(&pp->peer->vc->remote.nbma, + nifp)) { + cie_nbma_nat = pp->peer->vc->remote.nbma; + debugf(NHRP_DEBUG_COMMON, + "shortcut res_rep: NAT detected using %pSU as cie_nbma", + &cie_nbma_nat); + } + } + + if (sockunion_family(&cie_nbma_nat) != AF_UNSPEC) + nbma_addr = &cie_nbma_nat; + else if (sockunion_family(&cie_nbma) != AF_UNSPEC) + nbma_addr = &cie_nbma; + else + nbma_addr = &pp->src_nbma; + + if (sockunion_family(&cie_nbma) != AF_UNSPEC) + claimed_nbma_addr = &cie_nbma; + else + claimed_nbma_addr = &pp->src_nbma; holdtime = htons(cie->holding_time); debugf(NHRP_DEBUG_COMMON, @@ -424,15 +548,14 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp) cie->code = NHRP_CODE_INSUFFICIENT_RESOURCES; continue; } - if (nbma_addr) - sockunion2str(nbma_addr, buf, sizeof(buf)); debugf(NHRP_DEBUG_COMMON, - "shortcut res_rep: updating binding for nmba addr %s", - nbma_addr ? buf : "(NULL)"); - if (!nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC, holdtime, - nhrp_peer_ref(pp->peer), - htons(cie->mtu), nbma_addr)) { + "shortcut res_rep: updating binding for nmba addr %pSU", + nbma_addr); + if (!nhrp_cache_update_binding( + c, NHRP_CACHE_DYNAMIC, holdtime, + nhrp_peer_get(pp->ifp, nbma_addr), htons(cie->mtu), + nbma_addr, claimed_nbma_addr)) { cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED; continue; } @@ -468,17 +591,23 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp) while ((ext = nhrp_ext_pull(&pp->extensions, &payload)) != NULL) { switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) { case NHRP_EXTENSION_NAT_ADDRESS: - if (sockunion_family(&nifp->nat_nbma) == AF_UNSPEC) - break; ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS); if (!ext) goto err; - cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, - &nifp->nat_nbma, &pp->if_ad->addr); - if (!cie) - goto err; - nhrp_ext_complete(zb, ext); + if (sockunion_family(&nifp->nat_nbma) != AF_UNSPEC) { + cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, + &nifp->nat_nbma, + &pp->if_ad->addr); + if (!cie) + goto err; + cie->prefix_length = + 8 * sockunion_get_addrlen( + &pp->if_ad->addr); + + cie->mtu = htons(pp->if_ad->mtu); + nhrp_ext_complete(zb, ext); + } break; default: if (nhrp_ext_reply(zb, hdr, ifp, ext, &payload) < 0) @@ -486,7 +615,6 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp) break; } } - nhrp_packet_complete(zb, hdr); nhrp_peer_send(peer, zb); err: @@ -559,7 +687,11 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p) : &cie_nbma; nbma_natoa = NULL; if (natted) { - nbma_natoa = nbma_addr; + nbma_natoa = + (sockunion_family(&p->peer->vc->remote.nbma) + == AF_UNSPEC) + ? nbma_addr + : &p->peer->vc->remote.nbma; } holdtime = htons(cie->holding_time); @@ -574,7 +706,8 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p) if (!nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC, holdtime, nhrp_peer_ref(p->peer), - htons(cie->mtu), nbma_natoa)) { + htons(cie->mtu), nbma_natoa, + nbma_addr)) { cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED; continue; } @@ -592,9 +725,13 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p) goto err; zbuf_copy(zb, &payload, zbuf_used(&payload)); if (natted) { - nhrp_cie_push(zb, NHRP_CODE_SUCCESS, - &p->peer->vc->remote.nbma, - &p->src_proto); + cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, + &p->peer->vc->remote.nbma, + &p->src_proto); + cie->prefix_length = + 8 * sockunion_get_addrlen( + &p->if_ad->addr); + cie->mtu = htons(p->if_ad->mtu); } nhrp_ext_complete(zb, ext); break; @@ -794,20 +931,23 @@ static struct { static void nhrp_peer_forward(struct nhrp_peer *p, struct nhrp_packet_parser *pp) { - struct zbuf *zb, extpl; + struct zbuf *zb, *zb_copy, extpl; struct nhrp_packet_header *hdr; struct nhrp_extension_header *ext, *dst; struct nhrp_cie_header *cie; struct nhrp_interface *nifp = pp->ifp->info; struct nhrp_afi_data *if_ad = pp->if_ad; - union sockunion cie_nbma, cie_protocol; + union sockunion cie_nbma, cie_protocol, cie_protocol_mandatory, *proto; uint16_t type, len; + struct nhrp_cache *c; if (pp->hdr->hop_count == 0) return; /* Create forward packet - copy header */ zb = zbuf_alloc(1500); + zb_copy = zbuf_alloc(1500); + hdr = nhrp_packet_push(zb, pp->hdr->type, &pp->src_nbma, &pp->src_proto, &pp->dst_proto); hdr->flags = pp->hdr->flags; @@ -815,8 +955,13 @@ static void nhrp_peer_forward(struct nhrp_peer *p, hdr->u.request_id = pp->hdr->u.request_id; /* Copy payload */ + zbuf_copy_peek(zb_copy, &pp->payload, zbuf_used(&pp->payload)); zbuf_copy(zb, &pp->payload, zbuf_used(&pp->payload)); + /* Get CIE Extension from Mandatory part */ + sockunion_family(&cie_protocol_mandatory) = AF_UNSPEC; + nhrp_cie_pull(zb_copy, pp->hdr, &cie_nbma, &cie_protocol_mandatory); + /* Copy extensions */ while ((ext = nhrp_ext_pull(&pp->extensions, &extpl)) != NULL) { type = htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY; @@ -848,19 +993,82 @@ static void nhrp_peer_forward(struct nhrp_peer *p, &nifp->nbma, &if_ad->addr); if (!cie) goto err; + cie->mtu = htons(if_ad->mtu); cie->holding_time = htons(if_ad->holdtime); } break; + case NHRP_EXTENSION_NAT_ADDRESS: + c = NULL; + proto = NULL; + + /* If NAT extension is empty then attempt to populate + * it with cached NBMA information + */ + if (len == 0) { + if (packet_types[hdr->type].type + == PACKET_REQUEST) { + debugf(NHRP_DEBUG_COMMON, + "Processing NHRP_EXTENSION_NAT_ADDRESS while forwarding the request packet"); + proto = &pp->src_proto; + } else if (packet_types[hdr->type].type + == PACKET_REPLY) { + debugf(NHRP_DEBUG_COMMON, + "Processing NHRP_EXTENSION_NAT_ADDRESS while forwarding the reply packet"); + /* For reply packet use protocol + * specified in CIE of mandatory part + * for cache lookup + */ + if (sockunion_family( + &cie_protocol_mandatory) + != AF_UNSPEC) + proto = &cie_protocol_mandatory; + } + } + + if (proto) { + debugf(NHRP_DEBUG_COMMON, "Proto is %pSU", + proto); + c = nhrp_cache_get(nifp->ifp, proto, 0); + } + + if (c) { + debugf(NHRP_DEBUG_COMMON, + "c->cur.remote_nbma_natoa is %pSU", + &c->cur.remote_nbma_natoa); + if (sockunion_family(&c->cur.remote_nbma_natoa) + != AF_UNSPEC) { + cie = nhrp_cie_push( + zb, + NHRP_CODE_SUCCESS, + &c->cur.remote_nbma_natoa, + proto); + if (!cie) + goto err; + } + } else { + if (proto) + debugf(NHRP_DEBUG_COMMON, + "No cache entry for proto %pSU", + proto); + /* Copy existing NAT extension to new packet if + * either it was already not-empty, or we do not + * have valid cache information + */ + zbuf_put(zb, extpl.head, len); + } + break; default: if (htons(ext->type) & NHRP_EXTENSION_FLAG_COMPULSORY) /* FIXME: RFC says to just copy, but not - * append our selves to the transit NHS list */ + * append our selves to the transit NHS list + */ goto err; /* fallthru */ case NHRP_EXTENSION_RESPONDER_ADDRESS: /* Supported compulsory extensions, and any * non-compulsory that is not explicitly handled, - * should be just copied. */ + * should be just copied. + */ zbuf_copy(zb, &extpl, len); break; } @@ -870,10 +1078,12 @@ static void nhrp_peer_forward(struct nhrp_peer *p, nhrp_packet_complete(zb, hdr); nhrp_peer_send(p, zb); zbuf_free(zb); + zbuf_free(zb_copy); return; err: nhrp_packet_debug(pp->pkt, "FWD-FAIL"); zbuf_free(zb); + zbuf_free(zb_copy); } static void nhrp_packet_debug(struct zbuf *zb, const char *dir) diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 8ce19cd4a3..56861551ea 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -203,17 +203,18 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, void *arg) { struct nhrp_packet_parser *pp = arg; + struct interface *ifp = pp->ifp; + struct nhrp_interface *nifp = ifp->info; struct nhrp_shortcut *s = container_of(reqid, struct nhrp_shortcut, reqid); struct nhrp_shortcut *ps; struct nhrp_extension_header *ext; struct nhrp_cie_header *cie; struct nhrp_cache *c = NULL; - struct nhrp_cache *c_dst_proto = NULL; + struct nhrp_cache *c_dst = NULL; union sockunion *proto, cie_proto, *nbma, cie_nbma, nat_nbma; struct prefix prefix, route_prefix; struct zbuf extpl; - char buf[4][SU_ADDRSTRLEN]; int holding_time = pp->if_ad->holdtime; nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid); @@ -235,16 +236,6 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, return; } - /* Parse extensions */ - memset(&nat_nbma, 0, sizeof(nat_nbma)); - while ((ext = nhrp_ext_pull(&pp->extensions, &extpl)) != NULL) { - switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) { - case NHRP_EXTENSION_NAT_ADDRESS: - nhrp_cie_pull(&extpl, pp->hdr, &nat_nbma, &cie_proto); - break; - } - } - /* Minor sanity check */ prefix2sockunion(s->p, &cie_proto); if (!sockunion_same(&cie_proto, &pp->dst_proto)) { @@ -280,16 +271,58 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, prefix.prefixlen = route_prefix.prefixlen; } - debugf(NHRP_DEBUG_COMMON, - "Shortcut: %pFX is at proto %pSU dst_proto %pSU cie-nbma %pSU nat-nbma %pSU cie-holdtime %d", - &prefix, proto, &pp->dst_proto, &cie_nbma, &nat_nbma, - htons(cie->holding_time)); + /* Parse extensions */ + memset(&nat_nbma, 0, sizeof(nat_nbma)); + while ((ext = nhrp_ext_pull(&pp->extensions, &extpl)) != NULL) { + switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) { + case NHRP_EXTENSION_NAT_ADDRESS: { + struct nhrp_cie_header *cie_nat; + + do { + union sockunion cie_nat_proto, cie_nat_nbma; + + sockunion_family(&cie_nat_proto) = AF_UNSPEC; + sockunion_family(&cie_nat_nbma) = AF_UNSPEC; + cie_nat = nhrp_cie_pull(&extpl, pp->hdr, + &cie_nat_nbma, + &cie_nat_proto); + /* We are interested only in peer CIE */ + if (cie_nat + && sockunion_same(&cie_nat_proto, proto)) { + nat_nbma = cie_nat_nbma; + } + } while (cie_nat); + } break; + default: + break; + } + } /* Update cache entry for the protocol to nbma binding */ - if (sockunion_family(&nat_nbma) != AF_UNSPEC) + if (sockunion_family(&nat_nbma) != AF_UNSPEC) { + debugf(NHRP_DEBUG_COMMON, + "Shortcut: NAT detected (NAT extension) proto %pSU NBMA %pSU claimed-NBMA %pSU", + proto, &nat_nbma, &cie_nbma); nbma = &nat_nbma; - else + } + /* For NHRP resolution reply the cie_nbma in mandatory part is the + * address of the actual address of the sender + */ + else if (!sockunion_same(&cie_nbma, &pp->peer->vc->remote.nbma) + && !nhrp_nhs_match_ip(&pp->peer->vc->remote.nbma, nifp)) { + debugf(NHRP_DEBUG_COMMON, + "Shortcut: NAT detected (no NAT Extension) proto %pSU NBMA %pSU claimed-NBMA %pSU", + proto, &pp->peer->vc->remote.nbma, &cie_nbma); + nbma = &pp->peer->vc->remote.nbma; + nat_nbma = *nbma; + } else { nbma = &cie_nbma; + } + + debugf(NHRP_DEBUG_COMMON, + "Shortcut: %pFX is at proto %pSU dst_proto %pSU NBMA %pSU cie-holdtime %d", + &prefix, proto, &pp->dst_proto, nbma, + htons(cie->holding_time)); if (sockunion_family(nbma)) { c = nhrp_cache_get(pp->ifp, proto, 1); @@ -299,25 +332,31 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC, holding_time, nhrp_peer_get(pp->ifp, nbma), - htons(cie->mtu), nbma); + htons(cie->mtu), + nbma, + &cie_nbma); } else { debugf(NHRP_DEBUG_COMMON, - "Shortcut: no cache for nbma %s", buf[2]); + "Shortcut: no cache for proto %pSU", proto); } /* Update cache binding for dst_proto as well */ - if (proto != &pp->dst_proto) { - c_dst_proto = nhrp_cache_get(pp->ifp, &pp->dst_proto, 1); - if (c_dst_proto) { + if (sockunion_cmp(proto, &pp->dst_proto)) { + c_dst = nhrp_cache_get(pp->ifp, &pp->dst_proto, 1); + if (c_dst) { debugf(NHRP_DEBUG_COMMON, - "Shortcut: cache found, update binding"); - nhrp_cache_update_binding(c_dst_proto, NHRP_CACHE_DYNAMIC, + "Shortcut: cache found, update binding"); + nhrp_cache_update_binding(c_dst, + NHRP_CACHE_DYNAMIC, holding_time, nhrp_peer_get(pp->ifp, nbma), - htons(cie->mtu), nbma); + htons(cie->mtu), + nbma, + &cie_nbma); } else { debugf(NHRP_DEBUG_COMMON, - "Shortcut: no cache for nbma %s", buf[2]); + "Shortcut: no cache for proto %pSU", + &pp->dst_proto); } } } @@ -356,6 +395,7 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s) struct nhrp_afi_data *if_ad; struct nhrp_peer *peer; struct nhrp_cie_header *cie; + struct nhrp_extension_header *ext; if (nhrp_route_address(NULL, &s->addr, NULL, &peer) != NHRP_ROUTE_NBMA_NEXTHOP) @@ -399,7 +439,14 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s) /* Cisco NAT detection extension */ hdr->flags |= htons(NHRP_FLAG_RESOLUTION_NAT); - nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS); + ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS); + if (sockunion_family(&nifp->nat_nbma) != AF_UNSPEC) { + cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &nifp->nat_nbma, + &if_ad->addr); + cie->prefix_length = 8 * sockunion_get_addrlen(&if_ad->addr); + cie->mtu = htons(if_ad->mtu); + nhrp_ext_complete(zb, ext); + } nhrp_packet_complete(zb, hdr); diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index 1ea4c5e64f..4358605e2b 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -525,11 +525,11 @@ DEFUN(if_nhrp_map, if_nhrp_map_cmd, c->map = 1; if (type == NHRP_CACHE_LOCAL) nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0, - NULL); + NULL, NULL); else nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0, nhrp_peer_get(ifp, &nbma_addr), 0, - NULL); + NULL, NULL); return CMD_SUCCESS; } @@ -565,7 +565,8 @@ DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd, return CMD_SUCCESS; nhrp_cache_update_binding(c, c->cur.type, -1, - nhrp_peer_get(ifp, &nbma_addr), 0, NULL); + nhrp_peer_get(ifp, &nbma_addr), 0, NULL, + NULL); return CMD_SUCCESS; } @@ -629,7 +630,7 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx) { struct info_ctx *ctx = pctx; struct vty *vty = ctx->vty; - char buf[2][SU_ADDRSTRLEN]; + char buf[3][SU_ADDRSTRLEN]; struct json_object *json = NULL; if (ctx->afi != family2afi(sockunion_family(&c->remote_addr))) @@ -637,17 +638,42 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx) if (!ctx->count && !ctx->json) { - vty_out(vty, "%-8s %-8s %-24s %-24s %-6s %s\n", "Iface", "Type", - "Protocol", "NBMA", "Flags", "Identity"); + vty_out(vty, "%-8s %-8s %-24s %-24s %-24s %-6s %s\n", "Iface", + "Type", "Protocol", "NBMA", "Claimed NBMA", "Flags", + "Identity"); } ctx->count++; sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])); - if (c->cur.peer) - sockunion2str(&c->cur.peer->vc->remote.nbma, - buf[1], sizeof(buf[1])); - else - snprintf(buf[1], sizeof(buf[1]), "-"); + if (c->cur.type == NHRP_CACHE_LOCAL) { + struct nhrp_interface *nifp = c->ifp->info; + + if (sockunion_family(&nifp->nbma) != AF_UNSPEC) { + sockunion2str(&nifp->nbma, buf[1], sizeof(buf[1])); + sockunion2str(&nifp->nbma, buf[2], sizeof(buf[2])); + } else { + snprintf(buf[1], sizeof(buf[1]), "-"); + snprintf(buf[2], sizeof(buf[2]), "-"); + } + + /* if we are behind NAT then update NBMA field */ + if (sockunion_family(&nifp->nat_nbma) != AF_UNSPEC) + sockunion2str(&nifp->nat_nbma, buf[1], sizeof(buf[1])); + } else { + if (c->cur.peer) + sockunion2str(&c->cur.peer->vc->remote.nbma, + buf[1], sizeof(buf[1])); + else + snprintf(buf[1], sizeof(buf[1]), "-"); + + if (c->cur.peer + && sockunion_family(&c->cur.remote_nbma_claimed) + != AF_UNSPEC) + sockunion2str(&c->cur.remote_nbma_claimed, + buf[2], sizeof(buf[2])); + else + snprintf(buf[2], sizeof(buf[2]), "-"); + } if (ctx->json) { json = json_object_new_object(); @@ -656,6 +682,7 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx) nhrp_cache_type_str[c->cur.type]); json_object_string_add(json, "protocol", buf[0]); json_object_string_add(json, "nbma", buf[1]); + json_object_string_add(json, "claimed_nbma", buf[2]); if (c->used) json_object_boolean_true_add(json, "used"); @@ -681,9 +708,10 @@ static void show_ip_nhrp_cache(struct nhrp_cache *c, void *pctx) json_object_array_add(ctx->json, json); return; } - vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %c%c%c %s\n", c->ifp->name, + vty_out(ctx->vty, "%-8s %-8s %-24s %-24s %-24s %c%c%c %s\n", + c->ifp->name, nhrp_cache_type_str[c->cur.type], - buf[0], buf[1], + buf[0], buf[1], buf[2], c->used ? 'U' : ' ', c->t_timeout ? 'T' : ' ', c->t_auth ? 'A' : ' ', c->cur.peer ? c->cur.peer->vc->remote.id : "-"); @@ -970,7 +998,8 @@ static void clear_nhrp_cache(struct nhrp_cache *c, void *data) { struct info_ctx *ctx = data; if (c->cur.type <= NHRP_CACHE_DYNAMIC) { - nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL); + nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL, + NULL); ctx->count++; } } diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h index 9c8c293b9e..e4afb22f80 100644 --- a/nhrpd/nhrpd.h +++ b/nhrpd/nhrpd.h @@ -156,6 +156,7 @@ struct nhrp_peer { struct nhrp_vc *vc; struct thread *t_fallback; struct notifier_block vc_notifier, ifp_notifier; + struct thread *t_timer; }; struct nhrp_packet_parser { @@ -225,9 +226,11 @@ struct nhrp_cache { struct { enum nhrp_cache_type type; union sockunion remote_nbma_natoa; + union sockunion remote_nbma_claimed; struct nhrp_peer *peer; time_t expires; uint32_t mtu; + int holding_time; } cur, new; }; @@ -383,7 +386,8 @@ void nhrp_cache_config_foreach(struct interface *ifp, void nhrp_cache_set_used(struct nhrp_cache *, int); int nhrp_cache_update_binding(struct nhrp_cache *, enum nhrp_cache_type type, int holding_time, struct nhrp_peer *p, - uint32_t mtu, union sockunion *nbma_natoa); + uint32_t mtu, union sockunion *nbma_natoa, + union sockunion *claimed_nbma); void nhrp_cache_notify_add(struct nhrp_cache *c, struct notifier_block *, notifier_fn_t); void nhrp_cache_notify_del(struct nhrp_cache *c, struct notifier_block *); @@ -465,4 +469,6 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb); void nhrp_peer_send(struct nhrp_peer *p, struct zbuf *zb); void nhrp_peer_send_indication(struct interface *ifp, uint16_t, struct zbuf *); +int nhrp_nhs_match_ip(union sockunion *in_ip, struct nhrp_interface *nifp); + #endif diff --git a/nhrpd/zbuf.c b/nhrpd/zbuf.c index a78d827ea5..a23526af48 100644 --- a/nhrpd/zbuf.c +++ b/nhrpd/zbuf.c @@ -230,3 +230,15 @@ void zbuf_copy(struct zbuf *zdst, struct zbuf *zsrc, size_t len) return; memcpy(dst, src, len); } + +void zbuf_copy_peek(struct zbuf *zdst, struct zbuf *zsrc, size_t len) +{ + const void *src; + void *dst; + + dst = zbuf_pushn(zdst, len); + src = zbuf_pulln(zsrc, 0); + if (!dst || !src) + return; + memcpy(dst, src, len); +} diff --git a/nhrpd/zbuf.h b/nhrpd/zbuf.h index e6f7101d63..d4a7c15a95 100644 --- a/nhrpd/zbuf.h +++ b/nhrpd/zbuf.h @@ -190,6 +190,7 @@ static inline void zbuf_put_be32(struct zbuf *zb, uint32_t val) } void zbuf_copy(struct zbuf *zb, struct zbuf *src, size_t len); +void zbuf_copy_peek(struct zbuf *zdst, struct zbuf *zsrc, size_t len); void zbufq_init(struct zbuf_queue *); void zbufq_reset(struct zbuf_queue *); diff --git a/ospf6d/ospf6d.conf.sample b/ospf6d/ospf6d.conf.sample deleted file mode 100644 index 0a6ddb7137..0000000000 --- a/ospf6d/ospf6d.conf.sample +++ /dev/null @@ -1,52 +0,0 @@ -! -! Zebra configuration saved from vty -! 2003/11/28 00:49:49 -! -hostname ospf6d@plant -password zebra -log stdout -service advanced-vty -! -debug ospf6 neighbor state -! -interface fxp0 - ipv6 ospf6 cost 1 - ipv6 ospf6 hello-interval 10 - ipv6 ospf6 dead-interval 40 - ipv6 ospf6 retransmit-interval 5 - ipv6 ospf6 priority 0 - ipv6 ospf6 transmit-delay 1 - ipv6 ospf6 instance-id 0 -! -interface lo0 - ipv6 ospf6 cost 1 - ipv6 ospf6 hello-interval 10 - ipv6 ospf6 dead-interval 40 - ipv6 ospf6 retransmit-interval 5 - ipv6 ospf6 priority 1 - ipv6 ospf6 transmit-delay 1 - ipv6 ospf6 instance-id 0 -! -router ospf6 - router-id 255.1.1.1 - redistribute static route-map static-ospf6 - interface fxp0 area 0.0.0.0 -! -access-list access4 permit 127.0.0.1/32 -! -ipv6 access-list access6 permit 3ffe:501::/32 -ipv6 access-list access6 permit 2001:200::/48 -ipv6 access-list access6 permit ::1/128 -! -ipv6 prefix-list test-prefix seq 1000 deny any -! -route-map static-ospf6 permit 10 - match ipv6 address prefix-list test-prefix - set metric-type type-2 - set metric 2000 -! -line vty - access-class access4 - ipv6 access-class access6 - exec-timeout 0 0 -! diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index 788b532a90..5ccae5b279 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -5,7 +5,6 @@ if OSPF6D noinst_LIBRARIES += ospf6d/libospf6.a sbin_PROGRAMS += ospf6d/ospf6d -dist_examples_DATA += ospf6d/ospf6d.conf.sample vtysh_scan += \ ospf6d/ospf6_abr.c \ ospf6d/ospf6_asbr.c \ diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 6829c4a347..6e4bc7abf1 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -694,6 +694,13 @@ static int ospf_if_delete_hook(struct interface *ifp) struct route_node *rn; rc = ospf_opaque_del_if(ifp); + /* + * This function must be called before `route_table_finish` due to + * BFD integration need to iterate over the interface neighbors to + * remove all registrations. + */ + ospf_del_if_params(ifp, IF_DEF_PARAMS(ifp)); + route_table_finish(IF_OIFS(ifp)); for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) @@ -701,7 +708,6 @@ static int ospf_if_delete_hook(struct interface *ifp) ospf_del_if_params(ifp, rn->info); route_table_finish(IF_OIFS_PARAMS(ifp)); - ospf_del_if_params(ifp, IF_DEF_PARAMS(ifp)); XFREE(MTYPE_OSPF_IF_INFO, ifp->info); return rc; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 791f9eb551..2d06e6884d 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -7865,10 +7865,9 @@ DEFUN (ip_ospf_message_digest_key, } key_id = strtol(keyid, NULL, 10); - if (ospf_crypt_key_lookup(params->auth_crypt, key_id) != NULL) { - vty_out(vty, "OSPF: Key %d already exists\n", key_id); - return CMD_WARNING; - } + + /* Remove existing key, if any */ + ospf_crypt_key_delete(params->auth_crypt, key_id); ck = ospf_crypt_key_new(); ck->key_id = (uint8_t)key_id; @@ -8968,9 +8967,12 @@ DEFUN (ip_ospf_area, // update/create address-level params params = ospf_get_if_params((ifp), (addr)); if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) { - vty_out(vty, - "Must remove previous area/address config before changing ospf area\n"); - return CMD_WARNING_CONFIG_FAILED; + if (!IPV4_ADDR_SAME(¶ms->if_area, &area_id)) { + vty_out(vty, + "Must remove previous area/address config before changing ospf area\n"); + return CMD_WARNING_CONFIG_FAILED; + } else + return CMD_SUCCESS; } ospf_if_update_params((ifp), (addr)); } diff --git a/ospfd/ospfd.conf.sample b/ospfd/ospfd.conf.sample deleted file mode 100644 index 0e8ac67bba..0000000000 --- a/ospfd/ospfd.conf.sample +++ /dev/null @@ -1,13 +0,0 @@ -! -*- ospf -*- -! -! OSPFd sample configuration file -! -! -hostname ospfd -password zebra -!enable password please-set-at-here -! -!router ospf -! network 192.168.1.0/24 area 0 -! -log stdout diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 63610e38d8..f592a9eec8 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -5,7 +5,6 @@ if OSPFD noinst_LIBRARIES += ospfd/libfrrospf.a sbin_PROGRAMS += ospfd/ospfd -dist_examples_DATA += ospfd/ospfd.conf.sample vtysh_scan += \ ospfd/ospf_bfd.c \ ospfd/ospf_dump.c \ diff --git a/pathd/path_pcep.h b/pathd/path_pcep.h index 654d089cbc..d0af674ff9 100644 --- a/pathd/path_pcep.h +++ b/pathd/path_pcep.h @@ -84,7 +84,7 @@ DECLARE_MTYPE(PCEP); struct pcep_config_group_opts { char name[64]; - char tcp_md5_auth[TCP_MD5SIG_MAXKEYLEN]; + char tcp_md5_auth[PCEP_MD5SIG_MAXKEYLEN]; struct ipaddr source_ip; short source_port; bool draft07; diff --git a/pathd/pathd.conf.sample b/pathd/pathd.conf.sample deleted file mode 100644 index 9fe7d2d6e3..0000000000 --- a/pathd/pathd.conf.sample +++ /dev/null @@ -1,41 +0,0 @@ -! Default pathd configuration sample -! -password frr -log stdout - -segment-routing - traffic-eng - segment-list test1 - index 10 mpls label 123 - index 20 mpls label 456 - ! - segment-list test2 - index 10 mpls label 321 - index 20 mpls label 654 - ! - policy color 1 endpoint 1.1.1.1 - name one - binding-sid 100 - candidate-path preference 100 name test1 explicit segment-list test1 - candidate-path preference 200 name test2 explicit segment-list test2 - ! - policy color 2 endpoint 2.2.2.2 - name two - binding-sid 101 - candidate-path preference 100 name def explicit segment-list test2 - candidate-path preference 200 name dyn dynamic - bandwidth 12345 - metric bound abc 16 required - metric te 10 - ! - ! - pcep - pcc-peer PCE1 - address ip 127.0.0.1 - sr-draft07 - ! - pcc - peer PCE1 - ! - ! -! diff --git a/pathd/subdir.am b/pathd/subdir.am index b4501214bf..38df326489 100644 --- a/pathd/subdir.am +++ b/pathd/subdir.am @@ -5,7 +5,6 @@ if PATHD noinst_LIBRARIES += pathd/libpath.a sbin_PROGRAMS += pathd/pathd -dist_examples_DATA += pathd/pathd.conf.sample vtysh_scan += $(top_srcdir)/pathd/path_cli.c vtysh_daemons += pathd # TODO add man page @@ -22,7 +21,6 @@ pathd_libpath_a_SOURCES = \ pathd/path_cli.c \ pathd/path_debug.c \ pathd/path_errors.c \ - pathd/path_main.c \ pathd/path_nb.c \ pathd/path_nb_config.c \ pathd/path_nb_state.c \ @@ -50,7 +48,9 @@ noinst_HEADERS += \ pathd/pathd.h \ # end -pathd_pathd_SOURCES = pathd/path_main.c +pathd_pathd_SOURCES = \ + pathd/path_main.c \ + # end nodist_pathd_pathd_SOURCES = \ yang/frr-pathd.yang.c \ # end diff --git a/pbrd/pbrd.conf.sample b/pbrd/pbrd.conf.sample deleted file mode 100644 index c9e7dce01f..0000000000 --- a/pbrd/pbrd.conf.sample +++ /dev/null @@ -1,19 +0,0 @@ -! Sample pbrd configuration file -! -! A quick example of what a pbr configuration might look like -! -! -log stdout -! -! nexthop-group TEST -! nexthop 4.5.6.7 -! nexthop 5.6.7.8 -! ! -! pbr-map BLUE seq 100 -! match dst-ip 9.9.9.0/24 -! match src-ip 10.10.10.0/24 -! set nexthop-group TEST -! ! -! int swp1 -! pbr-policy BLUE -! diff --git a/pbrd/subdir.am b/pbrd/subdir.am index 7ad071af3b..bbe3f2ab71 100644 --- a/pbrd/subdir.am +++ b/pbrd/subdir.am @@ -5,7 +5,6 @@ if PBRD noinst_LIBRARIES += pbrd/libpbr.a sbin_PROGRAMS += pbrd/pbrd -dist_examples_DATA += pbrd/pbrd.conf.sample vtysh_scan += \ pbrd/pbr_vty.c \ pbrd/pbr_debug.c \ diff --git a/pceplib/pcep.h b/pceplib/pcep.h index 278ab9d5dc..b5d02c7e62 100644 --- a/pceplib/pcep.h +++ b/pceplib/pcep.h @@ -28,12 +28,10 @@ #endif #if defined(linux) || defined(GNU_LINUX) -//#include <netinet/in.h> + #define ipv6_u __in6_u #else -// bsd family -#define TCP_MD5SIG_MAXKEYLEN 80 -//#include <netinet/in.h> +/* bsd family */ #define ipv6_u __u6_addr #ifdef __FreeBSD__ #include <sys/endian.h> @@ -45,4 +43,12 @@ #include <sys/socket.h> #include <netinet/in.h> #include <pthread.h> + +/* Cross-compilation seems to have trouble finding this */ +#if defined(TCP_MD5SIG_MAXKEYLEN) +#define PCEP_MD5SIG_MAXKEYLEN TCP_MD5SIG_MAXKEYLEN +#else +#define PCEP_MD5SIG_MAXKEYLEN 80 +#endif + #endif diff --git a/pceplib/pcep_msg_tlvs_encoding.c b/pceplib/pcep_msg_tlvs_encoding.c index 967f138143..37f3353f76 100644 --- a/pceplib/pcep_msg_tlvs_encoding.c +++ b/pceplib/pcep_msg_tlvs_encoding.c @@ -25,6 +25,15 @@ * Encoding and decoding for PCEP Object TLVs. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __FreeBSD__ +#include <sys/endian.h> +#else +#include <endian.h> +#endif /* __FreeBSD__ */ #include <stdlib.h> #include <string.h> diff --git a/pceplib/pcep_pcc.c b/pceplib/pcep_pcc.c index 1a702a8b63..d263f64f39 100644 --- a/pceplib/pcep_pcc.c +++ b/pceplib/pcep_pcc.c @@ -53,7 +53,7 @@ struct cmd_line_args { char dest_ip_str[MAX_DST_IP_STR]; short src_tcp_port; short dest_tcp_port; - char tcp_md5_str[TCP_MD5SIG_MAXKEYLEN]; /* RFC 2385 */ + char tcp_md5_str[PCEP_MD5SIG_MAXKEYLEN]; /* RFC 2385 */ bool is_ipv6; bool eventpoll; /* poll for pcep_event's, or use callback (default) */ }; diff --git a/pceplib/pcep_session_logic.h b/pceplib/pcep_session_logic.h index a082ec66da..9cdec5250f 100644 --- a/pceplib/pcep_session_logic.h +++ b/pceplib/pcep_session_logic.h @@ -122,7 +122,7 @@ typedef struct pcep_configuration_ { struct pcep_versioning *pcep_msg_versioning; - char tcp_authentication_str[TCP_MD5SIG_MAXKEYLEN]; + char tcp_authentication_str[PCEP_MD5SIG_MAXKEYLEN]; bool is_tcp_auth_md5; /* true: RFC 2385, false: RFC 5925 */ } pcep_configuration; diff --git a/pceplib/pcep_socket_comm.h b/pceplib/pcep_socket_comm.h index 797ffda860..89d2492914 100644 --- a/pceplib/pcep_socket_comm.h +++ b/pceplib/pcep_socket_comm.h @@ -91,9 +91,9 @@ typedef struct pcep_socket_comm_session_ { int received_bytes; bool close_after_write; void *external_socket_data; /* used for external socket infra */ - char tcp_authentication_str[TCP_MD5SIG_MAXKEYLEN - + 1]; /* should be used with is_tcp_auth_md5 - flag */ + /* should be used with is_tcp_auth_md5 flag */ + char tcp_authentication_str[PCEP_MD5SIG_MAXKEYLEN + 1]; + bool is_tcp_auth_md5; /* flag to distinguish between rfc 2385 (md5) and rfc 5925 (tcp-ao) */ diff --git a/pceplib/test/pcep_msg_tlvs_test.c b/pceplib/test/pcep_msg_tlvs_test.c index 6b650f6823..57e1d16e91 100644 --- a/pceplib/test/pcep_msg_tlvs_test.c +++ b/pceplib/test/pcep_msg_tlvs_test.c @@ -21,6 +21,15 @@ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __FreeBSD__ +#include <sys/endian.h> +#else +#include <endian.h> +#endif /* __FreeBSD__ */ #include <stdlib.h> #include <CUnit/CUnit.h> diff --git a/pimd/pimd.conf.sample b/pimd/pimd.conf.sample deleted file mode 100644 index de1da6b838..0000000000 --- a/pimd/pimd.conf.sample +++ /dev/null @@ -1,40 +0,0 @@ -! -! pimd sample configuration file -! -hostname quagga-pimd-router -password zebra -!enable password zebra -! -!log file pimd.log -log stdout -! -line vty - exec-timeout 60 -! -!debug igmp -!debug pim -!debug pim zebra -! -ip multicast-routing -! -! ! You may want to enable ssmpingd for troubleshooting -! ! See http://www.venaas.no/multicast/ssmping/ -! ! -! ip ssmpingd 1.1.1.1 -! ip ssmpingd 2.2.2.2 -! -! ! HINTS: -! ! - Enable "ip pim ssm" on the interface directly attached to the -! ! multicast source host (if this is the first-hop router) -! ! - Enable "ip pim ssm" on pim-routers-facing interfaces -! ! - Enable "ip igmp" on IGMPv3-hosts-facing interfaces -! ! - In order to inject IGMPv3 local membership information in the -! ! PIM protocol state, enable both "ip pim ssm" and "ip igmp" on -! ! the same interface; otherwise PIM won't advertise -! ! IGMPv3-learned membership to other PIM routers -! -interface eth0 - ip pim ssm - ip igmp - -! -x- diff --git a/pimd/subdir.am b/pimd/subdir.am index 717f4782f8..9910642ffa 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -7,7 +7,6 @@ noinst_LIBRARIES += pimd/libpim.a sbin_PROGRAMS += pimd/pimd bin_PROGRAMS += pimd/mtracebis noinst_PROGRAMS += pimd/test_igmpv3_join -dist_examples_DATA += pimd/pimd.conf.sample vtysh_scan += pimd/pim_cmd.c vtysh_daemons += pimd man8 += $(MANBUILD)/frr-pimd.8 diff --git a/python/clippy/elf.py b/python/clippy/elf.py index 4ed334f0c4..02cb2e38b3 100644 --- a/python/clippy/elf.py +++ b/python/clippy/elf.py @@ -162,7 +162,10 @@ class ELFDissectData(object): for field in parent._efields[self.elfclass]: if field[0] == fieldname: break - offset += struct.calcsize(field[1]) + spec = field[1] + if spec == 'P': + spec = 'I' if self.elfclass == 32 else 'Q' + offset += struct.calcsize(spec) else: raise AttributeError('%r not found in %r.fields' % (fieldname, parent)) diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index b6d7ab2416..47c6ad41af 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -456,6 +456,7 @@ ln -s %{_sbindir}/frrinit.sh %{buildroot}%{_initddir}/frr %endif install %{zeb_src}/tools/etc/frr/daemons %{buildroot}%{_sysconfdir}/frr +install %{zeb_src}/tools/etc/frr/frr.conf %{buildroot}%{_sysconfdir}/frr install -m644 %{zeb_rh_src}/frr.pam %{buildroot}%{_sysconfdir}/pam.d/frr install -m644 %{zeb_rh_src}/frr.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/frr install -d -m750 %{buildroot}%{rundir} @@ -641,7 +642,7 @@ fi %files -%doc */*.sample* COPYING +%doc COPYING %doc doc/mpls %doc README.md /usr/share/yang/*.yang @@ -654,9 +655,6 @@ fi %dir %attr(750,root,root) %{_localstatedir}/log/frr %dir %attr(750,root,root) %{rundir} %endif -%if 0%{?vty_group:1} - %attr(750,%{frr_user},%{vty_group}) %{configdir}/vtysh.conf.sample -%endif %{_infodir}/frr.info.gz %{_mandir}/man*/* %{_sbindir}/zebra diff --git a/ripd/ripd.conf.sample b/ripd/ripd.conf.sample deleted file mode 100644 index e11bf0bb23..0000000000 --- a/ripd/ripd.conf.sample +++ /dev/null @@ -1,22 +0,0 @@ -! -*- rip -*- -! -! RIPd sample configuration file -! -hostname ripd -password zebra -! -! debug rip events -! debug rip packet -! -router rip -! network 11.0.0.0/8 -! network eth0 -! route 10.0.0.0/8 -! distribute-list private-only in eth0 -! -!access-list private-only permit 10.0.0.0/8 -!access-list private-only deny any -! -!log file ripd.log -! -log stdout diff --git a/ripd/subdir.am b/ripd/subdir.am index 09d5590329..99979bff0d 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -5,7 +5,6 @@ if RIPD noinst_LIBRARIES += ripd/librip.a sbin_PROGRAMS += ripd/ripd -dist_examples_DATA += ripd/ripd.conf.sample vtysh_scan += \ ripd/rip_cli.c \ ripd/rip_debug.c \ diff --git a/ripngd/ripng_peer.c b/ripngd/ripng_peer.c index 479fcaeb54..554b1d68f6 100644 --- a/ripngd/ripng_peer.c +++ b/ripngd/ripng_peer.c @@ -163,8 +163,8 @@ void ripng_peer_display(struct vty *vty, struct ripng *ripng) char timebuf[RIPNG_UPTIME_LEN]; for (ALL_LIST_ELEMENTS(ripng->peer_list, node, nnode, peer)) { - vty_out(vty, " %s \n%14s %10d %10d %10d %s\n", - inet6_ntoa(peer->addr), " ", peer->recv_badpackets, + vty_out(vty, " %pI6 \n%14s %10d %10d %10d %s\n", + &peer->addr, " ", peer->recv_badpackets, peer->recv_badroutes, ZEBRA_RIPNG_DISTANCE_DEFAULT, ripng_peer_uptime(peer, timebuf, RIPNG_UPTIME_LEN)); } diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 749feaca6c..0e83140149 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -191,7 +191,7 @@ int ripng_send_packet(caddr_t buf, int bufsize, struct sockaddr_in6 *to, if (IS_RIPNG_DEBUG_SEND) { if (to) - zlog_debug("send to %s", inet6_ntoa(to->sin6_addr)); + zlog_debug("send to %pI6", &to->sin6_addr); zlog_debug(" send interface %s", ifp->name); zlog_debug(" send packet size %d", bufsize); } @@ -237,8 +237,8 @@ int ripng_send_packet(caddr_t buf, int bufsize, struct sockaddr_in6 *to, if (ret < 0) { if (to) flog_err_sys(EC_LIB_SOCKET, - "RIPng send fail on %s to %s: %s", - ifp->name, inet6_ntoa(to->sin6_addr), + "RIPng send fail on %s to %pI6: %s", + ifp->name, &to->sin6_addr, safe_strerror(errno)); else flog_err_sys(EC_LIB_SOCKET, "RIPng send fail on %s: %s", @@ -338,11 +338,11 @@ void ripng_packet_dump(struct ripng_packet *packet, int size, for (lim = (caddr_t)packet + size; (caddr_t)rte < lim; rte++) { if (rte->metric == RIPNG_METRIC_NEXTHOP) - zlog_debug(" nexthop %s/%d", inet6_ntoa(rte->addr), + zlog_debug(" nexthop %pI6/%d", &rte->addr, rte->prefixlen); else - zlog_debug(" %s/%d metric %d tag %" ROUTE_TAG_PRI, - inet6_ntoa(rte->addr), rte->prefixlen, + zlog_debug(" %pI6/%d metric %d tag %" ROUTE_TAG_PRI, + &rte->addr, rte->prefixlen, rte->metric, (route_tag_t)ntohs(rte->tag)); } } @@ -353,9 +353,9 @@ static void ripng_nexthop_rte(struct rte *rte, struct sockaddr_in6 *from, { /* Logging before checking RTE. */ if (IS_RIPNG_DEBUG_RECV) - zlog_debug("RIPng nexthop RTE address %s tag %" ROUTE_TAG_PRI + zlog_debug("RIPng nexthop RTE address %pI6 tag %" ROUTE_TAG_PRI " prefixlen %d", - inet6_ntoa(rte->addr), (route_tag_t)ntohs(rte->tag), + &rte->addr, (route_tag_t)ntohs(rte->tag), rte->prefixlen); /* RFC2080 2.1.1 Next Hop: @@ -364,14 +364,13 @@ static void ripng_nexthop_rte(struct rte *rte, struct sockaddr_in6 *from, if (ntohs(rte->tag) != 0) zlog_warn( "RIPng nexthop RTE with non zero tag value %" ROUTE_TAG_PRI - " from %s", - (route_tag_t)ntohs(rte->tag), - inet6_ntoa(from->sin6_addr)); + " from %pI6", + (route_tag_t)ntohs(rte->tag), &from->sin6_addr); if (rte->prefixlen != 0) zlog_warn( - "RIPng nexthop RTE with non zero prefixlen value %d from %s", - rte->prefixlen, inet6_ntoa(from->sin6_addr)); + "RIPng nexthop RTE with non zero prefixlen value %d from %pI6", + rte->prefixlen, &from->sin6_addr); /* Specifying a value of 0:0:0:0:0:0:0:0 in the prefix field of a next hop RTE indicates that the next hop address should be the @@ -396,8 +395,8 @@ static void ripng_nexthop_rte(struct rte *rte, struct sockaddr_in6 *from, information is ignored, a possibly sub-optimal, but absolutely valid, route may be taken. If the received next hop address is not a link-local address, it should be treated as 0:0:0:0:0:0:0:0. */ - zlog_warn("RIPng nexthop RTE with non link-local address %s from %pI6", - inet6_ntoa(rte->addr), &from->sin6_addr); + zlog_warn("RIPng nexthop RTE with non link-local address %pI6 from %pI6", + &rte->addr, &from->sin6_addr); nexthop->flag = RIPNG_NEXTHOP_UNSPEC; memset(&nexthop->address, 0, sizeof(struct in6_addr)); @@ -750,8 +749,8 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from, if (ret == RMAP_DENYMATCH) { if (IS_RIPNG_DEBUG_PACKET) zlog_debug( - "RIPng %s/%d is filtered by route-map in", - inet6_ntoa(p.prefix), p.prefixlen); + "RIPng %pFX is filtered by route-map in", + &p); return; } @@ -993,8 +992,8 @@ void ripng_redistribute_add(struct ripng *ripng, int type, int sub_type, p, ifindex2ifname(ifindex, ripng->vrf->vrf_id)); else zlog_debug( - "Redistribute new prefix %pFX with nexthop %s on the interface %s", - p, inet6_ntoa(*nexthop), + "Redistribute new prefix %pFX with nexthop %pI6 on the interface %s", + p, nexthop, ifindex2ifname(ifindex, ripng->vrf->vrf_id)); } @@ -1106,8 +1105,8 @@ static void ripng_response_process(struct ripng_packet *packet, int size, /* RFC2080 2.4.2 Response Messages: The Response must be ignored if it is not from the RIPng port. */ if (ntohs(from->sin6_port) != RIPNG_PORT_DEFAULT) { - zlog_warn("RIPng packet comes from non RIPng port %d from %s", - ntohs(from->sin6_port), inet6_ntoa(from->sin6_addr)); + zlog_warn("RIPng packet comes from non RIPng port %d from %pI6", + ntohs(from->sin6_port), &from->sin6_addr); ripng_peer_bad_packet(ripng, from); return; } @@ -1116,8 +1115,8 @@ static void ripng_response_process(struct ripng_packet *packet, int size, whether the datagram is from a valid neighbor; the source of the datagram must be a link-local address. */ if (!IN6_IS_ADDR_LINKLOCAL(&from->sin6_addr)) { - zlog_warn("RIPng packet comes from non link local address %s", - inet6_ntoa(from->sin6_addr)); + zlog_warn("RIPng packet comes from non link local address %pI6", + &from->sin6_addr); ripng_peer_bad_packet(ripng, from); return; } @@ -1129,8 +1128,8 @@ static void ripng_response_process(struct ripng_packet *packet, int size, and such datagrams must be ignored. */ if (ripng_lladdr_check(ifp, &from->sin6_addr)) { zlog_warn( - "RIPng packet comes from my own link local address %s", - inet6_ntoa(from->sin6_addr)); + "RIPng packet comes from my own link local address %pI6", + &from->sin6_addr); ripng_peer_bad_packet(ripng, from); return; } @@ -1141,8 +1140,8 @@ static void ripng_response_process(struct ripng_packet *packet, int size, packets) must be examined to ensure that the hop count is 255. */ if (hoplimit >= 0 && hoplimit != 255) { zlog_warn( - "RIPng packet comes with non 255 hop count %d from %s", - hoplimit, inet6_ntoa(from->sin6_addr)); + "RIPng packet comes with non 255 hop count %d from %pI6", + hoplimit, &from->sin6_addr); ripng_peer_bad_packet(ripng, from); return; } @@ -1173,25 +1172,22 @@ static void ripng_response_process(struct ripng_packet *packet, int size, should never be present in an RTE. */ if (IN6_IS_ADDR_MULTICAST(&rte->addr)) { zlog_warn( - "Destination prefix is a multicast address %s/%d [%d]", - inet6_ntoa(rte->addr), rte->prefixlen, - rte->metric); + "Destination prefix is a multicast address %pI6/%d [%d]", + &rte->addr, rte->prefixlen, rte->metric); ripng_peer_bad_route(ripng, from); continue; } if (IN6_IS_ADDR_LINKLOCAL(&rte->addr)) { zlog_warn( - "Destination prefix is a link-local address %s/%d [%d]", - inet6_ntoa(rte->addr), rte->prefixlen, - rte->metric); + "Destination prefix is a link-local address %pI6/%d [%d]", + &rte->addr, rte->prefixlen, rte->metric); ripng_peer_bad_route(ripng, from); continue; } if (IN6_IS_ADDR_LOOPBACK(&rte->addr)) { zlog_warn( - "Destination prefix is a loopback address %s/%d [%d]", - inet6_ntoa(rte->addr), rte->prefixlen, - rte->metric); + "Destination prefix is a loopback address %pI6/%d [%d]", + &rte->addr, rte->prefixlen, rte->metric); ripng_peer_bad_route(ripng, from); continue; } @@ -1199,17 +1195,17 @@ static void ripng_response_process(struct ripng_packet *packet, int size, /* - is the prefix length valid (i.e., between 0 and 128, inclusive) */ if (rte->prefixlen > 128) { - zlog_warn("Invalid prefix length %s/%d from %s%%%s", - inet6_ntoa(rte->addr), rte->prefixlen, - inet6_ntoa(from->sin6_addr), ifp->name); + zlog_warn("Invalid prefix length %pI6/%d from %pI6%%%s", + &rte->addr, rte->prefixlen, + &from->sin6_addr, ifp->name); ripng_peer_bad_route(ripng, from); continue; } /* - is the metric valid (i.e., between 1 and 16, inclusive) */ if (!(rte->metric >= 1 && rte->metric <= 16)) { - zlog_warn("Invalid metric %d from %s%%%s", rte->metric, - inet6_ntoa(from->sin6_addr), ifp->name); + zlog_warn("Invalid metric %d from %pI6%%%s", + rte->metric, &from->sin6_addr, ifp->name); ripng_peer_bad_route(ripng, from); continue; } @@ -1342,8 +1338,8 @@ static int ripng_read(struct thread *thread) /* Check RTE boundary. RTE size (Packet length - RIPng header size (4)) must be multiple size of one RTE size (20). */ if (((len - 4) % 20) != 0) { - zlog_warn("RIPng invalid packet size %d from %s (VRF %s)", len, - inet6_ntoa(from.sin6_addr), ripng->vrf_name); + zlog_warn("RIPng invalid packet size %d from %pI6 (VRF %s)", + len, &from.sin6_addr, ripng->vrf_name); ripng_peer_bad_packet(ripng, &from); return 0; } @@ -1354,8 +1350,8 @@ static int ripng_read(struct thread *thread) /* RIPng packet received. */ if (IS_RIPNG_DEBUG_EVENT) zlog_debug( - "RIPng packet received from %s port %d on %s (VRF %s)", - inet6_ntoa(from.sin6_addr), ntohs(from.sin6_port), + "RIPng packet received from %pI6 port %d on %s (VRF %s)", + &from.sin6_addr, ntohs(from.sin6_port), ifp ? ifp->name : "unknown", ripng->vrf_name); /* Logging before packet checking. */ @@ -1581,8 +1577,8 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to, if (IS_RIPNG_DEBUG_EVENT) { if (to) - zlog_debug("RIPng update routes to neighbor %s", - inet6_ntoa(to->sin6_addr)); + zlog_debug("RIPng update routes to neighbor %pI6", + &to->sin6_addr); else zlog_debug("RIPng update routes on interface %s", ifp->name); @@ -2089,8 +2085,8 @@ DEFUN (show_ipv6_ripng, #endif /* DEBUG */ vty_out(vty, "\n"); vty_out(vty, "%*s", 18, " "); - len = vty_out(vty, "%s", - inet6_ntoa(rinfo->nexthop)); + len = vty_out(vty, "%pI6", + &rinfo->nexthop); len = 28 - len; if (len > 0) diff --git a/ripngd/ripngd.conf.sample b/ripngd/ripngd.conf.sample deleted file mode 100644 index 28f08c399a..0000000000 --- a/ripngd/ripngd.conf.sample +++ /dev/null @@ -1,20 +0,0 @@ -! -*- rip -*- -! -! RIPngd sample configuration file -! -hostname ripngd -password zebra -! -! debug ripng events -! debug ripng packet -! -! -router ripng -! network sit1 -! route 3ffe:506::0/32 -! distribute-list local-only out sit1 -! -!ipv6 access-list local-only permit 3ffe:506::0/32 -!ipv6 access-list local-only deny any -! -log stdout diff --git a/ripngd/subdir.am b/ripngd/subdir.am index 8d370f1b5d..9d8d27d4cc 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -50,5 +50,3 @@ ripngd_ripngd_SOURCES = \ nodist_ripngd_ripngd_SOURCES = \ yang/frr-ripngd.yang.c \ # end - -dist_examples_DATA += ripngd/ripngd.conf.sample diff --git a/sharpd/sharpd.conf.sample b/sharpd/sharpd.conf.sample deleted file mode 100644 index d1cc19a51f..0000000000 --- a/sharpd/sharpd.conf.sample +++ /dev/null @@ -1,6 +0,0 @@ -! Default sharpd configuration sample -! -! There are no `default` configuration commands for sharpd -! all commands are at the view or enable level. -! -log stdout diff --git a/sharpd/subdir.am b/sharpd/subdir.am index d161eb6327..acf4fe5d00 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -5,7 +5,6 @@ if SHARPD noinst_LIBRARIES += sharpd/libsharp.a sbin_PROGRAMS += sharpd/sharpd -dist_examples_DATA += sharpd/sharpd.conf.sample vtysh_scan += sharpd/sharp_vty.c vtysh_daemons += sharpd man8 += $(MANBUILD)/frr-sharpd.8 diff --git a/staticd/staticd.conf.sample b/staticd/staticd.conf.sample deleted file mode 100644 index 3b64eb9c90..0000000000 --- a/staticd/staticd.conf.sample +++ /dev/null @@ -1,5 +0,0 @@ -! Default staticd configuration sample -! -log stdout -! -! ip route 4.5.6.7/32 10.10.10.10 diff --git a/staticd/subdir.am b/staticd/subdir.am index a0ae2569cb..62969a0a2a 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -5,7 +5,6 @@ if STATICD noinst_LIBRARIES += staticd/libstatic.a sbin_PROGRAMS += staticd/staticd -dist_examples_DATA += staticd/staticd.conf.sample vtysh_scan += staticd/static_vty.c vtysh_daemons += staticd man8 += $(MANBUILD)/frr-staticd.8 diff --git a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py index c858571254..c10e32ad0a 100644 --- a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py +++ b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py @@ -346,9 +346,9 @@ def test_converge_protocols(): print("Show that v4 routes are right\n") v4_routesFile = "%s/r%s/ipv4_routes.ref" % (thisDir, i) - expected = net["r%s" % i].cmd( - "sort {} 2> /dev/null".format(v4_routesFile) - ).rstrip() + expected = ( + net["r%s" % i].cmd("sort {} 2> /dev/null".format(v4_routesFile)).rstrip() + ) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( @@ -379,9 +379,9 @@ def test_converge_protocols(): print("Show that v6 routes are right\n") v6_routesFile = "%s/r%s/ipv6_routes.ref" % (thisDir, i) - expected = net["r%s" % i].cmd( - "sort {} 2> /dev/null".format(v6_routesFile) - ).rstrip() + expected = ( + net["r%s" % i].cmd("sort {} 2> /dev/null".format(v6_routesFile)).rstrip() + ) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/__init__.py b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/__init__.py diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r1/bgpd.conf b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r1/bgpd.conf new file mode 100644 index 0000000000..c320bb5d11 --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r1/bgpd.conf @@ -0,0 +1,7 @@ +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.101 remote-as external + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r1/zebra.conf b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r1/zebra.conf new file mode 100644 index 0000000000..1782edc2a5 --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r1/zebra.conf @@ -0,0 +1,7 @@ +! +int lo + ip address 172.16.1.1/32 +! +int r1-eth0 + ip address 192.168.1.1/24 +! diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r2/bgpd.conf b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r2/bgpd.conf new file mode 100644 index 0000000000..cb712e9a8d --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r2/bgpd.conf @@ -0,0 +1,3 @@ +router bgp 65103 + no bgp ebgp-requires-policy + neighbor 192.168.1.101 remote-as external diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r2/zebra.conf b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r2/zebra.conf new file mode 100644 index 0000000000..968171e7b9 --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r2/zebra.conf @@ -0,0 +1,4 @@ +! +int r2-eth0 + ip address 192.168.1.103/24 +! diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r3/bgpd.conf b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r3/bgpd.conf new file mode 100644 index 0000000000..a6e3260d15 --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r3/bgpd.conf @@ -0,0 +1,5 @@ +router bgp 65000 + bgp router-id 192.168.1.101 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.103 remote-as external diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r3/zebra.conf b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r3/zebra.conf new file mode 100644 index 0000000000..ddcf862132 --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/r3/zebra.conf @@ -0,0 +1,4 @@ +! +int r3-eth0 + ip address 192.168.1.101/24 +! diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py new file mode 100644 index 0000000000..19c4c5f87d --- /dev/null +++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python + +# Copyright (c) 2021 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +https://tools.ietf.org/html/rfc4271 + +Check if NEXT_HOP attribute is not changed if peer X shares a +common subnet with this address. + +- Otherwise, if the route being announced was learned from an + external peer, the speaker can use an IP address of any + adjacent router (known from the received NEXT_HOP attribute) + that the speaker itself uses for local route calculation in + the NEXT_HOP attribute, provided that peer X shares a common + subnet with this address. This is a second form of "third + party" NEXT_HOP attribute. +""" + +import os +import sys +import json +import time +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 4): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_ebgp_common_subnet_nh_unchanged(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r2 = tgen.gears["r2"] + r3 = tgen.gears["r3"] + + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show ip bgp summary json")) + expected = { + "ipv4Unicast": { + "peers": { + "192.168.1.1": {"state": "Established"}, + "192.168.1.103": {"state": "Established"}, + } + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, r3) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Failed bgp convergence in "{}"'.format(r3) + + def _bgp_nh_unchanged(router): + output = json.loads(router.vtysh_cmd("show ip bgp 172.16.1.1/32 json")) + expected = {"paths": [{"nexthops": [{"ip": "192.168.1.1"}]}]} + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_nh_unchanged, r2) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Wrong next-hop in "{}"'.format(r2) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py b/tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py index 400e7e9bf5..75506d1a51 100644 --- a/tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py +++ b/tests/topotests/bgp-ecmp-topo1/test_bgp_ecmp_topo1.py @@ -45,6 +45,10 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo + +pytestmark = [pytest.mark.bgpd] + + total_ebgp_peers = 20 ##################################################### diff --git a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py index dfe6a8074d..fffcbbd0ef 100644 --- a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py +++ b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py @@ -67,6 +67,10 @@ from lib.topolog import logger from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp from lib.topojson import build_topo_from_json, build_config_from_json + +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology and configuration creation jsonFile = "{}/ebgp_ecmp_topo2.json".format(CWD) diff --git a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py index 2bde52af1d..342a0a4b2f 100644 --- a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py +++ b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py @@ -67,6 +67,10 @@ from lib.topolog import logger from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp from lib.topojson import build_topo_from_json, build_config_from_json + +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology and configuration creation jsonFile = "{}/ibgp_ecmp_topo2.json".format(CWD) diff --git a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py index 2744920272..f389632b1e 100644 --- a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py +++ b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py @@ -35,7 +35,7 @@ import json import platform from functools import partial -pytestmark = [pytest.mark.pimd] +pytestmark = [pytest.mark.bgpd, pytest.mark.pimd] # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) diff --git a/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py b/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py index db4eab9d3d..b830e16b9a 100755 --- a/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py +++ b/tests/topotests/bgp-snmp-mplsl3vpn/test_bgp_snmp_mplsvpn.py @@ -505,8 +505,10 @@ def test_r1_mplsvpn_VrfTable(): associated_int = r1_snmp.get( "mplsL3VpnVrfAssociatedInterfaces.{}".format(snmp_str_to_oid("VRF-a")) ) - assertmsg = "mplsL3VpnVrfAssociatedInterfaces incorrect should be 3 value {}".format( - associated_int + assertmsg = ( + "mplsL3VpnVrfAssociatedInterfaces incorrect should be 3 value {}".format( + associated_int + ) ) assert associated_int == "3", assertmsg diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py index 222478f12d..320e6d430c 100644 --- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py +++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py @@ -42,13 +42,11 @@ sys.path.append(os.path.join(CWD, "../")) from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger +from lib.common_config import adjust_router_l3mdev # Required to instantiate the topology builder class. from mininet.topo import Topo -l3mdev_accept = 0 -krel = "" - class BGPEVPNTopo(Topo): "Test topology builder" @@ -73,8 +71,6 @@ class BGPEVPNTopo(Topo): def setup_module(mod): "Sets up the pytest environment" - global l3mdev_accept - global krel tgen = Topogen(BGPEVPNTopo, mod.__name__) tgen.start_topology() @@ -90,18 +86,13 @@ def setup_module(mod): ) return pytest.skip("Skipping BGP EVPN RT5 NETNS Test. Kernel not supported") - l3mdev_accept = 1 - logger.info("setting net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept)) - # create VRF vrf-101 on R1 and R2 # create loop101 cmds_vrflite = [ - "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept), "ip link add {}-vrf-101 type vrf table 101", "ip ru add oif {}-vrf-101 table 101", "ip ru add iif {}-vrf-101 table 101", "ip link set dev {}-vrf-101 up", - "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept), "ip link add loop101 type dummy", "ip link set dev loop101 master {}-vrf-101", "ip link set dev loop101 up", @@ -139,6 +130,7 @@ def setup_module(mod): logger.info("result: " + output) router = tgen.gears["r2"] + adjust_router_l3mdev(tgen, "r2") for cmd in cmds_vrflite: logger.info("cmd to r2: " + cmd.format("r2")) output = router.run(cmd.format("r2")) diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py index a6338d0c70..b70626fcce 100644 --- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py +++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py @@ -258,10 +258,12 @@ def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: - clear_bgp(tgen, addr_type, dut) + neighbor = topo["routers"][peer]["links"]["r1-link1"][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, dut, neighbor=neighbor) for addr_type in ADDR_TYPES: - clear_bgp(tgen, addr_type, peer) + neighbor = topo["routers"][dut]["links"]["r2-link1"][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, peer, neighbor=neighbor) result = verify_bgp_convergence_from_running_config(tgen) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) @@ -551,7 +553,7 @@ def test_BGP_GR_TC_46_p1(request): write_test_footer(tc_name) -def test_BGP_GR_TC_50_p1(request): +def BGP_GR_TC_50_p1(request): """ Test Objective : Transition from Peer-level helper to Global inherit helper Global Mode : None @@ -613,9 +615,6 @@ def test_BGP_GR_TC_50_p1(request): configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") - result = verify_bgp_convergence_from_running_config(tgen) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - step("Verify on R2 that R1 advertises GR capabilities as a helper node") for addr_type in ADDR_TYPES: @@ -721,7 +720,12 @@ def test_BGP_GR_TC_50_p1(request): } } - configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") + result = create_router_bgp(tgen, topo, input_dict) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + for addr_type in ADDR_TYPES: + neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) result = verify_bgp_convergence_from_running_config(tgen) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) @@ -979,7 +983,15 @@ def test_BGP_GR_TC_51_p1(request): } } - configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") + result = create_router_bgp(tgen, topo, input_dict) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + for addr_type in ADDR_TYPES: + neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) + + result = verify_bgp_convergence_from_running_config(tgen) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Verify on R2 that R1 advertises GR capabilities as a helper node") @@ -1317,20 +1329,22 @@ def test_BGP_GR_TC_4_p0(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Phase 5] : R2 is about to come up now ") @@ -1695,10 +1709,10 @@ def test_BGP_GR_TC_6_1_2_p1(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: - clear_bgp(tgen, addr_type, "r1") - clear_bgp(tgen, addr_type, "r2") + neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) - result = verify_bgp_convergence_from_running_config(tgen, topo) + result = verify_bgp_convergence_from_running_config(tgen) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) # Verify GR stats @@ -1790,10 +1804,11 @@ def test_BGP_GR_TC_6_1_2_p1(request): result = verify_r_bit( tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r2: R-bit is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r2: R-bit is set to True\n Error: {}".format( tc_name, result - )) + ) logger.info("Restart BGPd on R2 ") kill_router_daemons(tgen, "r2", ["bgpd"]) @@ -1811,10 +1826,11 @@ def test_BGP_GR_TC_6_1_2_p1(request): result = verify_r_bit( tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r2: R-bit is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r2: R-bit is set to True\n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) @@ -2096,20 +2112,22 @@ def test_BGP_GR_TC_17_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Phase 5] : R2 is about to come up now ") @@ -2128,10 +2146,11 @@ def test_BGP_GR_TC_17_p1(request): result = verify_r_bit( tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: R-bit is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: R-bit is set to True\n Error: {}".format( tc_name, result - )) + ) # Verifying BGP RIB routes next_hop = next_hop_per_address_family( @@ -2457,20 +2476,22 @@ def test_BGP_GR_TC_20_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Phase 5] : R2 is about to come up now ") @@ -2651,10 +2672,10 @@ def test_BGP_GR_TC_31_1_p1(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: - clear_bgp(tgen, addr_type, "r1") - clear_bgp(tgen, addr_type, "r2") + neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) - result = verify_bgp_convergence_from_running_config(tgen, topo) + result = verify_bgp_convergence_from_running_config(tgen) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) # Verify GR stats @@ -2743,10 +2764,10 @@ def test_BGP_GR_TC_31_1_p1(request): result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info("[Phase 4] : R1 is about to come up now ") start_router_daemons(tgen, "r1", ["bgpd"]) @@ -2932,10 +2953,10 @@ def test_BGP_GR_TC_31_2_p1(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: - clear_bgp(tgen, addr_type, "r1") - clear_bgp(tgen, addr_type, "r2") + neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) - result = verify_bgp_convergence_from_running_config(tgen, topo) + result = verify_bgp_convergence_from_running_config(tgen) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) # Verify GR stats @@ -3225,10 +3246,12 @@ def test_BGP_GR_TC_9_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes @@ -3236,10 +3259,10 @@ def test_BGP_GR_TC_9_p1(request): result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Phase 5] : R2 is about to come up now ") @@ -3269,10 +3292,11 @@ def test_BGP_GR_TC_9_p1(request): result = verify_f_bit( tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: F-bit is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: F-bit is set to True\n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) @@ -3404,10 +3428,12 @@ def test_BGP_GR_TC_17_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes @@ -3415,10 +3441,10 @@ def test_BGP_GR_TC_17_p1(request): result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Phase 5] : R2 is about to come up now ") @@ -3440,10 +3466,11 @@ def test_BGP_GR_TC_17_p1(request): result = verify_r_bit( tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: R-bit is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: R-bit is set to True\n Error: {}".format( tc_name, result - )) + ) # Verifying BGP RIB routes next_hop = next_hop_per_address_family( @@ -3663,10 +3690,12 @@ def test_BGP_GR_TC_43_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) protocol = "bgp" result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False @@ -3971,10 +4000,12 @@ def test_BGP_GR_TC_44_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) @@ -4999,10 +5030,10 @@ def test_BGP_GR_TC_48_p1(request): result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) dut = "r2" peer = "r1" @@ -5013,17 +5044,19 @@ def test_BGP_GR_TC_48_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r2: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r2: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) step("Bring up BGP on R1 and remove Peer-level GR config from R1") @@ -5258,7 +5291,7 @@ def test_BGP_GR_TC_49_p1(request): write_test_footer(tc_name) -def test_BGP_GR_TC_52_p1(request): +def BGP_GR_TC_52_p1(request): """ Test Objective : Transition from Peer-level disbale to Global inherit helper Global Mode : None @@ -5382,17 +5415,19 @@ def test_BGP_GR_TC_52_p1(request): result = verify_bgp_rib( tgen, addr_type, dut, input_topo, next_hop, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) result = verify_rib( tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) step("Bring up BGP on R2 and remove Peer-level GR config from R1") diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py index 2c5dd92f54..9438b90ef8 100644 --- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py +++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py @@ -251,12 +251,14 @@ def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: - clear_bgp(tgen, addr_type, dut) + neighbor = topo["routers"][peer]["links"][dut][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, dut, neighbor=neighbor) for addr_type in ADDR_TYPES: - clear_bgp(tgen, addr_type, peer) + neighbor = topo["routers"][dut]["links"][peer][addr_type].split("/")[0] + clear_bgp(tgen, addr_type, peer, neighbor=neighbor) - result = verify_bgp_convergence_from_running_config(tgen, topo) + result = verify_bgp_convergence_from_running_config(tgen) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) return True @@ -555,10 +557,11 @@ def test_BGP_GR_TC_3_p0(request): result = verify_eor( tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r2: EOR is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r2: EOR is set to True\n Error: {}".format( tc_name, result - )) + ) logger.info( "Waiting for selection deferral timer({} sec)..".format(GR_SELECT_DEFER_TIMER) @@ -701,10 +704,11 @@ def test_BGP_GR_TC_11_p0(request): result = verify_eor( tgen, topo, addr_type, input_dict, dut="r1", peer="r3", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: EOR is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format( tc_name, result - )) + ) logger.info( "Waiting for selection deferral timer({} sec).. ".format( @@ -731,10 +735,11 @@ def test_BGP_GR_TC_11_p0(request): result = verify_eor( tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r3: EOR is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) @@ -930,7 +935,7 @@ def test_BGP_GR_10_p2(request): write_test_footer(tc_name) -def test_BGP_GR_16_p2(request): +def BGP_GR_16_p2(request): """ Test Objective : Verify BGP-GR feature when restarting node is a transit router for it's iBGP peers. @@ -1468,35 +1473,39 @@ def test_BGP_GR_18_p1(request): dut = "r6" input_dict_1 = {key: topo["routers"][key] for key in ["r1"]} result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r6: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes before shutting down BGPd daemon result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r6: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying BGP RIB routes dut = "r2" result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes before shutting down BGPd daemon result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r6: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) write_test_footer(tc_name) @@ -1957,18 +1966,20 @@ def test_BGP_GR_chaos_29_p1(request): # Verifying BGP RIB routes before shutting down BGPd daemon input_dict = {key: topo["routers"][key] for key in ["r1"]} result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes before shutting down BGPd daemon result = verify_rib(tgen, addr_type, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r3: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Step 4] : Start BGPd daemon on R1..") @@ -2210,10 +2221,12 @@ def test_BGP_GR_chaos_33_p1(request): result = verify_rib( tgen, addr_type, dut, input_dict_2, next_hop_4, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) if addr_type == "ipv6": @@ -2225,10 +2238,12 @@ def test_BGP_GR_chaos_33_p1(request): result = verify_rib( tgen, addr_type, dut, input_dict_2, next_hop_6, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Step 4] : Start BGPd daemon on R1 and R4..") @@ -2409,27 +2424,30 @@ def test_BGP_GR_chaos_34_2_p1(request): result = verify_f_bit( tgen, topo, addr_type, input_dict, "r3", "r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r3: F-bit is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format( tc_name, result - )) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying BGP RIB routes after starting BGPd daemon input_dict_1 = {key: topo["routers"][key] for key in ["r1"]} result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r3: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) write_test_footer(tc_name) @@ -2566,10 +2584,11 @@ def test_BGP_GR_chaos_34_1_p1(request): result = verify_f_bit( tgen, topo, addr_type, input_dict_2, "r3", "r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r3: F-bit is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format( tc_name, result - )) + ) logger.info(" Expected behavior: {}".format(result)) logger.info("[Step 3] : Kill BGPd daemon on R1..") @@ -2585,18 +2604,20 @@ def test_BGP_GR_chaos_34_1_p1(request): # Verifying BGP RIB routes input_dict = {key: topo["routers"][key] for key in ["r1"]} result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes result = verify_rib(tgen, addr_type, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r3: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) # Start BGPd daemon on R1 @@ -2770,27 +2791,30 @@ def test_BGP_GR_chaos_32_p1(request): result = verify_eor( tgen, topo, addr_type, input_dict_3, dut="r5", peer="r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r5: EOR is set to TRUE\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r5: EOR is set to TRUE\n Error: {}".format( tc_name, result - )) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying BGP RIB routes after starting BGPd daemon input_dict_1 = {key: topo["routers"][key] for key in ["r5"]} result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r3: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) write_test_footer(tc_name) @@ -2896,10 +2920,11 @@ def test_BGP_GR_chaos_37_p1(request): result = verify_eor( tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r3: EOR is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format( tc_name, result - )) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying BGP RIB routes after starting BGPd daemon @@ -2962,10 +2987,11 @@ def test_BGP_GR_chaos_37_p1(request): result = verify_eor( tgen, topo, addr_type, input_dict_3, dut="r1", peer="r3", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: EOR is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) @@ -3117,18 +3143,20 @@ def test_BGP_GR_chaos_30_p1(request): # Verifying BGP RIB routes before shutting down BGPd daemon input_dict = {key: topo["routers"][key] for key in ["r3"]} result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes before shutting down BGPd daemon result = verify_rib(tgen, addr_type, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) write_test_footer(tc_name) @@ -3530,10 +3558,10 @@ def BGP_GR_TC_7_p1(request): dut = "r1" input_dict_1 = {key: topo["routers"][key] for key in ["r3"]} result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) write_test_footer(tc_name) @@ -3707,10 +3735,11 @@ def test_BGP_GR_TC_23_p1(request): result = verify_eor( tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: EOR is set to True\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format( tc_name, result - )) + ) # Verifying BGP RIB routes received from router R1 dut = "r1" @@ -3831,18 +3860,20 @@ def test_BGP_GR_20_p1(request): dut = "r3" input_dict_1 = {key: topo["routers"][key] for key in ["r1"]} result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: routes are still present in BGP RIB\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info(" Expected behavior: {}".format(result)) # Verifying RIB routes before shutting down BGPd daemon result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r3: routes are still present in ZEBRA\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) + ) logger.info(" Expected behavior: {}".format(result)) # Start BGPd daemon on R1 diff --git a/tests/topotests/bgp_instance_del_test/test_bgp_instance_del_test.py b/tests/topotests/bgp_instance_del_test/test_bgp_instance_del_test.py index 47cc0eb39d..0c7e84a5a3 100755 --- a/tests/topotests/bgp_instance_del_test/test_bgp_instance_del_test.py +++ b/tests/topotests/bgp_instance_del_test/test_bgp_instance_del_test.py @@ -30,6 +30,9 @@ sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../") from lib.ltemplate import * +pytestmark = [pytest.mark.bgpd, pytest.mark.ldpd, pytest.mark.ospfd] + + def test_check_linux_vrf(): CliOnFail = None # For debugging, uncomment the next line diff --git a/tests/topotests/bgp_ipv6_rtadv/test_bgp_ipv6_rtadv.py b/tests/topotests/bgp_ipv6_rtadv/test_bgp_ipv6_rtadv.py index 783e746418..cd845be296 100644 --- a/tests/topotests/bgp_ipv6_rtadv/test_bgp_ipv6_rtadv.py +++ b/tests/topotests/bgp_ipv6_rtadv/test_bgp_ipv6_rtadv.py @@ -46,6 +46,9 @@ from lib.topolog import logger from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd] + + class BGPIPV6RTADVTopo(Topo): "Test topology builder" diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py index 1c3c51f68e..5d97537bd0 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py @@ -84,6 +84,7 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from lib.ltemplate import ltemplateRtrCmd +from lib.common_config import adjust_router_l3mdev # Required to instantiate the topology builder class. from mininet.topo import Topo @@ -145,26 +146,12 @@ class ThisTestTopo(Topo): switch[1].add_link(tgen.gears["r3"], nodeif="r3-eth1") -l3mdev_accept = 0 - - def ltemplatePreRouterStartHook(): - global l3mdev_accept cc = ltemplateRtrCmd() krel = platform.release() tgen = get_topogen() logger.info("pre router-start hook, kernel=" + krel) - if ( - topotest.version_cmp(krel, "4.15") >= 0 - and topotest.version_cmp(krel, "4.18") <= 0 - ): - l3mdev_accept = 1 - - if topotest.version_cmp(krel, "5.0") >= 0: - l3mdev_accept = 1 - - logger.info("setting net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept)) # check for mpls if tgen.hasmpls != True: logger.info("MPLS not available, skipping setup") @@ -187,10 +174,11 @@ def ltemplatePreRouterStartHook(): "ip ru add oif {0}-cust1 table 10", "ip ru add iif {0}-cust1 table 10", "ip link set dev {0}-cust1 up", - "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept), ] for rtr in rtrs: - router = tgen.gears[rtr] + # adjust handling of VRF traffic + adjust_router_l3mdev(tgen, rtr) + for cmd in cmds: cc.doCmd(tgen, rtr, cmd.format(rtr)) cc.doCmd(tgen, rtr, "ip link set dev {0}-eth4 master {0}-cust1".format(rtr)) @@ -229,9 +217,11 @@ def ltemplatePreRouterStartHook(): "ip ru add oif {0}-cust2 table 20", "ip ru add iif {0}-cust2 table 20", "ip link set dev {0}-cust2 up", - "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept), ] for rtr in rtrs: + # adjust handling of VRF traffic + adjust_router_l3mdev(tgen, rtr) + for cmd in cmds: cc.doCmd(tgen, rtr, cmd.format(rtr)) cc.doCmd(tgen, rtr, "ip link set dev {0}-eth0 master {0}-cust2".format(rtr)) diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py index 7c154ecd15..650ba20b8c 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py @@ -1,6 +1,7 @@ from lib.lutil import luCommand -from customize import l3mdev_accept +from lib.common_config import kernel_requires_l3mdev_adjustment +l3mdev_accept = kernel_requires_l3mdev_adjustment() l3mdev_rtrs = ["r1", "r3", "r4", "ce4"] for rtr in l3mdev_rtrs: luCommand(rtr, "sysctl net.ipv4.tcp_l3mdev_accept", " = \d*", "none", "") diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py index 8e5ffe10be..84d9c48f35 100644 --- a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py +++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py @@ -598,10 +598,12 @@ def test_large_community_lists_with_rmap_apply_and_remove(request): result = verify_bgp_community( tgen, adt, dut, NETWORKS[adt], input_dict_4, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "largeCommunity is still present after deleting route-map \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) write_test_footer(tc_name) @@ -899,10 +901,10 @@ def test_large_community_lists_with_rmap_set_none(request): dut = "r6" for adt in ADDR_TYPES: result = verify_bgp_community(tgen, adt, dut, NETWORKS[adt], expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "Community-list is still present \n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "Community-list is still present \n Error: {}".format(tc_name, result) + ) write_test_footer(tc_name) @@ -2238,10 +2240,10 @@ def test_large_community_lists_with_rmap_match_regex(request): result = verify_bgp_community( tgen, adt, dut, NETWORKS[adt], input_dict_7, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "largeCommunity is still present \n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "largeCommunity is still present \n Error: {}".format(tc_name, result) + ) write_test_footer(tc_name) diff --git a/tests/topotests/bgp_lu_topo1/test_bgp_lu.py b/tests/topotests/bgp_lu_topo1/test_bgp_lu.py index d550c38a2f..d1745674f0 100644 --- a/tests/topotests/bgp_lu_topo1/test_bgp_lu.py +++ b/tests/topotests/bgp_lu_topo1/test_bgp_lu.py @@ -45,6 +45,10 @@ from lib.topolog import logger # Required to instantiate the topology builder class. from mininet.topo import Topo + +pytestmark = [pytest.mark.bgpd] + + # Basic scenario for BGP-LU. Nodes are directly connected. # Node 3 is advertising many routes to 2, which advertises them # as BGP-LU to 1; this way we get routes with actual labels, as diff --git a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py index 464d6eb475..5ecaee2ece 100644 --- a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py +++ b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py @@ -508,10 +508,10 @@ def test_ambiguous_overlapping_addresses_in_different_vrfs_p0(request): ) result = verify_rib(tgen, addr_type, dut, input_dict_1, tag=500, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are present with tag value 500 \n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "Routes are present with tag value 500 \n Error: {}".format(tc_name, result) + ) logger.info("Expected Behavior: {}".format(result)) step( @@ -1147,10 +1147,12 @@ def test_prefixes_leaking_p0(request): result = verify_rib( tgen, addr_type, dut, input_dict_1, metric=123, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "Routes are present with metric value 123 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info("Expected Behavior: {}".format(result)) result = verify_rib(tgen, addr_type, dut, input_dict_2, metric=123) @@ -1161,10 +1163,12 @@ def test_prefixes_leaking_p0(request): result = verify_rib( tgen, addr_type, dut, input_dict_2, metric=0, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "Routes are present with metric value 0 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info("Expected Behavior: {}".format(result)) write_test_footer(tc_name) diff --git a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py index 10cf1c6ae8..c8d1330122 100644 --- a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py +++ b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py @@ -102,6 +102,10 @@ from lib.topolog import logger from lib.bgp import clear_bgp, verify_bgp_rib, create_router_bgp, verify_bgp_convergence from lib.topojson import build_config_from_json, build_topo_from_json + +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology creation jsonFile = "{}/bgp_multi_vrf_topo2.json".format(CWD) @@ -2218,16 +2222,20 @@ def test_restart_bgpd_daemon_p1(request): } result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "Routes are still present in VRF RED_A and RED_B \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) result = verify_rib(tgen, addr_type, dut, input_dict_2, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "Routes are still present in VRF BLUE_A and BLUE_B \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("Bring up BGPd daemon on R1.") start_router_daemons(tgen, "r1", ["bgpd"]) diff --git a/tests/topotests/bgp_peer-group/test_bgp_peer-group.py b/tests/topotests/bgp_peer-group/test_bgp_peer-group.py index 7c7a8b87ed..21dc725793 100644 --- a/tests/topotests/bgp_peer-group/test_bgp_peer-group.py +++ b/tests/topotests/bgp_peer-group/test_bgp_peer-group.py @@ -39,6 +39,9 @@ from lib.topolog import logger from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd] + + class TemplateTopo(Topo): def build(self, *_args, **_opts): tgen = get_topogen(self) diff --git a/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py b/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py index 4764ff8945..2a98cb341d 100644 --- a/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py +++ b/tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py @@ -86,6 +86,10 @@ from lib.bgp import ( ) from lib.topojson import build_topo_from_json, build_config_from_json + +pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] + + # Reading the data from JSON File for topology and configuration creation jsonFile = "{}/bgp_recursive_route_ebgp_multi_hop.json".format(CWD) try: @@ -365,10 +369,11 @@ def test_recursive_routes_iBGP_peer_p1(request): protocol="bgp", expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Reconfigure the same static route on R2 again") dut = "r2" @@ -486,10 +491,11 @@ def test_recursive_routes_iBGP_peer_p1(request): result = verify_rib( tgen, addr_type, "r2", input_dict_4, protocol="bgp", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) @@ -598,10 +604,11 @@ def test_next_hop_as_self_ip_p1(request): next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Shut interface on R2 that has IP from the subnet as BGP next-hop") intf_r2_r4 = topo["routers"]["r2"]["links"]["r4"]["interface"] @@ -676,10 +683,11 @@ def test_next_hop_as_self_ip_p1(request): next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) @@ -1622,10 +1630,11 @@ def test_BGP_peering_bw_loopback_and_physical_p1(request): step("Verify that once eBGP multi-hop is removed, BGP session goes down") result = verify_bgp_convergence_from_running_config(tgen, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "BGP is converged \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format( tc_name, result - )) + ) step("Add ebgp-multihop command on R3 again") for addr_type in ADDR_TYPES: @@ -1663,10 +1672,11 @@ def test_BGP_peering_bw_loopback_and_physical_p1(request): step("Verify that BGP session goes down, when update-source is removed") result = verify_bgp_convergence_from_running_config(tgen, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "BGP is converged \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format( tc_name, result - )) + ) step("Add update-source command on R1 again") for addr_type in ADDR_TYPES: @@ -1715,18 +1725,20 @@ def test_BGP_peering_bw_loopback_and_physical_p1(request): next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format( tc_name, result - )) + ) sleep(3) step("Verify that BGP session goes down, when static route is removed") result = verify_bgp_convergence_from_running_config(tgen, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "BGP is converged \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format( tc_name, result - )) + ) step("Add static route on R3 again") for addr_type in ADDR_TYPES: @@ -1768,10 +1780,11 @@ def test_BGP_peering_bw_loopback_and_physical_p1(request): sleep(3) step("Verify that BGP neighborship between R1 and R3 goes down") result = verify_bgp_convergence_from_running_config(tgen, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "BGP is converged \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format( tc_name, result - )) + ) intf_r1_r3 = topo["routers"]["r1"]["links"]["r3"]["interface"] shutdown_bringup_interface(tgen, "r1", intf_r1_r3, True) @@ -2087,10 +2100,11 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request): ], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Reconfigure multipath-relax command on R4") result = create_router_bgp(tgen, topo, maxpath_relax) @@ -2147,10 +2161,11 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request): ], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "Routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Re-configure maximum-path 2 command on R4") input_dict_8 = { @@ -2338,10 +2353,11 @@ def test_password_authentication_for_eBGP_and_iBGP_peers_p1(request): "configured but not peer routers" ) result = verify_bgp_convergence(tgen, topo, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "BGP is converged \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format( tc_name, result - )) + ) step("configure same password on R2 and R3") for routerN in ["r2", "r3"]: @@ -2368,10 +2384,11 @@ def test_password_authentication_for_eBGP_and_iBGP_peers_p1(request): "strings are in CAPs on R2 and R3" ) result = verify_bgp_convergence(tgen, topo, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "BGP is converged \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format( tc_name, result - )) + ) step("Configure same password on R2 and R3 without CAPs") for routerN in ["r2", "r3"]: @@ -2395,10 +2412,11 @@ def test_password_authentication_for_eBGP_and_iBGP_peers_p1(request): step("Verify if password is removed from R1, both sessions go down again") result = verify_bgp_convergence(tgen, topo, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "BGP is converged \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "BGP is converged \n Error: {}".format( tc_name, result - )) + ) step("Configure alphanumeric password on R1 and peer routers R2,R3") for bgp_neighbor in ["r2", "r3"]: diff --git a/tests/topotests/bgp_sender-as-path-loop-detection/test_bgp_sender-as-path-loop-detection.py b/tests/topotests/bgp_sender-as-path-loop-detection/test_bgp_sender-as-path-loop-detection.py index 88935ae4d1..dffe24f3a0 100644 --- a/tests/topotests/bgp_sender-as-path-loop-detection/test_bgp_sender-as-path-loop-detection.py +++ b/tests/topotests/bgp_sender-as-path-loop-detection/test_bgp_sender-as-path-loop-detection.py @@ -44,6 +44,9 @@ from lib.topolog import logger from mininet.topo import Topo +pytestmark = [pytest.mark.bgpd] + + class TemplateTopo(Topo): def build(self, *_args, **_opts): tgen = get_topogen(self) diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py index b99f1a7418..291a6e7c3a 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py @@ -498,6 +498,7 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo): # ##################################################### + def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): """ TC5_FUNC_5: @@ -762,9 +763,7 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): for addr_type in ADDR_TYPES: - step( - "On router R1 delete static routes in vrf ISR to LOOPBACK_1" - ) + step("On router R1 delete static routes in vrf ISR to LOOPBACK_1") input_routes_r1 = { "r1": { @@ -772,7 +771,7 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request): { "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]], "next_hop": (intf_r2_r1[addr_type]).split("/")[0], - "delete": True + "delete": True, } ] } diff --git a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py index 97d98415db..92ee8513e1 100644 --- a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py +++ b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py @@ -42,6 +42,7 @@ sys.path.append(os.path.join(CWD, "../")) from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger +from lib.common_config import adjust_router_l3mdev # Required to instantiate the topology builder class. from mininet.topo import Topo @@ -71,22 +72,6 @@ def setup_module(mod): router_list = tgen.routers() logger.info("Testing with VRF Lite support") - krel = platform.release() - - # May need to adjust handling of vrf traffic depending on kernel version - l3mdev_accept = 0 - if ( - topotest.version_cmp(krel, "4.15") >= 0 - and topotest.version_cmp(krel, "4.18") <= 0 - ): - l3mdev_accept = 1 - - if topotest.version_cmp(krel, "5.0") >= 0: - l3mdev_accept = 1 - - logger.info( - "krel '{0}' setting net.ipv4.tcp_l3mdev_accept={1}".format(krel, l3mdev_accept) - ) cmds = [ "ip link add {0}-cust1 type vrf table 1001", @@ -99,15 +84,8 @@ def setup_module(mod): for cmd in cmds: output = tgen.net[rname].cmd(cmd.format(rname)) - output = tgen.net[rname].cmd("sysctl -n net.ipv4.tcp_l3mdev_accept") - logger.info( - "router {0}: existing tcp_l3mdev_accept was {1}".format(rname, output) - ) - - if l3mdev_accept: - output = tgen.net[rname].cmd( - "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept) - ) + # adjust handling of vrf traffic + adjust_router_l3mdev(tgen, rname) for rname, router in router_list.items(): router.load_config( diff --git a/tests/topotests/conftest.py b/tests/topotests/conftest.py index 7ad5d8c9ab..cf64956bfd 100755 --- a/tests/topotests/conftest.py +++ b/tests/topotests/conftest.py @@ -11,6 +11,7 @@ from lib.topotest import json_cmp_result from lib.topotest import g_extra_config as topotest_extra_config from lib.topolog import logger + def pytest_addoption(parser): """ Add topology-only option to the topology tester. This option makes pytest @@ -143,9 +144,7 @@ def pytest_configure(config): vtysh_on_error = config.getoption("--vtysh-on-error") topotest_extra_config["vtysh_on_error"] = vtysh_on_error - topotest_extra_config["pause_after"] = ( - pause_after or shell or vtysh - ) + topotest_extra_config["pause_after"] = pause_after or shell or vtysh topotest_extra_config["topology_only"] = config.getoption("--topology-only") @@ -177,9 +176,11 @@ def pytest_runtest_makereport(item, call): else: error = True # Handle assert failures - parent._previousfailed = item # pylint: disable=W0212 + parent._previousfailed = item # pylint: disable=W0212 logger.error( - 'assert failed at "{}/{}": {}'.format(modname, item.name, call.excinfo.value) + 'assert failed at "{}/{}": {}'.format( + modname, item.name, call.excinfo.value + ) ) # (topogen) Set topology error to avoid advancing in the test. @@ -188,7 +189,6 @@ def pytest_runtest_makereport(item, call): # This will cause topogen to report error on `routers_have_failure`. tgen.set_error("{}/{}".format(modname, item.name)) - if error and topotest_extra_config["shell_on_error"]: for router in tgen.routers(): pause = True diff --git a/tests/topotests/isis-snmp/test_isis_snmp.py b/tests/topotests/isis-snmp/test_isis_snmp.py index 1bcd0eefc6..07f3335e23 100755 --- a/tests/topotests/isis-snmp/test_isis_snmp.py +++ b/tests/topotests/isis-snmp/test_isis_snmp.py @@ -124,7 +124,6 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears["r3"]) - def setup_module(mod): "Sets up the pytest environment" @@ -148,20 +147,24 @@ def setup_module(mod): # Don't start the following in the CE nodes if router.name[0] == "r": router.load_config( - TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)), + TopoRouter.RD_ISIS, + os.path.join(CWD, "{}/isisd.conf".format(rname)), "-M snmp", ) router.load_config( - TopoRouter.RD_LDP, os.path.join(CWD, "{}/ldpd.conf".format(rname)), + TopoRouter.RD_LDP, + os.path.join(CWD, "{}/ldpd.conf".format(rname)), ) router.load_config( - TopoRouter.RD_SNMP, os.path.join(CWD, "{}/snmpd.conf".format(rname)), + TopoRouter.RD_SNMP, + os.path.join(CWD, "{}/snmpd.conf".format(rname)), "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap", ) # After loading the configurations, this function loads configured daemons. tgen.start_router() + def teardown_module(mod): "Teardown the pytest environment" tgen = get_topogen() @@ -169,6 +172,7 @@ def teardown_module(mod): # This function tears down the whole topology. tgen.stop_topology() + def router_compare_json_output(rname, command, reference): "Compare router JSON output" @@ -184,6 +188,7 @@ def router_compare_json_output(rname, command, reference): assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) assert diff is None, assertmsg + def generate_oid(numoids, index1, index2): if numoids == 1: oid = "{}".format(index1) @@ -200,7 +205,9 @@ def test_isis_convergence(): router_compare_json_output( rname, "show yang operational-data /frr-interface:lib isisd", - "show_yang_interface_isis_adjacencies.ref") + "show_yang_interface_isis_adjacencies.ref", + ) + def test_r1_scalar_snmp(): "Wait for protocol convergence" @@ -213,26 +220,26 @@ def test_r1_scalar_snmp(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") - assert r1_snmp.test_oid('isisSysVersion', "one(1)") - assert r1_snmp.test_oid('isisSysLevelType', "level1and2(3)") - assert r1_snmp.test_oid('isisSysID',"00 00 00 00 00 01") - assert r1_snmp.test_oid('isisSysMaxPathSplits',"32") - assert r1_snmp.test_oid('isisSysMaxLSPGenInt',"900 seconds") - assert r1_snmp.test_oid('isisSysAdminState',"on(1)") - assert r1_snmp.test_oid('isisSysMaxAge',"1200 seconds") - assert r1_snmp.test_oid('isisSysProtSupported',"07 5 6 7") + assert r1_snmp.test_oid("isisSysVersion", "one(1)") + assert r1_snmp.test_oid("isisSysLevelType", "level1and2(3)") + assert r1_snmp.test_oid("isisSysID", "00 00 00 00 00 01") + assert r1_snmp.test_oid("isisSysMaxPathSplits", "32") + assert r1_snmp.test_oid("isisSysMaxLSPGenInt", "900 seconds") + assert r1_snmp.test_oid("isisSysAdminState", "on(1)") + assert r1_snmp.test_oid("isisSysMaxAge", "1200 seconds") + assert r1_snmp.test_oid("isisSysProtSupported", "07 5 6 7") r2 = tgen.net.get("r2") r2_snmp = SnmpTester(r2, "2.2.2.2", "public", "2c") - - assert r2_snmp.test_oid('isisSysVersion', "one(1)") - assert r2_snmp.test_oid('isisSysLevelType', "level1and2(3)") - assert r2_snmp.test_oid('isisSysID',"00 00 00 00 00 02") - assert r2_snmp.test_oid('isisSysMaxPathSplits',"32") - assert r2_snmp.test_oid('isisSysMaxLSPGenInt',"900 seconds") - assert r2_snmp.test_oid('isisSysAdminState',"on(1)") - assert r2_snmp.test_oid('isisSysMaxAge',"1200 seconds") - assert r2_snmp.test_oid('isisSysProtSupported',"07 5 6 7") + + assert r2_snmp.test_oid("isisSysVersion", "one(1)") + assert r2_snmp.test_oid("isisSysLevelType", "level1and2(3)") + assert r2_snmp.test_oid("isisSysID", "00 00 00 00 00 02") + assert r2_snmp.test_oid("isisSysMaxPathSplits", "32") + assert r2_snmp.test_oid("isisSysMaxLSPGenInt", "900 seconds") + assert r2_snmp.test_oid("isisSysAdminState", "on(1)") + assert r2_snmp.test_oid("isisSysMaxAge", "1200 seconds") + assert r2_snmp.test_oid("isisSysProtSupported", "07 5 6 7") circtable_test = { @@ -245,7 +252,8 @@ circtable_test = { "isisCircMeshGroupEnabled": ["inactive(1)", "inactive(1)", "inactive(1)"], "isisCircSmallHellos": ["false(2)", "false(2)", "false(2)"], "isisCirc3WayEnabled": ["false(2)", "false(2)", "false(2)"], - } +} + def test_r1_isisCircTable(): tgen = get_topogen() @@ -256,9 +264,9 @@ def test_r1_isisCircTable(): r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") oids = [] - oids.append(generate_oid(1,1,0)) - oids.append(generate_oid(1,2,0)) - oids.append(generate_oid(1,3,0)) + oids.append(generate_oid(1, 1, 0)) + oids.append(generate_oid(1, 2, 0)) + oids.append(generate_oid(1, 3, 0)) # check items for item in circtable_test.keys(): @@ -267,14 +275,26 @@ def test_r1_isisCircTable(): ) assert r1_snmp.test_oid_walk(item, circtable_test[item], oids), assertmsg + circleveltable_test = { "isisCircLevelMetric": ["10", "10", "10", "10"], "isisCircLevelWideMetric": ["10", "10", "0", "0"], "isisCircLevelISPriority": ["64", "64", "64", "64"], "isisCircLevelHelloMultiplier": ["10", "10", "10", "10"], - "isisCircLevelHelloTimer": ["3000 milliseconds", "3000 milliseconds", "3000 milliseconds", "3000 milliseconds"], - "isisCircLevelMinLSPRetransInt": ["1 seconds", "1 seconds", "0 seconds", "0 seconds"], - } + "isisCircLevelHelloTimer": [ + "3000 milliseconds", + "3000 milliseconds", + "3000 milliseconds", + "3000 milliseconds", + ], + "isisCircLevelMinLSPRetransInt": [ + "1 seconds", + "1 seconds", + "0 seconds", + "0 seconds", + ], +} + def test_r1_isislevelCircTable(): tgen = get_topogen() @@ -285,10 +305,10 @@ def test_r1_isislevelCircTable(): r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") oids = [] - oids.append(generate_oid(2,1,"area")) - oids.append(generate_oid(2,2,"area")) - oids.append(generate_oid(2,3,"area")) - oids.append(generate_oid(2,3,"domain")) + oids.append(generate_oid(2, 1, "area")) + oids.append(generate_oid(2, 2, "area")) + oids.append(generate_oid(2, 3, "area")) + oids.append(generate_oid(2, 3, "domain")) # check items for item in circleveltable_test.keys(): @@ -316,6 +336,7 @@ adjtable_down_test = { "isisISAdjNeighPriority": ["64"], } + def test_r1_isisAdjTable(): "check ISIS Adjacency Table" tgen = get_topogen() @@ -324,11 +345,11 @@ def test_r1_isisAdjTable(): r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") oids = [] - oids.append(generate_oid(2,1,1)) - oids.append(generate_oid(2,2,1)) + oids.append(generate_oid(2, 1, 1)) + oids.append(generate_oid(2, 2, 1)) oids_down = [] - oids_down.append(generate_oid(2,1,1)) + oids_down.append(generate_oid(2, 1, 1)) # check items for item in adjtable_test.keys(): @@ -337,7 +358,6 @@ def test_r1_isisAdjTable(): ) assert r1_snmp.test_oid_walk(item, adjtable_test[item], oids), assertmsg - # shutdown interface and one adjacency should be removed "check ISIS adjacency is removed when interface is shutdown" r1_cmd.vtysh_cmd("conf t\ninterface r1-eth1\nshutdown") @@ -347,7 +367,9 @@ def test_r1_isisAdjTable(): assertmsg = "{} should be {} oids {} full dict {}:".format( item, adjtable_down_test[item], oids_down, r1_snmp.walk(item) ) - assert r1_snmp.test_oid_walk(item, adjtable_down_test[item], oids_down), assertmsg + assert r1_snmp.test_oid_walk( + item, adjtable_down_test[item], oids_down + ), assertmsg # no shutdown interface and adjacency should be restored r1_cmd.vtysh_cmd("conf t\ninterface r1-eth1\nno shutdown") diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_topology.json b/tests/topotests/isis-topo1-vrf/r1/r1_topology.json index 8e3cdc7bd6..1a6fe6d5c6 100644 --- a/tests/topotests/isis-topo1-vrf/r1/r1_topology.json +++ b/tests/topotests/isis-topo1-vrf/r1/r1_topology.json @@ -5,73 +5,73 @@ { "vertex": "r1" } - ], + ], "ipv6": [ { "vertex": "r1" } ] - }, + }, "level-2": { "ipv4": [ { "vertex": "r1" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r1(4)", + "type": "IP internal", "vertex": "10.0.20.0/24" - }, + }, { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r1(4)", - "type": "TE-IS", + "interface": "r1-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r1(4)", + "type": "TE-IS", "vertex": "r3" - }, + }, { - "interface": "r3", - "metric": "TE", - "next-hop": "20", - "parent": "r1-eth0", - "type": "IP", + "interface": "r1-eth0", + "metric": "20", + "next-hop": "r3", + "parent": "r3(4)", + "type": "IP TE", "vertex": "10.0.20.0/24" - }, + }, { - "interface": "r3", - "metric": "TE", - "next-hop": "20", - "parent": "r1-eth0", - "type": "IP", + "interface": "r1-eth0", + "metric": "20", + "next-hop": "r3", + "parent": "r3(4)", + "type": "IP TE", "vertex": "10.0.10.0/24" } - ], + ], "ipv6": [ { "vertex": "r1" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r1(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:1::/64" - }, + }, { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r1(4)", - "type": "TE-IS", + "interface": "r1-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r1(4)", + "type": "TE-IS", "vertex": "r3" - }, + }, { - "interface": "r3", - "metric": "internal", - "next-hop": "20", - "parent": "r1-eth0", - "type": "IP6", + "interface": "r1-eth0", + "metric": "20", + "next-hop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:1::/64" } ] diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_topology.json b/tests/topotests/isis-topo1-vrf/r2/r2_topology.json index 72022a8167..a77f7977f9 100644 --- a/tests/topotests/isis-topo1-vrf/r2/r2_topology.json +++ b/tests/topotests/isis-topo1-vrf/r2/r2_topology.json @@ -5,76 +5,76 @@ { "vertex": "r2" } - ], + ], "ipv6": [ { "vertex": "r2" } ] - }, + }, "level-2": { "ipv4": [ { "vertex": "r2" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r2(4)", + "type": "IP internal", "vertex": "10.0.21.0/24" - }, + }, { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r2(4)", - "type": "TE-IS", + "interface": "r2-eth0", + "metric": "10", + "next-hop": "r4", + "parent": "r2(4)", + "type": "TE-IS", "vertex": "r4" - }, + }, { - "interface": "r4", - "metric": "TE", - "next-hop": "20", - "parent": "r2-eth0", - "type": "IP", + "interface": "r2-eth0", + "metric": "20", + "next-hop": "r4", + "parent": "r4(4)", + "type": "IP TE", "vertex": "10.0.21.0/24" - }, + }, { - "interface": "r4", - "metric": "TE", - "next-hop": "20", - "parent": "r2-eth0", - "type": "IP", + "interface": "r2-eth0", + "metric": "20", + "next-hop": "r4", + "parent": "r4(4)", + "type": "IP TE", "vertex": "10.0.11.0/24" } - ], + ], "ipv6": [ { "vertex": "r2" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r2(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:2::/64" - }, + }, { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r2(4)", - "type": "TE-IS", + "interface": "r2-eth0", + "metric": "10", + "next-hop": "r4", + "parent": "r2(4)", + "type": "TE-IS", "vertex": "r4" - }, + }, { - "interface": "r4", - "metric": "internal", - "next-hop": "20", - "parent": "r2-eth0", - "type": "IP6", + "interface": "r2-eth0", + "metric": "20", + "next-hop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:2::/64" } ] } } -}
\ No newline at end of file +} diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_topology.json b/tests/topotests/isis-topo1-vrf/r3/r3_topology.json index 62b895766e..1e5d331965 100644 --- a/tests/topotests/isis-topo1-vrf/r3/r3_topology.json +++ b/tests/topotests/isis-topo1-vrf/r3/r3_topology.json @@ -4,126 +4,126 @@ "ipv4": [ { "vertex": "r3" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r3(4)", + "type": "IP internal", "vertex": "10.0.10.0/24" - }, + }, { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r3(4)", - "type": "TE-IS", + "interface": "r3-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r3(4)", + "type": "TE-IS", "vertex": "r5" - }, + }, { - "interface": "r5", - "metric": "TE", - "next-hop": "20", - "parent": "r3-eth1", - "type": "IP", + "interface": "r3-eth1", + "metric": "20", + "next-hop": "r5", + "parent": "r5(4)", + "type": "IP TE", "vertex": "10.0.10.0/24" - }, + }, { - "interface": "r5", - "metric": "TE", - "next-hop": "20", - "parent": "r3-eth1", - "type": "IP", + "interface": "r3-eth1", + "metric": "20", + "next-hop": "r5", + "parent": "r5(4)", + "type": "IP TE", "vertex": "10.0.11.0/24" - }, + }, { - "interface": "r5", - "metric": "TE", - "next-hop": "30", - "parent": "r3-eth1", - "type": "IP", + "interface": "r3-eth1", + "metric": "30", + "next-hop": "r5", + "parent": "r4(4)", + "type": "IP TE", "vertex": "10.0.21.0/24" } - ], + ], "ipv6": [ { "vertex": "r3" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r3(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:1::/64" - }, + }, { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r3(4)", - "type": "TE-IS", + "interface": "r3-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r3(4)", + "type": "TE-IS", "vertex": "r5" - }, + }, { - "interface": "r5", - "metric": "internal", - "next-hop": "20", - "parent": "r3-eth1", - "type": "IP6", + "interface": "r3-eth1", + "metric": "20", + "next-hop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:2::/64" - }, + }, { - "interface": "r5", - "metric": "internal", - "next-hop": "30", - "parent": "r3-eth1", - "type": "IP6", + "interface": "r3-eth1", + "metric": "30", + "next-hop": "r5", + "parent": "r4(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:2::/64" } ] - }, + }, "level-2": { "ipv4": [ { "vertex": "r3" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r3(4)", + "type": "IP internal", "vertex": "10.0.20.0/24" - }, + }, { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "TE-IS", + "interface": "r3-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r3(4)", + "type": "TE-IS", "vertex": "r3" - }, + }, { - "interface": "r3", - "metric": "TE", - "next-hop": "20", - "parent": "r3-eth0", - "type": "IP", + "interface": "r3-eth0", + "metric": "20", + "next-hop": "r3", + "parent": "r3(4)", + "type": "IP TE", "vertex": "10.0.20.0/24" } - ], + ], "ipv6": [ { "vertex": "r3" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r3(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:1::/64" - }, + }, { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "TE-IS", + "interface": "r3-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r3(4)", + "type": "TE-IS", "vertex": "r3" } ] diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_topology.json b/tests/topotests/isis-topo1-vrf/r4/r4_topology.json index 0d69550cad..34f5ac9ca4 100644 --- a/tests/topotests/isis-topo1-vrf/r4/r4_topology.json +++ b/tests/topotests/isis-topo1-vrf/r4/r4_topology.json @@ -4,126 +4,126 @@ "ipv4": [ { "vertex": "r4" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r4(4)", + "type": "IP internal", "vertex": "10.0.11.0/24" - }, + }, { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r4(4)", - "type": "TE-IS", + "interface": "r4-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r4(4)", + "type": "TE-IS", "vertex": "r5" - }, + }, { - "interface": "r5", - "metric": "TE", - "next-hop": "20", - "parent": "r4-eth1", - "type": "IP", + "interface": "r4-eth1", + "metric": "20", + "next-hop": "r5", + "parent": "r5(4)", + "type": "IP TE", "vertex": "10.0.10.0/24" - }, + }, { - "interface": "r5", - "metric": "TE", - "next-hop": "20", - "parent": "r4-eth1", - "type": "IP", + "interface": "r4-eth1", + "metric": "20", + "next-hop": "r5", + "parent": "r5(4)", + "type": "IP TE", "vertex": "10.0.11.0/24" - }, + }, { - "interface": "r5", - "metric": "TE", - "next-hop": "30", - "parent": "r4-eth1", - "type": "IP", + "interface": "r4-eth1", + "metric": "30", + "next-hop": "r5", + "parent": "r3(4)", + "type": "IP TE", "vertex": "10.0.20.0/24" } - ], + ], "ipv6": [ { "vertex": "r4" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r4(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:2::/64" - }, + }, { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r4(4)", - "type": "TE-IS", + "interface": "r4-eth1", + "metric": "10", + "next-hop": "r5", + "parent": "r4(4)", + "type": "TE-IS", "vertex": "r5" - }, + }, { - "interface": "r5", - "metric": "internal", - "next-hop": "20", - "parent": "r4-eth1", - "type": "IP6", + "interface": "r4-eth1", + "metric": "20", + "next-hop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:1::/64" - }, + }, { - "interface": "r5", - "metric": "internal", - "next-hop": "30", - "parent": "r4-eth1", - "type": "IP6", + "interface": "r4-eth1", + "metric": "30", + "next-hop": "r5", + "parent": "r3(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:1::/64" } ] - }, + }, "level-2": { "ipv4": [ { "vertex": "r4" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r4(4)", + "type": "IP internal", "vertex": "10.0.21.0/24" - }, + }, { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r4(4)", - "type": "TE-IS", + "interface": "r4-eth0", + "metric": "10", + "next-hop": "r2", + "parent": "r4(4)", + "type": "TE-IS", "vertex": "r2" - }, + }, { - "interface": "r2", - "metric": "TE", - "next-hop": "20", - "parent": "r4-eth0", - "type": "IP", + "interface": "r4-eth0", + "metric": "20", + "next-hop": "r2", + "parent": "r2(4)", + "type": "IP TE", "vertex": "10.0.21.0/24" } - ], + ], "ipv6": [ { "vertex": "r4" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r4(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:2::/64" - }, + }, { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r4(4)", - "type": "TE-IS", + "interface": "r4-eth0", + "metric": "10", + "next-hop": "r2", + "parent": "r4(4)", + "type": "TE-IS", "vertex": "r2" } ] diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_topology.json b/tests/topotests/isis-topo1-vrf/r5/r5_topology.json index b4ed6a069d..ace56536e9 100644 --- a/tests/topotests/isis-topo1-vrf/r5/r5_topology.json +++ b/tests/topotests/isis-topo1-vrf/r5/r5_topology.json @@ -4,121 +4,121 @@ "ipv4": [ { "vertex": "r5" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r5(4)", + "type": "IP internal", "vertex": "10.0.10.0/24" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP", + "metric": "0", + "parent": "r5(4)", + "type": "IP internal", "vertex": "10.0.11.0/24" - }, + }, { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r5(4)", - "type": "TE-IS", + "interface": "r5-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r5(4)", + "type": "TE-IS", "vertex": "r3" - }, + }, { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r5(4)", - "type": "TE-IS", + "interface": "r5-eth1", + "metric": "10", + "next-hop": "r4", + "parent": "r5(4)", + "type": "TE-IS", "vertex": "r4" - }, + }, { - "interface": "r3", - "metric": "TE", - "next-hop": "20", - "parent": "r5-eth0", - "type": "IP", + "interface": "r5-eth0", + "metric": "20", + "next-hop": "r3", + "parent": "r3(4)", + "type": "IP TE", "vertex": "10.0.20.0/24" - }, + }, { - "interface": "r3", - "metric": "TE", - "next-hop": "20", - "parent": "r5-eth0", - "type": "IP", + "interface": "r5-eth0", + "metric": "20", + "next-hop": "r3", + "parent": "r3(4)", + "type": "IP TE", "vertex": "10.0.10.0/24" - }, + }, { - "interface": "r4", - "metric": "TE", - "next-hop": "20", - "parent": "r5-eth1", - "type": "IP", + "interface": "r5-eth1", + "metric": "20", + "next-hop": "r4", + "parent": "r4(4)", + "type": "IP TE", "vertex": "10.0.21.0/24" - }, + }, { - "interface": "r4", - "metric": "TE", - "next-hop": "20", - "parent": "r5-eth1", - "type": "IP", + "interface": "r5-eth1", + "metric": "20", + "next-hop": "r4", + "parent": "r4(4)", + "type": "IP TE", "vertex": "10.0.11.0/24" } - ], + ], "ipv6": [ { "vertex": "r5" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r5(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:1::/64" - }, + }, { - "metric": "internal", - "parent": "0", - "type": "IP6", + "metric": "0", + "parent": "r5(4)", + "type": "IP6 internal", "vertex": "2001:db8:2:2::/64" - }, + }, { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r5(4)", - "type": "TE-IS", + "interface": "r5-eth0", + "metric": "10", + "next-hop": "r3", + "parent": "r5(4)", + "type": "TE-IS", "vertex": "r3" - }, + }, { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r5(4)", - "type": "TE-IS", + "interface": "r5-eth1", + "metric": "10", + "next-hop": "r4", + "parent": "r5(4)", + "type": "TE-IS", "vertex": "r4" - }, + }, { - "interface": "r3", - "metric": "internal", - "next-hop": "20", - "parent": "r5-eth0", - "type": "IP6", + "interface": "r5-eth0", + "metric": "20", + "next-hop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:1::/64" - }, + }, { - "interface": "r4", - "metric": "internal", - "next-hop": "20", - "parent": "r5-eth1", - "type": "IP6", + "interface": "r5-eth1", + "metric": "20", + "next-hop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", "vertex": "2001:db8:1:2::/64" } ] - }, + }, "level-2": { - "ipv4": [], + "ipv4": [], "ipv6": [] } } -}
\ No newline at end of file +} diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py index ae904ba69e..b7fe0c2ddb 100644 --- a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py @@ -41,12 +41,29 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from lib.topotest import iproute2_is_vrf_capable -from lib.common_config import required_linux_kernel_version +from lib.common_config import ( + required_linux_kernel_version, + adjust_router_l3mdev, +) from mininet.topo import Topo pytestmark = [pytest.mark.isisd] +VERTEX_TYPE_LIST = [ + "pseudo_IS", + "pseudo_TE-IS", + "IS", + "TE-IS", + "ES", + "IP internal", + "IP external", + "IP TE", + "IP6 internal", + "IP6 external", + "UNKNOWN", +] + class ISISTopo1(Topo): "Simple two layer ISIS vrf topology" @@ -93,22 +110,6 @@ def setup_module(mod): tgen.start_topology() logger.info("Testing with VRF Lite support") - krel = platform.release() - - # May need to adjust handling of vrf traffic depending on kernel version - l3mdev_accept = 0 - if ( - topotest.version_cmp(krel, "4.15") >= 0 - and topotest.version_cmp(krel, "4.18") <= 0 - ): - l3mdev_accept = 1 - - if topotest.version_cmp(krel, "5.0") >= 0: - l3mdev_accept = 1 - - logger.info( - "krel '{0}' setting net.ipv4.tcp_l3mdev_accept={1}".format(krel, l3mdev_accept) - ) cmds = [ "ip link add {0}-cust1 type vrf table 1001", @@ -122,15 +123,9 @@ def setup_module(mod): # create VRF rx-cust1 and link rx-eth0 to rx-cust1 for cmd in cmds: output = tgen.net[rname].cmd(cmd.format(rname)) - output = tgen.net[rname].cmd("sysctl -n net.ipv4.tcp_l3mdev_accept") - logger.info( - "router {0}: existing tcp_l3mdev_accept was {1}".format(rname, output) - ) - if l3mdev_accept: - output = tgen.net[rname].cmd( - "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept) - ) + # adjust handling of vrf traffic + adjust_router_l3mdev(tgen, rname) for rname, router in tgen.routers().items(): router.load_config( @@ -316,6 +311,7 @@ def parse_topology(lines, level): areas = {} area = None ipv = None + vertex_type_regex = "|".join(VERTEX_TYPE_LIST) for line in lines: area_match = re.match(r"Area (.+):", line) @@ -335,44 +331,57 @@ def parse_topology(lines, level): ipv = "ipv4" continue - item_match = re.match(r"([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)", line) - if item_match is not None: + item_match = re.match( + r"([^\s]+) ([^\s]+) ([^\s]+) ([^\s]+) ([^\s]+) ([^\s]+)", line + ) + if ( + item_match is not None + and item_match.group(1) == "Vertex" + and item_match.group(2) == "Type" + and item_match.group(3) == "Metric" + and item_match.group(4) == "Next-Hop" + and item_match.group(5) == "Interface" + and item_match.group(6) == "Parent" + ): # Skip header - if ( - item_match.group(1) == "Vertex" - and item_match.group(2) == "Type" - and item_match.group(3) == "Metric" - and item_match.group(4) == "Next-Hop" - and item_match.group(5) == "Interface" - and item_match.group(6) == "Parent" - ): - continue + continue + item_match = re.match( + r"([^\s]+) ({}) ([0]|([1-9][0-9]*)) ([^\s]+) ([^\s]+) ([^\s]+)".format( + vertex_type_regex + ), + line, + ) + if item_match is not None: areas[area][level][ipv].append( { "vertex": item_match.group(1), "type": item_match.group(2), "metric": item_match.group(3), - "next-hop": item_match.group(4), - "interface": item_match.group(5), - "parent": item_match.group(6), + "next-hop": item_match.group(5), + "interface": item_match.group(6), + "parent": item_match.group(7), } ) continue - item_match = re.match(r"([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)", line) + item_match = re.match( + r"([^\s]+) ({}) ([0]|([1-9][0-9]*)) ([^\s]+)".format(vertex_type_regex), + line, + ) + if item_match is not None: areas[area][level][ipv].append( { "vertex": item_match.group(1), "type": item_match.group(2), "metric": item_match.group(3), - "parent": item_match.group(4), + "parent": item_match.group(5), } ) continue - item_match = re.match(r"([^ ]+)", line) + item_match = re.match(r"([^\s]+)", line) if item_match is not None: areas[area][level][ipv].append({"vertex": item_match.group(1)}) continue diff --git a/tests/topotests/ldp-snmp/test_ldp_snmp_topo1.py b/tests/topotests/ldp-snmp/test_ldp_snmp_topo1.py index 4144f9b261..f47d906157 100644 --- a/tests/topotests/ldp-snmp/test_ldp_snmp_topo1.py +++ b/tests/topotests/ldp-snmp/test_ldp_snmp_topo1.py @@ -141,15 +141,16 @@ def setup_module(mod): TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) ) router.load_config( - TopoRouter.RD_LDP, os.path.join(CWD, "{}/ldpd.conf".format(rname)), - "-M snmp" + TopoRouter.RD_LDP, + os.path.join(CWD, "{}/ldpd.conf".format(rname)), + "-M snmp", ) router.load_config( - TopoRouter.RD_SNMP, os.path.join(CWD, "{}/snmpd.conf".format(rname)), - "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap" + TopoRouter.RD_SNMP, + os.path.join(CWD, "{}/snmpd.conf".format(rname)), + "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap", ) - tgen.start_router() @@ -199,7 +200,7 @@ def test_rib(): # Skip if previous fatal error condition is raised # TODO: disabling this check to avoid 'snmpd not running' errors - #if tgen.routers_have_failure(): + # if tgen.routers_have_failure(): # pytest.skip(tgen.errors) for rname in ["r1", "r2", "r3"]: @@ -212,7 +213,7 @@ def test_ldp_adjacencies(): # Skip if previous fatal error condition is raised # TODO: disabling this check to avoid 'snmpd not running' errors - #if tgen.routers_have_failure(): + # if tgen.routers_have_failure(): # pytest.skip(tgen.errors) for rname in ["r1", "r2", "r3"]: @@ -226,7 +227,7 @@ def test_ldp_neighbors(): tgen = get_topogen() # Skip if previous fatal error condition is raised - #if tgen.routers_have_failure(): + # if tgen.routers_have_failure(): # pytest.skip(tgen.errors) for rname in ["r1", "r2", "r3"]: @@ -242,8 +243,8 @@ def test_r1_ldp_lsr_objects(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") - assert r1_snmp.test_oid('mplsLdpLsrId', "01 01 01 01") - assert r1_snmp.test_oid('mplsLdpLsrLoopDetectionCapable', 'none(1)') + assert r1_snmp.test_oid("mplsLdpLsrId", "01 01 01 01") + assert r1_snmp.test_oid("mplsLdpLsrLoopDetectionCapable", "none(1)") def test_r1_ldp_entity_table(): @@ -253,52 +254,31 @@ def test_r1_ldp_entity_table(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityLdpId', ['1.1.1.1:0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityIndex', ['1']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityProtocolVersion', ['1']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityAdminStatus', ['enable(1)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityOperStatus', ['enabled(2)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityTcpPort', ['646']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityUdpDscPort', ['646']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityMaxPduLength', ['4096 octets']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityKeepAliveHoldTimer', ['180 seconds']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityHelloHoldTimer', ['0 seconds']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityInitSessionThreshold', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityLabelDistMethod', ['downstreamUnsolicited(2)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityLabelRetentionMode', ['liberal(2)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityPathVectorLimit', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityHopCountLimit', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityTransportAddrKind', ['loopback(2)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityTargetPeer', ['true(1)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityTargetPeerAddrType', ['ipv4(1)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityTargetPeerAddr', ['01 01 01 01']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityLabelType', ['generic(1)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityDiscontinuityTime', ['(0) 0:00:00.00']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStorageType', ['nonVolatile(3)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityRowStatus', ['createAndGo(4)']) + assert r1_snmp.test_oid_walk("mplsLdpEntityLdpId", ["1.1.1.1:0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityIndex", ["1"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityProtocolVersion", ["1"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityAdminStatus", ["enable(1)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityOperStatus", ["enabled(2)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityTcpPort", ["646"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityUdpDscPort", ["646"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityMaxPduLength", ["4096 octets"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityKeepAliveHoldTimer", ["180 seconds"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityHelloHoldTimer", ["0 seconds"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityInitSessionThreshold", ["0"]) + assert r1_snmp.test_oid_walk( + "mplsLdpEntityLabelDistMethod", ["downstreamUnsolicited(2)"] + ) + assert r1_snmp.test_oid_walk("mplsLdpEntityLabelRetentionMode", ["liberal(2)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityPathVectorLimit", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityHopCountLimit", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityTransportAddrKind", ["loopback(2)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityTargetPeer", ["true(1)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityTargetPeerAddrType", ["ipv4(1)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityTargetPeerAddr", ["01 01 01 01"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityLabelType", ["generic(1)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityDiscontinuityTime", ["(0) 0:00:00.00"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStorageType", ["nonVolatile(3)"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityRowStatus", ["createAndGo(4)"]) def test_r1_ldp_entity_stats_table(): @@ -308,32 +288,23 @@ def test_r1_ldp_entity_stats_table(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsSessionAttempts", ["0"]) assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsSessionAttempts', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsSessionRejectedNoHelloErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsSessionRejectedAdErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsSessionRejectedMaxPduErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsSessionRejectedLRErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsBadLdpIdentifierErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsBadPduLengthErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsBadMessageLengthErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsBadTlvLengthErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsMalformedTlvValueErrors', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsKeepAliveTimerExpErrors', ['0']) + "mplsLdpEntityStatsSessionRejectedNoHelloErrors", ["0"] + ) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsSessionRejectedAdErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsSessionRejectedMaxPduErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsSessionRejectedLRErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsBadLdpIdentifierErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsBadPduLengthErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsBadMessageLengthErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsBadTlvLengthErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsMalformedTlvValueErrors", ["0"]) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsKeepAliveTimerExpErrors", ["0"]) assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsShutdownReceivedNotifications', ['0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpEntityStatsShutdownSentNotifications', ['0']) + "mplsLdpEntityStatsShutdownReceivedNotifications", ["0"] + ) + assert r1_snmp.test_oid_walk("mplsLdpEntityStatsShutdownSentNotifications", ["0"]) def test_r1_ldp_peer_table(): @@ -343,17 +314,16 @@ def test_r1_ldp_peer_table(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") + assert r1_snmp.test_oid_walk("mplsLdpPeerLdpId", ["2.2.2.2:0", "3.3.3.3:0"]) assert r1_snmp.test_oid_walk( - 'mplsLdpPeerLdpId', ['2.2.2.2:0', '3.3.3.3:0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpPeerLabelDistMethod', - ['downstreamUnsolicited(2)', 'downstreamUnsolicited(2)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpPeerPathVectorLimit', ['0', '0']) + "mplsLdpPeerLabelDistMethod", + ["downstreamUnsolicited(2)", "downstreamUnsolicited(2)"], + ) + assert r1_snmp.test_oid_walk("mplsLdpPeerPathVectorLimit", ["0", "0"]) + assert r1_snmp.test_oid_walk("mplsLdpPeerTransportAddrType", ["ipv4(1)", "ipv4(1)"]) assert r1_snmp.test_oid_walk( - 'mplsLdpPeerTransportAddrType', ['ipv4(1)', 'ipv4(1)']) - assert r1_snmp.test_oid_walk( - 'mplsLdpPeerTransportAddr', ['02 02 02 02', '03 03 03 03']) + "mplsLdpPeerTransportAddr", ["02 02 02 02", "03 03 03 03"] + ) def test_r1_ldp_session_table(): @@ -363,18 +333,20 @@ def test_r1_ldp_session_table(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") - assert r1_snmp.test_oid_walk('mplsLdpSessionState', - ['operational(5)', 'operational(5)']) - assert r1_snmp.test_oid_walk('mplsLdpSessionRole', - ['passive(3)', 'passive(3)']) - assert r1_snmp.test_oid_walk('mplsLdpSessionProtocolVersion', - ['1', '1']) - assert r1_snmp.test_oid_walk('mplsLdpSessionKeepAliveTime', - ['180 seconds', '180 seconds']) - assert r1_snmp.test_oid_walk('mplsLdpSessionMaxPduLength', - ['4096 octets', '4096 octets']) - assert r1_snmp.test_oid_walk('mplsLdpSessionDiscontinuityTime', - ['(0) 0:00:00.00', '(0) 0:00:00.00']) + assert r1_snmp.test_oid_walk( + "mplsLdpSessionState", ["operational(5)", "operational(5)"] + ) + assert r1_snmp.test_oid_walk("mplsLdpSessionRole", ["passive(3)", "passive(3)"]) + assert r1_snmp.test_oid_walk("mplsLdpSessionProtocolVersion", ["1", "1"]) + assert r1_snmp.test_oid_walk( + "mplsLdpSessionKeepAliveTime", ["180 seconds", "180 seconds"] + ) + assert r1_snmp.test_oid_walk( + "mplsLdpSessionMaxPduLength", ["4096 octets", "4096 octets"] + ) + assert r1_snmp.test_oid_walk( + "mplsLdpSessionDiscontinuityTime", ["(0) 0:00:00.00", "(0) 0:00:00.00"] + ) def test_r1_ldp_session_stats_table(): @@ -384,10 +356,8 @@ def test_r1_ldp_session_stats_table(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") - assert r1_snmp.test_oid_walk( - 'mplsLdpSessionStatsUnknownMesTypeErrors', ['0', '0']) - assert r1_snmp.test_oid_walk( - 'mplsLdpSessionStatsUnknownTlvErrors', ['0', '0']) + assert r1_snmp.test_oid_walk("mplsLdpSessionStatsUnknownMesTypeErrors", ["0", "0"]) + assert r1_snmp.test_oid_walk("mplsLdpSessionStatsUnknownTlvErrors", ["0", "0"]) def test_r1_ldp_hello_adjacency_table(): @@ -397,12 +367,11 @@ def test_r1_ldp_hello_adjacency_table(): r1 = tgen.net.get("r1") r1_snmp = SnmpTester(r1, "1.1.1.1", "public", "2c") - assert r1_snmp.test_oid_walk('mplsLdpHelloAdjacencyIndex', - ['1', '2', '1']) - assert r1_snmp.test_oid_walk('mplsLdpHelloAdjacencyHoldTime', - ['15', '45', '15']) - assert r1_snmp.test_oid_walk('mplsLdpHelloAdjacencyType', - ['link(1)', 'targeted(2)', 'link(1)']) + assert r1_snmp.test_oid_walk("mplsLdpHelloAdjacencyIndex", ["1", "2", "1"]) + assert r1_snmp.test_oid_walk("mplsLdpHelloAdjacencyHoldTime", ["15", "45", "15"]) + assert r1_snmp.test_oid_walk( + "mplsLdpHelloAdjacencyType", ["link(1)", "targeted(2)", "link(1)"] + ) # Memory leak test template diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 867831e114..d2212d1807 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -43,7 +43,7 @@ from lib.common_config import ( run_frr_cmd, FRRCFG_FILE, retry, - get_ipv6_linklocal_address + get_ipv6_linklocal_address, ) LOGDIR = "/tmp/topotests/" @@ -1582,7 +1582,7 @@ def verify_bgp_convergence_from_running_config(tgen, dut=None): return True -def clear_bgp(tgen, addr_type, router, vrf=None): +def clear_bgp(tgen, addr_type, router, vrf=None, neighbor=None): """ This API is to clear bgp neighborship by running clear ip bgp */clear bgp ipv6 * command, @@ -1593,6 +1593,7 @@ def clear_bgp(tgen, addr_type, router, vrf=None): * `addr_type`: ip type ipv4/ipv6 * `router`: device under test * `vrf`: vrf name + * `neighbor`: Neighbor for which bgp needs to be cleared Usage ----- @@ -1616,12 +1617,16 @@ def clear_bgp(tgen, addr_type, router, vrf=None): if vrf: for _vrf in vrf: run_frr_cmd(rnode, "clear ip bgp vrf {} *".format(_vrf)) + elif neighbor: + run_frr_cmd(rnode, "clear bgp ipv4 {}".format(neighbor)) else: run_frr_cmd(rnode, "clear ip bgp *") elif addr_type == "ipv6": if vrf: for _vrf in vrf: run_frr_cmd(rnode, "clear bgp vrf {} ipv6 *".format(_vrf)) + elif neighbor: + run_frr_cmd(rnode, "clear bgp ipv6 {}".format(neighbor)) else: run_frr_cmd(rnode, "clear bgp ipv6 *") else: diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index a4c98924b6..ead593d2ca 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -72,6 +72,59 @@ config.read(PYTESTINI_PATH) config_section = "topogen" +# Debug logs for daemons +DEBUG_LOGS = { + "pimd": [ + "debug msdp events", + "debug msdp packets", + "debug igmp events", + "debug igmp trace", + "debug mroute", + "debug mroute detail", + "debug pim events", + "debug pim packets", + "debug pim trace", + "debug pim zebra", + "debug pim bsm", + "debug pim packets joins", + "debug pim packets register", + "debug pim nht", + ], + "bgpd": [ + "debug bgp neighbor-events", + "debug bgp updates", + "debug bgp zebra", + "debug bgp nht", + "debug bgp neighbor-events", + "debug bgp graceful-restart", + "debug bgp update-groups", + "debug bgp vpn leak-from-vrf", + "debug bgp vpn leak-to-vrf", + "debug bgp zebr", + "debug bgp updates", + "debug bgp nht", + "debug bgp neighbor-events", + "debug vrf", + ], + "zebra": [ + "debug zebra events", + "debug zebra rib", + "debug zebra vxlan", + "debug zebra nht", + ], + "ospf": [ + "debug ospf event", + "debug ospf ism", + "debug ospf lsa", + "debug ospf nsm", + "debug ospf nssa", + "debug ospf packet all", + "debug ospf sr", + "debug ospf te", + "debug ospf zebra", + ], +} + if config.has_option("topogen", "verbosity"): loglevel = config.get("topogen", "verbosity") loglevel = loglevel.upper() @@ -249,6 +302,7 @@ def create_common_configuration( config_map = OrderedDict( { "general_config": "! FRR General Config\n", + "debug_log_config": "! Debug log Config\n", "interface_config": "! Interfaces Config\n", "static_route": "! Static Route Config\n", "prefix_list": "! Prefix List Config\n", @@ -1052,6 +1106,89 @@ def tcpdump_capture_stop(tgen, router): return True +def create_debug_log_config(tgen, input_dict, build=False): + """ + Enable/disable debug logs for any protocol with defined debug + options and logs would be saved to created log file + + Parameters + ---------- + * `tgen` : Topogen object + * `input_dict` : details to enable debug logs for protocols + * `build` : Only for initial setup phase this is set as True. + + + Usage: + ------ + input_dict = { + "r2": { + "debug":{ + "log_file" : "debug.log", + "enable": ["pimd", "zebra"], + "disable": { + "bgpd":[ + 'debug bgp neighbor-events', + 'debug bgp updates', + 'debug bgp zebra', + ] + } + } + } + } + + result = create_debug_log_config(tgen, input_dict) + + Returns + ------- + True or False + """ + + result = False + try: + for router in input_dict.keys(): + debug_config = [] + if "debug" in input_dict[router]: + debug_dict = input_dict[router]["debug"] + + disable_logs = debug_dict.setdefault("disable", None) + enable_logs = debug_dict.setdefault("enable", None) + log_file = debug_dict.setdefault("log_file", None) + + if log_file: + _log_file = os.path.join(LOGDIR, tgen.modname, log_file) + debug_config.append("log file {} \n".format(_log_file)) + + if type(enable_logs) is list: + for daemon in enable_logs: + for debug_log in DEBUG_LOGS[daemon]: + debug_config.append("{}".format(debug_log)) + elif type(enable_logs) is dict: + for daemon, debug_logs in enable_logs.items(): + for debug_log in debug_logs: + debug_config.append("{}".format(debug_log)) + + if type(disable_logs) is list: + for daemon in disable_logs: + for debug_log in DEBUG_LOGS[daemon]: + debug_config.append("no {}".format(debug_log)) + elif type(disable_logs) is dict: + for daemon, debug_logs in disable_logs.items(): + for debug_log in debug_logs: + debug_config.append("no {}".format(debug_log)) + + result = create_common_configuration( + tgen, router, debug_config, "debug_log_config", build=build + ) + except InvalidCLIError: + # Traceback + errormsg = traceback.format_exc() + logger.error(errormsg) + return errormsg + + logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) + return result + + ############################################# # Common APIs, will be used by all protocols ############################################# @@ -3728,7 +3865,7 @@ def get_ipv6_linklocal_address(topo, node, intf): """ tgen = get_topogen() ext_nh = tgen.net[node].get_ipv6_linklocal() - req_nh = topo[node]['links'][intf]['interface'] + req_nh = topo[node]["links"][intf]["interface"] llip = None for llips in ext_nh: if llips[0] == req_nh: @@ -3736,8 +3873,9 @@ def get_ipv6_linklocal_address(topo, node, intf): logger.info("Link local ip found = %s", llip) return llip - errormsg = "Failed: Link local ip not found on router {}, "\ - "interface {}".format(node, intf) + errormsg = "Failed: Link local ip not found on router {}, " "interface {}".format( + node, intf + ) return errormsg @@ -4372,3 +4510,51 @@ def verify_ip_nht(tgen, input_dict): logger.debug("Exiting lib API: verify_ip_nht()") return False + + +def kernel_requires_l3mdev_adjustment(): + """ + Checks if the L3 master device needs to be adjusted to handle VRF traffic + based on kernel version. + + Returns + ------- + 1 or 0 + """ + + if version_cmp(platform.release(), "4.15") >= 0: + return 1 + return 0 + + +def adjust_router_l3mdev(tgen, router): + """ + Adjusts a routers L3 master device to handle VRF traffic depending on kernel + version. + + Parameters + ---------- + * `tgen` : tgen object + * `router` : router id to be configured. + + Returns + ------- + True + """ + + l3mdev_accept = kernel_requires_l3mdev_adjustment() + + logger.info( + "router {0}: setting net.ipv4.tcp_l3mdev_accept={1}".format( + router, l3mdev_accept + ) + ) + + output = tgen.net[router].cmd("sysctl -n net.ipv4.tcp_l3mdev_accept") + logger.info("router {0}: existing tcp_l3mdev_accept was {1}".format(router, output)) + + tgen.net[router].cmd( + "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept) + ) + + return True diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 9f642411b5..04a12d0eec 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -344,9 +344,7 @@ def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config= for lnk in input_dict[router]["links"].keys(): if "ospf" not in input_dict[router]["links"][lnk]: logger.debug( - "Router %s: ospf config is not present in" - "input_dict", - router + "Router %s: ospf config is not present in" "input_dict", router ) continue ospf_data = input_dict[router]["links"][lnk]["ospf"] diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 104b215078..2a46115850 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -54,6 +54,7 @@ from mininet.term import makeTerm g_extra_config = {} + def gdb_core(obj, daemon, corefiles): gdbcmds = """ info threads @@ -545,7 +546,6 @@ def iproute2_is_vrf_capable(): stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, - encoding="utf-8" ) iproute2_err = subp.communicate()[1].splitlines()[0].split()[0] @@ -1346,15 +1346,9 @@ class Router(Node): # Run a command in a new window (gnome-terminal, screen, tmux, xterm) def runInWindow(self, cmd, title=None): topo_terminal = os.getenv("FRR_TOPO_TERMINAL") - if topo_terminal or ( - "TMUX" not in os.environ and "STY" not in os.environ - ): + if topo_terminal or ("TMUX" not in os.environ and "STY" not in os.environ): term = topo_terminal if topo_terminal else "xterm" - makeTerm( - self, - title=title if title else cmd, - term=term, - cmd=cmd) + makeTerm(self, title=title if title else cmd, term=term, cmd=cmd) else: nscmd = "sudo nsenter -m -n -t {} {}".format(self.pid, cmd) if "TMUX" in os.environ: @@ -1363,9 +1357,7 @@ class Router(Node): cmd = "{} {}".format(wcmd, nscmd) elif "STY" in os.environ: if os.path.exists( - "/run/screen/S-{}/{}".format( - os.environ['USER'], os.environ['STY'] - ) + "/run/screen/S-{}/{}".format(os.environ["USER"], os.environ["STY"]) ): wcmd = "screen" else: @@ -1373,7 +1365,6 @@ class Router(Node): cmd = "{} {}".format(wcmd, nscmd) self.cmd(cmd) - def startRouter(self, tgen=None): # Disable integrated-vtysh-config self.cmd( @@ -1460,7 +1451,7 @@ class Router(Node): def startRouterDaemons(self, daemons=None): "Starts all FRR daemons for this router." - gdb_breakpoints = g_extra_config["gdb_breakpoints"] + gdb_breakpoints = g_extra_config["gdb_breakpoints"] gdb_daemons = g_extra_config["gdb_daemons"] gdb_routers = g_extra_config["gdb_routers"] @@ -1521,12 +1512,10 @@ class Router(Node): if ( (gdb_routers or gdb_daemons) - and (not gdb_routers - or self.name in gdb_routers - or "all" in gdb_routers) - and (not gdb_daemons - or daemon in gdb_daemons - or "all" in gdb_daemons) + and ( + not gdb_routers or self.name in gdb_routers or "all" in gdb_routers + ) + and (not gdb_daemons or daemon in gdb_daemons or "all" in gdb_daemons) ): if daemon == "snmpd": cmdopt += " -f " @@ -1547,7 +1536,6 @@ class Router(Node): self.cmd(" ".join([cmdenv, binary, cmdopt])) logger.info("{}: {} {} started".format(self, self.routertype, daemon)) - # Start Zebra first if "zebra" in daemons_list: start_daemon("zebra", "-s 90000000") diff --git a/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py b/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py index 6b7180978e..cd398a5111 100644 --- a/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py +++ b/tests/topotests/multicast-pim-bsm-topo1/test_mcast_pim_bsmp_01.py @@ -648,7 +648,11 @@ def test_BSR_CRP_with_blackhole_address_p1(request): input_dict = { "i1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": next_hop_rp}]}, "l1": {"static_routes": [{"network": BSR1_ADDR, "next_hop": next_hop_lhr}]}, - "f1": {"static_routes": [{"network": CRP, "next_hop": next_hop_fhr, "delete": True}]}, + "f1": { + "static_routes": [ + {"network": CRP, "next_hop": next_hop_fhr, "delete": True} + ] + }, } result = create_static_routes(tgen, input_dict) @@ -692,10 +696,11 @@ def test_BSR_CRP_with_blackhole_address_p1(request): step("Verify if b1 chosen as BSR in l1") result = verify_pim_bsr(tgen, topo, "l1", BSR_IP_1, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "b1 is not chosen as BSR in l1 \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "b1 is not chosen as BSR in l1 \n Error: {}".format( tc_name, result - )) + ) state_after = verify_pim_interface_traffic(tgen, state_dict) assert isinstance( @@ -841,10 +846,12 @@ def test_new_router_fwd_p0(request): # Verify bsr state in l1 step("Verify no BSR in l1 as i1 would not forward the no-forward bsm") result = verify_pim_bsr(tgen, topo, "l1", bsr_ip, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "BSR data is present after no-forward bsm also \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) # unconfigure unicast bsm on f1-i1-eth2 step("unconfigure unicast bsm on f1-i1-eth2, will forward with only mcast") @@ -966,10 +973,11 @@ def test_int_bsm_config_p1(request): result = verify_ip_mroutes( tgen, "i1", src_addr, GROUP_ADDRESS, iif, oil, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "Mroutes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "Mroutes are still present \n Error: {}".format( tc_name, result - )) + ) # unconfigure bsm processing on f1 on f1-i1-eth2 step("unconfigure bsm processing on f1 in f1-i1-eth2, will drop bsm") @@ -989,20 +997,21 @@ def test_int_bsm_config_p1(request): # Verify bsr state in i1 step("Verify if b1 is not chosen as BSR in i1") result = verify_pim_bsr(tgen, topo, "i1", bsr_ip, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "b1 is chosen as BSR in i1 \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "b1 is chosen as BSR in i1 \n Error: {}".format( tc_name, result - )) + ) # check if mroute still not installed because of rp not available step("check if mroute still not installed because of rp not available") result = verify_ip_mroutes( tgen, "i1", src_addr, GROUP_ADDRESS, iif, oil, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "mroute installed but rp not available \n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "mroute installed but rp not available \n Error: {}".format(tc_name, result) + ) # configure bsm processing on i1 on f1-i1-eth2 step("configure bsm processing on f1 in f1-i1-eth2, will accept bsm") @@ -1464,10 +1473,11 @@ def test_BSM_timeout_p0(request): tgen, topo, "f1", group, rp_source="BSR", expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "bsr has not aged out in f1 \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "bsr has not aged out in f1 \n Error: {}".format( tc_name, result - )) + ) # Verify RP mapping removed after hold timer expires group = "225.1.1.1/32" @@ -1491,20 +1501,23 @@ def test_BSM_timeout_p0(request): result = verify_join_state_and_timer( tgen, dut, iif, src_addr, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "join state is up and join timer is running in l1 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) # Verify ip mroute is not installed step("Verify mroute not installed in l1") result = verify_ip_mroutes( tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "mroute installed in l1 \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( tc_name, result - )) + ) step("clear BSM database before moving to next case") clear_bsrp_data(tgen, topo) @@ -1657,10 +1670,11 @@ def test_iif_join_state_p0(request): result = verify_ip_mroutes( tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "mroute installed in l1 \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( tc_name, result - )) + ) # Add back route for RP to make it reachable step("Add back route for RP to make it reachable") diff --git a/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py b/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py index 5fc5e52518..199746d5f6 100644 --- a/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py +++ b/tests/topotests/multicast-pim-bsm-topo2/test_mcast_pim_bsmp_02.py @@ -104,6 +104,10 @@ from lib.pim import ( from lib.topolog import logger from lib.topojson import build_topo_from_json, build_config_from_json + +pytestmark = [pytest.mark.pimd] + + # Reading the data from JSON File for topology creation jsonFile = "{}/mcast_pim_bsmp_02.json".format(CWD) try: @@ -454,10 +458,11 @@ def test_starg_mroute_p0(request): result = verify_ip_mroutes( tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, wait=20, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "mroute installed in l1 \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroute installed in l1 \n Error: {}".format( tc_name, result - )) + ) # Send BSM again to configure rp step("Add back RP by sending BSM from b1") @@ -807,10 +812,11 @@ def test_BSR_election_p0(request): # Verify bsr state in FHR step("Verify if b2 is not chosen as bsr in f1") result = verify_pim_bsr(tgen, topo, "f1", bsr_ip2, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "b2 is chosen as bsr in f1 \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "b2 is chosen as bsr in f1 \n Error: {}".format( tc_name, result - )) + ) # Verify if b1 is still chosen as bsr step("Verify if b1 is still chosen as bsr in f1") diff --git a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py index 1c22654541..33f476de44 100755 --- a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py +++ b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo3.py @@ -3487,11 +3487,11 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "upstream is still present after shut the link from " - "FHR to RP from RP node \n Error: {}".format( - tc_name, result - )) + "FHR to RP from RP node \n Error: {}".format(tc_name, result) + ) step(" No shut the link from FHR to RP from RP node") @@ -3638,11 +3638,11 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "upstream is still present after shut the link from " - "FHR to RP from FHR node \n Error: {}".format( - tc_name, result - )) + "FHR to RP from FHR node \n Error: {}".format(tc_name, result) + ) step(" No shut the link from FHR to RP from FHR node") diff --git a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py index 68b7849c2b..1081b764ac 100755 --- a/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py +++ b/tests/topotests/multicast-pim-sm-topo3/test_multicast_pim_sm_topo4.py @@ -490,10 +490,12 @@ def test_mroute_when_RP_reachable_default_route_p2(request): data["oil"], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "mroutes(S,G) are present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) result = verify_upstream_iif( tgen, @@ -503,10 +505,12 @@ def test_mroute_when_RP_reachable_default_route_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "upstream is present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) for data in input_dict_starg: result = verify_ip_mroutes( @@ -518,10 +522,12 @@ def test_mroute_when_RP_reachable_default_route_p2(request): data["oil"], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "mroutes(*,G) are present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) result = verify_upstream_iif( tgen, @@ -531,10 +537,12 @@ def test_mroute_when_RP_reachable_default_route_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "upstream is present after delete of static routes on c1 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("Configure default routes on c2") @@ -557,10 +565,12 @@ def test_mroute_when_RP_reachable_default_route_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "RP info is unknown after removing static route from c2 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("Verify (s,g) populated after adding default route ") @@ -787,10 +797,11 @@ def test_mroute_with_RP_default_route_all_nodes_p2(request): data["oil"], expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "mroutes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "mroutes are still present \n Error: {}".format( tc_name, result - )) + ) result = verify_upstream_iif( tgen, @@ -800,10 +811,11 @@ def test_mroute_with_RP_default_route_all_nodes_p2(request): IGMP_JOIN_RANGE_1, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "upstream is still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "upstream is still present \n Error: {}".format( tc_name, result - )) + ) step("Configure default routes on all the nodes") @@ -840,10 +852,12 @@ def test_mroute_with_RP_default_route_all_nodes_p2(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_1, "Unknown", rp_address, SOURCE, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "RP info is unknown after removing static route from c2 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("Verify (s,g) populated after adding default route ") diff --git a/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py b/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py index 1317ec67b4..e90230eb3b 100755 --- a/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py +++ b/tests/topotests/multicast-pim-static-rp-topo1/test_multicast_pim_static_rp.py @@ -423,10 +423,12 @@ def test_add_delete_static_RP_p0(request): dut = "r1" interface = "r1-r0-eth0" result = verify_igmp_groups(tgen, dut, interface, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: igmp group present without any IGMP join \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r1: Verify show ip pim interface traffic without any IGMP join") state_dict = {"r1": {"r1-r2-eth1": ["pruneTx"]}} @@ -492,26 +494,29 @@ def test_add_delete_static_RP_p0(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: RP info present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: RP info present \n Error: {}".format( tc_name, result - )) + ) step("r1: Verify upstream IIF interface") result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: upstream IIF interface present \n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: upstream IIF interface present \n Error: {}".format(tc_name, result) + ) step("r1: Verify upstream join state and join timer") result = verify_join_state_and_timer( tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: upstream join state is up and join timer is running \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r1: Verify PIM state") result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) @@ -521,10 +526,11 @@ def test_add_delete_static_RP_p0(request): step("r1: Verify ip mroutes") result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: mroutes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: mroutes are still present \n Error: {}".format( tc_name, result - )) + ) step("r1: Verify show ip pim interface traffic without any IGMP join") state_after = verify_pim_interface_traffic(tgen, state_dict) @@ -681,10 +687,12 @@ def test_SPT_RPT_path_same_p1(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S, G) upstream join state is up and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r2-eth1" @@ -811,17 +819,19 @@ def test_not_reachable_static_RP_p0(request): "using show ip pim state" ) result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "OIL is not same and IIF is not cleared on R1 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream") result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: upstream IIF is not unknown \n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: upstream IIF is not unknown \n Error: {}".format(tc_name, result) + ) step( "r1: join state should not be joined and join timer should stop," @@ -830,10 +840,12 @@ def test_not_reachable_static_RP_p0(request): result = verify_join_state_and_timer( tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: join state is joined and timer is not stopped \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step( "r1: (*,G) prune is sent towards the RP interface, verify using" @@ -850,10 +862,12 @@ def test_not_reachable_static_RP_p0(request): step("r1: (*, G) cleared from mroute table using show ip mroute") result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: (*, G) are not cleared from mroute table \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) logger.info("Expected behavior: {}".format(result)) # Uncomment next line for debugging @@ -920,10 +934,11 @@ def test_add_RP_after_join_received_p1(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: rp-info is present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: rp-info is present \n Error: {}".format( tc_name, result - )) + ) step("joinTx value before join sent") state_dict = {"r1": {"r1-r2-eth1": ["joinTx"]}} @@ -944,34 +959,38 @@ def test_add_RP_after_join_received_p1(request): step("r1: Verify upstream IIF interface") result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: upstream IFF interface is present \n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: upstream IFF interface is present \n Error: {}".format(tc_name, result) + ) step("r1: Verify upstream join state and join timer") result = verify_join_state_and_timer( tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: upstream join state is joined and timer is running \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r1: Verify PIM state") result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: PIM state is up\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format( tc_name, result - )) + ) step("r1: Verify ip mroutes") result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: mroutes are still present\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format( tc_name, result - )) + ) step("r1: Configure static RP") input_dict = { @@ -1095,33 +1114,37 @@ def test_reachable_static_RP_after_join_p0(request): step("r1 : Verify upstream IIF interface") iif = "r1-r2-eth1" result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: upstream IIF interface is present\n Error: {}".format( - tc_name, result - )) + assert result is not True, ( + "Testcase {} : Failed \n " + "r1: upstream IIF interface is present\n Error: {}".format(tc_name, result) + ) step("r1 : Verify upstream join state and join timer") result = verify_join_state_and_timer( tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: upstream join state is joined and timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r1 : Verify PIM state") result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: PIM state is up\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format( tc_name, result - )) + ) step("r1 : Verify ip mroutes") result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: mroutes are still present\n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format( tc_name, result - )) + ) step("r1: Make RP reachable") intf = "r1-r2-eth1" @@ -1362,10 +1385,12 @@ def test_send_join_on_higher_preffered_rp_p1(request): result = verify_pim_rp_info( tgen, topo, dut, GROUP_RANGE, oif, rp_address_2, SOURCE, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: rp-info is present for group 225.1.1.1 \n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step( "r1 : Verify RPF interface updated in mroute when higher preferred" @@ -1619,11 +1644,11 @@ def test_RP_configured_as_LHR_1_p1(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S, G) upstream join state is joined and join" - " timer is running \n Error: {}".format( - tc_name, result - )) + " timer is running \n Error: {}".format(tc_name, result) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -1828,10 +1853,12 @@ def test_RP_configured_as_LHR_2_p1(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -2036,10 +2063,12 @@ def test_RP_configured_as_FHR_1_p1(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -2245,10 +2274,12 @@ def test_RP_configured_as_FHR_2_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -2372,10 +2403,12 @@ def test_SPT_RPT_path_different_p1(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -2394,10 +2427,12 @@ def test_SPT_RPT_path_different_p1(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (S, G) ip mroutes") oif = "none" @@ -2623,10 +2658,12 @@ def test_restart_pimd_process_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -2791,10 +2828,12 @@ def test_multiple_groups_same_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -2813,10 +2852,12 @@ def test_multiple_groups_same_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (S, G) ip mroutes") oif = "none" @@ -2932,10 +2973,12 @@ def test_multiple_groups_same_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (S, G) ip mroutes") oif = "none" @@ -2952,10 +2995,12 @@ def test_multiple_groups_same_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -3132,10 +3177,12 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (S, G) ip mroutes") oif = "none" @@ -3154,10 +3201,12 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -3224,10 +3273,12 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r4: Verify (S, G) ip mroutes") oif = "none" @@ -3399,10 +3450,12 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (S, G) ip mroutes") oif = "none" @@ -3421,10 +3474,12 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -3491,10 +3546,12 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r4: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r4: Verify (S, G) ip mroutes") oif = "none" @@ -3513,10 +3570,12 @@ def test_multiple_groups_different_RP_address_p2(request): result = verify_join_state_and_timer( tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (S, G) ip mroutes") oif = "r3-r1-eth0" @@ -3643,30 +3702,36 @@ def test_shutdown_primary_path_p1(request): iif = "r1-r3-eth2" oif = "r1-r0-eth0" result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (*, G) ip mroutes") dut = "r2" iif = "lo" oif = "r2-r3-eth1" result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: Verify (*, G) ip mroutes") dut = "r3" iif = "r3-r2-eth1" oif = "r3-r1-eth0" result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r3: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r3: No shutdown the link from R1 to R3 from R3 node") dut = "r3" @@ -3826,20 +3891,24 @@ def test_delete_RP_shut_noshut_upstream_interface_p1(request): iif = "r1-r2-eth1" oif = "r1-r0-eth0" result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (*, G) ip mroutes cleared") dut = "r2" iif = "lo" oif = "r2-r1-eth0" result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) write_test_footer(tc_name) @@ -3949,20 +4018,24 @@ def test_delete_RP_shut_noshut_RP_interface_p1(request): iif = "r1-r2-eth1" oif = "r1-r0-eth0" result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) step("r2: Verify (*, G) ip mroutes cleared") dut = "r2" iif = "lo" oif = "r2-r1-eth0" result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r2: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format( - tc_name, result - )) + tc_name, result + ) + ) write_test_footer(tc_name) diff --git a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py index 57b93c3fd5..b6e5e14830 100644 --- a/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py +++ b/tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py @@ -86,6 +86,7 @@ from mininet.topo import Topo pytestmark = [pytest.mark.ospfd] + class TemplateTopo(Topo): "Test topology builder" @@ -385,9 +386,7 @@ def test_rib_ipv4_step5(): pytest.skip(tgen.errors) logger.info("Disabling SR on rt6") - tgen.net["rt6"].cmd( - 'vtysh -c "conf t" -c "router ospf" -c "no segment-routing on"' - ) + tgen.net["rt6"].cmd('vtysh -c "conf t" -c "router ospf" -c "no segment-routing on"') for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( @@ -652,7 +651,7 @@ def test_mpls_lib_step10(): # Expected changes: # -All commands should be rejected # -#def test_ospf_invalid_config_step11(): +# def test_ospf_invalid_config_step11(): # logger.info("Test (step 11): check if invalid configuration is rejected") # tgen = get_topogen() # diff --git a/tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py b/tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py index 1d69f5d699..32f9b3453e 100644 --- a/tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py +++ b/tests/topotests/ospf-te-topo1/test_ospf_te_topo1.py @@ -79,6 +79,7 @@ import pytest pytestmark = [pytest.mark.ospfd] + class OspfTeTopo(Topo): "Test topology builder" @@ -175,6 +176,7 @@ def setup_testcase(msg): # Note that all routers must discover the same Network Topology, so the same TED. + def test_step1(): "Step1: Check initial topology" @@ -190,12 +192,8 @@ def test_step2(): tgen = setup_testcase("Step2: Shutdown interface between r1 & r2") - tgen.net["r1"].cmd( - 'vtysh -c "conf t" -c "interface r1-eth1" -c "shutdown"' - ) - tgen.net["r2"].cmd( - 'vtysh -c "conf t" -c "interface r2-eth1" -c "shutdown"' - ) + tgen.net["r1"].cmd('vtysh -c "conf t" -c "interface r1-eth1" -c "shutdown"') + tgen.net["r2"].cmd('vtysh -c "conf t" -c "interface r2-eth1" -c "shutdown"') for rname in ["r1", "r2", "r3", "r4"]: compare_ted_json_output(tgen, rname, "ted_step2.json") @@ -207,9 +205,7 @@ def test_step3(): tgen = setup_testcase("Step3: Disable Inter-AS on r3") - tgen.net["r3"].cmd( - 'vtysh -c "conf t" -c "router ospf" -c "no mpls-te inter-as"' - ) + tgen.net["r3"].cmd('vtysh -c "conf t" -c "router ospf" -c "no mpls-te inter-as"') for rname in ["r1", "r2", "r3", "r4"]: compare_ted_json_output(tgen, rname, "ted_step3.json") @@ -221,18 +217,14 @@ def test_step4(): tgen = setup_testcase("Step4: Enable Segment Routing on r1 & r2") - tgen.net["r1"].cmd( - 'vtysh -c "conf t" -c "router ospf" -c "segment-routing on"' - ) + tgen.net["r1"].cmd('vtysh -c "conf t" -c "router ospf" -c "segment-routing on"') tgen.net["r1"].cmd( 'vtysh -c "conf t" -c "router ospf" -c "segment-routing global-block 20000 23999"' ) tgen.net["r1"].cmd( 'vtysh -c "conf t" -c "router ospf" -c "segment-routing prefix 10.0.255.1/32 index 10"' ) - tgen.net["r2"].cmd( - 'vtysh -c "conf t" -c "router ospf" -c "segment-routing on"' - ) + tgen.net["r2"].cmd('vtysh -c "conf t" -c "router ospf" -c "segment-routing on"') tgen.net["r2"].cmd( 'vtysh -c "conf t" -c "router ospf" -c "segment-routing node-msd 16"' ) @@ -253,12 +245,8 @@ def test_step5(): tgen = setup_testcase("Step5: Re-enable interface between r1 & r2") - tgen.net["r1"].cmd( - 'vtysh -c "conf t" -c "interface r1-eth1" -c "no shutdown"' - ) - tgen.net["r2"].cmd( - 'vtysh -c "conf t" -c "interface r2-eth1" -c "no shutdown"' - ) + tgen.net["r1"].cmd('vtysh -c "conf t" -c "interface r1-eth1" -c "no shutdown"') + tgen.net["r2"].cmd('vtysh -c "conf t" -c "interface r2-eth1" -c "no shutdown"') for rname in ["r1", "r2", "r3", "r4"]: compare_ted_json_output(tgen, rname, "ted_step5.json") @@ -291,9 +279,7 @@ def test_step7(): tgen = setup_testcase("Step7: Disable OSPF on r4") - tgen.net["r4"].cmd( - 'vtysh -c "conf t" -c "no router ospf"' - ) + tgen.net["r4"].cmd('vtysh -c "conf t" -c "no router ospf"') for rname in ["r1", "r2", "r3"]: compare_ted_json_output(tgen, rname, "ted_step7.json") diff --git a/tests/topotests/ospf-topo1/r1/ospf6d.conf-pre-v4 b/tests/topotests/ospf-topo1/r1/ospf6d.conf-pre-v4 deleted file mode 100644 index 6a40f859db..0000000000 --- a/tests/topotests/ospf-topo1/r1/ospf6d.conf-pre-v4 +++ /dev/null @@ -1,9 +0,0 @@ -! -router ospf6 - router-id 10.0.255.1 - redistribute kernel - redistribute connected - redistribute static - interface r1-eth0 area 0.0.0.0 - interface r1-eth1 area 0.0.0.0 -! diff --git a/tests/topotests/ospf-topo1/r2/ospf6d.conf-pre-v4 b/tests/topotests/ospf-topo1/r2/ospf6d.conf-pre-v4 deleted file mode 100644 index 7448b25327..0000000000 --- a/tests/topotests/ospf-topo1/r2/ospf6d.conf-pre-v4 +++ /dev/null @@ -1,9 +0,0 @@ -! -router ospf6 - router-id 10.0.255.2 - redistribute kernel - redistribute connected - redistribute static - interface r2-eth0 area 0.0.0.0 - interface r2-eth1 area 0.0.0.0 -! diff --git a/tests/topotests/ospf-topo1/r3/ospf6d.conf-pre-v4 b/tests/topotests/ospf-topo1/r3/ospf6d.conf-pre-v4 deleted file mode 100644 index e853e0e2b2..0000000000 --- a/tests/topotests/ospf-topo1/r3/ospf6d.conf-pre-v4 +++ /dev/null @@ -1,10 +0,0 @@ -! -router ospf6 - router-id 10.0.255.3 - redistribute kernel - redistribute connected - redistribute static - interface r3-eth0 area 0.0.0.0 - interface r3-eth1 area 0.0.0.0 - interface r3-eth2 area 0.0.0.1 -! diff --git a/tests/topotests/ospf-topo1/r4/ospf6d.conf-pre-v4 b/tests/topotests/ospf-topo1/r4/ospf6d.conf-pre-v4 deleted file mode 100644 index dcc07a4fdc..0000000000 --- a/tests/topotests/ospf-topo1/r4/ospf6d.conf-pre-v4 +++ /dev/null @@ -1,9 +0,0 @@ -! -router ospf6 - router-id 10.0.255.4 - redistribute kernel - redistribute connected - redistribute static - interface r4-eth0 area 0.0.0.1 - interface r4-eth1 area 0.0.0.1 -! diff --git a/tests/topotests/ospf-topo1/test_ospf_topo1.py b/tests/topotests/ospf-topo1/test_ospf_topo1.py index 5bb6c2c818..42634ce906 100644 --- a/tests/topotests/ospf-topo1/test_ospf_topo1.py +++ b/tests/topotests/ospf-topo1/test_ospf_topo1.py @@ -93,8 +93,6 @@ def setup_module(mod): tgen.start_topology() ospf6_config = "ospf6d.conf" - if tgen.gears["r1"].has_version("<", "4.0"): - ospf6_config = "ospf6d.conf-pre-v4" router_list = tgen.routers() for rname, router in router_list.items(): @@ -118,6 +116,88 @@ def teardown_module(mod): tgen.stop_topology() +def test_wait_protocol_convergence(): + "Wait for OSPFv2/OSPFv3 to converge" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for protocols to converge") + + def expect_ospfv2_neighbor_full(router, neighbor): + "Wait until OSPFv2 convergence." + logger.info("waiting OSPFv2 router '{}'".format(router)) + + def run_command_and_expect(): + """ + Function that runs command and expect the following outcomes: + * Full/DR + * Full/DROther + * Full/Backup + """ + result = tgen.gears[router].vtysh_cmd( + "show ip ospf neighbor json", isjson=True + ) + if ( + topotest.json_cmp( + result, {"neighbors": {neighbor: [{"state": "Full/DR"}]}} + ) + is None + ): + return None + + if ( + topotest.json_cmp( + result, {"neighbors": {neighbor: [{"state": "Full/DROther"}]}} + ) + is None + ): + return None + + return topotest.json_cmp( + result, {"neighbors": {neighbor: [{"state": "Full/Backup"}]}} + ) + + _, result = topotest.run_and_expect( + run_command_and_expect, None, count=130, wait=1 + ) + assertmsg = '"{}" convergence failure'.format(router) + assert result is None, assertmsg + + def expect_ospfv3_neighbor_full(router, neighbor): + "Wait until OSPFv3 convergence." + logger.info("waiting OSPFv3 router '{}'".format(router)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ipv6 ospf6 neighbor json", + {"neighbors": [{"neighborId": neighbor, "state": "Full"}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = '"{}" convergence failure'.format(router) + assert result is None, assertmsg + + # Wait for OSPFv2 convergence + expect_ospfv2_neighbor_full("r1", "10.0.255.2") + expect_ospfv2_neighbor_full("r1", "10.0.255.3") + expect_ospfv2_neighbor_full("r2", "10.0.255.1") + expect_ospfv2_neighbor_full("r2", "10.0.255.3") + expect_ospfv2_neighbor_full("r3", "10.0.255.1") + expect_ospfv2_neighbor_full("r3", "10.0.255.2") + expect_ospfv2_neighbor_full("r3", "10.0.255.4") + expect_ospfv2_neighbor_full("r4", "10.0.255.3") + + # Wait for OSPFv3 convergence + expect_ospfv3_neighbor_full("r1", "10.0.255.2") + expect_ospfv3_neighbor_full("r1", "10.0.255.3") + expect_ospfv3_neighbor_full("r2", "10.0.255.1") + expect_ospfv3_neighbor_full("r2", "10.0.255.3") + expect_ospfv3_neighbor_full("r3", "10.0.255.1") + expect_ospfv3_neighbor_full("r3", "10.0.255.2") + expect_ospfv3_neighbor_full("r3", "10.0.255.4") + expect_ospfv3_neighbor_full("r4", "10.0.255.3") + + def compare_show_ipv6_ospf6(rname, expected): """ Calls 'show ipv6 ospf6 route' for router `rname` and compare the obtained diff --git a/tests/topotests/ospf6-topo1/r1/ospf6d.conf b/tests/topotests/ospf6-topo1/r1/ospf6d.conf index ab2c0c647e..9f7e058931 100644 --- a/tests/topotests/ospf6-topo1/r1/ospf6d.conf +++ b/tests/topotests/ospf6-topo1/r1/ospf6d.conf @@ -11,9 +11,13 @@ debug ospf6 flooding ! interface r1-stubnet ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! interface r1-sw5 ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! router ospf6 ospf6 router-id 10.0.0.1 diff --git a/tests/topotests/ospf6-topo1/r2/ospf6d.conf b/tests/topotests/ospf6-topo1/r2/ospf6d.conf index 075e815ed8..26ebc2c0ea 100644 --- a/tests/topotests/ospf6-topo1/r2/ospf6d.conf +++ b/tests/topotests/ospf6-topo1/r2/ospf6d.conf @@ -11,9 +11,13 @@ debug ospf6 flooding ! interface r2-stubnet ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! interface r2-sw5 ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! router ospf6 ospf6 router-id 10.0.0.2 diff --git a/tests/topotests/ospf6-topo1/r3/ospf6d.conf b/tests/topotests/ospf6-topo1/r3/ospf6d.conf index e9a07a7e28..e902496530 100644 --- a/tests/topotests/ospf6-topo1/r3/ospf6d.conf +++ b/tests/topotests/ospf6-topo1/r3/ospf6d.conf @@ -11,12 +11,18 @@ debug ospf6 flooding ! interface r3-stubnet ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! interface r3-sw5 ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! interface r3-sw6 ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! router ospf6 ospf6 router-id 10.0.0.3 diff --git a/tests/topotests/ospf6-topo1/r4/ospf6d.conf b/tests/topotests/ospf6-topo1/r4/ospf6d.conf index fa66645f5a..5607a789de 100644 --- a/tests/topotests/ospf6-topo1/r4/ospf6d.conf +++ b/tests/topotests/ospf6-topo1/r4/ospf6d.conf @@ -11,9 +11,13 @@ debug ospf6 flooding ! interface r4-stubnet ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! interface r4-sw6 ipv6 ospf6 network broadcast + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! router ospf6 ospf6 router-id 10.0.0.4 diff --git a/tests/topotests/ospf6-topo1/test_ospf6_topo1.py b/tests/topotests/ospf6-topo1/test_ospf6_topo1.py index 6ae886b76e..f8c3476e18 100644 --- a/tests/topotests/ospf6-topo1/test_ospf6_topo1.py +++ b/tests/topotests/ospf6-topo1/test_ospf6_topo1.py @@ -185,70 +185,38 @@ def teardown_module(mod): tgen.stop_topology() -def test_ospf6_converged(): - +def test_wait_protocol_convergence(): + "Wait for OSPFv3 to converge" tgen = get_topogen() - - # Don't run this test if we have any failure. if tgen.routers_have_failure(): pytest.skip(tgen.errors) - # For debugging, uncomment the next line - # tgen.mininet_cli() - - # Wait for OSPF6 to converge (All Neighbors in either Full or TwoWay State) - logger.info("Waiting for OSPF6 convergence") - - # Set up for regex - pat1 = re.compile("^[0-9]") - pat2 = re.compile("Full") - - timeout = 60 - while timeout > 0: - logger.info("Timeout in %s: " % timeout), - sys.stdout.flush() - - # Look for any node not yet converged - for router, rnode in tgen.routers().items(): - resStr = rnode.vtysh_cmd("show ipv6 ospf neigh") - - isConverged = False + logger.info("waiting for protocols to converge") - for line in resStr.splitlines(): - res1 = pat1.match(line) - if res1: - isConverged = True - res2 = pat2.search(line) - - if res2 == None: - isConverged = False - break - - if isConverged == False: - logger.info("Waiting for {}".format(router)) - sys.stdout.flush() - break - - if isConverged: - logger.info("Done") - break - else: - sleep(5) - timeout -= 5 + def expect_neighbor_full(router, neighbor): + "Wait until OSPFv3 convergence." + logger.info("waiting OSPFv3 router '{}'".format(router)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ipv6 ospf6 neighbor json", + {"neighbors": [{"neighborId": neighbor, "state": "Full"}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = '"{}" convergence failure'.format(router) + assert result is None, assertmsg - if timeout == 0: - # Bail out with error if a router fails to converge - ospfStatus = rnode.vtysh_cmd("show ipv6 ospf neigh") - assert False, "OSPFv6 did not converge:\n{}".format(ospfStatus) + expect_neighbor_full("r1", "10.0.0.2") + expect_neighbor_full("r1", "10.0.0.3") - logger.info("OSPFv3 converged.") + expect_neighbor_full("r2", "10.0.0.1") + expect_neighbor_full("r2", "10.0.0.3") - # For debugging, uncomment the next line - # tgen.mininet_cli() + expect_neighbor_full("r3", "10.0.0.1") + expect_neighbor_full("r3", "10.0.0.2") + expect_neighbor_full("r3", "10.0.0.4") - # Make sure that all daemons are still running - if tgen.routers_have_failure(): - assert tgen.errors == "", tgen.errors + expect_neighbor_full("r4", "10.0.0.3") def compare_show_ipv6(rname, expected): diff --git a/tests/topotests/ospf6-topo2/test_ospf6_topo2.py b/tests/topotests/ospf6-topo2/test_ospf6_topo2.py index 32aff05982..efc8565bb3 100644 --- a/tests/topotests/ospf6-topo2/test_ospf6_topo2.py +++ b/tests/topotests/ospf6-topo2/test_ospf6_topo2.py @@ -141,12 +141,19 @@ def test_ospf6_default_route(): topotest.router_json_cmp, tgen.gears[router], "show ipv6 ospf6 database inter-prefix detail json", - {"areaScopedLinkStateDb": [{ - "areaId": area, - "lsa": [{ - "prefix": prefix, - "metric": metric, - }]}]}, + { + "areaScopedLinkStateDb": [ + { + "areaId": area, + "lsa": [ + { + "prefix": prefix, + "metric": metric, + } + ], + } + ] + }, ) _, result = topotest.run_and_expect(test_func, None, count=4, wait=1) assertmsg = '"{}" convergence failure'.format(router) diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py index cebe55b39c..c117fc6a72 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py @@ -249,17 +249,20 @@ def test_ospf_chaos_tc31_p1(request): dut = "r1" protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + result = verify_rib( + tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Bring up OSPFd daemon on R0.") start_router_daemons(tgen, "r0", ["ospfd"]) @@ -482,17 +485,20 @@ def test_ospf_chaos_tc34_p1(request): dut = "r1" protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) - result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol, - expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + result = verify_rib( + tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False + ) + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Bring up staticd daemon on R0.") start_router_daemons(tgen, "r0", ["staticd"]) diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py index adf82a5e85..1aabc06db0 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py @@ -259,19 +259,21 @@ def test_ospf_ecmp_tc16_p0(request): shutdown_bringup_interface(tgen, dut, intf, False) result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) protocol = "ospf" result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) for intfr in range(1, 7): intf = topo["routers"]["r1"]["links"]["r0-link{}".format(intfr)]["interface"] @@ -326,10 +328,11 @@ def test_ospf_ecmp_tc16_p0(request): result = verify_ospf_rib( tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) protocol = "ospf" result = verify_rib( @@ -342,10 +345,11 @@ def test_ospf_ecmp_tc16_p0(request): attempts=5, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Re configure the static route in R0.") dut = "r0" @@ -432,10 +436,11 @@ def test_ospf_ecmp_tc17_p0(request): result = verify_ospf_rib( tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) protocol = "ospf" result = verify_rib( @@ -448,10 +453,11 @@ def test_ospf_ecmp_tc17_p0(request): attempts=5, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Reconfigure the static route in R0.Change ECMP value to 2.") dut = "r0" diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py index c5230d6614..e6dc18a434 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py @@ -307,10 +307,11 @@ def test_ospf_lan_ecmp_tc18_p0(request): result = verify_ospf_rib( tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) protocol = "ospf" result = verify_rib( @@ -323,10 +324,11 @@ def test_ospf_lan_ecmp_tc18_p0(request): attempts=5, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py index 2fbb27f4fc..d9b90a132a 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py @@ -397,10 +397,11 @@ def test_ospf_lan_tc1_p0(request): shutdown_bringup_interface(tgen, dut, intf, False) result = verify_ospf_neighbor(tgen, topo, dut, lan=True, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r0: OSPF neighbors-hip is up \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r0: OSPF neighbors-hip is up \n Error: {}".format( tc_name, result - )) + ) step("No Shut interface on R0") dut = "r0" diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py index b99ce6cfb8..7864d0307a 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py @@ -332,18 +332,20 @@ def test_ospf_routemaps_functionality_tc19_p0(request): } } result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are present in fib \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are present in fib \n Error: {}".format( tc_name, result - )) + ) step("Delete and reconfigure prefix list.") # Create ip prefix list @@ -383,18 +385,20 @@ def test_ospf_routemaps_functionality_tc19_p0(request): } } result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) pfx_list = { "r0": { @@ -438,18 +442,20 @@ def test_ospf_routemaps_functionality_tc19_p0(request): } } result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) @@ -496,18 +502,20 @@ def test_ospf_routemaps_functionality_tc20_p0(request): dut = "r1" protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, attempts=2, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, attempts=2, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) step( "configure the route map with the same name that is used " @@ -523,18 +531,20 @@ def test_ospf_routemaps_functionality_tc20_p0(request): dut = "r1" protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) # Create route map routemaps = {"r0": {"route_maps": {"rmap_ipv4": [{"action": "deny"}]}}} @@ -545,18 +555,20 @@ def test_ospf_routemaps_functionality_tc20_p0(request): dut = "r1" protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) step("Delete the route map.") # Create route map @@ -573,18 +585,20 @@ def test_ospf_routemaps_functionality_tc20_p0(request): dut = "r1" protocol = "ospf" result = verify_ospf_rib(tgen, dut, input_dict, expected=False) - assert result is not True, ("Testcase {} : Failed \n " - "r1: OSPF routes are present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format( tc_name, result - )) + ) result = verify_rib( tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False ) - assert result is not True, ("Testcase {} : Failed \n " - "r1: routes are still present \n Error: {}".format( + assert ( + result is not True + ), "Testcase {} : Failed \n " "r1: routes are still present \n Error: {}".format( tc_name, result - )) + ) write_test_footer(tc_name) diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py index fb6b28ce5b..1432a82b12 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py @@ -247,11 +247,11 @@ def test_ospf_redistribution_tc5_p0(request): if result is not True: break - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: OSPF routes are present after deleting ip address of newly " - "configured interface of R0 \n Error: {}".format( - tc_name, result - )) + "configured interface of R0 \n Error: {}".format(tc_name, result) + ) protocol = "ospf" result = verify_rib( @@ -264,11 +264,11 @@ def test_ospf_redistribution_tc5_p0(request): attempts=5, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: OSPF routes are present in fib after deleting ip address of newly " - "configured interface of R0 \n Error: {}".format( - tc_name, result - )) + "configured interface of R0 \n Error: {}".format(tc_name, result) + ) step("Add back the deleted ip address on newly configured interface of R0") topo1 = { @@ -370,11 +370,11 @@ def test_ospf_redistribution_tc6_p0(request): result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False) if result is not True: break - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: OSPF routes are present after deleting ip address of newly " - "configured loopback of R0 \n Error: {}".format( - tc_name, result - )) + "configured loopback of R0 \n Error: {}".format(tc_name, result) + ) protocol = "ospf" result = verify_rib( @@ -386,11 +386,11 @@ def test_ospf_redistribution_tc6_p0(request): next_hop=nh, expected=False, ) - assert result is not True, ("Testcase {} : Failed \n " + assert result is not True, ( + "Testcase {} : Failed \n " "r1: OSPF routes are present in fib after deleting ip address of newly " - "configured loopback of R0 \n Error: {}".format( - tc_name, result - )) + "configured loopback of R0 \n Error: {}".format(tc_name, result) + ) step("Add back the deleted ip address on newly configured interface of R0") topo1 = { diff --git a/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py index 74d609c57e..76e50beb5c 100644 --- a/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py +++ b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py @@ -94,12 +94,14 @@ def setup_module(mod): tgen.start_router() + def teardown_module(_mod): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() + def test_converge_protocols(): "Wait for protocol convergence" @@ -110,19 +112,26 @@ def test_converge_protocols(): topotest.sleep(10, "Waiting for OSPF convergence") + def ospf_configure_suppress_fa(router_name, area): "Configure OSPF suppress-fa in router_name" tgen = get_topogen() router = tgen.gears[router_name] - router.vtysh_cmd("conf t\nrouter ospf\narea {} nssa suppress-fa\nexit\n".format(area)) + router.vtysh_cmd( + "conf t\nrouter ospf\narea {} nssa suppress-fa\nexit\n".format(area) + ) + def ospf_unconfigure_suppress_fa(router_name, area): "Remove OSPF suppress-fa in router_name" tgen = get_topogen() router = tgen.gears[router_name] - router.vtysh_cmd("conf t\nrouter ospf\nno area {} nssa suppress-fa\nexit\n".format(area)) + router.vtysh_cmd( + "conf t\nrouter ospf\nno area {} nssa suppress-fa\nexit\n".format(area) + ) + def ospf_get_lsa_type5(router_name): "Return a dict with link state id as key and forwarding addresses as value" @@ -141,7 +150,8 @@ def ospf_get_lsa_type5(router_name): result[lsa] = re1.group(1) return result -@pytest.fixture(scope='module', name='original') + +@pytest.fixture(scope="module", name="original") def test_ospf_set_suppress_fa(): "Test OSPF area [x] nssa suppress-fa" @@ -162,6 +172,7 @@ def test_ospf_set_suppress_fa(): # in the test_ospf_unset_supress_fa return initial + def test_ospf_unset_supress_fa(original): "Test OSPF no area [x] nssa suppress-fa" diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py index dc4e29ebde..5d4950a70e 100644 --- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py @@ -949,10 +949,11 @@ def static_routes_rmap_pfxlist_p0_tc7_ebgp(request): result4 = verify_rib( tgen, addr_type, dut, input_dict, protocol=protocol, expected=False ) - assert result4 is not True, ("Testcase {} : Failed \n" - "routes are still present \n Error: {}".format( + assert ( + result4 is not True + ), "Testcase {} : Failed \n" "routes are still present \n Error: {}".format( tc_name, result4 - )) + ) step("vm4 should be present in FRR1") dut = "r1" diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py index 14db729195..09c437c3c4 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py @@ -947,10 +947,11 @@ def test_static_routes_rmap_pfxlist_p0_tc7_ibgp(request): result4 = verify_rib( tgen, addr_type, dut, input_dict, protocol=protocol, expected=False ) - assert result4 is not True, ("Testcase {} : Failed \n" - "routes are still present \n Error: {}".format( + assert ( + result4 is not True + ), "Testcase {} : Failed \n" "routes are still present \n Error: {}".format( tc_name, result4 - )) + ) step("vm4 should be present in FRR1") dut = "r1" diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons index f6d512be72..b1526888ed 100644 --- a/tools/etc/frr/daemons +++ b/tools/etc/frr/daemons @@ -30,6 +30,7 @@ pbrd=no bfdd=no fabricd=no vrrpd=no +pathd=no # # If this option is set the /etc/init.d/frr script automatically loads @@ -55,6 +56,7 @@ staticd_options="-A 127.0.0.1" bfdd_options=" -A 127.0.0.1" fabricd_options="-A 127.0.0.1" vrrpd_options=" -A 127.0.0.1" +pathd_options=" -A 127.0.0.1" # configuration profile # diff --git a/tools/etc/frr/frr.conf b/tools/etc/frr/frr.conf index 61f7a65620..5ee6d15c91 100644 --- a/tools/etc/frr/frr.conf +++ b/tools/etc/frr/frr.conf @@ -1,3 +1,10 @@ -# default to using syslog. /etc/rsyslog.d/45-frr.conf places the log -# in /var/log/frr/frr.log +# default to using syslog. /etc/rsyslog.d/45-frr.conf places the log in +# /var/log/frr/frr.log +# +# Note: +# FRR's configuration shell, vtysh, dynamically edits the live, in-memory +# configuration while FRR is running. When instructed, vtysh will persist the +# live configuration to this file, overwriting its contents. If you want to +# avoid this, you can edit this file manually before starting FRR, or instruct +# vtysh to write configuration to a different file. log syslog informational diff --git a/tools/frr-reload.py b/tools/frr-reload.py index cfc745d434..f4b832691e 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -1115,6 +1115,16 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): for (ctx_keys, line) in lines_to_del: deleted = False + # If there is a change in the segment routing block ranges, do it + # in-place, to avoid requesting spurious label chunks which might fail + if line and "segment-routing global-block" in line: + for (add_key, add_line) in lines_to_add: + if ctx_keys[0] == add_key[0] and add_line and "segment-routing global-block" in add_line: + lines_to_del_to_del.append((ctx_keys, line)) + break + continue + + if ctx_keys[0].startswith("router bgp") and line: if line.startswith("neighbor "): diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in index 2d925dbac3..475e56cf72 100644 --- a/tools/frrcommon.sh.in +++ b/tools/frrcommon.sh.in @@ -35,7 +35,7 @@ FRR_DEFAULT_PROFILE="@DFLT_NAME@" # traditional / datacenter # - keep zebra first # - watchfrr does NOT belong in this list -DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd" +DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd pathd" RELOAD_SCRIPT="$D_PATH/frr-reload.py" # diff --git a/vrrpd/subdir.am b/vrrpd/subdir.am index 96ae530894..dfa9b261c3 100644 --- a/vrrpd/subdir.am +++ b/vrrpd/subdir.am @@ -5,7 +5,6 @@ if VRRPD noinst_LIBRARIES += vrrpd/libvrrp.a sbin_PROGRAMS += vrrpd/vrrpd -# dist_examples_DATA += staticd/staticd.conf.sample vtysh_scan += vrrpd/vrrp_vty.c vtysh_daemons += vrrpd man8 += $(MANBUILD)/frr-vrrpd.8 diff --git a/vtysh/subdir.am b/vtysh/subdir.am index 86861b0390..5f7d854948 100644 --- a/vtysh/subdir.am +++ b/vtysh/subdir.am @@ -4,7 +4,6 @@ if VTYSH bin_PROGRAMS += vtysh/vtysh -dist_examples_DATA += vtysh/vtysh.conf.sample man1 += $(MANBUILD)/vtysh.1 endif diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 3764188292..75fee1d297 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2932,10 +2932,15 @@ DEFUN (vtysh_show_history, /* Memory */ DEFUN (vtysh_show_memory, vtysh_show_memory_cmd, - "show memory", + "show memory [" DAEMONS_LIST "]", SHOW_STR - "Memory statistics\n") + "Memory statistics\n" + DAEMONS_STR) { + if (argc == 3) + return show_one_daemon(vty, argv, argc - 1, + argv[argc - 1]->text); + return show_per_daemon(vty, argv, argc, "Memory statistics for %s:\n"); } @@ -3719,19 +3724,19 @@ DEFUN (no_vtysh_output_file, DEFUN(find, find_cmd, - "find REGEX", + "find REGEX...", "Find CLI command matching a regular expression\n" "Search pattern (POSIX regex)\n") { - char *pattern = argv[1]->arg; const struct cmd_node *node; const struct cmd_element *cli; vector clis; - regex_t exp = {}; - + char *pattern = argv_concat(argv, argc, 1); int cr = regcomp(&exp, pattern, REG_NOSUB | REG_EXTENDED); + XFREE(MTYPE_TMP, pattern); + if (cr != 0) { switch (cr) { case REG_BADBR: diff --git a/vtysh/vtysh.conf.sample b/vtysh/vtysh.conf.sample deleted file mode 100644 index 4e0a2beb44..0000000000 --- a/vtysh/vtysh.conf.sample +++ /dev/null @@ -1,7 +0,0 @@ -! -! Sample configuration file for vtysh. -! -!service integrated-vtysh-config -!hostname quagga-router -!username root nopassword -! diff --git a/yang/frr-bgp-common.yang b/yang/frr-bgp-common.yang index 1840e3728c..1a19d52965 100644 --- a/yang/frr-bgp-common.yang +++ b/yang/frr-bgp-common.yang @@ -393,7 +393,7 @@ submodule frr-bgp-common { container global-neighbor-config { leaf dynamic-neighbors-limit { type uint32 { - range "1..5000"; + range "1..65535"; } description "Maximum number of BGP Dynamic Neighbors that can be created."; diff --git a/yang/frr-bgp.yang b/yang/frr-bgp.yang index 24998a470d..ae44447df7 100644 --- a/yang/frr-bgp.yang +++ b/yang/frr-bgp.yang @@ -1057,6 +1057,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec" { @@ -1332,6 +1334,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec" { diff --git a/zebra/debug.c b/zebra/debug.c index 21fa765c63..05eed0d26e 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -94,8 +94,11 @@ DEFUN_NOSH (show_debugging_zebra, vty_out(vty, " Zebra detailed next-hop tracking debugging is on\n"); else if (IS_ZEBRA_DEBUG_NHT) vty_out(vty, " Zebra next-hop tracking debugging is on\n"); - if (IS_ZEBRA_DEBUG_MPLS) + if (IS_ZEBRA_DEBUG_MPLS_DETAIL) + vty_out(vty, " Zebra detailed MPLS debugging is on\n"); + else if (IS_ZEBRA_DEBUG_MPLS) vty_out(vty, " Zebra MPLS debugging is on\n"); + if (IS_ZEBRA_DEBUG_VXLAN) vty_out(vty, " Zebra VXLAN debugging is on\n"); if (IS_ZEBRA_DEBUG_PW) @@ -159,14 +162,19 @@ DEFUN (debug_zebra_nht, return CMD_SUCCESS; } -DEFUN (debug_zebra_mpls, +DEFPY (debug_zebra_mpls, debug_zebra_mpls_cmd, - "debug zebra mpls", + "debug zebra mpls [detailed$detail]", DEBUG_STR "Zebra configuration\n" - "Debug option set for zebra MPLS LSPs\n") + "Debug option set for zebra MPLS LSPs\n" + "Debug option for detailed info\n") { zebra_debug_mpls = ZEBRA_DEBUG_MPLS; + + if (detail) + zebra_debug_mpls |= ZEBRA_DEBUG_MPLS_DETAILED; + return CMD_SUCCESS; } @@ -422,11 +430,12 @@ DEFUN (no_debug_zebra_nht, DEFUN (no_debug_zebra_mpls, no_debug_zebra_mpls_cmd, - "no debug zebra mpls", + "no debug zebra mpls [detailed]", NO_STR DEBUG_STR "Zebra configuration\n" - "Debug option set for zebra MPLS LSPs\n") + "Debug option set for zebra MPLS LSPs\n" + "Debug option for zebra detailed info\n") { zebra_debug_mpls = 0; return CMD_SUCCESS; @@ -628,10 +637,14 @@ static int config_write_debug(struct vty *vty) write++; } - if (IS_ZEBRA_DEBUG_MPLS) { + if (IS_ZEBRA_DEBUG_MPLS_DETAIL) { + vty_out(vty, "debug zebra mpls detailed\n"); + write++; + } else if (IS_ZEBRA_DEBUG_MPLS) { vty_out(vty, "debug zebra mpls\n"); write++; } + if (IS_ZEBRA_DEBUG_VXLAN) { vty_out(vty, "debug zebra vxlan\n"); write++; diff --git a/zebra/debug.h b/zebra/debug.h index 86506846ad..dc44367d01 100644 --- a/zebra/debug.h +++ b/zebra/debug.h @@ -48,7 +48,8 @@ extern "C" { #define ZEBRA_DEBUG_NHT 0x01 #define ZEBRA_DEBUG_NHT_DETAILED 0x02 -#define ZEBRA_DEBUG_MPLS 0x01 +#define ZEBRA_DEBUG_MPLS 0x01 +#define ZEBRA_DEBUG_MPLS_DETAILED 0x02 #define ZEBRA_DEBUG_VXLAN 0x01 @@ -93,6 +94,8 @@ extern "C" { #define IS_ZEBRA_DEBUG_NHT_DETAILED (zebra_debug_nht & ZEBRA_DEBUG_NHT_DETAILED) #define IS_ZEBRA_DEBUG_MPLS (zebra_debug_mpls & ZEBRA_DEBUG_MPLS) +#define IS_ZEBRA_DEBUG_MPLS_DETAIL \ + (zebra_debug_mpls & ZEBRA_DEBUG_MPLS_DETAILED) #define IS_ZEBRA_DEBUG_VXLAN (zebra_debug_vxlan & ZEBRA_DEBUG_VXLAN) #define IS_ZEBRA_DEBUG_PW (zebra_debug_pw & ZEBRA_DEBUG_PW) diff --git a/zebra/subdir.am b/zebra/subdir.am index 6a582f6901..80ea9ac7b8 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -4,7 +4,6 @@ if ZEBRA sbin_PROGRAMS += zebra/zebra -dist_examples_DATA += zebra/zebra.conf.sample vtysh_scan += \ zebra/debug.c \ zebra/interface.c \ diff --git a/zebra/zebra.conf.sample b/zebra/zebra.conf.sample deleted file mode 100644 index 03042eb083..0000000000 --- a/zebra/zebra.conf.sample +++ /dev/null @@ -1,23 +0,0 @@ -! -*- zebra -*- -! -! zebra sample configuration file -! -hostname Router -password zebra -enable password zebra -! -! Interface's description. -! -!interface lo -! description test of desc. -! -!interface sit0 -! multicast - -! -! Static default route sample. -! -!ip route 0.0.0.0/0 203.181.89.241 -! - -!log file zebra.log diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index c0c064cbc7..6d42957b24 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -872,6 +872,22 @@ static void lsp_schedule(struct hash_bucket *bucket, void *ctxt) zebra_lsp_t *lsp; lsp = (zebra_lsp_t *)bucket->data; + + /* In the common flow, this is used when external events occur. For + * LSPs with backup nhlfes, we'll assume that the forwarding + * plane will use the backups to handle these events, until the + * owning protocol can react. + */ + if (ctxt == NULL) { + /* Skip LSPs with backups */ + if (nhlfe_list_first(&lsp->backup_nhlfe_list) != NULL) { + if (IS_ZEBRA_DEBUG_MPLS_DETAIL) + zlog_debug("%s: skip LSP in-label %u", + __func__, lsp->ile.in_label); + return; + } + } + (void)lsp_processq_add(lsp); } |
