summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_attr.c101
-rw-r--r--bgpd/bgp_attr.h41
-rw-r--r--bgpd/bgp_clist.c4
-rw-r--r--bgpd/bgp_community.c13
-rw-r--r--bgpd/bgp_community.h3
-rw-r--r--bgpd/bgp_debug.c6
-rw-r--r--bgpd/bgp_evpn.c4
-rw-r--r--bgpd/bgp_evpn_mh.c58
-rw-r--r--bgpd/bgp_evpn_mh.h1
-rw-r--r--bgpd/bgp_evpn_vty.c40
-rw-r--r--bgpd/bgp_fsm.c74
-rw-r--r--bgpd/bgp_label.c6
-rw-r--r--bgpd/bgp_lcommunity.c13
-rw-r--r--bgpd/bgp_lcommunity.h3
-rw-r--r--bgpd/bgp_mpath.c12
-rw-r--r--bgpd/bgp_mplsvpn.c17
-rw-r--r--bgpd/bgp_mplsvpn.h4
-rw-r--r--bgpd/bgp_packet.c106
-rw-r--r--bgpd/bgp_route.c68
-rw-r--r--bgpd/bgp_routemap.c43
-rw-r--r--bgpd/bgp_rpki.c68
-rw-r--r--bgpd/bgp_script.c9
-rw-r--r--bgpd/bgp_updgrp.c2
-rw-r--r--bgpd/bgp_updgrp.h9
-rw-r--r--bgpd/bgp_updgrp_adv.c2
-rw-r--r--bgpd/bgp_updgrp_packet.c6
-rw-r--r--bgpd/bgp_vty.c70
-rw-r--r--bgpd/bgp_zebra.c22
-rw-r--r--bgpd/bgpd.c143
-rw-r--r--bgpd/bgpd.h30
-rw-r--r--bgpd/rfapi/rfapi.c8
-rw-r--r--bgpd/rfapi/vnc_export_bgp.c3
-rw-r--r--configure.ac3
-rw-r--r--doc/developer/building-docker.rst21
-rw-r--r--doc/developer/draft-zebra-00.ms8
-rw-r--r--doc/developer/logging.rst59
-rw-r--r--doc/user/bgp.rst13
-rw-r--r--doc/user/pimv6.rst8
-rw-r--r--doc/user/zebra.rst15
-rw-r--r--docker/centos-8/Dockerfile8
-rw-r--r--docker/ubi-8/Dockerfile83
-rwxr-xr-xdocker/ubi-8/build.sh46
-rwxr-xr-xdocker/ubi-8/docker-start4
-rw-r--r--eigrpd/eigrp_routemap.c4
-rw-r--r--isisd/isis_bfd.c2
-rw-r--r--isisd/isis_circuit.c7
-rw-r--r--isisd/isis_nb_config.c50
-rw-r--r--isisd/isis_te.c4
-rw-r--r--isisd/isisd.c2
-rw-r--r--lib/frrscript.c6
-rw-r--r--lib/link_state.c19
-rw-r--r--lib/link_state.h2
-rw-r--r--lib/prefix.h65
-rw-r--r--lib/routemap.h1
-rw-r--r--lib/routemap_cli.c42
-rw-r--r--lib/thread.c2
-rw-r--r--lib/zlog.h2
-rw-r--r--m4/.gitignore1
-rw-r--r--ospf6d/ospf6_asbr.c1
-rw-r--r--ospf6d/ospf6_top.h2
-rw-r--r--ospfclient/ospf_apiclient.c6
-rw-r--r--ospfd/ospf_apiserver.c14
-rw-r--r--ospfd/ospf_apiserver.h10
-rw-r--r--ospfd/ospf_ext.c10
-rw-r--r--ospfd/ospf_opaque.c18
-rw-r--r--ospfd/ospf_opaque.h2
-rw-r--r--ospfd/ospf_ri.c12
-rw-r--r--ospfd/ospf_sr.c2
-rw-r--r--ospfd/ospf_te.c16
-rw-r--r--ospfd/ospf_vty.c15
-rw-r--r--ospfd/ospfd.h2
-rw-r--r--pathd/path_pcep_controller.h2
-rw-r--r--pathd/path_ted.c6
-rw-r--r--pbrd/pbr_zebra.c2
-rw-r--r--pceplib/pcep_msg_objects.h2
-rw-r--r--pimd/pim6_cmd.c1000
-rw-r--r--pimd/pim6_cmd.h1
-rw-r--r--pimd/pim_addr.h19
-rw-r--r--pimd/pim_cmd.c2911
-rw-r--r--pimd/pim_cmd.h9
-rw-r--r--pimd/pim_cmd_common.c2209
-rw-r--r--pimd/pim_cmd_common.h62
-rw-r--r--pimd/pim_iface.c21
-rw-r--r--pimd/pim_iface.h29
-rw-r--r--pimd/pim_ifchannel.c4
-rw-r--r--pimd/pim_igmp.c104
-rw-r--r--pimd/pim_igmpv3.c4
-rw-r--r--pimd/pim_mroute.c22
-rw-r--r--pimd/pim_nb_config.c42
-rw-r--r--pimd/pim_nht.c55
-rw-r--r--pimd/pim_oil.h3
-rw-r--r--pimd/pim_pim.c12
-rw-r--r--pimd/pim_rp.c13
-rw-r--r--pimd/pim_rp.h3
-rw-r--r--pimd/pim_ssm.c14
-rw-r--r--pimd/pim_ssmpingd.c6
-rw-r--r--pimd/pim_upstream.c2
-rw-r--r--pimd/pim_vty.c8
-rw-r--r--pimd/pim_vxlan.c12
-rw-r--r--pimd/pim_zebra.c7
-rw-r--r--pimd/pim_zlookup.c6
-rw-r--r--ripd/rip_interface.c14
-rw-r--r--ripd/rip_routemap.c4
-rw-r--r--ripngd/ripng_interface.c14
-rw-r--r--ripngd/ripng_routemap.c4
-rw-r--r--staticd/static_zebra.c2
-rw-r--r--tests/lib/test_frrlua.c6
-rw-r--r--tests/lib/test_grpc.py4
-rw-r--r--tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py2
-rw-r--r--tests/topotests/bgp_basic_functionality_topo1/test_bgp_basic_functionality.py2
-rw-r--r--tests/topotests/bgp_communities_topo1/test_bgp_communities.py2
-rw-r--r--tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py2
-rw-r--r--tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py2
-rw-r--r--tests/topotests/bgp_ecmp_topo2/test_ebgp_ecmp_topo2.py6
-rw-r--r--tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py6
-rwxr-xr-xtests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py2
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py6
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py6
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py6
-rw-r--r--tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py8
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py2
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py2
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py2
-rw-r--r--tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py2
-rw-r--r--tests/topotests/bgp_gr_functionality_topo3/bgp_gr_functionality_topo3.py2
-rw-r--r--tests/topotests/bgp_gshut_topo1/test_ebgp_gshut_topo1.py2
-rw-r--r--tests/topotests/bgp_gshut_topo1/test_ibgp_gshut_topo1.py2
-rw-r--r--tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_ibgp_nbr.py6
-rw-r--r--tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_nbr.py6
-rw-r--r--tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py6
-rw-r--r--tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_nbr.py6
-rw-r--r--tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_unnumbered_nbr.py6
-rw-r--r--tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py2
-rw-r--r--tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py2
-rw-r--r--tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py2
-rw-r--r--tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py2
-rw-r--r--tests/topotests/bgp_path_attributes_topo1/test_bgp_path_attributes.py2
-rw-r--r--tests/topotests/bgp_prefix_list_topo1/test_prefix_lists.py2
-rw-r--r--tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py2
-rw-r--r--tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py2
-rw-r--r--tests/topotests/bgp_route_map/test_route_map_topo1.py2
-rw-r--r--tests/topotests/bgp_route_map/test_route_map_topo2.py2
-rw-r--r--tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py2
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py2
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py2
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py2
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py2
-rw-r--r--tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py2
-rw-r--r--tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py2
-rw-r--r--tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py2
-rw-r--r--tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py2
-rwxr-xr-xtests/topotests/example_topojson_test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py2
-rwxr-xr-xtests/topotests/example_topojson_test/test_topo_json_single_link/test_example_topojson.py2
-rwxr-xr-xtests/topotests/example_topojson_test/test_topo_json_single_link_loopback/test_example_topojson.py2
-rw-r--r--tests/topotests/lib/common_config.py6
-rw-r--r--tests/topotests/lib/pim.py28
-rw-r--r--tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py4
-rw-r--r--tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py10
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py2
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py2
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py14
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py2
-rwxr-xr-xtests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_authentication.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_chaos.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_lan.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_nssa.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py2
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_single_area.py2
-rw-r--r--tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py2
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py2
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py2
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py6
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py6
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py2
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py2
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py2
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py6
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py2
-rw-r--r--tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py2
-rw-r--r--tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py2
-rw-r--r--tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py2
-rw-r--r--tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py2
-rw-r--r--tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py2
-rw-r--r--tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py2
-rw-r--r--tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py2
-rw-r--r--tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py2
-rw-r--r--tests/topotests/zebra_multiple_connected/r1/ip_route.json62
-rw-r--r--tests/topotests/zebra_multiple_connected/r1/ip_route2.json102
-rw-r--r--tests/topotests/zebra_multiple_connected/r1/zebra.conf9
-rw-r--r--tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py162
-rw-r--r--tools/frrcommon.sh.in6
-rw-r--r--vtysh/vtysh.c12
-rw-r--r--watchfrr/watchfrr.c69
-rw-r--r--yang/frr-bgp-bmp.yang6
-rw-r--r--yang/frr-bgp-common-structure.yang4
-rw-r--r--yang/frr-bgp-common.yang2
-rw-r--r--zebra/rt_netlink.c2
-rw-r--r--zebra/rtadv.c8
-rw-r--r--zebra/zebra_evpn.c23
-rw-r--r--zebra/zebra_evpn_mac.c2
-rw-r--r--zebra/zebra_evpn_mh.c25
-rw-r--r--zebra/zebra_nhg.c92
-rw-r--r--zebra/zebra_srv6_vty.c6
-rw-r--r--zebra/zebra_vxlan.c27
-rw-r--r--zebra/zserv.c4
212 files changed, 5464 insertions, 3653 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 2f246e61d8..df03e9a34d 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -986,6 +986,10 @@ struct attr *bgp_attr_aggregate_intern(
attr.origin = origin;
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
+ /* MED */
+ attr.med = 0;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
+
/* AS path attribute. */
if (aspath)
attr.aspath = aspath_intern(aspath);
@@ -1008,18 +1012,13 @@ struct attr *bgp_attr_aggregate_intern(
}
bgp_attr_set_community(&attr, community);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
}
- if (ecommunity) {
+ if (ecommunity)
bgp_attr_set_ecommunity(&attr, ecommunity);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
- }
- if (lcommunity) {
+ if (lcommunity)
bgp_attr_set_lcommunity(&attr, lcommunity);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
- }
if (bgp_in_graceful_shutdown(bgp))
bgp_attr_add_gshut_community(&attr);
@@ -1096,22 +1095,18 @@ void bgp_attr_unintern_sub(struct attr *attr)
comm = bgp_attr_get_community(attr);
community_unintern(&comm);
- UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES));
bgp_attr_set_community(attr, NULL);
ecomm = bgp_attr_get_ecommunity(attr);
ecommunity_unintern(&ecomm);
- UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
bgp_attr_set_ecommunity(attr, NULL);
ipv6_ecomm = bgp_attr_get_ipv6_ecommunity(attr);
ecommunity_unintern(&ipv6_ecomm);
- UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES));
bgp_attr_set_ipv6_ecommunity(attr, NULL);
lcomm = bgp_attr_get_lcommunity(attr);
lcommunity_unintern(&lcomm);
- UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
bgp_attr_set_lcommunity(attr, NULL);
cluster = bgp_attr_get_cluster(attr);
@@ -1243,7 +1238,7 @@ void bgp_attr_flush(struct attr *attr)
* are partial/optional and hence where the error likely was not
* introduced by the sending neighbour.
*/
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
bgp_size_t length)
{
@@ -1450,7 +1445,8 @@ static bool bgp_attr_flag_invalid(struct bgp_attr_parser_args *args)
}
/* Get origin attribute of the update message. */
-static bgp_attr_parse_ret_t bgp_attr_origin(struct bgp_attr_parser_args *args)
+static enum bgp_attr_parse_ret
+bgp_attr_origin(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
@@ -1520,8 +1516,8 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
return BGP_ATTR_PARSE_PROCEED;
}
-static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer,
- struct attr *const attr)
+static enum bgp_attr_parse_ret bgp_attr_aspath_check(struct peer *const peer,
+ struct attr *const attr)
{
/* These checks were part of bgp_attr_aspath, but with
* as4 we should to check aspath things when
@@ -1603,8 +1599,8 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
/*
* Check that the nexthop attribute is valid.
*/
-bgp_attr_parse_ret_t
-bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr)
+enum bgp_attr_parse_ret bgp_attr_nexthop_valid(struct peer *peer,
+ struct attr *attr)
{
in_addr_t nexthop_h;
@@ -1633,7 +1629,8 @@ bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr)
}
/* Nexthop attribute. */
-static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args)
+static enum bgp_attr_parse_ret
+bgp_attr_nexthop(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
@@ -1655,7 +1652,7 @@ static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args)
}
/* MED atrribute. */
-static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args)
+static enum bgp_attr_parse_ret bgp_attr_med(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
@@ -1678,7 +1675,7 @@ static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args)
}
/* Local preference attribute. */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_local_pref(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -1790,7 +1787,7 @@ static int bgp_attr_aggregator(struct bgp_attr_parser_args *args)
}
/* New Aggregator attribute */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args,
as_t *as4_aggregator_as,
struct in_addr *as4_aggregator_addr)
@@ -1834,7 +1831,7 @@ bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args,
/* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH.
*/
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
struct aspath *as4_path, as_t as4_aggregator,
struct in_addr *as4_aggregator_addr)
@@ -1936,7 +1933,7 @@ bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
}
/* Community attribute. */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_community(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -1963,13 +1960,11 @@ bgp_attr_community(struct bgp_attr_parser_args *args)
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
-
return BGP_ATTR_PARSE_PROCEED;
}
/* Originator ID attribute. */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_originator_id(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -1997,7 +1992,7 @@ bgp_attr_originator_id(struct bgp_attr_parser_args *args)
}
/* Cluster list attribute. */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_cluster_list(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -2268,7 +2263,7 @@ int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
}
/* Large Community attribute. */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_large_community(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -2294,13 +2289,11 @@ bgp_attr_large_community(struct bgp_attr_parser_args *args)
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
-
return BGP_ATTR_PARSE_PROCEED;
}
/* Extended Community attribute. */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -2332,8 +2325,6 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
-
/* Extract DF election preference and mobility sequence number */
attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg);
@@ -2376,7 +2367,7 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
}
/* IPv6 Extended Community attribute. */
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -2403,8 +2394,6 @@ bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES);
-
return BGP_ATTR_PARSE_PROCEED;
}
@@ -2541,7 +2530,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
/* SRv6 Service Data Sub-Sub-TLV attribute
* draft-ietf-bess-srv6-services-07
*/
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_srv6_service_data(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -2622,7 +2611,7 @@ bgp_attr_srv6_service_data(struct bgp_attr_parser_args *args)
/* SRv6 Service Sub-TLV attribute
* draft-ietf-bess-srv6-services-07
*/
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_srv6_service(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -2631,7 +2620,7 @@ bgp_attr_srv6_service(struct bgp_attr_parser_args *args)
uint8_t type, sid_flags;
uint16_t length, endpoint_behavior;
size_t headersz = sizeof(type) + sizeof(length);
- bgp_attr_parse_ret_t err;
+ enum bgp_attr_parse_ret err;
char buf[BUFSIZ];
if (STREAM_READABLE(peer->curr) < headersz) {
@@ -2717,8 +2706,9 @@ bgp_attr_srv6_service(struct bgp_attr_parser_args *args)
* Read an individual SID value returning how much data we have read
* Returns 0 if there was an error that needs to be passed up the stack
*/
-static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length,
- struct bgp_attr_parser_args *args)
+static enum bgp_attr_parse_ret
+bgp_attr_psid_sub(uint8_t type, uint16_t length,
+ struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
@@ -2925,11 +2915,11 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length,
/* Prefix SID attribute
* draft-ietf-idr-bgp-prefix-sid-05
*/
-bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
+enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
struct attr *const attr = args->attr;
- bgp_attr_parse_ret_t ret;
+ enum bgp_attr_parse_ret ret;
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
@@ -2988,7 +2978,7 @@ bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
/* PMSI tunnel attribute (RFC 6514)
* Basic validation checks done here.
*/
-static bgp_attr_parse_ret_t
+static enum bgp_attr_parse_ret
bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
{
struct peer *const peer = args->peer;
@@ -3036,7 +3026,8 @@ bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
}
/* BGP unknown attribute treatment. */
-static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args)
+static enum bgp_attr_parse_ret
+bgp_attr_unknown(struct bgp_attr_parser_args *args)
{
bgp_size_t total = args->total;
struct transit *transit;
@@ -3141,11 +3132,12 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr)
/* Read attribute of update packet. This function is called from
bgp_update_receive() in bgp_packet.c. */
-bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
- bgp_size_t size, struct bgp_nlri *mp_update,
- struct bgp_nlri *mp_withdraw)
+enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
+ bgp_size_t size,
+ struct bgp_nlri *mp_update,
+ struct bgp_nlri *mp_withdraw)
{
- bgp_attr_parse_ret_t ret;
+ enum bgp_attr_parse_ret ret;
uint8_t flag = 0;
uint8_t type = 0;
bgp_size_t length;
@@ -4185,9 +4177,14 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
&& (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
-
- if (peer->sort == BGP_PEER_IBGP
- || peer->sort == BGP_PEER_CONFED) {
+ bool transparent = CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_RSERVER_CLIENT) &&
+ from &&
+ CHECK_FLAG(from->af_flags[afi][safi],
+ PEER_FLAG_RSERVER_CLIENT);
+
+ if (peer->sort == BGP_PEER_IBGP ||
+ peer->sort == BGP_PEER_CONFED || transparent) {
if (ecomm->size * 8 > 255) {
stream_putc(s,
BGP_ATTR_FLAG_OPTIONAL
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 1f199da161..ac5734ede6 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -370,25 +370,25 @@ struct transit {
? bgp_attr_get_cluster((attr))->length \
: 0)
-typedef enum {
+enum bgp_attr_parse_ret {
BGP_ATTR_PARSE_PROCEED = 0,
BGP_ATTR_PARSE_ERROR = -1,
BGP_ATTR_PARSE_WITHDRAW = -2,
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
- */
+ */
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
BGP_ATTR_PARSE_EOR = -4,
-} bgp_attr_parse_ret_t;
+};
struct bpacket_attr_vec_arr;
/* Prototypes. */
extern void bgp_attr_init(void);
extern void bgp_attr_finish(void);
-extern bgp_attr_parse_ret_t bgp_attr_parse(struct peer *, struct attr *,
- bgp_size_t, struct bgp_nlri *,
- struct bgp_nlri *);
+extern enum bgp_attr_parse_ret bgp_attr_parse(struct peer *, struct attr *,
+ bgp_size_t, struct bgp_nlri *,
+ struct bgp_nlri *);
extern struct attr *bgp_attr_intern(struct attr *attr);
extern void bgp_attr_unintern_sub(struct attr *);
extern void bgp_attr_unintern(struct attr **);
@@ -432,7 +432,7 @@ extern int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
struct bgp_nlri *);
extern int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
struct bgp_nlri *);
-extern bgp_attr_parse_ret_t
+extern enum bgp_attr_parse_ret
bgp_attr_prefix_sid(struct bgp_attr_parser_args *args);
extern struct bgp_attr_encap_subtlv *
@@ -471,8 +471,8 @@ extern void bgp_packet_mpunreach_prefix(
bool addpath_capable, uint32_t addpath_tx_id, struct attr *attr);
extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt);
-extern bgp_attr_parse_ret_t bgp_attr_nexthop_valid(struct peer *peer,
- struct attr *attr);
+extern enum bgp_attr_parse_ret bgp_attr_nexthop_valid(struct peer *peer,
+ struct attr *attr);
static inline int bgp_rmap_nhop_changed(uint32_t out_rmap_flags,
uint32_t in_rmap_flags)
@@ -516,6 +516,11 @@ static inline void bgp_attr_set_ecommunity(struct attr *attr,
struct ecommunity *ecomm)
{
attr->ecommunity = ecomm;
+
+ if (ecomm)
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
+ else
+ UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
}
static inline struct lcommunity *
@@ -528,6 +533,12 @@ static inline void bgp_attr_set_lcommunity(struct attr *attr,
struct lcommunity *lcomm)
{
attr->lcommunity = lcomm;
+
+ if (lcomm)
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
+ else
+ UNSET_FLAG(attr->flag,
+ ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
}
static inline struct community *bgp_attr_get_community(const struct attr *attr)
@@ -539,6 +550,11 @@ static inline void bgp_attr_set_community(struct attr *attr,
struct community *comm)
{
attr->community = comm;
+
+ if (comm)
+ SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES));
+ else
+ UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES));
}
static inline struct ecommunity *
@@ -551,6 +567,13 @@ static inline void bgp_attr_set_ipv6_ecommunity(struct attr *attr,
struct ecommunity *ipv6_ecomm)
{
attr->ipv6_ecommunity = ipv6_ecomm;
+
+ if (ipv6_ecomm)
+ SET_FLAG(attr->flag,
+ ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES));
+ else
+ UNSET_FLAG(attr->flag,
+ ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES));
}
static inline struct transit *bgp_attr_get_transit(const struct attr *attr)
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index 0e590a463c..0631f8b95a 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -557,7 +557,7 @@ static bool community_regexp_match(struct community *com, regex_t *reg)
if (com == NULL || com->size == 0)
str = "";
else
- str = community_str(com, false);
+ str = community_str(com, false, true);
regstr = bgp_alias2community_str(str);
@@ -631,7 +631,7 @@ static bool lcommunity_regexp_match(struct lcommunity *com, regex_t *reg)
if (com == NULL || com->size == 0)
str = "";
else
- str = lcommunity_str(com, false);
+ str = lcommunity_str(com, false, true);
regstr = bgp_alias2community_str(str);
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index 6e6a3cd587..78cf9ea76c 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -200,7 +200,8 @@ struct community *community_uniq_sort(struct community *com)
0xFFFFFF04 "no-peer"
For other values, "AS:VAL" format is used. */
-static void set_community_string(struct community *com, bool make_json)
+static void set_community_string(struct community *com, bool make_json,
+ bool translate_alias)
{
int i;
char *str;
@@ -447,7 +448,9 @@ static void set_community_string(struct community *com, bool make_json)
val = comval & 0xFFFF;
char buf[32];
snprintf(buf, sizeof(buf), "%u:%d", as, val);
- const char *com2alias = bgp_community2alias(buf);
+ const char *com2alias =
+ translate_alias ? bgp_community2alias(buf)
+ : buf;
strlcat(str, com2alias, len);
if (make_json) {
@@ -487,7 +490,7 @@ struct community *community_intern(struct community *com)
/* Make string. */
if (!find->str)
- set_community_string(find, false);
+ set_community_string(find, false, true);
return find;
}
@@ -548,7 +551,7 @@ struct community *community_dup(struct community *com)
}
/* Return string representation of communities attribute. */
-char *community_str(struct community *com, bool make_json)
+char *community_str(struct community *com, bool make_json, bool translate_alias)
{
if (!com)
return NULL;
@@ -557,7 +560,7 @@ char *community_str(struct community *com, bool make_json)
XFREE(MTYPE_COMMUNITY_STR, com->str);
if (!com->str)
- set_community_string(com, make_json);
+ set_community_string(com, make_json, translate_alias);
return com->str;
}
diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h
index 2a1fbf526a..6f0ae0235c 100644
--- a/bgpd/bgp_community.h
+++ b/bgpd/bgp_community.h
@@ -76,7 +76,8 @@ extern struct community *community_uniq_sort(struct community *);
extern struct community *community_parse(uint32_t *, unsigned short);
extern struct community *community_intern(struct community *);
extern void community_unintern(struct community **);
-extern char *community_str(struct community *, bool make_json);
+extern char *community_str(struct community *, bool make_json,
+ bool translate_alias);
extern unsigned int community_hash_make(const struct community *);
extern struct community *community_str2com(const char *);
extern bool community_match(const struct community *, const struct community *);
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 5d14ff0fa6..49003e9428 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -411,12 +411,14 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size)
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf),
", community %s",
- community_str(bgp_attr_get_community(attr), false));
+ community_str(bgp_attr_get_community(attr), false,
+ true));
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf),
", large-community %s",
- lcommunity_str(bgp_attr_get_lcommunity(attr), false));
+ lcommunity_str(bgp_attr_get_lcommunity(attr), false,
+ true));
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf),
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 7982c2ff60..fbb0d2272a 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -759,8 +759,6 @@ static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,
ecommunity_add_val(bgp_attr_get_ecommunity(attr), &eval_rmac,
true, true);
}
-
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
/*
@@ -870,8 +868,6 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
attr, ecommunity_merge(bgp_attr_get_ecommunity(attr),
&ecom_na));
}
-
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
/*
diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c
index 59a958444d..6db4cba44d 100644
--- a/bgpd/bgp_evpn_mh.c
+++ b/bgpd/bgp_evpn_mh.c
@@ -385,9 +385,9 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
if (remote_pi) {
flog_err(
EC_BGP_ES_INVALID,
- "%u ERROR: local es route for ESI: %s Vtep %pI4 also learnt from remote",
+ "%u ERROR: local es route for ESI: %s vtep %pI4 also learnt from remote",
bgp->vrf_id, es ? es->esi_str : "Null",
- &es->originator_ip);
+ es ? &es->originator_ip : NULL);
return -1;
}
@@ -622,8 +622,6 @@ static void bgp_evpn_type4_route_extcomm_build(struct bgp_evpn_es *es,
bgp_attr_set_ecommunity(
attr,
ecommunity_merge(bgp_attr_get_ecommunity(attr), &ecom_df));
-
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
/* Create or update local type-4 route */
@@ -904,8 +902,6 @@ bgp_evpn_type1_es_route_extcomm_build(struct bgp_evpn_es_frag *es_frag,
ecom));
}
}
-
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
/* Extended communities associated with EAD-per-EVI */
@@ -932,8 +928,6 @@ static void bgp_evpn_type1_evi_route_extcomm_build(struct bgp_evpn_es *es,
bgp_attr_set_ecommunity(
attr,
ecommunity_merge(bgp_attr_get_ecommunity(attr), ecom));
-
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
/* Update EVPN EAD (type-1) route -
@@ -1273,9 +1267,9 @@ void bgp_evpn_mh_config_ead_export_rt(struct bgp *bgp,
}
}
- if (node_to_del)
- list_delete_node(bgp_mh_info->ead_es_export_rtl,
- node_to_del);
+ assert(node_to_del);
+ list_delete_node(bgp_mh_info->ead_es_export_rtl,
+ node_to_del);
}
} else {
listnode_add_sort(bgp_mh_info->ead_es_export_rtl, ecomcfg);
@@ -1688,7 +1682,7 @@ static bool bgp_evpn_is_macip_path(struct bgp_path_info *pi)
* This is done indirectly by re-attempting an install of the
* route in the associated VRFs. As a part of the VRF install use
* of l3 NHG is evaluated and this results in the
- * attr.es_flag ATTR_ES_USE_L3_NHG being set or cleared.
+ * attr.es_flag ATTR_ES_L3_NHG_USE being set or cleared.
*/
static void
bgp_evpn_es_path_update_on_es_vrf_chg(struct bgp_evpn_es_vrf *es_vrf,
@@ -1902,9 +1896,6 @@ static struct bgp_evpn_es *bgp_evpn_es_new(struct bgp *bgp, const esi_t *esi)
{
struct bgp_evpn_es *es;
- if (!bgp)
- return NULL;
-
es = XCALLOC(MTYPE_BGP_EVPN_ES, sizeof(struct bgp_evpn_es));
/* set the ESI */
@@ -2364,7 +2355,6 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
struct in_addr originator_ip, bool oper_up,
uint16_t df_pref, bool bypass)
{
- char buf[ESI_STR_LEN];
struct bgp_evpn_es *es;
bool new_es = true;
bool regen_esr = false;
@@ -2374,15 +2364,8 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
if (es) {
if (CHECK_FLAG(es->flags, BGP_EVPNES_LOCAL))
new_es = false;
- } else {
+ } else
es = bgp_evpn_es_new(bgp, esi);
- if (!es) {
- flog_err(EC_BGP_ES_CREATE,
- "%u: Failed to allocate ES entry for ESI %s - at Local ES Add",
- bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
- return -1;
- }
- }
if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
zlog_debug("add local es %s orig-ip %pI4 df_pref %u %s",
@@ -2886,7 +2869,7 @@ static void bgp_evpn_l3nhg_zebra_add_v4_or_v6(struct bgp_evpn_es_vrf *es_vrf,
static bool bgp_evpn_l3nhg_zebra_ok(struct bgp_evpn_es_vrf *es_vrf)
{
- if (!bgp_mh_info->host_routes_use_l3nhg && !bgp_mh_info->install_l3nhg)
+ if (!bgp_mh_info->host_routes_use_l3nhg)
return false;
/* Check socket. */
@@ -3460,14 +3443,11 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
new_active ? "active" : "inactive");
/* add VTEP to parent es */
- if (new_active) {
- struct bgp_evpn_es_vtep *es_vtep;
-
- es_vtep = bgp_evpn_es_vtep_add(bgp, evi_vtep->es_evi->es,
- evi_vtep->vtep_ip, false /*esr*/,
- 0, 0);
- evi_vtep->es_vtep = es_vtep;
- } else {
+ if (new_active)
+ evi_vtep->es_vtep = bgp_evpn_es_vtep_add(
+ bgp, evi_vtep->es_evi->es, evi_vtep->vtep_ip,
+ false /*esr*/, 0, 0);
+ else {
if (evi_vtep->es_vtep) {
bgp_evpn_es_vtep_do_del(bgp, evi_vtep->es_vtep,
false /*esr*/);
@@ -3821,15 +3801,8 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
&p->prefix.ead_addr.ip.ipaddr_v4);
es = bgp_evpn_es_find(esi);
- if (!es) {
+ if (!es)
es = bgp_evpn_es_new(bgp, esi);
- if (!es) {
- flog_err(EC_BGP_ES_CREATE,
- "%u: Failed to allocate ES entry for ESI %s - at remote ES Add",
- bgp->vrf_id, esi_to_str(esi, buf, sizeof(buf)));
- return -1;
- }
- }
es_evi = bgp_evpn_es_evi_find(es, vpn);
if (!es_evi)
@@ -4419,14 +4392,12 @@ static uint32_t bgp_evpn_es_run_consistency_checks(struct bgp_evpn_es *es)
static void bgp_evpn_run_consistency_checks(struct thread *t)
{
int proc_cnt = 0;
- int es_cnt = 0;
struct listnode *node;
struct listnode *nextnode;
struct bgp_evpn_es *es;
for (ALL_LIST_ELEMENTS(bgp_mh_info->pend_es_list,
node, nextnode, es)) {
- ++es_cnt;
++proc_cnt;
/* run consistency checks on the ES and remove it from the
* pending list
@@ -4966,7 +4937,6 @@ void bgp_evpn_mh_init(void)
/* config knobs - XXX add cli to control it */
bgp_mh_info->ead_evi_adv_for_down_links = true;
bgp_mh_info->consistency_checking = true;
- bgp_mh_info->install_l3nhg = false;
bgp_mh_info->host_routes_use_l3nhg = BGP_EVPN_MH_USE_ES_L3NHG_DEF;
bgp_mh_info->suppress_l3_ecomm_on_inactive_es = true;
bgp_mh_info->bgp_evpn_nh_setup = true;
diff --git a/bgpd/bgp_evpn_mh.h b/bgpd/bgp_evpn_mh.h
index d60c7019e6..dc3fe44776 100644
--- a/bgpd/bgp_evpn_mh.h
+++ b/bgpd/bgp_evpn_mh.h
@@ -321,7 +321,6 @@ struct bgp_evpn_mh_info {
/* Enable ES consistency checking */
bool consistency_checking;
/* Use L3 NHGs for host routes in symmetric IRB */
- bool install_l3nhg;
bool host_routes_use_l3nhg;
/* Some vendors are not generating the EAD-per-EVI route. This knob
* can be turned off to activate a remote ES-PE when the EAD-per-ES
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 5f519e84ed..109de1efb2 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -3867,19 +3867,19 @@ DEFUN (bgp_evpn_advertise_type5,
if (!(afi == AFI_IP || afi == AFI_IP6)) {
vty_out(vty,
- "%%only ipv4 or ipv6 address families are supported\n");
+ "%% Only ipv4 or ipv6 address families are supported\n");
return CMD_WARNING;
}
if (safi != SAFI_UNICAST) {
vty_out(vty,
- "%%only ipv4 unicast or ipv6 unicast are supported\n");
+ "%% Only ipv4 unicast or ipv6 unicast are supported\n");
return CMD_WARNING;
}
if ((oly != OVERLAY_INDEX_TYPE_NONE)
&& (oly != OVERLAY_INDEX_GATEWAY_IP)) {
- vty_out(vty, "%%Unknown overlay-index type specified\n");
+ vty_out(vty, "%% Unknown overlay-index type specified\n");
return CMD_WARNING;
}
@@ -4058,13 +4058,13 @@ DEFUN (no_bgp_evpn_advertise_type5,
if (!(afi == AFI_IP || afi == AFI_IP6)) {
vty_out(vty,
- "%%only ipv4 or ipv6 address families are supported\n");
+ "%% Only ipv4 or ipv6 address families are supported\n");
return CMD_WARNING;
}
if (safi != SAFI_UNICAST) {
vty_out(vty,
- "%%only ipv4 unicast or ipv6 unicast are supported\n");
+ "%% Only ipv4 unicast or ipv6 unicast are supported\n");
return CMD_WARNING;
}
@@ -4495,7 +4495,7 @@ DEFPY(show_bgp_l2vpn_evpn_es,
if (esi_str) {
if (!str_to_esi(esi_str, &esi)) {
- vty_out(vty, "%%Malformed ESI\n");
+ vty_out(vty, "%% Malformed ESI\n");
return CMD_WARNING;
}
bgp_evpn_es_show_esi(vty, &esi, uj);
@@ -4517,7 +4517,7 @@ DEFPY(show_bgp_l2vpn_evpn_es_vrf, show_bgp_l2vpn_evpn_es_vrf_cmd,
if (esi_str) {
if (!str_to_esi(esi_str, &esi)) {
- vty_out(vty, "%%Malformed ESI\n");
+ vty_out(vty, "%% Malformed ESI\n");
return CMD_WARNING;
}
bgp_evpn_es_vrf_show_esi(vty, &esi, uj);
@@ -5132,7 +5132,7 @@ DEFPY_HIDDEN(
if (esi_str) {
if (!str_to_esi(esi_str, &esi)) {
- vty_out(vty, "%%Malformed ESI\n");
+ vty_out(vty, "%% Malformed ESI\n");
return CMD_WARNING;
}
esi_p = &esi;
@@ -5165,7 +5165,7 @@ DEFPY_HIDDEN(
if (esi_str) {
if (!str_to_esi(esi_str, &esi)) {
- vty_out(vty, "%%Malformed ESI\n");
+ vty_out(vty, "%% Malformed ESI\n");
return CMD_WARNING;
}
esi_p = &esi;
@@ -5267,19 +5267,19 @@ DEFPY_HIDDEN(test_es_add,
bgp = bgp_get_evpn();
if (!bgp) {
- vty_out(vty, "%%EVPN BGP instance not yet created\n");
+ vty_out(vty, "%% EVPN BGP instance not yet created\n");
return CMD_WARNING;
}
if (!str_to_esi(esi_str, &esi)) {
- vty_out(vty, "%%Malformed ESI\n");
+ vty_out(vty, "%% Malformed ESI\n");
return CMD_WARNING;
}
if (no) {
ret = bgp_evpn_local_es_del(bgp, &esi);
if (ret == -1) {
- vty_out(vty, "%%Failed to delete ES\n");
+ vty_out(vty, "%% Failed to delete ES\n");
return CMD_WARNING;
}
} else {
@@ -5292,7 +5292,7 @@ DEFPY_HIDDEN(test_es_add,
ret = bgp_evpn_local_es_add(bgp, &esi, vtep_ip, oper_up,
EVPN_MH_DF_PREF_MIN, false);
if (ret == -1) {
- vty_out(vty, "%%Failed to add ES\n");
+ vty_out(vty, "%% Failed to add ES\n");
return CMD_WARNING;
}
}
@@ -5316,25 +5316,25 @@ DEFPY_HIDDEN(test_es_vni_add,
bgp = bgp_get_evpn();
if (!bgp) {
- vty_out(vty, "%%EVPN BGP instance not yet created\n");
+ vty_out(vty, "%% EVPN BGP instance not yet created\n");
return CMD_WARNING;
}
if (!str_to_esi(esi_str, &esi)) {
- vty_out(vty, "%%Malformed ESI\n");
+ vty_out(vty, "%% Malformed ESI\n");
return CMD_WARNING;
}
if (no) {
ret = bgp_evpn_local_es_evi_del(bgp, &esi, vni);
if (ret == -1) {
- vty_out(vty, "%%Failed to deref ES VNI\n");
+ vty_out(vty, "%% Failed to deref ES VNI\n");
return CMD_WARNING;
}
} else {
ret = bgp_evpn_local_es_evi_add(bgp, &esi, vni);
if (ret == -1) {
- vty_out(vty, "%%Failed to ref ES VNI\n");
+ vty_out(vty, "%% Failed to ref ES VNI\n");
return CMD_WARNING;
}
}
@@ -5747,9 +5747,13 @@ DEFUN (show_bgp_vrf_l3vni_info,
name = argv[idx_vrf]->arg;
bgp = bgp_lookup_by_name(name);
+ if (strmatch(name, VRF_DEFAULT_NAME))
+ bgp = bgp_get_default();
+
if (!bgp) {
if (!uj)
- vty_out(vty, "BGP instance for VRF %s not found", name);
+ vty_out(vty, "BGP instance for VRF %s not found\n",
+ name);
else {
json_object_string_add(json, "warning",
"BGP instance not found");
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 43908fcb78..6854a6501a 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -677,8 +677,7 @@ static void bgp_llgr_stale_timer_expire(struct thread *thread)
* stale routes from the neighbor that it is retaining.
*/
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s(%s) Long-lived stale timer (%s) expired",
- peer->host, bgp_peer_hostname(peer),
+ zlog_debug("%pBP Long-lived stale timer (%s) expired", peer,
get_afi_safi_str(afi, safi, false));
UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_LLGR_WAIT);
@@ -720,10 +719,8 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) Long-lived set stale community (LLGR_STALE) for: %pFX",
- peer->host,
- bgp_peer_hostname(peer),
- &dest->p);
+ "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
+ peer, &dest->p);
attr = *pi->attr;
bgp_attr_add_llgr_community(&attr);
@@ -750,10 +747,8 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) Long-lived set stale community (LLGR_STALE) for: %pFX",
- peer->host,
- bgp_peer_hostname(peer),
- &dest->p);
+ "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
+ peer, &dest->p);
attr = *pi->attr;
bgp_attr_add_llgr_community(&attr);
@@ -777,10 +772,9 @@ static void bgp_graceful_restart_timer_expire(struct thread *thread)
peer = THREAD_ARG(thread);
if (bgp_debug_neighbor_events(peer)) {
- zlog_debug("%s(%s) graceful restart timer expired", peer->host,
- bgp_peer_hostname(peer));
- zlog_debug("%s(%s) graceful restart stalepath timer stopped",
- peer->host, bgp_peer_hostname(peer));
+ zlog_debug("%pBP graceful restart timer expired", peer);
+ zlog_debug("%pBP graceful restart stalepath timer stopped",
+ peer);
}
FOREACH_AFI_SAFI (afi, safi) {
@@ -806,8 +800,8 @@ static void bgp_graceful_restart_timer_expire(struct thread *thread)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) Long-lived stale timer (%s) started for %d sec",
- peer->host, bgp_peer_hostname(peer),
+ "%pBP Long-lived stale timer (%s) started for %d sec",
+ peer,
get_afi_safi_str(afi, safi, false),
peer->llgr[afi][safi].stale_time);
@@ -842,8 +836,8 @@ static void bgp_graceful_stale_timer_expire(struct thread *thread)
peer = THREAD_ARG(thread);
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s(%s) graceful restart stalepath timer expired",
- peer->host, bgp_peer_hostname(peer));
+ zlog_debug("%pBP graceful restart stalepath timer expired",
+ peer);
/* NSF delete stale route */
FOREACH_AFI_SAFI_NSF (afi, safi)
@@ -1395,8 +1389,8 @@ int bgp_stop(struct peer *peer)
struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
zlog_info(
- "%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
- peer->host, bgp_peer_hostname(peer),
+ "%%ADJCHANGE: neighbor %pBP in vrf %s Down %s",
+ peer,
vrf ? ((vrf->vrf_id != VRF_DEFAULT)
? vrf->name
: VRF_DEFAULT_NAME)
@@ -1409,19 +1403,17 @@ int bgp_stop(struct peer *peer)
BGP_TIMER_OFF(peer->t_gr_stale);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) graceful restart stalepath timer stopped",
- peer->host, bgp_peer_hostname(peer));
+ "%pBP graceful restart stalepath timer stopped",
+ peer);
}
if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
if (bgp_debug_neighbor_events(peer)) {
zlog_debug(
- "%s(%s) graceful restart timer started for %d sec",
- peer->host, bgp_peer_hostname(peer),
- peer->v_gr_restart);
+ "%pBP graceful restart timer started for %d sec",
+ peer, peer->v_gr_restart);
zlog_debug(
- "%s(%s) graceful restart stalepath timer started for %d sec",
- peer->host, bgp_peer_hostname(peer),
- peer->bgp->stalepath_time);
+ "%pBP graceful restart stalepath timer started for %d sec",
+ peer, peer->bgp->stalepath_time);
}
BGP_TIMER_ON(peer->t_gr_restart,
bgp_graceful_restart_timer_expire,
@@ -1442,8 +1434,8 @@ int bgp_stop(struct peer *peer)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) route-refresh restart stalepath timer stopped",
- peer->host, bgp_peer_hostname(peer));
+ "%pBP route-refresh restart stalepath timer stopped",
+ peer);
}
/* If peer reset before receiving EOR, decrement EOR count and
@@ -2099,8 +2091,7 @@ static int bgp_establish(struct peer *peer)
/* bgp log-neighbor-changes of neighbor Up */
if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
- zlog_info("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up",
- peer->host, bgp_peer_hostname(peer),
+ zlog_info("%%ADJCHANGE: neighbor %pBP in vrf %s Up", peer,
vrf ? ((vrf->vrf_id != VRF_DEFAULT)
? vrf->name
: VRF_DEFAULT_NAME)
@@ -2113,9 +2104,9 @@ static int bgp_establish(struct peer *peer)
UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
if (bgp_debug_neighbor_events(peer)) {
if (BGP_PEER_RESTARTING_MODE(peer))
- zlog_debug("peer %s BGP_RESTARTING_MODE", peer->host);
+ zlog_debug("%pBP BGP_RESTARTING_MODE", peer);
else if (BGP_PEER_HELPER_MODE(peer))
- zlog_debug("peer %s BGP_HELPER_MODE", peer->host);
+ zlog_debug("%pBP BGP_HELPER_MODE", peer);
}
FOREACH_AFI_SAFI_NSF (afi, safi) {
@@ -2189,16 +2180,15 @@ static int bgp_establish(struct peer *peer)
BGP_TIMER_OFF(peer->t_gr_stale);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) graceful restart stalepath timer stopped",
- peer->host, bgp_peer_hostname(peer));
+ "%pBP graceful restart stalepath timer stopped",
+ peer);
}
}
if (peer->t_gr_restart) {
BGP_TIMER_OFF(peer->t_gr_restart);
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s(%s) graceful restart timer stopped",
- peer->host, bgp_peer_hostname(peer));
+ zlog_debug("%pBP graceful restart timer stopped", peer);
}
/* Reset uptime, turn on keepalives, send current table. */
@@ -2215,8 +2205,8 @@ static int bgp_establish(struct peer *peer)
BGP_TIMER_OFF(peer->t_llgr_stale[afi][safi]);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s Long-lived stale timer stopped for afi/safi: %d/%d",
- peer->host, afi, safi);
+ "%pBP Long-lived stale timer stopped for afi/safi: %d/%d",
+ peer, afi, safi);
}
if (CHECK_FLAG(peer->af_cap[afi][safi],
@@ -2765,10 +2755,10 @@ const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd)
peer_gr_cmd = "NO_PEER_GR_CMD";
break;
case PEER_DISABLE_CMD:
- peer_gr_cmd = "PEER_GR_CMD";
+ peer_gr_cmd = "PEER_DISABLE_GR_CMD";
break;
case NO_PEER_DISABLE_CMD:
- peer_gr_cmd = "NO_PEER_GR_CMD";
+ peer_gr_cmd = "NO_PEER_DISABLE_GR_CMD";
break;
case PEER_HELPER_CMD:
peer_gr_cmd = "PEER_HELPER_CMD";
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index 4a20f2c090..f53deb63b3 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -313,14 +313,14 @@ static int bgp_nlri_get_labels(struct peer *peer, uint8_t *pnt, uint8_t plen,
/* If we RX multiple labels we will end up keeping only the last
* one. We do not yet support a label stack greater than 1. */
if (label_depth > 1)
- zlog_info("%s rcvd UPDATE with label stack %d deep", peer->host,
+ zlog_info("%pBP rcvd UPDATE with label stack %d deep", peer,
label_depth);
if (!(bgp_is_withdraw_label(label) || label_bos(label)))
flog_warn(
EC_BGP_INVALID_LABEL_STACK,
- "%s rcvd UPDATE with invalid label stack - no bottom of stack",
- peer->host);
+ "%pBP rcvd UPDATE with invalid label stack - no bottom of stack",
+ peer);
return llen;
}
diff --git a/bgpd/bgp_lcommunity.c b/bgpd/bgp_lcommunity.c
index 60ad75c73b..8720170013 100644
--- a/bgpd/bgp_lcommunity.c
+++ b/bgpd/bgp_lcommunity.c
@@ -175,7 +175,8 @@ struct lcommunity *lcommunity_merge(struct lcommunity *lcom1,
return lcom1;
}
-static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
+static void set_lcommunity_string(struct lcommunity *lcom, bool make_json,
+ bool translate_alias)
{
int i;
int len;
@@ -228,7 +229,8 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
snprintf(lcsb, sizeof(lcsb), "%u:%u:%u", global, local1,
local2);
- const char *com2alias = bgp_community2alias(lcsb);
+ const char *com2alias =
+ translate_alias ? bgp_community2alias(lcsb) : lcsb;
len = strlcat(str_buf, com2alias, str_buf_sz);
assert((unsigned int)len < str_buf_sz);
@@ -264,7 +266,7 @@ struct lcommunity *lcommunity_intern(struct lcommunity *lcom)
find->refcnt++;
if (!find->str)
- set_lcommunity_string(find, false);
+ set_lcommunity_string(find, false, true);
return find;
}
@@ -291,7 +293,8 @@ void lcommunity_unintern(struct lcommunity **lcom)
}
/* Return string representation of lcommunities attribute. */
-char *lcommunity_str(struct lcommunity *lcom, bool make_json)
+char *lcommunity_str(struct lcommunity *lcom, bool make_json,
+ bool translate_alias)
{
if (!lcom)
return NULL;
@@ -300,7 +303,7 @@ char *lcommunity_str(struct lcommunity *lcom, bool make_json)
XFREE(MTYPE_LCOMMUNITY_STR, lcom->str);
if (!lcom->str)
- set_lcommunity_string(lcom, make_json);
+ set_lcommunity_string(lcom, make_json, translate_alias);
return lcom->str;
}
diff --git a/bgpd/bgp_lcommunity.h b/bgpd/bgp_lcommunity.h
index 6ccb6b7879..b9b5fe35d5 100644
--- a/bgpd/bgp_lcommunity.h
+++ b/bgpd/bgp_lcommunity.h
@@ -69,7 +69,8 @@ extern struct hash *lcommunity_hash(void);
extern struct lcommunity *lcommunity_str2com(const char *);
extern bool lcommunity_match(const struct lcommunity *,
const struct lcommunity *);
-extern char *lcommunity_str(struct lcommunity *, bool make_json);
+extern char *lcommunity_str(struct lcommunity *, bool make_json,
+ bool translate_alias);
extern bool lcommunity_include(struct lcommunity *lcom, uint8_t *ptr);
extern void lcommunity_del_val(struct lcommunity *lcom, uint8_t *ptr);
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index 6e695d0301..6cd6ddd9dd 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -905,18 +905,12 @@ void bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
attr.aspath = aspath;
attr.origin = origin;
- if (community) {
+ if (community)
bgp_attr_set_community(&attr, community);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
- }
- if (ecomm) {
+ if (ecomm)
bgp_attr_set_ecommunity(&attr, ecomm);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
- }
- if (lcomm) {
+ if (lcomm)
bgp_attr_set_lcommunity(&attr, lcomm);
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
- }
/* Zap multipath attr nexthop so we set nexthop to self */
attr.nexthop.s_addr = INADDR_ANY;
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 32a1d9a152..0074d5daac 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -523,7 +523,7 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
struct in6_addr *sid_locator)
{
struct listnode *node;
- struct prefix_ipv6 *chunk;
+ struct srv6_locator_chunk *chunk;
struct in6_addr sid_buf;
bool alloced = false;
int label = 0;
@@ -532,8 +532,8 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
return false;
for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
- *sid_locator = chunk->prefix;
- sid_buf = chunk->prefix;
+ *sid_locator = chunk->prefix.prefix;
+ sid_buf = chunk->prefix.prefix;
if (index != 0) {
label = index << 12;
transpose_sid(&sid_buf, label, 64, 16);
@@ -1147,7 +1147,6 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
.rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
}
bgp_attr_set_ecommunity(&static_attr, new_ecom);
- SET_FLAG(static_attr.flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
if (debug && bgp_attr_get_ecommunity(&static_attr)) {
char *s = ecommunity_ecom2str(
@@ -1511,8 +1510,6 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
bgp_attr_set_ecommunity(&static_attr, new_ecom);
if (new_ecom->size == 0) {
- UNSET_FLAG(static_attr.flag,
- ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
ecommunity_free(&new_ecom);
bgp_attr_set_ecommunity(&static_attr, NULL);
}
@@ -1924,7 +1921,7 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
struct bgp *bgp_import;
struct listnode *node;
struct ecommunity *ecom;
- vpn_policy_direction_t idir, edir;
+ enum vpn_policy_direction idir, edir;
/*
* Router-id change that is not explicitly configured
@@ -2037,7 +2034,7 @@ void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
afi_t afi, safi_t safi)
{
const char *export_name;
- vpn_policy_direction_t idir, edir;
+ enum vpn_policy_direction idir, edir;
char *vname, *tmp_name;
char buf[RD_ADDRSTRLEN];
struct ecommunity *ecom;
@@ -2166,7 +2163,7 @@ void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
afi_t afi, safi_t safi)
{
const char *export_name, *tmp_name;
- vpn_policy_direction_t idir, edir;
+ enum vpn_policy_direction idir, edir;
char *vname;
struct ecommunity *ecom = NULL;
struct listnode *node;
@@ -3089,7 +3086,7 @@ void bgp_vpn_leak_export(struct bgp *from_bgp)
char *vname;
struct listnode *node, *next;
struct ecommunity *ecom;
- vpn_policy_direction_t idir, edir;
+ enum vpn_policy_direction idir, edir;
safi_t safi = SAFI_UNICAST;
struct bgp *to_bgp;
int debug;
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 5bf772fefe..8c2eae279c 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -205,7 +205,7 @@ static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi,
return 1;
}
-static inline void vpn_leak_prechange(vpn_policy_direction_t direction,
+static inline void vpn_leak_prechange(enum vpn_policy_direction direction,
afi_t afi, struct bgp *bgp_vpn,
struct bgp *bgp_vrf)
{
@@ -225,7 +225,7 @@ static inline void vpn_leak_prechange(vpn_policy_direction_t direction,
}
}
-static inline void vpn_leak_postchange(vpn_policy_direction_t direction,
+static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
afi_t afi, struct bgp *bgp_vpn,
struct bgp *bgp_vrf)
{
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 424659136e..b0d852ee63 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -483,10 +483,8 @@ void bgp_generate_updgrp_packets(struct thread *thread)
if (bgp_debug_neighbor_events(
peer))
zlog_debug(
- "%s(%s) sending route-refresh (EoRR) for %s/%s",
- peer->host,
- bgp_peer_hostname(
- peer),
+ "%pBP sending route-refresh (EoRR) for %s/%s",
+ peer,
afi2str(afi),
safi2str(safi));
}
@@ -915,10 +913,8 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
stream_putc(s, ORF_COMMON_PART_REMOVE_ALL);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s",
- peer->host,
- bgp_peer_hostname(peer),
- orf_type,
+ "%pBP sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s",
+ peer, orf_type,
(when_to_refresh ==
REFRESH_DEFER
? "defer"
@@ -935,10 +931,8 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
ORF_COMMON_PART_DENY);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s",
- peer->host,
- bgp_peer_hostname(peer),
- orf_type,
+ "%pBP sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s",
+ peer, orf_type,
(when_to_refresh ==
REFRESH_DEFER
? "defer"
@@ -958,9 +952,9 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi,
if (bgp_debug_neighbor_events(peer)) {
if (!orf_refresh)
zlog_debug(
- "%s(%s) sending REFRESH_REQ for afi/safi: %s/%s",
- peer->host, bgp_peer_hostname(peer),
- iana_afi2str(pkt_afi), iana_safi2str(pkt_safi));
+ "%pBP sending REFRESH_REQ for afi/safi: %s/%s",
+ peer, iana_afi2str(pkt_afi),
+ iana_safi2str(pkt_safi));
}
/* Add packet to the peer. */
@@ -1004,8 +998,8 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s",
- peer->host, bgp_peer_hostname(peer),
+ "%pBP sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s",
+ peer,
action == CAPABILITY_ACTION_SET ? "Advertising"
: "Removing",
iana_afi2str(pkt_afi), iana_safi2str(pkt_safi));
@@ -1561,8 +1555,8 @@ static void bgp_refresh_stalepath_timer_expire(struct thread *thread)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) route-refresh (BoRR) timer expired for afi/safi: %d/%d",
- peer->host, bgp_peer_hostname(peer), afi, safi);
+ "%pBP route-refresh (BoRR) timer expired for afi/safi: %d/%d",
+ peer, afi, safi);
bgp_timer_set(peer);
}
@@ -1685,7 +1679,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
*
* Complicates the flow a little though..
*/
- bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
+ enum bgp_attr_parse_ret attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
/* This define morphs the update case into a withdraw when lower levels
* have signalled an error condition where this is best.
*/
@@ -1714,12 +1708,11 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
flog_err(
EC_BGP_UPDATE_RCV,
- "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
- peer->host);
+ "%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
+ peer);
if (ret && bgp_debug_update(peer, NULL, NULL, 1)) {
- zlog_debug("%s(%s) rcvd UPDATE w/ attr: %s", peer->host,
- bgp_peer_hostname(peer),
+ zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
peer->rcvd_attr_str);
peer->rcvd_attr_printed = 1;
}
@@ -1749,9 +1742,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
}
if (BGP_DEBUG(update, UPDATE_IN))
- zlog_debug("%s(%s) rcvd UPDATE wlen %d attrlen %d alen %d",
- peer->host, bgp_peer_hostname(peer), withdraw_len,
- attribute_len, update_len);
+ zlog_debug("%pBP rcvd UPDATE wlen %d attrlen %d alen %d", peer,
+ withdraw_len, attribute_len, update_len);
/* Parse any given NLRIs */
for (int i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++) {
@@ -2104,8 +2096,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
if (bgp_debug_neighbor_events(peer)) {
zlog_debug(
- "%s rcvd Prefixlist ORF(%d) length %d",
- peer->host, orf_type, orf_len);
+ "%pBP rcvd Prefixlist ORF(%d) length %d",
+ peer, orf_type, orf_len);
}
/* we're going to read at least 1 byte of common
@@ -2137,8 +2129,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
if (bgp_debug_neighbor_events(
peer))
zlog_debug(
- "%s rcvd Remove-All pfxlist ORF request",
- peer->host);
+ "%pBP rcvd Remove-All pfxlist ORF request",
+ peer);
prefix_bgp_orf_remove_all(afi,
name);
break;
@@ -2189,8 +2181,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
char buf[INET6_BUFSIZ];
zlog_debug(
- "%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
- peer->host,
+ "%pBP rcvd %s %s seq %u %s/%d ge %d le %d%s",
+ peer,
(common & ORF_COMMON_PART_REMOVE
? "Remove"
: "Add"),
@@ -2220,8 +2212,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
if (!ok || (ok && ret != CMD_SUCCESS)) {
zlog_info(
- "%s Received misformatted prefixlist ORF. Remove All pfxlist",
- peer->host);
+ "%pBP Received misformatted prefixlist ORF. Remove All pfxlist",
+ peer);
prefix_bgp_orf_remove_all(afi,
name);
break;
@@ -2234,7 +2226,7 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
stream_forward_getp(s, orf_len);
}
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s rcvd Refresh %s ORF request", peer->host,
+ zlog_debug("%pBP rcvd Refresh %s ORF request", peer,
when_to_refresh == REFRESH_DEFER
? "Defer"
: "Immediate");
@@ -2285,18 +2277,16 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
PEER_STATUS_EOR_RECEIVED)) {
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) rcvd route-refresh (BoRR) for %s/%s before EoR",
- peer->host, bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi));
+ "%pBP rcvd route-refresh (BoRR) for %s/%s before EoR",
+ peer, afi2str(afi), safi2str(safi));
return BGP_PACKET_NOOP;
}
if (peer->t_refresh_stalepath) {
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received",
- peer->host, bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi));
+ "%pBP rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received",
+ peer, afi2str(afi), safi2str(safi));
return BGP_PACKET_NOOP;
}
@@ -2324,16 +2314,14 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds",
- peer->host, bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi),
+ "%pBP rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds",
+ peer, afi2str(afi), safi2str(safi),
peer->bgp->stalepath_time);
} else if (subtype == BGP_ROUTE_REFRESH_EORR) {
if (!peer->t_refresh_stalepath) {
zlog_err(
- "%s(%s) rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received",
- peer->host, bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi));
+ "%pBP rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received",
+ peer, afi2str(afi), safi2str(safi));
return BGP_PACKET_NOOP;
}
@@ -2345,18 +2333,16 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer",
- peer->host, bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi));
+ "%pBP rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer",
+ peer, afi2str(afi), safi2str(safi));
if (peer->nsf[afi][safi])
bgp_clear_stale_route(peer, afi, safi);
} else {
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) rcvd route-refresh (REQUEST) for %s/%s",
- peer->host, bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi));
+ "%pBP rcvd route-refresh (REQUEST) for %s/%s",
+ peer, afi2str(afi), safi2str(safi));
/* In response to a "normal route refresh request" from the
* peer, the speaker MUST send a BoRR message.
@@ -2371,10 +2357,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
PEER_STATUS_EOR_SEND)) {
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) rcvd route-refresh (REQUEST) for %s/%s before EoR",
- peer->host,
- bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi));
+ "%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR",
+ peer, afi2str(afi),
+ safi2str(safi));
return BGP_PACKET_NOOP;
}
@@ -2383,9 +2368,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) sending route-refresh (BoRR) for %s/%s",
- peer->host, bgp_peer_hostname(peer),
- afi2str(afi), safi2str(safi));
+ "%pBP sending route-refresh (BoRR) for %s/%s",
+ peer, afi2str(afi), safi2str(safi));
/* Set flag Ready-To-Send to know when we can send EoRR
* message.
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 01120ef44a..abf14778d7 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -565,8 +565,8 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
{
const struct prefix *new_p;
struct attr *newattr, *existattr;
- bgp_peer_sort_t new_sort;
- bgp_peer_sort_t exist_sort;
+ enum bgp_peer_sort new_sort;
+ enum bgp_peer_sort exist_sort;
uint32_t new_pref;
uint32_t exist_pref;
uint32_t new_med;
@@ -1769,7 +1769,6 @@ void bgp_attr_add_llgr_community(struct attr *attr)
community_free(&llgr);
bgp_attr_set_community(attr, new);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
}
void bgp_attr_add_gshut_community(struct attr *attr)
@@ -1798,7 +1797,6 @@ void bgp_attr_add_gshut_community(struct attr *attr)
community_free(&gshut);
bgp_attr_set_community(attr, new);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
/* When we add the graceful-shutdown community we must also
* lower the local-preference */
@@ -2207,6 +2205,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
&rmap_path);
+ bgp_attr_flush(&dummy_attr);
peer->rmap_type = 0;
if (ret == RMAP_DENYMATCH) {
@@ -2216,7 +2215,6 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
peer->host, p,
ROUTE_MAP_OUT_NAME(filter));
- bgp_attr_flush(&dummy_attr);
return false;
}
}
@@ -3433,9 +3431,9 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
return false;
zlog_info(
- "%%MAXPFXEXCEED: No. of %s prefix received from %s(%s) %u exceed, limit %u",
- get_afi_safi_str(afi, safi, false), peer->host,
- bgp_peer_hostname(peer), pcount, peer->pmax[afi][safi]);
+ "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
+ get_afi_safi_str(afi, safi, false), peer, pcount,
+ peer->pmax[afi][safi]);
SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
if (CHECK_FLAG(peer->af_flags[afi][safi],
@@ -3473,9 +3471,8 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) Maximum-prefix restart timer started for %d secs",
- peer->host, bgp_peer_hostname(peer),
- peer->v_pmax_restart);
+ "%pBP Maximum-prefix restart timer started for %d secs",
+ peer, peer->v_pmax_restart);
BGP_TIMER_ON(peer->t_pmax_restart,
bgp_maximum_prefix_restart_timer,
@@ -3495,8 +3492,8 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
return false;
zlog_info(
- "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
- get_afi_safi_str(afi, safi, false), peer->host, pcount,
+ "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
+ get_afi_safi_str(afi, safi, false), peer, pcount,
peer->pmax[afi][safi]);
SET_FLAG(peer->af_sflags[afi][safi],
PEER_STATUS_PREFIX_THRESHOLD);
@@ -3712,7 +3709,6 @@ static void bgp_attr_add_no_export_community(struct attr *attr)
community_free(&no_export);
bgp_attr_set_community(attr, new);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
}
int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
@@ -4009,7 +4005,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
num_labels, addpath_id ? 1 : 0,
addpath_id, evpn, pfx_buf,
sizeof(pfx_buf));
- zlog_debug("%s rcvd %s", peer->host,
+ zlog_debug("%pBP rcvd %s", peer,
pfx_buf);
}
@@ -4024,8 +4020,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
if (bgp_debug_update(peer, p, NULL, 1)) {
if (!peer->rcvd_attr_printed) {
zlog_debug(
- "%s rcvd UPDATE w/ attr: %s",
- peer->host,
+ "%pBP rcvd UPDATE w/ attr: %s",
+ peer,
peer->rcvd_attr_str);
peer->rcvd_attr_printed = 1;
}
@@ -4036,8 +4032,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
addpath_id, evpn, pfx_buf,
sizeof(pfx_buf));
zlog_debug(
- "%s rcvd %s...duplicate ignored",
- peer->host, pfx_buf);
+ "%pBP rcvd %s...duplicate ignored",
+ peer, pfx_buf);
}
/* graceful restart STALE flag unset. */
@@ -4063,8 +4059,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
addpath_id ? 1 : 0, addpath_id, evpn,
pfx_buf, sizeof(pfx_buf));
zlog_debug(
- "%s rcvd %s, flapped quicker than processing",
- peer->host, pfx_buf);
+ "%pBP rcvd %s, flapped quicker than processing",
+ peer, pfx_buf);
}
bgp_path_info_restore(dest, pi);
@@ -4084,7 +4080,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
num_labels, addpath_id ? 1 : 0,
addpath_id, evpn, pfx_buf,
sizeof(pfx_buf));
- zlog_debug("%s rcvd %s", peer->host, pfx_buf);
+ zlog_debug("%pBP rcvd %s", peer, pfx_buf);
}
/* graceful restart STALE flag unset. */
@@ -4381,7 +4377,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
/* Received Logging. */
if (bgp_debug_update(peer, p, NULL, 1)) {
if (!peer->rcvd_attr_printed) {
- zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
+ zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
peer->rcvd_attr_str);
peer->rcvd_attr_printed = 1;
}
@@ -4389,7 +4385,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
addpath_id ? 1 : 0, addpath_id, evpn,
pfx_buf, sizeof(pfx_buf));
- zlog_debug("%s rcvd %s", peer->host, pfx_buf);
+ zlog_debug("%pBP rcvd %s", peer, pfx_buf);
}
/* Make new BGP info. */
@@ -4533,7 +4529,7 @@ filtered:
if (bgp_debug_update(peer, p, NULL, 1)) {
if (!peer->rcvd_attr_printed) {
- zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
+ zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
peer->rcvd_attr_str);
peer->rcvd_attr_printed = 1;
}
@@ -4541,8 +4537,8 @@ filtered:
bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
addpath_id ? 1 : 0, addpath_id, evpn,
pfx_buf, sizeof(pfx_buf));
- zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
- peer->host, pfx_buf, reason);
+ zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
+ peer, pfx_buf, reason);
}
if (pi) {
@@ -4646,7 +4642,7 @@ int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
addpath_id ? 1 : 0, addpath_id, NULL,
pfx_buf, sizeof(pfx_buf));
- zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
+ zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
pfx_buf);
}
@@ -8190,14 +8186,16 @@ DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
"[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
"as-set$as_set_s"
"|summary-only$summary_only"
- "|route-map WORD$rmap_name"
+ "|route-map RMAP_NAME$rmap_name"
"|origin <egp|igp|incomplete>$origin_s"
"|matching-MED-only$match_med"
- "|suppress-map WORD$suppress_map"
+ "|suppress-map RMAP_NAME$suppress_map"
"}]",
NO_STR
"Configure BGP aggregate entries\n"
- "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n"
+ "Aggregate prefix\n"
+ "Aggregate address\n"
+ "Aggregate mask\n"
"Generate AS set path information\n"
"Filter more specific routes from updates\n"
"Apply route map to aggregate network\n"
@@ -8252,10 +8250,10 @@ DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
"[no] aggregate-address X:X::X:X/M$prefix [{"
"as-set$as_set_s"
"|summary-only$summary_only"
- "|route-map WORD$rmap_name"
+ "|route-map RMAP_NAME$rmap_name"
"|origin <egp|igp|incomplete>$origin_s"
"|matching-MED-only$match_med"
- "|suppress-map WORD$suppress_map"
+ "|suppress-map RMAP_NAME$suppress_map"
"}]",
NO_STR
"Configure BGP aggregate entries\n"
@@ -10507,7 +10505,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
if (json_paths) {
if (!bgp_attr_get_community(attr)->json)
community_str(bgp_attr_get_community(attr),
- true);
+ true, true);
json_object_lock(bgp_attr_get_community(attr)->json);
json_object_object_add(
json_path, "community",
@@ -10538,7 +10536,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
if (json_paths) {
if (!bgp_attr_get_lcommunity(attr)->json)
lcommunity_str(bgp_attr_get_lcommunity(attr),
- true);
+ true, true);
json_object_lock(bgp_attr_get_lcommunity(attr)->json);
json_object_object_add(
json_path, "largeCommunity",
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 6fcc083e33..6c303a9e5f 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1841,7 +1841,7 @@ struct route_map_rule_cmd route_set_srte_color_cmd = {
"sr-te color", route_set_srte_color, route_set_srte_color_compile,
route_set_srte_color_free};
-/* Set nexthop to object. ojbect must be pointer to struct attr. */
+/* Set nexthop to object. object must be pointer to struct attr. */
struct rmap_ip_nexthop_set {
struct in_addr *address;
int peer_address;
@@ -2199,7 +2199,6 @@ route_set_community(void *rule, const struct prefix *prefix, void *object)
/* "none" case. */
if (rcs->none) {
- attr->flag &= ~(ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES));
bgp_attr_set_community(attr, NULL);
/* See the longer comment down below. */
if (old && old->refcnt == 0)
@@ -2227,8 +2226,6 @@ route_set_community(void *rule, const struct prefix *prefix, void *object)
/* will be interned by caller if required */
bgp_attr_set_community(attr, new);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
-
return RMAP_OKAY;
}
@@ -2313,7 +2310,6 @@ route_set_lcommunity(void *rule, const struct prefix *prefix, void *object)
/* "none" case. */
if (rcs->none) {
- attr->flag &= ~(ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
bgp_attr_set_lcommunity(attr, NULL);
/* See the longer comment down below. */
@@ -2341,8 +2337,6 @@ route_set_lcommunity(void *rule, const struct prefix *prefix, void *object)
/* will be intern()'d or attr_flush()'d by bgp_update_main() */
bgp_attr_set_lcommunity(attr, new);
- attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
-
return RMAP_OKAY;
}
@@ -2438,13 +2432,9 @@ route_set_lcommunity_delete(void *rule, const struct prefix *pfx, void *object)
if (new->size == 0) {
bgp_attr_set_lcommunity(path->attr, NULL);
- path->attr->flag &=
- ~ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
lcommunity_free(&new);
} else {
bgp_attr_set_lcommunity(path->attr, new);
- path->attr->flag |=
- ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
}
}
@@ -2526,12 +2516,9 @@ route_set_community_delete(void *rule, const struct prefix *prefix,
if (new->size == 0) {
bgp_attr_set_community(path->attr, NULL);
- path->attr->flag &=
- ~ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
community_free(&new);
} else {
bgp_attr_set_community(path->attr, new);
- path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
}
}
@@ -2597,7 +2584,6 @@ route_set_ecommunity(void *rule, const struct prefix *prefix, void *object)
attr = path->attr;
if (rcs->none) {
- attr->flag &= ~(ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
bgp_attr_set_ecommunity(attr, NULL);
return RMAP_OKAY;
}
@@ -2624,8 +2610,6 @@ route_set_ecommunity(void *rule, const struct prefix *prefix, void *object)
/* will be intern()'d or attr_flush()'d by bgp_update_main() */
bgp_attr_set_ecommunity(path->attr, new_ecom);
- path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
-
return RMAP_OKAY;
}
@@ -2787,7 +2771,6 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
/* new_ecom will be intern()'d or attr_flush()'d in call stack */
bgp_attr_set_ecommunity(path->attr, new_ecom);
- path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
/* Mark that route-map has set link bandwidth; used in attribute
* setting decisions.
@@ -3306,7 +3289,7 @@ static const struct route_map_rule_cmd
/* `set ipv6 nexthop global IP_ADDRESS' */
-/* Set nexthop to object. ojbect must be pointer to struct attr. */
+/* Set nexthop to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_ipv6_nexthop_global(void *rule, const struct prefix *p, void *object)
{
@@ -3418,7 +3401,7 @@ static const struct route_map_rule_cmd
/* `set ipv6 nexthop local IP_ADDRESS' */
-/* Set nexthop to object. ojbect must be pointer to struct attr. */
+/* Set nexthop to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_ipv6_nexthop_local(void *rule, const struct prefix *p, void *object)
{
@@ -3478,7 +3461,7 @@ static const struct route_map_rule_cmd
/* `set ipv6 nexthop peer-address' */
-/* Set nexthop to object. ojbect must be pointer to struct attr. */
+/* Set nexthop to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_ipv6_nexthop_peer(void *rule, const struct prefix *pfx, void *object)
{
@@ -3809,6 +3792,14 @@ static void bgp_route_map_update_peer_group(const char *rmap_name,
if (filter->usmap.name
&& (strcmp(rmap_name, filter->usmap.name) == 0))
filter->usmap.map = map;
+
+ if (filter->advmap.aname &&
+ (strcmp(rmap_name, filter->advmap.aname) == 0))
+ filter->advmap.amap = map;
+
+ if (filter->advmap.cname &&
+ (strcmp(rmap_name, filter->advmap.cname) == 0))
+ filter->advmap.cmap = map;
}
}
}
@@ -5562,19 +5553,19 @@ DEFUN_YANG (set_community,
str = buffer_getstr(b);
buffer_free(b);
- if (str) {
+ if (str)
com = community_str2com(str);
- XFREE(MTYPE_TMP, str);
- }
/* Can't compile user input into communities attribute. */
if (!com) {
- vty_out(vty, "%% Malformed communities attribute\n");
+ vty_out(vty, "%% Malformed communities attribute '%s'\n", str);
+ XFREE(MTYPE_TMP, str);
return CMD_WARNING_CONFIG_FAILED;
}
+ XFREE(MTYPE_TMP, str);
/* Set communites attribute string. */
- str = community_str(com, false);
+ str = community_str(com, false, false);
if (additive) {
size_t argstr_sz = strlen(str) + strlen(" additive") + 1;
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index c724b938d1..eb9d5f3f73 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -64,13 +64,16 @@
#endif
static struct thread *t_rpki;
+static struct thread *t_rpki_start;
DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE, "BGP RPKI Cache server");
DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group");
+DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_RTRLIB, "BGP RPKI RTRLib");
#define POLLING_PERIOD_DEFAULT 3600
#define EXPIRE_INTERVAL_DEFAULT 7200
#define RETRY_INTERVAL_DEFAULT 600
+#define BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT 3
#define RPKI_DEBUG(...) \
if (rpki_debug) { \
@@ -122,6 +125,7 @@ static int add_tcp_cache(const char *host, const char *port,
static void print_record(const struct pfx_record *record, struct vty *vty);
static int is_synchronized(void);
static int is_running(void);
+static int is_stopping(void);
static void route_match_free(void *rule);
static enum route_map_cmd_result_t route_match(void *rule,
const struct prefix *prefix,
@@ -156,17 +160,17 @@ static const struct route_map_rule_cmd route_match_rpki_cmd = {
static void *malloc_wrapper(size_t size)
{
- return XMALLOC(MTYPE_BGP_RPKI_CACHE, size);
+ return XMALLOC(MTYPE_BGP_RPKI_RTRLIB, size);
}
static void *realloc_wrapper(void *ptr, size_t size)
{
- return XREALLOC(MTYPE_BGP_RPKI_CACHE, ptr, size);
+ return XREALLOC(MTYPE_BGP_RPKI_RTRLIB, ptr, size);
}
static void free_wrapper(void *ptr)
{
- XFREE(MTYPE_BGP_RPKI_CACHE, ptr);
+ XFREE(MTYPE_BGP_RPKI_RTRLIB, ptr);
}
static void init_tr_socket(struct cache *cache)
@@ -331,7 +335,7 @@ static struct rtr_mgr_group *get_groups(void)
inline int is_synchronized(void)
{
- return rtr_is_running && rtr_mgr_conf_in_sync(rtr_config);
+ return is_running() && rtr_mgr_conf_in_sync(rtr_config);
}
inline int is_running(void)
@@ -339,6 +343,11 @@ inline int is_running(void)
return rtr_is_running;
}
+inline int is_stopping(void)
+{
+ return rtr_is_stopping;
+}
+
static struct prefix *pfx_record_to_prefix(struct pfx_record *record)
{
struct prefix *prefix = prefix_new();
@@ -480,7 +489,7 @@ static void rpki_connection_status_cb(const struct rtr_mgr_group *group
struct pfx_record rec = {0};
int retval;
- if (rtr_is_stopping ||
+ if (is_stopping() ||
atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst))
return;
@@ -500,8 +509,8 @@ static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)),
const struct pfx_record rec,
const bool added __attribute__((unused)))
{
- if (rtr_is_stopping
- || atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst))
+ if (is_stopping() ||
+ atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst))
return;
int retval =
@@ -587,6 +596,18 @@ static int bgp_rpki_module_init(void)
return 0;
}
+static void start_expired(struct thread *thread)
+{
+ if (!rtr_mgr_conf_in_sync(rtr_config)) {
+ thread_add_timer(bm->master, start_expired, NULL,
+ BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT,
+ &t_rpki_start);
+ return;
+ }
+
+ rtr_is_running = 1;
+}
+
static int start(void)
{
int ret;
@@ -620,7 +641,8 @@ static int start(void)
rtr_mgr_free(rtr_config);
return ERROR;
}
- rtr_is_running = 1;
+
+ thread_add_timer(bm->master, start_expired, NULL, 0, &t_rpki_start);
XFREE(MTYPE_BGP_RPKI_CACHE_GROUP, groups);
@@ -630,7 +652,8 @@ static int start(void)
static void stop(void)
{
rtr_is_stopping = 1;
- if (rtr_is_running) {
+ if (is_running()) {
+ THREAD_OFF(t_rpki_start);
rtr_mgr_stop(rtr_config);
rtr_mgr_free(rtr_config);
rtr_is_running = 0;
@@ -639,7 +662,10 @@ static void stop(void)
static int reset(bool force)
{
- if (rtr_is_running && !force)
+ if (is_running() && !force)
+ return SUCCESS;
+
+ if (thread_is_scheduled(t_rpki_start))
return SUCCESS;
RPKI_DEBUG("Resetting RPKI Session");
@@ -722,7 +748,7 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
enum pfxv_state result;
if (!is_synchronized())
- return 0;
+ return RPKI_NOT_BEING_USED;
// No aspath means route comes from iBGP
if (!attr->aspath || !attr->aspath->segments) {
@@ -762,7 +788,7 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
break;
default:
- return 0;
+ return RPKI_NOT_BEING_USED;
}
// Do the actual validation
@@ -792,7 +818,7 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
prefix, as_number);
break;
}
- return 0;
+ return RPKI_NOT_BEING_USED;
}
static int add_cache(struct cache *cache)
@@ -804,7 +830,7 @@ static int add_cache(struct cache *cache)
group.sockets_len = 1;
group.sockets = &cache->rtr_socket;
- if (rtr_is_running) {
+ if (is_running()) {
init_tr_socket(cache);
if (rtr_mgr_add_group(rtr_config, &group) != RTR_SUCCESS) {
@@ -902,9 +928,8 @@ static void free_cache(struct cache *cache)
if (cache->type == TCP) {
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->host);
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->port);
- if (cache->tr_config.tcp_config->bindaddr)
- XFREE(MTYPE_BGP_RPKI_CACHE,
- cache->tr_config.tcp_config->bindaddr);
+ XFREE(MTYPE_BGP_RPKI_CACHE,
+ cache->tr_config.tcp_config->bindaddr);
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config);
}
#if defined(FOUND_SSH)
@@ -916,9 +941,8 @@ static void free_cache(struct cache *cache)
cache->tr_config.ssh_config->client_privkey_path);
XFREE(MTYPE_BGP_RPKI_CACHE,
cache->tr_config.ssh_config->server_hostkey_path);
- if (cache->tr_config.ssh_config->bindaddr)
- XFREE(MTYPE_BGP_RPKI_CACHE,
- cache->tr_config.ssh_config->bindaddr);
+ XFREE(MTYPE_BGP_RPKI_CACHE,
+ cache->tr_config.ssh_config->bindaddr);
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.ssh_config);
}
#endif
@@ -1171,9 +1195,9 @@ DEFPY (no_rpki_cache,
return CMD_WARNING;
}
- if (rtr_is_running && listcount(cache_list) == 1) {
+ if (is_running() && listcount(cache_list) == 1) {
stop();
- } else if (rtr_is_running) {
+ } else if (is_running()) {
if (rtr_mgr_remove_group(rtr_config, preference) == RTR_ERROR) {
vty_out(vty, "Could not remove cache %ld", preference);
diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c
index 9446a25a05..bf3e612bfd 100644
--- a/bgpd/bgp_script.c
+++ b/bgpd/bgp_script.c
@@ -156,18 +156,19 @@ void lua_pushattr(lua_State *L, const struct attr *attr)
void lua_decode_attr(lua_State *L, int idx, struct attr *attr)
{
- lua_getfield(L, -1, "metric");
+ lua_getfield(L, idx, "metric");
attr->med = lua_tointeger(L, -1);
lua_pop(L, 1);
- lua_getfield(L, -1, "ifindex");
+ lua_getfield(L, idx, "ifindex");
attr->nh_ifindex = lua_tointeger(L, -1);
lua_pop(L, 1);
- lua_getfield(L, -1, "aspath");
+ lua_getfield(L, idx, "aspath");
attr->aspath = aspath_str2aspath(lua_tostring(L, -1));
lua_pop(L, 1);
- lua_getfield(L, -1, "localpref");
+ lua_getfield(L, idx, "localpref");
attr->local_pref = lua_tointeger(L, -1);
lua_pop(L, 1);
+ lua_pop(L, 1);
}
void *lua_toattr(lua_State *L, int idx)
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index aa3e44318a..e85118e588 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -1463,7 +1463,7 @@ static int update_group_periodic_merge_walkcb(struct update_group *updgrp,
* over multiple statements. Useful to set dirty flag on
* update groups.
*/
-void update_group_policy_update(struct bgp *bgp, bgp_policy_type_e ptype,
+void update_group_policy_update(struct bgp *bgp, enum bgp_policy_type ptype,
const char *pname, int route_update,
int start_event)
{
diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h
index 0e10341bc4..e3309ab7c5 100644
--- a/bgpd/bgp_updgrp.h
+++ b/bgpd/bgp_updgrp.h
@@ -74,7 +74,7 @@
| PEER_CAP_ADDPATH_AF_TX_ADV | PEER_CAP_ADDPATH_AF_RX_RCV \
| PEER_CAP_ENHE_AF_NEGO)
-typedef enum { BGP_ATTR_VEC_NH = 0, BGP_ATTR_VEC_MAX } bpacket_attr_vec_type;
+enum bpacket_attr_vec_type { BGP_ATTR_VEC_NH = 0, BGP_ATTR_VEC_MAX };
typedef struct {
uint32_t flags;
@@ -288,7 +288,7 @@ struct updwalk_context {
struct bgp_path_info *pi;
uint64_t updgrp_id;
uint64_t subgrp_id;
- bgp_policy_type_e policy_type;
+ enum bgp_policy_type policy_type;
const char *policy_name;
int policy_event_start_flag;
int policy_route_update;
@@ -368,7 +368,8 @@ extern void update_subgroup_split_peer(struct peer_af *, struct update_group *);
extern bool update_subgroup_check_merge(struct update_subgroup *, const char *);
extern bool update_subgroup_trigger_merge_check(struct update_subgroup *,
int force);
-extern void update_group_policy_update(struct bgp *bgp, bgp_policy_type_e ptype,
+extern void update_group_policy_update(struct bgp *bgp,
+ enum bgp_policy_type ptype,
const char *pname, int route_update,
int start_event);
extern void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
@@ -409,7 +410,7 @@ extern struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
struct peer_af *paf);
extern void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr);
extern void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
- bpacket_attr_vec_type type,
+ enum bpacket_attr_vec_type type,
struct stream *s, struct attr *attr);
extern void subgroup_default_update_packet(struct update_subgroup *subgrp,
struct attr *attr,
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c
index 0d8ee79ae5..87558f9c35 100644
--- a/bgpd/bgp_updgrp_adv.c
+++ b/bgpd/bgp_updgrp_adv.c
@@ -818,6 +818,8 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
assert(attr.aspath);
attr.local_pref = bgp->default_local_pref;
+ attr.med = 0;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) {
/* IPv6 global nexthop must be included. */
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index cf24e1d689..c4a3ca7500 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -1240,7 +1240,7 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
static void
bpacket_vec_arr_inherit_attr_flags(struct bpacket_attr_vec_arr *vecarr,
- bpacket_attr_vec_type type,
+ enum bpacket_attr_vec_type type,
struct attr *attr)
{
if (CHECK_FLAG(attr->rmap_change_flags,
@@ -1291,8 +1291,8 @@ void bpacket_attr_vec_arr_reset(struct bpacket_attr_vec_arr *vecarr)
/* Setup a particular node entry in the vecarr */
void bpacket_attr_vec_arr_set_vec(struct bpacket_attr_vec_arr *vecarr,
- bpacket_attr_vec_type type, struct stream *s,
- struct attr *attr)
+ enum bpacket_attr_vec_type type,
+ struct stream *s, struct attr *attr)
{
if (!vecarr)
return;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 3600e2f0ec..2aa77576a1 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -286,7 +286,7 @@ static int bgp_srv6_locator_unset(struct bgp *bgp)
{
int ret;
struct listnode *node, *nnode;
- struct prefix_ipv6 *chunk;
+ struct srv6_locator_chunk *chunk;
struct bgp_srv6_function *func;
struct bgp *bgp_vrf;
struct in6_addr *tovpn_sid;
@@ -934,12 +934,12 @@ static void bgp_clear_vty_error(struct vty *vty, struct peer *peer, afi_t afi,
switch (error) {
case BGP_ERR_AF_UNCONFIGURED:
vty_out(vty,
- "%%BGP: Enable %s address family for the neighbor %s\n",
+ "%% BGP: Enable %s address family for the neighbor %s\n",
get_afi_safi_str(afi, safi, false), peer->host);
break;
case BGP_ERR_SOFT_RECONFIG_UNCONFIGURED:
vty_out(vty,
- "%%BGP: Inbound soft reconfig for %s not possible as it\n has neither refresh capability, nor inbound soft reconfig\n",
+ "%% BGP: Inbound soft reconfig for %s not possible as it\n has neither refresh capability, nor inbound soft reconfig\n",
peer->host);
break;
default:
@@ -1086,7 +1086,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
peer = peer_lookup(bgp, &su);
if (!peer) {
vty_out(vty,
- "%%BGP: Unknown neighbor - \"%s\"\n",
+ "%% BGP: Unknown neighbor - \"%s\"\n",
arg);
return CMD_WARNING;
}
@@ -1113,7 +1113,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
group = peer_group_lookup(bgp, arg);
if (!group) {
- vty_out(vty, "%%BGP: No such peer-group %s\n", arg);
+ vty_out(vty, "%% BGP: No such peer-group %s\n", arg);
return CMD_WARNING;
}
@@ -1128,7 +1128,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
if (!found)
vty_out(vty,
- "%%BGP: No %s peer belonging to peer-group %s is configured\n",
+ "%% BGP: No %s peer belonging to peer-group %s is configured\n",
get_afi_safi_str(afi, safi, false), arg);
return CMD_SUCCESS;
@@ -1163,7 +1163,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
if (!found)
vty_out(vty,
- "%%BGP: No external %s peer is configured\n",
+ "%% BGP: No external %s peer is configured\n",
get_afi_safi_str(afi, safi, false));
return CMD_SUCCESS;
@@ -1200,7 +1200,7 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
if (!found)
vty_out(vty,
- "%%BGP: No %s peer is configured with AS %s\n",
+ "%% BGP: No %s peer is configured with AS %s\n",
get_afi_safi_str(afi, safi, false), arg);
return CMD_SUCCESS;
@@ -7434,7 +7434,7 @@ DEFPY (bgp_condadv_period,
DEFPY (neighbor_advertise_map,
neighbor_advertise_map_cmd,
- "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$exist WORD$condition_str",
+ "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map RMAP_NAME$advertise_str <exist-map|non-exist-map>$exist RMAP_NAME$condition_str",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -7455,7 +7455,7 @@ DEFPY (neighbor_advertise_map,
}
ALIAS_HIDDEN(neighbor_advertise_map, neighbor_advertise_map_hidden_cmd,
- "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$exist WORD$condition_str",
+ "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map RMAP_NAME$advertise_str <exist-map|non-exist-map>$exist RMAP_NAME$condition_str",
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Route-map to conditionally advertise routes\n"
"Name of advertise map\n"
@@ -8700,7 +8700,7 @@ DEFPY (af_rt_vpn_imexport,
int ret;
struct ecommunity *ecom = NULL;
int dodir[BGP_VPN_POLICY_DIR_MAX] = {0};
- vpn_policy_direction_t dir;
+ enum vpn_policy_direction dir;
afi_t afi;
int idx = 0;
bool yes = true;
@@ -8780,7 +8780,7 @@ DEFPY (af_route_map_vpn_imexport,
VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
int dodir[BGP_VPN_POLICY_DIR_MAX] = {0};
- vpn_policy_direction_t dir;
+ enum vpn_policy_direction dir;
afi_t afi;
int idx = 0;
bool yes = true;
@@ -8843,7 +8843,7 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd,
"name of route-map\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- vpn_policy_direction_t dir = BGP_VPN_POLICY_DIR_FROMVPN;
+ enum vpn_policy_direction dir = BGP_VPN_POLICY_DIR_FROMVPN;
afi_t afi;
struct bgp *bgp_default;
@@ -8896,7 +8896,7 @@ DEFPY(af_no_import_vrf_route_map, af_no_import_vrf_route_map_cmd,
"name of route-map\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- vpn_policy_direction_t dir = BGP_VPN_POLICY_DIR_FROMVPN;
+ enum vpn_policy_direction dir = BGP_VPN_POLICY_DIR_FROMVPN;
afi_t afi;
afi = vpn_policy_getafi(vty, bgp, true);
@@ -9027,7 +9027,7 @@ DEFPY (bgp_imexport_vpn,
int idx = 0;
bool yes = true;
int flag;
- vpn_policy_direction_t dir;
+ enum vpn_policy_direction dir;
if (argv_find(argv, argc, "no", &idx))
yes = false;
@@ -9316,7 +9316,7 @@ DEFPY (show_bgp_srv6,
{
struct bgp *bgp;
struct listnode *node;
- struct prefix_ipv6 *chunk;
+ struct srv6_locator_chunk *chunk;
struct bgp_srv6_function *func;
struct in6_addr *tovpn4_sid;
struct in6_addr *tovpn6_sid;
@@ -9331,7 +9331,7 @@ DEFPY (show_bgp_srv6,
vty_out(vty, "locator_name: %s\n", bgp->srv6_locator_name);
vty_out(vty, "locator_chunks:\n");
for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
- prefix2str(chunk, buf, sizeof(buf));
+ prefix2str(&chunk->prefix, buf, sizeof(buf));
vty_out(vty, "- %s\n", buf);
}
@@ -12559,6 +12559,18 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
else
json_object_boolean_false_add(
json_neigh, "extendedOptionalParametersLength");
+
+ /* Conditional advertisements */
+ json_object_int_add(
+ json_neigh,
+ "bgpTimerConfiguredConditionalAdvertisementsSec",
+ bgp->condition_check_period);
+ if (thread_is_scheduled(bgp->t_condition_check))
+ json_object_int_add(
+ json_neigh,
+ "bgpTimerUntilConditionalAdvertisementsSec",
+ thread_timer_remain_second(
+ bgp->t_condition_check));
} else {
/* Administrative shutdown. */
if (CHECK_FLAG(p->flags, PEER_FLAG_SHUTDOWN)
@@ -12636,6 +12648,16 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(p))
vty_out(vty,
" Extended Optional Parameters Length is enabled\n");
+
+ /* Conditional advertisements */
+ vty_out(vty,
+ " Configured conditional advertisements interval is %d seconds\n",
+ bgp->condition_check_period);
+ if (thread_is_scheduled(bgp->t_condition_check))
+ vty_out(vty,
+ " Time until conditional advertisements begin is %lu seconds\n",
+ thread_timer_remain_second(
+ bgp->t_condition_check));
}
/* Capability. */
if (peer_established(p) &&
@@ -13042,7 +13064,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
json_object_object_add(json_cap, "hostName",
json_hname);
- /* Gracefull Restart */
+ /* Graceful Restart */
if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV) ||
CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV)) {
if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV) &&
@@ -13452,7 +13474,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
vty_out(vty, "none");
vty_out(vty, "\n");
}
- } /* Gracefull Restart */
+ } /* Graceful Restart */
}
}
@@ -14473,7 +14495,7 @@ static void community_show_all_iterator(struct hash_bucket *bucket,
com = (struct community *)bucket->data;
vty_out(vty, "[%p] (%ld) %s\n", (void *)com, com->refcnt,
- community_str(com, false));
+ community_str(com, false, false));
}
/* Show BGP's community internal data. */
@@ -14502,7 +14524,7 @@ static void lcommunity_show_all_iterator(struct hash_bucket *bucket,
lcom = (struct lcommunity *)bucket->data;
vty_out(vty, "[%p] (%ld) %s\n", (void *)lcom, lcom->refcnt,
- lcommunity_str(lcom, false));
+ lcommunity_str(lcom, false, false));
}
/* Show BGP's community internal data. */
@@ -14604,7 +14626,7 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
char *vname;
char buf1[INET6_ADDRSTRLEN];
char *ecom_str;
- vpn_policy_direction_t dir;
+ enum vpn_policy_direction dir;
if (json) {
json_object *json_import_vrfs = NULL;
@@ -19354,9 +19376,9 @@ static const char *community_list_config_str(struct community_entry *entry)
str = "";
else {
if (entry->style == COMMUNITY_LIST_STANDARD)
- str = community_str(entry->u.com, false);
+ str = community_str(entry->u.com, false, false);
else if (entry->style == LARGE_COMMUNITY_LIST_STANDARD)
- str = lcommunity_str(entry->u.lcom, false);
+ str = lcommunity_str(entry->u.lcom, false, false);
else
str = entry->config;
}
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 78eaac7806..77b8a8ab96 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -3155,26 +3155,26 @@ static int bgp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
struct stream *s = NULL;
struct bgp *bgp = bgp_get_default();
struct listnode *node;
- struct prefix_ipv6 *c;
- struct srv6_locator_chunk s6c = {};
- struct prefix_ipv6 *chunk = NULL;
+ struct srv6_locator_chunk *c;
+ struct srv6_locator_chunk *chunk = srv6_locator_chunk_alloc();
s = zclient->ibuf;
- zapi_srv6_locator_chunk_decode(s, &s6c);
+ zapi_srv6_locator_chunk_decode(s, chunk);
- if (strcmp(bgp->srv6_locator_name, s6c.locator_name) != 0) {
+ if (strcmp(bgp->srv6_locator_name, chunk->locator_name) != 0) {
zlog_err("%s: Locator name unmatch %s:%s", __func__,
- bgp->srv6_locator_name, s6c.locator_name);
+ bgp->srv6_locator_name, chunk->locator_name);
+ srv6_locator_chunk_free(chunk);
return 0;
}
for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, c)) {
- if (!prefix_cmp(c, &s6c.prefix))
+ if (!prefix_cmp(&c->prefix, &chunk->prefix)) {
+ srv6_locator_chunk_free(chunk);
return 0;
+ }
}
- chunk = prefix_ipv6_new();
- *chunk = s6c.prefix;
listnode_add(bgp->srv6_locator_chunks, chunk);
vpn_leak_postchange_all();
return 0;
@@ -3203,7 +3203,7 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
struct srv6_locator loc = {};
struct bgp *bgp = bgp_get_default();
struct listnode *node, *nnode;
- struct prefix_ipv6 *chunk;
+ struct srv6_locator_chunk *chunk;
struct bgp_srv6_function *func;
struct bgp *bgp_vrf;
struct in6_addr *tovpn_sid;
@@ -3215,7 +3215,7 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
// refresh chunks
for (ALL_LIST_ELEMENTS(bgp->srv6_locator_chunks, node, nnode, chunk))
if (prefix_match((struct prefix *)&loc.prefix,
- (struct prefix *)chunk))
+ (struct prefix *)&chunk->prefix))
listnode_delete(bgp->srv6_locator_chunks, chunk);
// refresh functions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 22c09a38ac..a2361758dc 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -565,7 +565,7 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as)
AS change. Just Reset EBGP sessions, not CONFED sessions. If we
were not doing confederation before, reset all EBGP sessions. */
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- bgp_peer_sort_t ptype = peer_sort(peer);
+ enum bgp_peer_sort ptype = peer_sort(peer);
/* We're looking for peers who's AS is not local or part of our
confederation. */
@@ -1004,7 +1004,7 @@ void peer_af_flag_inherit(struct peer *peer, afi_t afi, safi_t safi,
}
/* Check peer's AS number and determines if this peer is IBGP or EBGP */
-static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
+static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
{
struct bgp *bgp;
@@ -1091,13 +1091,13 @@ static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
}
/* Calculate and cache the peer "sort" */
-bgp_peer_sort_t peer_sort(struct peer *peer)
+enum bgp_peer_sort peer_sort(struct peer *peer)
{
peer->sort = peer_calc_sort(peer);
return peer->sort;
}
-bgp_peer_sort_t peer_sort_lookup(struct peer *peer)
+enum bgp_peer_sort peer_sort_lookup(struct peer *peer)
{
return peer->sort;
}
@@ -1826,7 +1826,7 @@ int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
/* Change peer's AS number. */
void peer_as_change(struct peer *peer, as_t as, int as_specified)
{
- bgp_peer_sort_t origtype, newtype;
+ enum bgp_peer_sort origtype, newtype;
/* Stop peer. */
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
@@ -1931,8 +1931,8 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
return BGP_ERR_PEER_GROUP_MEMBER;
}
- bgp_peer_sort_t peer_sort_type =
- peer_sort(peer->group->conf);
+ enum bgp_peer_sort peer_sort_type =
+ peer_sort(peer->group->conf);
/* Explicit AS numbers used, compare AS numbers */
if (as_type == AS_SPECIFIED) {
@@ -2103,6 +2103,20 @@ static void peer_group2peer_config_copy_af(struct peer_group *group,
PEER_ATTR_INHERIT(peer, group, filter[afi][safi].usmap.map);
}
+ /* Conditional Advertisements */
+ if (!CHECK_FLAG(pfilter_ovrd[RMAP_OUT], PEER_FT_ADVERTISE_MAP)) {
+ PEER_STR_ATTR_INHERIT(peer, group,
+ filter[afi][safi].advmap.aname,
+ MTYPE_BGP_FILTER_NAME);
+ PEER_ATTR_INHERIT(peer, group, filter[afi][safi].advmap.amap);
+ PEER_STR_ATTR_INHERIT(peer, group,
+ filter[afi][safi].advmap.cname,
+ MTYPE_BGP_FILTER_NAME);
+ PEER_ATTR_INHERIT(peer, group, filter[afi][safi].advmap.cmap);
+ PEER_ATTR_INHERIT(peer, group,
+ filter[afi][safi].advmap.condition);
+ }
+
if (peer->addpath_type[afi][safi] == BGP_ADDPATH_NONE) {
peer->addpath_type[afi][safi] = conf->addpath_type[afi][safi];
bgp_addpath_type_changed(conf->bgp);
@@ -2349,15 +2363,14 @@ void peer_nsf_stop(struct peer *peer)
if (peer->t_gr_restart) {
BGP_TIMER_OFF(peer->t_gr_restart);
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s(%s) graceful restart timer stopped",
- peer->host, bgp_peer_hostname(peer));
+ zlog_debug("%pBP graceful restart timer stopped", peer);
}
if (peer->t_gr_stale) {
BGP_TIMER_OFF(peer->t_gr_stale);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) graceful restart stalepath timer stopped",
- peer->host, bgp_peer_hostname(peer));
+ "%pBP graceful restart stalepath timer stopped",
+ peer);
}
bgp_clear_route_all(peer);
}
@@ -2899,7 +2912,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
int first_member = 0;
afi_t afi;
safi_t safi;
- bgp_peer_sort_t ptype, gtype;
+ enum bgp_peer_sort ptype, gtype;
/* Lookup the peer. */
if (!peer)
@@ -3767,7 +3780,7 @@ void bgp_free(struct bgp *bgp)
XFREE(MTYPE_BGP_EVPN_INFO, bgp->evpn_info);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- vpn_policy_direction_t dir;
+ enum vpn_policy_direction dir;
if (bgp->vpn_policy[afi].import_vrf)
list_delete(&bgp->vpn_policy[afi].import_vrf);
@@ -4296,9 +4309,8 @@ static void peer_flag_modify_action(struct peer *peer, uint32_t flag)
BGP_TIMER_OFF(peer->t_pmax_restart);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) Maximum-prefix restart timer canceled",
- peer->host,
- bgp_peer_hostname(peer));
+ "%pBP Maximum-prefix restart timer canceled",
+ peer);
}
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
@@ -4491,7 +4503,7 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
}
/*
- * Update peer-group members, unless they are explicitely overriding
+ * Update peer-group members, unless they are explicitly overriding
* peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
@@ -4544,7 +4556,7 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
struct peer *member;
struct listnode *node, *nnode;
struct peer_flag_action action;
- bgp_peer_sort_t ptype;
+ enum bgp_peer_sort ptype;
memset(&action, 0, sizeof(struct peer_flag_action));
size = sizeof(peer_af_flag_action_list)
@@ -4659,7 +4671,7 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
set != invert);
} else {
/*
- * Update peer-group members, unless they are explicitely
+ * Update peer-group members, unless they are explicitly
* overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode,
@@ -4921,7 +4933,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname)
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -4992,7 +5004,7 @@ int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5069,7 +5081,7 @@ int peer_update_source_unset(struct peer *peer)
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5149,7 +5161,7 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5225,7 +5237,7 @@ int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi)
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5330,7 +5342,7 @@ int peer_weight_set(struct peer *peer, afi_t afi, safi_t safi, uint16_t weight)
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5377,7 +5389,7 @@ int peer_weight_unset(struct peer *peer, afi_t afi, safi_t safi)
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5423,7 +5435,7 @@ int peer_timers_set(struct peer *peer, uint32_t keepalive, uint32_t holdtime)
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5462,7 +5474,7 @@ int peer_timers_unset(struct peer *peer)
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5502,7 +5514,7 @@ int peer_timers_connect_set(struct peer *peer, uint32_t connect)
}
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5556,7 +5568,7 @@ int peer_timers_connect_unset(struct peer *peer)
}
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5604,7 +5616,7 @@ int peer_advertise_interval_set(struct peer *peer, uint32_t routeadv)
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5661,7 +5673,7 @@ int peer_advertise_interval_unset(struct peer *peer)
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5702,7 +5714,7 @@ int peer_timers_delayopen_set(struct peer *peer, uint32_t delayopen)
return 0;
/* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
/* Skip peers with overridden configuration. */
@@ -5749,7 +5761,7 @@ int peer_timers_delayopen_unset(struct peer *peer)
return 0;
/* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
/* Skip peers with overridden configuration. */
@@ -5819,7 +5831,7 @@ int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
/*
* Set flag and configuration on all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5885,7 +5897,7 @@ int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
/*
* Remove flags and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -5911,7 +5923,7 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
struct bgp *bgp = peer->bgp;
struct peer *member;
struct listnode *node, *nnode;
- bgp_peer_sort_t ptype = peer_sort(peer);
+ enum bgp_peer_sort ptype = peer_sort(peer);
if (ptype != BGP_PEER_EBGP && ptype != BGP_PEER_INTERNAL)
return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
@@ -5954,7 +5966,7 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6030,7 +6042,7 @@ int peer_local_as_unset(struct peer *peer)
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6094,7 +6106,7 @@ int peer_password_set(struct peer *peer, const char *password)
/*
* Set flag and configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6172,7 +6184,7 @@ int peer_password_unset(struct peer *peer)
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6242,7 +6254,7 @@ int peer_distribute_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
/*
* Set configuration on all peer-group members, un less they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6309,7 +6321,7 @@ int peer_distribute_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
/*
* Remove configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6427,7 +6439,7 @@ int peer_prefix_list_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
/*
* Set configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6495,7 +6507,7 @@ int peer_prefix_list_unset(struct peer *peer, afi_t afi, safi_t safi,
/*
* Remove configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6611,7 +6623,7 @@ int peer_aslist_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
/*
* Set configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6678,7 +6690,7 @@ int peer_aslist_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
/*
* Remove configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6808,7 +6820,7 @@ int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
/*
* Set configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6874,7 +6886,7 @@ int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
/*
* Remove configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6928,7 +6940,7 @@ int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
/*
* Set configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -6990,7 +7002,7 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
/*
* Remove configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -7094,7 +7106,7 @@ int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
/*
* Set configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -7155,7 +7167,7 @@ int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
/*
* Remove configuration on all peer-group members, unless they are
- * explicitely overriding peer-group configuration.
+ * explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -7189,8 +7201,8 @@ static bool peer_maximum_prefix_clear_overflow(struct peer *peer)
BGP_TIMER_OFF(peer->t_pmax_restart);
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- "%s(%s) Maximum-prefix restart timer cancelled",
- peer->host, bgp_peer_hostname(peer));
+ "%pBP Maximum-prefix restart timer cancelled",
+ peer);
}
BGP_EVENT_ADD(peer, BGP_Start);
return true;
@@ -7233,7 +7245,7 @@ int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
/*
* Set flags and configuration on all peer-group members, unless they
- * are explicitely overriding peer-group configuration.
+ * are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -7294,7 +7306,7 @@ int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
/*
* Remove flags and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
struct peer *member;
@@ -7356,7 +7368,7 @@ int peer_maximum_prefix_out_set(struct peer *peer, afi_t afi, safi_t safi,
/*
* Set flag and configuration on all peer-group members, unless they
- * are explicitely overriding peer-group configuration.
+ * are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
/* Skip peers with overridden configuration. */
@@ -7398,7 +7410,7 @@ int peer_maximum_prefix_out_unset(struct peer *peer, afi_t afi, safi_t safi)
/*
* Remove flag and configuration from all peer-group members, unless
- * they are explicitely overriding peer-group configuration.
+ * they are explicitly overriding peer-group configuration.
*/
for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
/* Skip peers with overridden configuration. */
@@ -8138,3 +8150,16 @@ void bgp_gr_apply_running_config(void)
gr_router_detected = false;
}
}
+
+printfrr_ext_autoreg_p("BP", printfrr_bp);
+static ssize_t printfrr_bp(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *ptr)
+{
+ const struct peer *peer = ptr;
+
+ if (!peer)
+ return bputs(buf, "(null)");
+
+ return bprintfrr(buf, "%s(%s)", peer->host,
+ peer->hostname ? peer->hostname : "Unknown");
+}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 766b0199f4..dfed9f2ae9 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -192,11 +192,11 @@ struct bgp_redist {
struct bgp_rmap rmap;
};
-typedef enum {
+enum vpn_policy_direction {
BGP_VPN_POLICY_DIR_FROMVPN = 0,
BGP_VPN_POLICY_DIR_TOVPN = 1,
BGP_VPN_POLICY_DIR_MAX = 2
-} vpn_policy_direction_t;
+};
struct vpn_policy {
struct bgp *bgp; /* parent */
@@ -901,13 +901,13 @@ struct bgp_filter {
/* IBGP/EBGP identifier. We also have a CONFED peer, which is to say,
a peer who's AS is part of our Confederation. */
-typedef enum {
+enum bgp_peer_sort {
BGP_PEER_UNSPECIFIED,
BGP_PEER_IBGP,
BGP_PEER_EBGP,
BGP_PEER_INTERNAL,
BGP_PEER_CONFED,
-} bgp_peer_sort_t;
+};
/* BGP message header and packet size. */
#define BGP_MARKER_SIZE 16
@@ -1084,7 +1084,7 @@ struct peer {
/* Peer's local AS number. */
as_t local_as;
- bgp_peer_sort_t sort;
+ enum bgp_peer_sort sort;
/* Peer's Change local AS number. */
as_t change_local_as;
@@ -1968,12 +1968,12 @@ enum bgp_create_error_code {
/*
* Enumeration of different policy kinds a peer can be configured with.
*/
-typedef enum {
+enum bgp_policy_type {
BGP_POLICY_ROUTE_MAP,
BGP_POLICY_FILTER_LIST,
BGP_POLICY_PREFIX_LIST,
BGP_POLICY_DISTRIBUTE_LIST,
-} bgp_policy_type_e;
+};
/* peer_flag_change_type. */
enum peer_change_type {
@@ -2025,8 +2025,8 @@ extern struct peer *peer_unlock_with_caller(const char *, struct peer *);
#define peer_unlock(A) peer_unlock_with_caller(__FUNCTION__, (A))
#define peer_lock(B) peer_lock_with_caller(__FUNCTION__, (B))
-extern bgp_peer_sort_t peer_sort(struct peer *peer);
-extern bgp_peer_sort_t peer_sort_lookup(struct peer *peer);
+extern enum bgp_peer_sort peer_sort(struct peer *peer);
+extern enum bgp_peer_sort peer_sort_lookup(struct peer *peer);
extern bool peer_active(struct peer *);
extern bool peer_active_nego(struct peer *);
@@ -2473,11 +2473,6 @@ static inline bool bgp_in_graceful_shutdown(struct bgp *bgp)
!!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN));
}
-static inline const char *bgp_peer_hostname(struct peer *peer)
-{
- return peer->hostname ? peer->hostname : "Unknown";
-}
-
/* For benefit of rfapi */
extern struct peer *peer_new(struct bgp *bgp);
@@ -2508,4 +2503,11 @@ void peer_tcp_mss_unset(struct peer *peer);
extern void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi,
safi_t safi);
+
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+/* clang-format off */
+#pragma FRR printfrr_ext "%pBP" (struct peer *)
+/* clang-format on */
+#endif
+
#endif /* _QUAGGA_BGPD_H */
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index 1c8497843e..3aa8868374 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -832,9 +832,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
struct ecommunity *ecomm = bgp_attr_get_ecommunity(&attr);
- if (ecomm->size) {
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
- } else {
+ if (!ecomm->size) {
ecommunity_free(&ecomm);
bgp_attr_set_ecommunity(&attr, NULL);
}
@@ -3980,7 +3978,7 @@ rfapi_rfp_get_group_config_name_l2(struct rfapi_cfg *rfc, const char *name,
* rfp_start_val value returned by rfp_start
* type group type
* name group name
- * criteria RFAPI caller provided serach criteria
+ * criteria RFAPI caller provided search criteria
* search_cb optional rfp_group_config_search_cb_t
*
* output:
@@ -4037,7 +4035,7 @@ void *rfapi_rfp_get_group_config_ptr_name(
* rfp_start_val value returned by rfp_start
* type group type
* logical_net_id group logical network identifier
- * criteria RFAPI caller provided serach criteria
+ * criteria RFAPI caller provided search criteria
* search_cb optional rfp_group_config_search_cb_t
*
* output:
diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c
index f4f2e11391..c479b4d65a 100644
--- a/bgpd/rfapi/vnc_export_bgp.c
+++ b/bgpd/rfapi/vnc_export_bgp.c
@@ -650,9 +650,6 @@ encap_attr_export(struct attr *new, struct attr *orig,
} else {
bgp_attr_set_ecommunity(new, ecom_ro);
}
- if (ecom_ro) {
- new->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
- }
/*
* Set MED
diff --git a/configure.ac b/configure.ac
index 170d16ca6a..c636fade70 100644
--- a/configure.ac
+++ b/configure.ac
@@ -325,6 +325,9 @@ else
fi
fi
+dnl just stick -g into LDFLAGS, if we don't have it in CFLAGS it won't do much
+LDFLAGS="$LDFLAGS -g"
+
AM_CONDITIONAL([DEV_BUILD], [test "$enable_dev_build" = "yes"])
dnl always want these CFLAGS
diff --git a/doc/developer/building-docker.rst b/doc/developer/building-docker.rst
index 35b51cd9c0..4cf356049e 100644
--- a/doc/developer/building-docker.rst
+++ b/doc/developer/building-docker.rst
@@ -109,6 +109,27 @@ No script, multi-arch (ex. amd64, arm64)::
+Building ubi 8 Image
+-----------------------
+
+Script::
+
+ ./docker/ubi-8/build.sh
+
+Script with params, an example could be this (all that info will go to docker label) ::
+
+ ./docker/ubi-8/build.sh frr:ubi-8-my-test "$(git rev-parse --short=10 HEAD)" my_release my_name my_vendor
+
+No script::
+
+ docker build -f docker/ubi-8/Dockerfile .
+
+No script, multi-arch (ex. amd64, arm64)::
+
+ docker buildx build --platform linux/amd64,linux/arm64 -f docker/ubi-8/Dockerfile -t frr-ubi-8:latest .
+
+
+
Building Ubuntu 18.04 Image
---------------------------
diff --git a/doc/developer/draft-zebra-00.ms b/doc/developer/draft-zebra-00.ms
index 25994727a0..b5d6924613 100644
--- a/doc/developer/draft-zebra-00.ms
+++ b/doc/developer/draft-zebra-00.ms
@@ -179,13 +179,13 @@ Interface information message format.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Index (1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| Inteface flag (4) |
+| Interface flag (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| Inteface metric (4) |
+| Interface metric (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| Inteface MTU (4) |
+| Interface MTU (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| Inteface Address count (4) |
+| Interface Address count (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.DE
.sp
diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst
index 7046361204..16d555461d 100644
--- a/doc/developer/logging.rst
+++ b/doc/developer/logging.rst
@@ -171,7 +171,7 @@ Networking data types
:frrfmtout:`(*,1.2.3.4)`
- This is *(S,G)* output for use in pimd. (Note prefix_sg is not a prefix
+ This is *(S,G)* output for use in zebra. (Note prefix_sg is not a prefix
"subclass" like the other prefix_* structs.)
.. frrfmt:: %pSU (union sockunion *)
@@ -205,12 +205,6 @@ Networking data types
``%pNHci``: :frrfmtout:`eth0` — compact interface only
-.. frrfmt:: %pBD (struct bgp_dest *)
-
- :frrfmtout:`fe80::1234/64`
-
- (only available in bgpd.)
-
.. frrfmt:: %dPF (int)
:frrfmtout:`AF_INET`
@@ -361,6 +355,57 @@ FRR library helper formats
(The output is aligned to some degree.)
+FRR daemon specific formats
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following formats are only available in specific daemons, as the code
+implementing them is part of the daemon, not the library.
+
+zebra
+"""""
+
+.. frrfmt:: %pZN (struct route_node *)
+
+ Print information for a RIB node, including zebra-specific data.
+
+ :frrfmtout:`::/0 src fe80::/64 (MRIB)` (``%pZN``)
+
+ :frrfmtout:`1234` (``%pZNt`` - table number)
+
+bgpd
+""""
+
+.. frrfmt:: %pBD (struct bgp_dest *)
+
+ Print prefix for a BGP destination.
+
+ :frrfmtout:`fe80::1234/64`
+
+.. frrfmt:: %pBP (struct peer *)
+
+ :frrfmtout:`192.168.1.1(leaf1.frrouting.org)`
+
+ Print BGP peer's IP and hostname together.
+
+pimd/pim6d
+""""""""""
+
+.. frrfmt:: %pPA (pim_addr *)
+
+ Format IP address according to IP version (pimd vs. pim6d) being compiled.
+
+ :frrfmtout:`fe80::1234` / :frrfmtout:`10.0.0.1`
+
+ :frrfmtout:`*` (``%pPAs`` - replace 0.0.0.0/:: with star)
+
+.. frrfmt:: %pSG (pim_sgaddr *)
+
+ Format S,G pair according to IP version (pimd vs. pim6d) being compiled.
+ Braces are included.
+
+ :frrfmtout:`(*,224.0.0.0)`
+
+
General utility formats
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index b9733cd522..e7adad91b7 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2947,16 +2947,18 @@ This group of server links is referred to as an Ethernet Segment.
Ethernet Segments
"""""""""""""""""
An Ethernet Segment can be configured by specifying a system-MAC and a
-local discriminator against the bond interface on the PE (via zebra) -
+local discriminator or a complete ESINAME against the bond interface on the
+PE (via zebra) -
-.. clicmd:: evpn mh es-id (1-16777215)
+.. clicmd:: evpn mh es-id <(1-16777215)|ESINAME>
.. clicmd:: evpn mh es-sys-mac X:X:X:X:X:X
The sys-mac and local discriminator are used for generating a 10-byte,
-Type-3 Ethernet Segment ID.
+Type-3 Ethernet Segment ID. ESINAME is a 10-byte, Type-0 Ethernet Segment ID -
+"00:AA:BB:CC:DD:EE:FF:GG:HH:II".
-Type-1 (EAS-per-ES and EAD-per-EVI) routes are used to advertise the locally
+Type-1 (EAD-per-ES and EAD-per-EVI) routes are used to advertise the locally
attached ESs and to learn off remote ESs in the network. Local Type-2/MAC-IP
routes are also advertised with a destination ESI allowing for MAC-IP syncing
between Ethernet Segment peers.
@@ -3056,8 +3058,7 @@ route maybe fragmented.
The number of EVIs per-EAD route can be configured via the following
BGP command -
-.. index:: [no] ead-es-frag evi-limit(1-1000)
-.. clicmd:: [no] ead-es-frag evi-limit(1-1000)
+.. clicmd:: [no] ead-es-frag evi-limit (1-1000)
Sample Configuration
^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst
index e71cf4631c..f0946a13f7 100644
--- a/doc/user/pimv6.rst
+++ b/doc/user/pimv6.rst
@@ -113,6 +113,14 @@ Certain signals have special meanings to *pim6d*.
notifications to the kernel. This command is vrf aware, to configure for a
vrf, enter the vrf submode.
+.. clicmd:: ipv6 ssmpingd [X:X::X:X]
+
+ Enable ipv6 ssmpingd configuration. A network level management tool
+ to check whether one can receive multicast packets via SSM from host.
+ The host target given to ssmping must run the ssmpingd daemon which listens
+ for IPv4 and IPv6 unicast requests. When it receives one, it responds to a
+ well known SSM multicast group which ssmping just have joined.
+
.. _pimv6-interface-configuration:
PIMv6 Interface Configuration
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index 0244f7c583..4f04e8616c 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -283,6 +283,17 @@ the default route.
Allow IPv6 nexthop tracking to resolve via the default route. This parameter
is configured per-VRF, so the command is also available in the VRF subnode.
+.. clicmd:: show ip nht [vrf NAME] [A.B.C.D|X:X::X:X] [mrib]
+
+ Show nexthop tracking status for address resolution. If vrf is not specified
+ then display the default vrf. If ``all`` is specified show all vrf address
+ resolution output. If an ipv4 or ipv6 address is not specified then display
+ all addresses tracked, else display the requested address. The mrib keyword
+ indicates that the operator wants to see the multicast rib address resolution
+ table. An alternative form of the command is ``show ip import-check`` and this
+ form of the command is deprecated at this point in time.
+
+
Administrative Distance
=======================
@@ -712,7 +723,7 @@ and this section also helps that case.
Create a new locator. If the name of an existing locator is specified,
move to specified locator's configuration node to change the settings it.
-.. clicmd:: prefix X:X::X:X/M [function-bits-length 32]
+.. clicmd:: prefix X:X::X:X/M [func-bits 32]
Set the ipv6 prefix block of the locator. SRv6 locator is defined by
RFC8986. The actual routing protocol specifies the locator and allocates a
@@ -732,7 +743,7 @@ and this section also helps that case.
will be ``2001:db8:1:1:1::``)
The function bits range is 16bits by default. If operator want to change
- function bits range, they can configure with ``function-bits-length``
+ function bits range, they can configure with ``func-bits``
option.
::
diff --git a/docker/centos-8/Dockerfile b/docker/centos-8/Dockerfile
index 71378c2451..df095edcde 100644
--- a/docker/centos-8/Dockerfile
+++ b/docker/centos-8/Dockerfile
@@ -1,7 +1,11 @@
# This stage builds an rpm from the source
FROM centos:centos8 as centos-8-builder
+RUN sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-*
+RUN sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-*
+
RUN dnf install --enablerepo=powertools -y rpm-build git autoconf pcre-devel \
+ systemd-devel \
automake libtool make readline-devel texinfo net-snmp-devel pkgconfig \
groff pkgconfig json-c-devel pam-devel bison flex python3-pytest \
c-ares-devel python3-devel python3-sphinx libcap-devel platform-python-devel \
@@ -32,6 +36,10 @@ RUN echo '%_smp_mflags %( echo "-j$(/usr/bin/getconf _NPROCESSORS_ONLN)"; )' >>
# This stage installs frr from the rpm
FROM centos:centos8
+
+RUN sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-* \
+ && sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-*
+
RUN mkdir -p /pkgs/rpm \
&& yum install -y https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm
diff --git a/docker/ubi-8/Dockerfile b/docker/ubi-8/Dockerfile
new file mode 100644
index 0000000000..7b2db66ede
--- /dev/null
+++ b/docker/ubi-8/Dockerfile
@@ -0,0 +1,83 @@
+# This stage builds an rpm from the source
+FROM registry.access.redhat.com/ubi8/ubi:8.5 as ubi-8-builder
+
+RUN dnf -y update-minimal --security --sec-severity=Important --sec-severity=Critical
+
+RUN rpm --import https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/PowerTools/x86_64/os
+
+RUN dnf install -qy https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \
+ && dnf install --enablerepo=* -qy rpm-build git autoconf pcre-devel \
+ systemd-devel automake libtool make readline-devel texinfo \
+ net-snmp-devel pkgconfig groff pkgconfig json-c-devel pam-devel \
+ bison flex python3-pytest c-ares-devel python3-devel python3-sphinx \
+ libcap-devel platform-python-devel \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-devel-0.7.0-1.el7.centos.x86_64.rpm
+
+
+COPY . /src
+
+ARG PKGVER
+
+RUN echo '%_smp_mflags %( echo "-j$(/usr/bin/getconf _NPROCESSORS_ONLN)"; )' >> /root/.rpmmacros \
+ && cd /src \
+ && ./bootstrap.sh \
+ && ./configure \
+ --enable-rpki \
+ --enable-snmp=agentx \
+ --enable-numeric-version \
+ --with-pkg-extra-version="_palmetto_git$PKGVER" \
+ && make dist \
+ && cd / \
+ && mkdir -p /rpmbuild/{SOURCES,SPECS} \
+ && cp /src/frr*.tar.gz /rpmbuild/SOURCES \
+ && cp /src/redhat/frr.spec /rpmbuild/SPECS \
+ && rpmbuild \
+ --define "_topdir /rpmbuild" \
+ -ba /rpmbuild/SPECS/frr.spec
+
+# This stage installs frr from the rpm
+FROM registry.access.redhat.com/ubi8/ubi:8.5
+RUN dnf -y update-minimal --security --sec-severity=Important --sec-severity=Critical
+ARG FRR_IMAGE_TAG
+ARG FRR_RELEASE
+ARG FRR_NAME
+ARG FRR_VENDOR
+LABEL name=$FRR_NAME \
+ vendor=$FRR_VENDOR \
+ version=$FRR_IMAGE_TAG \
+ release=$FRR_RELEASE
+
+RUN rpm --import https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os
+
+RUN dnf install -qy https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \
+ && mkdir -p /pkgs/rpm \
+ && dnf install --enablerepo=* -qy https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm
+
+COPY --from=ubi-8-builder /rpmbuild/RPMS/ /pkgs/rpm/
+
+RUN dnf install -qy /pkgs/rpm/*/*.rpm \
+ && rm -rf /pkgs \
+# Own the config / PID files
+ && mkdir -p /var/run/frr \
+ && chown -R frr:frr /etc/frr /var/run/frr
+
+# Add tini because no CentOS8 package
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /sbin/tini
+RUN chmod +x /sbin/tini
+
+# Simple init manager for reaping processes and forwarding signals
+ENTRYPOINT ["/sbin/tini", "--"]
+
+# Default CMD starts watchfrr
+COPY docker/ubi-8/docker-start /usr/lib/frr/docker-start
+CMD ["/usr/lib/frr/docker-start"]
diff --git a/docker/ubi-8/build.sh b/docker/ubi-8/build.sh
new file mode 100755
index 0000000000..0216636893
--- /dev/null
+++ b/docker/ubi-8/build.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+set -e
+
+##
+# Package version needs to be decimal
+##
+DISTRO=ubi-8
+
+GITREV="$2"
+if [ -z "$GITREV" ];then
+ GITREV="$(git rev-parse --short=10 HEAD)"
+fi
+
+FRR_IMAGE_TAG="$1"
+if [ -z $FRR_IMAGE_TAG ];then
+ FRR_IMAGE_TAG="frr:ubi-8-$GITREV"
+fi
+PKGVER="$(printf '%u\n' 0x$GITREV)"
+
+FRR_RELEASE="$3"
+if [ -z $FRR_RELEASE ];then
+ FRR_RELEASE=$(git describe --tags --abbrev=0)
+fi
+
+FRR_NAME=$4
+if [ -z $FRR_NAME ];then
+ FRR_NAME=frr
+fi
+
+FRR_VENDOR=$5
+if [ -z $FRR_VENDOR ];then
+ FRR_VENDOR=frr
+fi
+
+docker build \
+ --cache-from="frr:$DISTRO-builder-$GITREV" \
+ --file=docker/$DISTRO/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --build-arg="FRR_IMAGE_TAG=$FRR_IMAGE_TAG" \
+ --build-arg="FRR_RELEASE=$FRR_RELEASE" \
+ --build-arg="FRR_NAME=$FRR_NAME" \
+ --build-arg="FRR_VENDOR=$FRR_VENDOR" \
+ --tag="$FRR_IMAGE_TAG" \
+ .
+
diff --git a/docker/ubi-8/docker-start b/docker/ubi-8/docker-start
new file mode 100755
index 0000000000..d954142ab9
--- /dev/null
+++ b/docker/ubi-8/docker-start
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+source /usr/lib/frr/frrcommon.sh
+/usr/lib/frr/watchfrr $(daemon_list)
diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c
index d9b500a8fd..218cea7fa3 100644
--- a/eigrpd/eigrp_routemap.c
+++ b/eigrpd/eigrp_routemap.c
@@ -690,7 +690,7 @@ static const struct route_map_rule_cmd route_set_metric_cmd = {
/* `set ip next-hop IP_ADDRESS' */
-/* Set nexthop to object. ojbect must be pointer to struct attr. */
+/* Set nexthop to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_ip_nexthop(void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
@@ -748,7 +748,7 @@ static const struct route_map_rule_cmd route_set_ip_nexthop_cmd = {
/* `set tag TAG' */
-/* Set tag to object. ojbect must be pointer to struct attr. */
+/* Set tag to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_tag(void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c
index 1f50fb9342..5311a384e7 100644
--- a/isisd/isis_bfd.c
+++ b/isisd/isis_bfd.c
@@ -168,6 +168,8 @@ void isis_bfd_circuit_cmd(struct isis_circuit *circuit)
struct listnode *node;
struct isis_adjacency *adj;
+ if (!adjdb)
+ continue;
for (ALL_LIST_ELEMENTS_RO(adjdb, node, adj))
bfd_adj_cmd(adj);
}
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index c7bf1e2012..fedceed3bb 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -661,8 +661,11 @@ int isis_circuit_up(struct isis_circuit *circuit)
"Interface MTU %zu on %s is too low to support area lsp mtu %u!",
isis_circuit_pdu_size(circuit),
circuit->interface->name, circuit->area->lsp_mtu);
- isis_circuit_update_all_srmflags(circuit, 0);
- return ISIS_ERROR;
+
+ /* Allow ISIS to continue configuration. With this
+ * configuration failure ISIS will attempt to send lsp
+ * packets but will fail until the mtu is configured properly
+ */
}
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 019c26687b..cf4c2aea0a 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -393,30 +393,11 @@ int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args)
*/
int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args)
{
- struct listnode *node;
- struct isis_circuit *circuit;
uint16_t lsp_mtu = yang_dnode_get_uint16(args->dnode, NULL);
struct isis_area *area;
switch (args->event) {
case NB_EV_VALIDATE:
- area = nb_running_get_entry(args->dnode, NULL, false);
- if (!area)
- break;
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
- if (circuit->state != C_STATE_INIT
- && circuit->state != C_STATE_UP)
- continue;
- if (lsp_mtu > isis_circuit_pdu_size(circuit)) {
- snprintf(
- args->errmsg, args->errmsg_len,
- "ISIS area contains circuit %s, which has a maximum PDU size of %zu",
- circuit->interface->name,
- isis_circuit_pdu_size(circuit));
- return NB_ERR_VALIDATION;
- }
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -1868,7 +1849,7 @@ int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
/* Remove Link State Database */
- ls_ted_del_all(area->mta->ted);
+ ls_ted_del_all(&area->mta->ted);
/* Flush LSP if circuit engage */
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
@@ -2552,43 +2533,14 @@ int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args)
*/
int lib_interface_isis_create(struct nb_cb_create_args *args)
{
- struct isis_area *area = NULL;
struct interface *ifp;
struct isis_circuit *circuit = NULL;
const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
- uint32_t min_mtu, actual_mtu;
switch (args->event) {
case NB_EV_PREPARE:
case NB_EV_ABORT:
- break;
case NB_EV_VALIDATE:
- /* check if interface mtu is sufficient. If the area has not
- * been created yet, assume default MTU for the area
- */
- ifp = nb_running_get_entry(args->dnode, NULL, false);
- /* zebra might not know yet about the MTU - nothing we can do */
- if (!ifp || ifp->mtu == 0)
- break;
- actual_mtu =
- if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
-
- area = isis_area_lookup(area_tag, ifp->vrf->vrf_id);
- if (area)
- min_mtu = area->lsp_mtu;
- else
-#ifndef FABRICD
- min_mtu = yang_get_default_uint16(
- "/frr-isisd:isis/instance/lsp/mtu");
-#else
- min_mtu = DEFAULT_LSP_MTU;
-#endif /* ifndef FABRICD */
- if (actual_mtu < min_mtu) {
- snprintf(args->errmsg, args->errmsg_len,
- "Interface %s has MTU %u, minimum MTU for the area is %u",
- ifp->name, actual_mtu, min_mtu);
- return NB_ERR_VALIDATION;
- }
break;
case NB_EV_APPLY:
ifp = nb_running_get_entry(args->dnode, NULL, true);
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 95fbca17a8..1a1e0dc294 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -65,7 +65,7 @@
#include "isisd/isis_zebra.h"
/*------------------------------------------------------------------------*
- * Followings are control functions for MPLS-TE parameters management.
+ * Following are control functions for MPLS-TE parameters management.
*------------------------------------------------------------------------*/
/* Main initialization / update function of the MPLS TE Circuit context */
@@ -1231,7 +1231,7 @@ void isis_te_init_ted(struct isis_area *area)
isis_te_parse_lsp(area->mta, lsp);
}
-/* Followings are vty command functions */
+/* Following are vty command functions */
#ifndef FABRICD
static void show_router_id(struct vty *vty, struct isis_area *area)
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 369b83396a..47fe62d27c 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -1628,7 +1628,7 @@ void print_debug(struct vty *vty, int flags, int onoff)
vty_out(vty, "IS-IS Update related packet debugging is %s\n",
onoffs);
if (flags & DEBUG_RTE_EVENTS)
- vty_out(vty, "IS-IS Route related debuggin is %s\n", onoffs);
+ vty_out(vty, "IS-IS Route related debugging is %s\n", onoffs);
if (flags & DEBUG_EVENTS)
vty_out(vty, "IS-IS Event debugging is %s\n", onoffs);
if (flags & DEBUG_PACKET_DUMP)
diff --git a/lib/frrscript.c b/lib/frrscript.c
index 4fee79991a..8add44c19e 100644
--- a/lib/frrscript.c
+++ b/lib/frrscript.c
@@ -373,7 +373,7 @@ int frrscript_load(struct frrscript *fs, const char *function_name,
}
if (luaL_dofile(L, script_name) != 0) {
- zlog_err("frrscript: failed loading script '%s.lua': error: %s",
+ zlog_err("frrscript: failed loading script '%s': error: %s",
script_name, lua_tostring(L, -1));
goto fail;
}
@@ -381,7 +381,7 @@ int frrscript_load(struct frrscript *fs, const char *function_name,
/* To check the Lua function, we get it from the global table */
lua_getglobal(L, function_name);
if (lua_isfunction(L, lua_gettop(L)) == 0) {
- zlog_err("frrscript: loaded script '%s.lua' but %s not found",
+ zlog_err("frrscript: loaded script '%s' but %s not found",
script_name, function_name);
goto fail;
}
@@ -391,7 +391,7 @@ int frrscript_load(struct frrscript *fs, const char *function_name,
if (load_cb && (*load_cb)(fs) != 0) {
zlog_err(
- "frrscript: '%s.lua': %s: loaded but callback returned non-zero exit code",
+ "frrscript: '%s': %s: loaded but callback returned non-zero exit code",
script_name, function_name);
goto fail;
}
diff --git a/lib/link_state.c b/lib/link_state.c
index e4ccd0fb65..639a1d37d8 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -997,25 +997,26 @@ void ls_ted_del(struct ls_ted *ted)
XFREE(MTYPE_LS_DB, ted);
}
-void ls_ted_del_all(struct ls_ted *ted)
+void ls_ted_del_all(struct ls_ted **ted)
{
struct ls_vertex *vertex;
struct ls_edge *edge;
struct ls_subnet *subnet;
- if (ted == NULL)
+ if (*ted == NULL)
return;
/* First remove Vertices, Edges and Subnets and associated Link State */
- frr_each_safe (vertices, &ted->vertices, vertex)
- ls_vertex_del_all(ted, vertex);
- frr_each_safe (edges, &ted->edges, edge)
- ls_edge_del_all(ted, edge);
- frr_each_safe (subnets, &ted->subnets, subnet)
- ls_subnet_del_all(ted, subnet);
+ frr_each_safe (vertices, &(*ted)->vertices, vertex)
+ ls_vertex_del_all(*ted, vertex);
+ frr_each_safe (edges, &(*ted)->edges, edge)
+ ls_edge_del_all(*ted, edge);
+ frr_each_safe (subnets, &(*ted)->subnets, subnet)
+ ls_subnet_del_all(*ted, subnet);
/* then remove TED itself */
- ls_ted_del(ted);
+ ls_ted_del(*ted);
+ *ted = NULL;
}
void ls_ted_clean(struct ls_ted *ted)
diff --git a/lib/link_state.h b/lib/link_state.h
index 761e8b6a27..f46a2068a1 100644
--- a/lib/link_state.h
+++ b/lib/link_state.h
@@ -746,7 +746,7 @@ extern void ls_ted_del(struct ls_ted *ted);
*
* @param ted Link State Data Base
*/
-extern void ls_ted_del_all(struct ls_ted *ted);
+extern void ls_ted_del_all(struct ls_ted **ted);
/**
* Clean Link State Data Base by removing all Vertices, Edges and SubNets marked
diff --git a/lib/prefix.h b/lib/prefix.h
index 816a1517e1..5e03a7b4f5 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -585,6 +585,71 @@ static inline int is_default_host_route(const struct prefix *p)
return 0;
}
+/* IPv6 scope values, usable for IPv4 too (cf. below) */
+/* clang-format off */
+enum {
+ /* 0: reserved */
+ MCAST_SCOPE_IFACE = 0x1,
+ MCAST_SCOPE_LINK = 0x2,
+ MCAST_SCOPE_REALM = 0x3,
+ MCAST_SCOPE_ADMIN = 0x4,
+ MCAST_SCOPE_SITE = 0x5,
+ /* 6-7: unassigned */
+ MCAST_SCOPE_ORG = 0x8,
+ /* 9-d: unassigned */
+ MCAST_SCOPE_GLOBAL = 0xe,
+ /* f: reserved */
+};
+/* clang-format on */
+
+static inline uint8_t ipv6_mcast_scope(const struct in6_addr *addr)
+{
+ return addr->s6_addr[1] & 0xf;
+}
+
+static inline bool ipv6_mcast_nofwd(const struct in6_addr *addr)
+{
+ return (addr->s6_addr[1] & 0xf) <= MCAST_SCOPE_LINK;
+}
+
+static inline bool ipv6_mcast_ssm(const struct in6_addr *addr)
+{
+ uint32_t bits = ntohl(addr->s6_addr32[0]);
+
+ /* ff3x:0000::/32 */
+ return (bits & 0xfff0ffff) == 0xff300000;
+}
+
+static inline uint8_t ipv4_mcast_scope(const struct in_addr *addr)
+{
+ uint32_t bits = ntohl(addr->s_addr);
+
+ /* 224.0.0.0/24 - link scope */
+ if ((bits & 0xffffff00) == 0xe0000000)
+ return MCAST_SCOPE_LINK;
+ /* 239.0.0.0/8 - org scope */
+ if ((bits & 0xff000000) == 0xef000000)
+ return MCAST_SCOPE_ORG;
+
+ return MCAST_SCOPE_GLOBAL;
+}
+
+static inline bool ipv4_mcast_nofwd(const struct in_addr *addr)
+{
+ uint32_t bits = ntohl(addr->s_addr);
+
+ /* 224.0.0.0/24 */
+ return (bits & 0xffffff00) == 0xe0000000;
+}
+
+static inline bool ipv4_mcast_ssm(const struct in_addr *addr)
+{
+ uint32_t bits = ntohl(addr->s_addr);
+
+ /* 232.0.0.0/8 */
+ return (bits & 0xff000000) == 0xe8000000;
+}
+
#ifdef _FRR_ATTRIBUTE_PRINTFRR
#pragma FRR printfrr_ext "%pEA" (struct ethaddr *)
diff --git a/lib/routemap.h b/lib/routemap.h
index 6c4916898a..3ef60222bf 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -276,6 +276,7 @@ DECLARE_QOBJ_TYPE(route_map);
#define IS_MATCH_LOCAL_PREF(C) \
(strmatch(C, "frr-bgp-route-map:match-local-preference"))
#define IS_MATCH_ALIAS(C) (strmatch(C, "frr-bgp-route-map:match-alias"))
+#define IS_MATCH_SCRIPT(C) (strmatch(C, "frr-bgp-route-map:match-script"))
#define IS_MATCH_ORIGIN(C) \
(strmatch(C, "frr-bgp-route-map:match-origin"))
#define IS_MATCH_RPKI(C) (strmatch(C, "frr-bgp-route-map:rpki"))
diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c
index 2685bd2d79..315007be1c 100644
--- a/lib/routemap_cli.c
+++ b/lib/routemap_cli.c
@@ -635,6 +635,11 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode,
yang_dnode_get_string(
dnode,
"./rmap-match-condition/frr-bgp-route-map:alias"));
+ } else if (IS_MATCH_SCRIPT(condition)) {
+ vty_out(vty, " match script %s\n",
+ yang_dnode_get_string(
+ dnode,
+ "./rmap-match-condition/frr-bgp-route-map:script"));
} else if (IS_MATCH_ORIGIN(condition)) {
vty_out(vty, " match origin %s\n",
yang_dnode_get_string(
@@ -1429,41 +1434,6 @@ void route_map_optimization_disabled_show(struct vty *vty,
name);
}
-#if CONFDATE > 20220409
-CPP_NOTICE("Time to remove old route-map optimization command")
-#endif
-
-DEFPY_HIDDEN(
- routemap_optimization, routemap_optimization_cmd,
- "[no] route-map optimization",
- NO_STR
- "route-map\n"
- "optimization\n")
-{
- const struct lyd_node *rmi_dnode;
- const char *rm_name;
- char xpath[XPATH_MAXLEN];
-
- vty_out(vty,
- "%% This command is deprecated. Please, use `route-map NAME optimization` from the config node.\n");
-
- rmi_dnode =
- yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
- if (!rmi_dnode) {
- vty_out(vty, "%% Failed to get RMI dnode in candidate DB\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- rm_name = yang_dnode_get_string(rmi_dnode, "../name");
-
- snprintf(
- xpath, sizeof(xpath),
- "/frr-route-map:lib/route-map[name='%s']/optimization-disabled",
- rm_name);
- nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, no ? "true" : "false");
- return nb_cli_apply_changes(vty, NULL);
-}
-
static int route_map_config_write(struct vty *vty)
{
const struct lyd_node *dnode;
@@ -1582,6 +1552,4 @@ void route_map_cli_init(void)
install_element(RMAP_NODE, &set_srte_color_cmd);
install_element(RMAP_NODE, &no_set_srte_color_cmd);
-
- install_element(RMAP_NODE, &routemap_optimization_cmd);
}
diff --git a/lib/thread.c b/lib/thread.c
index 90074b3d89..44183257bb 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -751,7 +751,7 @@ void thread_master_free(struct thread_master *m)
XFREE(MTYPE_THREAD_MASTER, m);
}
-/* Return remain time in miliseconds. */
+/* Return remain time in milliseconds. */
unsigned long thread_timer_remain_msec(struct thread *thread)
{
int64_t remain;
diff --git a/lib/zlog.h b/lib/zlog.h
index a530c589a8..dcc0bf14e9 100644
--- a/lib/zlog.h
+++ b/lib/zlog.h
@@ -68,7 +68,7 @@ struct xrefdata_logmsg {
* initialization and/or before config load. There is no need to call e.g.
* fprintf(stderr, ...) just because it's "too early" at startup. Depending
* on context, it may still be the right thing to use fprintf though -- try to
- * determine wether something is a log message or something else.
+ * determine whether something is a log message or something else.
*/
extern void vzlogx(const struct xref_logmsg *xref, int prio,
diff --git a/m4/.gitignore b/m4/.gitignore
index 01a2a593d0..63f9fa78ed 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -3,6 +3,7 @@
!ax_compare_version.m4
!ax_cxx_compile_stdcxx.m4
+!ax_lua.m4
!ax_prog_perl_modules.m4
!ax_pthread.m4
!ax_python.m4
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 40afd716c7..63444f8e57 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -1440,6 +1440,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
/* apply route-map */
if (ROUTEMAP(red)) {
troute.route_option = &tinfo;
+ troute.ospf6 = ospf6;
tinfo.ifindex = ifindex;
tinfo.tag = tag;
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index f06a3254ac..9dddd465fe 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -70,7 +70,7 @@ struct ospf6_gr_info {
};
struct ospf6_gr_helper {
- /* Gracefull restart Helper supported configs*/
+ /* Graceful restart Helper supported configs*/
/* Supported grace interval*/
uint32_t supported_grace_time;
diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c
index 29f1c0807d..1908604bd9 100644
--- a/ospfclient/ospf_apiclient.c
+++ b/ospfclient/ospf_apiclient.c
@@ -91,7 +91,7 @@ static unsigned short ospf_apiclient_getport(void)
}
/* -----------------------------------------------------------
- * Followings are functions for connection management
+ * Following are functions for connection management
* -----------------------------------------------------------
*/
@@ -300,7 +300,7 @@ int ospf_apiclient_close(struct ospf_apiclient *oclient)
}
/* -----------------------------------------------------------
- * Followings are functions to send a request to OSPFd
+ * Following are functions to send a request to OSPFd
* -----------------------------------------------------------
*/
@@ -498,7 +498,7 @@ int ospf_apiclient_lsa_delete(struct ospf_apiclient *oclient,
}
/* -----------------------------------------------------------
- * Followings are handlers for messages from OSPF daemon
+ * Following are handlers for messages from OSPF daemon
* -----------------------------------------------------------
*/
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index a624f4ce1e..97bd125aee 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -221,7 +221,7 @@ static struct ospf_apiserver *lookup_apiserver_by_lsa(struct ospf_lsa *lsa)
}
/* -----------------------------------------------------------
- * Followings are functions to manage client connections.
+ * Following are functions to manage client connections.
* -----------------------------------------------------------
*/
static int ospf_apiserver_new_lsa_hook(struct ospf_lsa *lsa)
@@ -1174,7 +1174,7 @@ int ospf_apiserver_handle_register_event(struct ospf_apiserver *apiserv,
/* -----------------------------------------------------------
- * Followings are functions for LSDB synchronization.
+ * Following are functions for LSDB synchronization.
* -----------------------------------------------------------
*/
@@ -1345,7 +1345,7 @@ int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv,
/* -----------------------------------------------------------
- * Followings are functions to originate or update LSA
+ * Following are functions to originate or update LSA
* from an application.
* -----------------------------------------------------------
*/
@@ -1787,7 +1787,7 @@ out:
/* -----------------------------------------------------------
- * Followings are functions to delete LSAs
+ * Following are functions to delete LSAs
* -----------------------------------------------------------
*/
@@ -1952,7 +1952,7 @@ void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv,
/* -----------------------------------------------------------
- * Followings are callback functions to handle opaque types
+ * Following are callback functions to handle opaque types
* -----------------------------------------------------------
*/
@@ -2102,7 +2102,7 @@ void ospf_apiserver_show_info(struct vty *vty, struct json_object *json,
}
/* -----------------------------------------------------------
- * Followings are functions to notify clients about events
+ * Following are functions to notify clients about events
* -----------------------------------------------------------
*/
@@ -2417,7 +2417,7 @@ static void apiserver_clients_lsa_change_notify(uint8_t msgtype,
/* -------------------------------------------------------------
- * Followings are hooks invoked when LSAs are updated or deleted
+ * Following are hooks invoked when LSAs are updated or deleted
* -------------------------------------------------------------
*/
diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h
index 3d57737080..b4d8bb2f52 100644
--- a/ospfd/ospf_apiserver.h
+++ b/ospfd/ospf_apiserver.h
@@ -79,7 +79,7 @@ enum ospf_apiserver_event {
};
/* -----------------------------------------------------------
- * Followings are functions to manage client connections.
+ * Following are functions to manage client connections.
* -----------------------------------------------------------
*/
@@ -99,7 +99,7 @@ extern int ospf_apiserver_send_reply(struct ospf_apiserver *apiserv,
uint32_t seqnr, uint8_t rc);
/* -----------------------------------------------------------
- * Followings are message handler functions
+ * Following are message handler functions
* -----------------------------------------------------------
*/
@@ -147,7 +147,7 @@ extern int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv,
/* -----------------------------------------------------------
- * Followings are functions for LSA origination/deletion
+ * Following are functions for LSA origination/deletion
* -----------------------------------------------------------
*/
@@ -169,7 +169,7 @@ extern void ospf_apiserver_flood_opaque_lsa(struct ospf_lsa *lsa);
/* -----------------------------------------------------------
- * Followings are callback functions to handle opaque types
+ * Following are callback functions to handle opaque types
* -----------------------------------------------------------
*/
@@ -191,7 +191,7 @@ extern void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv,
uint8_t opaque_type);
/* -----------------------------------------------------------
- * Followings are hooks when LSAs are updated or deleted
+ * Following are hooks when LSAs are updated or deleted
* -----------------------------------------------------------
*/
diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c
index 0e5a7e29c0..69847088e4 100644
--- a/ospfd/ospf_ext.c
+++ b/ospfd/ospf_ext.c
@@ -74,7 +74,7 @@ static struct ospf_ext_lp OspfEXT;
/*
* -----------------------------------------------------------------------
- * Followings are initialize/terminate functions for Extended Prefix/Link
+ * Following are initialize/terminate functions for Extended Prefix/Link
* Opaque LSA handling.
* -----------------------------------------------------------------------
*/
@@ -216,7 +216,7 @@ void ospf_ext_finish(void)
/*
* ---------------------------------------------------------------------
- * Followings are control functions for Extended Prefix/Link Opaque LSA
+ * Following are control functions for Extended Prefix/Link Opaque LSA
* parameters management.
* ---------------------------------------------------------------------
*/
@@ -681,7 +681,7 @@ void ospf_ext_update_sr(bool enable)
/*
* -----------------------------------------------------------------------
- * Followings are callback functions against generic Opaque-LSAs handling
+ * Following are callback functions against generic Opaque-LSAs handling
* -----------------------------------------------------------------------
*/
@@ -985,7 +985,7 @@ static int ospf_ext_pref_lsa_update(struct ospf_lsa *lsa)
/*
* -------------------------------------------------------
- * Followings are OSPF protocol processing functions for
+ * Following are OSPF protocol processing functions for
* Extended Prefix/Link Opaque LSA
* -------------------------------------------------------
*/
@@ -1713,7 +1713,7 @@ static void ospf_ext_lsa_schedule(struct ext_itf *exti, enum lsa_opcode op)
/*
* ------------------------------------
- * Followings are vty show functions.
+ * Following are vty show functions.
* ------------------------------------
*/
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index b781c9edc1..947454c0df 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -61,7 +61,7 @@ DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_TYPE, "OSPF opaque per-type info");
DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info");
/*------------------------------------------------------------------------*
- * Followings are initialize/terminate functions for Opaque-LSAs handling.
+ * Following are initialize/terminate functions for Opaque-LSAs handling.
*------------------------------------------------------------------------*/
#ifdef SUPPORT_OSPF_API
@@ -258,7 +258,7 @@ static const char *ospf_opaque_type_name(uint8_t opaque_type)
}
/*------------------------------------------------------------------------*
- * Followings are management functions to store user specified callbacks.
+ * Following are management functions to store user specified callbacks.
*------------------------------------------------------------------------*/
struct opaque_info_per_type; /* Forward declaration. */
@@ -467,7 +467,7 @@ ospf_opaque_functab_lookup(struct ospf_lsa *lsa)
}
/*------------------------------------------------------------------------*
- * Followings are management functions for self-originated LSA entries.
+ * Following are management functions for self-originated LSA entries.
*------------------------------------------------------------------------*/
/*
@@ -759,7 +759,7 @@ out:
}
/*------------------------------------------------------------------------*
- * Followings are (vty) configuration functions for Opaque-LSAs handling.
+ * Following are (vty) configuration functions for Opaque-LSAs handling.
*------------------------------------------------------------------------*/
DEFUN (capability_opaque,
@@ -830,7 +830,7 @@ static void ospf_opaque_register_vty(void)
}
/*------------------------------------------------------------------------*
- * Followings are collection of user-registered function callers.
+ * Following are collection of user-registered function callers.
*------------------------------------------------------------------------*/
static int opaque_lsa_new_if_callback(struct list *funclist,
@@ -978,7 +978,7 @@ out:
}
/*------------------------------------------------------------------------*
- * Followings are glue functions to call Opaque-LSA specific processing.
+ * Following are glue functions to call Opaque-LSA specific processing.
*------------------------------------------------------------------------*/
int ospf_opaque_new_if(struct interface *ifp)
@@ -1283,7 +1283,7 @@ out:
}
/*------------------------------------------------------------------------*
- * Followings are Opaque-LSA origination/refresh management functions.
+ * Following are Opaque-LSA origination/refresh management functions.
*------------------------------------------------------------------------*/
static void ospf_opaque_type9_lsa_originate(struct thread *t);
@@ -1647,7 +1647,7 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa)
}
/*------------------------------------------------------------------------*
- * Followings are re-origination/refresh/flush operations of Opaque-LSAs,
+ * Following are re-origination/refresh/flush operations of Opaque-LSAs,
* triggered by external interventions (vty session, signaling, etc).
*------------------------------------------------------------------------*/
@@ -2162,7 +2162,7 @@ void ospf_opaque_self_originated_lsa_received(struct ospf_neighbor *nbr,
}
/*------------------------------------------------------------------------*
- * Followings are util functions; probably be used by Opaque-LSAs only...
+ * Following are util functions; probably be used by Opaque-LSAs only...
*------------------------------------------------------------------------*/
struct ospf *oi_to_top(struct ospf_interface *oi)
diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h
index b26bc1e10c..59d4288bf2 100644
--- a/ospfd/ospf_opaque.h
+++ b/ospfd/ospf_opaque.h
@@ -64,7 +64,7 @@
#define OPAQUE_TYPE_EXTENDED_LINK_LSA 8
#define OPAQUE_TYPE_MAX 8
-/* Followings types are proposed in internet-draft documents. */
+/* Following types are proposed in internet-draft documents. */
#define OPAQUE_TYPE_8021_QOSPF 129
#define OPAQUE_TYPE_SECONDARY_NEIGHBOR_DISCOVERY 224
#define OPAQUE_TYPE_FLOODGATE 225
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index 0efa6ca4d5..3efdb53102 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -66,7 +66,7 @@
static struct ospf_router_info OspfRI;
/*------------------------------------------------------------------------------*
- * Followings are initialize/terminate functions for Router Information
+ * Following are initialize/terminate functions for Router Information
*handling.
*------------------------------------------------------------------------------*/
@@ -232,7 +232,7 @@ static struct ospf_ri_area_info *lookup_by_area(struct ospf_area *area)
}
/*------------------------------------------------------------------------*
- * Followings are control functions for ROUTER INFORMATION parameters
+ * Following are control functions for ROUTER INFORMATION parameters
*management.
*------------------------------------------------------------------------*/
@@ -668,7 +668,7 @@ void ospf_router_info_update_sr(bool enable, struct sr_node *srn)
}
/*------------------------------------------------------------------------*
- * Followings are callback functions against generic Opaque-LSAs handling.
+ * Following are callback functions against generic Opaque-LSAs handling.
*------------------------------------------------------------------------*/
static void ospf_router_info_ism_change(struct ospf_interface *oi,
int old_state)
@@ -693,7 +693,7 @@ static void ospf_router_info_ism_change(struct ospf_interface *oi,
}
/*------------------------------------------------------------------------*
- * Followings are OSPF protocol processing functions for ROUTER INFORMATION
+ * Following are OSPF protocol processing functions for ROUTER INFORMATION
*------------------------------------------------------------------------*/
static void build_tlv_header(struct stream *s, struct tlv_header *tlvh)
@@ -1223,7 +1223,7 @@ static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
}
/*------------------------------------------------------------------------*
- * Followings are vty session control functions.
+ * Following are vty session control functions.
*------------------------------------------------------------------------*/
#define check_tlv_size(size, msg) \
@@ -1660,7 +1660,7 @@ static void ospf_router_info_config_write_router(struct vty *vty)
}
/*------------------------------------------------------------------------*
- * Followings are vty command functions.
+ * Following are vty command functions.
*------------------------------------------------------------------------*/
/* Simple wrapper schedule RI LSA action in function of the scope */
static void ospf_router_info_schedule(enum lsa_opcode opcode)
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index b5dbc4a5a9..c861685f4e 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -2023,7 +2023,7 @@ void ospf_sr_update_task(struct ospf *ospf)
/*
* --------------------------------------
- * Followings are vty command functions.
+ * Following are vty command functions.
* --------------------------------------
*/
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 999bc49d91..ddc62982bd 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -79,7 +79,7 @@ static const char *const mode2text[] = {"Off", "AS", "Area"};
/*------------------------------------------------------------------------*
- * Followings are initialize/terminate functions for MPLS-TE handling.
+ * Following are initialize/terminate functions for MPLS-TE handling.
*------------------------------------------------------------------------*/
static int ospf_mpls_te_new_if(struct interface *ifp);
@@ -197,7 +197,7 @@ void ospf_mpls_te_finish(void)
}
/*------------------------------------------------------------------------*
- * Followings are control functions for MPLS-TE parameters management.
+ * Following are control functions for MPLS-TE parameters management.
*------------------------------------------------------------------------*/
static void del_mpls_te_link(void *val)
{
@@ -814,7 +814,7 @@ static int is_mandated_params_set(struct mpls_te_link *lp)
}
/*------------------------------------------------------------------------*
- * Followings are callback functions against generic Opaque-LSAs handling.
+ * Following are callback functions against generic Opaque-LSAs handling.
*------------------------------------------------------------------------*/
static int ospf_mpls_te_new_if(struct interface *ifp)
@@ -1079,7 +1079,7 @@ static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_state)
}
/*------------------------------------------------------------------------*
- * Followings are OSPF protocol processing functions for MPLS-TE LSA.
+ * Following are OSPF protocol processing functions for MPLS-TE LSA.
*------------------------------------------------------------------------*/
static void build_tlv_header(struct stream *s, struct tlv_header *tlvh)
@@ -1624,7 +1624,7 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode)
/**
* ------------------------------------------------------
- * Followings are Link State Data Base control functions.
+ * Following are Link State Data Base control functions.
* ------------------------------------------------------
*/
@@ -3153,7 +3153,7 @@ static void ospf_te_init_ted(struct ls_ted *ted, struct ospf *ospf)
}
/*------------------------------------------------------------------------*
- * Followings are vty session control functions.
+ * Following are vty session control functions.
*------------------------------------------------------------------------*/
#define check_tlv_size(size, msg) \
do { \
@@ -3846,7 +3846,7 @@ static void ospf_mpls_te_config_write_router(struct vty *vty)
}
/*------------------------------------------------------------------------*
- * Followings are vty command functions.
+ * Following are vty command functions.
*------------------------------------------------------------------------*/
DEFUN (ospf_mpls_te_on,
@@ -3908,7 +3908,7 @@ DEFUN (no_ospf_mpls_te,
ote_debug("MPLS-TE: ON -> OFF");
/* Remove TED */
- ls_ted_del_all(OspfMplsTE.ted);
+ ls_ted_del_all(&OspfMplsTE.ted);
OspfMplsTE.enabled = false;
/* Flush all TE Opaque LSAs */
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index a753340476..3bd4a9bb68 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -4394,7 +4394,8 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty,
json_neighbor = json_object_new_object();
- ospf_nbr_ism_state_message(nbr, msgbuf, 16);
+ ospf_nbr_ism_state_message(nbr, msgbuf,
+ sizeof(msgbuf));
#if CONFDATE > 20230321
CPP_NOTICE("Remove show_ip_ospf_neighbor_sub() JSON keys: priority, state, deadTimeMsecs, address, retransmitCounter, requestCounter, dbSummaryCounter")
#endif
@@ -4490,7 +4491,8 @@ CPP_NOTICE("Remove show_ip_ospf_neighbor_sub() JSON keys: priority, state, deadT
json_object_array_add(json_neigh_array,
json_neighbor);
} else {
- ospf_nbr_ism_state_message(nbr, msgbuf, 16);
+ ospf_nbr_ism_state_message(nbr, msgbuf,
+ sizeof(msgbuf));
if (nbr->state == NSM_Attempt
&& nbr->router_id.s_addr == INADDR_ANY)
@@ -5116,6 +5118,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
char timebuf[OSPF_TIME_DUMP_SIZE];
json_object *json_neigh = NULL, *json_neigh_array = NULL;
char neigh_str[INET_ADDRSTRLEN] = {0};
+ char neigh_state[16] = {0};
if (use_json) {
if (prev_nbr &&
@@ -5168,15 +5171,13 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
ospf_area_desc_string(oi->area), oi->ifp->name);
/* Show neighbor priority and state. */
+ ospf_nbr_ism_state_message(nbr, neigh_state, sizeof(neigh_state));
if (use_json) {
json_object_int_add(json_neigh, "nbrPriority", nbr->priority);
- json_object_string_add(
- json_neigh, "nbrState",
- lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
+ json_object_string_add(json_neigh, "nbrState", neigh_state);
} else
vty_out(vty, " Neighbor priority is %d, State is %s,",
- nbr->priority,
- lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
+ nbr->priority, neigh_state);
/* Show state changes. */
if (use_json)
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 4f1b1493a6..268e4d6f8d 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -337,7 +337,7 @@ struct ospf {
struct list *external[ZEBRA_ROUTE_MAX + 1];
#define EXTERNAL_INFO(E) (E->external_info)
- /* Gracefull restart Helper supported configs*/
+ /* Graceful restart Helper supported configs*/
/* Supported grace interval*/
uint32_t supported_grace_time;
diff --git a/pathd/path_pcep_controller.h b/pathd/path_pcep_controller.h
index de113feee9..bc7ed4910a 100644
--- a/pathd/path_pcep_controller.h
+++ b/pathd/path_pcep_controller.h
@@ -132,7 +132,7 @@ struct pcep_pcc_info *pcep_ctrl_get_pcc_info(struct frr_pthread *fpt,
/* Asynchronously send a report. The caller is giving away the path structure,
* it shouldn't be allocated on the stack. If `pcc_id` is `0` the report is
- * sent by all PCCs. The parameter is_stable is used to hint wether the status
+ * sent by all PCCs. The parameter is_stable is used to hint whether the status
* will soon change, this is used to ensure all report updates are sent even
* when missing status update events */
int pcep_ctrl_send_report(struct frr_pthread *fpt, int pcc_id,
diff --git a/pathd/path_ted.c b/pathd/path_ted.c
index 3440b93399..7477444104 100644
--- a/pathd/path_ted.c
+++ b/pathd/path_ted.c
@@ -66,7 +66,7 @@ uint32_t path_ted_teardown(void)
PATH_TED_DEBUG("%s : TED [%p]", __func__, ted_state_g.ted);
path_ted_unregister_vty();
path_ted_stop_importing_igp();
- ls_ted_del_all(ted_state_g.ted);
+ ls_ted_del_all(&ted_state_g.ted);
path_ted_timer_sync_cancel();
path_ted_timer_refresh_cancel();
return 0;
@@ -353,7 +353,7 @@ DEFPY (debug_path_ted,
}
/*
- * Followings are vty command functions.
+ * Following are vty command functions.
*/
/* clang-format off */
DEFUN (path_ted_on,
@@ -391,7 +391,7 @@ DEFUN (no_path_ted,
}
/* Remove TED */
- ls_ted_del_all(ted_state_g.ted);
+ ls_ted_del_all(&ted_state_g.ted);
ted_state_g.enabled = false;
PATH_TED_DEBUG("%s: PATHD-TED: ON -> OFF", __func__);
ted_state_g.import = IMPORT_UNKNOWN;
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index da4e3e1bc0..4506dc1af1 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -64,7 +64,7 @@ void pbr_if_del(struct interface *ifp)
XFREE(MTYPE_PBR_INTERFACE, ifp->info);
}
-/* Inteface addition message from zebra. */
+/* Interface addition message from zebra. */
int pbr_ifp_create(struct interface *ifp)
{
DEBUGD(&pbr_dbg_zebra, "%s: %s", __func__, ifp->name);
diff --git a/pceplib/pcep_msg_objects.h b/pceplib/pcep_msg_objects.h
index 270db4aa8d..6d7d3be7e6 100644
--- a/pceplib/pcep_msg_objects.h
+++ b/pceplib/pcep_msg_objects.h
@@ -542,7 +542,7 @@ struct pcep_ro_subobj_asn {
uint16_t asn; /* Autonomous system number */
};
-/* The SR ERO and SR RRO subojbects are the same, except
+/* The SR ERO and SR RRO subobjects are the same, except
* the SR-RRO does not have the L flag in the Type field.
* Defined in draft-ietf-pce-segment-routing-16 */
enum pcep_sr_subobj_nai {
diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c
index 7b3e04fdc0..ce26f912f4 100644
--- a/pimd/pim6_cmd.c
+++ b/pimd/pim6_cmd.c
@@ -33,11 +33,14 @@
#include "pimd.h"
#include "pim6_cmd.h"
+#include "pim_cmd_common.h"
#include "pim_vty.h"
#include "lib/northbound_cli.h"
#include "pim_errors.h"
#include "pim_nb.h"
-#include "pim_cmd_common.h"
+#include "pim_addr.h"
+#include "pim_nht.h"
+
#ifndef VTYSH_EXTRACT_PL
#include "pimd/pim6_cmd_clippy.c"
@@ -167,7 +170,7 @@ DEFPY (ipv6_pim_rp_keep_alive,
"ipv6 pim rp keep-alive-timer (1-65535)$kat",
IPV6_STR
PIM_STR
- "Rendevous Point\n"
+ "Rendezvous Point\n"
"Keep alive Timer\n"
"Seconds\n")
{
@@ -180,7 +183,7 @@ DEFPY (no_ipv6_pim_rp_keep_alive,
NO_STR
IPV6_STR
PIM_STR
- "Rendevous Point\n"
+ "Rendezvous Point\n"
"Keep alive Timer\n"
IGNORED_IN_NO_STR)
{
@@ -448,6 +451,33 @@ DEFPY (no_ipv6_pim_rp_prefix_list,
return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
}
+
+DEFPY (ipv6_ssmpingd,
+ ipv6_ssmpingd_cmd,
+ "ipv6 ssmpingd [X:X::X:X]$source",
+ IPV6_STR
+ CONF_SSMPINGD_STR
+ "Source address\n")
+{
+ const char *src_str = (source_str) ? source_str : "::";
+
+ return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
+}
+
+
+DEFPY (no_ipv6_ssmpingd,
+ no_ipv6_ssmpingd_cmd,
+ "no ipv6 ssmpingd [X:X::X:X]$source",
+ NO_STR
+ IPV6_STR
+ CONF_SSMPINGD_STR
+ "Source address\n")
+{
+ const char *src_str = (source_str) ? source_str : "::";
+
+ return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
+}
+
DEFPY (interface_ipv6_mld_join,
interface_ipv6_mld_join_cmd,
"ipv6 mld join X:X::X:X$group [X:X::X:X$source]",
@@ -622,6 +652,926 @@ DEFPY (interface_no_ipv6_mld_query_interval,
"frr-routing:ipv6");
}
+DEFPY (mld_group_watermark,
+ mld_group_watermark_cmd,
+ "ipv6 mld watermark-warn (1-65535)$limit",
+ IPV6_STR
+ MLD_STR
+ "Configure group limit for watermark warning\n"
+ "Group count to generate watermark warning\n")
+{
+ PIM_DECLVAR_CONTEXT(vrf, pim);
+ /* TBD Depends on MLD data structure changes */
+ return CMD_SUCCESS;
+}
+
+DEFPY (no_mld_group_watermark,
+ no_mld_group_watermark_cmd,
+ "no ipv6 mld watermark-warn [(1-65535)$limit]",
+ NO_STR
+ IPV6_STR
+ MLD_STR
+ "Unconfigure group limit for watermark warning\n"
+ IGNORED_IN_NO_STR)
+{
+ PIM_DECLVAR_CONTEXT(vrf, pim);
+ /* TBD Depends on MLD data structure changes */
+ return CMD_SUCCESS;
+}
+
+DEFPY (interface_ipv6_mld_query_max_response_time,
+ interface_ipv6_mld_query_max_response_time_cmd,
+ "ipv6 mld query-max-response-time (1-65535)$qmrt",
+ IPV6_STR
+ IFACE_MLD_STR
+ IFACE_MLD_QUERY_MAX_RESPONSE_TIME_STR
+ "Query response value in deci-seconds\n")
+{
+ return gm_process_query_max_response_time_cmd(vty, qmrt_str);
+}
+
+DEFPY (interface_no_ipv6_mld_query_max_response_time,
+ interface_no_ipv6_mld_query_max_response_time_cmd,
+ "no ipv6 mld query-max-response-time [(1-65535)]",
+ NO_STR
+ IPV6_STR
+ IFACE_MLD_STR
+ IFACE_MLD_QUERY_MAX_RESPONSE_TIME_STR
+ IGNORED_IN_NO_STR)
+{
+ return gm_process_no_query_max_response_time_cmd(vty);
+}
+
+DEFPY (interface_ipv6_mld_last_member_query_count,
+ interface_ipv6_mld_last_member_query_count_cmd,
+ "ipv6 mld last-member-query-count (1-255)$lmqc",
+ IPV6_STR
+ IFACE_MLD_STR
+ IFACE_MLD_LAST_MEMBER_QUERY_COUNT_STR
+ "Last member query count\n")
+{
+ return gm_process_last_member_query_count_cmd(vty, lmqc_str);
+}
+
+DEFPY (interface_no_ipv6_mld_last_member_query_count,
+ interface_no_ipv6_mld_last_member_query_count_cmd,
+ "no ipv6 mld last-member-query-count [(1-255)]",
+ NO_STR
+ IPV6_STR
+ IFACE_MLD_STR
+ IFACE_MLD_LAST_MEMBER_QUERY_COUNT_STR
+ IGNORED_IN_NO_STR)
+{
+ return gm_process_no_last_member_query_count_cmd(vty);
+}
+
+DEFPY (interface_ipv6_mld_last_member_query_interval,
+ interface_ipv6_mld_last_member_query_interval_cmd,
+ "ipv6 mld last-member-query-interval (1-65535)$lmqi",
+ IPV6_STR
+ IFACE_MLD_STR
+ IFACE_MLD_LAST_MEMBER_QUERY_INTERVAL_STR
+ "Last member query interval in deciseconds\n")
+{
+ return gm_process_last_member_query_interval_cmd(vty, lmqi_str);
+}
+
+DEFPY (interface_no_ipv6_mld_last_member_query_interval,
+ interface_no_ipv6_mld_last_member_query_interval_cmd,
+ "no ipv6 mld last-member-query-interval [(1-65535)]",
+ NO_STR
+ IPV6_STR
+ IFACE_MLD_STR
+ IFACE_MLD_LAST_MEMBER_QUERY_INTERVAL_STR
+ IGNORED_IN_NO_STR)
+{
+ return gm_process_no_last_member_query_interval_cmd(vty);
+}
+
+DEFPY (show_ipv6_pim_rp,
+ show_ipv6_pim_rp_cmd,
+ "show ipv6 pim [vrf NAME] rp-info [X:X::X:X/M$group] [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM RP information\n"
+ "Multicast Group range\n"
+ JSON_STR)
+{
+ struct pim_instance *pim;
+ struct vrf *v;
+ json_object *json_parent = NULL;
+ struct prefix *range = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (group_str) {
+ range = prefix_new();
+ prefix_copy(range, group);
+ apply_mask(range);
+ }
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_rp_show_information(pim, range, vty, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ prefix_free(&range);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_rp_vrf_all,
+ show_ipv6_pim_rp_vrf_all_cmd,
+ "show ipv6 pim vrf all rp-info [X:X::X:X/M$group] [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM RP information\n"
+ "Multicast Group range\n"
+ JSON_STR)
+{
+ struct vrf *vrf;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+ struct prefix *range = NULL;
+
+ if (group_str) {
+ range = prefix_new();
+ prefix_copy(range, group);
+ apply_mask(range);
+ }
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", vrf->name);
+ else
+ json_vrf = json_object_new_object();
+ pim_rp_show_information(vrf->info, range, vty, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
+ }
+ if (json)
+ vty_json(vty, json_parent);
+
+ prefix_free(&range);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_rpf,
+ show_ipv6_pim_rpf_cmd,
+ "show ipv6 pim [vrf NAME] rpf [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM cached source rpf information\n"
+ JSON_STR)
+{
+ struct pim_instance *pim;
+ struct vrf *v;
+ json_object *json_parent = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_show_rpf(pim, vty, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_rpf_vrf_all,
+ show_ipv6_pim_rpf_vrf_all_cmd,
+ "show ipv6 pim vrf all rpf [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM cached source rpf information\n"
+ JSON_STR)
+{
+ struct vrf *vrf;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", vrf->name);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_rpf(vrf->info, vty, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
+ }
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_secondary,
+ show_ipv6_pim_secondary_cmd,
+ "show ipv6 pim [vrf NAME] secondary",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM neighbor addresses\n")
+{
+ struct pim_instance *pim;
+ struct vrf *v;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ pim_show_neighbors_secondary(pim, vty);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_statistics,
+ show_ipv6_pim_statistics_cmd,
+ "show ipv6 pim [vrf NAME] statistics [interface WORD$word] [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM statistics\n"
+ INTERFACE_STR
+ "PIM interface\n"
+ JSON_STR)
+{
+ struct pim_instance *pim;
+ struct vrf *v;
+ bool uj = !!json;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (word)
+ pim_show_statistics(pim, vty, word, uj);
+ else
+ pim_show_statistics(pim, vty, NULL, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_upstream,
+ show_ipv6_pim_upstream_cmd,
+ "show ipv6 pim [vrf NAME] upstream [X:X::X:X$s_or_g [X:X::X:X$g]] [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM upstream information\n"
+ "The Source or Group\n"
+ "The Group\n"
+ JSON_STR)
+{
+ pim_sgaddr sg = {0};
+ struct vrf *v;
+ bool uj = !!json;
+ struct pim_instance *pim;
+ json_object *json_parent = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v) {
+ vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
+ return CMD_WARNING;
+ }
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (uj)
+ json_parent = json_object_new_object();
+
+ if (!pim_addr_is_any(s_or_g)) {
+ if (!pim_addr_is_any(g)) {
+ sg.src = s_or_g;
+ sg.grp = g;
+ } else
+ sg.grp = s_or_g;
+ }
+
+ pim_show_upstream(pim, vty, &sg, json_parent);
+
+ if (uj)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_upstream_vrf_all,
+ show_ipv6_pim_upstream_vrf_all_cmd,
+ "show ipv6 pim vrf all upstream [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM upstream information\n"
+ JSON_STR)
+{
+ pim_sgaddr sg = {0};
+ struct vrf *vrf;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", vrf->name);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_upstream(vrf->info, vty, &sg, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
+ }
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_upstream_join_desired,
+ show_ipv6_pim_upstream_join_desired_cmd,
+ "show ipv6 pim [vrf NAME] upstream-join-desired [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM upstream join-desired\n"
+ JSON_STR)
+{
+ struct pim_instance *pim;
+ struct vrf *v;
+ bool uj = !!json;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ pim_show_join_desired(pim, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_upstream_rpf,
+ show_ipv6_pim_upstream_rpf_cmd,
+ "show ipv6 pim [vrf NAME] upstream-rpf [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM upstream source rpf\n"
+ JSON_STR)
+{
+ struct pim_instance *pim;
+ struct vrf *v;
+ bool uj = !!json;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ pim_show_upstream_rpf(pim, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_state,
+ show_ipv6_pim_state_cmd,
+ "show ipv6 pim [vrf NAME] state [X:X::X:X$s_or_g [X:X::X:X$g]] [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM state information\n"
+ "Unicast or Multicast address\n"
+ "Multicast address\n"
+ JSON_STR)
+{
+ struct pim_instance *pim;
+ struct vrf *v;
+ json_object *json_parent = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_show_state(pim, vty, s_or_g_str, g_str, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_state_vrf_all,
+ show_ipv6_pim_state_vrf_all_cmd,
+ "show ipv6 pim vrf all state [X:X::X:X$s_or_g [X:X::X:X$g]] [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM state information\n"
+ "Unicast or Multicast address\n"
+ "Multicast address\n"
+ JSON_STR)
+{
+ struct vrf *vrf;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", vrf->name);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_state(vrf->info, vty, s_or_g_str, g_str, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
+ }
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_channel,
+ show_ipv6_pim_channel_cmd,
+ "show ipv6 pim [vrf NAME] channel [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM downstream channel info\n"
+ JSON_STR)
+{
+ struct vrf *v;
+ bool uj = !!json;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim_show_channel(v->info, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_interface,
+ show_ipv6_pim_interface_cmd,
+ "show ipv6 pim [vrf NAME] interface [detail|WORD]$interface [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM interface information\n"
+ "Detailed output\n"
+ "interface name\n"
+ JSON_STR)
+{
+ struct vrf *v;
+ bool uj = !!json;
+ json_object *json_parent = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ if (uj)
+ json_parent = json_object_new_object();
+
+ if (interface)
+ pim_show_interfaces_single(v->info, vty, interface, false,
+ json_parent);
+ else
+ pim_show_interfaces(v->info, vty, false, json_parent);
+
+ if (uj)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_interface_vrf_all,
+ show_ipv6_pim_interface_vrf_all_cmd,
+ "show ipv6 pim vrf all interface [detail|WORD]$interface [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM interface information\n"
+ "Detailed output\n"
+ "interface name\n"
+ JSON_STR)
+{
+ bool uj = !!json;
+ struct vrf *v;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (uj)
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (v, vrf_name_head, &vrfs_by_name) {
+ if (!uj)
+ vty_out(vty, "VRF: %s\n", v->name);
+ else
+ json_vrf = json_object_new_object();
+
+ if (interface)
+ pim_show_interfaces_single(v->info, vty, interface,
+ false, json_vrf);
+ else
+ pim_show_interfaces(v->info, vty, false, json_vrf);
+
+ if (uj)
+ json_object_object_add(json_parent, v->name, json_vrf);
+ }
+ if (uj)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_join,
+ show_ipv6_pim_join_cmd,
+ "show ipv6 pim [vrf NAME] join [X:X::X:X$s_or_g [X:X::X:X$g]] [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM interface join information\n"
+ "The Source or Group\n"
+ "The Group\n"
+ JSON_STR)
+{
+ pim_sgaddr sg = {};
+ struct vrf *v;
+ struct pim_instance *pim;
+ json_object *json_parent = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v) {
+ vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
+ return CMD_WARNING;
+ }
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (!pim_addr_is_any(s_or_g)) {
+ if (!pim_addr_is_any(g)) {
+ sg.src = s_or_g;
+ sg.grp = g;
+ } else
+ sg.grp = s_or_g;
+ }
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_show_join(pim, vty, &sg, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_join_vrf_all,
+ show_ipv6_pim_join_vrf_all_cmd,
+ "show ipv6 pim vrf all join [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM interface join information\n"
+ JSON_STR)
+{
+ pim_sgaddr sg = {0};
+ struct vrf *vrf_struct;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (vrf_struct, vrf_name_head, &vrfs_by_name) {
+ if (!json_parent)
+ vty_out(vty, "VRF: %s\n", vrf_struct->name);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_join(vrf_struct->info, vty, &sg, json_vrf);
+
+ if (json)
+ json_object_object_add(json_parent, vrf_struct->name,
+ json_vrf);
+ }
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_WARNING;
+}
+
+DEFPY (show_ipv6_pim_jp_agg,
+ show_ipv6_pim_jp_agg_cmd,
+ "show ipv6 pim [vrf NAME] jp-agg",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "join prune aggregation list\n")
+{
+ struct vrf *v;
+ struct pim_instance *pim;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v) {
+ vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
+ return CMD_WARNING;
+ }
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ pim_show_jp_agg_list(pim, vty);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_local_membership,
+ show_ipv6_pim_local_membership_cmd,
+ "show ipv6 pim [vrf NAME] local-membership [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM interface local-membership\n"
+ JSON_STR)
+{
+ struct vrf *v;
+ bool uj = !!json;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim_show_membership(v->info, vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_neighbor,
+ show_ipv6_pim_neighbor_cmd,
+ "show ipv6 pim [vrf NAME] neighbor [detail|WORD]$interface [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM neighbor information\n"
+ "Detailed output\n"
+ "Name of interface or neighbor\n"
+ JSON_STR)
+{
+ struct vrf *v;
+ json_object *json_parent = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ if (interface)
+ pim_show_neighbors_single(v->info, vty, interface, json_parent);
+ else
+ pim_show_neighbors(v->info, vty, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_neighbor_vrf_all,
+ show_ipv6_pim_neighbor_vrf_all_cmd,
+ "show ipv6 pim vrf all neighbor [detail|WORD]$interface [json$json]",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM neighbor information\n"
+ "Detailed output\n"
+ "Name of interface or neighbor\n"
+ JSON_STR)
+{
+ struct vrf *v;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
+ RB_FOREACH (v, vrf_name_head, &vrfs_by_name) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", v->name);
+ else
+ json_vrf = json_object_new_object();
+
+ if (interface)
+ pim_show_neighbors_single(v->info, vty, interface,
+ json_vrf);
+ else
+ pim_show_neighbors(v->info, vty, json_vrf);
+
+ if (json)
+ json_object_object_add(json_parent, v->name, json_vrf);
+ }
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_nexthop,
+ show_ipv6_pim_nexthop_cmd,
+ "show ipv6 pim [vrf NAME] nexthop",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM cached nexthop rpf information\n")
+{
+ struct vrf *v;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim_show_nexthop(v->info, vty);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ipv6_pim_nexthop_lookup,
+ show_ipv6_pim_nexthop_lookup_cmd,
+ "show ipv6 pim [vrf NAME] nexthop-lookup X:X::X:X$source X:X::X:X$group",
+ SHOW_STR
+ IPV6_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM cached nexthop rpf lookup\n"
+ "Source/RP address\n"
+ "Multicast Group address\n")
+{
+ struct prefix nht_p;
+ int result = 0;
+ pim_addr vif_source;
+ struct prefix grp;
+ struct pim_nexthop nexthop;
+ char nexthop_addr_str[PIM_ADDRSTRLEN];
+ struct vrf *v;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ if (!pim_rp_set_upstream_addr(v->info, &vif_source, source, group))
+ return CMD_SUCCESS;
+
+ pim_addr_to_prefix(&nht_p, vif_source);
+ pim_addr_to_prefix(&grp, group);
+ memset(&nexthop, 0, sizeof(nexthop));
+
+ result = pim_ecmp_nexthop_lookup(v->info, &nexthop, &nht_p, &grp, 0);
+
+ if (!result) {
+ vty_out(vty,
+ "Nexthop Lookup failed, no usable routes returned.\n");
+ return CMD_SUCCESS;
+ }
+
+ pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
+ nexthop_addr_str, sizeof(nexthop_addr_str));
+ vty_out(vty, "Group %s --- Nexthop %s Interface %s\n", group_str,
+ nexthop_addr_str, nexthop.interface->name);
+
+ return CMD_SUCCESS;
+}
+
void pim_cmd_init(void)
{
if_cmd_init(pim_interface_config_write);
@@ -665,6 +1615,10 @@ void pim_cmd_init(void)
install_element(VRF_NODE, &ipv6_pim_rp_prefix_list_cmd);
install_element(CONFIG_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
install_element(VRF_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
+ install_element(CONFIG_NODE, &ipv6_ssmpingd_cmd);
+ install_element(VRF_NODE, &ipv6_ssmpingd_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_ssmpingd_cmd);
+ install_element(VRF_NODE, &no_ipv6_ssmpingd_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_mld_cmd);
install_element(INTERFACE_NODE, &interface_no_ipv6_mld_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_mld_join_cmd);
@@ -674,4 +1628,44 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_ipv6_mld_query_interval_cmd);
install_element(INTERFACE_NODE,
&interface_no_ipv6_mld_query_interval_cmd);
+ install_element(CONFIG_NODE, &mld_group_watermark_cmd);
+ install_element(VRF_NODE, &mld_group_watermark_cmd);
+ install_element(CONFIG_NODE, &no_mld_group_watermark_cmd);
+ install_element(VRF_NODE, &no_mld_group_watermark_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_ipv6_mld_query_max_response_time_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ipv6_mld_query_max_response_time_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_ipv6_mld_last_member_query_count_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ipv6_mld_last_member_query_count_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_ipv6_mld_last_member_query_interval_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ipv6_mld_last_member_query_interval_cmd);
+
+ install_element(VIEW_NODE, &show_ipv6_pim_rp_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_rp_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_rpf_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_rpf_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_secondary_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_statistics_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_upstream_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_upstream_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_upstream_join_desired_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_upstream_rpf_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_state_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_state_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_channel_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_interface_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_interface_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_join_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_join_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_jp_agg_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_local_membership_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_neighbor_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_neighbor_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_nexthop_cmd);
+ install_element(VIEW_NODE, &show_ipv6_pim_nexthop_lookup_cmd);
}
diff --git a/pimd/pim6_cmd.h b/pimd/pim6_cmd.h
index ac5eb3f9bf..d6853a7410 100644
--- a/pimd/pim6_cmd.h
+++ b/pimd/pim6_cmd.h
@@ -43,6 +43,7 @@
#define DEBUG_MLD_EVENTS_STR "MLD protocol events\n"
#define DEBUG_MLD_PACKETS_STR "MLD protocol packets\n"
#define DEBUG_MLD_TRACE_STR "MLD internal daemon activity\n"
+#define CONF_SSMPINGD_STR "Enable ssmpingd operation\n"
void pim_cmd_init(void);
diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h
index e422a2e2da..eca907da37 100644
--- a/pimd/pim_addr.h
+++ b/pimd/pim_addr.h
@@ -34,6 +34,8 @@ typedef struct in_addr pim_addr;
#define PIM_MAX_BITLEN IPV4_MAX_BITLEN
#define PIM_AF_NAME "ip"
+#define PIM_ADDR_FUNCNAME(name) ipv4_##name
+
union pimprefixptr {
prefixtype(pimprefixptr, struct prefix, p)
prefixtype(pimprefixptr, struct prefix_ipv4, p4)
@@ -53,6 +55,8 @@ typedef struct in6_addr pim_addr;
#define PIM_MAX_BITLEN IPV6_MAX_BITLEN
#define PIM_AF_NAME "ipv6"
+#define PIM_ADDR_FUNCNAME(name) ipv6_##name
+
union pimprefixptr {
prefixtype(pimprefixptr, struct prefix, p)
prefixtype(pimprefixptr, struct prefix_ipv6, p6)
@@ -101,6 +105,21 @@ static inline pim_addr pim_addr_from_prefix(union pimprefixconstptr in)
return ret;
}
+static inline uint8_t pim_addr_scope(const pim_addr addr)
+{
+ return PIM_ADDR_FUNCNAME(mcast_scope)(&addr);
+}
+
+static inline bool pim_addr_nofwd(const pim_addr addr)
+{
+ return PIM_ADDR_FUNCNAME(mcast_nofwd)(&addr);
+}
+
+static inline bool pim_addr_ssm(const pim_addr addr)
+{
+ return PIM_ADDR_FUNCNAME(mcast_ssm)(&addr);
+}
+
/* don't use this struct directly, use the pim_sgaddr typedef */
struct _pim_sgaddr {
pim_addr grp;
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 86d179fe39..706a21322b 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -67,6 +67,7 @@
#include "lib/northbound_cli.h"
#include "pim_errors.h"
#include "pim_nb.h"
+#include "pim_addr.h"
#include "pim_cmd_common.h"
#ifndef VTYSH_EXTRACT_PL
@@ -80,14 +81,6 @@ static struct cmd_node debug_node = {
.config_write = pim_debug_config_write,
};
-static inline bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match)
-{
- return (pim_addr_is_any(match.grp) ||
- !pim_addr_cmp(match.grp, item.grp)) &&
- (pim_addr_is_any(match.src) ||
- !pim_addr_cmp(match.src, item.src));
-}
-
static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
const int argc, int *idx)
{
@@ -300,180 +293,6 @@ static void pim_show_assert_winner_metric(struct pim_instance *pim,
}
}
-static void json_object_pim_ifp_add(struct json_object *json,
- struct interface *ifp)
-{
- struct pim_interface *pim_ifp;
-
- pim_ifp = ifp->info;
- json_object_string_add(json, "name", ifp->name);
- json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
- json_object_string_addf(json, "address", "%pI4",
- &pim_ifp->primary_address);
- json_object_int_add(json, "index", ifp->ifindex);
-
- if (if_is_multicast(ifp))
- json_object_boolean_true_add(json, "flagMulticast");
-
- if (if_is_broadcast(ifp))
- json_object_boolean_true_add(json, "flagBroadcast");
-
- if (ifp->flags & IFF_ALLMULTI)
- json_object_boolean_true_add(json, "flagAllMulticast");
-
- if (ifp->flags & IFF_PROMISC)
- json_object_boolean_true_add(json, "flagPromiscuous");
-
- if (PIM_IF_IS_DELETED(ifp))
- json_object_boolean_true_add(json, "flagDeleted");
-
- if (pim_if_lan_delay_enabled(ifp))
- json_object_boolean_true_add(json, "lanDelayEnabled");
-}
-
-static void pim_show_membership_helper(struct vty *vty,
- struct pim_interface *pim_ifp,
- struct pim_ifchannel *ch,
- struct json_object *json)
-{
- char ch_grp_str[PIM_ADDRSTRLEN];
- json_object *json_iface = NULL;
- json_object *json_row = NULL;
-
- json_object_object_get_ex(json, ch->interface->name, &json_iface);
- if (!json_iface) {
- json_iface = json_object_new_object();
- json_object_pim_ifp_add(json_iface, ch->interface);
- json_object_object_add(json, ch->interface->name, json_iface);
- }
-
- snprintfrr(ch_grp_str, sizeof(ch_grp_str), "%pPAs", &ch->sg.grp);
-
- json_row = json_object_new_object();
- json_object_string_addf(json_row, "source", "%pPAs", &ch->sg.src);
- json_object_string_add(json_row, "group", ch_grp_str);
- json_object_string_add(json_row, "localMembership",
- ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
- ? "NOINFO"
- : "INCLUDE");
- json_object_object_add(json_iface, ch_grp_str, json_row);
-}
-
-static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
- bool uj)
-{
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct interface *ifp;
- enum json_type type;
- json_object *json = NULL;
- json_object *json_tmp = NULL;
-
- json = json_object_new_object();
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
-
- RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
- pim_show_membership_helper(vty, pim_ifp, ch, json);
- } /* scan interface channels */
- }
-
- if (uj) {
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- } else {
- vty_out(vty,
- "Interface Address Source Group Membership\n");
-
- /*
- * Example of the json data we are traversing
- *
- * {
- * "swp3":{
- * "name":"swp3",
- * "state":"up",
- * "address":"10.1.20.1",
- * "index":5,
- * "flagMulticast":true,
- * "flagBroadcast":true,
- * "lanDelayEnabled":true,
- * "226.10.10.10":{
- * "source":"*",
- * "group":"226.10.10.10",
- * "localMembership":"INCLUDE"
- * }
- * }
- * }
- */
-
- /* foreach interface */
- json_object_object_foreach(json, key, val)
- {
-
- /* Find all of the keys where the val is an object. In
- * the example
- * above the only one is 226.10.10.10
- */
- json_object_object_foreach(val, if_field_key,
- if_field_val)
- {
- type = json_object_get_type(if_field_val);
-
- if (type == json_type_object) {
- vty_out(vty, "%-16s ", key);
-
- json_object_object_get_ex(
- val, "address", &json_tmp);
- vty_out(vty, "%-15s ",
- json_object_get_string(
- json_tmp));
-
- json_object_object_get_ex(if_field_val,
- "source",
- &json_tmp);
- vty_out(vty, "%-15s ",
- json_object_get_string(
- json_tmp));
-
- /* Group */
- vty_out(vty, "%-15s ", if_field_key);
-
- json_object_object_get_ex(
- if_field_val, "localMembership",
- &json_tmp);
- vty_out(vty, "%-10s\n",
- json_object_get_string(
- json_tmp));
- }
- }
- }
- }
-
- json_object_free(json);
-}
-
-static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp)
-{
- vty_out(vty, "Flags\n");
- vty_out(vty, "-----\n");
- vty_out(vty, "All Multicast : %s\n",
- (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
- vty_out(vty, "Broadcast : %s\n",
- if_is_broadcast(ifp) ? "yes" : "no");
- vty_out(vty, "Deleted : %s\n",
- PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
- vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
- vty_out(vty, "Multicast : %s\n",
- if_is_multicast(ifp) ? "yes" : "no");
- vty_out(vty, "Promiscuous : %s\n",
- (ifp->flags & IFF_PROMISC) ? "yes" : "no");
- vty_out(vty, "\n");
- vty_out(vty, "\n");
-}
-
static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
bool uj)
{
@@ -874,412 +693,6 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty,
vty_json(vty, json);
}
-static void pim_show_interfaces_single(struct pim_instance *pim,
- struct vty *vty, const char *ifname,
- bool mlag, bool uj)
-{
- struct in_addr ifaddr;
- struct interface *ifp;
- struct listnode *neighnode;
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- struct pim_upstream *up;
- time_t now;
- char dr_str[INET_ADDRSTRLEN];
- char dr_uptime[10];
- char expire[10];
- char grp_str[INET_ADDRSTRLEN];
- char hello_period[10];
- char hello_timer[10];
- char neigh_src_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- char stat_uptime[10];
- char uptime[10];
- int found_ifname = 0;
- int print_header;
- json_object *json = NULL;
- json_object *json_row = NULL;
- json_object *json_pim_neighbor = NULL;
- json_object *json_pim_neighbors = NULL;
- json_object *json_group = NULL;
- json_object *json_group_source = NULL;
- json_object *json_fhr_sources = NULL;
- struct pim_secondary_addr *sec_addr;
- struct listnode *sec_node;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (mlag == true && pim_ifp->activeactive == false)
- continue;
-
- if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
- continue;
-
- found_ifname = 1;
- ifaddr = pim_ifp->primary_address;
- pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
- sizeof(dr_str));
- pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
- pim_ifp->pim_dr_election_last);
- pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
- pim_ifp->t_pim_hello_timer);
- pim_time_mmss(hello_period, sizeof(hello_period),
- pim_ifp->pim_hello_period);
- pim_time_uptime(stat_uptime, sizeof(stat_uptime),
- now - pim_ifp->pim_ifstat_start);
-
- if (uj) {
- char pbuf[PREFIX2STR_BUFFER];
- json_row = json_object_new_object();
- json_object_pim_ifp_add(json_row, ifp);
-
- if (pim_ifp->update_source.s_addr != INADDR_ANY) {
- json_object_string_addf(
- json_row, "useSource", "%pI4",
- &pim_ifp->update_source);
- }
- if (pim_ifp->sec_addr_list) {
- json_object *sec_list = NULL;
-
- sec_list = json_object_new_array();
- for (ALL_LIST_ELEMENTS_RO(
- pim_ifp->sec_addr_list, sec_node,
- sec_addr)) {
- json_object_array_add(
- sec_list,
- json_object_new_string(
- prefix2str(
- &sec_addr->addr,
- pbuf,
- sizeof(pbuf))));
- }
- json_object_object_add(json_row,
- "secondaryAddressList",
- sec_list);
- }
-
- // PIM neighbors
- if (pim_ifp->pim_neighbor_list->count) {
- json_pim_neighbors = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO(
- pim_ifp->pim_neighbor_list,
- neighnode, neigh)) {
- json_pim_neighbor =
- json_object_new_object();
- pim_inet4_dump("<src?>",
- neigh->source_addr,
- neigh_src_str,
- sizeof(neigh_src_str));
- pim_time_uptime(uptime, sizeof(uptime),
- now - neigh->creation);
- pim_time_timer_to_hhmmss(
- expire, sizeof(expire),
- neigh->t_expire_timer);
-
- json_object_string_add(
- json_pim_neighbor, "address",
- neigh_src_str);
- json_object_string_add(
- json_pim_neighbor, "upTime",
- uptime);
- json_object_string_add(
- json_pim_neighbor, "holdtime",
- expire);
-
- json_object_object_add(
- json_pim_neighbors,
- neigh_src_str,
- json_pim_neighbor);
- }
-
- json_object_object_add(json_row, "neighbors",
- json_pim_neighbors);
- }
-
- json_object_string_add(json_row, "drAddress", dr_str);
- json_object_int_add(json_row, "drPriority",
- pim_ifp->pim_dr_priority);
- json_object_string_add(json_row, "drUptime", dr_uptime);
- json_object_int_add(json_row, "drElections",
- pim_ifp->pim_dr_election_count);
- json_object_int_add(json_row, "drChanges",
- pim_ifp->pim_dr_election_changes);
-
- // FHR
- frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- if (ifp != up->rpf.source_nexthop.interface)
- continue;
-
- if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
- continue;
-
- if (!json_fhr_sources)
- json_fhr_sources =
- json_object_new_object();
-
- snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
- &up->sg.grp);
- snprintfrr(src_str, sizeof(src_str), "%pPAs",
- &up->sg.src);
- pim_time_uptime(uptime, sizeof(uptime),
- now - up->state_transition);
-
- /*
- * Does this group live in json_fhr_sources?
- * If not create it.
- */
- json_object_object_get_ex(json_fhr_sources,
- grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json_fhr_sources,
- grp_str,
- json_group);
- }
-
- json_group_source = json_object_new_object();
- json_object_string_add(json_group_source,
- "source", src_str);
- json_object_string_add(json_group_source,
- "group", grp_str);
- json_object_string_add(json_group_source,
- "upTime", uptime);
- json_object_object_add(json_group, src_str,
- json_group_source);
- }
-
- if (json_fhr_sources) {
- json_object_object_add(json_row,
- "firstHopRouter",
- json_fhr_sources);
- }
-
- json_object_int_add(json_row, "helloPeriod",
- pim_ifp->pim_hello_period);
- json_object_int_add(json_row, "holdTime",
- PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
- json_object_string_add(json_row, "helloTimer",
- hello_timer);
- json_object_string_add(json_row, "helloStatStart",
- stat_uptime);
- json_object_int_add(json_row, "helloReceived",
- pim_ifp->pim_ifstat_hello_recv);
- json_object_int_add(json_row, "helloReceivedFailed",
- pim_ifp->pim_ifstat_hello_recvfail);
- json_object_int_add(json_row, "helloSend",
- pim_ifp->pim_ifstat_hello_sent);
- json_object_int_add(json_row, "hellosendFailed",
- pim_ifp->pim_ifstat_hello_sendfail);
- json_object_int_add(json_row, "helloGenerationId",
- pim_ifp->pim_generation_id);
-
- json_object_int_add(
- json_row, "effectivePropagationDelay",
- pim_if_effective_propagation_delay_msec(ifp));
- json_object_int_add(
- json_row, "effectiveOverrideInterval",
- pim_if_effective_override_interval_msec(ifp));
- json_object_int_add(
- json_row, "joinPruneOverrideInterval",
- pim_if_jp_override_interval_msec(ifp));
-
- json_object_int_add(
- json_row, "propagationDelay",
- pim_ifp->pim_propagation_delay_msec);
- json_object_int_add(
- json_row, "propagationDelayHighest",
- pim_ifp->pim_neighbors_highest_propagation_delay_msec);
- json_object_int_add(
- json_row, "overrideInterval",
- pim_ifp->pim_override_interval_msec);
- json_object_int_add(
- json_row, "overrideIntervalHighest",
- pim_ifp->pim_neighbors_highest_override_interval_msec);
- if (pim_ifp->bsm_enable)
- json_object_boolean_true_add(json_row,
- "bsmEnabled");
- if (pim_ifp->ucast_bsm_accept)
- json_object_boolean_true_add(json_row,
- "ucastBsmEnabled");
- json_object_object_add(json, ifp->name, json_row);
-
- } else {
- vty_out(vty, "Interface : %s\n", ifp->name);
- vty_out(vty, "State : %s\n",
- if_is_up(ifp) ? "up" : "down");
- if (pim_ifp->update_source.s_addr != INADDR_ANY) {
- vty_out(vty, "Use Source : %pI4\n",
- &pim_ifp->update_source);
- }
- if (pim_ifp->sec_addr_list) {
- vty_out(vty, "Address : %pI4 (primary)\n",
- &ifaddr);
- for (ALL_LIST_ELEMENTS_RO(
- pim_ifp->sec_addr_list, sec_node,
- sec_addr))
- vty_out(vty, " %pFX\n",
- &sec_addr->addr);
- } else {
- vty_out(vty, "Address : %pI4\n",
- &ifaddr);
- }
- vty_out(vty, "\n");
-
- // PIM neighbors
- print_header = 1;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
- neighnode, neigh)) {
-
- if (print_header) {
- vty_out(vty, "PIM Neighbors\n");
- vty_out(vty, "-------------\n");
- print_header = 0;
- }
-
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str,
- sizeof(neigh_src_str));
- pim_time_uptime(uptime, sizeof(uptime),
- now - neigh->creation);
- pim_time_timer_to_hhmmss(expire, sizeof(expire),
- neigh->t_expire_timer);
- vty_out(vty,
- "%-15s : up for %s, holdtime expires in %s\n",
- neigh_src_str, uptime, expire);
- }
-
- if (!print_header) {
- vty_out(vty, "\n");
- vty_out(vty, "\n");
- }
-
- vty_out(vty, "Designated Router\n");
- vty_out(vty, "-----------------\n");
- vty_out(vty, "Address : %s\n", dr_str);
- vty_out(vty, "Priority : %u(%d)\n",
- pim_ifp->pim_dr_priority,
- pim_ifp->pim_dr_num_nondrpri_neighbors);
- vty_out(vty, "Uptime : %s\n", dr_uptime);
- vty_out(vty, "Elections : %d\n",
- pim_ifp->pim_dr_election_count);
- vty_out(vty, "Changes : %d\n",
- pim_ifp->pim_dr_election_changes);
- vty_out(vty, "\n");
- vty_out(vty, "\n");
-
- // FHR
- print_header = 1;
- frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- if (!up->rpf.source_nexthop.interface)
- continue;
-
- if (strcmp(ifp->name,
- up->rpf.source_nexthop
- .interface->name)
- != 0)
- continue;
-
- if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
- continue;
-
- if (print_header) {
- vty_out(vty,
- "FHR - First Hop Router\n");
- vty_out(vty,
- "----------------------\n");
- print_header = 0;
- }
-
- pim_time_uptime(uptime, sizeof(uptime),
- now - up->state_transition);
- vty_out(vty,
- "%pPAs : %pPAs is a source, uptime is %s\n",
- &up->sg.grp, &up->sg.src, uptime);
- }
-
- if (!print_header) {
- vty_out(vty, "\n");
- vty_out(vty, "\n");
- }
-
- vty_out(vty, "Hellos\n");
- vty_out(vty, "------\n");
- vty_out(vty, "Period : %d\n",
- pim_ifp->pim_hello_period);
- vty_out(vty, "HoldTime : %d\n",
- PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
- vty_out(vty, "Timer : %s\n", hello_timer);
- vty_out(vty, "StatStart : %s\n", stat_uptime);
- vty_out(vty, "Receive : %d\n",
- pim_ifp->pim_ifstat_hello_recv);
- vty_out(vty, "Receive Failed : %d\n",
- pim_ifp->pim_ifstat_hello_recvfail);
- vty_out(vty, "Send : %d\n",
- pim_ifp->pim_ifstat_hello_sent);
- vty_out(vty, "Send Failed : %d\n",
- pim_ifp->pim_ifstat_hello_sendfail);
- vty_out(vty, "Generation ID : %08x\n",
- pim_ifp->pim_generation_id);
- vty_out(vty, "\n");
- vty_out(vty, "\n");
-
- pim_print_ifp_flags(vty, ifp);
-
- vty_out(vty, "Join Prune Interval\n");
- vty_out(vty, "-------------------\n");
- vty_out(vty, "LAN Delay : %s\n",
- pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
- vty_out(vty, "Effective Propagation Delay : %d msec\n",
- pim_if_effective_propagation_delay_msec(ifp));
- vty_out(vty, "Effective Override Interval : %d msec\n",
- pim_if_effective_override_interval_msec(ifp));
- vty_out(vty, "Join Prune Override Interval : %d msec\n",
- pim_if_jp_override_interval_msec(ifp));
- vty_out(vty, "\n");
- vty_out(vty, "\n");
-
- vty_out(vty, "LAN Prune Delay\n");
- vty_out(vty, "---------------\n");
- vty_out(vty, "Propagation Delay : %d msec\n",
- pim_ifp->pim_propagation_delay_msec);
- vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
- pim_ifp->pim_neighbors_highest_propagation_delay_msec);
- vty_out(vty, "Override Interval : %d msec\n",
- pim_ifp->pim_override_interval_msec);
- vty_out(vty, "Override Interval (Highest) : %d msec\n",
- pim_ifp->pim_neighbors_highest_override_interval_msec);
- vty_out(vty, "\n");
- vty_out(vty, "\n");
-
- vty_out(vty, "BSM Status\n");
- vty_out(vty, "----------\n");
- vty_out(vty, "Bsm Enabled : %s\n",
- pim_ifp->bsm_enable ? "yes" : "no");
- vty_out(vty, "Unicast Bsm Enabled : %s\n",
- pim_ifp->ucast_bsm_accept ? "yes" : "no");
- vty_out(vty, "\n");
- vty_out(vty, "\n");
- }
- }
-
- if (uj)
- vty_json(vty, json);
- else if (!found_ifname)
- vty_out(vty, "%% No such interface\n");
-}
-
static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
const char *ifname, bool uj)
{
@@ -1424,101 +837,6 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
}
}
-static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
- bool mlag, bool uj)
-{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct pim_upstream *up;
- int fhr = 0;
- int pim_nbrs = 0;
- int pim_ifchannels = 0;
- json_object *json = NULL;
- json_object *json_row = NULL;
- json_object *json_tmp;
-
- json = json_object_new_object();
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (mlag == true && pim_ifp->activeactive == false)
- continue;
-
- pim_nbrs = pim_ifp->pim_neighbor_list->count;
- pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
- fhr = 0;
-
- frr_each (rb_pim_upstream, &pim->upstream_head, up)
- if (ifp == up->rpf.source_nexthop.interface)
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
- fhr++;
-
- json_row = json_object_new_object();
- json_object_pim_ifp_add(json_row, ifp);
- json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
- json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
- json_object_int_add(json_row, "firstHopRouterCount", fhr);
- json_object_string_addf(json_row, "pimDesignatedRouter", "%pI4",
- &pim_ifp->pim_dr_addr);
-
- if (pim_ifp->pim_dr_addr.s_addr
- == pim_ifp->primary_address.s_addr)
- json_object_boolean_true_add(
- json_row, "pimDesignatedRouterLocal");
-
- json_object_object_add(json, ifp->name, json_row);
- }
-
- if (uj) {
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- } else {
- vty_out(vty,
- "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
-
- json_object_object_foreach(json, key, val)
- {
- vty_out(vty, "%-16s ", key);
-
- json_object_object_get_ex(val, "state", &json_tmp);
- vty_out(vty, "%5s ", json_object_get_string(json_tmp));
-
- json_object_object_get_ex(val, "address", &json_tmp);
- vty_out(vty, "%15s ",
- json_object_get_string(json_tmp));
-
- json_object_object_get_ex(val, "pimNeighbors",
- &json_tmp);
- vty_out(vty, "%8d ", json_object_get_int(json_tmp));
-
- if (json_object_object_get_ex(
- val, "pimDesignatedRouterLocal",
- &json_tmp)) {
- vty_out(vty, "%15s ", "local");
- } else {
- json_object_object_get_ex(
- val, "pimDesignatedRouter", &json_tmp);
- vty_out(vty, "%15s ",
- json_object_get_string(json_tmp));
- }
-
- json_object_object_get_ex(val, "firstHopRouter",
- &json_tmp);
- vty_out(vty, "%3d ", json_object_get_int(json_tmp));
-
- json_object_object_get_ex(val, "pimIfChannels",
- &json_tmp);
- vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
- }
- }
-
- json_object_free(json);
-}
-
static void pim_show_interface_traffic(struct pim_instance *pim,
struct vty *vty, bool uj)
{
@@ -1702,1200 +1020,6 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim,
vty_out(vty, "%% No such interface\n");
}
-static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
- struct pim_ifchannel *ch, json_object *json,
- time_t now, bool uj)
-{
- json_object *json_iface = NULL;
- json_object *json_row = NULL;
- json_object *json_grp = NULL;
- struct in_addr ifaddr;
- char uptime[10];
- char expire[10];
- char prune[10];
- char buf[PREFIX_STRLEN];
-
- ifaddr = pim_ifp->primary_address;
-
- pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
- pim_time_timer_to_mmss(expire, sizeof(expire),
- ch->t_ifjoin_expiry_timer);
- pim_time_timer_to_mmss(prune, sizeof(prune),
- ch->t_ifjoin_prune_pending_timer);
-
- if (uj) {
- char ch_grp_str[PIM_ADDRSTRLEN];
- char ch_src_str[PIM_ADDRSTRLEN];
-
- snprintfrr(ch_grp_str, sizeof(ch_grp_str), "%pPAs",
- &ch->sg.grp);
- snprintfrr(ch_src_str, sizeof(ch_src_str), "%pPAs",
- &ch->sg.src);
-
- json_object_object_get_ex(json, ch->interface->name,
- &json_iface);
-
- if (!json_iface) {
- json_iface = json_object_new_object();
- json_object_pim_ifp_add(json_iface, ch->interface);
- json_object_object_add(json, ch->interface->name,
- json_iface);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", ch_src_str);
- json_object_string_add(json_row, "group", ch_grp_str);
- json_object_string_add(json_row, "upTime", uptime);
- json_object_string_add(json_row, "expire", expire);
- json_object_string_add(json_row, "prune", prune);
- json_object_string_add(
- json_row, "channelJoinName",
- pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
- if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) {
-#if CONFDATE > 20230131
-CPP_NOTICE("Remove JSON object commands with keys starting with capital")
-#endif
- json_object_int_add(json_row, "SGRpt", 1);
- json_object_int_add(json_row, "sgRpt", 1);
- }
- if (PIM_IF_FLAG_TEST_PROTO_PIM(ch->flags))
- json_object_int_add(json_row, "protocolPim", 1);
- if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch->flags))
- json_object_int_add(json_row, "protocolIgmp", 1);
- json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
- if (!json_grp) {
- json_grp = json_object_new_object();
- json_object_object_add(json_grp, ch_src_str, json_row);
- json_object_object_add(json_iface, ch_grp_str,
- json_grp);
- } else
- json_object_object_add(json_grp, ch_src_str, json_row);
- } else {
- vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-10s %8s %-6s %5s\n",
- ch->interface->name,
- inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
- &ch->sg.src, &ch->sg.grp,
- pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
- uptime, expire, prune);
- }
-}
-
-static void pim_show_join(struct pim_instance *pim, struct vty *vty,
- pim_sgaddr *sg, bool uj)
-{
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct interface *ifp;
- time_t now;
- json_object *json = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out(vty,
- "Interface Address Source Group State Uptime Expire Prune\n");
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
-
- RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
- if (!pim_sgaddr_match(ch->sg, *sg))
- continue;
- pim_show_join_helper(vty, pim_ifp, ch, json, now, uj);
- } /* scan interface channels */
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
-static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
- const char *neighbor, bool uj)
-{
- struct listnode *neighnode;
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- time_t now;
- int found_neighbor = 0;
- int option_address_list;
- int option_dr_priority;
- int option_generation_id;
- int option_holdtime;
- int option_lan_prune_delay;
- int option_t_bit;
- char uptime[10];
- char expire[10];
- char neigh_src_str[INET_ADDRSTRLEN];
-
- json_object *json = NULL;
- json_object *json_ifp = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
- neigh)) {
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str, sizeof(neigh_src_str));
-
- /*
- * The user can specify either the interface name or the
- * PIM neighbor IP.
- * If this pim_ifp matches neither then skip.
- */
- if (strcmp(neighbor, "detail")
- && strcmp(neighbor, ifp->name)
- && strcmp(neighbor, neigh_src_str))
- continue;
-
- found_neighbor = 1;
- pim_time_uptime(uptime, sizeof(uptime),
- now - neigh->creation);
- pim_time_timer_to_hhmmss(expire, sizeof(expire),
- neigh->t_expire_timer);
-
- option_address_list = 0;
- option_dr_priority = 0;
- option_generation_id = 0;
- option_holdtime = 0;
- option_lan_prune_delay = 0;
- option_t_bit = 0;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_ADDRESS_LIST))
- option_address_list = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_DR_PRIORITY))
- option_dr_priority = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_GENERATION_ID))
- option_generation_id = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_HOLDTIME))
- option_holdtime = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_LAN_PRUNE_DELAY))
- option_lan_prune_delay = 1;
-
- if (PIM_OPTION_IS_SET(
- neigh->hello_options,
- PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
- option_t_bit = 1;
-
- if (uj) {
-
- /* Does this ifp live in json? If not create
- * it. */
- json_object_object_get_ex(json, ifp->name,
- &json_ifp);
-
- if (!json_ifp) {
- json_ifp = json_object_new_object();
- json_object_pim_ifp_add(json_ifp, ifp);
- json_object_object_add(json, ifp->name,
- json_ifp);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "interface",
- ifp->name);
- json_object_string_add(json_row, "address",
- neigh_src_str);
- json_object_string_add(json_row, "upTime",
- uptime);
- json_object_string_add(json_row, "holdtime",
- expire);
- json_object_int_add(json_row, "drPriority",
- neigh->dr_priority);
- json_object_int_add(json_row, "generationId",
- neigh->generation_id);
-
- if (option_address_list)
- json_object_boolean_true_add(
- json_row,
- "helloOptionAddressList");
-
- if (option_dr_priority)
- json_object_boolean_true_add(
- json_row,
- "helloOptionDrPriority");
-
- if (option_generation_id)
- json_object_boolean_true_add(
- json_row,
- "helloOptionGenerationId");
-
- if (option_holdtime)
- json_object_boolean_true_add(
- json_row,
- "helloOptionHoldtime");
-
- if (option_lan_prune_delay)
- json_object_boolean_true_add(
- json_row,
- "helloOptionLanPruneDelay");
-
- if (option_t_bit)
- json_object_boolean_true_add(
- json_row, "helloOptionTBit");
-
- json_object_object_add(json_ifp, neigh_src_str,
- json_row);
-
- } else {
- vty_out(vty, "Interface : %s\n", ifp->name);
- vty_out(vty, "Neighbor : %s\n", neigh_src_str);
- vty_out(vty,
- " Uptime : %s\n",
- uptime);
- vty_out(vty,
- " Holdtime : %s\n",
- expire);
- vty_out(vty,
- " DR Priority : %d\n",
- neigh->dr_priority);
- vty_out(vty,
- " Generation ID : %08x\n",
- neigh->generation_id);
- vty_out(vty,
- " Override Interval (msec) : %d\n",
- neigh->override_interval_msec);
- vty_out(vty,
- " Propagation Delay (msec) : %d\n",
- neigh->propagation_delay_msec);
- vty_out(vty,
- " Hello Option - Address List : %s\n",
- option_address_list ? "yes" : "no");
- vty_out(vty,
- " Hello Option - DR Priority : %s\n",
- option_dr_priority ? "yes" : "no");
- vty_out(vty,
- " Hello Option - Generation ID : %s\n",
- option_generation_id ? "yes" : "no");
- vty_out(vty,
- " Hello Option - Holdtime : %s\n",
- option_holdtime ? "yes" : "no");
- vty_out(vty,
- " Hello Option - LAN Prune Delay : %s\n",
- option_lan_prune_delay ? "yes" : "no");
- vty_out(vty,
- " Hello Option - T-bit : %s\n",
- option_t_bit ? "yes" : "no");
- bfd_sess_show(vty, json_ifp,
- neigh->bfd_session);
- vty_out(vty, "\n");
- }
- }
- }
-
- if (uj)
- vty_json(vty, json);
- else if (!found_neighbor)
- vty_out(vty, "%% No such interface or neighbor\n");
-}
-
-static void pim_show_state(struct pim_instance *pim, struct vty *vty,
- const char *src_or_group, const char *group, bool uj)
-{
- struct channel_oil *c_oil;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_ifp_in = NULL;
- json_object *json_ifp_out = NULL;
- json_object *json_source = NULL;
- time_t now;
- int first_oif;
- now = pim_time_monotonic_sec();
-
- if (uj) {
- json = json_object_new_object();
- } else {
- vty_out(vty,
- "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
- vty_out(vty,
- "\nActive Source Group RPT IIF OIL\n");
- }
-
- frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
- char grp_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- char in_ifname[INTERFACE_NAMSIZ + 1];
- char out_ifname[INTERFACE_NAMSIZ + 1];
- int oif_vif_index;
- struct interface *ifp_in;
- bool isRpt;
- first_oif = 1;
-
- if ((c_oil->up &&
- PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil->up->flags)) ||
- c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
- isRpt = true;
- else
- isRpt = false;
-
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
- sizeof(grp_str));
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
- sizeof(src_str));
- ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
-
- if (ifp_in)
- strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
- else
- strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
-
- if (src_or_group) {
- if (strcmp(src_or_group, src_str)
- && strcmp(src_or_group, grp_str))
- continue;
-
- if (group && strcmp(group, grp_str))
- continue;
- }
-
- if (uj) {
-
- /* Find the group, create it if it doesn't exist */
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str,
- json_group);
- }
-
- /* Find the source nested under the group, create it if
- * it doesn't exist */
- json_object_object_get_ex(json_group, src_str,
- &json_source);
-
- if (!json_source) {
- json_source = json_object_new_object();
- json_object_object_add(json_group, src_str,
- json_source);
- }
-
- /* Find the inbound interface nested under the source,
- * create it if it doesn't exist */
- json_object_object_get_ex(json_source, in_ifname,
- &json_ifp_in);
-
- if (!json_ifp_in) {
- json_ifp_in = json_object_new_object();
- json_object_object_add(json_source, in_ifname,
- json_ifp_in);
- json_object_int_add(json_source, "Installed",
- c_oil->installed);
- json_object_int_add(json_source, "installed",
- c_oil->installed);
- if (isRpt)
- json_object_boolean_true_add(
- json_source, "isRpt");
- else
- json_object_boolean_false_add(
- json_source, "isRpt");
- json_object_int_add(json_source, "RefCount",
- c_oil->oil_ref_count);
- json_object_int_add(json_source, "refCount",
- c_oil->oil_ref_count);
- json_object_int_add(json_source, "OilListSize",
- c_oil->oil_size);
- json_object_int_add(json_source, "oilListSize",
- c_oil->oil_size);
- json_object_int_add(
- json_source, "OilRescan",
- c_oil->oil_inherited_rescan);
- json_object_int_add(
- json_source, "oilRescan",
- c_oil->oil_inherited_rescan);
- json_object_int_add(json_source, "LastUsed",
- c_oil->cc.lastused);
- json_object_int_add(json_source, "lastUsed",
- c_oil->cc.lastused);
- json_object_int_add(json_source, "PacketCount",
- c_oil->cc.pktcnt);
- json_object_int_add(json_source, "packetCount",
- c_oil->cc.pktcnt);
- json_object_int_add(json_source, "ByteCount",
- c_oil->cc.bytecnt);
- json_object_int_add(json_source, "byteCount",
- c_oil->cc.bytecnt);
- json_object_int_add(json_source,
- "WrongInterface",
- c_oil->cc.wrong_if);
- json_object_int_add(json_source,
- "wrongInterface",
- c_oil->cc.wrong_if);
- }
- } else {
- vty_out(vty, "%-6d %-15s %-15s %-3s %-16s ",
- c_oil->installed, src_str, grp_str,
- isRpt ? "y" : "n", in_ifname);
- }
-
- for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
- ++oif_vif_index) {
- struct interface *ifp_out;
- char oif_uptime[10];
- int ttl;
-
- ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
- if (ttl < 1)
- continue;
-
- ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
- pim_time_uptime(
- oif_uptime, sizeof(oif_uptime),
- now - c_oil->oif_creation[oif_vif_index]);
-
- if (ifp_out)
- strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
- else
- strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
-
- if (uj) {
- json_ifp_out = json_object_new_object();
- json_object_string_add(json_ifp_out, "source",
- src_str);
- json_object_string_add(json_ifp_out, "group",
- grp_str);
- json_object_string_add(json_ifp_out,
- "inboundInterface",
- in_ifname);
- json_object_string_add(json_ifp_out,
- "outboundInterface",
- out_ifname);
- json_object_int_add(json_ifp_out, "installed",
- c_oil->installed);
-
- json_object_object_add(json_ifp_in, out_ifname,
- json_ifp_out);
- } else {
- if (first_oif) {
- first_oif = 0;
- vty_out(vty, "%s(%c%c%c%c%c)",
- out_ifname,
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_IGMP)
- ? 'I'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_PIM)
- ? 'J'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_VXLAN)
- ? 'V'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_STAR)
- ? '*'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_MUTE)
- ? 'M'
- : ' ');
- } else
- vty_out(vty, ", %s(%c%c%c%c%c)",
- out_ifname,
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_IGMP)
- ? 'I'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_PIM)
- ? 'J'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_VXLAN)
- ? 'V'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_PROTO_STAR)
- ? '*'
- : ' ',
- (c_oil->oif_flags[oif_vif_index]
- & PIM_OIF_FLAG_MUTE)
- ? 'M'
- : ' ');
- }
- }
-
- if (!uj)
- vty_out(vty, "\n");
- }
-
-
- if (uj)
- vty_json(vty, json);
- else
- vty_out(vty, "\n");
-}
-
-static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
- bool uj)
-{
- struct listnode *neighnode;
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- time_t now;
- char uptime[10];
- char expire[10];
- char neigh_src_str[INET_ADDRSTRLEN];
- json_object *json = NULL;
- json_object *json_ifp_rows = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj) {
- json = json_object_new_object();
- } else {
- vty_out(vty,
- "Interface Neighbor Uptime Holdtime DR Pri\n");
- }
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- if (uj)
- json_ifp_rows = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
- neigh)) {
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str, sizeof(neigh_src_str));
- pim_time_uptime(uptime, sizeof(uptime),
- now - neigh->creation);
- pim_time_timer_to_hhmmss(expire, sizeof(expire),
- neigh->t_expire_timer);
-
- if (uj) {
- json_row = json_object_new_object();
- json_object_string_add(json_row, "interface",
- ifp->name);
- json_object_string_add(json_row, "neighbor",
- neigh_src_str);
- json_object_string_add(json_row, "upTime",
- uptime);
- json_object_string_add(json_row, "holdTime",
- expire);
- json_object_int_add(json_row, "holdTimeMax",
- neigh->holdtime);
- json_object_int_add(json_row, "drPriority",
- neigh->dr_priority);
- json_object_object_add(json_ifp_rows,
- neigh_src_str, json_row);
-
- } else {
- vty_out(vty, "%-16s %15s %8s %8s %6d\n",
- ifp->name, neigh_src_str, uptime,
- expire, neigh->dr_priority);
- }
- }
-
- if (uj) {
- json_object_object_add(json, ifp->name, json_ifp_rows);
- json_ifp_rows = NULL;
- }
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
-static void pim_show_neighbors_secondary(struct pim_instance *pim,
- struct vty *vty)
-{
- struct interface *ifp;
-
- vty_out(vty,
- "Interface Address Neighbor Secondary \n");
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *neighnode;
- struct pim_neighbor *neigh;
- char buf[PREFIX_STRLEN];
-
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- ifaddr = pim_ifp->primary_address;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
- neigh)) {
- char neigh_src_str[INET_ADDRSTRLEN];
- struct listnode *prefix_node;
- struct prefix *p;
-
- if (!neigh->prefix_list)
- continue;
-
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str, sizeof(neigh_src_str));
-
- for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
- prefix_node, p))
- vty_out(vty, "%-16s %-15s %-15s %-15pFX\n",
- ifp->name,
- inet_ntop(AF_INET, &ifaddr,
- buf, sizeof(buf)),
- neigh_src_str, p);
- }
- }
-}
-
-static void json_object_pim_upstream_add(json_object *json,
- struct pim_upstream *up)
-{
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
- json_object_boolean_true_add(json, "drJoinDesired");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
- json_object_boolean_true_add(json, "drJoinDesiredUpdated");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
- json_object_boolean_true_add(json, "firstHopRouter");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
- json_object_boolean_true_add(json, "sourceIgmp");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
- json_object_boolean_true_add(json, "sourcePim");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
- json_object_boolean_true_add(json, "sourceStream");
-
- /* XXX: need to print ths flag in the plain text display as well */
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
- json_object_boolean_true_add(json, "sourceMsdp");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
- json_object_boolean_true_add(json, "sendSGRptPrune");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
- json_object_boolean_true_add(json, "lastHopRouter");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY)
- json_object_boolean_true_add(json, "disableKATExpiry");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_STATIC_IIF)
- json_object_boolean_true_add(json, "staticIncomingInterface");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL)
- json_object_boolean_true_add(json,
- "allowIncomingInterfaceinOil");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA)
- json_object_boolean_true_add(json, "noPimRegistrationData");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG)
- json_object_boolean_true_add(json, "forcePimRegistration");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG)
- json_object_boolean_true_add(json, "sourceVxlanOrigination");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
- json_object_boolean_true_add(json, "sourceVxlanTermination");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
- json_object_boolean_true_add(json, "mlagVxlan");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
- json_object_boolean_true_add(json,
- "mlagNonDesignatedForwarder");
-}
-
-static const char *
-pim_upstream_state2brief_str(enum pim_upstream_state join_state,
- char *state_str, size_t state_str_len)
-{
- switch (join_state) {
- case PIM_UPSTREAM_NOTJOINED:
- strlcpy(state_str, "NotJ", state_str_len);
- break;
- case PIM_UPSTREAM_JOINED:
- strlcpy(state_str, "J", state_str_len);
- break;
- default:
- strlcpy(state_str, "Unk", state_str_len);
- }
- return state_str;
-}
-
-static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
- char *state_str, size_t state_str_len)
-{
- switch (reg_state) {
- case PIM_REG_NOINFO:
- strlcpy(state_str, "RegNI", state_str_len);
- break;
- case PIM_REG_JOIN:
- strlcpy(state_str, "RegJ", state_str_len);
- break;
- case PIM_REG_JOIN_PENDING:
- case PIM_REG_PRUNE:
- strlcpy(state_str, "RegP", state_str_len);
- break;
- }
- return state_str;
-}
-
-static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
- pim_sgaddr *sg, bool uj)
-{
- struct pim_upstream *up;
- time_t now;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out(vty,
- "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
-
- frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- char uptime[10];
- char join_timer[10];
- char rs_timer[10];
- char ka_timer[10];
- char msdp_reg_timer[10];
- char state_str[PIM_REG_STATE_STR_LEN];
-
- if (!pim_sgaddr_match(up->sg, *sg))
- continue;
-
- pim_time_uptime(uptime, sizeof(uptime),
- now - up->state_transition);
- pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
- up->t_join_timer);
-
- /*
- * If the upstream is not dummy and it has a J/P timer for the
- * neighbor display that
- */
- if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
- struct pim_neighbor *nbr;
-
- nbr = pim_neighbor_find_prefix(
- up->rpf.source_nexthop.interface,
- &up->rpf.rpf_addr);
- if (nbr)
- pim_time_timer_to_hhmmss(join_timer,
- sizeof(join_timer),
- nbr->jp_timer);
- }
-
- pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
- up->t_rs_timer);
- pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
- up->t_ka_timer);
- pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
- up->t_msdp_reg_timer);
-
- pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str));
- if (up->reg_state != PIM_REG_NOINFO) {
- char tmp_str[PIM_REG_STATE_STR_LEN];
- char tmp[sizeof(state_str) + 1];
-
- snprintf(tmp, sizeof(tmp), ",%s",
- pim_reg_state2brief_str(up->reg_state, tmp_str,
- sizeof(tmp_str)));
- strlcat(state_str, tmp, sizeof(state_str));
- }
-
- if (uj) {
- char grp_str[PIM_ADDRSTRLEN];
- char src_str[PIM_ADDRSTRLEN];
-
- snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
- &up->sg.grp);
- snprintfrr(src_str, sizeof(src_str), "%pPAs",
- &up->sg.src);
-
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str,
- json_group);
- }
-
- json_row = json_object_new_object();
- json_object_pim_upstream_add(json_row, up);
- json_object_string_add(
- json_row, "inboundInterface",
- up->rpf.source_nexthop.interface
- ? up->rpf.source_nexthop.interface->name
- : "Unknown");
-
- /*
- * The RPF address we use is slightly different
- * based upon what we are looking up.
- * If we have a S, list that unless
- * we are the FHR, else we just put
- * the RP as the rpfAddress
- */
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR ||
- pim_addr_is_any(up->sg.src)) {
- char rpf[PREFIX_STRLEN];
- struct pim_rpf *rpg;
-
- rpg = RP(pim, up->sg.grp);
- pim_inet4_dump("<rpf?>",
- rpg->rpf_addr.u.prefix4, rpf,
- sizeof(rpf));
- json_object_string_add(json_row, "rpfAddress",
- rpf);
- } else {
- json_object_string_add(json_row, "rpfAddress",
- src_str);
- }
-
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "state", state_str);
- json_object_string_add(
- json_row, "joinState",
- pim_upstream_state2str(up->join_state));
- json_object_string_add(
- json_row, "regState",
- pim_reg_state2str(up->reg_state, state_str, sizeof(state_str)));
- json_object_string_add(json_row, "upTime", uptime);
- json_object_string_add(json_row, "joinTimer",
- join_timer);
- json_object_string_add(json_row, "resetTimer",
- rs_timer);
- json_object_string_add(json_row, "keepaliveTimer",
- ka_timer);
- json_object_string_add(json_row, "msdpRegTimer",
- msdp_reg_timer);
- json_object_int_add(json_row, "refCount",
- up->ref_count);
- json_object_int_add(json_row, "sptBit", up->sptbit);
- json_object_object_add(json_group, src_str, json_row);
- } else {
- vty_out(vty,
- "%-16s%-15pPAs %-15pPAs %-11s %-8s %-9s %-9s %-9s %6d\n",
- up->rpf.source_nexthop.interface
- ? up->rpf.source_nexthop.interface->name
- : "Unknown",
- &up->sg.src, &up->sg.grp, state_str, uptime,
- join_timer, rs_timer, ka_timer, up->ref_count);
- }
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
-static void pim_show_channel_helper(struct pim_instance *pim,
- struct vty *vty,
- struct pim_interface *pim_ifp,
- struct pim_ifchannel *ch,
- json_object *json, bool uj)
-{
- struct pim_upstream *up = ch->upstream;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj) {
- char grp_str[PIM_ADDRSTRLEN];
- char src_str[PIM_ADDRSTRLEN];
-
- snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
- snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
-
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_pim_upstream_add(json_row, up);
- json_object_string_add(json_row, "interface",
- ch->interface->name);
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
-
- if (pim_macro_ch_lost_assert(ch))
- json_object_boolean_true_add(json_row, "lostAssert");
-
- if (pim_macro_chisin_joins(ch))
- json_object_boolean_true_add(json_row, "joins");
-
- if (pim_macro_chisin_pim_include(ch))
- json_object_boolean_true_add(json_row, "pimInclude");
-
- if (pim_upstream_evaluate_join_desired(pim, up))
- json_object_boolean_true_add(json_row,
- "evaluateJoinDesired");
-
- json_object_object_add(json_group, src_str, json_row);
-
- } else {
- vty_out(vty, "%-16s %-15pPAs %-15pPAs %-10s %-5s %-10s %-11s %-6s\n",
- ch->interface->name, &up->sg.src, &up->sg.grp,
- pim_macro_ch_lost_assert(ch) ? "yes" : "no",
- pim_macro_chisin_joins(ch) ? "yes" : "no",
- pim_macro_chisin_pim_include(ch) ? "yes" : "no",
- PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
- ? "yes"
- : "no",
- pim_upstream_evaluate_join_desired(pim, up) ? "yes"
- : "no");
- }
-}
-
-static void pim_show_channel(struct pim_instance *pim, struct vty *vty,
- bool uj)
-{
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct interface *ifp;
-
- json_object *json = NULL;
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out(vty,
- "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
-
- /* scan per-interface (S,G) state */
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
-
-
- RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
- /* scan all interfaces */
- pim_show_channel_helper(pim, vty, pim_ifp, ch,
- json, uj);
- }
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
-static void pim_show_join_desired_helper(struct pim_instance *pim,
- struct vty *vty,
- struct pim_upstream *up,
- json_object *json, bool uj)
-{
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj) {
- char grp_str[PIM_ADDRSTRLEN];
- char src_str[PIM_ADDRSTRLEN];
-
- snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
- snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
-
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_pim_upstream_add(json_row, up);
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
-
- if (pim_upstream_evaluate_join_desired(pim, up))
- json_object_boolean_true_add(json_row,
- "evaluateJoinDesired");
-
- json_object_object_add(json_group, src_str, json_row);
-
- } else {
- vty_out(vty, "%-15pPAs %-15pPAs %-6s\n",
- &up->sg.src, &up->sg.grp,
- pim_upstream_evaluate_join_desired(pim, up) ? "yes"
- : "no");
- }
-}
-
-static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
- bool uj)
-{
- struct pim_upstream *up;
-
- json_object *json = NULL;
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out(vty,
- "Source Group EvalJD\n");
-
- frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- /* scan all interfaces */
- pim_show_join_desired_helper(pim, vty, up,
- json, uj);
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
-static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
- bool uj)
-{
- struct pim_upstream *up;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out(vty,
- "Source Group RpfIface RibNextHop RpfAddress \n");
-
- frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- char rpf_nexthop_str[PREFIX_STRLEN];
- char rpf_addr_str[PREFIX_STRLEN];
- struct pim_rpf *rpf;
- const char *rpf_ifname;
-
- rpf = &up->rpf;
-
- pim_addr_dump("<nexthop?>",
- &rpf->source_nexthop.mrib_nexthop_addr,
- rpf_nexthop_str, sizeof(rpf_nexthop_str));
- pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
- sizeof(rpf_addr_str));
-
- rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
-
- if (uj) {
- char grp_str[PIM_ADDRSTRLEN];
- char src_str[PIM_ADDRSTRLEN];
-
- snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
- &up->sg.grp);
- snprintfrr(src_str, sizeof(src_str), "%pPAs",
- &up->sg.src);
-
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str,
- json_group);
- }
-
- json_row = json_object_new_object();
- json_object_pim_upstream_add(json_row, up);
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "rpfInterface",
- rpf_ifname);
- json_object_string_add(json_row, "ribNexthop",
- rpf_nexthop_str);
- json_object_string_add(json_row, "rpfAddress",
- rpf_addr_str);
- json_object_object_add(json_group, src_str, json_row);
- } else {
- vty_out(vty, "%-15pPAs %-15pPAs %-16s %-15s %-15s\n",
- &up->sg.src, &up->sg.grp, rpf_ifname,
- rpf_nexthop_str, rpf_addr_str);
- }
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
-static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
- time_t now, json_object *json)
-{
- char refresh_uptime[10];
-
- pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
- pim->rpf_cache_refresh_last);
-
- if (json) {
- json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
- router->rpf_cache_refresh_delay_msec);
- json_object_int_add(
- json, "rpfCacheRefreshTimer",
- pim_time_timer_remain_msec(pim->rpf_cache_refresher));
- json_object_int_add(json, "rpfCacheRefreshRequests",
- pim->rpf_cache_refresh_requests);
- json_object_int_add(json, "rpfCacheRefreshEvents",
- pim->rpf_cache_refresh_events);
- json_object_string_add(json, "rpfCacheRefreshLast",
- refresh_uptime);
- json_object_int_add(json, "nexthopLookups",
- pim->nexthop_lookups);
- json_object_int_add(json, "nexthopLookupsAvoided",
- pim->nexthop_lookups_avoided);
- } else {
- vty_out(vty,
- "RPF Cache Refresh Delay: %ld msecs\n"
- "RPF Cache Refresh Timer: %ld msecs\n"
- "RPF Cache Refresh Requests: %lld\n"
- "RPF Cache Refresh Events: %lld\n"
- "RPF Cache Refresh Last: %s\n"
- "Nexthop Lookups: %lld\n"
- "Nexthop Lookups Avoided: %lld\n",
- router->rpf_cache_refresh_delay_msec,
- pim_time_timer_remain_msec(pim->rpf_cache_refresher),
- (long long)pim->rpf_cache_refresh_requests,
- (long long)pim->rpf_cache_refresh_events,
- refresh_uptime, (long long)pim->nexthop_lookups,
- (long long)pim->nexthop_lookups_avoided);
- }
-}
-
static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
time_t now)
{
@@ -2919,129 +1043,6 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
uptime_mroute_del, (long long)pim->mroute_del_events);
}
-static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
-{
- struct pim_upstream *up;
- time_t now = pim_time_monotonic_sec();
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj) {
- json = json_object_new_object();
- show_rpf_refresh_stats(vty, pim, now, json);
- } else {
- show_rpf_refresh_stats(vty, pim, now, json);
- vty_out(vty, "\n");
- vty_out(vty,
- "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
- }
-
- frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- char rpf_addr_str[PREFIX_STRLEN];
- char rib_nexthop_str[PREFIX_STRLEN];
- const char *rpf_ifname;
- struct pim_rpf *rpf = &up->rpf;
-
- pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
- sizeof(rpf_addr_str));
- pim_addr_dump("<nexthop?>",
- &rpf->source_nexthop.mrib_nexthop_addr,
- rib_nexthop_str, sizeof(rib_nexthop_str));
-
- rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
-
- if (uj) {
- char grp_str[PIM_ADDRSTRLEN];
- char src_str[PIM_ADDRSTRLEN];
-
- snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
- &up->sg.grp);
- snprintfrr(src_str, sizeof(src_str), "%pPAs",
- &up->sg.src);
-
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str,
- json_group);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "rpfInterface",
- rpf_ifname);
- json_object_string_add(json_row, "rpfAddress",
- rpf_addr_str);
- json_object_string_add(json_row, "ribNexthop",
- rib_nexthop_str);
- json_object_int_add(
- json_row, "routeMetric",
- rpf->source_nexthop.mrib_route_metric);
- json_object_int_add(
- json_row, "routePreference",
- rpf->source_nexthop.mrib_metric_preference);
- json_object_object_add(json_group, src_str, json_row);
-
- } else {
- vty_out(vty, "%-15pPAs %-15pPAs %-16s %-15s %-15s %6d %4d\n",
- &up->sg.src, &up->sg.grp, rpf_ifname,
- rpf_addr_str, rib_nexthop_str,
- rpf->source_nexthop.mrib_route_metric,
- rpf->source_nexthop.mrib_metric_preference);
- }
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
-struct pnc_cache_walk_data {
- struct vty *vty;
- struct pim_instance *pim;
-};
-
-static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
-{
- struct pim_nexthop_cache *pnc = bucket->data;
- struct pnc_cache_walk_data *cwd = arg;
- struct vty *vty = cwd->vty;
- struct pim_instance *pim = cwd->pim;
- struct nexthop *nh_node = NULL;
- ifindex_t first_ifindex;
- struct interface *ifp = NULL;
- char buf[PREFIX_STRLEN];
-
- for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
- first_ifindex = nh_node->ifindex;
- ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
-
- vty_out(vty, "%-15s ", inet_ntop(AF_INET,
- &pnc->rpf.rpf_addr.u.prefix4,
- buf, sizeof(buf)));
- vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
- vty_out(vty, "%pI4 ", &nh_node->gate.ipv4);
- vty_out(vty, "\n");
- }
- return CMD_SUCCESS;
-}
-
-static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
-{
- struct pnc_cache_walk_data cwd;
-
- cwd.vty = vty;
- cwd.pim = pim;
- vty_out(vty, "Number of registered addresses: %lu\n",
- pim->rpf_hash->count);
- vty_out(vty, "Address Interface Nexthop\n");
- vty_out(vty, "---------------------------------------------\n");
-
- hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
-}
-
/* Display the bsm database details */
static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
{
@@ -3325,78 +1326,6 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
vty_json(vty, json);
}
-/* pim statistics - just adding only bsm related now.
- * We can continue to add all pim related stats here.
- */
-static void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
- const char *ifname, bool uj)
-{
- json_object *json = NULL;
- struct interface *ifp;
-
- if (uj) {
- json = json_object_new_object();
- json_object_int_add(json, "bsmRx", pim->bsm_rcvd);
- json_object_int_add(json, "bsmTx", pim->bsm_sent);
- json_object_int_add(json, "bsmDropped", pim->bsm_dropped);
- } else {
- vty_out(vty, "BSM Statistics :\n");
- vty_out(vty, "----------------\n");
- vty_out(vty, "Number of Received BSMs : %" PRIu64 "\n",
- pim->bsm_rcvd);
- vty_out(vty, "Number of Forwared BSMs : %" PRIu64 "\n",
- pim->bsm_sent);
- vty_out(vty, "Number of Dropped BSMs : %" PRIu64 "\n",
- pim->bsm_dropped);
- }
-
- vty_out(vty, "\n");
-
- /* scan interfaces */
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- struct pim_interface *pim_ifp = ifp->info;
-
- if (ifname && strcmp(ifname, ifp->name))
- continue;
-
- if (!pim_ifp)
- continue;
-
- if (!uj) {
- vty_out(vty, "Interface : %s\n", ifp->name);
- vty_out(vty, "-------------------\n");
- vty_out(vty,
- "Number of BSMs dropped due to config miss : %u\n",
- pim_ifp->pim_ifstat_bsm_cfg_miss);
- vty_out(vty, "Number of unicast BSMs dropped : %u\n",
- pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
- vty_out(vty,
- "Number of BSMs dropped due to invalid scope zone : %u\n",
- pim_ifp->pim_ifstat_bsm_invalid_sz);
- } else {
-
- json_object *json_row = NULL;
-
- json_row = json_object_new_object();
-
- json_object_string_add(json_row, "If Name", ifp->name);
- json_object_int_add(json_row, "bsmDroppedConfig",
- pim_ifp->pim_ifstat_bsm_cfg_miss);
- json_object_int_add(
- json_row, "bsmDroppedUnicast",
- pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
- json_object_int_add(json_row,
- "bsmDroppedInvalidScopeZone",
- pim_ifp->pim_ifstat_bsm_invalid_sz);
- json_object_object_add(json, ifp->name, json_row);
- }
- vty_out(vty, "\n");
- }
-
- if (uj)
- vty_json(vty, json);
-}
-
static void clear_pim_statistics(struct pim_instance *pim)
{
struct interface *ifp;
@@ -3594,7 +1523,7 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
json = json_object_new_object();
else
vty_out(vty,
- "Interface Address Group Source Timer Fwd Uptime \n");
+ "Interface Group Source Timer Fwd Uptime \n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -4570,9 +2499,9 @@ DEFUN (show_ip_pim_assert_winner_metric,
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_interface,
+DEFPY (show_ip_pim_interface,
show_ip_pim_interface_cmd,
- "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
+ "show ip pim [mlag$mlag] [vrf NAME] interface [detail|WORD]$interface [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -4583,30 +2512,34 @@ DEFUN (show_ip_pim_interface,
"interface name\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
- bool mlag = false;
+ struct vrf *v;
+ bool uj = !!json;
+ bool is_mlag = !!mlag;
+ json_object *json_parent = NULL;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- if (argv_find(argv, argc, "mlag", &idx))
- mlag = true;
+ if (uj)
+ json_parent = json_object_new_object();
- if (argv_find(argv, argc, "WORD", &idx)
- || argv_find(argv, argc, "detail", &idx))
- pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, mlag,
- uj);
+ if (interface)
+ pim_show_interfaces_single(v->info, vty, interface, is_mlag,
+ json_parent);
else
- pim_show_interfaces(vrf->info, vty, mlag, uj);
+ pim_show_interfaces(v->info, vty, is_mlag, json_parent);
+
+ if (uj)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_interface_vrf_all,
+DEFPY (show_ip_pim_interface_vrf_all,
show_ip_pim_interface_vrf_all_cmd,
- "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
+ "show ip pim [mlag$mlag] vrf all interface [detail|WORD]$interface [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -4617,35 +2550,32 @@ DEFUN (show_ip_pim_interface_vrf_all,
"interface name\n"
JSON_STR)
{
- int idx = 2;
- bool uj = use_json(argc, argv);
- struct vrf *vrf;
- bool first = true;
- bool mlag = false;
-
- if (argv_find(argv, argc, "mlag", &idx))
- mlag = true;
+ bool uj = !!json;
+ bool is_mlag = !!mlag;
+ struct vrf *v;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
- idx = 6;
if (uj)
- vty_out(vty, "{ ");
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
- vty_out(vty, "VRF: %s\n", vrf->name);
- if (argv_find(argv, argc, "WORD", &idx)
- || argv_find(argv, argc, "detail", &idx))
- pim_show_interfaces_single(vrf->info, vty,
- argv[idx]->arg, mlag, uj);
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (v, vrf_name_head, &vrfs_by_name) {
+ if (!uj)
+ vty_out(vty, "VRF: %s\n", v->name);
else
- pim_show_interfaces(vrf->info, vty, mlag, uj);
+ json_vrf = json_object_new_object();
+
+ if (interface)
+ pim_show_interfaces_single(v->info, vty, interface,
+ is_mlag, json_vrf);
+ else
+ pim_show_interfaces(v->info, vty, is_mlag, json_vrf);
+
+ if (uj)
+ json_object_object_add(json_parent, v->name, json_vrf);
}
if (uj)
- vty_out(vty, "}\n");
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
@@ -4664,8 +2594,8 @@ DEFPY (show_ip_pim_join,
{
pim_sgaddr sg = {0};
struct vrf *v;
- bool uj = !!json;
struct pim_instance *pim;
+ json_object *json_parent = NULL;
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
@@ -4688,14 +2618,20 @@ DEFPY (show_ip_pim_join,
sg.grp = s_or_g;
}
- pim_show_join(pim, vty, &sg, uj);
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_show_join(pim, vty, &sg, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_join_vrf_all,
+DEFPY (show_ip_pim_join_vrf_all,
show_ip_pim_join_vrf_all_cmd,
- "show ip pim vrf all join [json]",
+ "show ip pim vrf all join [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -4704,77 +2640,29 @@ DEFUN (show_ip_pim_join_vrf_all,
JSON_STR)
{
pim_sgaddr sg = {0};
- bool uj = use_json(argc, argv);
- struct vrf *vrf;
- bool first = true;
+ struct vrf *vrf_struct;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
- if (uj)
- vty_out(vty, "{ ");
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
- vty_out(vty, "VRF: %s\n", vrf->name);
- pim_show_join(vrf->info, vty, &sg, uj);
+ if (json)
+ json_parent = json_object_new_object();
+ RB_FOREACH (vrf_struct, vrf_name_head, &vrfs_by_name) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", vrf_struct->name);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_join(vrf_struct->info, vty, &sg, json_vrf);
+
+ if (json)
+ json_object_object_add(json_parent, vrf_struct->name,
+ json_vrf);
}
- if (uj)
- vty_out(vty, "}\n");
+ if (json)
+ vty_json(vty, json_parent);
return CMD_WARNING;
}
-static void pim_show_jp_agg_helper(struct vty *vty,
- struct interface *ifp,
- struct pim_neighbor *neigh,
- struct pim_upstream *up,
- int is_join)
-{
- char rpf_str[INET_ADDRSTRLEN];
-
- /* pius->address.s_addr */
- pim_inet4_dump("<rpf?>", neigh->source_addr, rpf_str, sizeof(rpf_str));
-
- vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %5s\n", ifp->name, rpf_str,
- &up->sg.src, &up->sg.grp, is_join ? "J" : "P");
-}
-
-static void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
-{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct listnode *n_node;
- struct pim_neighbor *neigh;
- struct listnode *jag_node;
- struct pim_jp_agg_group *jag;
- struct listnode *js_node;
- struct pim_jp_sources *js;
-
- vty_out(vty,
- "Interface RPF Nbr Source Group State\n");
-
- FOR_ALL_INTERFACES (pim->vrf, ifp) {
- pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
- n_node, neigh)) {
- for (ALL_LIST_ELEMENTS_RO(neigh->upstream_jp_agg,
- jag_node, jag)) {
- for (ALL_LIST_ELEMENTS_RO(jag->sources,
- js_node, js)) {
- pim_show_jp_agg_helper(vty,
- ifp, neigh, js->up,
- js->is_join);
- }
- }
- }
- }
-}
-
DEFPY (show_ip_pim_jp_agg,
show_ip_pim_jp_agg_cmd,
"show ip pim [vrf NAME] jp-agg",
@@ -4805,9 +2693,9 @@ DEFPY (show_ip_pim_jp_agg,
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_local_membership,
+DEFPY (show_ip_pim_local_membership,
show_ip_pim_local_membership_cmd,
- "show ip pim [vrf NAME] local-membership [json]",
+ "show ip pim [vrf NAME] local-membership [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -4815,14 +2703,15 @@ DEFUN (show_ip_pim_local_membership,
"PIM interface local-membership\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct vrf *v;
+ bool uj = !!json;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- pim_show_membership(vrf->info, vty, uj);
+ pim_show_membership(v->info, vty, uj);
return CMD_SUCCESS;
}
@@ -5094,9 +2983,9 @@ DEFUN(show_ip_pim_mlag_up_vrf_all, show_ip_pim_mlag_up_vrf_all_cmd,
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_neighbor,
+DEFPY (show_ip_pim_neighbor,
show_ip_pim_neighbor_cmd,
- "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
+ "show ip pim [vrf NAME] neighbor [detail|WORD]$interface [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5106,25 +2995,31 @@ DEFUN (show_ip_pim_neighbor,
"Name of interface or neighbor\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct vrf *v;
+ json_object *json_parent = NULL;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- if (argv_find(argv, argc, "detail", &idx)
- || argv_find(argv, argc, "WORD", &idx))
- pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
+ if (json)
+ json_parent = json_object_new_object();
+
+ if (interface)
+ pim_show_neighbors_single(v->info, vty, interface, json_parent);
else
- pim_show_neighbors(vrf->info, vty, uj);
+ pim_show_neighbors(v->info, vty, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_neighbor_vrf_all,
+DEFPY (show_ip_pim_neighbor_vrf_all,
show_ip_pim_neighbor_vrf_all_cmd,
- "show ip pim vrf all neighbor [detail|WORD] [json]",
+ "show ip pim vrf all neighbor [detail|WORD]$interface [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5134,35 +3029,34 @@ DEFUN (show_ip_pim_neighbor_vrf_all,
"Name of interface or neighbor\n"
JSON_STR)
{
- int idx = 2;
- bool uj = use_json(argc, argv);
- struct vrf *vrf;
- bool first = true;
+ struct vrf *v;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
- if (uj)
- vty_out(vty, "{ ");
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
- vty_out(vty, "VRF: %s\n", vrf->name);
- if (argv_find(argv, argc, "detail", &idx)
- || argv_find(argv, argc, "WORD", &idx))
- pim_show_neighbors_single(vrf->info, vty,
- argv[idx]->arg, uj);
+ if (json)
+ json_parent = json_object_new_object();
+ RB_FOREACH (v, vrf_name_head, &vrfs_by_name) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", v->name);
+ else
+ json_vrf = json_object_new_object();
+
+ if (interface)
+ pim_show_neighbors_single(v->info, vty, interface,
+ json_vrf);
else
- pim_show_neighbors(vrf->info, vty, uj);
+ pim_show_neighbors(v->info, vty, json_vrf);
+
+ if (json)
+ json_object_object_add(json_parent, v->name, json_vrf);
}
- if (uj)
- vty_out(vty, "}\n");
+ if (json)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_secondary,
+DEFPY (show_ip_pim_secondary,
show_ip_pim_secondary_cmd,
"show ip pim [vrf NAME] secondary",
SHOW_STR
@@ -5171,20 +3065,29 @@ DEFUN (show_ip_pim_secondary,
VRF_CMD_HELP_STR
"PIM neighbor addresses\n")
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct pim_instance *pim;
+ struct vrf *v;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
return CMD_WARNING;
+ }
- pim_show_neighbors_secondary(vrf->info, vty);
+ pim_show_neighbors_secondary(pim, vty);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_state,
+DEFPY (show_ip_pim_state,
show_ip_pim_state_cmd,
- "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
+ "show ip pim [vrf NAME] state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5194,32 +3097,36 @@ DEFUN (show_ip_pim_state,
"Multicast address\n"
JSON_STR)
{
- const char *src_or_group = NULL;
- const char *group = NULL;
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct pim_instance *pim;
+ struct vrf *v;
+ json_object *json_parent = NULL;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- if (uj)
- argc--;
+ pim = pim_get_pim_instance(v->vrf_id);
- if (argv_find(argv, argc, "A.B.C.D", &idx)) {
- src_or_group = argv[idx]->arg;
- if (idx + 1 < argc)
- group = argv[idx + 1]->arg;
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
}
- pim_show_state(vrf->info, vty, src_or_group, group, uj);
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_show_state(pim, vty, s_or_g_str, g_str, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_state_vrf_all,
+DEFPY (show_ip_pim_state_vrf_all,
show_ip_pim_state_vrf_all_cmd,
- "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
+ "show ip pim vrf all state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5229,36 +3136,25 @@ DEFUN (show_ip_pim_state_vrf_all,
"Multicast address\n"
JSON_STR)
{
- const char *src_or_group = NULL;
- const char *group = NULL;
- int idx = 2;
- bool uj = use_json(argc, argv);
struct vrf *vrf;
- bool first = true;
-
- if (uj) {
- vty_out(vty, "{ ");
- argc--;
- }
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
- if (argv_find(argv, argc, "A.B.C.D", &idx)) {
- src_or_group = argv[idx]->arg;
- if (idx + 1 < argc)
- group = argv[idx + 1]->arg;
- }
+ if (json)
+ json_parent = json_object_new_object();
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
+ if (!json)
vty_out(vty, "VRF: %s\n", vrf->name);
- pim_show_state(vrf->info, vty, src_or_group, group, uj);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_state(vrf->info, vty, s_or_g_str, g_str, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
}
- if (uj)
- vty_out(vty, "}\n");
+ if (json)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
@@ -5279,6 +3175,7 @@ DEFPY (show_ip_pim_upstream,
struct vrf *v;
bool uj = !!json;
struct pim_instance *pim;
+ json_object *json_parent = NULL;
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
@@ -5293,6 +3190,9 @@ DEFPY (show_ip_pim_upstream,
return CMD_WARNING;
}
+ if (uj)
+ json_parent = json_object_new_object();
+
if (s_or_g.s_addr != INADDR_ANY) {
if (g.s_addr != INADDR_ANY) {
sg.src = s_or_g;
@@ -5300,14 +3200,17 @@ DEFPY (show_ip_pim_upstream,
} else
sg.grp = s_or_g;
}
- pim_show_upstream(pim, vty, &sg, uj);
+ pim_show_upstream(pim, vty, &sg, json_parent);
+
+ if (uj)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_upstream_vrf_all,
+DEFPY (show_ip_pim_upstream_vrf_all,
show_ip_pim_upstream_vrf_all_cmd,
- "show ip pim vrf all upstream [json]",
+ "show ip pim vrf all upstream [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5316,29 +3219,33 @@ DEFUN (show_ip_pim_upstream_vrf_all,
JSON_STR)
{
pim_sgaddr sg = {0};
- bool uj = use_json(argc, argv);
struct vrf *vrf;
- bool first = true;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
- if (uj)
- vty_out(vty, "{ ");
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
+ if (!json)
vty_out(vty, "VRF: %s\n", vrf->name);
- pim_show_upstream(vrf->info, vty, &sg, uj);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_upstream(vrf->info, vty, &sg, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
}
+ if (json)
+ vty_json(vty, json_parent);
+
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_channel,
+DEFPY (show_ip_pim_channel,
show_ip_pim_channel_cmd,
- "show ip pim [vrf NAME] channel [json]",
+ "show ip pim [vrf NAME] channel [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5346,21 +3253,22 @@ DEFUN (show_ip_pim_channel,
"PIM downstream channel info\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct vrf *v;
+ bool uj = !!json;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- pim_show_channel(vrf->info, vty, uj);
+ pim_show_channel(v->info, vty, uj);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_upstream_join_desired,
+DEFPY (show_ip_pim_upstream_join_desired,
show_ip_pim_upstream_join_desired_cmd,
- "show ip pim [vrf NAME] upstream-join-desired [json]",
+ "show ip pim [vrf NAME] upstream-join-desired [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5368,21 +3276,30 @@ DEFUN (show_ip_pim_upstream_join_desired,
"PIM upstream join-desired\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct pim_instance *pim;
+ struct vrf *v;
+ bool uj = !!json;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- pim_show_join_desired(vrf->info, vty, uj);
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ pim_show_join_desired(pim, vty, uj);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_upstream_rpf,
+DEFPY (show_ip_pim_upstream_rpf,
show_ip_pim_upstream_rpf_cmd,
- "show ip pim [vrf NAME] upstream-rpf [json]",
+ "show ip pim [vrf NAME] upstream-rpf [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5390,21 +3307,30 @@ DEFUN (show_ip_pim_upstream_rpf,
"PIM upstream source rpf\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct pim_instance *pim;
+ struct vrf *v;
+ bool uj = !!json;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
+ return CMD_WARNING;
+
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
return CMD_WARNING;
+ }
- pim_show_upstream_rpf(vrf->info, vty, uj);
+ pim_show_upstream_rpf(pim, vty, uj);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_rp,
+DEFPY (show_ip_pim_rp,
show_ip_pim_rp_cmd,
- "show ip pim [vrf NAME] rp-info [A.B.C.D/M] [json]",
+ "show ip pim [vrf NAME] rp-info [A.B.C.D/M$group] [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5413,28 +3339,45 @@ DEFUN (show_ip_pim_rp,
"Multicast Group range\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct pim_instance *pim;
+ struct vrf *v;
+ json_object *json_parent = NULL;
struct prefix *range = NULL;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- if (argv_find(argv, argc, "A.B.C.D/M", &idx)) {
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (group_str) {
range = prefix_new();
- (void)str2prefix(argv[idx]->arg, range);
+ prefix_copy(range, group);
apply_mask(range);
}
- pim_rp_show_information(vrf->info, range, vty, uj);
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_rp_show_information(pim, range, vty, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ prefix_free(&range);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_rp_vrf_all,
+DEFPY (show_ip_pim_rp_vrf_all,
show_ip_pim_rp_vrf_all_cmd,
- "show ip pim vrf all rp-info [A.B.C.D/M] [json]",
+ "show ip pim vrf all rp-info [A.B.C.D/M$group] [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5443,39 +3386,41 @@ DEFUN (show_ip_pim_rp_vrf_all,
"Multicast Group range\n"
JSON_STR)
{
- int idx = 0;
- bool uj = use_json(argc, argv);
struct vrf *vrf;
- bool first = true;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
struct prefix *range = NULL;
- if (argv_find(argv, argc, "A.B.C.D/M", &idx)) {
+ if (group_str) {
range = prefix_new();
- (void)str2prefix(argv[idx]->arg, range);
+ prefix_copy(range, group);
apply_mask(range);
}
- if (uj)
- vty_out(vty, "{ ");
+ if (json)
+ json_parent = json_object_new_object();
+
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
+ if (!json)
vty_out(vty, "VRF: %s\n", vrf->name);
- pim_rp_show_information(vrf->info, range, vty, uj);
+ else
+ json_vrf = json_object_new_object();
+ pim_rp_show_information(vrf->info, range, vty, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
}
- if (uj)
- vty_out(vty, "}\n");
+ if (json)
+ vty_json(vty, json_parent);
+
+ prefix_free(&range);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_rpf,
+DEFPY (show_ip_pim_rpf,
show_ip_pim_rpf_cmd,
- "show ip pim [vrf NAME] rpf [json]",
+ "show ip pim [vrf NAME] rpf [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5483,21 +3428,36 @@ DEFUN (show_ip_pim_rpf,
"PIM cached source rpf information\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct pim_instance *pim;
+ struct vrf *v;
+ json_object *json_parent = NULL;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- pim_show_rpf(vrf->info, vty, uj);
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_show_rpf(pim, vty, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_rpf_vrf_all,
+DEFPY (show_ip_pim_rpf_vrf_all,
show_ip_pim_rpf_vrf_all_cmd,
- "show ip pim vrf all rpf [json]",
+ "show ip pim vrf all rpf [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5505,29 +3465,30 @@ DEFUN (show_ip_pim_rpf_vrf_all,
"PIM cached source rpf information\n"
JSON_STR)
{
- bool uj = use_json(argc, argv);
struct vrf *vrf;
- bool first = true;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
- if (uj)
- vty_out(vty, "{ ");
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
- } else
+ if (!json)
vty_out(vty, "VRF: %s\n", vrf->name);
- pim_show_rpf(vrf->info, vty, uj);
+ else
+ json_vrf = json_object_new_object();
+ pim_show_rpf(vrf->info, vty, json_vrf);
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
}
- if (uj)
- vty_out(vty, "}\n");
+ if (json)
+ vty_json(vty, json_parent);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_nexthop,
+DEFPY (show_ip_pim_nexthop,
show_ip_pim_nexthop_cmd,
"show ip pim [vrf NAME] nexthop",
SHOW_STR
@@ -5536,20 +3497,21 @@ DEFUN (show_ip_pim_nexthop,
VRF_CMD_HELP_STR
"PIM cached nexthop rpf information\n")
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *v;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- pim_show_nexthop(vrf->info, vty);
+ pim_show_nexthop(v->info, vty);
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_nexthop_lookup,
+DEFPY (show_ip_pim_nexthop_lookup,
show_ip_pim_nexthop_lookup_cmd,
- "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
+ "show ip pim [vrf NAME] nexthop-lookup A.B.C.D$source A.B.C.D$group",
SHOW_STR
IP_STR
PIM_STR
@@ -5560,61 +3522,37 @@ DEFUN (show_ip_pim_nexthop_lookup,
{
struct prefix nht_p;
int result = 0;
- struct in_addr src_addr, grp_addr;
- struct in_addr vif_source;
- const char *addr_str, *addr_str1;
+ pim_addr vif_source;
struct prefix grp;
struct pim_nexthop nexthop;
char nexthop_addr_str[PREFIX_STRLEN];
- char grp_str[PREFIX_STRLEN];
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *v;
- if (!vrf)
- return CMD_WARNING;
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
- argv_find(argv, argc, "A.B.C.D", &idx);
- addr_str = argv[idx]->arg;
- result = inet_pton(AF_INET, addr_str, &src_addr);
- if (result <= 0) {
- vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
- errno, safe_strerror(errno));
+ if (!v)
return CMD_WARNING;
- }
- if (pim_is_group_224_4(src_addr)) {
+ if (pim_is_group_224_4(source)) {
vty_out(vty,
"Invalid argument. Expected Valid Source Address.\n");
return CMD_WARNING;
}
- addr_str1 = argv[idx + 1]->arg;
- result = inet_pton(AF_INET, addr_str1, &grp_addr);
- if (result <= 0) {
- vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
- errno, safe_strerror(errno));
- return CMD_WARNING;
- }
-
- if (!pim_is_group_224_4(grp_addr)) {
+ if (!pim_is_group_224_4(group)) {
vty_out(vty,
"Invalid argument. Expected Valid Multicast Group Address.\n");
return CMD_WARNING;
}
- if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
- grp_addr))
+ if (!pim_rp_set_upstream_addr(v->info, &vif_source, source, group))
return CMD_SUCCESS;
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = vif_source;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = grp_addr;
+ pim_addr_to_prefix(&nht_p, vif_source);
+ pim_addr_to_prefix(&grp, group);
memset(&nexthop, 0, sizeof(nexthop));
- result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
+ result = pim_ecmp_nexthop_lookup(v->info, &nexthop, &nht_p, &grp, 0);
if (!result) {
vty_out(vty,
@@ -5622,10 +3560,9 @@ DEFUN (show_ip_pim_nexthop_lookup,
return CMD_SUCCESS;
}
- pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
nexthop_addr_str, sizeof(nexthop_addr_str));
- vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
+ vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", group_str,
nexthop_addr_str, nexthop.interface->name);
return CMD_SUCCESS;
@@ -5702,9 +3639,9 @@ DEFUN (show_ip_pim_bsrp,
return CMD_SUCCESS;
}
-DEFUN (show_ip_pim_statistics,
+DEFPY (show_ip_pim_statistics,
show_ip_pim_statistics_cmd,
- "show ip pim [vrf NAME] statistics [interface WORD] [json]",
+ "show ip pim [vrf NAME] statistics [interface WORD$word] [json$json]",
SHOW_STR
IP_STR
PIM_STR
@@ -5714,17 +3651,26 @@ DEFUN (show_ip_pim_statistics,
"PIM interface\n"
JSON_STR)
{
- int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- bool uj = use_json(argc, argv);
+ struct pim_instance *pim;
+ struct vrf *v;
+ bool uj = !!json;
- if (!vrf)
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+
+ if (!v)
return CMD_WARNING;
- if (argv_find(argv, argc, "WORD", &idx))
- pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
+ pim = pim_get_pim_instance(v->vrf_id);
+
+ if (!pim) {
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (word)
+ pim_show_statistics(pim, vty, word, uj);
else
- pim_show_statistics(vrf->info, vty, NULL, uj);
+ pim_show_statistics(pim, vty, NULL, uj);
return CMD_SUCCESS;
}
@@ -5840,7 +3786,7 @@ static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
vty_out(vty, "\n");
- show_rpf_refresh_stats(vty, pim, now, NULL);
+ pim_show_rpf_refresh_stats(vty, pim, now, NULL);
vty_out(vty, "\n");
@@ -6963,7 +4909,7 @@ DEFPY (ip_pim_rp_keep_alive,
"ip pim rp keep-alive-timer (1-65535)$kat",
IP_STR
"pim multicast routing\n"
- "Rendevous Point\n"
+ "Rendezvous Point\n"
"Keep alive Timer\n"
"Seconds\n")
{
@@ -6976,7 +4922,7 @@ DEFUN (no_ip_pim_rp_keep_alive,
NO_STR
IP_STR
"pim multicast routing\n"
- "Rendevous Point\n"
+ "Rendezvous Point\n"
"Keep alive Timer\n"
IGNORED_IN_NO_STR)
{
@@ -7116,7 +5062,7 @@ DEFPY (ip_pim_rp,
"ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
IP_STR
"pim multicast routing\n"
- "Rendevous Point\n"
+ "Rendezvous Point\n"
"ip address of RP\n"
"Group Address range to cover\n")
{
@@ -7144,7 +5090,7 @@ DEFPY (no_ip_pim_rp,
NO_STR
IP_STR
"pim multicast routing\n"
- "Rendevous Point\n"
+ "Rendezvous Point\n"
"ip address of RP\n"
"Group Address range to cover\n")
{
@@ -7265,22 +5211,6 @@ DEFUN (no_ip_pim_ssm_prefix_list_name,
return CMD_WARNING_CONFIG_FAILED;
}
-static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
- struct vty *vty, bool uj)
-{
- struct pim_ssm *ssm = pim->ssm_info;
- const char *range_str =
- ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
-
- if (uj) {
- json_object *json;
- json = json_object_new_object();
- json_object_string_add(json, "ssmGroups", range_str);
- vty_json(vty, json);
- } else
- vty_out(vty, "SSM group range : %s\n", range_str);
-}
-
DEFUN (show_ip_pim_ssm_range,
show_ip_pim_ssm_range_cmd,
"show ip pim [vrf NAME] group-type [json]",
@@ -7384,24 +5314,9 @@ DEFUN (ip_ssmpingd,
"Source address\n")
{
int idx_ipv4 = 2;
- const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
- const char *vrfname;
- char ssmpingd_ip_xpath[XPATH_MAXLEN];
-
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
+ const char *src_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
- snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
- sizeof(ssmpingd_ip_xpath));
-
- nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_CREATE,
- source_str);
-
- return nb_cli_apply_changes(vty, NULL);
+ return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
}
DEFUN (no_ip_ssmpingd,
@@ -7412,25 +5327,10 @@ DEFUN (no_ip_ssmpingd,
CONF_SSMPINGD_STR
"Source address\n")
{
- const char *vrfname;
int idx_ipv4 = 3;
- const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
- char ssmpingd_ip_xpath[XPATH_MAXLEN];
-
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
+ const char *src_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
- snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
- sizeof(ssmpingd_ip_xpath));
-
- nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_DESTROY,
- source_str);
-
- return nb_cli_apply_changes(vty, NULL);
+ return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
}
DEFUN (ip_pim_ecmp,
@@ -7734,35 +5634,15 @@ DEFUN (interface_no_ip_igmp_version,
"frr-routing:ipv4");
}
-DEFUN (interface_ip_igmp_query_max_response_time,
+DEFPY (interface_ip_igmp_query_max_response_time,
interface_ip_igmp_query_max_response_time_cmd,
- "ip igmp query-max-response-time (1-65535)",
+ "ip igmp query-max-response-time (1-65535)$qmrt",
IP_STR
IFACE_IGMP_STR
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
"Query response value in deci-seconds\n")
{
- const struct lyd_node *pim_enable_dnode;
-
- pim_enable_dnode =
- yang_dnode_getf(vty->candidate_config->dnode,
- FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
- "frr-routing:ipv4");
-
- if (!pim_enable_dnode) {
- nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
- "true");
- } else {
- if (!yang_dnode_get_bool(pim_enable_dnode, "."))
- nb_cli_enqueue_change(vty, "./enable",
- NB_OP_MODIFY, "true");
- }
-
- nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
- argv[3]->arg);
-
- return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
- "frr-routing:ipv4");
+ return gm_process_query_max_response_time_cmd(vty, qmrt_str);
}
DEFUN (interface_no_ip_igmp_query_max_response_time,
@@ -7774,10 +5654,7 @@ DEFUN (interface_no_ip_igmp_query_max_response_time,
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
IGNORED_IN_NO_STR)
{
- nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
- NULL);
- return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
- "frr-routing:ipv4");
+ return gm_process_no_query_max_response_time_cmd(vty);
}
DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
@@ -7826,34 +5703,15 @@ DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
"frr-routing:ipv4");
}
-DEFUN (interface_ip_igmp_last_member_query_count,
+DEFPY (interface_ip_igmp_last_member_query_count,
interface_ip_igmp_last_member_query_count_cmd,
- "ip igmp last-member-query-count (1-255)",
+ "ip igmp last-member-query-count (1-255)$lmqc",
IP_STR
IFACE_IGMP_STR
IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
"Last member query count\n")
{
- const struct lyd_node *pim_enable_dnode;
-
- pim_enable_dnode =
- yang_dnode_getf(vty->candidate_config->dnode,
- FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
- "frr-routing:ipv4");
- if (!pim_enable_dnode) {
- nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
- "true");
- } else {
- if (!yang_dnode_get_bool(pim_enable_dnode, "."))
- nb_cli_enqueue_change(vty, "./enable",
- NB_OP_MODIFY, "true");
- }
-
- nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_MODIFY,
- argv[3]->arg);
-
- return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
- "frr-routing:ipv4");
+ return gm_process_last_member_query_count_cmd(vty, lmqc_str);
}
DEFUN (interface_no_ip_igmp_last_member_query_count,
@@ -7865,41 +5723,18 @@ DEFUN (interface_no_ip_igmp_last_member_query_count,
IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
IGNORED_IN_NO_STR)
{
- nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_DESTROY,
- NULL);
-
- return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
- "frr-routing:ipv4");
+ return gm_process_no_last_member_query_count_cmd(vty);
}
-DEFUN (interface_ip_igmp_last_member_query_interval,
+DEFPY (interface_ip_igmp_last_member_query_interval,
interface_ip_igmp_last_member_query_interval_cmd,
- "ip igmp last-member-query-interval (1-65535)",
+ "ip igmp last-member-query-interval (1-65535)$lmqi",
IP_STR
IFACE_IGMP_STR
IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
"Last member query interval in deciseconds\n")
{
- const struct lyd_node *pim_enable_dnode;
-
- pim_enable_dnode =
- yang_dnode_getf(vty->candidate_config->dnode,
- FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
- "frr-routing:ipv4");
- if (!pim_enable_dnode) {
- nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
- "true");
- } else {
- if (!yang_dnode_get_bool(pim_enable_dnode, "."))
- nb_cli_enqueue_change(vty, "./enable",
- NB_OP_MODIFY, "true");
- }
-
- nb_cli_enqueue_change(vty, "./last-member-query-interval", NB_OP_MODIFY,
- argv[3]->arg);
-
- return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
- "frr-routing:ipv4");
+ return gm_process_last_member_query_interval_cmd(vty, lmqi_str);
}
DEFUN (interface_no_ip_igmp_last_member_query_interval,
@@ -7911,11 +5746,7 @@ DEFUN (interface_no_ip_igmp_last_member_query_interval,
IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
IGNORED_IN_NO_STR)
{
- nb_cli_enqueue_change(vty, "./last-member-query-interval",
- NB_OP_DESTROY, NULL);
-
- return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
- "frr-routing:ipv4");
+ return gm_process_no_last_member_query_interval_cmd(vty);
}
DEFUN (interface_ip_pim_drprio,
diff --git a/pimd/pim_cmd.h b/pimd/pim_cmd.h
index 89a4e6e699..8022eeea0e 100644
--- a/pimd/pim_cmd.h
+++ b/pimd/pim_cmd.h
@@ -73,13 +73,4 @@
void pim_cmd_init(void);
-/*
- * Special Macro to allow us to get the correct pim_instance;
- */
-#define PIM_DECLVAR_CONTEXT(A, B) \
- struct vrf *A = VTY_GET_CONTEXT(vrf); \
- struct pim_instance *B = \
- (vrf) ? vrf->info : pim_get_pim_instance(VRF_DEFAULT); \
- vrf = (vrf) ? vrf : pim->vrf;
-
#endif /* PIM_CMD_H */
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index c5d89f8065..fa61cfc06b 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -31,13 +31,27 @@
#include "vrf.h"
#include "ferr.h"
#include "lib/srcdest_table.h"
+#include "lib/linklist.h"
#include "pimd.h"
#include "pim_vty.h"
#include "lib/northbound_cli.h"
#include "pim_errors.h"
#include "pim_nb.h"
+#include "pim_mroute.h"
+#include "pim_cmd.h"
+#include "pim6_cmd.h"
#include "pim_cmd_common.h"
+#include "pim_time.h"
+#include "pim_zebra.h"
+#include "pim_zlookup.h"
+#include "pim_iface.h"
+#include "pim_macro.h"
+#include "pim_neighbor.h"
+#include "pim_nht.h"
+#include "pim_sock.h"
+#include "pim_ssm.h"
+#include "pim_addr.h"
/**
* Get current node VRF name.
@@ -653,3 +667,2198 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
return nb_cli_apply_changes(vty, NULL);
}
+
+bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match)
+{
+ return (pim_addr_is_any(match.grp) ||
+ !pim_addr_cmp(match.grp, item.grp)) &&
+ (pim_addr_is_any(match.src) ||
+ !pim_addr_cmp(match.src, item.src));
+}
+
+void json_object_pim_ifp_add(struct json_object *json, struct interface *ifp)
+{
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ json_object_string_add(json, "name", ifp->name);
+ json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
+ json_object_string_addf(json, "address", "%pPA",
+ &pim_ifp->primary_address);
+ json_object_int_add(json, "index", ifp->ifindex);
+
+ if (if_is_multicast(ifp))
+ json_object_boolean_true_add(json, "flagMulticast");
+
+ if (if_is_broadcast(ifp))
+ json_object_boolean_true_add(json, "flagBroadcast");
+
+ if (ifp->flags & IFF_ALLMULTI)
+ json_object_boolean_true_add(json, "flagAllMulticast");
+
+ if (ifp->flags & IFF_PROMISC)
+ json_object_boolean_true_add(json, "flagPromiscuous");
+
+ if (PIM_IF_IS_DELETED(ifp))
+ json_object_boolean_true_add(json, "flagDeleted");
+
+ if (pim_if_lan_delay_enabled(ifp))
+ json_object_boolean_true_add(json, "lanDelayEnabled");
+}
+
+void pim_print_ifp_flags(struct vty *vty, struct interface *ifp)
+{
+ vty_out(vty, "Flags\n");
+ vty_out(vty, "-----\n");
+ vty_out(vty, "All Multicast : %s\n",
+ (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
+ vty_out(vty, "Broadcast : %s\n",
+ if_is_broadcast(ifp) ? "yes" : "no");
+ vty_out(vty, "Deleted : %s\n",
+ PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
+ vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
+ vty_out(vty, "Multicast : %s\n",
+ if_is_multicast(ifp) ? "yes" : "no");
+ vty_out(vty, "Promiscuous : %s\n",
+ (ifp->flags & IFF_PROMISC) ? "yes" : "no");
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+}
+
+void json_object_pim_upstream_add(json_object *json, struct pim_upstream *up)
+{
+ json_object_boolean_add(
+ json, "drJoinDesired",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED));
+ json_object_boolean_add(
+ json, "drJoinDesiredUpdated",
+ CHECK_FLAG(up->flags,
+ PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED));
+ json_object_boolean_add(
+ json, "firstHopRouter",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_FHR));
+ json_object_boolean_add(
+ json, "sourceIgmp",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP));
+ json_object_boolean_add(
+ json, "sourcePim",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_SRC_PIM));
+ json_object_boolean_add(
+ json, "sourceStream",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM));
+ /* XXX: need to print ths flag in the plain text display as well */
+ json_object_boolean_add(
+ json, "sourceMsdp",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_SRC_MSDP));
+ json_object_boolean_add(
+ json, "sendSGRptPrune",
+ CHECK_FLAG(up->flags,
+ PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE));
+ json_object_boolean_add(
+ json, "lastHopRouter",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_SRC_LHR));
+ json_object_boolean_add(
+ json, "disableKATExpiry",
+ CHECK_FLAG(up->flags,
+ PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY));
+ json_object_boolean_add(
+ json, "staticIncomingInterface",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_STATIC_IIF));
+ json_object_boolean_add(
+ json, "allowIncomingInterfaceinOil",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL));
+ json_object_boolean_add(
+ json, "noPimRegistrationData",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA));
+ json_object_boolean_add(
+ json, "forcePimRegistration",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG));
+ json_object_boolean_add(
+ json, "sourceVxlanOrigination",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG));
+ json_object_boolean_add(
+ json, "sourceVxlanTermination",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM));
+ json_object_boolean_add(
+ json, "mlagVxlan",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN));
+ json_object_boolean_add(
+ json, "mlagNonDesignatedForwarder",
+ CHECK_FLAG(up->flags, PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF));
+}
+
+static const char *
+pim_upstream_state2brief_str(enum pim_upstream_state join_state,
+ char *state_str, size_t state_str_len)
+{
+ switch (join_state) {
+ case PIM_UPSTREAM_NOTJOINED:
+ strlcpy(state_str, "NotJ", state_str_len);
+ break;
+ case PIM_UPSTREAM_JOINED:
+ strlcpy(state_str, "J", state_str_len);
+ break;
+ default:
+ strlcpy(state_str, "Unk", state_str_len);
+ }
+ return state_str;
+}
+
+static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
+ char *state_str,
+ size_t state_str_len)
+{
+ switch (reg_state) {
+ case PIM_REG_NOINFO:
+ strlcpy(state_str, "RegNI", state_str_len);
+ break;
+ case PIM_REG_JOIN:
+ strlcpy(state_str, "RegJ", state_str_len);
+ break;
+ case PIM_REG_JOIN_PENDING:
+ case PIM_REG_PRUNE:
+ strlcpy(state_str, "RegP", state_str_len);
+ break;
+ }
+ return state_str;
+}
+
+void pim_show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
+ time_t now, json_object *json)
+{
+ char refresh_uptime[10];
+
+ pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
+ pim->rpf_cache_refresh_last);
+
+ if (json) {
+ json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
+ router->rpf_cache_refresh_delay_msec);
+ json_object_int_add(
+ json, "rpfCacheRefreshTimer",
+ pim_time_timer_remain_msec(pim->rpf_cache_refresher));
+ json_object_int_add(json, "rpfCacheRefreshRequests",
+ pim->rpf_cache_refresh_requests);
+ json_object_int_add(json, "rpfCacheRefreshEvents",
+ pim->rpf_cache_refresh_events);
+ json_object_string_add(json, "rpfCacheRefreshLast",
+ refresh_uptime);
+ json_object_int_add(json, "nexthopLookups",
+ pim->nexthop_lookups);
+ json_object_int_add(json, "nexthopLookupsAvoided",
+ pim->nexthop_lookups_avoided);
+ } else {
+ vty_out(vty,
+ "RPF Cache Refresh Delay: %ld msecs\n"
+ "RPF Cache Refresh Timer: %ld msecs\n"
+ "RPF Cache Refresh Requests: %lld\n"
+ "RPF Cache Refresh Events: %lld\n"
+ "RPF Cache Refresh Last: %s\n"
+ "Nexthop Lookups: %lld\n"
+ "Nexthop Lookups Avoided: %lld\n",
+ router->rpf_cache_refresh_delay_msec,
+ pim_time_timer_remain_msec(pim->rpf_cache_refresher),
+ (long long)pim->rpf_cache_refresh_requests,
+ (long long)pim->rpf_cache_refresh_events,
+ refresh_uptime, (long long)pim->nexthop_lookups,
+ (long long)pim->nexthop_lookups_avoided);
+ }
+}
+
+void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json)
+{
+ struct pim_upstream *up;
+ time_t now = pim_time_monotonic_sec();
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ pim_show_rpf_refresh_stats(vty, pim, now, json);
+
+ if (!json) {
+ vty_out(vty, "\n");
+ vty_out(vty,
+ "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
+ }
+
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ char rpf_addr_str[PREFIX_STRLEN];
+ char rib_nexthop_str[PREFIX_STRLEN];
+ const char *rpf_ifname;
+ struct pim_rpf *rpf = &up->rpf;
+
+ pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
+ sizeof(rpf_addr_str));
+ pim_addr_dump("<nexthop?>",
+ &rpf->source_nexthop.mrib_nexthop_addr,
+ rib_nexthop_str, sizeof(rib_nexthop_str));
+
+ rpf_ifname =
+ rpf->source_nexthop.interface ? rpf->source_nexthop
+ .interface->name
+ : "<ifname?>";
+
+ if (json) {
+ char grp_str[PIM_ADDRSTRLEN];
+ char src_str[PIM_ADDRSTRLEN];
+
+ snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
+ &up->sg.grp);
+ snprintfrr(src_str, sizeof(src_str), "%pPAs",
+ &up->sg.src);
+
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rpfInterface",
+ rpf_ifname);
+ json_object_string_add(json_row, "rpfAddress",
+ rpf_addr_str);
+ json_object_string_add(json_row, "ribNexthop",
+ rib_nexthop_str);
+ json_object_int_add(
+ json_row, "routeMetric",
+ rpf->source_nexthop.mrib_route_metric);
+ json_object_int_add(
+ json_row, "routePreference",
+ rpf->source_nexthop.mrib_metric_preference);
+ json_object_object_add(json_group, src_str, json_row);
+
+ } else {
+ vty_out(vty,
+ "%-15pPAs %-15pPAs %-16s %-15s %-15s %6d %4d\n",
+ &up->sg.src, &up->sg.grp, rpf_ifname,
+ rpf_addr_str, rib_nexthop_str,
+ rpf->source_nexthop.mrib_route_metric,
+ rpf->source_nexthop.mrib_metric_preference);
+ }
+ }
+}
+
+void pim_show_neighbors_secondary(struct pim_instance *pim, struct vty *vty)
+{
+ struct interface *ifp;
+
+ vty_out(vty,
+ "Interface Address Neighbor Secondary \n");
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ struct pim_interface *pim_ifp;
+ pim_addr ifaddr;
+ struct listnode *neighnode;
+ struct pim_neighbor *neigh;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ ifaddr = pim_ifp->primary_address;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
+ neigh)) {
+ struct listnode *prefix_node;
+ struct prefix *p;
+
+ if (!neigh->prefix_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
+ prefix_node, p))
+ vty_out(vty,
+ "%-16s %-15pPAs %-15pPAs %-15pFX\n",
+ ifp->name, &ifaddr, &neigh->source_addr,
+ p);
+ }
+ }
+}
+
+void pim_show_state(struct pim_instance *pim, struct vty *vty,
+ const char *src_or_group, const char *group,
+ json_object *json)
+{
+ struct channel_oil *c_oil;
+ json_object *json_group = NULL;
+ json_object *json_ifp_in = NULL;
+ json_object *json_ifp_out = NULL;
+ json_object *json_source = NULL;
+ time_t now;
+ int first_oif;
+
+ now = pim_time_monotonic_sec();
+
+ if (!json) {
+ vty_out(vty,
+ "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
+ vty_out(vty,
+ "\nActive Source Group RPT IIF OIL\n");
+ }
+
+ frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
+ char src_str[PIM_ADDRSTRLEN];
+ char grp_str[PIM_ADDRSTRLEN];
+ char in_ifname[INTERFACE_NAMSIZ + 1];
+ char out_ifname[INTERFACE_NAMSIZ + 1];
+ int oif_vif_index;
+ struct interface *ifp_in;
+ bool isRpt;
+
+ first_oif = 1;
+
+ if ((c_oil->up &&
+ PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil->up->flags)) ||
+ pim_addr_is_any(*oil_origin(c_oil)))
+ isRpt = true;
+ else
+ isRpt = false;
+
+ snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
+ oil_mcastgrp(c_oil));
+ snprintfrr(src_str, sizeof(src_str), "%pPAs",
+ oil_origin(c_oil));
+ ifp_in = pim_if_find_by_vif_index(pim, *oil_parent(c_oil));
+
+ if (ifp_in)
+ strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
+ else
+ strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
+
+ if (src_or_group) {
+ if (strcmp(src_or_group, src_str) &&
+ strcmp(src_or_group, grp_str))
+ continue;
+
+ if (group && strcmp(group, grp_str))
+ continue;
+ }
+
+ if (json) {
+
+ /* Find the group, create it if it doesn't exist */
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ /* Find the source nested under the group, create it if
+ * it doesn't exist
+ */
+ json_object_object_get_ex(json_group, src_str,
+ &json_source);
+
+ if (!json_source) {
+ json_source = json_object_new_object();
+ json_object_object_add(json_group, src_str,
+ json_source);
+ }
+
+ /* Find the inbound interface nested under the source,
+ * create it if it doesn't exist
+ */
+ json_object_object_get_ex(json_source, in_ifname,
+ &json_ifp_in);
+
+ if (!json_ifp_in) {
+ json_ifp_in = json_object_new_object();
+ json_object_object_add(json_source, in_ifname,
+ json_ifp_in);
+ json_object_int_add(json_source, "Installed",
+ c_oil->installed);
+ json_object_int_add(json_source, "installed",
+ c_oil->installed);
+ json_object_boolean_add(json_source, "isRpt",
+ isRpt);
+ json_object_int_add(json_source, "RefCount",
+ c_oil->oil_ref_count);
+ json_object_int_add(json_source, "refCount",
+ c_oil->oil_ref_count);
+ json_object_int_add(json_source, "OilListSize",
+ c_oil->oil_size);
+ json_object_int_add(json_source, "oilListSize",
+ c_oil->oil_size);
+ json_object_int_add(
+ json_source, "OilRescan",
+ c_oil->oil_inherited_rescan);
+ json_object_int_add(
+ json_source, "oilRescan",
+ c_oil->oil_inherited_rescan);
+ json_object_int_add(json_source, "LastUsed",
+ c_oil->cc.lastused);
+ json_object_int_add(json_source, "lastUsed",
+ c_oil->cc.lastused);
+ json_object_int_add(json_source, "PacketCount",
+ c_oil->cc.pktcnt);
+ json_object_int_add(json_source, "packetCount",
+ c_oil->cc.pktcnt);
+ json_object_int_add(json_source, "ByteCount",
+ c_oil->cc.bytecnt);
+ json_object_int_add(json_source, "byteCount",
+ c_oil->cc.bytecnt);
+ json_object_int_add(json_source,
+ "WrongInterface",
+ c_oil->cc.wrong_if);
+ json_object_int_add(json_source,
+ "wrongInterface",
+ c_oil->cc.wrong_if);
+ }
+ } else
+ vty_out(vty, "%-6d %-15pPAs %-15pPAs %-3s %-16s ",
+ c_oil->installed, oil_origin(c_oil),
+ oil_mcastgrp(c_oil), isRpt ? "y" : "n",
+ in_ifname);
+
+ for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
+ ++oif_vif_index) {
+ struct interface *ifp_out;
+ char oif_uptime[10];
+ int ttl;
+
+ ttl = oil_if_has(c_oil, oif_vif_index);
+ if (ttl < 1)
+ continue;
+
+ ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
+ pim_time_uptime(
+ oif_uptime, sizeof(oif_uptime),
+ now - c_oil->oif_creation[oif_vif_index]);
+
+ if (ifp_out)
+ strlcpy(out_ifname, ifp_out->name,
+ sizeof(out_ifname));
+ else
+ strlcpy(out_ifname, "<oif?>",
+ sizeof(out_ifname));
+
+ if (json) {
+ json_ifp_out = json_object_new_object();
+ json_object_string_add(json_ifp_out, "source",
+ src_str);
+ json_object_string_add(json_ifp_out, "group",
+ grp_str);
+ json_object_string_add(json_ifp_out,
+ "inboundInterface",
+ in_ifname);
+ json_object_string_add(json_ifp_out,
+ "outboundInterface",
+ out_ifname);
+ json_object_int_add(json_ifp_out, "installed",
+ c_oil->installed);
+
+ json_object_object_add(json_ifp_in, out_ifname,
+ json_ifp_out);
+ } else {
+ if (first_oif) {
+ first_oif = 0;
+ vty_out(vty, "%s(%c%c%c%c%c)",
+ out_ifname,
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_IGMP)
+ ? 'I'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_PIM)
+ ? 'J'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_VXLAN)
+ ? 'V'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_STAR)
+ ? '*'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_MUTE)
+ ? 'M'
+ : ' ');
+ } else
+ vty_out(vty, ", %s(%c%c%c%c%c)",
+ out_ifname,
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_IGMP)
+ ? 'I'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_PIM)
+ ? 'J'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_VXLAN)
+ ? 'V'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_PROTO_STAR)
+ ? '*'
+ : ' ',
+ (c_oil->oif_flags
+ [oif_vif_index] &
+ PIM_OIF_FLAG_MUTE)
+ ? 'M'
+ : ' ');
+ }
+ }
+
+ if (!json)
+ vty_out(vty, "\n");
+ }
+
+ if (!json)
+ vty_out(vty, "\n");
+}
+
+/* pim statistics - just adding only bsm related now.
+ * We can continue to add all pim related stats here.
+ */
+void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
+ const char *ifname, bool uj)
+{
+ json_object *json = NULL;
+ struct interface *ifp;
+
+ if (uj) {
+ json = json_object_new_object();
+ json_object_int_add(json, "bsmRx", pim->bsm_rcvd);
+ json_object_int_add(json, "bsmTx", pim->bsm_sent);
+ json_object_int_add(json, "bsmDropped", pim->bsm_dropped);
+ } else {
+ vty_out(vty, "BSM Statistics :\n");
+ vty_out(vty, "----------------\n");
+ vty_out(vty, "Number of Received BSMs : %" PRIu64 "\n",
+ pim->bsm_rcvd);
+ vty_out(vty, "Number of Forwared BSMs : %" PRIu64 "\n",
+ pim->bsm_sent);
+ vty_out(vty, "Number of Dropped BSMs : %" PRIu64 "\n",
+ pim->bsm_dropped);
+ }
+
+ vty_out(vty, "\n");
+
+ /* scan interfaces */
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (ifname && strcmp(ifname, ifp->name))
+ continue;
+
+ if (!pim_ifp)
+ continue;
+
+ if (!uj) {
+ vty_out(vty, "Interface : %s\n", ifp->name);
+ vty_out(vty, "-------------------\n");
+ vty_out(vty,
+ "Number of BSMs dropped due to config miss : %u\n",
+ pim_ifp->pim_ifstat_bsm_cfg_miss);
+ vty_out(vty, "Number of unicast BSMs dropped : %u\n",
+ pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
+ vty_out(vty,
+ "Number of BSMs dropped due to invalid scope zone : %u\n",
+ pim_ifp->pim_ifstat_bsm_invalid_sz);
+ } else {
+
+ json_object *json_row = NULL;
+
+ json_row = json_object_new_object();
+
+ json_object_string_add(json_row, "If Name", ifp->name);
+ json_object_int_add(json_row, "bsmDroppedConfig",
+ pim_ifp->pim_ifstat_bsm_cfg_miss);
+ json_object_int_add(
+ json_row, "bsmDroppedUnicast",
+ pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
+ json_object_int_add(json_row,
+ "bsmDroppedInvalidScopeZone",
+ pim_ifp->pim_ifstat_bsm_invalid_sz);
+ json_object_object_add(json, ifp->name, json_row);
+ }
+ vty_out(vty, "\n");
+ }
+
+ if (uj)
+ vty_json(vty, json);
+}
+
+void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
+ pim_sgaddr *sg, json_object *json)
+{
+ struct pim_upstream *up;
+ time_t now;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (!json)
+ vty_out(vty,
+ "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
+
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ char uptime[10];
+ char join_timer[10];
+ char rs_timer[10];
+ char ka_timer[10];
+ char msdp_reg_timer[10];
+ char state_str[PIM_REG_STATE_STR_LEN];
+
+ if (!pim_sgaddr_match(up->sg, *sg))
+ continue;
+
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - up->state_transition);
+ pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
+ up->t_join_timer);
+
+ /*
+ * If the upstream is not dummy and it has a J/P timer for the
+ * neighbor display that
+ */
+ if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
+ struct pim_neighbor *nbr;
+
+ nbr = pim_neighbor_find_prefix(
+ up->rpf.source_nexthop.interface,
+ &up->rpf.rpf_addr);
+ if (nbr)
+ pim_time_timer_to_hhmmss(join_timer,
+ sizeof(join_timer),
+ nbr->jp_timer);
+ }
+
+ pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
+ up->t_rs_timer);
+ pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
+ up->t_ka_timer);
+ pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
+ up->t_msdp_reg_timer);
+
+ pim_upstream_state2brief_str(up->join_state, state_str,
+ sizeof(state_str));
+ if (up->reg_state != PIM_REG_NOINFO) {
+ char tmp_str[PIM_REG_STATE_STR_LEN];
+ char tmp[sizeof(state_str) + 1];
+
+ snprintf(tmp, sizeof(tmp), ",%s",
+ pim_reg_state2brief_str(up->reg_state, tmp_str,
+ sizeof(tmp_str)));
+ strlcat(state_str, tmp, sizeof(state_str));
+ }
+
+ if (json) {
+ char grp_str[PIM_ADDRSTRLEN];
+ char src_str[PIM_ADDRSTRLEN];
+
+ snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
+ &up->sg.grp);
+ snprintfrr(src_str, sizeof(src_str), "%pPAs",
+ &up->sg.src);
+
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(
+ json_row, "inboundInterface",
+ up->rpf.source_nexthop.interface
+ ? up->rpf.source_nexthop.interface->name
+ : "Unknown");
+
+ /*
+ * The RPF address we use is slightly different
+ * based upon what we are looking up.
+ * If we have a S, list that unless
+ * we are the FHR, else we just put
+ * the RP as the rpfAddress
+ */
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR ||
+ pim_addr_is_any(up->sg.src)) {
+ struct pim_rpf *rpg;
+
+ rpg = RP(pim, up->sg.grp);
+ json_object_string_addf(json_row, "rpfAddress",
+ "%pFX", &rpg->rpf_addr);
+ } else {
+ json_object_string_add(json_row, "rpfAddress",
+ src_str);
+ }
+
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "state", state_str);
+ json_object_string_add(
+ json_row, "joinState",
+ pim_upstream_state2str(up->join_state));
+ json_object_string_add(
+ json_row, "regState",
+ pim_reg_state2str(up->reg_state, state_str,
+ sizeof(state_str)));
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "joinTimer",
+ join_timer);
+ json_object_string_add(json_row, "resetTimer",
+ rs_timer);
+ json_object_string_add(json_row, "keepaliveTimer",
+ ka_timer);
+ json_object_string_add(json_row, "msdpRegTimer",
+ msdp_reg_timer);
+ json_object_int_add(json_row, "refCount",
+ up->ref_count);
+ json_object_int_add(json_row, "sptBit", up->sptbit);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty,
+ "%-16s%-15pPAs %-15pPAs %-11s %-8s %-9s %-9s %-9s %6d\n",
+ up->rpf.source_nexthop.interface
+ ? up->rpf.source_nexthop.interface->name
+ : "Unknown",
+ &up->sg.src, &up->sg.grp, state_str, uptime,
+ join_timer, rs_timer, ka_timer, up->ref_count);
+ }
+ }
+}
+
+static void pim_show_join_desired_helper(struct pim_instance *pim,
+ struct vty *vty,
+ struct pim_upstream *up,
+ json_object *json, bool uj)
+{
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ char grp_str[PIM_ADDRSTRLEN];
+ char src_str[PIM_ADDRSTRLEN];
+
+ snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
+ snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
+
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+
+ if (pim_upstream_evaluate_join_desired(pim, up))
+ json_object_boolean_true_add(json_row,
+ "evaluateJoinDesired");
+
+ json_object_object_add(json_group, src_str, json_row);
+
+ } else {
+ vty_out(vty, "%-15pPAs %-15pPAs %-6s\n", &up->sg.src,
+ &up->sg.grp,
+ pim_upstream_evaluate_join_desired(pim, up) ? "yes"
+ : "no");
+ }
+}
+
+void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, bool uj)
+{
+ struct pim_upstream *up;
+
+ json_object *json = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty, "Source Group EvalJD\n");
+
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ /* scan all interfaces */
+ pim_show_join_desired_helper(pim, vty, up, json, uj);
+ }
+
+ if (uj)
+ vty_json(vty, json);
+}
+
+void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
+{
+ struct pim_upstream *up;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Source Group RpfIface RibNextHop RpfAddress \n");
+
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ char rpf_nexthop_str[PREFIX_STRLEN];
+ char rpf_addr_str[PREFIX_STRLEN];
+ struct pim_rpf *rpf;
+ const char *rpf_ifname;
+
+ rpf = &up->rpf;
+
+ pim_addr_dump("<nexthop?>",
+ &rpf->source_nexthop.mrib_nexthop_addr,
+ rpf_nexthop_str, sizeof(rpf_nexthop_str));
+ pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
+ sizeof(rpf_addr_str));
+
+ rpf_ifname =
+ rpf->source_nexthop.interface ? rpf->source_nexthop
+ .interface->name
+ : "<ifname?>";
+
+ if (uj) {
+ char grp_str[PIM_ADDRSTRLEN];
+ char src_str[PIM_ADDRSTRLEN];
+
+ snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
+ &up->sg.grp);
+ snprintfrr(src_str, sizeof(src_str), "%pPAs",
+ &up->sg.src);
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rpfInterface",
+ rpf_ifname);
+ json_object_string_add(json_row, "ribNexthop",
+ rpf_nexthop_str);
+ json_object_string_add(json_row, "rpfAddress",
+ rpf_addr_str);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "%-15pPAs %-15pPAs %-16s %-15s %-15s\n",
+ &up->sg.src, &up->sg.grp, rpf_ifname,
+ rpf_nexthop_str, rpf_addr_str);
+ }
+ }
+
+ if (uj)
+ vty_json(vty, json);
+}
+
+static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
+ struct pim_ifchannel *ch, json_object *json,
+ time_t now)
+{
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
+ json_object *json_grp = NULL;
+ pim_addr ifaddr;
+ char uptime[10];
+ char expire[10];
+ char prune[10];
+
+ ifaddr = pim_ifp->primary_address;
+
+ pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
+ pim_time_timer_to_mmss(expire, sizeof(expire),
+ ch->t_ifjoin_expiry_timer);
+ pim_time_timer_to_mmss(prune, sizeof(prune),
+ ch->t_ifjoin_prune_pending_timer);
+
+ if (json) {
+ char ch_grp_str[PIM_ADDRSTRLEN];
+
+ json_object_object_get_ex(json, ch->interface->name,
+ &json_iface);
+
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface, ch->interface);
+ json_object_object_add(json, ch->interface->name,
+ json_iface);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_addf(json_row, "source", "%pPAs",
+ &ch->sg.src);
+ json_object_string_addf(json_row, "group", "%pPAs",
+ &ch->sg.grp);
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "expire", expire);
+ json_object_string_add(json_row, "prune", prune);
+ json_object_string_add(
+ json_row, "channelJoinName",
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
+ if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) {
+#if CONFDATE > 20230131
+ CPP_NOTICE(
+ "Remove JSON object commands with keys starting with capital")
+#endif
+ json_object_int_add(json_row, "SGRpt", 1);
+ json_object_int_add(json_row, "sgRpt", 1);
+ }
+ if (PIM_IF_FLAG_TEST_PROTO_PIM(ch->flags))
+ json_object_int_add(json_row, "protocolPim", 1);
+ if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch->flags))
+ json_object_int_add(json_row, "protocolIgmp", 1);
+ snprintfrr(ch_grp_str, sizeof(ch_grp_str), "%pPAs",
+ &ch->sg.grp);
+ json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
+ if (!json_grp) {
+ json_grp = json_object_new_object();
+ json_object_object_addf(json_grp, json_row, "%pPAs",
+ &ch->sg.src);
+ json_object_object_addf(json_iface, json_grp, "%pPAs",
+ &ch->sg.grp);
+ } else
+ json_object_object_addf(json_grp, json_row, "%pPAs",
+ &ch->sg.src);
+ } else {
+ vty_out(vty,
+ "%-16s %-15pPAs %-15pPAs %-15pPAs %-10s %8s %-6s %5s\n",
+ ch->interface->name, &ifaddr, &ch->sg.src, &ch->sg.grp,
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
+ uptime, expire, prune);
+ }
+}
+
+void pim_show_join(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
+ json_object *json)
+{
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct interface *ifp;
+ time_t now;
+
+ now = pim_time_monotonic_sec();
+
+ if (!json)
+ vty_out(vty,
+ "Interface Address Source Group State Uptime Expire Prune\n");
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ continue;
+
+ RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
+ if (!pim_sgaddr_match(ch->sg, *sg))
+ continue;
+
+ pim_show_join_helper(vty, pim_ifp, ch, json, now);
+ } /* scan interface channels */
+ }
+}
+
+static void pim_show_jp_agg_helper(struct vty *vty, struct interface *ifp,
+ struct pim_neighbor *neigh,
+ struct pim_upstream *up, int is_join)
+{
+ vty_out(vty, "%-16s %-15pPAs %-15pPAs %-15pPAs %5s\n", ifp->name,
+ &neigh->source_addr, &up->sg.src, &up->sg.grp,
+ is_join ? "J" : "P");
+}
+
+void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
+{
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct listnode *n_node;
+ struct pim_neighbor *neigh;
+ struct listnode *jag_node;
+ struct pim_jp_agg_group *jag;
+ struct listnode *js_node;
+ struct pim_jp_sources *js;
+
+ vty_out(vty,
+ "Interface RPF Nbr Source Group State\n");
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, n_node,
+ neigh)) {
+ for (ALL_LIST_ELEMENTS_RO(neigh->upstream_jp_agg,
+ jag_node, jag)) {
+ for (ALL_LIST_ELEMENTS_RO(jag->sources, js_node,
+ js)) {
+ pim_show_jp_agg_helper(vty, ifp, neigh,
+ js->up,
+ js->is_join);
+ }
+ }
+ }
+ }
+}
+
+static void pim_show_membership_helper(struct vty *vty,
+ struct pim_interface *pim_ifp,
+ struct pim_ifchannel *ch,
+ struct json_object *json)
+{
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
+
+ json_object_object_get_ex(json, ch->interface->name, &json_iface);
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface, ch->interface);
+ json_object_object_add(json, ch->interface->name, json_iface);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_addf(json_row, "source", "%pPAs", &ch->sg.src);
+ json_object_string_addf(json_row, "group", "%pPAs", &ch->sg.grp);
+ json_object_string_add(json_row, "localMembership",
+ ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
+ ? "NOINFO"
+ : "INCLUDE");
+ json_object_object_addf(json_iface, json_row, "%pPAs", &ch->sg.grp);
+}
+
+void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
+{
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct interface *ifp;
+ enum json_type type;
+ json_object *json = NULL;
+ json_object *json_tmp = NULL;
+
+ json = json_object_new_object();
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ continue;
+
+ RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
+ pim_show_membership_helper(vty, pim_ifp, ch, json);
+ } /* scan interface channels */
+ }
+
+ if (uj) {
+ vty_json(vty, json);
+ } else {
+ vty_out(vty,
+ "Interface Address Source Group Membership\n");
+
+ /*
+ * Example of the json data we are traversing
+ *
+ * {
+ * "swp3":{
+ * "name":"swp3",
+ * "state":"up",
+ * "address":"10.1.20.1",
+ * "index":5,
+ * "flagMulticast":true,
+ * "flagBroadcast":true,
+ * "lanDelayEnabled":true,
+ * "226.10.10.10":{
+ * "source":"*",
+ * "group":"226.10.10.10",
+ * "localMembership":"INCLUDE"
+ * }
+ * }
+ * }
+ */
+
+ /* foreach interface */
+ json_object_object_foreach(json, key, val)
+ {
+
+ /* Find all of the keys where the val is an object. In
+ * the example
+ * above the only one is 226.10.10.10
+ */
+ json_object_object_foreach(val, if_field_key,
+ if_field_val)
+ {
+ type = json_object_get_type(if_field_val);
+
+ if (type == json_type_object) {
+ vty_out(vty, "%-16s ", key);
+
+ json_object_object_get_ex(
+ val, "address", &json_tmp);
+ vty_out(vty, "%-15s ",
+ json_object_get_string(
+ json_tmp));
+
+ json_object_object_get_ex(if_field_val,
+ "source",
+ &json_tmp);
+ vty_out(vty, "%-15s ",
+ json_object_get_string(
+ json_tmp));
+
+ /* Group */
+ vty_out(vty, "%-15s ", if_field_key);
+
+ json_object_object_get_ex(
+ if_field_val, "localMembership",
+ &json_tmp);
+ vty_out(vty, "%-10s\n",
+ json_object_get_string(
+ json_tmp));
+ }
+ }
+ }
+ json_object_free(json);
+ }
+}
+
+static void pim_show_channel_helper(struct pim_instance *pim, struct vty *vty,
+ struct pim_interface *pim_ifp,
+ struct pim_ifchannel *ch, json_object *json,
+ bool uj)
+{
+ struct pim_upstream *up = ch->upstream;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ char grp_str[PIM_ADDRSTRLEN];
+
+ snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "interface",
+ ch->interface->name);
+ json_object_string_addf(json_row, "source", "%pPAs",
+ &up->sg.src);
+ json_object_string_addf(json_row, "group", "%pPAs",
+ &up->sg.grp);
+
+ if (pim_macro_ch_lost_assert(ch))
+ json_object_boolean_true_add(json_row, "lostAssert");
+
+ if (pim_macro_chisin_joins(ch))
+ json_object_boolean_true_add(json_row, "joins");
+
+ if (pim_macro_chisin_pim_include(ch))
+ json_object_boolean_true_add(json_row, "pimInclude");
+
+ if (pim_upstream_evaluate_join_desired(pim, up))
+ json_object_boolean_true_add(json_row,
+ "evaluateJoinDesired");
+
+ json_object_object_addf(json_group, json_row, "%pPAs",
+ &up->sg.src);
+
+ } else {
+ vty_out(vty,
+ "%-16s %-15pPAs %-15pPAs %-10s %-5s %-10s %-11s %-6s\n",
+ ch->interface->name, &up->sg.src, &up->sg.grp,
+ pim_macro_ch_lost_assert(ch) ? "yes" : "no",
+ pim_macro_chisin_joins(ch) ? "yes" : "no",
+ pim_macro_chisin_pim_include(ch) ? "yes" : "no",
+ PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
+ ? "yes"
+ : "no",
+ pim_upstream_evaluate_join_desired(pim, up) ? "yes"
+ : "no");
+ }
+}
+
+void pim_show_channel(struct pim_instance *pim, struct vty *vty, bool uj)
+{
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct interface *ifp;
+
+ json_object *json = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
+
+ /* scan per-interface (S,G) state */
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ continue;
+
+
+ RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
+ /* scan all interfaces */
+ pim_show_channel_helper(pim, vty, pim_ifp, ch, json,
+ uj);
+ }
+ }
+
+ if (uj)
+ vty_json(vty, json);
+}
+
+void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, bool mlag,
+ json_object *json)
+{
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_upstream *up;
+ int fhr = 0;
+ int pim_nbrs = 0;
+ int pim_ifchannels = 0;
+ bool uj = true;
+ json_object *json_row = NULL;
+ json_object *json_tmp;
+
+ if (!json) {
+ uj = false;
+ json = json_object_new_object();
+ }
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (mlag == true && pim_ifp->activeactive == false)
+ continue;
+
+ pim_nbrs = pim_ifp->pim_neighbor_list->count;
+ pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
+ fhr = 0;
+
+ frr_each (rb_pim_upstream, &pim->upstream_head, up)
+ if (ifp == up->rpf.source_nexthop.interface)
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
+ fhr++;
+
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
+ json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
+ json_object_int_add(json_row, "firstHopRouterCount", fhr);
+ json_object_string_addf(json_row, "pimDesignatedRouter",
+ "%pPAs", &pim_ifp->pim_dr_addr);
+
+ if (pim_addr_cmp(pim_ifp->pim_dr_addr,
+ pim_ifp->primary_address))
+ json_object_boolean_true_add(
+ json_row, "pimDesignatedRouterLocal");
+
+ json_object_object_add(json, ifp->name, json_row);
+ }
+
+ if (!uj) {
+ vty_out(vty,
+ "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
+
+ json_object_object_foreach(json, key, val)
+ {
+ vty_out(vty, "%-16s ", key);
+
+ json_object_object_get_ex(val, "state", &json_tmp);
+ vty_out(vty, "%5s ", json_object_get_string(json_tmp));
+
+ json_object_object_get_ex(val, "address", &json_tmp);
+ vty_out(vty, "%15s ",
+ json_object_get_string(json_tmp));
+
+ json_object_object_get_ex(val, "pimNeighbors",
+ &json_tmp);
+ vty_out(vty, "%8d ", json_object_get_int(json_tmp));
+
+ if (json_object_object_get_ex(
+ val, "pimDesignatedRouterLocal",
+ &json_tmp)) {
+ vty_out(vty, "%15s ", "local");
+ } else {
+ json_object_object_get_ex(
+ val, "pimDesignatedRouter", &json_tmp);
+ vty_out(vty, "%15s ",
+ json_object_get_string(json_tmp));
+ }
+
+ json_object_object_get_ex(val, "firstHopRouter",
+ &json_tmp);
+ vty_out(vty, "%3d ", json_object_get_int(json_tmp));
+
+ json_object_object_get_ex(val, "pimIfChannels",
+ &json_tmp);
+ vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
+ }
+ }
+}
+
+void pim_show_interfaces_single(struct pim_instance *pim, struct vty *vty,
+ const char *ifname, bool mlag,
+ json_object *json)
+{
+ pim_addr ifaddr;
+ struct interface *ifp;
+ struct listnode *neighnode;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ struct pim_upstream *up;
+ time_t now;
+ char dr_str[PIM_ADDRSTRLEN];
+ char dr_uptime[10];
+ char expire[10];
+ char grp_str[PIM_ADDRSTRLEN];
+ char hello_period[10];
+ char hello_timer[10];
+ char neigh_src_str[PIM_ADDRSTRLEN];
+ char src_str[PIM_ADDRSTRLEN];
+ char stat_uptime[10];
+ char uptime[10];
+ int found_ifname = 0;
+ int print_header;
+ json_object *json_row = NULL;
+ json_object *json_pim_neighbor = NULL;
+ json_object *json_pim_neighbors = NULL;
+ json_object *json_group = NULL;
+ json_object *json_group_source = NULL;
+ json_object *json_fhr_sources = NULL;
+ struct pim_secondary_addr *sec_addr;
+ struct listnode *sec_node;
+
+ now = pim_time_monotonic_sec();
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (mlag == true && pim_ifp->activeactive == false)
+ continue;
+
+ if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
+ continue;
+
+ found_ifname = 1;
+ ifaddr = pim_ifp->primary_address;
+ snprintfrr(dr_str, sizeof(dr_str), "%pPAs",
+ &pim_ifp->pim_dr_addr);
+ pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
+ pim_ifp->pim_dr_election_last);
+ pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
+ pim_ifp->t_pim_hello_timer);
+ pim_time_mmss(hello_period, sizeof(hello_period),
+ pim_ifp->pim_hello_period);
+ pim_time_uptime(stat_uptime, sizeof(stat_uptime),
+ now - pim_ifp->pim_ifstat_start);
+
+ if (json) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+
+ if (!pim_addr_is_any(pim_ifp->update_source)) {
+ json_object_string_addf(
+ json_row, "useSource", "%pPAs",
+ &pim_ifp->update_source);
+ }
+ if (pim_ifp->sec_addr_list) {
+ json_object *sec_list = NULL;
+
+ sec_list = json_object_new_array();
+ for (ALL_LIST_ELEMENTS_RO(
+ pim_ifp->sec_addr_list, sec_node,
+ sec_addr)) {
+ json_object_array_add(
+ sec_list,
+ json_object_new_stringf(
+ "%pFXh",
+ &sec_addr->addr));
+ }
+ json_object_object_add(json_row,
+ "secondaryAddressList",
+ sec_list);
+ }
+
+ /* PIM neighbors */
+ if (pim_ifp->pim_neighbor_list->count) {
+ json_pim_neighbors = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(
+ pim_ifp->pim_neighbor_list,
+ neighnode, neigh)) {
+ json_pim_neighbor =
+ json_object_new_object();
+ snprintfrr(neigh_src_str,
+ sizeof(neigh_src_str),
+ "%pPAs",
+ &neigh->source_addr);
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(
+ expire, sizeof(expire),
+ neigh->t_expire_timer);
+
+ json_object_string_add(
+ json_pim_neighbor, "address",
+ neigh_src_str);
+ json_object_string_add(
+ json_pim_neighbor, "upTime",
+ uptime);
+ json_object_string_add(
+ json_pim_neighbor, "holdtime",
+ expire);
+
+ json_object_object_add(
+ json_pim_neighbors,
+ neigh_src_str,
+ json_pim_neighbor);
+ }
+
+ json_object_object_add(json_row, "neighbors",
+ json_pim_neighbors);
+ }
+
+ json_object_string_add(json_row, "drAddress", dr_str);
+ json_object_int_add(json_row, "drPriority",
+ pim_ifp->pim_dr_priority);
+ json_object_string_add(json_row, "drUptime", dr_uptime);
+ json_object_int_add(json_row, "drElections",
+ pim_ifp->pim_dr_election_count);
+ json_object_int_add(json_row, "drChanges",
+ pim_ifp->pim_dr_election_changes);
+
+ /* FHR */
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ if (ifp != up->rpf.source_nexthop.interface)
+ continue;
+
+ if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
+ continue;
+
+ if (!json_fhr_sources)
+ json_fhr_sources =
+ json_object_new_object();
+
+ snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
+ &up->sg.grp);
+ snprintfrr(src_str, sizeof(src_str), "%pPAs",
+ &up->sg.src);
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - up->state_transition);
+
+ /*
+ * Does this group live in json_fhr_sources?
+ * If not create it.
+ */
+ json_object_object_get_ex(json_fhr_sources,
+ grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json_fhr_sources,
+ grp_str,
+ json_group);
+ }
+
+ json_group_source = json_object_new_object();
+ json_object_string_add(json_group_source,
+ "source", src_str);
+ json_object_string_add(json_group_source,
+ "group", grp_str);
+ json_object_string_add(json_group_source,
+ "upTime", uptime);
+ json_object_object_add(json_group, src_str,
+ json_group_source);
+ }
+
+ if (json_fhr_sources) {
+ json_object_object_add(json_row,
+ "firstHopRouter",
+ json_fhr_sources);
+ }
+
+ json_object_int_add(json_row, "helloPeriod",
+ pim_ifp->pim_hello_period);
+ json_object_int_add(json_row, "holdTime",
+ PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
+ json_object_string_add(json_row, "helloTimer",
+ hello_timer);
+ json_object_string_add(json_row, "helloStatStart",
+ stat_uptime);
+ json_object_int_add(json_row, "helloReceived",
+ pim_ifp->pim_ifstat_hello_recv);
+ json_object_int_add(json_row, "helloReceivedFailed",
+ pim_ifp->pim_ifstat_hello_recvfail);
+ json_object_int_add(json_row, "helloSend",
+ pim_ifp->pim_ifstat_hello_sent);
+ json_object_int_add(json_row, "hellosendFailed",
+ pim_ifp->pim_ifstat_hello_sendfail);
+ json_object_int_add(json_row, "helloGenerationId",
+ pim_ifp->pim_generation_id);
+
+ json_object_int_add(
+ json_row, "effectivePropagationDelay",
+ pim_if_effective_propagation_delay_msec(ifp));
+ json_object_int_add(
+ json_row, "effectiveOverrideInterval",
+ pim_if_effective_override_interval_msec(ifp));
+ json_object_int_add(
+ json_row, "joinPruneOverrideInterval",
+ pim_if_jp_override_interval_msec(ifp));
+
+ json_object_int_add(
+ json_row, "propagationDelay",
+ pim_ifp->pim_propagation_delay_msec);
+ json_object_int_add(
+ json_row, "propagationDelayHighest",
+ pim_ifp->pim_neighbors_highest_propagation_delay_msec);
+ json_object_int_add(
+ json_row, "overrideInterval",
+ pim_ifp->pim_override_interval_msec);
+ json_object_int_add(
+ json_row, "overrideIntervalHighest",
+ pim_ifp->pim_neighbors_highest_override_interval_msec);
+ if (pim_ifp->bsm_enable)
+ json_object_boolean_true_add(json_row,
+ "bsmEnabled");
+ if (pim_ifp->ucast_bsm_accept)
+ json_object_boolean_true_add(json_row,
+ "ucastBsmEnabled");
+ json_object_object_add(json, ifp->name, json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s\n", ifp->name);
+ vty_out(vty, "State : %s\n",
+ if_is_up(ifp) ? "up" : "down");
+ if (!pim_addr_is_any(pim_ifp->update_source)) {
+ vty_out(vty, "Use Source : %pPAs\n",
+ &pim_ifp->update_source);
+ }
+ if (pim_ifp->sec_addr_list) {
+ vty_out(vty, "Address : %pPAs (primary)\n",
+ &ifaddr);
+ for (ALL_LIST_ELEMENTS_RO(
+ pim_ifp->sec_addr_list, sec_node,
+ sec_addr))
+ vty_out(vty, " %pFX\n",
+ &sec_addr->addr);
+ } else {
+ vty_out(vty, "Address : %pPAs\n", &ifaddr);
+ }
+ vty_out(vty, "\n");
+
+ /* PIM neighbors */
+ print_header = 1;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
+ neighnode, neigh)) {
+
+ if (print_header) {
+ vty_out(vty, "PIM Neighbors\n");
+ vty_out(vty, "-------------\n");
+ print_header = 0;
+ }
+
+ snprintfrr(neigh_src_str, sizeof(neigh_src_str),
+ "%pPAs", &neigh->source_addr);
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire),
+ neigh->t_expire_timer);
+ vty_out(vty,
+ "%-15s : up for %s, holdtime expires in %s\n",
+ neigh_src_str, uptime, expire);
+ }
+
+ if (!print_header) {
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+ }
+
+ vty_out(vty, "Designated Router\n");
+ vty_out(vty, "-----------------\n");
+ vty_out(vty, "Address : %s\n", dr_str);
+ vty_out(vty, "Priority : %u(%d)\n",
+ pim_ifp->pim_dr_priority,
+ pim_ifp->pim_dr_num_nondrpri_neighbors);
+ vty_out(vty, "Uptime : %s\n", dr_uptime);
+ vty_out(vty, "Elections : %d\n",
+ pim_ifp->pim_dr_election_count);
+ vty_out(vty, "Changes : %d\n",
+ pim_ifp->pim_dr_election_changes);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ /* FHR */
+ print_header = 1;
+ frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+ if (!up->rpf.source_nexthop.interface)
+ continue;
+
+ if (strcmp(ifp->name,
+ up->rpf.source_nexthop
+ .interface->name) != 0)
+ continue;
+
+ if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
+ continue;
+
+ if (print_header) {
+ vty_out(vty,
+ "FHR - First Hop Router\n");
+ vty_out(vty,
+ "----------------------\n");
+ print_header = 0;
+ }
+
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - up->state_transition);
+ vty_out(vty,
+ "%pPAs : %pPAs is a source, uptime is %s\n",
+ &up->sg.grp, &up->sg.src, uptime);
+ }
+
+ if (!print_header) {
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+ }
+
+ vty_out(vty, "Hellos\n");
+ vty_out(vty, "------\n");
+ vty_out(vty, "Period : %d\n",
+ pim_ifp->pim_hello_period);
+ vty_out(vty, "HoldTime : %d\n",
+ PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
+ vty_out(vty, "Timer : %s\n", hello_timer);
+ vty_out(vty, "StatStart : %s\n", stat_uptime);
+ vty_out(vty, "Receive : %d\n",
+ pim_ifp->pim_ifstat_hello_recv);
+ vty_out(vty, "Receive Failed : %d\n",
+ pim_ifp->pim_ifstat_hello_recvfail);
+ vty_out(vty, "Send : %d\n",
+ pim_ifp->pim_ifstat_hello_sent);
+ vty_out(vty, "Send Failed : %d\n",
+ pim_ifp->pim_ifstat_hello_sendfail);
+ vty_out(vty, "Generation ID : %08x\n",
+ pim_ifp->pim_generation_id);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ pim_print_ifp_flags(vty, ifp);
+
+ vty_out(vty, "Join Prune Interval\n");
+ vty_out(vty, "-------------------\n");
+ vty_out(vty, "LAN Delay : %s\n",
+ pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
+ vty_out(vty, "Effective Propagation Delay : %d msec\n",
+ pim_if_effective_propagation_delay_msec(ifp));
+ vty_out(vty, "Effective Override Interval : %d msec\n",
+ pim_if_effective_override_interval_msec(ifp));
+ vty_out(vty, "Join Prune Override Interval : %d msec\n",
+ pim_if_jp_override_interval_msec(ifp));
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ vty_out(vty, "LAN Prune Delay\n");
+ vty_out(vty, "---------------\n");
+ vty_out(vty, "Propagation Delay : %d msec\n",
+ pim_ifp->pim_propagation_delay_msec);
+ vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
+ pim_ifp->pim_neighbors_highest_propagation_delay_msec);
+ vty_out(vty, "Override Interval : %d msec\n",
+ pim_ifp->pim_override_interval_msec);
+ vty_out(vty, "Override Interval (Highest) : %d msec\n",
+ pim_ifp->pim_neighbors_highest_override_interval_msec);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ vty_out(vty, "BSM Status\n");
+ vty_out(vty, "----------\n");
+ vty_out(vty, "Bsm Enabled : %s\n",
+ pim_ifp->bsm_enable ? "yes" : "no");
+ vty_out(vty, "Unicast Bsm Enabled : %s\n",
+ pim_ifp->ucast_bsm_accept ? "yes" : "no");
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+ }
+ }
+
+ if (!found_ifname)
+ vty_out(vty, "%% No such interface\n");
+}
+
+void ip_pim_ssm_show_group_range(struct pim_instance *pim, struct vty *vty,
+ bool uj)
+{
+ struct pim_ssm *ssm = pim->ssm_info;
+ const char *range_str =
+ ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
+
+ if (uj) {
+ json_object *json;
+
+ json = json_object_new_object();
+ json_object_string_add(json, "ssmGroups", range_str);
+ vty_json(vty, json);
+ } else
+ vty_out(vty, "SSM group range : %s\n", range_str);
+}
+
+struct pnc_cache_walk_data {
+ struct vty *vty;
+ struct pim_instance *pim;
+};
+
+static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
+{
+ struct pim_nexthop_cache *pnc = bucket->data;
+ struct pnc_cache_walk_data *cwd = arg;
+ struct vty *vty = cwd->vty;
+ struct pim_instance *pim = cwd->pim;
+ struct nexthop *nh_node = NULL;
+ ifindex_t first_ifindex;
+ struct interface *ifp = NULL;
+ char buf[PREFIX_STRLEN];
+
+ for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
+ first_ifindex = nh_node->ifindex;
+ ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
+
+ vty_out(vty, "%-15s ",
+ inet_ntop(AF_INET, &pnc->rpf.rpf_addr.u.prefix4, buf,
+ sizeof(buf)));
+ vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
+ vty_out(vty, "%pI4 ", &nh_node->gate.ipv4);
+ vty_out(vty, "\n");
+ }
+ return CMD_SUCCESS;
+}
+
+void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
+{
+ struct pnc_cache_walk_data cwd;
+
+ cwd.vty = vty;
+ cwd.pim = pim;
+ vty_out(vty, "Number of registered addresses: %lu\n",
+ pim->rpf_hash->count);
+ vty_out(vty, "Address Interface Nexthop\n");
+ vty_out(vty, "---------------------------------------------\n");
+
+ hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
+}
+
+void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
+ const char *neighbor, json_object *json)
+{
+ struct listnode *neighnode;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ time_t now;
+ int found_neighbor = 0;
+ int option_address_list;
+ int option_dr_priority;
+ int option_generation_id;
+ int option_holdtime;
+ int option_lan_prune_delay;
+ int option_t_bit;
+ char uptime[10];
+ char expire[10];
+ char neigh_src_str[PIM_ADDRSTRLEN];
+
+ json_object *json_ifp = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
+ neigh)) {
+ snprintfrr(neigh_src_str, sizeof(neigh_src_str),
+ "%pPAs", &neigh->source_addr);
+
+ /*
+ * The user can specify either the interface name or the
+ * PIM neighbor IP.
+ * If this pim_ifp matches neither then skip.
+ */
+ if (strcmp(neighbor, "detail") &&
+ strcmp(neighbor, ifp->name) &&
+ strcmp(neighbor, neigh_src_str))
+ continue;
+
+ found_neighbor = 1;
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire),
+ neigh->t_expire_timer);
+
+ option_address_list = 0;
+ option_dr_priority = 0;
+ option_generation_id = 0;
+ option_holdtime = 0;
+ option_lan_prune_delay = 0;
+ option_t_bit = 0;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_ADDRESS_LIST))
+ option_address_list = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_DR_PRIORITY))
+ option_dr_priority = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_GENERATION_ID))
+ option_generation_id = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_HOLDTIME))
+ option_holdtime = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY))
+ option_lan_prune_delay = 1;
+
+ if (PIM_OPTION_IS_SET(
+ neigh->hello_options,
+ PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
+ option_t_bit = 1;
+
+ if (json) {
+
+ /* Does this ifp live in json? If not create it
+ */
+ json_object_object_get_ex(json, ifp->name,
+ &json_ifp);
+
+ if (!json_ifp) {
+ json_ifp = json_object_new_object();
+ json_object_pim_ifp_add(json_ifp, ifp);
+ json_object_object_add(json, ifp->name,
+ json_ifp);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "interface",
+ ifp->name);
+ json_object_string_add(json_row, "address",
+ neigh_src_str);
+ json_object_string_add(json_row, "upTime",
+ uptime);
+ json_object_string_add(json_row, "holdtime",
+ expire);
+ json_object_int_add(json_row, "drPriority",
+ neigh->dr_priority);
+ json_object_int_add(json_row, "generationId",
+ neigh->generation_id);
+
+ if (option_address_list)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionAddressList");
+
+ if (option_dr_priority)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionDrPriority");
+
+ if (option_generation_id)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionGenerationId");
+
+ if (option_holdtime)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionHoldtime");
+
+ if (option_lan_prune_delay)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionLanPruneDelay");
+
+ if (option_t_bit)
+ json_object_boolean_true_add(
+ json_row, "helloOptionTBit");
+
+ json_object_object_add(json_ifp, neigh_src_str,
+ json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s\n", ifp->name);
+ vty_out(vty, "Neighbor : %s\n", neigh_src_str);
+ vty_out(vty,
+ " Uptime : %s\n",
+ uptime);
+ vty_out(vty,
+ " Holdtime : %s\n",
+ expire);
+ vty_out(vty,
+ " DR Priority : %d\n",
+ neigh->dr_priority);
+ vty_out(vty,
+ " Generation ID : %08x\n",
+ neigh->generation_id);
+ vty_out(vty,
+ " Override Interval (msec) : %d\n",
+ neigh->override_interval_msec);
+ vty_out(vty,
+ " Propagation Delay (msec) : %d\n",
+ neigh->propagation_delay_msec);
+ vty_out(vty,
+ " Hello Option - Address List : %s\n",
+ option_address_list ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - DR Priority : %s\n",
+ option_dr_priority ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - Generation ID : %s\n",
+ option_generation_id ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - Holdtime : %s\n",
+ option_holdtime ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - LAN Prune Delay : %s\n",
+ option_lan_prune_delay ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - T-bit : %s\n",
+ option_t_bit ? "yes" : "no");
+ bfd_sess_show(vty, json_ifp,
+ neigh->bfd_session);
+ vty_out(vty, "\n");
+ }
+ }
+ }
+
+ if (!found_neighbor)
+ vty_out(vty, "%% No such interface or neighbor\n");
+}
+
+void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
+ json_object *json)
+{
+ struct listnode *neighnode;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ time_t now;
+ char uptime[10];
+ char expire[10];
+ char neigh_src_str[PIM_ADDRSTRLEN];
+ json_object *json_ifp_rows = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (!json) {
+ vty_out(vty,
+ "Interface Neighbor Uptime Holdtime DR Pri\n");
+ }
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ if (json)
+ json_ifp_rows = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
+ neigh)) {
+ snprintfrr(neigh_src_str, sizeof(neigh_src_str),
+ "%pPAs", &neigh->source_addr);
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire),
+ neigh->t_expire_timer);
+
+ if (json) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "interface",
+ ifp->name);
+ json_object_string_add(json_row, "neighbor",
+ neigh_src_str);
+ json_object_string_add(json_row, "upTime",
+ uptime);
+ json_object_string_add(json_row, "holdTime",
+ expire);
+ json_object_int_add(json_row, "holdTimeMax",
+ neigh->holdtime);
+ json_object_int_add(json_row, "drPriority",
+ neigh->dr_priority);
+ json_object_object_add(json_ifp_rows,
+ neigh_src_str, json_row);
+
+ } else {
+ vty_out(vty, "%-16s %15s %8s %8s %6d\n",
+ ifp->name, neigh_src_str, uptime,
+ expire, neigh->dr_priority);
+ }
+ }
+
+ if (json) {
+ json_object_object_add(json, ifp->name, json_ifp_rows);
+ json_ifp_rows = NULL;
+ }
+ }
+}
+
+int gm_process_query_max_response_time_cmd(struct vty *vty,
+ const char *qmrt_str)
+{
+ const struct lyd_node *pim_enable_dnode;
+
+ pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+
+ if (!pim_enable_dnode) {
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
+ } else {
+ if (!yang_dnode_get_bool(pim_enable_dnode, "."))
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
+ "true");
+ }
+
+ nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
+ qmrt_str);
+ return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
+int gm_process_no_query_max_response_time_cmd(struct vty *vty)
+{
+ nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
+ NULL);
+ return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
+int gm_process_last_member_query_count_cmd(struct vty *vty,
+ const char *lmqc_str)
+{
+ const struct lyd_node *pim_enable_dnode;
+
+ pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+ if (!pim_enable_dnode) {
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
+ } else {
+ if (!yang_dnode_get_bool(pim_enable_dnode, "."))
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
+ "true");
+ }
+
+ nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_MODIFY,
+ lmqc_str);
+ return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
+int gm_process_no_last_member_query_count_cmd(struct vty *vty)
+{
+ nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_DESTROY,
+ NULL);
+ return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
+int gm_process_last_member_query_interval_cmd(struct vty *vty,
+ const char *lmqi_str)
+{
+ const struct lyd_node *pim_enable_dnode;
+
+ pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
+ FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+ if (!pim_enable_dnode) {
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
+ } else {
+ if (!yang_dnode_get_bool(pim_enable_dnode, "."))
+ nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
+ "true");
+ }
+
+ nb_cli_enqueue_change(vty, "./last-member-query-interval", NB_OP_MODIFY,
+ lmqi_str);
+ return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
+int gm_process_no_last_member_query_interval_cmd(struct vty *vty)
+{
+ nb_cli_enqueue_change(vty, "./last-member-query-interval",
+ NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
+
+int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
+ const char *src_str)
+{
+ const char *vrfname;
+ char ssmpingd_ip_xpath[XPATH_MAXLEN];
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
+ FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
+ FRR_PIM_AF_XPATH_VAL);
+ strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
+ sizeof(ssmpingd_ip_xpath));
+
+ nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, operation, src_str);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h
index b7e6b6ac80..f5e0ef5878 100644
--- a/pimd/pim_cmd_common.h
+++ b/pimd/pim_cmd_common.h
@@ -58,5 +58,67 @@ int pim_process_ip_mroute_cmd(struct vty *vty, const char *interface,
const char *group_str, const char *source_str);
int pim_process_no_ip_mroute_cmd(struct vty *vty, const char *interface,
const char *group_str, const char *src_str);
+void json_object_pim_upstream_add(json_object *json, struct pim_upstream *up);
+void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json);
+void pim_show_neighbors_secondary(struct pim_instance *pim, struct vty *vty);
+void pim_show_state(struct pim_instance *pim, struct vty *vty,
+ const char *src_or_group, const char *group,
+ json_object *json);
+void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
+ const char *ifname, bool uj);
+void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
+ pim_sgaddr *sg, json_object *json);
+void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, bool uj);
+void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj);
+void pim_show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
+ time_t now, json_object *json);
+bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match);
+void json_object_pim_ifp_add(struct json_object *json, struct interface *ifp);
+void pim_print_ifp_flags(struct vty *vty, struct interface *ifp);
+void json_object_pim_upstream_add(json_object *json, struct pim_upstream *up);
+void pim_show_join(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
+ json_object *json);
+void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty);
+void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj);
+void pim_show_channel(struct pim_instance *pim, struct vty *vty, bool uj);
+void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, bool mlag,
+ json_object *json);
+void pim_show_interfaces_single(struct pim_instance *pim, struct vty *vty,
+ const char *ifname, bool mlag,
+ json_object *json);
+void ip_pim_ssm_show_group_range(struct pim_instance *pim, struct vty *vty,
+ bool uj);
+void pim_show_nexthop(struct pim_instance *pim, struct vty *vty);
+void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
+ const char *neighbor, json_object *json);
+void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
+ json_object *json);
+int gm_process_query_max_response_time_cmd(struct vty *vty,
+ const char *qmrt_str);
+int gm_process_no_query_max_response_time_cmd(struct vty *vty);
+int gm_process_last_member_query_count_cmd(struct vty *vty,
+ const char *lmqc_str);
+int gm_process_no_last_member_query_count_cmd(struct vty *vty);
+int gm_process_last_member_query_interval_cmd(struct vty *vty,
+ const char *lmqi_str);
+int gm_process_no_last_member_query_interval_cmd(struct vty *vty);
+int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
+ const char *src_str);
+/*
+ * Special Macro to allow us to get the correct pim_instance
+ */
+#define PIM_DECLVAR_CONTEXT(A, B) \
+ struct vrf *A = VTY_GET_CONTEXT(vrf); \
+ struct pim_instance *B = \
+ (vrf) ? vrf->info : pim_get_pim_instance(VRF_DEFAULT); \
+ vrf = (vrf) ? vrf : pim->vrf
+/*
+ * Special Macro to allow us to get the correct pim_instance;
+ */
+#define PIM_DECLVAR_CONTEXT(A, B) \
+ struct vrf *A = VTY_GET_CONTEXT(vrf); \
+ struct pim_instance *B = \
+ (vrf) ? vrf->info : pim_get_pim_instance(VRF_DEFAULT); \
+ vrf = (vrf) ? vrf : pim->vrf
#endif /* PIM_CMD_COMMON_H */
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 4470d05663..f75293fdb7 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -123,7 +123,6 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
- pim_ifp->options = 0;
pim_ifp->pim = ifp->vrf->info;
pim_ifp->mroute_vif_index = -1;
@@ -150,13 +149,9 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
assert(pim_ifp->gm_query_max_response_time_dsec <
pim_ifp->gm_default_query_interval);
- if (pim)
- PIM_IF_DO_PIM(pim_ifp->options);
+ pim_ifp->pim_enable = pim;
#if PIM_IPV == 4
- if (igmp)
- PIM_IF_DO_IGMP(pim_ifp->options);
-
- PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
+ pim_ifp->igmp_enable = igmp;
#endif
pim_ifp->gm_join_list = NULL;
@@ -317,7 +312,7 @@ static int detect_primary_address_change(struct interface *ifp,
if (changed) {
/* Before updating pim_ifp send Hello time with 0 hold time */
- if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+ if (pim_ifp->pim_enable) {
pim_hello_send(ifp, 0 /* zero-sec holdtime */);
}
pim_ifp->primary_address = new_prim_addr;
@@ -462,7 +457,7 @@ static void detect_address_change(struct interface *ifp, int force_prim_as_any,
if (changed) {
- if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+ if (!pim_ifp->pim_enable) {
return;
}
@@ -543,7 +538,7 @@ void pim_if_addr_add(struct connected *ifc)
#if PIM_IPV == 4
struct in_addr ifaddr = ifc->address->u.prefix4;
- if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ if (pim_ifp->igmp_enable) {
struct gm_sock *igmp;
/* lookup IGMP socket */
@@ -610,7 +605,7 @@ void pim_if_addr_add(struct connected *ifc)
} /* igmp mtrace only */
#endif
- if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+ if (pim_ifp->pim_enable) {
if (!pim_addr_is_any(pim_ifp->primary_address)) {
@@ -802,7 +797,7 @@ void pim_if_addr_add_all(struct interface *ifp)
}
if (!v4_addrs && v6_addrs && !if_is_loopback(ifp)) {
- if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+ if (pim_ifp->pim_enable) {
/* Interface has a valid primary address ? */
if (!pim_addr_is_any(pim_ifp->primary_address)) {
@@ -1211,7 +1206,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp)
assert(pim_ifp);
/* join suppression disabled ? */
- if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options))
+ if (pim_ifp->pim_can_disable_join_suppression)
return 0;
/* t_suppressed = t_periodic * rand(1.1, 1.4) */
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index bab73eae86..3535db70a8 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -34,31 +34,8 @@
#include "bfd.h"
#include "pim_str.h"
-#define PIM_IF_MASK_PIM (1 << 0)
-#define PIM_IF_MASK_IGMP (1 << 1)
-#define PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS (1 << 2)
-#define PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION (1 << 3)
-
#define PIM_IF_IS_DELETED(ifp) ((ifp)->ifindex == IFINDEX_INTERNAL)
-#define PIM_IF_TEST_PIM(options) (PIM_IF_MASK_PIM & (options))
-#define PIM_IF_TEST_IGMP(options) (PIM_IF_MASK_IGMP & (options))
-#define PIM_IF_TEST_IGMP_LISTEN_ALLROUTERS(options) (PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS & (options))
-#define PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(options) \
- (PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION & (options))
-
-#define PIM_IF_DO_PIM(options) ((options) |= PIM_IF_MASK_PIM)
-#define PIM_IF_DO_IGMP(options) ((options) |= PIM_IF_MASK_IGMP)
-#define PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(options) ((options) |= PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS)
-#define PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPPRESSION(options) \
- ((options) |= PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION)
-
-#define PIM_IF_DONT_PIM(options) ((options) &= ~PIM_IF_MASK_PIM)
-#define PIM_IF_DONT_IGMP(options) ((options) &= ~PIM_IF_MASK_IGMP)
-#define PIM_IF_DONT_IGMP_LISTEN_ALLROUTERS(options) ((options) &= ~PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS)
-#define PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPPRESSION(options) \
- ((options) &= ~PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION)
-
#define PIM_I_am_DR(pim_ifp) \
!pim_addr_cmp((pim_ifp)->pim_dr_addr, (pim_ifp)->primary_address)
#define PIM_I_am_DualActive(pim_ifp) (pim_ifp)->activeactive == true
@@ -93,7 +70,11 @@ struct pim_secondary_addr {
};
struct pim_interface {
- uint32_t options; /* bit vector */
+ bool pim_enable : 1;
+ bool pim_can_disable_join_suppression : 1;
+
+ bool igmp_enable : 1;
+
ifindex_t mroute_vif_index;
struct pim_instance *pim;
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index f9fb8cf094..54cd824f9e 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -1155,7 +1155,7 @@ int pim_ifchannel_local_membership_add(struct interface *ifp, pim_sgaddr *sg,
return 0;
}
- if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+ if (!pim_ifp->pim_enable) {
if (PIM_DEBUG_EVENTS)
zlog_debug("%s:%pSG PIM is not configured on this interface %s",
__func__, sg, ifp->name);
@@ -1249,7 +1249,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, pim_sgaddr *sg)
pim_ifp = ifp->info;
if (!pim_ifp)
return;
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ if (!pim_ifp->pim_enable)
return;
orig = ch = pim_ifchannel_find(ifp, sg);
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 57c4cdc470..8f81dbc23a 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -72,42 +72,42 @@ void igmp_anysource_forward_stop(struct gm_group *group)
}
static void igmp_source_forward_reevaluate_one(struct pim_instance *pim,
- struct gm_source *source)
+ struct gm_source *source,
+ int is_grp_ssm)
{
pim_sgaddr sg;
struct gm_group *group = source->source_group;
- struct pim_ifchannel *ch;
-
- if ((source->source_addr.s_addr != INADDR_ANY) ||
- !IGMP_SOURCE_TEST_FORWARDING(source->source_flags))
- return;
memset(&sg, 0, sizeof(sg));
sg.src = source->source_addr;
sg.grp = group->group_addr;
- ch = pim_ifchannel_find(group->interface, &sg);
- if (pim_is_grp_ssm(pim, group->group_addr)) {
- /* If SSM group withdraw local membership */
- if (ch &&
- (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE)) {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug(
- "local membership del for %pSG as G is now SSM",
- &sg);
- pim_ifchannel_local_membership_del(group->interface,
- &sg);
+ /** if there is no PIM state **/
+ if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
+ if (pim_addr_is_any(source->source_addr)) {
+ if (is_grp_ssm) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "local membership del for %pSG as G is now SSM",
+ &sg);
+ igmp_source_forward_stop(source);
+ }
+ } else {
+ if (!is_grp_ssm) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "local membership del for %pSG as G is now ASM",
+ &sg);
+ igmp_source_forward_stop(source);
+ }
}
} else {
- /* If ASM group add local membership */
- if (!ch ||
- (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO)) {
+ if (!pim_addr_is_any(source->source_addr) && (is_grp_ssm)) {
if (PIM_DEBUG_PIM_EVENTS)
zlog_debug(
- "local membership add for %pSG as G is now ASM",
+ "local membership add for %pSG as G is now SSM",
&sg);
- pim_ifchannel_local_membership_add(
- group->interface, &sg, false /*is_vxlan*/);
+ igmp_source_forward_start(pim, source);
}
}
}
@@ -118,7 +118,7 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp = ifp->info;
- struct listnode *grpnode;
+ struct listnode *grpnode, *grp_nextnode;
struct gm_group *grp;
struct pim_ifchannel *ch, *ch_temp;
@@ -126,10 +126,11 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
continue;
/* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
- grp)) {
+ for (ALL_LIST_ELEMENTS(pim_ifp->gm_group_list, grpnode,
+ grp_nextnode, grp)) {
struct listnode *srcnode;
struct gm_source *src;
+ int is_grp_ssm;
/*
* RFC 4604
@@ -139,16 +140,16 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
* MODE_IS_EXCLUDE and CHANGE_TO_EXCLUDE_MODE
* requests in the SSM range.
*/
- if (pim_is_grp_ssm(pim, grp->group_addr) &&
- grp->group_filtermode_isexcl) {
+ is_grp_ssm = pim_is_grp_ssm(pim, grp->group_addr);
+ if (is_grp_ssm && grp->group_filtermode_isexcl) {
igmp_group_delete(grp);
} else {
/* scan group sources */
for (ALL_LIST_ELEMENTS_RO(
grp->group_source_list, srcnode,
src)) {
- igmp_source_forward_reevaluate_one(pim,
- src);
+ igmp_source_forward_reevaluate_one(
+ pim, src, is_grp_ssm);
} /* scan group sources */
}
} /* scan igmp groups */
@@ -179,6 +180,18 @@ void igmp_source_forward_start(struct pim_instance *pim,
IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
}
+ /*
+ * PIM state should not be allowed for ASM group with valid source
+ * address.
+ */
+ if ((!pim_is_grp_ssm(pim, source->source_group->group_addr)) &&
+ !pim_addr_is_any(source->source_addr)) {
+ zlog_warn(
+ "%s: (S,G)=%pSG ASM range having source address, not allowed to create PIM state",
+ __func__, &sg);
+ return;
+ }
+
/* Prevent IGMP interface from installing multicast route multiple
times */
if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
@@ -193,8 +206,8 @@ void igmp_source_forward_start(struct pim_instance *pim,
}
/*
- igmp_source_forward_stop: stop fowarding, but keep the source
- igmp_source_delete: stop fowarding, and delete the source
+ igmp_source_forward_stop: stop forwarding, but keep the source
+ igmp_source_delete: stop forwarding, and delete the source
*/
void igmp_source_forward_stop(struct gm_source *source)
{
@@ -229,8 +242,7 @@ void igmp_source_forward_stop(struct gm_source *source)
/* This socket is used for TXing IGMP packets only, IGMP RX happens
* in pim_mroute_msg()
*/
-static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
- uint32_t pim_options)
+static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp)
{
int fd;
int join = 0;
@@ -242,17 +254,14 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
if (fd < 0)
return -1;
- if (PIM_IF_TEST_IGMP_LISTEN_ALLROUTERS(pim_options)) {
- if (inet_aton(PIM_ALL_ROUTERS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex,
- pim_ifp))
- ++join;
- } else {
- zlog_warn(
- "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s",
- __FILE__, __func__, fd, &ifaddr,
- PIM_ALL_ROUTERS, errno, safe_strerror(errno));
- }
+ if (inet_aton(PIM_ALL_ROUTERS, &group)) {
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex, pim_ifp))
+ ++join;
+ } else {
+ zlog_warn(
+ "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s",
+ __FILE__, __func__, fd, &ifaddr, PIM_ALL_ROUTERS, errno,
+ safe_strerror(errno));
}
/*
@@ -1244,14 +1253,11 @@ struct gm_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
struct in_addr ifaddr, struct interface *ifp,
bool mtrace_only)
{
- struct pim_interface *pim_ifp;
struct gm_sock *igmp;
struct sockaddr_in sin;
int fd;
- pim_ifp = ifp->info;
-
- fd = igmp_sock_open(ifaddr, ifp, pim_ifp->options);
+ fd = igmp_sock_open(ifaddr, ifp);
if (fd < 0) {
zlog_warn("Could not open IGMP socket for %pI4 on %s",
&ifaddr, ifp->name);
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index b6114f9ead..fb9b385338 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -340,8 +340,8 @@ static void source_channel_oil_detach(struct gm_source *source)
}
/*
- igmp_source_delete: stop fowarding, and delete the source
- igmp_source_forward_stop: stop fowarding, but keep the source
+ igmp_source_delete: stop forwarding, and delete the source
+ igmp_source_forward_stop: stop forwarding, but keep the source
*/
void igmp_source_delete(struct gm_source *source)
{
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 7fc4f12d27..3015c4a61b 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -437,6 +437,28 @@ int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, const char *buf)
pim_ifp->primary_address,
up->upstream_register);
up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ } else {
+ /*
+ * At this point pimd is connected to
+ * the source, it has a parent, we are not
+ * the RP and the SPTBIT should be set
+ * since we know *the* S,G is on the SPT.
+ * The first time this happens, let's cause
+ * an immediate join to go out so that
+ * the RP can trim this guy immediately
+ * if necessary, instead of waiting
+ * one join/prune send cycle
+ */
+ if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE &&
+ up->parent &&
+ up->rpf.source_nexthop.interface !=
+ up->parent->rpf.source_nexthop
+ .interface) {
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ pim_jp_agg_single_upstream_send(
+ &up->parent->rpf, up->parent,
+ true);
+ }
}
pim_upstream_keep_alive_timer_start(
up, pim_ifp->pim->keep_alive_time);
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index 7fe7c0395f..d174b8a0af 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -63,8 +63,7 @@ static void pim_if_membership_clear(struct interface *ifp)
pim_ifp = ifp->info;
assert(pim_ifp);
- if (PIM_IF_TEST_PIM(pim_ifp->options)
- && PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ if (pim_ifp->pim_enable && pim_ifp->igmp_enable) {
return;
}
@@ -90,9 +89,9 @@ static void pim_if_membership_refresh(struct interface *ifp)
pim_ifp = ifp->info;
assert(pim_ifp);
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ if (!pim_ifp->pim_enable)
return;
- if (!PIM_IF_TEST_IGMP(pim_ifp->options))
+ if (!pim_ifp->igmp_enable)
return;
/*
@@ -143,7 +142,7 @@ static int pim_cmd_interface_add(struct interface *ifp)
if (!pim_ifp)
pim_ifp = pim_if_new(ifp, false, true, false, false);
else
- PIM_IF_DO_PIM(pim_ifp->options);
+ pim_ifp->pim_enable = true;
pim_if_addr_add_all(ifp);
pim_if_membership_refresh(ifp);
@@ -159,7 +158,7 @@ static int pim_cmd_interface_delete(struct interface *ifp)
if (!pim_ifp)
return 1;
- PIM_IF_DONT_PIM(pim_ifp->options);
+ pim_ifp->pim_enable = false;
pim_if_membership_clear(ifp);
@@ -169,7 +168,7 @@ static int pim_cmd_interface_delete(struct interface *ifp)
*/
pim_sock_delete(ifp, "pim unconfigured on interface");
- if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ if (!pim_ifp->igmp_enable) {
pim_if_addr_del_all(ifp);
pim_if_delete(ifp);
}
@@ -360,8 +359,8 @@ static int pim_cmd_igmp_start(struct interface *ifp)
pim_ifp = pim_if_new(ifp, true, false, false, false);
need_startup = 1;
} else {
- if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
- PIM_IF_DO_IGMP(pim_ifp->options);
+ if (!pim_ifp->igmp_enable) {
+ pim_ifp->igmp_enable = true;
need_startup = 1;
}
}
@@ -409,7 +408,6 @@ static void igmp_sock_query_interval_reconfig(struct gm_sock *igmp)
*/
igmp_startup_mode_on(igmp);
}
-#endif
static void igmp_sock_query_reschedule(struct gm_sock *igmp)
{
@@ -439,6 +437,7 @@ static void igmp_sock_query_reschedule(struct gm_sock *igmp)
assert(igmp->t_other_querier_timer);
}
}
+#endif /* PIM_IPV == 4 */
#if PIM_IPV == 4
static void change_query_interval(struct pim_interface *pim_ifp,
@@ -456,6 +455,7 @@ static void change_query_interval(struct pim_interface *pim_ifp,
}
#endif
+#if PIM_IPV == 4
static void change_query_max_response_time(struct pim_interface *pim_ifp,
int query_max_response_time_dsec)
{
@@ -503,6 +503,7 @@ static void change_query_max_response_time(struct pim_interface *pim_ifp,
}
}
}
+#endif
int routing_control_plane_protocols_name_validate(
struct nb_cb_create_args *args)
@@ -2537,13 +2538,13 @@ int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args *args)
if (!pim_ifp)
return NB_OK;
- PIM_IF_DONT_IGMP(pim_ifp->options);
+ pim_ifp->igmp_enable = false;
pim_if_membership_clear(ifp);
pim_if_addr_del_all_igmp(ifp);
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ if (!pim_ifp->pim_enable)
pim_if_delete(ifp);
}
@@ -2594,13 +2595,13 @@ int lib_interface_gmp_address_family_enable_modify(
if (!pim_ifp)
return NB_ERR_INCONSISTENCY;
- PIM_IF_DONT_IGMP(pim_ifp->options);
+ pim_ifp->igmp_enable = false;
pim_if_membership_clear(ifp);
pim_if_addr_del_all_igmp(ifp);
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ if (!pim_ifp->pim_enable)
pim_if_delete(ifp);
}
}
@@ -2733,6 +2734,7 @@ int lib_interface_gmp_address_family_query_interval_modify(
int lib_interface_gmp_address_family_query_max_response_time_modify(
struct nb_cb_modify_args *args)
{
+#if PIM_IPV == 4
struct interface *ifp;
int query_max_response_time_dsec;
@@ -2748,6 +2750,10 @@ int lib_interface_gmp_address_family_query_max_response_time_modify(
change_query_max_response_time(ifp->info,
query_max_response_time_dsec);
}
+#else
+ /* TBD Depends on MLD data structure changes */
+#endif
+
return NB_OK;
}
@@ -2758,6 +2764,7 @@ int lib_interface_gmp_address_family_query_max_response_time_modify(
int lib_interface_gmp_address_family_last_member_query_interval_modify(
struct nb_cb_modify_args *args)
{
+#if PIM_IPV == 4
struct interface *ifp;
struct pim_interface *pim_ifp;
int last_member_query_interval;
@@ -2777,6 +2784,9 @@ int lib_interface_gmp_address_family_last_member_query_interval_modify(
break;
}
+#else
+ /* TBD Depends on MLD data structure changes */
+#endif
return NB_OK;
}
@@ -2787,6 +2797,7 @@ int lib_interface_gmp_address_family_last_member_query_interval_modify(
int lib_interface_gmp_address_family_robustness_variable_modify(
struct nb_cb_modify_args *args)
{
+#if PIM_IPV == 4
struct interface *ifp;
struct pim_interface *pim_ifp;
int last_member_query_count;
@@ -2805,6 +2816,9 @@ int lib_interface_gmp_address_family_robustness_variable_modify(
break;
}
+#else
+ /* TBD Depends on MLD data structure changes */
+#endif
return NB_OK;
}
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 94dcfb8265..106bce61db 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -696,9 +696,7 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
int i;
struct pim_rpf rpf;
struct pim_nexthop_cache *pnc = NULL;
- struct pim_neighbor *nbr = NULL;
struct interface *ifp = NULL;
- struct interface *ifp1 = NULL;
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct pim_instance *pim;
struct zapi_route nhr;
@@ -739,11 +737,6 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
for (i = 0; i < nhr.nexthop_num; i++) {
nexthop = nexthop_from_zapi_nexthop(&nhr.nexthops[i]);
switch (nexthop->type) {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_BLACKHOLE:
- break;
case NEXTHOP_TYPE_IFINDEX:
/*
* Connected route (i.e. no nexthop), use
@@ -760,31 +753,44 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
pnc->rpf.rpf_addr.u.prefix6;
#endif
break;
- case NEXTHOP_TYPE_IPV6_IFINDEX:
+#if PIM_IPV == 4
+ /* RFC5549 IPv4-over-IPv6 nexthop handling:
+ * if we get an IPv6 nexthop in IPv4 PIM, hunt down a
+ * PIM neighbor and use that instead.
+ */
+ case NEXTHOP_TYPE_IPV6_IFINDEX: {
+ struct interface *ifp1 = NULL;
+ struct pim_neighbor *nbr = NULL;
+
ifp1 = if_lookup_by_index(nexthop->ifindex,
pim->vrf->vrf_id);
if (!ifp1)
nbr = NULL;
else
+ /* FIXME: should really use nbr's
+ * secondary address list here
+ */
nbr = pim_neighbor_find_if(ifp1);
+
/* Overwrite with Nbr address as NH addr */
if (nbr)
-#if PIM_IPV == 4
nexthop->gate.ipv4 = nbr->source_addr;
-#else
- nexthop->gate.ipv6 = nbr->source_addr;
-#endif
- else {
+ else
// Mark nexthop address to 0 until PIM
// Nbr is resolved.
-#if PIM_IPV == 4
nexthop->gate.ipv4 = PIMADDR_ANY;
+
+ break;
+ }
#else
- nexthop->gate.ipv6 = PIMADDR_ANY;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
#endif
- }
-
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ case NEXTHOP_TYPE_BLACKHOLE:
+ /* nothing to do for the other nexthop types */
break;
}
@@ -804,13 +810,18 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
continue;
}
- if (PIM_DEBUG_PIM_NHT)
+ if (PIM_DEBUG_PIM_NHT) {
+#if PIM_IPV == 4
+ pim_addr nhaddr = nexthop->gate.ipv4;
+#else
+ pim_addr nhaddr = nexthop->gate.ipv6;
+#endif
zlog_debug(
- "%s: NHT addr %pFX(%s) %d-nhop via %pI4(%s) type %d distance:%u metric:%u ",
+ "%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ",
__func__, &match, pim->vrf->name, i + 1,
- &nexthop->gate.ipv4, ifp->name,
- nexthop->type, nhr.distance,
- nhr.metric);
+ &nhaddr, ifp->name, nexthop->type,
+ nhr.distance, nhr.metric);
+ }
if (!ifp->info) {
/*
diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h
index 68b5ef474e..21047177ea 100644
--- a/pimd/pim_oil.h
+++ b/pimd/pim_oil.h
@@ -197,9 +197,6 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
pim_sgaddr *sg);
struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
pim_sgaddr *sg, const char *name);
-void pim_channel_oil_change_iif(struct pim_instance *pim,
- struct channel_oil *c_oil, int input_vif_index,
- const char *name);
struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil,
const char *name);
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index 50bbc0fe18..1baa5c38ca 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -526,11 +526,8 @@ void pim_sock_reset(struct interface *ifp)
PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
pim_ifp->pim_override_interval_msec =
PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
- if (PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION) {
- PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options);
- } else {
- PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options);
- }
+ pim_ifp->pim_can_disable_join_suppression =
+ PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION;
/* neighbors without lan_delay */
pim_ifp->pim_number_of_nonlandelay_neighbors = 0;
@@ -702,8 +699,7 @@ static int hello_send(struct interface *ifp, uint16_t holdtime)
__func__, &qpim_all_pim_routers_addr, ifp->name,
holdtime, pim_ifp->pim_propagation_delay_msec,
pim_ifp->pim_override_interval_msec,
- PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(
- pim_ifp->options),
+ pim_ifp->pim_can_disable_join_suppression,
pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
listcount(ifp->connected));
@@ -713,7 +709,7 @@ static int hello_send(struct interface *ifp, uint16_t holdtime)
pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
pim_ifp->pim_propagation_delay_msec,
pim_ifp->pim_override_interval_msec,
- PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options));
+ pim_ifp->pim_can_disable_join_suppression);
if (pim_tlv_size < 0) {
return -1;
}
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index a552e77823..730870fb33 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -1147,20 +1147,17 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
}
void pim_rp_show_information(struct pim_instance *pim, struct prefix *range,
- struct vty *vty, bool uj)
+ struct vty *vty, json_object *json)
{
struct rp_info *rp_info;
struct rp_info *prev_rp_info = NULL;
struct listnode *node;
char source[7];
- json_object *json = NULL;
json_object *json_rp_rows = NULL;
json_object *json_row = NULL;
- if (uj)
- json = json_object_new_object();
- else
+ if (!json)
vty_out(vty,
"RP address group/prefix-list OIF I am RP Source Group-Type\n");
for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
@@ -1184,7 +1181,7 @@ void pim_rp_show_information(struct pim_instance *pim, struct prefix *range,
strlcpy(source, "BSR", sizeof(source));
else
strlcpy(source, "None", sizeof(source));
- if (uj) {
+ if (json) {
/*
* If we have moved on to a new RP then add the
* entry for the previous RP
@@ -1257,12 +1254,10 @@ void pim_rp_show_information(struct pim_instance *pim, struct prefix *range,
prev_rp_info = rp_info;
}
- if (uj) {
+ if (json) {
if (prev_rp_info && json_rp_rows)
json_object_object_addf(json, json_rp_rows, "%pFXh",
&prev_rp_info->rp.rpf_addr);
-
- vty_json(vty, json);
}
}
diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h
index 04faeb5f26..e1bc71a3dc 100644
--- a/pimd/pim_rp.h
+++ b/pimd/pim_rp.h
@@ -25,6 +25,7 @@
#include "vty.h"
#include "plist.h"
#include "pim_rpf.h"
+#include "lib/json.h"
struct pim_interface;
@@ -79,7 +80,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, pim_addr group);
#define RP(P, G) pim_rp_g ((P), (G))
void pim_rp_show_information(struct pim_instance *pim, struct prefix *range,
- struct vty *vty, bool uj);
+ struct vty *vty, json_object *json);
void pim_resolve_rp_nh(struct pim_instance *pim, struct pim_neighbor *nbr);
int pim_rp_list_cmp(void *v1, void *v2);
struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c
index 74310474d4..62d6eb8308 100644
--- a/pimd/pim_ssm.c
+++ b/pimd/pim_ssm.c
@@ -70,19 +70,9 @@ void pim_ssm_prefix_list_update(struct pim_instance *pim,
static int pim_is_grp_standard_ssm(struct prefix *group)
{
- static int first = 1;
- static struct prefix group_ssm;
+ pim_addr addr = pim_addr_from_prefix(group);
- if (first) {
- if (!str2prefix(PIM_SSM_STANDARD_RANGE, &group_ssm))
- flog_err(EC_LIB_DEVELOPMENT,
- "%s: Failure to Read Group Address: %s",
- __func__, PIM_SSM_STANDARD_RANGE);
-
- first = 0;
- }
-
- return prefix_match(&group_ssm, group);
+ return pim_addr_ssm(addr);
}
int pim_is_grp_ssm(struct pim_instance *pim, pim_addr group_addr)
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index afa7e37da1..d86be85bd8 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -361,10 +361,8 @@ int pim_ssmpingd_start(struct pim_instance *pim, pim_addr source_addr)
return 0;
}
- {
- zlog_info("%s: starting ssmpingd for source %pPAs", __func__,
- &source_addr);
- }
+ zlog_info("%s: starting ssmpingd for source %pPAs", __func__,
+ &source_addr);
ss = ssmpingd_new(pim, source_addr);
if (!ss) {
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 571117ac0a..af1254f791 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -647,7 +647,7 @@ void pim_upstream_register_reevaluate(struct pim_instance *pim)
* 2. and along the RPT if SPTbit is not set
* If forwarding is hw accelerated i.e. control and dataplane components
* are separate you may not be able to reliably set SPT bit on intermediate
- * routers while still fowarding on the (S,G,rpt).
+ * routers while still forwarding on the (S,G,rpt).
*
* This macro is a slight deviation on the RFC and uses "traffic-agnostic"
* criteria to decide between using the RPT vs. SPT for forwarding.
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index a0dea63b79..b0db6b4d96 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -264,8 +264,8 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
struct ssmpingd_sock *ss;
++writes;
for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
- vty_out(vty, "%sip ssmpingd %pPA\n", spaces,
- &ss->source_addr);
+ vty_out(vty, "%s" PIM_AF_NAME " ssmpingd %pPA\n",
+ spaces, &ss->source_addr);
++writes;
}
}
@@ -289,7 +289,7 @@ static int pim_igmp_config_write(struct vty *vty, int writes,
struct pim_interface *pim_ifp)
{
/* IF ip igmp */
- if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ if (pim_ifp->igmp_enable) {
vty_out(vty, " ip igmp\n");
++writes;
}
@@ -361,7 +361,7 @@ int pim_config_write(struct vty *vty, int writes, struct interface *ifp,
{
struct pim_interface *pim_ifp = ifp->info;
- if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+ if (pim_ifp->pim_enable) {
vty_out(vty, " " PIM_AF_NAME " pim\n");
++writes;
}
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index 5e55b9f9c8..120293dbfd 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -880,6 +880,12 @@ void pim_vxlan_mlag_update(bool enable, bool peer_state, uint32_t role,
*/
pim = pim_get_pim_instance(VRF_DEFAULT);
+ if (!pim) {
+ if (PIM_DEBUG_VXLAN)
+ zlog_debug("%s: Unable to find pim instance", __func__);
+ return;
+ }
+
if (enable)
vxlan_mlag.flags |= PIM_VXLAN_MLAGF_ENABLED;
else
@@ -1137,7 +1143,7 @@ void pim_vxlan_add_term_dev(struct pim_instance *pim,
/* enable pim on the term ifp */
pim_ifp = (struct pim_interface *)ifp->info;
if (pim_ifp) {
- PIM_IF_DO_PIM(pim_ifp->options);
+ pim_ifp->pim_enable = true;
/* ifp is already oper up; activate it as a term dev */
if (pim_ifp->mroute_vif_index >= 0)
pim_vxlan_term_oif_update(pim, ifp);
@@ -1165,8 +1171,8 @@ void pim_vxlan_del_term_dev(struct pim_instance *pim)
pim_ifp = (struct pim_interface *)ifp->info;
if (pim_ifp) {
- PIM_IF_DONT_PIM(pim_ifp->options);
- if (!PIM_IF_TEST_IGMP(pim_ifp->options))
+ pim_ifp->pim_enable = false;
+ if (!pim_ifp->igmp_enable)
pim_if_delete(ifp);
}
}
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 7f463715a5..4bed8d5b73 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -166,6 +166,13 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
struct pim_instance *pim;
pim = pim_get_pim_instance(vrf_id);
+ if (!pim) {
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug("%s: Unable to find pim instance",
+ __func__);
+ return 0;
+ }
+
pim_ifp->pim = pim;
pim_rp_check_on_if_add(pim_ifp);
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index c487f995e7..5d99f131a8 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -388,6 +388,12 @@ void zclient_lookup_read_pipe(struct thread *thread)
struct pim_zlookup_nexthop nexthop_tab[10];
struct in_addr l = {.s_addr = INADDR_ANY};
+ if (!pim) {
+ if (PIM_DEBUG_PIM_NHT_DETAIL)
+ zlog_debug("%s: Unable to find pim instance", __func__);
+ return;
+ }
+
zclient_lookup_nexthop_once(pim, nexthop_tab, 10, l);
thread_add_timer(router->master, zclient_lookup_read_pipe, zlookup, 60,
&zlookup_read);
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 1269f25b35..042c9713b2 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -311,7 +311,7 @@ int if_check_address(struct rip *rip, struct in_addr addr)
return 0;
}
-/* Inteface link down message processing. */
+/* Interface link down message processing. */
static int rip_ifp_down(struct interface *ifp)
{
rip_interface_sync(ifp);
@@ -327,7 +327,7 @@ static int rip_ifp_down(struct interface *ifp)
return 0;
}
-/* Inteface link up message processing */
+/* Interface link up message processing */
static int rip_ifp_up(struct interface *ifp)
{
if (IS_RIP_DEBUG_ZEBRA)
@@ -351,7 +351,7 @@ static int rip_ifp_up(struct interface *ifp)
return 0;
}
-/* Inteface addition message from zebra. */
+/* Interface addition message from zebra. */
static int rip_ifp_create(struct interface *ifp)
{
rip_interface_sync(ifp);
@@ -617,7 +617,7 @@ int rip_interface_address_delete(ZAPI_CALLBACK_ARGS)
hook_call(rip_ifaddr_del, ifc);
- /* Chech wether this prefix needs to be removed */
+ /* Chech whether this prefix needs to be removed */
rip_apply_address_del(ifc);
}
@@ -628,7 +628,7 @@ int rip_interface_address_delete(ZAPI_CALLBACK_ARGS)
}
/* Check interface is enabled by network statement. */
-/* Check wether the interface has at least a connected prefix that
+/* Check whether the interface has at least a connected prefix that
* is within the ripng_enable_network table. */
static int rip_enable_network_lookup_if(struct interface *ifp)
{
@@ -663,7 +663,7 @@ static int rip_enable_network_lookup_if(struct interface *ifp)
return -1;
}
-/* Check wether connected is within the ripng_enable_network table. */
+/* Check whether connected is within the ripng_enable_network table. */
static int rip_enable_network_lookup2(struct connected *connected)
{
struct rip_interface *ri = connected->ifp->info;
@@ -840,7 +840,7 @@ static void rip_connect_set(struct interface *ifp, int set)
nh.ifindex = connected->ifp->ifindex;
nh.type = NEXTHOP_TYPE_IFINDEX;
if (set) {
- /* Check once more wether this prefix is within a
+ /* Check once more whether this prefix is within a
* "network IF_OR_PREF" one */
if ((rip_enable_if_lookup(rip, connected->ifp->name)
>= 0)
diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c
index 061cefec30..4da5f945fe 100644
--- a/ripd/rip_routemap.c
+++ b/ripd/rip_routemap.c
@@ -461,7 +461,7 @@ static const struct route_map_rule_cmd route_set_metric_cmd = {
/* `set ip next-hop IP_ADDRESS' */
-/* Set nexthop to object. ojbect must be pointer to struct attr. */
+/* Set nexthop to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_ip_nexthop(void *rule, const struct prefix *prefix,
@@ -515,7 +515,7 @@ static const struct route_map_rule_cmd route_set_ip_nexthop_cmd = {
/* `set tag TAG' */
-/* Set tag to object. ojbect must be pointer to struct attr. */
+/* Set tag to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_tag(void *rule, const struct prefix *prefix, void *object)
{
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 57bc40f005..5159a9825b 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -198,7 +198,7 @@ static int ripng_if_down(struct interface *ifp)
return 0;
}
-/* Inteface link up message processing. */
+/* Interface link up message processing. */
static int ripng_ifp_up(struct interface *ifp)
{
if (IS_RIPNG_DEBUG_ZEBRA)
@@ -222,7 +222,7 @@ static int ripng_ifp_up(struct interface *ifp)
return 0;
}
-/* Inteface link down message processing. */
+/* Interface link down message processing. */
static int ripng_ifp_down(struct interface *ifp)
{
ripng_interface_sync(ifp);
@@ -238,7 +238,7 @@ static int ripng_ifp_down(struct interface *ifp)
return 0;
}
-/* Inteface addition message from zebra. */
+/* Interface addition message from zebra. */
static int ripng_ifp_create(struct interface *ifp)
{
ripng_interface_sync(ifp);
@@ -432,7 +432,7 @@ int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS)
"RIPng connected address %pFX delete",
p);
- /* Check wether this prefix needs to be removed. */
+ /* Check whether this prefix needs to be removed. */
ripng_apply_address_del(ifc);
}
connected_free(&ifc);
@@ -442,7 +442,7 @@ int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS)
}
/* Lookup RIPng enable network. */
-/* Check wether the interface has at least a connected prefix that
+/* Check whether the interface has at least a connected prefix that
* is within the ripng->enable_network table. */
static int ripng_enable_network_lookup_if(struct interface *ifp)
{
@@ -477,7 +477,7 @@ static int ripng_enable_network_lookup_if(struct interface *ifp)
return -1;
}
-/* Check wether connected is within the ripng->enable_network table. */
+/* Check whether connected is within the ripng->enable_network table. */
static int ripng_enable_network_lookup2(struct connected *connected)
{
struct ripng_interface *ri = connected->ifp->info;
@@ -647,7 +647,7 @@ static void ripng_connect_set(struct interface *ifp, int set)
apply_mask_ipv6(&address);
if (set) {
- /* Check once more wether this prefix is within a
+ /* Check once more whether this prefix is within a
* "network IF_OR_PREF" one */
if ((ripng_enable_if_lookup(ripng, connected->ifp->name)
>= 0)
diff --git a/ripngd/ripng_routemap.c b/ripngd/ripng_routemap.c
index 9aed8d6963..4f2f9e2101 100644
--- a/ripngd/ripng_routemap.c
+++ b/ripngd/ripng_routemap.c
@@ -254,7 +254,7 @@ static const struct route_map_rule_cmd route_set_metric_cmd = {
/* `set ipv6 next-hop local IP_ADDRESS' */
-/* Set nexthop to object. ojbect must be pointer to struct attr. */
+/* Set nexthop to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_ipv6_nexthop_local(void *rule, const struct prefix *p, void *object)
{
@@ -307,7 +307,7 @@ static const struct route_map_rule_cmd
/* `set tag TAG' */
-/* Set tag to object. ojbect must be pointer to struct attr. */
+/* Set tag to object. object must be pointer to struct attr. */
static enum route_map_cmd_result_t
route_set_tag(void *rule, const struct prefix *prefix, void *object)
{
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index af153b4bc3..bf0e4e8ab9 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -87,7 +87,7 @@ static struct static_nht_hash_head static_nht_hash[1];
struct zclient *zclient;
uint32_t zebra_ecmp_count = MULTIPATH_NUM;
-/* Inteface addition message from zebra. */
+/* Interface addition message from zebra. */
static int static_ifp_create(struct interface *ifp)
{
static_ifindex_update(ifp, true);
diff --git a/tests/lib/test_frrlua.c b/tests/lib/test_frrlua.c
index a81446f9ca..fb6b77c0f8 100644
--- a/tests/lib/test_frrlua.c
+++ b/tests/lib/test_frrlua.c
@@ -61,7 +61,7 @@ static void test_encode_decode(void)
assert(strncmp(p_a_str, p_b_str, sizeof(p_b_str)) == 0);
assert(lua_gettop(L) == 0);
- struct interface ifp_a;
+ struct interface ifp_a = {};
struct interface ifp_b = ifp_a;
lua_pushinterface(L, &ifp_a);
@@ -79,7 +79,7 @@ static void test_encode_decode(void)
assert(ifp_a.ll_type == ifp_b.ll_type);
assert(lua_gettop(L) == 0);
- struct in_addr addr_a;
+ struct in_addr addr_a = {};
struct in_addr addr_b = addr_a;
lua_pushinaddr(L, &addr_a);
@@ -87,7 +87,7 @@ static void test_encode_decode(void)
assert(addr_a.s_addr == addr_b.s_addr);
assert(lua_gettop(L) == 0);
- struct in6_addr in6addr_a;
+ struct in6_addr in6addr_a = {};
struct in6_addr in6addr_b = in6addr_a;
lua_pushin6addr(L, &in6addr_a);
diff --git a/tests/lib/test_grpc.py b/tests/lib/test_grpc.py
index 2e292fadc9..7f722de422 100644
--- a/tests/lib/test_grpc.py
+++ b/tests/lib/test_grpc.py
@@ -13,6 +13,10 @@ class TestGRPC(object):
'S["GRPC_TRUE"]=""\n' not in open("../config.status").readlines(),
reason="GRPC not enabled",
)
+ @pytest.mark.skipif(
+ not os.path.isdir("/usr/share/yang"),
+ reason="YANG models aren't installed in /usr/share/yang",
+ )
def test_exits_cleanly(self):
basedir = os.path.dirname(inspect.getsourcefile(type(self)))
program = os.path.join(basedir, self.program)
diff --git a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py
index 961d72bd15..ec66c8caef 100644
--- a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py
+++ b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py
@@ -122,7 +122,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_basic_functionality_topo1/test_bgp_basic_functionality.py b/tests/topotests/bgp_basic_functionality_topo1/test_bgp_basic_functionality.py
index f416f3d2a4..600bf3adc0 100644
--- a/tests/topotests/bgp_basic_functionality_topo1/test_bgp_basic_functionality.py
+++ b/tests/topotests/bgp_basic_functionality_topo1/test_bgp_basic_functionality.py
@@ -137,7 +137,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py
index 123461caa9..e4c25ff5cb 100644
--- a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py
+++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py
@@ -99,7 +99,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py
index 947efa8f8a..f6ee9ea795 100644
--- a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py
+++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py
@@ -103,7 +103,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py
index 8a7192be29..31f033ae12 100644
--- a/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py
+++ b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py
@@ -169,7 +169,7 @@ def test_bgp_community_update_path_change():
if (
len(
tgen.gears["c1"].run(
- 'grep "10.0.1.2 rcvd 192.168.255.254/32 IPv4 unicast...duplicate ignored" bgpd.log'
+ 'grep "10.0.1.2(x1) rcvd 192.168.255.254/32 IPv4 unicast...duplicate ignored" bgpd.log'
)
)
> 0
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 ad999a1aff..2784e956fa 100644
--- a/tests/topotests/bgp_ecmp_topo2/test_ebgp_ecmp_topo2.py
+++ b/tests/topotests/bgp_ecmp_topo2/test_ebgp_ecmp_topo2.py
@@ -29,7 +29,7 @@ Following tests are covered to test ecmp functionality on EBGP.
3. Verify BGP table and RIB in DUT after clear BGP routes and neighbors.
4. Verify routes are cleared from BGP and RIB table of DUT when
redistribute static configuration is removed.
-5. Shut BGP neigbors one by one and verify BGP and routing table updated
+5. Shut BGP neighbors one by one and verify BGP and routing table updated
accordingly in DUT
6. Delete static routes and verify routers are cleared from BGP table and RIB
of DUT.
@@ -105,7 +105,7 @@ def setup_module(mod):
topo = tgen.json_topo
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -475,7 +475,7 @@ def test_ecmp_remove_redistribute_static(request):
@pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"])
def test_ecmp_shut_bgp_neighbor(request, test_type):
- """Shut BGP neigbors one by one and verify BGP and routing table updated
+ """Shut BGP neighbors one by one and verify BGP and routing table updated
accordingly in DUT"""
tc_name = request.node.name
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 28047424b4..704e8fdf04 100644
--- a/tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py
+++ b/tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py
@@ -29,7 +29,7 @@ Following tests are covered to test ecmp functionality on EBGP.
3. Verify BGP table and RIB in DUT after clear BGP routes and neighbors.
4. Verify routes are cleared from BGP and RIB table of DUT when
redistribute static configuration is removed.
-5. Shut BGP neigbors one by one and verify BGP and routing table updated
+5. Shut BGP neighbors one by one and verify BGP and routing table updated
accordingly in DUT
6. Delete static routes and verify routers are cleared from BGP table and RIB
of DUT.
@@ -105,7 +105,7 @@ def setup_module(mod):
topo = tgen.json_topo
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -476,7 +476,7 @@ def test_ecmp_remove_redistribute_static(request):
@pytest.mark.parametrize("test_type", ["redist_static", "advertise_nw"])
def test_ecmp_shut_bgp_neighbor(request, test_type):
- """Shut BGP neigbors one by one and verify BGP and routing table updated
+ """Shut BGP neighbors one by one and verify BGP and routing table updated
accordingly in DUT"""
tc_name = request.node.name
diff --git a/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py b/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py
index 17f5fb08b9..c594079d4f 100755
--- a/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py
+++ b/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py
@@ -135,7 +135,7 @@ def setup_module(mod):
l3mdev_accept = 0
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
tgen.start_topology()
# Configure MAC address for hosts as these MACs are advertised with EVPN type-2 routes
diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py
index 290bf16fea..f155325502 100644
--- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py
@@ -20,7 +20,7 @@
#
"""
-Following tests are covered to test BGP Gracefull Restart functionality.
+Following tests are covered to test BGP Graceful Restart functionality.
Basic Common Test steps for all the test case below :
- Create topology (setup module)
Creating 2 routers topology, r1, r2 in IBGP
@@ -81,7 +81,7 @@ Basic Common Test steps for all the test case below :
Global Mode : GR Restart
PerPeer Mode : None
GR Mode effective : GR Restart
-23. Transition from Peer-level disbale to Global inherit helper
+23. Transition from Peer-level disable to Global inherit helper
Global Mode : None
PerPeer Mode : GR Disable
GR Mode effective : GR Disable
@@ -176,7 +176,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
index 0647ad5d06..dda3bd4b30 100644
--- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
@@ -20,7 +20,7 @@
#
"""
-Following tests are covered to test BGP Gracefull Restart functionality.
+Following tests are covered to test BGP Graceful Restart functionality.
Basic Common Test steps for all the test case below :
- Create topology (setup module)
Creating 2 routers topology, r1, r2 in IBGP
@@ -81,7 +81,7 @@ Basic Common Test steps for all the test case below :
Global Mode : GR Restart
PerPeer Mode : None
GR Mode effective : GR Restart
-23. Transition from Peer-level disbale to Global inherit helper
+23. Transition from Peer-level disable to Global inherit helper
Global Mode : None
PerPeer Mode : GR Disable
GR Mode effective : GR Disable
@@ -176,7 +176,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py
index 0c3ff6451e..e4b533b295 100644
--- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py
@@ -20,7 +20,7 @@
#
"""
-Following tests are covered to test BGP Gracefull Restart functionality.
+Following tests are covered to test BGP Graceful Restart functionality.
Basic Common Test steps for all the test case below :
- Create topology (setup module)
Creating 2 routers topology, r1, r2 in IBGP
@@ -81,7 +81,7 @@ Basic Common Test steps for all the test case below :
Global Mode : GR Restart
PerPeer Mode : None
GR Mode effective : GR Restart
-23. Transition from Peer-level disbale to Global inherit helper
+23. Transition from Peer-level disable to Global inherit helper
Global Mode : None
PerPeer Mode : GR Disable
GR Mode effective : GR Disable
@@ -176,7 +176,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py
index 791ca37eae..835ef41de1 100644
--- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py
@@ -20,7 +20,7 @@
#
"""
-Following tests are covered to test BGP Gracefull Restart functionality.
+Following tests are covered to test BGP Graceful Restart functionality.
Basic Common Test steps for all the test case below :
- Create topology (setup module)
Creating 2 routers topology, r1, r2 in IBGP
@@ -81,7 +81,7 @@ Basic Common Test steps for all the test case below :
Global Mode : GR Restart
PerPeer Mode : None
GR Mode effective : GR Restart
-23. Transition from Peer-level disbale to Global inherit helper
+23. Transition from Peer-level disable to Global inherit helper
Global Mode : None
PerPeer Mode : GR Disable
GR Mode effective : GR Disable
@@ -176,7 +176,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -1418,7 +1418,7 @@ def test_BGP_GR_TC_49_p1(request):
def BGP_GR_TC_52_p1(request):
"""
- Test Objective : Transition from Peer-level disbale to Global inherit helper
+ Test Objective : Transition from Peer-level disable to Global inherit helper
Global Mode : None
PerPeer Mode : GR Disable
GR Mode effective : GR Disable
diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py
index 064fde1633..3afe38857b 100644
--- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py
@@ -173,7 +173,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py
index 4356c4d591..535f272ef4 100644
--- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py
@@ -173,7 +173,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py
index 86d676dd8b..a5c833dc5d 100644
--- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py
@@ -173,7 +173,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py
index 889f47f377..8671a79323 100644
--- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py
@@ -175,7 +175,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gr_functionality_topo3/bgp_gr_functionality_topo3.py b/tests/topotests/bgp_gr_functionality_topo3/bgp_gr_functionality_topo3.py
index c19ee06bab..6bf8b96309 100644
--- a/tests/topotests/bgp_gr_functionality_topo3/bgp_gr_functionality_topo3.py
+++ b/tests/topotests/bgp_gr_functionality_topo3/bgp_gr_functionality_topo3.py
@@ -266,7 +266,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gshut_topo1/test_ebgp_gshut_topo1.py b/tests/topotests/bgp_gshut_topo1/test_ebgp_gshut_topo1.py
index 14b8055d97..58133c44a9 100644
--- a/tests/topotests/bgp_gshut_topo1/test_ebgp_gshut_topo1.py
+++ b/tests/topotests/bgp_gshut_topo1/test_ebgp_gshut_topo1.py
@@ -108,7 +108,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_gshut_topo1/test_ibgp_gshut_topo1.py b/tests/topotests/bgp_gshut_topo1/test_ibgp_gshut_topo1.py
index e842e64ada..a79ce0e3a0 100644
--- a/tests/topotests/bgp_gshut_topo1/test_ibgp_gshut_topo1.py
+++ b/tests/topotests/bgp_gshut_topo1/test_ibgp_gshut_topo1.py
@@ -103,7 +103,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_ibgp_nbr.py b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_ibgp_nbr.py
index e9de3a5e15..68436177d8 100644
--- a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_ibgp_nbr.py
+++ b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_ibgp_nbr.py
@@ -123,7 +123,7 @@ def setup_module(mod):
topo = tgen.json_topo
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -155,7 +155,7 @@ def teardown_module():
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -182,7 +182,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_nbr.py b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_nbr.py
index b31c8499e8..1d424caa30 100644
--- a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_nbr.py
+++ b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_nbr.py
@@ -133,7 +133,7 @@ def setup_module(mod):
topo = tgen.json_topo
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -161,7 +161,7 @@ def teardown_module():
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -188,7 +188,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py
index bc5c4ddcd7..16d6b1993d 100644
--- a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py
+++ b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py
@@ -126,7 +126,7 @@ def setup_module(mod):
topo = tgen.json_topo
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -154,7 +154,7 @@ def teardown_module():
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -181,7 +181,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_nbr.py b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_nbr.py
index 3ce0293ffe..862cae42e9 100644
--- a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_nbr.py
+++ b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_nbr.py
@@ -124,7 +124,7 @@ def setup_module(mod):
topo = tgen.json_topo
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -152,7 +152,7 @@ def teardown_module():
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -180,7 +180,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_unnumbered_nbr.py b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_unnumbered_nbr.py
index a5a8b5fe68..1a91257f06 100644
--- a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_unnumbered_nbr.py
+++ b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ibgp_unnumbered_nbr.py
@@ -112,7 +112,7 @@ def setup_module(mod):
topo = tgen.json_topo
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
@@ -141,7 +141,7 @@ def teardown_module():
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -169,7 +169,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
index fa3598ff8e..03cfded514 100644
--- a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
+++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
@@ -141,7 +141,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
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 6b62b2c5ee..b11cda3cd0 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
@@ -130,7 +130,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
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 fbe1b038e3..7eb5bda2d8 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
@@ -204,7 +204,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
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 05961b1104..35e81d1c62 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
@@ -157,7 +157,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_path_attributes_topo1/test_bgp_path_attributes.py b/tests/topotests/bgp_path_attributes_topo1/test_bgp_path_attributes.py
index 1bd4c233d8..870c2f7a10 100644
--- a/tests/topotests/bgp_path_attributes_topo1/test_bgp_path_attributes.py
+++ b/tests/topotests/bgp_path_attributes_topo1/test_bgp_path_attributes.py
@@ -115,7 +115,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_prefix_list_topo1/test_prefix_lists.py b/tests/topotests/bgp_prefix_list_topo1/test_prefix_lists.py
index 64093497cb..2dc95cee21 100644
--- a/tests/topotests/bgp_prefix_list_topo1/test_prefix_lists.py
+++ b/tests/topotests/bgp_prefix_list_topo1/test_prefix_lists.py
@@ -100,7 +100,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
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 e255b4e88c..04f866f35b 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
@@ -130,7 +130,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py b/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py
index 1367d77e55..8c9d2c9dbf 100644
--- a/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py
+++ b/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py
@@ -119,7 +119,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_route_map/test_route_map_topo1.py b/tests/topotests/bgp_route_map/test_route_map_topo1.py
index 6556c050bb..655a3dc899 100644
--- a/tests/topotests/bgp_route_map/test_route_map_topo1.py
+++ b/tests/topotests/bgp_route_map/test_route_map_topo1.py
@@ -131,7 +131,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_route_map/test_route_map_topo2.py b/tests/topotests/bgp_route_map/test_route_map_topo2.py
index eccb2c1bf2..4da7eeb2ff 100644
--- a/tests/topotests/bgp_route_map/test_route_map_topo2.py
+++ b/tests/topotests/bgp_route_map/test_route_map_topo2.py
@@ -176,7 +176,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py b/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py
index c48bd8a439..7094c2805d 100644
--- a/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py
+++ b/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py
@@ -126,7 +126,7 @@ def setup_module(mod):
topo = tgen.json_topo
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
build_config_from_json(tgen, topo)
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 07ba0964d4..7d71ef761e 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
@@ -131,7 +131,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Run these tests for kernel version 4.19 or above
diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py
index 8ba96ef7a0..391c272dbc 100644
--- a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py
+++ b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py
@@ -118,7 +118,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Run these tests for kernel version 4.19 or above
diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py
index 1cf1b29097..a9aefc5003 100644
--- a/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py
+++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py
@@ -126,7 +126,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Run these tests for kernel version 4.19 or above
diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py
index 82daf08e18..97016caa75 100644
--- a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py
+++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4.py
@@ -127,7 +127,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Run these tests for kernel version 4.19 or above
diff --git a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py
index d9d4f4f8b2..b95e71c2eb 100644
--- a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py
+++ b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py
@@ -129,7 +129,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Run these tests for kernel version 4.19 or above
diff --git a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py
index e930b62706..9291fbd966 100644
--- a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py
+++ b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py
@@ -123,7 +123,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Run these tests for kernel version 4.19 or above
diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py
index 72d1251d25..332ffdf6d5 100644
--- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py
+++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py
@@ -141,7 +141,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py
index b3ff9d79ca..a641fec584 100644
--- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py
+++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py
@@ -158,7 +158,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/example_topojson_test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py b/tests/topotests/example_topojson_test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py
index 107b5e9624..fe4a256484 100755
--- a/tests/topotests/example_topojson_test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py
+++ b/tests/topotests/example_topojson_test/test_topo_json_multiple_links/test_example_topojson_multiple_links.py
@@ -110,7 +110,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# This function only purpose is to create configuration
diff --git a/tests/topotests/example_topojson_test/test_topo_json_single_link/test_example_topojson.py b/tests/topotests/example_topojson_test/test_topo_json_single_link/test_example_topojson.py
index b03215d21c..8bc28528dc 100755
--- a/tests/topotests/example_topojson_test/test_topo_json_single_link/test_example_topojson.py
+++ b/tests/topotests/example_topojson_test/test_topo_json_single_link/test_example_topojson.py
@@ -111,7 +111,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# This function only purpose is to create configuration
diff --git a/tests/topotests/example_topojson_test/test_topo_json_single_link_loopback/test_example_topojson.py b/tests/topotests/example_topojson_test/test_topo_json_single_link_loopback/test_example_topojson.py
index 594b156f8b..caf0a7c138 100755
--- a/tests/topotests/example_topojson_test/test_topo_json_single_link_loopback/test_example_topojson.py
+++ b/tests/topotests/example_topojson_test/test_topo_json_single_link_loopback/test_example_topojson.py
@@ -112,7 +112,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# This function only purpose is to create configuration
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index 0b97637c1e..564571c929 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -2928,7 +2928,7 @@ def addKernelRoute(
Parameters:
-----------
* `tgen` : Topogen object
- * `router`: router for which kernal routes needs to be added
+ * `router`: router for which kernel routes needs to be added
* `intf`: interface name, for which kernel routes needs to be added
* `bindToAddress`: bind to <host>, an interface or multicast
address
@@ -2969,7 +2969,7 @@ def addKernelRoute(
output = rnode.run(cmd)
def check_in_kernel(rnode, verify_cmd, grp_addr, router):
- # Verifying if ip route added to kernal
+ # Verifying if ip route added to kernel
errormsg = None
result = rnode.run(verify_cmd)
logger.debug("{}\n{}".format(verify_cmd, result))
@@ -4207,7 +4207,7 @@ def verify_bgp_community(tgen, addr_type, router, network, input_dict=None):
def get_ipv6_linklocal_address(topo, node, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py
index 1f723eab93..b4a6358389 100644
--- a/tests/topotests/lib/pim.py
+++ b/tests/topotests/lib/pim.py
@@ -602,7 +602,7 @@ def verify_pim_neighbors(tgen, topo, dut=None, iface=None, nbr_ip=None, expected
return True
-@retry(retry_timeout=40)
+@retry(retry_timeout=40, diag_pct=0)
def verify_igmp_groups(tgen, dut, interface, group_addresses, expected=True):
"""
Verify IGMP groups are received from an intended interface
@@ -676,7 +676,7 @@ def verify_igmp_groups(tgen, dut, interface, group_addresses, expected=True):
return True
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_upstream_iif(
tgen,
dut,
@@ -959,7 +959,7 @@ def verify_join_state_and_timer(
return True
-@retry(retry_timeout=120)
+@retry(retry_timeout=120, diag_pct=0)
def verify_ip_mroutes(
tgen,
dut,
@@ -1164,7 +1164,7 @@ def verify_ip_mroutes(
return True if return_uptime == False else uptime_dict
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_pim_rp_info(
tgen,
topo,
@@ -1329,7 +1329,7 @@ def verify_pim_rp_info(
return True
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_pim_state(
tgen,
dut,
@@ -1516,7 +1516,7 @@ def get_pim_interface_traffic(tgen, input_dict):
return output_dict
-@retry(retry_timeout=40)
+@retry(retry_timeout=40, diag_pct=0)
def verify_pim_interface(
tgen, topo, dut, interface=None, interface_ip=None, expected=True
):
@@ -2295,7 +2295,7 @@ def verify_pim_grp_rp_source(
return errormsg
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_pim_bsr(tgen, topo, dut, bsr_ip, expected=True):
"""
Verify all PIM interface are up and running, config is verified
@@ -2351,7 +2351,7 @@ def verify_pim_bsr(tgen, topo, dut, bsr_ip, expected=True):
return True
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_ip_pim_upstream_rpf(
tgen, topo, dut, interface, group_addresses, rp=None, expected=True
):
@@ -2551,7 +2551,7 @@ def enable_disable_pim_bsm(tgen, router, intf, enable=True):
return result
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_ip_pim_join(
tgen, topo, dut, interface, group_addresses, src_address=None, expected=True
):
@@ -2644,7 +2644,7 @@ def verify_ip_pim_join(
return True
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_igmp_config(tgen, input_dict, stats_return=False, expected=True):
"""
Verify igmp interface details, verifying following configs:
@@ -2934,7 +2934,7 @@ def verify_igmp_config(tgen, input_dict, stats_return=False, expected=True):
return True if stats_return == False else igmp_stats
-@retry(retry_timeout=60)
+@retry(retry_timeout=60, diag_pct=0)
def verify_pim_config(tgen, input_dict, expected=True):
"""
Verify pim interface details, verifying following configs:
@@ -3060,7 +3060,7 @@ def verify_pim_config(tgen, input_dict, expected=True):
return True
-@retry(retry_timeout=40)
+@retry(retry_timeout=20, diag_pct=0)
def verify_multicast_traffic(tgen, input_dict, return_traffic=False, expected=True):
"""
Verify multicast traffic by running
@@ -3303,7 +3303,7 @@ def get_refCount_for_mroute(tgen, dut, iif, src_address, group_addresses):
return refCount
-@retry(retry_timeout=40)
+@retry(retry_timeout=40, diag_pct=0)
def verify_multicast_flag_state(
tgen, dut, src_address, group_addresses, flag, expected=True
):
@@ -3400,7 +3400,7 @@ def verify_multicast_flag_state(
return True
-@retry(retry_timeout=40)
+@retry(retry_timeout=40, diag_pct=0)
def verify_igmp_interface(tgen, topo, dut, igmp_iface, interface_ip, expected=True):
"""
Verify all IGMP interface are up and running, config is verified
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 4ab160b52e..1a55d6d9f1 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
@@ -170,7 +170,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Don"t run this test if we have any failure.
@@ -313,7 +313,7 @@ def pre_config_to_bsm(tgen, topo, tc_name, bsr, sender, receiver, fhr, rp, lhr,
result = add_rp_interfaces_and_pim_config(tgen, topo, "lo", rp, rp_mapping)
assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- # Add kernal routes to sender and receiver
+ # Add kernel routes to sender and receiver
for group, rp_list in rp_mapping.items():
mask = group.split("/")[1]
if int(mask) == 32:
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 5f641b5286..31cd8f9858 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
@@ -150,7 +150,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Don"t run this test if we have any failure.
@@ -247,7 +247,7 @@ def pre_config_to_bsm(tgen, topo, tc_name, bsr, sender, receiver, fhr, rp, lhr,
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- # Add kernal route for source
+ # Add kernel route for source
group = topo["routers"][bsr]["bsm"]["bsr_packets"][packet]["pkt_dst"]
bsr_interface = topo["routers"][bsr]["links"][fhr]["interface"]
result = addKernelRoute(tgen, bsr, bsr_interface, group)
@@ -260,18 +260,18 @@ def pre_config_to_bsm(tgen, topo, tc_name, bsr, sender, receiver, fhr, rp, lhr,
result = add_rp_interfaces_and_pim_config(tgen, topo, "lo", rp, rp_mapping)
assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- # Add kernal routes to sender and receiver
+ # Add kernel routes to sender and receiver
for group, rp_list in rp_mapping.items():
mask = group.split("/")[1]
if int(mask) == 32:
group = group.split("/")[0]
- # Add kernal routes for sender
+ # Add kernel routes for sender
s_interface = topo["routers"][sender]["links"][fhr]["interface"]
result = addKernelRoute(tgen, sender, s_interface, group)
assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- # Add kernal routes for receiver
+ # Add kernel routes for receiver
r_interface = topo["routers"][receiver]["links"][lhr]["interface"]
result = addKernelRoute(tgen, receiver, r_interface, group)
assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
diff --git a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
index 9929f4b3c7..75fae6bb59 100755
--- a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
+++ b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
@@ -179,7 +179,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, tgen.json_topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Don"t run this test if we have any failure.
diff --git a/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py b/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py
index 57561c78eb..c2128cbad6 100755
--- a/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py
+++ b/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py
@@ -176,7 +176,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Don"t run this test if we have any failure.
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 907c75e9ee..6f3867cc2c 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
@@ -188,7 +188,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Don"t run this test if we have any failure.
@@ -2834,9 +2834,7 @@ def test_mroute_after_removing_RP_sending_IGMP_prune_p2(request):
intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
- traffic_before = verify_multicast_traffic(
- tgen, input_traffic, return_traffic=True, expected=False
- )
+ traffic_before = verify_multicast_traffic(tgen, input_traffic, return_traffic=True)
assert isinstance(traffic_before, dict), (
"Testcase {} : Failed \n traffic_before is not dictionary \n "
"Error: {}".format(tc_name, result)
@@ -2861,9 +2859,7 @@ def test_mroute_after_removing_RP_sending_IGMP_prune_p2(request):
intf_f1_i8 = topo["routers"]["f1"]["links"]["i8"]["interface"]
input_traffic = {"f1": {"traffic_sent": [intf_f1_i8]}}
- traffic_after = verify_multicast_traffic(
- tgen, input_traffic, return_traffic=True, expected=False
- )
+ traffic_after = verify_multicast_traffic(tgen, input_traffic, return_traffic=True)
assert isinstance(traffic_after, dict), (
"Testcase {} : Failed \n traffic_after is not dictionary \n "
"Error: {}".format(tc_name, result)
@@ -3274,8 +3270,6 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request):
intf_r2_l1 = topo["routers"]["r2"]["links"]["l1"]["interface"]
shutdown_bringup_interface(tgen, "r2", intf_r2_l1, False)
- app_helper.stop_host("i2")
-
step("Verify RP info after Shut the link from FHR to RP from RP node")
dut = "l1"
rp_address = "1.0.5.17"
@@ -3426,8 +3420,6 @@ def test_prune_sent_to_LHR_and_FHR_when_PIMnbr_down_p2(request):
step("Verify PIM Nbrs after Shut the link from FHR to RP from FHR node")
- app_helper.stop_host("i6")
-
step("Verify RP info after Shut the link from FHR to RP from FHR node")
dut = "l1"
rp_address = "1.0.5.17"
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 1b7158d597..b255bddcef 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
@@ -155,7 +155,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Don"t run this test if we have any failure.
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 a5cec93813..210f960b60 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
@@ -227,7 +227,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, TOPO)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Don"t run this test if we have any failure.
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py
index f9fa55e275..f42bc47d46 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py
@@ -146,7 +146,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py
index e63f59e846..2c9959c499 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py
@@ -138,7 +138,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
index 030b77c609..252481799c 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
@@ -106,7 +106,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py
index 86f3213fce..a0ab828717 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py
@@ -117,7 +117,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
index a578272e21..2b479db3c2 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
@@ -120,7 +120,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
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 4a5660f42f..00feefc4d0 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
@@ -121,7 +121,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py
index b32483f7ad..497a8b900b 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py
@@ -120,7 +120,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py
index aa34208acb..1917bd42f5 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py
@@ -118,7 +118,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py
index 7c09e71ef8..3b84a99cdf 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py
@@ -107,7 +107,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
index adc1b2cf3a..22d768d9f6 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
@@ -133,7 +133,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
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 88c87dcecd..8bd81a3854 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
@@ -129,7 +129,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py
index 73193582a6..c7ee723b3e 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py
@@ -114,7 +114,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py
index 2c7c6df37e..ff182be66f 100644
--- a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py
+++ b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py
@@ -123,7 +123,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py
index 36cde06c3e..3967f5f42a 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py
@@ -161,7 +161,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py
index baa0071f9c..d32a05a88e 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py
@@ -116,7 +116,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py
index 9353cd923b..75be0928ab 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py
@@ -121,7 +121,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
@@ -195,7 +195,7 @@ def red_connected(dut, config=True):
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -222,7 +222,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py
index fe8be0a4b3..ce880b413b 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py
@@ -134,7 +134,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
@@ -218,7 +218,7 @@ def red_connected(dut, config=True):
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -245,7 +245,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py
index 64a067cd1a..bdc4c139f7 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py
@@ -66,7 +66,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py
index dc3b915d49..7b41c80ce3 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py
@@ -143,7 +143,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py
index d7cf951c5f..0c9457b39e 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py
@@ -135,7 +135,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py
index 21d03fadfb..df3a0249ea 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py
@@ -126,7 +126,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
@@ -166,7 +166,7 @@ def teardown_module(mod):
def get_llip(onrouter, intf):
"""
- API to get the link local ipv6 address of a perticular interface
+ API to get the link local ipv6 address of a particular interface
Parameters
----------
@@ -193,7 +193,7 @@ def get_llip(onrouter, intf):
def get_glipv6(onrouter, intf):
"""
- API to get the global ipv6 address of a perticular interface
+ API to get the global ipv6 address of a particular interface
Parameters
----------
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
index 9ec06ec36b..c9824e79c5 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
@@ -120,7 +120,7 @@ def setup_module(mod):
daemons = topo_daemons(tgen, topo)
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen, daemons)
# Creating configuration from JSON
diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py
index 809a0a3240..abfba029f4 100644
--- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py
+++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo1_ebgp.py
@@ -94,7 +94,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py
index b85aa43ca4..f04279a081 100644
--- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py
+++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py
@@ -135,7 +135,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py
index 0e6ab6183c..6c76c928ec 100644
--- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py
+++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py
@@ -118,7 +118,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
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 7a7c5d63a7..3f49ced7ca 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
@@ -101,7 +101,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py
index e06d0fca3c..6b7b2adfd9 100644
--- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py
+++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py
@@ -94,7 +94,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py
index cb6c879459..350a117b94 100644
--- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py
+++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py
@@ -135,7 +135,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py
index 1ac91e1f5f..1861d9ad49 100644
--- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py
+++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py
@@ -117,7 +117,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
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 42d86f22da..8c97d6cb7e 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
@@ -96,7 +96,7 @@ def setup_module(mod):
# ... and here it calls Mininet initialization functions.
# Starting topology, create tmp files which are loaded to routers
- # to start deamons and then start routers
+ # to start daemons and then start routers
start_topology(tgen)
# Creating configuration from JSON
diff --git a/tests/topotests/zebra_multiple_connected/r1/ip_route.json b/tests/topotests/zebra_multiple_connected/r1/ip_route.json
new file mode 100644
index 0000000000..c29f2f9786
--- /dev/null
+++ b/tests/topotests/zebra_multiple_connected/r1/ip_route.json
@@ -0,0 +1,62 @@
+{
+ "10.0.1.0/24":[
+ {
+ "prefix":"10.0.1.0/24",
+ "prefixLen":24,
+ "protocol":"connected",
+ "vrfName":"default",
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.1.0/24",
+ "prefixLen":24,
+ "protocol":"connected",
+ "vrfName":"default",
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"r1-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.1.1/32":[
+ {
+ "prefix":"192.168.1.1/32",
+ "prefixLen":32,
+ "protocol":"kernel",
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.99",
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/zebra_multiple_connected/r1/ip_route2.json b/tests/topotests/zebra_multiple_connected/r1/ip_route2.json
new file mode 100644
index 0000000000..26995654f7
--- /dev/null
+++ b/tests/topotests/zebra_multiple_connected/r1/ip_route2.json
@@ -0,0 +1,102 @@
+{
+ "10.0.1.0/24":[
+ {
+ "prefix":"10.0.1.0/24",
+ "prefixLen":24,
+ "protocol":"connected",
+ "vrfName":"default",
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.1.0/24",
+ "prefixLen":24,
+ "protocol":"connected",
+ "vrfName":"default",
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"r1-eth0",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.1.30/32":[
+ {
+ "prefix":"10.0.1.30/32",
+ "prefixLen":32,
+ "protocol":"kernel",
+ "vrfName":"default",
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.9.9.0/24":[
+ {
+ "prefix":"10.9.9.0/24",
+ "prefixLen":24,
+ "protocol":"kernel",
+ "vrfName":"default",
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.30",
+ "afi":"ipv4",
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "192.168.1.1/32":[
+ {
+ "prefix":"192.168.1.1/32",
+ "prefixLen":32,
+ "protocol":"kernel",
+ "vrfName":"default",
+ "distance":0,
+ "metric":0,
+ "installed":true,
+ "table":254,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.99",
+ "afi":"ipv4",
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/zebra_multiple_connected/r1/zebra.conf b/tests/topotests/zebra_multiple_connected/r1/zebra.conf
new file mode 100644
index 0000000000..81adcadea8
--- /dev/null
+++ b/tests/topotests/zebra_multiple_connected/r1/zebra.conf
@@ -0,0 +1,9 @@
+interface r1-eth0
+ ip address 10.0.1.1/24
+!
+interface r1-eth1
+ ip address 10.0.1.2/24
+!
+interface r1-eth2
+ ip address 10.0.1.3/24
+! \ No newline at end of file
diff --git a/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py
new file mode 100644
index 0000000000..8882cf5bda
--- /dev/null
+++ b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+
+#
+# test_zebra_multiple_connected.py
+#
+# Copyright (c) 2022 by
+# Nvidia Corporation
+# Donald Sharp
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_zebra_multiple_connected.py: Testing multiple connected
+
+"""
+
+import os
+import re
+import sys
+import pytest
+import json
+from functools import partial
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+
+#####################################################
+##
+## Network Topology Definition
+##
+#####################################################
+
+
+def build_topo(tgen):
+ for routern in range(1, 4):
+ tgen.add_router("r{}".format(routern))
+
+ # On main router
+ # First switch is for a dummy interface (for local network)
+ switch = tgen.add_switch("sw1")
+ switch.add_link(tgen.gears["r1"])
+
+ # Switches for zebra
+ # switch 2 switch is for connection to zebra router
+ switch = tgen.add_switch("sw2")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ # switch 4 is stub on remote zebra router
+ switch = tgen.add_switch("sw4")
+ switch.add_link(tgen.gears["r3"])
+
+ # switch 3 is between zebra routers
+ switch = tgen.add_switch("sw3")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r3"])
+
+
+#####################################################
+##
+## Tests starting
+##
+#####################################################
+
+
+def setup_module(module):
+ "Setup topology"
+ tgen = Topogen(build_topo, module.__name__)
+ tgen.start_topology()
+
+ # This is a sample of configuration loading.
+ router_list = tgen.routers()
+ for rname, router in router_list.items():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(_mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ tgen.stop_topology()
+
+
+def test_zebra_connected_multiple():
+ "Test multiple connected routes that have a kernel route pointing at one"
+
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r1"]
+ router.run("ip route add 192.168.1.1/32 via 10.0.1.99 dev r1-eth1")
+ router.run("ip link add dummy1 type dummy")
+ router.run("ip link set dummy1 up")
+ router.run("ip link set dummy1 down")
+
+ routes = "{}/{}/ip_route.json".format(CWD, router.name)
+ expected = json.loads(open(routes).read())
+
+ test_func = partial(
+ topotest.router_json_cmp, router, "show ip route json", expected
+ )
+
+ _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ assert result is None, "Kernel route is missing from zebra"
+
+
+def test_zebra_system_recursion():
+ "Test a system route recursing through another system route"
+
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r1"]
+ router.run("ip route add 10.0.1.30/32 dev r1-eth1")
+ router.run("ip route add 10.9.9.0/24 via 10.0.1.30 dev r1-eth1")
+ router.run("ip link add dummy2 type dummy")
+ router.run("ip link set dummy2 up")
+ router.run("ip link set dummy2 down")
+
+ routes = "{}/{}/ip_route2.json".format(CWD, router.name)
+ expected = json.loads(open(routes).read())
+ test_func = partial(
+ topotest.router_json_cmp, router, "show ip route json", expected
+ )
+
+ _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ assert result is None, "Kernel route is missing from zebra"
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in
index d95f2d4be7..52f5277d25 100644
--- a/tools/frrcommon.sh.in
+++ b/tools/frrcommon.sh.in
@@ -253,11 +253,11 @@ all_start() {
all_stop() {
local pids reversed
- daemon_list daemons disabled
- [ "$1" = "--reallyall" ] && daemons="$daemons $disabled"
+ daemon_list enabled_daemons disabled_daemons
+ [ "$1" = "--reallyall" ] && enabled_daemons="$enabled_daemons $disabled_daemons"
reversed=""
- for dmninst in $daemons; do
+ for dmninst in $enabled_daemons; do
reversed="$dmninst $reversed"
done
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 9e8f73b101..0b85b2ea49 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -3204,7 +3204,7 @@ DEFUN (vtysh_write_terminal,
"Skip \"Building configuration...\" header\n")
{
unsigned int i;
- char line[] = "do write terminal\n";
+ char line[] = "do write terminal";
if (!strcmp(argv[argc - 1]->arg, "no-header"))
argc--;
@@ -3283,7 +3283,7 @@ static void backup_config_file(const char *fbackup)
int vtysh_write_config_integrated(void)
{
unsigned int i;
- char line[] = "do write terminal\n";
+ char line[] = "do write terminal";
FILE *fp;
int fd;
#ifdef FRR_USER
@@ -3396,12 +3396,12 @@ DEFUN (vtysh_write_memory,
"Write configuration to the file (same as write memory)\n")
{
int ret = CMD_SUCCESS;
- char line[] = "do write memory\n";
+ char line[] = "do write memory";
unsigned int i;
vty_out(vty, "Note: this version of vtysh never writes vtysh.conf\n");
- /* If integrated frr.conf explicitely set. */
+ /* If integrated frr.conf explicitly set. */
if (want_config_integrated()) {
ret = CMD_WARNING_CONFIG_FAILED;
@@ -3723,7 +3723,7 @@ DEFPY (vtysh_terminal_monitor,
"Receive log messages to active VTY session\n"
DAEMONS_STR)
{
- static const char line[] = "terminal monitor\n";
+ static const char line[] = "terminal monitor";
int ret_all = CMD_SUCCESS, ret, fd;
size_t i, ok = 0;
@@ -3775,7 +3775,7 @@ DEFPY (no_vtysh_terminal_monitor,
"Receive log messages to active VTY session\n"
DAEMONS_STR)
{
- static const char line[] = "no terminal monitor\n";
+ static const char line[] = "no terminal monitor";
int ret_all = CMD_SUCCESS, ret;
size_t i, ok = 0;
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index 4f50da380c..51e4f802c9 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -54,6 +54,7 @@
#define DEFAULT_LOGLEVEL LOG_INFO
#define DEFAULT_MIN_RESTART 60
#define DEFAULT_MAX_RESTART 600
+#define DEFAULT_OPERATIONAL_TIMEOUT 60
#define DEFAULT_RESTART_CMD WATCHFRR_SH_PATH " restart %s"
#define DEFAULT_START_CMD WATCHFRR_SH_PATH " start %s"
@@ -70,14 +71,14 @@ struct thread_master *master;
static bool watch_only = false;
const char *pathspace;
-typedef enum {
+enum restart_phase {
PHASE_NONE = 0,
PHASE_INIT,
PHASE_STOPS_PENDING,
PHASE_WAITING_DOWN,
PHASE_ZEBRA_RESTART_PENDING,
PHASE_WAITING_ZEBRA_UP
-} restart_phase_t;
+};
static const char *const phase_str[] = {
"Idle",
@@ -103,15 +104,17 @@ struct restart_info {
};
static struct global_state {
- restart_phase_t phase;
+ enum restart_phase phase;
struct thread *t_phase_hanging;
struct thread *t_startup_timeout;
+ struct thread *t_operational;
const char *vtydir;
long period;
long timeout;
long restart_timeout;
long min_restart_interval;
long max_restart_interval;
+ long operational_timeout;
struct daemon *daemons;
const char *restart_command;
const char *start_command;
@@ -131,18 +134,19 @@ static struct global_state {
.loglevel = DEFAULT_LOGLEVEL,
.min_restart_interval = DEFAULT_MIN_RESTART,
.max_restart_interval = DEFAULT_MAX_RESTART,
+ .operational_timeout = DEFAULT_OPERATIONAL_TIMEOUT,
.restart_command = DEFAULT_RESTART_CMD,
.start_command = DEFAULT_START_CMD,
.stop_command = DEFAULT_STOP_CMD,
};
-typedef enum {
+enum daemon_state {
DAEMON_INIT,
DAEMON_DOWN,
DAEMON_CONNECTING,
DAEMON_UP,
DAEMON_UNRESPONSIVE
-} daemon_state_t;
+};
#define IS_UP(DMN) \
(((DMN)->state == DAEMON_UP) || ((DMN)->state == DAEMON_UNRESPONSIVE))
@@ -153,7 +157,7 @@ static const char *const state_str[] = {
struct daemon {
const char *name;
- daemon_state_t state;
+ enum daemon_state state;
int fd;
struct timeval echo_sent;
unsigned int connect_tries;
@@ -177,6 +181,7 @@ struct daemon {
#define OPTION_MAXRESTART 2001
#define OPTION_DRY 2002
#define OPTION_NETNS 2003
+#define OPTION_MAXOPERATIONAL 2004
static const struct option longopts[] = {
{"daemon", no_argument, NULL, 'd'},
@@ -191,6 +196,7 @@ static const struct option longopts[] = {
{"dry", no_argument, NULL, OPTION_DRY},
{"min-restart-interval", required_argument, NULL, OPTION_MINRESTART},
{"max-restart-interval", required_argument, NULL, OPTION_MAXRESTART},
+ {"operational-timeout", required_argument, NULL, OPTION_MAXOPERATIONAL},
{"pid-file", required_argument, NULL, 'p'},
{"blank-string", required_argument, NULL, 'b'},
#ifdef GNU_LINUX
@@ -265,6 +271,9 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n",
--max-restart-interval\n\
Set the maximum seconds to wait between invocations of daemon\n\
restart commands (default is %d).\n\
+ --operational-timeout\n\
+ Set the time before systemd is notified that we are considered\n\
+ operational again after a daemon restart (default is %d).\n\
-i, --interval Set the status polling interval in seconds (default is %d)\n\
-t, --timeout Set the unresponsiveness timeout in seconds (default is %d)\n\
-T, --restart-timeout\n\
@@ -296,10 +305,10 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n",
-v, --version Print program version\n\
-h, --help Display this help and exit\n",
frr_vtydir, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG,
- DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART, DEFAULT_PERIOD,
- DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT,
- DEFAULT_RESTART_CMD, DEFAULT_START_CMD, DEFAULT_STOP_CMD,
- frr_vtydir);
+ DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART,
+ DEFAULT_OPERATIONAL_TIMEOUT, DEFAULT_PERIOD, DEFAULT_TIMEOUT,
+ DEFAULT_RESTART_TIMEOUT, DEFAULT_RESTART_CMD, DEFAULT_START_CMD,
+ DEFAULT_STOP_CMD, frr_vtydir);
}
static pid_t run_background(char *shell_cmd)
@@ -502,8 +511,6 @@ static int run_job(struct restart_info *restart, const char *cmdtype,
restart->pid = 0;
}
- systemd_send_status("FRR Operational");
-
/* Calculate the new restart interval. */
if (update_interval) {
if (delay.tv_sec > 2 * gs.max_restart_interval)
@@ -584,6 +591,11 @@ static void restart_done(struct daemon *dmn)
SET_WAKEUP_DOWN(dmn);
}
+static void daemon_restarting_operational(struct thread *thread)
+{
+ systemd_send_status("FRR Operational");
+}
+
static void daemon_down(struct daemon *dmn, const char *why)
{
if (IS_UP(dmn) || (dmn->state == DAEMON_INIT))
@@ -603,6 +615,8 @@ static void daemon_down(struct daemon *dmn, const char *why)
THREAD_OFF(dmn->t_wakeup);
if (try_connect(dmn) < 0)
SET_WAKEUP_DOWN(dmn);
+
+ systemd_send_status("FRR partially operational");
phase_check();
}
@@ -721,8 +735,15 @@ static void daemon_up(struct daemon *dmn, const char *why)
gs.numdown--;
dmn->connect_tries = 0;
zlog_notice("%s state -> up : %s", dmn->name, why);
- if (gs.numdown == 0)
+ if (gs.numdown == 0) {
daemon_send_ready(0);
+
+ THREAD_OFF(gs.t_operational);
+
+ thread_add_timer(master, daemon_restarting_operational, NULL,
+ gs.operational_timeout, &gs.t_operational);
+ }
+
SET_WAKEUP_ECHO(dmn);
phase_check();
}
@@ -848,7 +869,7 @@ static void phase_hanging(struct thread *t_hanging)
gs.phase = PHASE_NONE;
}
-static void set_phase(restart_phase_t new_phase)
+static void set_phase(enum restart_phase new_phase)
{
gs.phase = new_phase;
thread_cancel(&gs.t_phase_hanging);
@@ -889,6 +910,7 @@ static void phase_check(void)
case PHASE_WAITING_DOWN:
if (gs.numdown + IS_UP(gs.special) < gs.numdaemons)
break;
+ systemd_send_status("Phased Restart");
zlog_info("Phased restart: all routing daemons now down.");
run_job(&gs.special->restart, "restart", gs.restart_command, 1,
1);
@@ -898,6 +920,7 @@ static void phase_check(void)
case PHASE_ZEBRA_RESTART_PENDING:
if (gs.special->restart.pid)
break;
+ systemd_send_status("Zebra Restarting");
zlog_info("Phased restart: %s restart job completed.",
gs.special->name);
set_phase(PHASE_WAITING_ZEBRA_UP);
@@ -1030,6 +1053,12 @@ void watchfrr_status(struct vty *vty)
struct timeval delay;
vty_out(vty, "watchfrr global phase: %s\n", phase_str[gs.phase]);
+ vty_out(vty, " Restart Command: %pSQq\n", gs.restart_command);
+ vty_out(vty, " Start Command: %pSQq\n", gs.start_command);
+ vty_out(vty, " Stop Command: %pSQq\n", gs.stop_command);
+ vty_out(vty, " Min Restart Interval: %ld\n", gs.min_restart_interval);
+ vty_out(vty, " Max Restart Interval: %ld\n", gs.max_restart_interval);
+ vty_out(vty, " Restart Timeout: %ld\n", gs.restart_timeout);
if (gs.restart.pid)
vty_out(vty, " global restart running, pid %ld\n",
(long)gs.restart.pid);
@@ -1395,6 +1424,18 @@ int main(int argc, char **argv)
frr_help_exit(1);
}
} break;
+ case OPTION_MAXOPERATIONAL: {
+ char garbage[3];
+
+ if ((sscanf(optarg, "%ld%1s", &gs.operational_timeout,
+ garbage) != 1) ||
+ (gs.max_restart_interval < 0)) {
+ fprintf(stderr,
+ "Invalid Operational_timeout argument: %s\n",
+ optarg);
+ frr_help_exit(1);
+ }
+ } break;
case OPTION_NETNS:
netns_en = true;
if (optarg && strchr(optarg, '/')) {
diff --git a/yang/frr-bgp-bmp.yang b/yang/frr-bgp-bmp.yang
index cf945cabef..8c3de839b6 100644
--- a/yang/frr-bgp-bmp.yang
+++ b/yang/frr-bgp-bmp.yang
@@ -86,7 +86,7 @@ submodule frr-bgp-bmp {
type uint32 {
range "100..86400000";
}
- units "miliseconds";
+ units "milliseconds";
default "30000";
description
"Minimum connection retry interval.";
@@ -96,7 +96,7 @@ submodule frr-bgp-bmp {
type uint32 {
range "100..86400000";
}
- units "miliseconds";
+ units "milliseconds";
default "720000";
description
"Maximum connection retry interval.";
@@ -170,7 +170,7 @@ submodule frr-bgp-bmp {
type uint32 {
range "100..86400000";
}
- units "miliseconds";
+ units "milliseconds";
description
"Interval to send BMP Stats.";
}
diff --git a/yang/frr-bgp-common-structure.yang b/yang/frr-bgp-common-structure.yang
index 3378c10c03..4c12b956c4 100644
--- a/yang/frr-bgp-common-structure.yang
+++ b/yang/frr-bgp-common-structure.yang
@@ -159,7 +159,7 @@ submodule frr-bgp-common-structure {
type uint16 {
range "50..60000";
}
- units "miliseconds";
+ units "milliseconds";
default "300";
description
"Required min receive interval.";
@@ -170,7 +170,7 @@ submodule frr-bgp-common-structure {
type uint16 {
range "50..60000";
}
- units "miliseconds";
+ units "milliseconds";
default "300";
description
"Desired min transmit interval.";
diff --git a/yang/frr-bgp-common.yang b/yang/frr-bgp-common.yang
index 157e4cd614..2b1babdd28 100644
--- a/yang/frr-bgp-common.yang
+++ b/yang/frr-bgp-common.yang
@@ -444,7 +444,7 @@ submodule frr-bgp-common {
type uint32 {
range "0..4294967295";
}
- units "miliseconds";
+ units "milliseconds";
default "1000";
description
"Configures the Subgroup coalesce timer.";
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index f2cf9122fa..2ff083dec5 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -3273,7 +3273,7 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
memcpy(&mac, RTA_DATA(tb[NDA_LLADDR]), ETH_ALEN);
- if ((NDA_VLAN <= NDA_MAX) && tb[NDA_VLAN]) {
+ if (tb[NDA_VLAN]) {
vid_present = 1;
vid = *(uint16_t *)RTA_DATA(tb[NDA_VLAN]);
snprintf(vid_buf, sizeof(vid_buf), " VLAN %u", vid);
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 2ce5072945..ca833999cb 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -490,9 +490,11 @@ static void rtadv_timer(struct thread *thread)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
FOR_ALL_INTERFACES (vrf, ifp) {
- if (if_is_loopback(ifp) || !if_is_operative(ifp)
- || (vrf_is_backend_netns()
- && ifp->vrf->vrf_id != zvrf->vrf->vrf_id))
+ if (if_is_loopback(ifp) || !if_is_operative(ifp) ||
+ IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) ||
+ !connected_get_linklocal(ifp) ||
+ (vrf_is_backend_netns() &&
+ ifp->vrf->vrf_id != zvrf->vrf->vrf_id))
continue;
zif = ifp->info;
diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c
index d9d21462fb..d223a21eda 100644
--- a/zebra/zebra_evpn.c
+++ b/zebra/zebra_evpn.c
@@ -649,10 +649,9 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns,
struct zebra_l2info_vxlan *vxl = NULL;
struct zebra_from_svi_param *in_param =
(struct zebra_from_svi_param *)_in_param;
- int found = 0;
- if (!in_param)
- return NS_WALK_STOP;
+ assert(p_zevpn && in_param);
+
br_if = in_param->br_if;
zif = in_param->zif;
assert(zif);
@@ -676,17 +675,13 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns,
if (!in_param->bridge_vlan_aware
|| vxl->access_vlan == in_param->vid) {
- found = 1;
- break;
+ zevpn = zebra_evpn_lookup(vxl->vni);
+ *p_zevpn = zevpn;
+ return NS_WALK_STOP;
}
}
- if (!found)
- return NS_WALK_CONTINUE;
- zevpn = zebra_evpn_lookup(vxl->vni);
- if (p_zevpn)
- *p_zevpn = zevpn;
- return NS_WALK_STOP;
+ return NS_WALK_CONTINUE;
}
/*
@@ -831,8 +826,7 @@ static int zvni_map_to_macvlan_ns(struct ns *ns,
struct interface *tmp_if = NULL;
struct zebra_if *zif;
- if (!in_param)
- return NS_WALK_STOP;
+ assert(in_param && p_ifp);
/* Identify corresponding VLAN interface. */
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
@@ -846,8 +840,7 @@ static int zvni_map_to_macvlan_ns(struct ns *ns,
continue;
if (zif->link == in_param->svi_if) {
- if (p_ifp)
- *p_ifp = tmp_if;
+ *p_ifp = tmp_if;
return NS_WALK_STOP;
}
}
diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c
index 46d789bc34..128d233969 100644
--- a/zebra/zebra_evpn_mac.c
+++ b/zebra/zebra_evpn_mac.c
@@ -1872,7 +1872,7 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(
return mac;
}
-/* update local fowarding info. return true if a dest-ES change
+/* update local forwarding info. return true if a dest-ES change
* is detected
*/
static bool zebra_evpn_local_mac_update_fwd_info(struct zebra_mac *mac,
diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c
index a4272dd82e..b1e48374c4 100644
--- a/zebra/zebra_evpn_mh.c
+++ b/zebra/zebra_evpn_mh.c
@@ -3286,7 +3286,7 @@ DEFPY_HIDDEN(zebra_evpn_es_bypass, zebra_evpn_es_bypass_cmd,
} else {
if (!zebra_evpn_is_if_es_capable(zif)) {
vty_out(vty,
- "%%DF bypass cannot be associated with this interface type\n");
+ "%% DF bypass cannot be associated with this interface type\n");
return CMD_WARNING;
}
zebra_evpn_es_bypass_cfg_update(zif, true);
@@ -3311,7 +3311,7 @@ DEFPY(zebra_evpn_es_pref, zebra_evpn_es_pref_cmd,
} else {
if (!zebra_evpn_is_if_es_capable(zif)) {
vty_out(vty,
- "%%DF preference cannot be associated with this interface type\n");
+ "%% DF preference cannot be associated with this interface type\n");
return CMD_WARNING;
}
zebra_evpn_es_df_pref_update(zif, df_pref);
@@ -3341,25 +3341,26 @@ DEFPY(zebra_evpn_es_sys_mac,
ret = zebra_evpn_es_sys_mac_update(zif, &zero_mac);
if (ret == -1) {
- vty_out(vty, "%%Failed to clear ES sysmac\n");
+ vty_out(vty, "%% Failed to clear ES sysmac\n");
return CMD_WARNING;
}
} else {
if (!zebra_evpn_is_if_es_capable(zif)) {
vty_out(vty,
- "%%ESI cannot be associated with this interface type\n");
+ "%% ESI cannot be associated with this interface type\n");
return CMD_WARNING;
}
if (!mac || is_zero_mac(&mac->eth_addr)) {
- vty_out(vty, "%%ES sysmac value is invalid\n");
+ vty_out(vty, "%% ES sysmac value is invalid\n");
return CMD_WARNING;
}
ret = zebra_evpn_es_sys_mac_update(zif, &mac->eth_addr);
if (ret == -1) {
- vty_out(vty, "%%ESI already exists on a different interface\n");
+ vty_out(vty,
+ "%% ESI already exists on a different interface\n");
return CMD_WARNING;
}
}
@@ -3392,25 +3393,27 @@ DEFPY(zebra_evpn_es_id,
ret = zebra_evpn_es_type0_esi_update(zif, zero_esi);
if (ret == -1) {
- vty_out(vty, "%%Failed to clear ES local id\n");
+ vty_out(vty,
+ "%% Failed to clear ES local id or ESI name\n");
return CMD_WARNING;
}
} else {
if (!zebra_evpn_is_if_es_capable(zif)) {
vty_out(vty,
- "%%ESI cannot be associated with this interface type\n");
+ "%% ESI cannot be associated with this interface type\n");
return CMD_WARNING;
}
if (esi_str) {
if (!str_to_esi(esi_str, &esi)) {
- vty_out(vty, "%% Malformed ESI\n");
+ vty_out(vty, "%% Malformed ESI name\n");
return CMD_WARNING;
}
ret = zebra_evpn_es_type0_esi_update(zif, &esi);
} else {
if (!es_lid) {
- vty_out(vty, "%%Specify local ES ID\n");
+ vty_out(vty,
+ "%% Specify ES local id or ESI name\n");
return CMD_WARNING;
}
ret = zebra_evpn_es_lid_update(zif, es_lid);
@@ -3418,7 +3421,7 @@ DEFPY(zebra_evpn_es_id,
if (ret == -1) {
vty_out(vty,
- "%%ESI already exists on a different interface\n");
+ "%% ESI already exists on a different interface\n");
return CMD_WARNING;
}
}
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index 1b926dba5f..d1a34d0962 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -43,6 +43,7 @@
#include "zebra_dplane.h"
#include "zebra/interface.h"
#include "zebra/zapi_msg.h"
+#include "zebra/rib.h"
DEFINE_MTYPE_STATIC(ZEBRA, NHG, "Nexthop Group Entry");
DEFINE_MTYPE_STATIC(ZEBRA, NHG_CONNECTED, "Nexthop Group Connected");
@@ -1960,6 +1961,61 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop,
}
/*
+ * So this nexthop resolution has decided that a connected route
+ * is the correct choice. At this point in time if FRR has multiple
+ * connected routes that all point to the same prefix one will be
+ * selected, *but* the particular interface may not be the one
+ * that the nexthop points at. Let's look at all the available
+ * connected routes on this node and if any of them auto match
+ * the routes nexthops ifindex that is good enough for a match
+ *
+ * This code is depending on the fact that a nexthop->ifindex is 0
+ * if it is not known, if this assumption changes, yummy!
+ * Additionally a ifindx of 0 means figure it out for us.
+ */
+static struct route_entry *
+zebra_nhg_connected_ifindex(struct route_node *rn, struct route_entry *match,
+ int32_t curr_ifindex)
+{
+ struct nexthop *newhop = match->nhe->nhg.nexthop;
+ struct route_entry *re;
+
+ assert(newhop); /* What a kick in the patooey */
+
+ if (curr_ifindex == 0)
+ return match;
+
+ if (curr_ifindex == newhop->ifindex)
+ return match;
+
+ /*
+ * At this point we know that this route is matching a connected
+ * but there are possibly a bunch of connected routes that are
+ * alive that should be considered as well. So let's iterate over
+ * all the re's and see if they are connected as well and maybe one
+ * of those ifindexes match as well.
+ */
+ RNODE_FOREACH_RE (rn, re) {
+ if (re->type != ZEBRA_ROUTE_CONNECT)
+ continue;
+
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+ continue;
+
+ /*
+ * zebra has a connected route that is not removed
+ * let's test if it is good
+ */
+ newhop = re->nhe->nhg.nexthop;
+ assert(newhop);
+ if (curr_ifindex == newhop->ifindex)
+ return re;
+ }
+
+ return match;
+}
+
+/*
* Given a nexthop we need to properly recursively resolve,
* do a table lookup to find and match if at all possible.
* Set the nexthop->ifindex and resolution info as appropriate.
@@ -2209,25 +2265,25 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe,
continue;
}
- if (match->type == ZEBRA_ROUTE_CONNECT) {
- /* Directly point connected route. */
+ if ((match->type == ZEBRA_ROUTE_CONNECT) ||
+ (RIB_SYSTEM_ROUTE(match) && RSYSTEM_ROUTE(type))) {
+ match = zebra_nhg_connected_ifindex(rn, match,
+ nexthop->ifindex);
+
newhop = match->nhe->nhg.nexthop;
- if (newhop) {
- if (nexthop->type == NEXTHOP_TYPE_IPV4
- || nexthop->type == NEXTHOP_TYPE_IPV6)
- nexthop->ifindex = newhop->ifindex;
- else if (nexthop->ifindex != newhop->ifindex) {
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug(
- "%s: %pNHv given ifindex does not match nexthops ifindex found found: %pNHv",
- __func__, nexthop,
- newhop);
- /*
- * NEXTHOP_TYPE_*_IFINDEX but ifindex
- * doesn't match what we found.
- */
- return 0;
- }
+ if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
+ nexthop->type == NEXTHOP_TYPE_IPV6)
+ nexthop->ifindex = newhop->ifindex;
+ else if (nexthop->ifindex != newhop->ifindex) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "%s: %pNHv given ifindex does not match nexthops ifindex found: %pNHv",
+ __func__, nexthop, newhop);
+ /*
+ * NEXTHOP_TYPE_*_IFINDEX but ifindex
+ * doesn't match what we found.
+ */
+ return 0;
}
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c
index ebe0fffcb2..62ce17326c 100644
--- a/zebra/zebra_srv6_vty.c
+++ b/zebra/zebra_srv6_vty.c
@@ -354,8 +354,12 @@ static int zebra_sr_config(struct vty *vty)
inet_ntop(AF_INET6, &locator->prefix.prefix,
str, sizeof(str));
vty_out(vty, " locator %s\n", locator->name);
- vty_out(vty, " prefix %s/%u\n", str,
+ vty_out(vty, " prefix %s/%u", str,
locator->prefix.prefixlen);
+ if (locator->function_bits_length)
+ vty_out(vty, " func-bits %u",
+ locator->function_bits_length);
+ vty_out(vty, "\n");
vty_out(vty, " exit\n");
vty_out(vty, " !\n");
}
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 13e1f63457..fc7eb8c87a 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -1754,6 +1754,8 @@ static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
if (!zvrf)
return NS_WALK_STOP;
+ assert(_pifp);
+
/* loop through all vxlan-interface */
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
@@ -1784,8 +1786,7 @@ static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
zl3vni->local_vtep_ip = vxl->vtep_ip;
- if (_pifp)
- *_pifp = (void *)ifp;
+ *_pifp = (void *)ifp;
return NS_WALK_STOP;
}
@@ -1856,7 +1857,6 @@ struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id)
static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
{
- int found = 0;
struct zebra_ns *zns = ns->info;
struct zebra_l3vni **p_zl3vni = (struct zebra_l3vni **)_p_zl3vni;
struct zebra_from_svi_param *in_param =
@@ -1866,8 +1866,7 @@ static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL;
- if (!in_param)
- return NS_WALK_STOP;
+ assert(in_param && p_zl3vni);
/* loop through all vxlan-interface */
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
@@ -1886,17 +1885,12 @@ static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
if (!in_param->bridge_vlan_aware
|| vxl->access_vlan == in_param->vid) {
- found = 1;
- break;
+ *p_zl3vni = zl3vni_lookup(vxl->vni);
+ return NS_WALK_STOP;
}
}
- if (!found)
- return NS_WALK_CONTINUE;
-
- if (p_zl3vni)
- *p_zl3vni = zl3vni_lookup(vxl->vni);
- return NS_WALK_STOP;
+ return NS_WALK_CONTINUE;
}
/*
@@ -5130,8 +5124,13 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
vlan_if = zvni_map_to_svi(vxl->access_vlan,
zif->brslave_info.br_if);
- if (vlan_if)
+ if (vlan_if) {
zevpn->svi_if = vlan_if;
+ zevpn->vrf_id = vlan_if->vrf->vrf_id;
+ zl3vni = zl3vni_from_vrf(vlan_if->vrf->vrf_id);
+ if (zl3vni)
+ listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
+ }
/* Take further actions needed.
* Note that if we are here, there is a change of interest.
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 630c76c989..403f6c0d99 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -172,7 +172,7 @@ void zserv_log_message(const char *errmsg, struct stream *msg,
}
/*
- * Gracefully shut down a client connection.
+ * Gracefuly shut down a client connection.
*
* Cancel any pending tasks for the client's thread. Then schedule a task on
* the main thread to shut down the calling thread.
@@ -568,7 +568,7 @@ DEFINE_KOOH(zserv_client_close, (struct zserv *client), (client));
* Deinitialize zebra client.
*
* - Deregister and deinitialize related internal resources
- * - Gracefully close socket
+ * - Gracefuly close socket
* - Free associated resources
* - Free client structure
*