summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alpine/APKBUILD.in6
-rw-r--r--bgpd/bgp_evpn.c15
-rw-r--r--bgpd/bgp_evpn_mh.c6
-rw-r--r--bgpd/bgp_mplsvpn.c4
-rw-r--r--bgpd/bgp_route.c35
-rw-r--r--bgpd/bgp_vty.c77
-rw-r--r--bgpd/bgpd.h2
-rw-r--r--bgpd/rfapi/rfapi.c27
-rw-r--r--bgpd/rfapi/rfapi_rib.c19
-rw-r--r--bgpd/rfapi/rfapi_vty.c1
-rw-r--r--configure.ac16
-rw-r--r--doc/developer/logging.rst45
-rw-r--r--doc/user/bgp.rst11
-rw-r--r--doc/user/isisd.rst4
-rw-r--r--doc/user/mgmtd.rst11
-rw-r--r--doc/user/ospfd.rst12
-rw-r--r--doc/user/pim.rst9
-rw-r--r--docker/ubi-8/Dockerfile83
-rw-r--r--docker/ubi8-minimal/Dockerfile132
-rw-r--r--docker/ubi8-minimal/almalinux.repo23
-rwxr-xr-xdocker/ubi8-minimal/build.sh (renamed from docker/ubi-8/build.sh)22
-rwxr-xr-xdocker/ubi8-minimal/docker-start (renamed from docker/ubi-8/docker-start)0
-rw-r--r--isisd/fabricd.c13
-rw-r--r--isisd/isis_adjacency.c48
-rw-r--r--isisd/isis_adjacency.h2
-rw-r--r--isisd/isis_circuit.c14
-rw-r--r--isisd/isis_cli.c21
-rw-r--r--isisd/isis_common.h8
-rw-r--r--isisd/isis_dynhn.c6
-rw-r--r--isisd/isis_events.c4
-rw-r--r--isisd/isis_lfa.c4
-rw-r--r--isisd/isis_lsp.c127
-rw-r--r--isisd/isis_misc.c102
-rw-r--r--isisd/isis_misc.h5
-rw-r--r--isisd/isis_mt.c15
-rw-r--r--isisd/isis_nb.c7
-rw-r--r--isisd/isis_nb.h3
-rw-r--r--isisd/isis_nb_config.c28
-rw-r--r--isisd/isis_nb_notifications.c36
-rw-r--r--isisd/isis_nb_state.c10
-rw-r--r--isisd/isis_pdu.c185
-rw-r--r--isisd/isis_pdu.h2
-rw-r--r--isisd/isis_pdu_counter.c22
-rw-r--r--isisd/isis_pdu_counter.h2
-rw-r--r--isisd/isis_snmp.c24
-rw-r--r--isisd/isis_spf.c18
-rw-r--r--isisd/isis_sr.c16
-rw-r--r--isisd/isis_te.c14
-rw-r--r--isisd/isis_tlvs.c102
-rw-r--r--isisd/isis_tx_queue.c17
-rw-r--r--isisd/isisd.c58
-rw-r--r--isisd/isisd.h5
-rw-r--r--lib/if_rmap.c292
-rw-r--r--lib/if_rmap.h12
-rw-r--r--lib/iso.c144
-rw-r--r--lib/iso.h49
-rw-r--r--lib/link_state.c25
-rw-r--r--lib/mgmt_be_client.c15
-rw-r--r--lib/mgmt_fe_client.c29
-rw-r--r--lib/subdir.am3
-rw-r--r--mgmtd/mgmt_be_adapter.c12
-rw-r--r--mgmtd/mgmt_be_server.c2
-rw-r--r--mgmtd/mgmt_ds.c5
-rw-r--r--mgmtd/mgmt_fe_adapter.c26
-rw-r--r--mgmtd/mgmt_fe_server.c2
-rw-r--r--mgmtd/mgmt_history.c17
-rw-r--r--mgmtd/mgmt_history.h10
-rw-r--r--mgmtd/mgmt_txn.c41
-rw-r--r--mgmtd/mgmt_vty.c2
-rw-r--r--ospfd/ospf_interface.c28
-rw-r--r--ospfd/ospf_interface.h3
-rw-r--r--ospfd/ospf_lsa.c22
-rw-r--r--ospfd/ospf_network.c136
-rw-r--r--ospfd/ospf_network.h15
-rw-r--r--ospfd/ospf_packet.c23
-rw-r--r--ospfd/ospf_vty.c107
-rw-r--r--ospfd/ospfd.c30
-rw-r--r--ospfd/ospfd.h13
-rw-r--r--pimd/pim_cmd.c725
-rw-r--r--pimd/pim_cmd.h1
-rw-r--r--ripd/rip_nb.c21
-rw-r--r--ripd/rip_nb.h12
-rw-r--r--ripd/rip_nb_config.c90
-rw-r--r--ripd/ripd.c13
-rw-r--r--ripngd/ripng_nb.c21
-rw-r--r--ripngd/ripng_nb.h12
-rw-r--r--ripngd/ripng_nb_config.c89
-rw-r--r--tests/lib/subdir.am2
-rwxr-xr-xtests/topotests/bgp_evpn_vxlan_svd_topo1/test_bgp_evpn_vxlan_svd.py50
-rwxr-xr-xtests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py18
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py19
-rw-r--r--tests/topotests/bgp_lu_explicitnull/r1/bgpd.conf15
-rw-r--r--tests/topotests/bgp_lu_explicitnull/r1/zebra.conf6
-rw-r--r--tests/topotests/bgp_lu_explicitnull/r2/bgpd.conf15
-rw-r--r--tests/topotests/bgp_lu_explicitnull/r2/zebra.conf6
-rw-r--r--tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py194
-rw-r--r--tests/topotests/multicast_pim_sm_topo3/igmp_group_all_detail.json1
-rw-r--r--tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_brief.json51
-rw-r--r--tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_detail.json1
-rw-r--r--tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_brief.json22
-rw-r--r--tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_detail.json1
-rw-r--r--tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_group_all.json61
-rw-r--r--tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_single_group.json16
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py108
-rw-r--r--tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py5
-rw-r--r--yang/frr-if-rmap.yang80
-rw-r--r--yang/frr-isisd.yang7
-rw-r--r--yang/frr-ripd.yang6
-rw-r--r--yang/frr-ripngd.yang6
-rw-r--r--yang/subdir.am1
-rw-r--r--zebra/interface.c23
-rw-r--r--zebra/interface.h3
-rw-r--r--zebra/zebra_dplane.c9
-rw-r--r--zebra/zebra_rib.c3
114 files changed, 3103 insertions, 1151 deletions
diff --git a/alpine/APKBUILD.in b/alpine/APKBUILD.in
index 676f9a7a39..fd3c02f47e 100644
--- a/alpine/APKBUILD.in
+++ b/alpine/APKBUILD.in
@@ -18,7 +18,8 @@ makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
ncurses-libs ncurses-terminfo ncurses-terminfo-base patch pax-utils pcre2
perl pkgconf python3 python3-dev readline readline-dev sqlite-libs pcre2-dev
squashfs-tools sudo tar texinfo xorriso xz-libs py-pip rtrlib rtrlib-dev
- py3-sphinx elfutils elfutils-dev libyang-dev protobuf-c-compiler protobuf-c-dev"
+ py3-sphinx elfutils elfutils-dev libyang-dev protobuf-c-compiler protobuf-c-dev
+ lua5.3-dev lua5.3"
checkdepends="pytest py-setuptools"
install="$pkgname.pre-install $pkgname.pre-deinstall $pkgname.post-deinstall"
subpackages="$pkgname-dev $pkgname-doc $pkgname-dbg"
@@ -47,7 +48,8 @@ build() {
--enable-vty-group=frrvty \
--enable-user=$_user \
--enable-group=$_user \
- --enable-pcre2posix
+ --enable-pcre2posix \
+ --enable-scripting
make -j $(nproc)
}
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 96feb19c29..81117e94ef 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -6235,6 +6235,14 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id,
l3vni);
return -1;
}
+
+ if (CHECK_FLAG(bgp_evpn->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
+ flog_err(EC_BGP_NO_DFLT,
+ "Cannot process L3VNI %u ADD - EVPN BGP instance is shutting down",
+ l3vni);
+ return -1;
+ }
+
as = bgp_evpn->as;
/* if the BGP vrf instance doesn't exist - create one */
@@ -6377,6 +6385,13 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id)
return -1;
}
+ if (CHECK_FLAG(bgp_evpn->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
+ flog_err(EC_BGP_NO_DFLT,
+ "Cannot process L3VNI %u ADD - EVPN BGP instance is shutting down",
+ l3vni);
+ return -1;
+ }
+
/* Remove remote routes from BGT VRF even if BGP_VRF_AUTO is configured,
* bgp_delete would not remove/decrement bgp_path_info of the ip_prefix
* routes. This will uninstalling the routes from zebra and decremnt the
diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c
index d821d4d582..4aff93514f 100644
--- a/bgpd/bgp_evpn_mh.c
+++ b/bgpd/bgp_evpn_mh.c
@@ -1071,7 +1071,8 @@ void update_type1_routes_for_evi(struct bgp *bgp, struct bgpevpn *vpn)
continue;
/* Update EAD-ES */
- bgp_evpn_ead_es_route_update(bgp, es);
+ if (bgp_evpn_local_es_is_active(es))
+ bgp_evpn_ead_es_route_update(bgp, es);
/* Update EAD-EVI */
if (CHECK_FLAG(es->flags, BGP_EVPNES_ADV_EVI)) {
@@ -2608,6 +2609,9 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
listcount(es->macip_global_path_list));
json_object_int_add(json, "inconsistentVniVtepCount",
es->incons_evi_vtep_cnt);
+ if (es->flags & BGP_EVPNES_LOCAL)
+ json_object_int_add(json, "localEsDfPreference",
+ es->df_pref);
if (listcount(es->es_vtep_list)) {
json_vteps = json_object_new_array();
for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node,
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index c08f95cdf4..63168f1e7a 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1103,7 +1103,7 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
struct bgp_path_info *new;
struct bgp_path_info_extra *extra;
uint32_t num_sids = 0;
- void *parent = source_bpi;
+ struct bgp_path_info *parent = source_bpi;
if (new_attr->srv6_l3vpn || new_attr->srv6_vpn)
num_sids = 1;
@@ -1311,7 +1311,7 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
new->extra->parent = bgp_path_info_lock(parent);
bgp_dest_lock_node(
- (struct bgp_dest *)((struct bgp_path_info *)parent)->net);
+ (struct bgp_dest *)parent->net);
if (bgp_orig)
new->extra->bgp_orig = bgp_lock(bgp_orig);
if (nexthop_orig)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a23bffd4ae..b49206adce 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3070,7 +3070,9 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
* the IMPLICIT_NULL label. This is pretty specialized: it's only called
* in a path where we basically _know_ this is a BGP-LU route.
*/
-static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
+static bool bgp_lu_need_null_label(struct bgp *bgp,
+ const struct bgp_path_info *new_select,
+ afi_t afi, mpls_label_t *label)
{
/* Certain types get imp null; so do paths where the nexthop is
* not labeled.
@@ -3079,12 +3081,20 @@ static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
|| new_select->sub_type == BGP_ROUTE_AGGREGATE
|| new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
return true;
- else if (new_select->extra == NULL ||
- !bgp_is_valid_label(&new_select->extra->label[0]))
- /* TODO -- should be configurable? */
+ else if (new_select->extra &&
+ bgp_is_valid_label(&new_select->extra->label[0]))
+ return false;
+ if (label == NULL)
return true;
+ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
+ /* Disable PHP : explicit-null */
+ *label = afi == AFI_IP ? MPLS_LABEL_IPV4_EXPLICIT_NULL
+ : MPLS_LABEL_IPV6_EXPLICIT_NULL;
else
- return false;
+ /* Enforced PHP popping: implicit-null */
+ *label = MPLS_LABEL_IMPLICIT_NULL;
+
+ return true;
}
/*
@@ -3113,6 +3123,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
struct bgp_path_info *old_select;
struct bgp_path_info_pair old_and_new;
int debug = 0;
+ mpls_label_t mpls_label_null;
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
if (dest)
@@ -3167,7 +3178,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
* Right now, since we only deal with per-prefix labels, it is not
* necessary to do this upon changes to best path. Exceptions:
* - label index has changed -> recalculate resulting label
- * - path_info sub_type changed -> switch to/from implicit-null
+ * - path_info sub_type changed -> switch to/from null label value
* - no valid label (due to removed static label binding) -> get new one
*/
if (bgp->allocate_mpls_labels[afi][safi]) {
@@ -3176,11 +3187,12 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
|| bgp_label_index_differs(new_select, old_select)
|| new_select->sub_type != old_select->sub_type
|| !bgp_is_valid_label(&dest->local_label)) {
- /* Enforced penultimate hop popping:
- * implicit-null for local routes, aggregate
- * and redistributed routes
+ /* control label imposition for local routes,
+ * aggregate and redistributed routes
*/
- if (bgp_lu_need_imp_null(new_select)) {
+ mpls_label_null = MPLS_LABEL_IMPLICIT_NULL;
+ if (bgp_lu_need_null_label(bgp, new_select, afi,
+ &mpls_label_null)) {
if (CHECK_FLAG(
dest->flags,
BGP_NODE_REGISTERED_FOR_LABEL)
@@ -3189,8 +3201,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
BGP_NODE_LABEL_REQUESTED))
bgp_unregister_for_label(dest);
dest->local_label = mpls_lse_encode(
- MPLS_LABEL_IMPLICIT_NULL, 0, 0,
- 1);
+ mpls_label_null, 0, 0, 1);
bgp_set_valid_label(&dest->local_label);
} else
bgp_register_for_label(dest,
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index a436490ba1..de781d6b1e 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1675,28 +1675,46 @@ DEFUN (no_router_bgp,
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, tmp_bgp)) {
if (tmp_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
continue;
- if (CHECK_FLAG(tmp_bgp->af_flags[AFI_IP][SAFI_UNICAST],
- BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_IP6][SAFI_UNICAST],
- BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_IP][SAFI_UNICAST],
- BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_IP6][SAFI_UNICAST],
- BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_IP][SAFI_UNICAST],
+ if (CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_IP]
+ [SAFI_UNICAST],
+ BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT) ||
+ CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_IP6]
+ [SAFI_UNICAST],
+ BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT) ||
+ CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_IP]
+ [SAFI_UNICAST],
+ BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) ||
+ CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_IP6]
+ [SAFI_UNICAST],
+ BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT) ||
+ CHECK_FLAG(tmp_bgp->af_flags[AFI_IP]
+ [SAFI_UNICAST],
BGP_CONFIG_VRF_TO_VRF_EXPORT) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_IP6][SAFI_UNICAST],
+ CHECK_FLAG(tmp_bgp->af_flags[AFI_IP6]
+ [SAFI_UNICAST],
BGP_CONFIG_VRF_TO_VRF_EXPORT) ||
(bgp == bgp_get_evpn() &&
- (CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
- BGP_L2VPN_EVPN_ADV_IPV4_UNICAST) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
- BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
- BGP_L2VPN_EVPN_ADV_IPV6_UNICAST) ||
- CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
- BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))) ||
- (hashcount(tmp_bgp->vnihash))) {
+ (CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_L2VPN]
+ [SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADV_IPV4_UNICAST) ||
+ CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_L2VPN]
+ [SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP) ||
+ CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_L2VPN]
+ [SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADV_IPV6_UNICAST) ||
+ CHECK_FLAG(
+ tmp_bgp->af_flags[AFI_L2VPN]
+ [SAFI_EVPN],
+ BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))) ||
+ (tmp_bgp->l3vni)) {
vty_out(vty,
"%% Cannot delete default BGP instance. Dependent VRF instances exist\n");
return CMD_WARNING_CONFIG_FAILED;
@@ -2802,6 +2820,21 @@ DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd,
return CMD_SUCCESS;
}
+DEFPY(bgp_lu_uses_explicit_null, bgp_lu_uses_explicit_null_cmd,
+ "[no] bgp labeled-unicast explicit-null",
+ NO_STR BGP_STR
+ "BGP Labeled-unicast options\n"
+ "Use explicit-null label values for local prefixes\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (no)
+ UNSET_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL);
+ else
+ SET_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL);
+ return CMD_SUCCESS;
+}
+
DEFUN(bgp_suppress_duplicates, bgp_suppress_duplicates_cmd,
"bgp suppress-duplicates",
BGP_STR
@@ -18217,6 +18250,9 @@ int bgp_config_write(struct vty *vty)
? ""
: "no ");
+ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
+ vty_out(vty, " bgp labeled-unicast explicit-null\n");
+
/* draft-ietf-idr-deprecate-as-set-confed-set */
if (bgp->reject_as_sets)
vty_out(vty, " bgp reject-as-sets\n");
@@ -19136,6 +19172,9 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &bgp_ebgp_requires_policy_cmd);
install_element(BGP_NODE, &no_bgp_ebgp_requires_policy_cmd);
+ /* bgp labeled-unicast explicit-null */
+ install_element(BGP_NODE, &bgp_lu_uses_explicit_null_cmd);
+
/* bgp suppress-duplicates */
install_element(BGP_NODE, &bgp_suppress_duplicates_cmd);
install_element(BGP_NODE, &no_bgp_suppress_duplicates_cmd);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index a08a2870ee..b6491bf799 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -500,6 +500,8 @@ struct bgp {
#define BGP_FLAG_HARD_ADMIN_RESET (1ULL << 31)
/* Evaluate the AIGP attribute during the best path selection process */
#define BGP_FLAG_COMPARE_AIGP (1ULL << 32)
+/* For BGP-LU, force local prefixes to use explicit-null label */
+#define BGP_FLAG_LU_EXPLICIT_NULL (1ULL << 33)
/* BGP default address-families.
* New peers inherit enabled afi/safis from bgp instance.
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index 8d6db9d775..67c70431bd 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -51,6 +51,8 @@
#include <execinfo.h>
#endif /* HAVE_GLIBC_BACKTRACE */
+#define DEBUG_CLEANUP 0
+
struct ethaddr rfapi_ethaddr0 = {{0}};
#define DEBUG_RFAPI_STR "RF API debugging/testing command\n"
@@ -3677,11 +3679,36 @@ void rfapi_delete(struct bgp *bgp)
{
extern void rfp_clear_vnc_nve_all(void); /* can't fix correctly yet */
+#if DEBUG_CLEANUP
+ zlog_debug("%s: bgp %p", __func__, bgp);
+#endif
+
/*
* This clears queries and registered routes, and closes nves
*/
if (bgp->rfapi)
rfp_clear_vnc_nve_all();
+
+ /*
+ * close any remaining descriptors
+ */
+ struct rfapi *h = bgp->rfapi;
+
+ if (h && h->descriptors.count) {
+ struct listnode *node, *nnode;
+ struct rfapi_descriptor *rfd;
+#if DEBUG_CLEANUP
+ zlog_debug("%s: descriptor count %u", __func__,
+ h->descriptors.count);
+#endif
+ for (ALL_LIST_ELEMENTS(&h->descriptors, node, nnode, rfd)) {
+#if DEBUG_CLEANUP
+ zlog_debug("%s: closing rfd %p", __func__, rfd);
+#endif
+ (void)rfapi_close(rfd);
+ }
+ }
+
bgp_rfapi_cfg_destroy(bgp, bgp->rfapi_cfg);
bgp->rfapi_cfg = NULL;
bgp_rfapi_destroy(bgp, bgp->rfapi);
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index be9d30768c..5784f95b27 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -40,6 +40,7 @@
#define DEBUG_PENDING_DELETE_ROUTE 0
#define DEBUG_NHL 0
#define DEBUG_RIB_SL_RD 0
+#define DEBUG_CLEANUP 0
/* forward decl */
#if DEBUG_NHL
@@ -327,6 +328,11 @@ static void rfapiRibStartTimer(struct rfapi_descriptor *rfd,
tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE,
sizeof(struct rfapi_rib_tcb));
}
+#if DEBUG_CLEANUP
+ zlog_debug("%s: rfd %p, rn %p, ri %p, tcb %p", __func__, rfd, rn, ri,
+ tcb);
+#endif
+
tcb->rfd = rfd;
tcb->ri = ri;
tcb->rn = rn;
@@ -506,6 +512,16 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
NULL,
(void **)&ri)) {
+ if (ri->timer) {
+ struct rfapi_rib_tcb
+ *tcb;
+
+ tcb = EVENT_ARG(
+ ri->timer);
+ EVENT_OFF(ri->timer);
+ XFREE(MTYPE_RFAPI_RECENT_DELETE,
+ tcb);
+ }
rfapi_info_free(ri);
skiplist_delete_first(
(struct skiplist *)
@@ -555,6 +571,9 @@ void rfapiRibFree(struct rfapi_descriptor *rfd)
{
afi_t afi;
+#if DEBUG_CLEANUP
+ zlog_debug("%s: rfd %p", __func__, rfd);
+#endif
/*
* NB rfd is typically detached from master list, so is not included
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index 2877c29c20..29698846c3 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -4888,6 +4888,7 @@ static int vnc_clear_vrf(struct vty *vty, struct bgp *bgp, const char *arg_vrf,
clear_vnc_prefix(&cda);
vty_out(vty, "Cleared %u out of %d prefixes.\n", cda.pfx_count,
start_count);
+ print_cleared_stats(&cda); /* frees lists in cda */
return CMD_SUCCESS;
}
diff --git a/configure.ac b/configure.ac
index f3968df2aa..79288c67e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -299,14 +299,20 @@ if test "$enable_scripting" = "yes"; then
AX_LUA_HEADERS([], [
AC_MSG_ERROR([Lua 5.3 headers are required to build with Lua support. No other version is supported.])
])
- AX_LUA_LIBS([
+ PKG_CHECK_MODULES([LUA], [lua5.3], [
AC_DEFINE([HAVE_SCRIPTING], [1], [Have support for scripting])
- LIBS="$LIBS $LUA_LIB"
+ LIBS="$LIBS $LUA_LIBS"
SCRIPTING=true
], [
- SCRIPTING=false
- AC_MSG_ERROR([Lua 5.3 libraries are required to build with Lua support. No other version is supported.])
- ])
+ AX_LUA_LIBS([
+ AC_DEFINE([HAVE_SCRIPTING], [1], [Have support for scripting])
+ LIBS="$LIBS $LUA_LIB"
+ SCRIPTING=true
+ ], [
+ SCRIPTING=false
+ AC_MSG_ERROR([Lua 5.3 libraries are required to build with Lua support. No other version is supported.])
+ ])
+ ])
fi
dnl the following flags go in CFLAGS rather than AC_CFLAGS since they make
diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst
index b7021b69a1..2fe0a5989b 100644
--- a/doc/developer/logging.rst
+++ b/doc/developer/logging.rst
@@ -502,6 +502,51 @@ General utility formats
representation for a hexdump. Non-printable characters are replaced with
a dot.
+.. frrfmt:: %pIS (struct iso_address *)
+
+ ([IS]o Network address) - Format ISO Network Address
+
+ ``%pIS``: :frrfmtout:`01.0203.04O5`
+ ISO Network address is printed as separated byte. The number of byte of the
+ address is embeded in the `iso_net` structure.
+
+ ``%pISl``: :frrfmtout:`01.0203.04O5.0607.0809.1011.1213.14` - long format to
+ print the long version of the ISO Network address which include the System
+ ID and the PSEUDO-ID of the IS-IS system
+
+ Note that the `ISO_ADDR_STRLEN` define gives the total size of the string
+ that could be used in conjunction to snprintfrr. Use like::
+
+ char buf[ISO_ADDR_STRLEN];
+ struct iso_net addr = {.len = 4, .addr = {1, 2, 3, 4}};
+ snprintfrr(buf, ISO_ADDR_STRLEN, "%pIS", &addr);
+
+.. frrfmt:: %pSY (uint8_t *)
+
+ (IS-IS [SY]stem ID) - Format IS-IS System ID
+
+ ``%pSY``: :frrfmtout:`0102.0304.0506`
+
+.. frrfmt:: %pPN (uint8_t *)
+
+ (IS-IS [P]seudo [N]ode System ID) - Format IS-IS Pseudo Node System ID
+
+ ``%pPN``: :frrfmtout:`0102.0304.0506.07`
+
+.. frrfmt:: %pLS (uint8_t *)
+
+ (IS-IS [L]sp fragment [S]ystem ID) - Format IS-IS Pseudo System ID
+
+ ``%pLS``: :frrfmtout:`0102.0304.0506.07-08`
+
+ Note that the `ISO_SYSID_STRLEN` define gives the total size of the string
+ that could be used in conjunction to snprintfrr. Use like::
+
+ char buf[ISO_SYSID_STRLEN];
+ uint8_t id[8] = {1, 2, 3, 4 , 5 , 6 , 7, 8};
+ snprintfrr(buf, SYS_ID_SIZE, "%pSY", id);
+
+
Integer formats
^^^^^^^^^^^^^^^
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 946f0699f2..97d7ce6b75 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2767,6 +2767,17 @@ happened automatically if local-role is set.
value of his role (by setting local-role on his side). Otherwise, a Role
Mismatch Notification will be sent.
+Labeled unicast
+---------------
+
+*bgpd* supports labeled information, as per :rfc:`3107`.
+
+.. clicmd:: bgp labeled-unicast explicit-null
+
+By default, locally advertised prefixes use the `implicit-null` label to
+encode in the outgoing NLRI. The following command uses the `explicit-null`
+label value for all the BGP instances.
+
.. _bgp-l3vpn-vrfs:
L3VPN VRFs
diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst
index 90c13d4f93..88fa78ddfa 100644
--- a/doc/user/isisd.rst
+++ b/doc/user/isisd.rst
@@ -68,6 +68,10 @@ writing, *isisd* does not support multiple ISIS processes.
Log changes in adjacency state.
+.. clicmd:: log-pdu-drops
+
+ Log any dropped PDUs.
+
.. clicmd:: metric-style [narrow | transition | wide]
Set old-style (ISO 10589) or new-style packet formats:
diff --git a/doc/user/mgmtd.rst b/doc/user/mgmtd.rst
index 6ea7e7891a..6614a568f8 100644
--- a/doc/user/mgmtd.rst
+++ b/doc/user/mgmtd.rst
@@ -70,14 +70,6 @@ Frontend Interface and MGMTd:
database.
- Data can be retrieved anytime using GET_CONFIG/GET_DATA API.
- - Startup Database:
-
- - Consists of configuration data items only.
- - This is a copy of Running database that is stored in persistent
- storage and is used to load configurations on Running database during
- MGMT daemon startup.
- - Data cannot be edited/retrieved directly via Frontend interface.
-
- Operational Database:
- Consists of non-configurational data items.
@@ -313,8 +305,7 @@ MGMT Configuration commands
.. clicmd:: mgmt commit apply
This command commits any uncommited changes in the Candidate DB to the
- Running DB. It also dumps a copy of the tree in JSON format into
- frr_startup.json.
+ Running DB.
.. clicmd:: mgmt commit check
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst
index 67c0d15750..5171832604 100644
--- a/doc/user/ospfd.rst
+++ b/doc/user/ospfd.rst
@@ -310,6 +310,18 @@ To start OSPF process you have to specify the OSPF router.
of packets to process before returning. The defult value of this parameter
is 20.
+.. clicmd:: socket buffer <send | recv | all> (1-4000000000)
+
+ This command controls the ospf instance's socket buffer sizes. The
+ 'no' form resets one or both values to the default.
+
+.. clicmd:: no socket-per-interface
+
+ Ordinarily, ospfd uses a socket per interface for sending
+ packets. This command disables those per-interface sockets, and
+ causes ospfd to use a single socket per ospf instance for sending
+ and receiving packets.
+
.. _ospf-area:
Areas
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index 72471d7af0..d70c3c0e64 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -387,9 +387,14 @@ cause great confusion.
.. clicmd:: show ip igmp [vrf NAME] join [json]
Display IGMP static join information for a specific vrf.
- If "vrf all" is provided, it displays information for all the vrfs present.
+
+.. index:: show ip igmp [vrf NAME$vrf_name] groups [INTERFACE$ifname [GROUP$grp_str]] [detail] [json$json]
+.. clicmd:: show ip igmp [vrf NAME$vrf_name] groups [INTERFACE$ifname [GROUP$grp_str]] [detail] [json$json]
-.. clicmd:: show ip igmp groups
+ Display IGMP static join information for all the vrfs present.
+
+.. index:: show ip igmp vrf all groups [GROUP$grp_str] [detail$detail] [json$json]
+.. clicmd:: show ip igmp vrf all groups [GROUP$grp_str] [detail$detail] [json$json]
Display IGMP groups information.
diff --git a/docker/ubi-8/Dockerfile b/docker/ubi-8/Dockerfile
deleted file mode 100644
index 1d1e8bdc6e..0000000000
--- a/docker/ubi-8/Dockerfile
+++ /dev/null
@@ -1,83 +0,0 @@
-# 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-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm \
- https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-devel-0.8.0-1.el7.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-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.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/ubi8-minimal/Dockerfile b/docker/ubi8-minimal/Dockerfile
new file mode 100644
index 0000000000..adb04219be
--- /dev/null
+++ b/docker/ubi8-minimal/Dockerfile
@@ -0,0 +1,132 @@
+# This stage builds an rpm from the source
+ARG UBI8_MINIMAL_VERSION
+FROM registry.access.redhat.com/ubi8/ubi-minimal:${UBI8_MINIMAL_VERSION} as ubi8-minimal-builder
+
+RUN rpm --import https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-8
+
+ADD docker/ubi8-minimal/almalinux.repo /etc/yum.repos.d/almalinux.repo
+
+# ubi8-minimal comes with broken tzdata package installed, so we need to remove them
+# and later reinstall it again: https://bugzilla.redhat.com/show_bug.cgi?id=1668185
+RUN rpm --quiet -e --nodeps tzdata >/dev/null 2>&1
+
+RUN microdnf --disableplugin=subscription-manager --setopt=install_weak_deps=0 install \
+ autoconf \
+ automake \
+ bison \
+ c-ares-devel \
+ flex \
+ git \
+ groff \
+ json-c-devel \
+ libcap-devel \
+ libssh-devel \
+ libtool \
+ make \
+ net-snmp-devel \
+ openssl \
+ pam-devel \
+ pcre-devel \
+ pkgconfig \
+ platform-python-devel \
+ python3-devel \
+ python3-pytest \
+ python3-sphinx \
+ readline-devel \
+ rpm-build \
+ systemd-devel \
+ texinfo \
+ tzdata \
+ && microdnf --disableplugin=subscription-manager clean all
+
+RUN curl -sSL -o /tmp/libyang2.rpm https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-12/RedHat-8-x86_64-Packages/libyang2-2.0.7-1.el8.x86_64.rpm \
+ && rpm -i /tmp/libyang2.rpm \
+ && rm -f /tmp/libyang2.rpm
+
+RUN curl -sSL -o /tmp/libyang2-devel.rpm https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-12/RedHat-8-x86_64-Packages/libyang2-devel-2.0.7-1.el8.x86_64.rpm \
+ && rpm -i /tmp/libyang2-devel.rpm \
+ && rm -f /tmp/libyang2-devel.rpm
+
+RUN curl -sSL -o /tmp/librtr.rpm https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-149/RedHat-8-x86_64-Packages/librtr-0.8.0-1.el8.x86_64.rpm \
+ && rpm -i /tmp/librtr.rpm \
+ && rm -f /tmp/librtr.rpm
+
+RUN curl -sSL -o /tmp/librtr-devel.rpm https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-149/RedHat-8-x86_64-Packages/librtr-devel-0.8.0-1.el8.x86_64.rpm \
+ && rpm -i /tmp/librtr-devel.rpm \
+ && rm -f /tmp/librtr-devel.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="_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-minimal:${UBI8_MINIMAL_VERSION}
+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
+
+ADD docker/ubi8-minimal/almalinux.repo /etc/yum.repos.d/almalinux.repo
+
+RUN rpm --import https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-8
+
+RUN microdnf --disableplugin=subscription-manager --setopt=install_weak_deps=0 install \
+ c-ares \
+ initscripts \
+ net-snmp-agent-libs \
+ net-snmp-libs \
+ openssl \
+ python3 \
+ shadow-utils \
+ systemd \
+ && microdnf --disableplugin=subscription-manager clean all
+
+RUN curl -sSL -o /tmp/libyang2.rpm https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-12/RedHat-8-x86_64-Packages/libyang2-2.0.7-1.el8.x86_64.rpm \
+ && rpm -i /tmp/libyang2.rpm \
+ && rm -f /tmp/libyang2.rpm
+
+RUN curl -sSL -o /tmp/librtr.rpm https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-149/RedHat-8-x86_64-Packages/librtr-0.8.0-1.el8.x86_64.rpm \
+ && rpm -i /tmp/librtr.rpm \
+ && rm -f /tmp/librtr.rpm
+
+COPY --from=ubi8-minimal-builder /rpmbuild/RPMS/ /pkgs/rpm/
+
+# Install packages and create FRR files and folders. Be sure to own the config / PID files
+RUN rpm -i /pkgs/rpm/x86_64/*.rpm \
+ && rm -rf /pkgs \
+ && rm -rf /mnt/rootfs/var/cache/* /mnt/rootfs/var/log/dnf* /mnt/rootfs/var/log/yum.* \
+ && mkdir -p /var/run/frr \
+ && chown -R frr:frr /etc/frr /var/run/frr
+
+# There is no package for tini, add it manually
+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/ubi8-minimal/docker-start /usr/lib/frr/docker-start
+CMD ["/usr/lib/frr/docker-start"]
diff --git a/docker/ubi8-minimal/almalinux.repo b/docker/ubi8-minimal/almalinux.repo
new file mode 100644
index 0000000000..9b9877b180
--- /dev/null
+++ b/docker/ubi8-minimal/almalinux.repo
@@ -0,0 +1,23 @@
+[AlmaLinux - baseos]
+name=AlmaLinux $releasever - BaseOS
+mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/baseos
+# baseurl=https://repo.almalinux.org/almalinux/$releasever/BaseOS/$basearch/os/
+enabled=1
+gpgcheck=1
+countme=1
+
+[AlmaLinux - appstream]
+name=AlmaLinux $releasever - AppStream
+mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/appstream
+# baseurl=https://repo.almalinux.org/almalinux/$releasever/AppStream/$basearch/os/
+enabled=1
+gpgcheck=1
+countme=1
+
+[AlmaLinux - powertools]
+name=AlmaLinux $releasever - PowerTools
+mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/powertools
+# baseurl=https://repo.almalinux.org/almalinux/$releasever/PowerTools/$basearch/os/
+enabled=1
+gpgcheck=1
+countme=1
diff --git a/docker/ubi-8/build.sh b/docker/ubi8-minimal/build.sh
index 0216636893..2aa45c9bf5 100755
--- a/docker/ubi-8/build.sh
+++ b/docker/ubi8-minimal/build.sh
@@ -5,37 +5,45 @@ set -e
##
# Package version needs to be decimal
##
-DISTRO=ubi-8
+DISTRO=ubi8-minimal
+
+UBI8_MINIMAL_VERSION=$1
+if [ -z "$UBI8_MINIMAL_VERSION" ]; then
+ UBI8_MINIMAL_VERSION="latest"
+fi
GITREV="$2"
if [ -z "$GITREV" ];then
GITREV="$(git rev-parse --short=10 HEAD)"
fi
-FRR_IMAGE_TAG="$1"
+FRR_IMAGE_TAG="$3"
if [ -z $FRR_IMAGE_TAG ];then
- FRR_IMAGE_TAG="frr:ubi-8-$GITREV"
+ FRR_IMAGE_TAG="frr:ubi8-minimal-$GITREV"
fi
PKGVER="$(printf '%u\n' 0x$GITREV)"
-FRR_RELEASE="$3"
+FRR_RELEASE="$4"
if [ -z $FRR_RELEASE ];then
FRR_RELEASE=$(git describe --tags --abbrev=0)
fi
-FRR_NAME=$4
+FRR_NAME=$5
if [ -z $FRR_NAME ];then
FRR_NAME=frr
fi
-FRR_VENDOR=$5
+FRR_VENDOR=$6
if [ -z $FRR_VENDOR ];then
FRR_VENDOR=frr
fi
+DOCKERFILE_PATH="$(dirname $(realpath $0))/Dockerfile"
+
docker build \
--cache-from="frr:$DISTRO-builder-$GITREV" \
- --file=docker/$DISTRO/Dockerfile \
+ --file="$DOCKERFILE_PATH" \
+ --build-arg="UBI8_MINIMAL_VERSION=$UBI8_MINIMAL_VERSION" \
--build-arg="PKGVER=$PKGVER" \
--build-arg="FRR_IMAGE_TAG=$FRR_IMAGE_TAG" \
--build-arg="FRR_RELEASE=$FRR_RELEASE" \
diff --git a/docker/ubi-8/docker-start b/docker/ubi8-minimal/docker-start
index d954142ab9..d954142ab9 100755
--- a/docker/ubi-8/docker-start
+++ b/docker/ubi8-minimal/docker-start
diff --git a/isisd/fabricd.c b/isisd/fabricd.c
index 4fd39498a0..0be36e175a 100644
--- a/isisd/fabricd.c
+++ b/isisd/fabricd.c
@@ -273,8 +273,8 @@ void fabricd_initial_sync_hello(struct isis_circuit *circuit)
if (IS_DEBUG_ADJ_PACKETS)
zlog_debug(
- "OpenFabric: Started initial synchronization with %s on %s",
- sysid_print(circuit->u.p2p.neighbor->sysid),
+ "OpenFabric: Started initial synchronization with %pSY on %s",
+ circuit->u.p2p.neighbor->sysid,
circuit->interface->name);
}
@@ -359,7 +359,9 @@ static uint8_t fabricd_calculate_fabric_tier(struct isis_area *area)
return ISIS_TIER_UNDEFINED;
}
- zlog_info("OpenFabric: Found %s as furthest t0 from local system, dist == %u", rawlspid_print(furthest_t0->N.id), furthest_t0->d_N);
+ zlog_info(
+ "OpenFabric: Found %pLS as furthest t0 from local system, dist == %u",
+ furthest_t0->N.id, furthest_t0->d_N);
struct isis_spftree *remote_tree =
isis_run_hopcount_spf(area, furthest_t0->N.id, NULL);
@@ -372,8 +374,9 @@ static uint8_t fabricd_calculate_fabric_tier(struct isis_area *area)
isis_spftree_del(remote_tree);
return ISIS_TIER_UNDEFINED;
} else {
- zlog_info("OpenFabric: Found %s as furthest from remote dist == %u", rawlspid_print(furthest_from_remote->N.id),
- furthest_from_remote->d_N);
+ zlog_info(
+ "OpenFabric: Found %pLS as furthest from remote dist == %u",
+ furthest_from_remote->N.id, furthest_from_remote->d_N);
}
int64_t tier = furthest_from_remote->d_N - furthest_t0->d_N;
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 1871078cc1..30b71537e0 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -283,6 +283,8 @@ void isis_adj_process_threeway(struct isis_adjacency *adj,
}
const char *isis_adj_name(const struct isis_adjacency *adj)
{
+ static char buf[ISO_SYSID_STRLEN];
+
if (!adj)
return "NONE";
@@ -291,8 +293,9 @@ const char *isis_adj_name(const struct isis_adjacency *adj)
dyn = dynhn_find_by_id(adj->circuit->isis, adj->sysid);
if (dyn)
return dyn->hostname;
- else
- return sysid_print(adj->sysid);
+
+ snprintfrr(buf, sizeof(buf), "%pSY", adj->sysid);
+ return buf;
}
void isis_log_adj_change(struct isis_adjacency *adj,
enum isis_adj_state old_state,
@@ -439,9 +442,8 @@ void isis_adj_print(struct isis_adjacency *adj)
if (dyn)
zlog_debug("%s", dyn->hostname);
- zlog_debug("SystemId %20s SNPA %s, level %d; Holding Time %d",
- sysid_print(adj->sysid), snpa_print(adj->snpa), adj->level,
- adj->hold_time);
+ zlog_debug("SystemId %20pSY SNPA %pSY, level %d; Holding Time %d",
+ adj->sysid, adj->snpa, adj->level, adj->hold_time);
if (adj->ipv4_address_count) {
zlog_debug("IPv4 Address(es):");
for (unsigned int i = 0; i < adj->ipv4_address_count; i++)
@@ -530,7 +532,7 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json,
time2string(adj->last_upd +
adj->hold_time - now));
}
- json_object_string_add(json, "snpa", snpa_print(adj->snpa));
+ json_object_string_addf(json, "snpa", "%pSY", adj->snpa);
}
if (detail == ISIS_UI_LEVEL_DETAIL) {
@@ -581,8 +583,7 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json,
isis_mtid2str(adj->mt_set[i]));
}
}
- json_object_string_add(iface_json, "snpa",
- snpa_print(adj->snpa));
+ json_object_string_addf(iface_json, "snpa", "%pSY", adj->snpa);
if (adj->circuit &&
(adj->circuit->circ_type == CIRCUIT_T_BROADCAST)) {
dyn = dynhn_find_by_id(adj->circuit->isis, adj->lanid);
@@ -593,11 +594,8 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json,
json_object_string_add(iface_json, "lan-id",
buf);
} else {
- snprintfrr(buf, sizeof(buf), "%s-%02x",
- sysid_print(adj->lanid),
- adj->lanid[ISIS_SYS_ID_LEN]);
- json_object_string_add(iface_json, "lan-id",
- buf);
+ json_object_string_addf(iface_json, "lan-id",
+ "%pSY", adj->lanid);
}
json_object_int_add(iface_json, "lan-prio",
@@ -626,12 +624,9 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json,
area_addr_json);
for (unsigned int i = 0; i < adj->area_address_count;
i++) {
- json_object_string_add(
- area_addr_json, "isonet",
- isonet_print(adj->area_addresses[i]
- .area_addr,
- adj->area_addresses[i]
- .addr_len));
+ json_object_string_addf(
+ area_addr_json, "isonet", "%pIS",
+ &adj->area_addresses[i]);
}
}
if (adj->ipv4_address_count) {
@@ -736,7 +731,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
+ adj->hold_time - now);
} else
vty_out(vty, "- ");
- vty_out(vty, "%-10s", snpa_print(adj->snpa));
+ vty_out(vty, "%-10pSY", adj->snpa);
vty_out(vty, "\n");
}
@@ -780,7 +775,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
vty_out(vty, " %s\n",
isis_mtid2str(adj->mt_set[i]));
}
- vty_out(vty, " SNPA: %s", snpa_print(adj->snpa));
+ vty_out(vty, " SNPA: %pSY", adj->snpa);
if (adj->circuit
&& (adj->circuit->circ_type == CIRCUIT_T_BROADCAST)) {
dyn = dynhn_find_by_id(adj->circuit->isis, adj->lanid);
@@ -788,9 +783,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
vty_out(vty, ", LAN id: %s.%02x", dyn->hostname,
adj->lanid[ISIS_SYS_ID_LEN]);
else
- vty_out(vty, ", LAN id: %s.%02x",
- sysid_print(adj->lanid),
- adj->lanid[ISIS_SYS_ID_LEN]);
+ vty_out(vty, ", LAN id: %pPN", adj->lanid);
vty_out(vty, "\n");
vty_out(vty, " LAN Priority: %u",
@@ -811,11 +804,8 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
vty_out(vty, " Area Address(es):\n");
for (unsigned int i = 0; i < adj->area_address_count;
i++) {
- vty_out(vty, " %s\n",
- isonet_print(adj->area_addresses[i]
- .area_addr,
- adj->area_addresses[i]
- .addr_len));
+ vty_out(vty, " %pIS\n",
+ &adj->area_addresses[i]);
}
}
if (adj->ipv4_address_count) {
diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h
index f02f7a68ea..c0c8e68145 100644
--- a/isisd/isis_adjacency.h
+++ b/isisd/isis_adjacency.h
@@ -69,7 +69,7 @@ struct isis_adjacency {
struct isis_dis_record dis_record[DIS_RECORDS * ISIS_LEVELS];
enum isis_adj_state adj_state; /* adjacencyState */
enum isis_adj_usage adj_usage; /* adjacencyUsage */
- struct area_addr *area_addresses; /* areaAdressesOfNeighbour */
+ struct iso_address *area_addresses; /* areaAdressesOfNeighbour */
unsigned int area_address_count;
struct nlpids nlpids; /* protocols spoken ... */
struct in_addr *ipv4_addresses;
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 64b405737f..feab451233 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -695,10 +695,9 @@ int isis_circuit_up(struct isis_circuit *circuit)
}
#ifdef EXTREME_DEGUG
if (IS_DEBUG_EVENTS)
- zlog_debug("%s: if_id %d, isomtu %d snpa %s", __func__,
- circuit->interface->ifindex,
- ISO_MTU(circuit),
- snpa_print(circuit->u.bc.snpa));
+ zlog_debug("%s: if_id %d, isomtu %d snpa %pSY",
+ __func__, circuit->interface->ifindex,
+ ISO_MTU(circuit), circuit->u.bc.snpa);
#endif /* EXTREME_DEBUG */
circuit->u.bc.adjdb[0] = list_new();
@@ -995,8 +994,8 @@ void isis_circuit_print_json(struct isis_circuit *circuit,
json_object_string_add(iface_json, "level",
circuit_t2string(circuit->is_type));
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
- json_object_string_add(iface_json, "snpa",
- snpa_print(circuit->u.bc.snpa));
+ json_object_string_addf(iface_json, "snpa", "%pSY",
+ circuit->u.bc.snpa);
levels_json = json_object_new_array();
@@ -1122,8 +1121,7 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
circuit_type2string(circuit->circ_type));
vty_out(vty, ", Level: %s", circuit_t2string(circuit->is_type));
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
- vty_out(vty, ", SNPA: %-10s",
- snpa_print(circuit->u.bc.snpa));
+ vty_out(vty, ", SNPA: %-10pSY", circuit->u.bc.snpa);
vty_out(vty, "\n");
if (circuit->is_type & IS_LEVEL_1) {
vty_out(vty, " Level-1 Information:\n");
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index 7e1bb9255c..ee51e46858 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -3026,6 +3026,26 @@ void cli_show_isis_log_adjacency(struct vty *vty, const struct lyd_node *dnode,
}
/*
+ * XPath: /frr-isisd:isis/instance/log-pdu-drops
+ */
+DEFPY_YANG(log_pdu_drops, log_pdu_drops_cmd, "[no] log-pdu-drops",
+ NO_STR "Log any dropped PDUs\n")
+{
+ nb_cli_enqueue_change(vty, "./log-pdu-drops", NB_OP_MODIFY,
+ no ? "false" : "true");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_isis_log_pdu_drops(struct vty *vty, const struct lyd_node *dnode,
+ bool show_defaults)
+{
+ if (!yang_dnode_get_bool(dnode, NULL))
+ vty_out(vty, " no");
+ vty_out(vty, " log-pdu-drops\n");
+}
+
+/*
* XPath: /frr-isisd:isis/instance/mpls/ldp-sync
*/
DEFPY(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync",
@@ -3290,6 +3310,7 @@ void isis_cli_init(void)
install_element(INTERFACE_NODE, &isis_ti_lfa_cmd);
install_element(ISIS_NODE, &log_adj_changes_cmd);
+ install_element(ISIS_NODE, &log_pdu_drops_cmd);
install_element(ISIS_NODE, &isis_mpls_ldp_sync_cmd);
install_element(ISIS_NODE, &no_isis_mpls_ldp_sync_cmd);
diff --git a/isisd/isis_common.h b/isisd/isis_common.h
index c908dc2e24..2ded68f84d 100644
--- a/isisd/isis_common.h
+++ b/isisd/isis_common.h
@@ -11,14 +11,6 @@
#ifndef ISIS_COMMON_H
#define ISIS_COMMON_H
-/*
- * Area Address
- */
-struct area_addr {
- uint8_t addr_len;
- uint8_t area_addr[20];
-};
-
struct isis_passwd {
uint8_t len;
#define ISIS_PASSWD_TYPE_UNUSED 0
diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c
index 446e522019..61c49d08a7 100644
--- a/isisd/isis_dynhn.c
+++ b/isisd/isis_dynhn.c
@@ -145,12 +145,10 @@ void dynhn_print_all(struct vty *vty, struct isis *isis)
vty_out(vty, "Level System ID Dynamic Hostname\n");
for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) {
vty_out(vty, "%-7d", dyn->level);
- vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id),
- dyn->hostname);
+ vty_out(vty, "%pSY %-15s\n", dyn->id, dyn->hostname);
}
- vty_out(vty, " * %s %s\n", sysid_print(isis->sysid),
- cmd_hostname_get());
+ vty_out(vty, " * %pSY %s\n", isis->sysid, cmd_hostname_get());
return;
}
diff --git a/isisd/isis_events.c b/isisd/isis_events.c
index 8a2a2ab971..32231a079f 100644
--- a/isisd/isis_events.c
+++ b/isisd/isis_events.c
@@ -217,8 +217,8 @@ void isis_event_auth_failure(char *area_tag, const char *error_string,
uint8_t *sysid)
{
if (IS_DEBUG_EVENTS)
- zlog_debug("ISIS-Evt (%s) Authentication failure %s from %s",
- area_tag, error_string, sysid_print(sysid));
+ zlog_debug("ISIS-Evt (%s) Authentication failure %s from %pSY",
+ area_tag, error_string, sysid);
return;
}
diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c
index 7a25a92535..abb6168393 100644
--- a/isisd/isis_lfa.c
+++ b/isisd/isis_lfa.c
@@ -1466,8 +1466,8 @@ int isis_rlfa_activate(struct isis_spftree *spftree, struct rlfa *rlfa,
if (ldp_label == MPLS_INVALID_LABEL) {
if (IS_DEBUG_LFA)
zlog_debug(
- "ISIS-LFA: failed to activate RLFA: missing LDP label to reach PQ node through %s",
- sysid_print(vadj->sadj->id));
+ "ISIS-LFA: failed to activate RLFA: missing LDP label to reach PQ node through %pSY",
+ vadj->sadj->id);
return -1;
}
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index d569f6bd5b..fb69448d04 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -193,10 +193,9 @@ int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno,
|| (lsp->hdr.rem_lifetime != 0 && rem_lifetime != 0))) {
if (IS_DEBUG_SNP_PACKETS) {
zlog_debug(
- "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04hx, lifetime %hus",
- areatag, rawlspid_print(lsp->hdr.lsp_id),
- lsp->hdr.seqno, lsp->hdr.checksum,
- lsp->hdr.rem_lifetime);
+ "ISIS-Snp (%s): Compare LSP %pLS seq 0x%08x, cksum 0x%04hx, lifetime %hus",
+ areatag, lsp->hdr.lsp_id, lsp->hdr.seqno,
+ lsp->hdr.checksum, lsp->hdr.rem_lifetime);
zlog_debug(
"ISIS-Snp (%s): is equal to ours seq 0x%08x, cksum 0x%04hx, lifetime %hus",
areatag, seqno, checksum, rem_lifetime);
@@ -223,9 +222,9 @@ int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno,
&& lsp->hdr.rem_lifetime)))) {
if (IS_DEBUG_SNP_PACKETS) {
zlog_debug(
- "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04hx, lifetime %hus",
- areatag, rawlspid_print(lsp->hdr.lsp_id), seqno,
- checksum, rem_lifetime);
+ "ISIS-Snp (%s): Compare LSP %pLS seq 0x%08x, cksum 0x%04hx, lifetime %hus",
+ areatag, lsp->hdr.lsp_id, seqno, checksum,
+ rem_lifetime);
zlog_debug(
"ISIS-Snp (%s): is newer than ours seq 0x%08x, cksum 0x%04hx, lifetime %hus",
areatag, lsp->hdr.seqno, lsp->hdr.checksum,
@@ -234,9 +233,10 @@ int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno,
return LSP_NEWER;
}
if (IS_DEBUG_SNP_PACKETS) {
- zlog_debug("ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04hx, lifetime %hus",
- areatag, rawlspid_print(lsp->hdr.lsp_id), seqno,
- checksum, rem_lifetime);
+ zlog_debug(
+ "ISIS-Snp (%s): Compare LSP %pLS seq 0x%08x, cksum 0x%04hx, lifetime %hus",
+ areatag, lsp->hdr.lsp_id, seqno, checksum,
+ rem_lifetime);
zlog_debug(
"ISIS-Snp (%s): is older than ours seq 0x%08x, cksum 0x%04hx, lifetime %hus",
areatag, lsp->hdr.seqno, lsp->hdr.checksum,
@@ -554,8 +554,8 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
if (lsp->own_lsp) {
flog_err(
EC_LIB_DEVELOPMENT,
- "ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP",
- area->area_tag, rawlspid_print(lsp->hdr.lsp_id));
+ "ISIS-Upd (%s): BUG updating LSP %pLS still marked as own LSP",
+ area->area_tag, lsp->hdr.lsp_id);
lsp_clear_data(lsp);
lsp->own_lsp = 0;
}
@@ -634,10 +634,8 @@ struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
put_lsp_hdr(lsp, NULL, false);
if (IS_DEBUG_EVENTS)
- zlog_debug("New LSP with ID %s-%02x-%02x len %d seqnum %08x",
- sysid_print(lsp_id), LSP_PSEUDO_ID(lsp->hdr.lsp_id),
- LSP_FRAGMENT(lsp->hdr.lsp_id), lsp->hdr.pdu_len,
- lsp->hdr.seqno);
+ zlog_debug("New LSP with ID %pLS len %d seqnum %08x", lsp_id,
+ lsp->hdr.pdu_len, lsp->hdr.seqno);
return lsp;
}
@@ -704,7 +702,7 @@ void lspid_print(uint8_t *lsp_id, char *dest, size_t dest_len, char dynhost,
else if (!memcmp(isis->sysid, lsp_id, ISIS_SYS_ID_LEN) && dynhost)
snprintf(id, sizeof(id), "%.14s", cmd_hostname_get());
else
- memcpy(id, sysid_print(lsp_id), 15);
+ snprintf(id, sizeof(id), "%pSY", lsp_id);
if (frag)
snprintf(dest, dest_len, "%s.%02x-%02x", id,
@@ -1250,10 +1248,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
if (LSP_PSEUDO_ID(ne_id)) {
if (area->oldmetric) {
lsp_debug(
- "ISIS (%s): Adding DIS %s.%02x as old-style neighbor",
- area->area_tag,
- sysid_print(ne_id),
- LSP_PSEUDO_ID(ne_id));
+ "ISIS (%s): Adding DIS %pPN as old-style neighbor",
+ area->area_tag, ne_id);
isis_tlvs_add_oldstyle_reach(
lsp->tlvs, ne_id,
metric);
@@ -1279,9 +1275,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
if (area->oldmetric) {
lsp_debug(
- "ISIS (%s): Adding old-style is reach for %s",
- area->area_tag,
- sysid_print(ne_id));
+ "ISIS (%s): Adding old-style is reach for %pSY",
+ area->area_tag, ne_id);
isis_tlvs_add_oldstyle_reach(
lsp->tlvs, ne_id, metric);
}
@@ -1424,12 +1419,12 @@ int lsp_generate(struct isis_area *area, int level)
refresh_time, &area->t_lsp_refresh[level - 1]);
if (IS_DEBUG_UPDATE_PACKETS) {
- zlog_debug("ISIS-Upd (%s): Building L%d LSP %s, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus refresh %hus",
- area->area_tag, level,
- rawlspid_print(newlsp->hdr.lsp_id),
- newlsp->hdr.pdu_len, newlsp->hdr.seqno,
- newlsp->hdr.checksum, newlsp->hdr.rem_lifetime,
- refresh_time);
+ zlog_debug(
+ "ISIS-Upd (%s): Building L%d LSP %pLS, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus refresh %hus",
+ area->area_tag, level, newlsp->hdr.lsp_id,
+ newlsp->hdr.pdu_len, newlsp->hdr.seqno,
+ newlsp->hdr.checksum, newlsp->hdr.rem_lifetime,
+ refresh_time);
}
sched_debug(
"ISIS (%s): Built L%d LSP. Set triggered regenerate to non-pending.",
@@ -1506,8 +1501,8 @@ static int lsp_regenerate(struct isis_area *area, int level)
if (IS_DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): Refreshed our L%d LSP %s, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus refresh %hus",
- area->area_tag, level, rawlspid_print(lsp->hdr.lsp_id),
+ "ISIS-Upd (%s): Refreshed our L%d LSP %pLS, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus refresh %hus",
+ area->area_tag, level, lsp->hdr.lsp_id,
lsp->hdr.pdu_len, lsp->hdr.seqno, lsp->hdr.checksum,
lsp->hdr.rem_lifetime, refresh_time);
}
@@ -1698,9 +1693,9 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
lsp_clear_data(lsp);
lsp->tlvs = isis_alloc_tlvs();
lsp_debug(
- "ISIS (%s): Constructing pseudo LSP %s for interface %s level %d",
- area->area_tag, rawlspid_print(lsp->hdr.lsp_id),
- circuit->interface->name, level);
+ "ISIS (%s): Constructing pseudo LSP %pLS for interface %s level %d",
+ area->area_tag, lsp->hdr.lsp_id, circuit->interface->name,
+ level);
lsp->level = level;
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
@@ -1717,10 +1712,8 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
if (circuit->area->oldmetric) {
isis_tlvs_add_oldstyle_reach(lsp->tlvs, ne_id, 0);
- lsp_debug(
- "ISIS (%s): Adding %s.%02x as old-style neighbor (self)",
- area->area_tag, sysid_print(ne_id),
- LSP_PSEUDO_ID(ne_id));
+ lsp_debug("ISIS (%s): Adding %pPN as old-style neighbor (self)",
+ area->area_tag, ne_id);
}
if (circuit->area->newmetric) {
if (area_is_mt(circuit->area))
@@ -1728,10 +1721,8 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
else
mtid = ISIS_MT_DISABLE;
isis_tlvs_add_extended_reach(lsp->tlvs, mtid, ne_id, 0, NULL);
- lsp_debug(
- "ISIS (%s): Adding %s.%02x as te-style neighbor (self)",
- area->area_tag, sysid_print(ne_id),
- LSP_PSEUDO_ID(ne_id));
+ lsp_debug("ISIS (%s): Adding %pPN as te-style neighbor (self)",
+ area->area_tag, ne_id);
}
adj_list = list_new();
@@ -1740,8 +1731,8 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
for (ALL_LIST_ELEMENTS_RO(adj_list, node, adj)) {
if (!(adj->level & level)) {
lsp_debug(
- "ISIS (%s): Ignoring neighbor %s, level does not intersect",
- area->area_tag, sysid_print(adj->sysid));
+ "ISIS (%s): Ignoring neighbor %pSY, level does not intersect",
+ area->area_tag, adj->sysid);
continue;
}
@@ -1753,8 +1744,8 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
&& !(level == IS_LEVEL_2
&& adj->sys_type == ISIS_SYSTYPE_L2_IS)) {
lsp_debug(
- "ISIS (%s): Ignoring neighbor %s, level does not match",
- area->area_tag, sysid_print(adj->sysid));
+ "ISIS (%s): Ignoring neighbor %pSY, level does not match",
+ area->area_tag, adj->sysid);
continue;
}
@@ -1762,18 +1753,16 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
if (circuit->area->oldmetric) {
isis_tlvs_add_oldstyle_reach(lsp->tlvs, ne_id, 0);
lsp_debug(
- "ISIS (%s): Adding %s.%02x as old-style neighbor (peer)",
- area->area_tag, sysid_print(ne_id),
- LSP_PSEUDO_ID(ne_id));
+ "ISIS (%s): Adding %pPN as old-style neighbor (peer)",
+ area->area_tag, ne_id);
}
if (circuit->area->newmetric) {
isis_tlvs_add_extended_reach(lsp->tlvs,
ISIS_MT_IPV4_UNICAST,
ne_id, 0, NULL);
lsp_debug(
- "ISIS (%s): Adding %s.%02x as te-style neighbor (peer)",
- area->area_tag, sysid_print(ne_id),
- LSP_PSEUDO_ID(ne_id));
+ "ISIS (%s): Adding %pPN as te-style neighbor (peer)",
+ area->area_tag, ne_id);
}
}
list_delete(&adj_list);
@@ -1832,10 +1821,9 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
if (IS_DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): Built L%d Pseudo LSP %s, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus, refresh %hus",
- circuit->area->area_tag, level,
- rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.pdu_len,
- lsp->hdr.seqno, lsp->hdr.checksum,
+ "ISIS-Upd (%s): Built L%d Pseudo LSP %pLS, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus, refresh %hus",
+ circuit->area->area_tag, level, lsp->hdr.lsp_id,
+ lsp->hdr.pdu_len, lsp->hdr.seqno, lsp->hdr.checksum,
lsp->hdr.rem_lifetime, refresh_time);
}
@@ -1863,8 +1851,8 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
if (!lsp) {
flog_err(EC_LIB_DEVELOPMENT,
- "lsp_regenerate_pseudo: no l%d LSP %s found!", level,
- rawlspid_print(lsp_id));
+ "lsp_regenerate_pseudo: no l%d LSP %pLS found!", level,
+ lsp_id);
return ISIS_ERROR;
}
@@ -1887,10 +1875,9 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
if (IS_DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): Refreshed L%d Pseudo LSP %s, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus, refresh %hus",
- circuit->area->area_tag, level,
- rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.pdu_len,
- lsp->hdr.seqno, lsp->hdr.checksum,
+ "ISIS-Upd (%s): Refreshed L%d Pseudo LSP %pLS, len %hu, seq 0x%08x, cksum 0x%04hx, lifetime %hus, refresh %hus",
+ circuit->area->area_tag, level, lsp->hdr.lsp_id,
+ lsp->hdr.pdu_len, lsp->hdr.seqno, lsp->hdr.checksum,
lsp->hdr.rem_lifetime, refresh_time);
}
@@ -2101,10 +2088,9 @@ void lsp_tick(struct event *thread)
if (lsp->age_out == 0) {
zlog_debug(
- "ISIS-Upd (%s): L%u LSP %s seq 0x%08x aged out",
+ "ISIS-Upd (%s): L%u LSP %pLS seq 0x%08x aged out",
area->area_tag, lsp->level,
- rawlspid_print(lsp->hdr.lsp_id),
- lsp->hdr.seqno);
+ lsp->hdr.lsp_id, lsp->hdr.seqno);
/* if we're aging out fragment 0, lsp_destroy()
* below will delete all other fragments too,
@@ -2207,11 +2193,10 @@ void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit,
const char *func, const char *file, int line)
{
if (IS_DEBUG_FLOODING) {
- zlog_debug("Flooding LSP %s%s%s (From %s %s:%d)",
- rawlspid_print(lsp->hdr.lsp_id),
- circuit ? " except on " : "",
- circuit ? circuit->interface->name : "",
- func, file, line);
+ zlog_debug("Flooding LSP %pLS%s%s (From %s %s:%d)",
+ lsp->hdr.lsp_id, circuit ? " except on " : "",
+ circuit ? circuit->interface->name : "", func, file,
+ line);
}
if (!fabricd)
diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c
index 95d24036ec..09ffa3479a 100644
--- a/isisd/isis_misc.c
+++ b/isisd/isis_misc.c
@@ -32,48 +32,13 @@
#include "isisd/isis_dynhn.h"
/* staticly assigned vars for printing purposes */
+static char sys_hostname[ISO_SYSID_STRLEN];
struct in_addr new_prefix;
-/* len of xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx */
-/* + place for #0 termination */
-char isonet[51];
/* len of xxYxxMxWxdxxhxxmxxs + place for #0 termination */
char datestring[20];
char nlpidstring[30];
/*
- * This converts the isonet to its printable format
- */
-const char *isonet_print(const uint8_t *from, int len)
-{
- int i = 0;
- char tbuf[4];
- isonet[0] = '\0';
-
- if (!from)
- return "unknown";
-
- while (i < len) {
- if (i & 1) {
- snprintf(tbuf, sizeof(tbuf), "%02x", *(from + i));
- strlcat(isonet, tbuf, sizeof(isonet));
- } else {
- if (i == (len - 1)) { /* No dot at the end of address */
- snprintf(tbuf, sizeof(tbuf), "%02x",
- *(from + i));
- strlcat(isonet, tbuf, sizeof(isonet));
- } else {
- snprintf(tbuf, sizeof(tbuf), "%02x.",
- *(from + i));
- strlcat(isonet, tbuf, sizeof(isonet));
- }
- }
- i++;
- }
-
- return isonet;
-}
-
-/*
* Returns 0 on error, length of buff on ok
* extract dot from the dotted str, and insert all the number in a buff
*/
@@ -307,60 +272,6 @@ const char *isis_hello_padding2string(int hello_padding_type)
return NULL; /* not reached */
}
-/*
- * Print functions - we print to static vars
- */
-const char *snpa_print(const uint8_t *from)
-{
- return isis_format_id(from, ISIS_SYS_ID_LEN);
-}
-
-const char *sysid_print(const uint8_t *from)
-{
- return isis_format_id(from, ISIS_SYS_ID_LEN);
-}
-
-const char *rawlspid_print(const uint8_t *from)
-{
- return isis_format_id(from, 8);
-}
-
-#define FORMAT_ID_SIZE sizeof("0000.0000.0000.00-00")
-const char *isis_format_id(const uint8_t *id, size_t len)
-{
-#define FORMAT_BUF_COUNT 4
- static char buf_ring[FORMAT_BUF_COUNT][FORMAT_ID_SIZE];
- static size_t cur_buf = 0;
-
- char *rv;
-
- cur_buf++;
- if (cur_buf >= FORMAT_BUF_COUNT)
- cur_buf = 0;
-
- rv = buf_ring[cur_buf];
-
- if (!id) {
- snprintf(rv, FORMAT_ID_SIZE, "unknown");
- return rv;
- }
-
- if (len < 6) {
- snprintf(rv, FORMAT_ID_SIZE, "Short ID");
- return rv;
- }
-
- snprintf(rv, FORMAT_ID_SIZE, "%02x%02x.%02x%02x.%02x%02x", id[0], id[1],
- id[2], id[3], id[4], id[5]);
-
- if (len > 6)
- snprintf(rv + 14, FORMAT_ID_SIZE - 14, ".%02x", id[6]);
- if (len > 7)
- snprintf(rv + 17, FORMAT_ID_SIZE - 17, "-%02x", id[7]);
-
- return rv;
-}
-
const char *time2string(uint32_t time)
{
uint32_t rest;
@@ -474,7 +385,8 @@ const char *print_sys_hostname(const uint8_t *sysid)
return dyn->hostname;
}
- return sysid_print(sysid);
+ snprintfrr(sys_hostname, ISO_SYSID_STRLEN, "%pSY", sysid);
+ return sys_hostname;
}
/*
@@ -508,11 +420,11 @@ void zlog_dump_data(void *data, int len)
/* store hex str (for left side) */
snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
- strncat(hexstr, bytestr, sizeof(hexstr) - strlen(hexstr) - 1);
+ strlcat(hexstr, bytestr, sizeof(hexstr) - strlen(hexstr) - 1);
/* store char str (for right side) */
snprintf(bytestr, sizeof(bytestr), "%c", c);
- strncat(charstr, bytestr,
+ strlcat(charstr, bytestr,
sizeof(charstr) - strlen(charstr) - 1);
if ((i % 16) == 0) {
@@ -523,9 +435,9 @@ void zlog_dump_data(void *data, int len)
charstr[0] = 0;
} else if ((i % 8) == 0) {
/* half line: add whitespaces */
- strncat(hexstr, " ",
+ strlcat(hexstr, " ",
sizeof(hexstr) - strlen(hexstr) - 1);
- strncat(charstr, " ",
+ strlcat(charstr, " ",
sizeof(charstr) - strlen(charstr) - 1);
}
p++; /* next byte */
diff --git a/isisd/isis_misc.h b/isisd/isis_misc.h
index 01d9abe869..3a1d136b1d 100644
--- a/isisd/isis_misc.h
+++ b/isisd/isis_misc.h
@@ -28,11 +28,6 @@ int sysid2buff(uint8_t *, const char *);
/*
* Printing functions
*/
-const char *isonet_print(const uint8_t *, int len);
-const char *sysid_print(const uint8_t *);
-const char *snpa_print(const uint8_t *);
-const char *rawlspid_print(const uint8_t *);
-const char *isis_format_id(const uint8_t *id, size_t len);
const char *time2string(uint32_t);
const char *nlpid2str(uint8_t nlpid);
/* typedef struct nlpids nlpids; */
diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c
index fcc0f53815..d04a24dc46 100644
--- a/isisd/isis_mt.c
+++ b/isisd/isis_mt.c
@@ -507,8 +507,8 @@ static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
/* Check if MT is enable for this area */
if (!area_is_mt(area)) {
lsp_debug(
- "ISIS (%s): Adding %s.%02x as te-style neighbor (MT disable)",
- area->area_tag, sysid_print(id), LSP_PSEUDO_ID(id));
+ "ISIS (%s): Adding %pPN as te-style neighbor (MT disable)",
+ area->area_tag, id);
isis_tlvs_add_extended_reach(tlvs, ISIS_MT_DISABLE, id, metric,
ext);
return;
@@ -518,15 +518,12 @@ static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
for (unsigned int i = 0; i < mt_count; i++) {
uint16_t mtid = mt_set[i];
if (mt_set[i] == ISIS_MT_IPV4_UNICAST) {
- lsp_debug(
- "ISIS (%s): Adding %s.%02x as te-style neighbor",
- area->area_tag, sysid_print(id),
- LSP_PSEUDO_ID(id));
+ lsp_debug("ISIS (%s): Adding %pPN as te-style neighbor",
+ area->area_tag, id);
} else {
lsp_debug(
- "ISIS (%s): Adding %s.%02x as mt-style neighbor for %s",
- area->area_tag, sysid_print(id),
- LSP_PSEUDO_ID(id), isis_mtid2str(mtid));
+ "ISIS (%s): Adding %pPN as mt-style neighbor for %s",
+ area->area_tag, id, isis_mtid2str(mtid));
}
isis_tlvs_add_extended_reach(tlvs, mtid, id, metric, ext);
}
diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c
index 7dc3a0eb3d..9141bfc46c 100644
--- a/isisd/isis_nb.c
+++ b/isisd/isis_nb.c
@@ -559,6 +559,13 @@ const struct frr_yang_module_info frr_isisd_info = {
},
},
{
+ .xpath = "/frr-isisd:isis/instance/log-pdu-drops",
+ .cbs = {
+ .cli_show = cli_show_isis_log_pdu_drops,
+ .modify = isis_instance_log_pdu_drops_modify,
+ },
+ },
+ {
.xpath = "/frr-isisd:isis/instance/mpls-te",
.cbs = {
.cli_show = cli_show_isis_mpls_te,
diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h
index 480b2ce041..9a1f1f786f 100644
--- a/isisd/isis_nb.h
+++ b/isisd/isis_nb.h
@@ -196,6 +196,7 @@ int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_modify(
int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_destroy(
struct nb_cb_destroy_args *args);
int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args);
+int isis_instance_log_pdu_drops_modify(struct nb_cb_modify_args *args);
int isis_instance_mpls_te_create(struct nb_cb_create_args *args);
int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args);
int isis_instance_mpls_te_router_address_modify(struct nb_cb_modify_args *args);
@@ -609,6 +610,8 @@ void cli_show_ip_isis_priority(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);
void cli_show_isis_log_adjacency(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);
+void cli_show_isis_log_pdu_drops(struct vty *vty, const struct lyd_node *dnode,
+ bool show_defaults);
void cli_show_isis_mpls_ldp_sync(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);
void cli_show_isis_mpls_ldp_sync_holddown(struct vty *vty,
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 3817465a64..022bfbed6e 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -103,14 +103,14 @@ int isis_instance_is_type_modify(struct nb_cb_modify_args *args)
}
struct sysid_iter {
- struct area_addr *addr;
+ struct iso_address *addr;
bool same;
};
static int sysid_iter_cb(const struct lyd_node *dnode, void *arg)
{
struct sysid_iter *iter = arg;
- struct area_addr addr;
+ struct iso_address addr;
const char *net;
net = yang_dnode_get_string(dnode, NULL);
@@ -130,7 +130,7 @@ static int sysid_iter_cb(const struct lyd_node *dnode, void *arg)
int isis_instance_area_address_create(struct nb_cb_create_args *args)
{
struct isis_area *area;
- struct area_addr addr, *addrr = NULL, *addrp = NULL;
+ struct iso_address addr, *addrr = NULL, *addrp = NULL;
struct listnode *node;
struct sysid_iter iter;
uint8_t buff[255];
@@ -161,7 +161,8 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args)
}
break;
case NB_EV_PREPARE:
- addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
+ addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR,
+ sizeof(struct iso_address));
addrr->addr_len = dotformat2buff(buff, net_title);
memcpy(addrr->area_addr, buff, addrr->addr_len);
args->resource->ptr = addrr;
@@ -217,7 +218,7 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args)
int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args)
{
- struct area_addr addr, *addrp = NULL;
+ struct iso_address addr, *addrp = NULL;
struct listnode *node;
uint8_t buff[255];
struct isis_area *area;
@@ -1830,6 +1831,23 @@ int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args)
}
/*
+ * XPath: /frr-isisd:isis/instance/log-pdu-drops
+ */
+int isis_instance_log_pdu_drops_modify(struct nb_cb_modify_args *args)
+{
+ struct isis_area *area;
+ bool log = yang_dnode_get_bool(args->dnode, NULL);
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ area = nb_running_get_entry(args->dnode, NULL, true);
+ area->log_pdu_drops = log ? 1 : 0;
+
+ return NB_OK;
+}
+
+/*
* XPath: /frr-isisd:isis/instance/mpls-te
*/
int isis_instance_mpls_te_create(struct nb_cb_create_args *args)
diff --git a/isisd/isis_nb_notifications.c b/isisd/isis_nb_notifications.c
index 94b1c47d3e..5a1e312b4d 100644
--- a/isisd/isis_nb_notifications.c
+++ b/isisd/isis_nb_notifications.c
@@ -134,6 +134,7 @@ void isis_notif_lsp_too_large(const struct isis_circuit *circuit,
const char *xpath = "/frr-isisd:lsp-too-large";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
struct isis_area *area = circuit->area;
@@ -143,7 +144,8 @@ void isis_notif_lsp_too_large(const struct isis_circuit *circuit,
data = yang_data_new_uint32(xpath_arg, pdu_size);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
hook_call(isis_hook_lsp_too_large, circuit, pdu_size, lsp_id);
@@ -180,11 +182,13 @@ void isis_notif_corrupted_lsp(const struct isis_area *area,
const char *xpath = "/frr-isisd:corrupted-lsp-detected";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
notif_prep_instance_hdr(xpath, area, "default", arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
hook_call(isis_hook_corrupted_lsp, area);
@@ -201,11 +205,13 @@ void isis_notif_lsp_exceed_max(const struct isis_area *area,
const char *xpath = "/frr-isisd:attempt-to-exceed-max-sequence";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
notif_prep_instance_hdr(xpath, area, "default", arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
hook_call(isis_hook_lsp_exceed_max, area, lsp_id);
@@ -299,6 +305,7 @@ void isis_notif_adj_state_change(const struct isis_adjacency *adj,
const char *xpath = "/frr-isisd:adjacency-state-change";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
struct isis_circuit *circuit = adj->circuit;
struct isis_area *area = circuit->area;
@@ -312,7 +319,8 @@ void isis_notif_adj_state_change(const struct isis_adjacency *adj,
listnode_add(arguments, data);
}
snprintf(xpath_arg, sizeof(xpath_arg), "%s/neighbor-system-id", xpath);
- data = yang_data_new_string(xpath_arg, sysid_print(adj->sysid));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pSY", adj->sysid);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
@@ -389,13 +397,15 @@ void isis_notif_lsp_received(const struct isis_circuit *circuit,
const char *xpath = "/frr-isisd:lsp-received";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
struct isis_area *area = circuit->area;
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
data = yang_data_new_uint32(xpath_arg, seqno);
@@ -419,11 +429,13 @@ void isis_notif_lsp_gen(const struct isis_area *area, const uint8_t *lsp_id,
const char *xpath = "/frr-isisd:lsp-generation";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
notif_prep_instance_hdr(xpath, area, "default", arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/sequence", xpath);
data = yang_data_new_uint32(xpath_arg, seqno);
@@ -503,13 +515,15 @@ void isis_notif_lsp_error(const struct isis_circuit *circuit,
const char *xpath = "/frr-isisd:lsp-error-detected";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
struct isis_area *area = circuit->area;
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
@@ -530,13 +544,15 @@ void isis_notif_seqno_skipped(const struct isis_circuit *circuit,
const char *xpath = "/frr-isisd:sequence-number-skipped";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
struct isis_area *area = circuit->area;
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
hook_call(isis_hook_seqno_skipped, circuit, lsp_id);
@@ -553,13 +569,15 @@ void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,
const char *xpath = "/frr-isisd:own-lsp-purge";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
+ char xpath_value[ISO_SYSID_STRLEN];
struct yang_data *data;
struct isis_area *area = circuit->area;
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/lsp-id", xpath);
- data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pLS", lsp_id);
+ data = yang_data_new_string(xpath_arg, xpath_value);
listnode_add(arguments, data);
hook_call(isis_hook_own_lsp_purge, circuit, lsp_id);
diff --git a/isisd/isis_nb_state.c b/isisd/isis_nb_state.c
index 13fdddf555..b7c33ed27b 100644
--- a/isisd/isis_nb_state.c
+++ b/isisd/isis_nb_state.c
@@ -132,8 +132,11 @@ lib_interface_state_isis_adjacencies_adjacency_neighbor_sysid_get_elem(
struct nb_cb_get_elem_args *args)
{
const struct isis_adjacency *adj = args->list_entry;
+ char xpath_value[ISO_SYSID_STRLEN];
- return yang_data_new_string(args->xpath, sysid_print(adj->sysid));
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pSY", adj->sysid);
+
+ return yang_data_new_string(args->xpath, xpath_value);
}
/*
@@ -158,8 +161,11 @@ lib_interface_state_isis_adjacencies_adjacency_neighbor_snpa_get_elem(
struct nb_cb_get_elem_args *args)
{
const struct isis_adjacency *adj = args->list_entry;
+ char xpath_value[ISO_SYSID_STRLEN];
+
+ snprintfrr(xpath_value, ISO_SYSID_STRLEN, "%pSY", adj->snpa);
- return yang_data_new_string(args->xpath, snpa_print(adj->snpa));
+ return yang_data_new_string(args->xpath, xpath_value);
}
/*
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index d53d43ad0e..0cd43a7abc 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -514,9 +514,9 @@ static int process_lan_hello(struct iih_info *iih)
if (IS_DEBUG_ADJ_PACKETS) {
zlog_debug(
- "ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, cirID %u, length %zd",
- iih->circuit->area->area_tag, iih->level,
- snpa_print(iih->ssnpa), iih->circuit->interface->name,
+ "ISIS-Adj (%s): Rcvd L%d LAN IIH from %pSY on %s, cirType %s, cirID %u, length %zd",
+ iih->circuit->area->area_tag, iih->level, iih->ssnpa,
+ iih->circuit->interface->name,
circuit_t2string(iih->circuit->is_type),
iih->circuit->circuit_id,
stream_get_endp(iih->circuit->rcv_stream));
@@ -862,31 +862,32 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
#ifndef FABRICD
/* send northbound notification */
+ char buf[ISO_SYSID_STRLEN];
+
+ snprintfrr(buf, ISO_SYSID_STRLEN, "%pSY", hdr.lsp_id);
isis_notif_lsp_received(circuit, hdr.lsp_id, hdr.seqno, time(NULL),
- sysid_print(hdr.lsp_id));
+ buf);
#endif /* ifndef FABRICD */
if (pdu_len_validate(hdr.pdu_len, circuit)) {
- zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %hu",
- circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
- hdr.pdu_len);
+ zlog_debug("ISIS-Upd (%s): LSP %pLS invalid LSP length %hu",
+ circuit->area->area_tag, hdr.lsp_id, hdr.pdu_len);
return ISIS_WARNING;
}
if (IS_DEBUG_UPDATE_PACKETS) {
- zlog_debug("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus, len %hu, on %s",
- circuit->area->area_tag, level,
- rawlspid_print(hdr.lsp_id), hdr.seqno, hdr.checksum,
- hdr.rem_lifetime, hdr.pdu_len,
- circuit->interface->name);
+ zlog_debug(
+ "ISIS-Upd (%s): Rcvd L%d LSP %pLS, seq 0x%08x, cksum 0x%04hx, lifetime %hus, len %hu, on %s",
+ circuit->area->area_tag, level, hdr.lsp_id, hdr.seqno,
+ hdr.checksum, hdr.rem_lifetime, hdr.pdu_len,
+ circuit->interface->name);
}
/* lsp is_type check */
if ((hdr.lsp_bits & IS_LEVEL_1) != IS_LEVEL_1) {
- zlog_debug(
- "ISIS-Upd (%s): LSP %s invalid LSP is type 0x%x",
- circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
- hdr.lsp_bits & IS_LEVEL_1_AND_2);
+ zlog_debug("ISIS-Upd (%s): LSP %pLS invalid LSP is type 0x%x",
+ circuit->area->area_tag, hdr.lsp_id,
+ hdr.lsp_bits & IS_LEVEL_1_AND_2);
/* continue as per RFC1122 Be liberal in what you accept, and
* conservative in what you send */
}
@@ -896,27 +897,25 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
if (iso_csum_verify(STREAM_DATA(circuit->rcv_stream) + 12,
hdr.pdu_len - 12, hdr.checksum, 12)) {
zlog_debug(
- "ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04hx",
- circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
- hdr.checksum);
+ "ISIS-Upd (%s): LSP %pLS invalid LSP checksum 0x%04hx",
+ circuit->area->area_tag, hdr.lsp_id, hdr.checksum);
return ISIS_WARNING;
}
/* 7.3.15.1 a) 1 - external domain circuit will discard lsps */
if (circuit->ext_domain) {
zlog_debug(
- "ISIS-Upd (%s): LSP %s received at level %d over circuit with externalDomain = true",
- circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
- level);
+ "ISIS-Upd (%s): LSP %pLS received at level %d over circuit with externalDomain = true",
+ circuit->area->area_tag, hdr.lsp_id, level);
return ISIS_WARNING;
}
/* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */
if (!(circuit->is_type & level)) {
zlog_debug(
- "ISIS-Upd (%s): LSP %s received at level %d over circuit of type %s",
- circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
- level, circuit_t2string(circuit->is_type));
+ "ISIS-Upd (%s): LSP %pLS received at level %d over circuit of type %s",
+ circuit->area->area_tag, hdr.lsp_id, level,
+ circuit_t2string(circuit->is_type));
return ISIS_WARNING;
}
@@ -1016,11 +1015,11 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
if (!isis_adj_lookup_snpa(ssnpa,
circuit->u.bc.adjdb[level - 1])) {
- zlog_debug("(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus on %s",
- circuit->area->area_tag,
- rawlspid_print(hdr.lsp_id), hdr.seqno,
- hdr.checksum, hdr.rem_lifetime,
- circuit->interface->name);
+ zlog_debug(
+ "(%s): DS ======= LSP %pLS, seq 0x%08x, cksum 0x%04hx, lifetime %hus on %s",
+ circuit->area->area_tag, hdr.lsp_id, hdr.seqno,
+ hdr.checksum, hdr.rem_lifetime,
+ circuit->interface->name);
goto out; /* Silently discard */
}
}
@@ -1057,9 +1056,9 @@ dontcheckadj:
if (lsp && (lsp->hdr.seqno == hdr.seqno)
&& (lsp->hdr.checksum != hdr.checksum)
&& hdr.rem_lifetime) {
- zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum received.",
- circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
- hdr.seqno);
+ zlog_warn(
+ "ISIS-Upd (%s): LSP %pLS seq 0x%08x with confused checksum received.",
+ circuit->area->area_tag, hdr.lsp_id, hdr.seqno);
hdr.rem_lifetime = 0;
lsp_confusion = true;
} else
@@ -1153,10 +1152,9 @@ dontcheckadj:
}
if (IS_DEBUG_UPDATE_PACKETS)
zlog_debug(
- "ISIS-Upd (%s): (1) re-originating LSP %s new seq 0x%08x",
+ "ISIS-Upd (%s): (1) re-originating LSP %pLS new seq 0x%08x",
circuit->area->area_tag,
- rawlspid_print(hdr.lsp_id),
- lsp->hdr.seqno);
+ hdr.lsp_id, lsp->hdr.seqno);
} else {
/* our own LSP with 0 remaining life time */
#ifndef FABRICD
@@ -1194,9 +1192,8 @@ dontcheckadj:
#endif /* ifndef FABRICD */
if (IS_DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): (2) re-originating LSP %s new seq 0x%08x",
- circuit->area->area_tag,
- rawlspid_print(hdr.lsp_id),
+ "ISIS-Upd (%s): (2) re-originating LSP %pLS new seq 0x%08x",
+ circuit->area->area_tag, hdr.lsp_id,
lsp->hdr.seqno);
}
lsp_flood(lsp, NULL);
@@ -1361,9 +1358,9 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
if (!is_csnp && (circuit->circ_type == CIRCUIT_T_BROADCAST)
&& !circuit->u.bc.is_dr[level - 1]) {
zlog_debug(
- "ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s, skipping: we are not the DIS",
- circuit->area->area_tag, level, typechar,
- snpa_print(ssnpa), circuit->interface->name);
+ "ISIS-Snp (%s): Rcvd L%d %cSNP from %pSY on %s, skipping: we are not the DIS",
+ circuit->area->area_tag, level, typechar, ssnpa,
+ circuit->interface->name);
return ISIS_OK;
}
@@ -1452,16 +1449,16 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
/* debug isis snp-packets */
if (IS_DEBUG_SNP_PACKETS) {
- zlog_debug("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s",
- circuit->area->area_tag, level, typechar,
- snpa_print(ssnpa), circuit->interface->name);
+ zlog_debug("ISIS-Snp (%s): Rcvd L%d %cSNP from %pSY on %s",
+ circuit->area->area_tag, level, typechar, ssnpa,
+ circuit->interface->name);
for (struct isis_lsp_entry *entry = entry_head; entry;
entry = entry->next) {
zlog_debug(
- "ISIS-Snp (%s): %cSNP entry %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus",
- circuit->area->area_tag, typechar,
- rawlspid_print(entry->id), entry->seqno,
- entry->checksum, entry->rem_lifetime);
+ "ISIS-Snp (%s): %cSNP entry %pLS, seq 0x%08x, cksum 0x%04hx, lifetime %hus",
+ circuit->area->area_tag, typechar, entry->id,
+ entry->seqno, entry->checksum,
+ entry->rem_lifetime);
}
}
@@ -1654,14 +1651,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
if (idrp == ISO9542_ESIS) {
flog_err(EC_LIB_DEVELOPMENT,
"No support for ES-IS packet IDRP=%hhx", idrp);
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
if (idrp != ISO10589_ISIS) {
flog_err(EC_ISIS_PACKET, "Not an IS-IS packet IDRP=%hhx",
idrp);
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
@@ -1672,7 +1669,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
isis_notif_version_skew(circuit, version1, raw_pdu,
sizeof(raw_pdu));
#endif /* ifndef FABRICD */
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_WARNING;
}
@@ -1696,14 +1693,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
isis_notif_id_len_mismatch(circuit, id_len, raw_pdu,
sizeof(raw_pdu));
#endif /* ifndef FABRICD */
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
uint8_t expected_length;
if (pdu_size(pdu_type, &expected_length)) {
zlog_warn("Unsupported ISIS PDU %hhu", pdu_type);
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_WARNING;
}
@@ -1711,7 +1708,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
flog_err(EC_ISIS_PACKET,
"Expected fixed header length = %hhu but got %hhu",
expected_length, length);
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
@@ -1719,7 +1716,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
flog_err(
EC_ISIS_PACKET,
"PDU is too short to contain fixed header of given PDU type.");
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
@@ -1730,14 +1727,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
isis_notif_version_skew(circuit, version2, raw_pdu,
sizeof(raw_pdu));
#endif /* ifndef FABRICD */
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_WARNING;
}
if (circuit->is_passive) {
zlog_warn("Received ISIS PDU on passive circuit %s",
circuit->interface->name);
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_WARNING;
}
@@ -1756,7 +1753,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
isis_notif_max_area_addr_mismatch(circuit, max_area_addrs,
raw_pdu, sizeof(raw_pdu));
#endif /* ifndef FABRICD */
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
@@ -1765,8 +1762,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
case L2_LAN_HELLO:
case P2P_HELLO:
if (fabricd && pdu_type != P2P_HELLO) {
- pdu_counter_count(circuit->area->pdu_drop_counters,
- pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
@@ -1777,8 +1773,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
case FS_LINK_STATE:
if (fabricd && pdu_type != L2_LINK_STATE &&
pdu_type != FS_LINK_STATE) {
- pdu_counter_count(circuit->area->pdu_drop_counters,
- pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
@@ -1791,12 +1786,12 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
retval = process_snp(pdu_type, circuit, ssnpa);
break;
default:
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return ISIS_ERROR;
}
if (retval != ISIS_OK)
- pdu_counter_count(circuit->area->pdu_drop_counters, pdu_type);
+ pdu_counter_count_drop(circuit->area, pdu_type);
return retval;
}
@@ -2481,11 +2476,11 @@ void send_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp,
if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) {
flog_err(
EC_ISIS_PACKET,
- "ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus on %s. LSP Size is %zu while interface stream size is %zu.",
- circuit->area->area_tag, lsp->level,
- rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.seqno,
- lsp->hdr.checksum, lsp->hdr.rem_lifetime,
- circuit->interface->name, stream_get_endp(lsp->pdu),
+ "ISIS-Upd (%s): Can't send L%d LSP %pLS, seq 0x%08x, cksum 0x%04hx, lifetime %hus on %s. LSP Size is %zu while interface stream size is %zu.",
+ circuit->area->area_tag, lsp->level, lsp->hdr.lsp_id,
+ lsp->hdr.seqno, lsp->hdr.checksum,
+ lsp->hdr.rem_lifetime, circuit->interface->name,
+ stream_get_endp(lsp->pdu),
stream_get_size(circuit->snd_stream));
#ifndef FABRICD
/* send a northbound notification */
@@ -2509,14 +2504,14 @@ void send_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp,
}
if (IS_DEBUG_UPDATE_PACKETS) {
- zlog_debug("ISIS-Upd (%s): Sending %sL%d LSP %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus on %s",
- circuit->area->area_tag,
- (tx_type == TX_LSP_CIRCUIT_SCOPED)
- ? "Circuit scoped " : "",
- lsp->level,
- rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.seqno,
- lsp->hdr.checksum, lsp->hdr.rem_lifetime,
- circuit->interface->name);
+ zlog_debug(
+ "ISIS-Upd (%s): Sending %sL%d LSP %pLS, seq 0x%08x, cksum 0x%04hx, lifetime %hus on %s",
+ circuit->area->area_tag,
+ (tx_type == TX_LSP_CIRCUIT_SCOPED) ? "Circuit scoped "
+ : "",
+ lsp->level, lsp->hdr.lsp_id, lsp->hdr.seqno,
+ lsp->hdr.checksum, lsp->hdr.rem_lifetime,
+ circuit->interface->name);
if (IS_DEBUG_PACKET_DUMP)
zlog_dump_data(STREAM_DATA(circuit->snd_stream),
stream_get_endp(circuit->snd_stream));
@@ -2554,3 +2549,37 @@ out:
isis_tx_queue_del(circuit->tx_queue, lsp);
}
}
+
+void isis_log_pdu_drops(struct isis_area *area, const char *pdu_type)
+{
+ uint64_t total_drops = 0;
+
+ for (int i = 0; i < PDU_COUNTER_SIZE; i++) {
+ if (!area->pdu_drop_counters[i])
+ continue;
+ total_drops += area->pdu_drop_counters[i];
+ }
+
+ zlog_info("PDU drop detected of type: %s. %" PRIu64
+ " Total Drops; %" PRIu64 " L1 IIH drops; %" PRIu64
+ " L2 IIH drops; %" PRIu64 " P2P IIH drops; %" PRIu64
+ " L1 LSP drops; %" PRIu64 " L2 LSP drops; %" PRIu64
+ " FS LSP drops; %" PRIu64 " L1 CSNP drops; %" PRIu64
+ " L2 CSNP drops; %" PRIu64 " L1 PSNP drops; %" PRIu64
+ " L2 PSNP drops.",
+ pdu_type, total_drops,
+ pdu_counter_get_count(area->pdu_drop_counters, L1_LAN_HELLO),
+ pdu_counter_get_count(area->pdu_drop_counters, L2_LAN_HELLO),
+ pdu_counter_get_count(area->pdu_drop_counters, P2P_HELLO),
+ pdu_counter_get_count(area->pdu_drop_counters, L1_LINK_STATE),
+ pdu_counter_get_count(area->pdu_drop_counters, L2_LINK_STATE),
+ pdu_counter_get_count(area->pdu_drop_counters, FS_LINK_STATE),
+ pdu_counter_get_count(area->pdu_drop_counters,
+ L1_COMPLETE_SEQ_NUM),
+ pdu_counter_get_count(area->pdu_drop_counters,
+ L2_COMPLETE_SEQ_NUM),
+ pdu_counter_get_count(area->pdu_drop_counters,
+ L1_PARTIAL_SEQ_NUM),
+ pdu_counter_get_count(area->pdu_drop_counters,
+ L2_PARTIAL_SEQ_NUM));
+}
diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h
index ccd89a70f1..5303c61d38 100644
--- a/isisd/isis_pdu.h
+++ b/isisd/isis_pdu.h
@@ -206,4 +206,6 @@ void send_lsp(struct isis_circuit *circuit,
void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
int send_hello(struct isis_circuit *circuit, int level);
int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa);
+void isis_log_pdu_drops(struct isis_area *area, const char *pdu_type);
+
#endif /* _ZEBRA_ISIS_PDU_H */
diff --git a/isisd/isis_pdu_counter.c b/isisd/isis_pdu_counter.c
index 9d07b5e598..a3605a32a1 100644
--- a/isisd/isis_pdu_counter.c
+++ b/isisd/isis_pdu_counter.c
@@ -8,10 +8,10 @@
#include "vty.h"
-#include "isisd/isis_pdu_counter.h"
#include "isisd/isisd.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_pdu.h"
+#include "isisd/isis_pdu_counter.h"
static int pdu_type_to_counter_index(uint8_t pdu_type)
{
@@ -91,3 +91,23 @@ void pdu_counter_print(struct vty *vty, const char *prefix,
pdu_counter_index_to_name(i), counter[i]);
}
}
+
+void pdu_counter_count_drop(struct isis_area *area, uint8_t pdu_type)
+{
+ pdu_counter_count(area->pdu_drop_counters, pdu_type);
+
+ if (area->log_pdu_drops) {
+ isis_log_pdu_drops(
+ area, pdu_counter_index_to_name(
+ pdu_type_to_counter_index(pdu_type)));
+ }
+}
+
+uint64_t pdu_counter_get_count(pdu_counter_t counter, uint8_t pdu_type)
+{
+ int index = pdu_type_to_counter_index(pdu_type);
+
+ if (index < 0)
+ return -1;
+ return counter[index];
+}
diff --git a/isisd/isis_pdu_counter.h b/isisd/isis_pdu_counter.h
index c53c47368f..5c35b4fb51 100644
--- a/isisd/isis_pdu_counter.h
+++ b/isisd/isis_pdu_counter.h
@@ -24,5 +24,7 @@ typedef uint64_t pdu_counter_t[PDU_COUNTER_SIZE];
void pdu_counter_print(struct vty *vty, const char *prefix,
pdu_counter_t counter);
void pdu_counter_count(pdu_counter_t counter, uint8_t pdu_type);
+void pdu_counter_count_drop(struct isis_area *area, uint8_t pdu_type);
+uint64_t pdu_counter_get_count(pdu_counter_t counter, uint8_t pdu_type);
#endif
diff --git a/isisd/isis_snmp.c b/isisd/isis_snmp.c
index 6d9974fe9f..f9e3780e29 100644
--- a/isisd/isis_snmp.c
+++ b/isisd/isis_snmp.c
@@ -833,12 +833,12 @@ static int isis_snmp_conv_next(uint8_t *buf, size_t max_len, size_t *out_len,
*/
static int isis_snmp_area_addr_lookup_exact(oid *oid_idx, size_t oid_idx_len,
struct isis_area **ret_area,
- struct area_addr **ret_addr)
+ struct iso_address **ret_addr)
{
uint8_t cmp_buf[ISIS_SNMP_OSI_ADDR_LEN_MAX];
size_t addr_len;
struct isis_area *area = NULL;
- struct area_addr *addr = NULL;
+ struct iso_address *addr = NULL;
struct listnode *addr_node;
struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
@@ -880,15 +880,15 @@ static int isis_snmp_area_addr_lookup_exact(oid *oid_idx, size_t oid_idx_len,
static int isis_snmp_area_addr_lookup_next(oid *oid_idx, size_t oid_idx_len,
struct isis_area **ret_area,
- struct area_addr **ret_addr)
+ struct iso_address **ret_addr)
{
uint8_t cmp_buf[ISIS_SNMP_OSI_ADDR_LEN_MAX];
size_t addr_len;
int try_exact = 0;
struct isis_area *found_area = NULL;
struct isis_area *area = NULL;
- struct area_addr *found_addr = NULL;
- struct area_addr *addr = NULL;
+ struct iso_address *found_addr = NULL;
+ struct iso_address *addr = NULL;
struct listnode *addr_node;
struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
@@ -1501,7 +1501,7 @@ static uint8_t *isis_snmp_find_man_area(struct variable *v, oid *name,
WriteMethod **write_method)
{
int res;
- struct area_addr *area_addr = NULL;
+ struct iso_address *area_addr = NULL;
oid *oid_idx;
size_t oid_idx_len;
size_t off = 0;
@@ -2485,6 +2485,11 @@ static uint8_t *isis_snmp_find_isadj(struct variable *v, oid *name,
uint32_t delta_ticks;
time_t now_time;
+ /* Ring buffer to print SNPA */
+#define FORMAT_BUF_COUNT 4
+ static char snpa[FORMAT_BUF_COUNT][ISO_SYSID_STRLEN];
+ static size_t cur_buf = 0;
+
*write_method = NULL;
if (*length <= v->namelen) {
@@ -2531,9 +2536,10 @@ static uint8_t *isis_snmp_find_isadj(struct variable *v, oid *name,
return SNMP_INTEGER(adj->threeway_state);
case ISIS_ISADJ_NEIGHSNPAADDRESS: {
- const char *snpa = (char *)snpa_print(adj->snpa);
- *var_len = strlen(snpa);
- return (uint8_t *)snpa;
+ cur_buf = (cur_buf + 1) % FORMAT_BUF_COUNT;
+ snprintfrr(snpa[cur_buf], ISO_SYSID_STRLEN, "%pSY", adj->snpa);
+ *var_len = strlen(snpa[cur_buf]);
+ return (uint8_t *)snpa[cur_buf];
}
case ISIS_ISADJ_NEIGHSYSTYPE:
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index bfe3758cd8..8597049ac0 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -1067,8 +1067,8 @@ end:
&& !isis_level2_adj_up(spftree->area)) {
struct prefix_pair ip_info = { {0} };
if (IS_DEBUG_RTE_EVENTS)
- zlog_debug("ISIS-Spf (%s): add default %s route",
- rawlspid_print(lsp->hdr.lsp_id),
+ zlog_debug("ISIS-Spf (%pLS): add default %s route",
+ lsp->hdr.lsp_id,
spftree->family == AF_INET ? "ipv4"
: "ipv6");
@@ -1207,9 +1207,8 @@ static void isis_spf_preload_tent(struct isis_spftree *spftree,
if (isis_lfa_excise_adj_check(spftree, adj_id)) {
if (IS_DEBUG_LFA)
- zlog_debug("ISIS-SPF: excising adjacency %s",
- isis_format_id(sadj->id,
- ISIS_SYS_ID_LEN + 1));
+ zlog_debug("ISIS-SPF: excising adjacency %pPN",
+ sadj->id);
continue;
}
@@ -1324,8 +1323,8 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree,
LSP_FRAGMENT(lspid) = 0;
lsp = lsp_search(spftree->lspdb, lspid);
if (lsp == NULL || lsp->hdr.rem_lifetime == 0) {
- zlog_warn("ISIS-SPF: No LSP found from root to L%d %s",
- spftree->level, rawlspid_print(lspid));
+ zlog_warn("ISIS-SPF: No LSP found from root to L%d %pLS",
+ spftree->level, lspid);
return;
}
@@ -1663,9 +1662,8 @@ static void isis_spf_loop(struct isis_spftree *spftree,
lsp = lsp_for_vertex(spftree, vertex);
if (!lsp) {
- zlog_warn("ISIS-SPF: No LSP found for %s",
- isis_format_id(vertex->N.id,
- sizeof(vertex->N.id)));
+ zlog_warn("ISIS-SPF: No LSP found for %pPN",
+ vertex->N.id);
continue;
}
diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c
index cb330603e4..e43b84ab2e 100644
--- a/isisd/isis_sr.c
+++ b/isisd/isis_sr.c
@@ -1022,14 +1022,14 @@ static void show_node(struct vty *vty, struct isis_area *area, int level)
if (!cap)
continue;
- ttable_add_row(
- tt, "%s|%u - %u|%u - %u|%s|%u",
- sysid_print(lsp->hdr.lsp_id), cap->srgb.lower_bound,
- cap->srgb.lower_bound + cap->srgb.range_size - 1,
- cap->srlb.lower_bound,
- cap->srlb.lower_bound + cap->srlb.range_size - 1,
- cap->algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF",
- cap->msd);
+ ttable_add_row(tt, "%pSY|%u - %u|%u - %u|%s|%u",
+ lsp->hdr.lsp_id, cap->srgb.lower_bound,
+ cap->srgb.lower_bound + cap->srgb.range_size - 1,
+ cap->srlb.lower_bound,
+ cap->srlb.lower_bound + cap->srlb.range_size - 1,
+ cap->algo[0] == SR_ALGORITHM_SPF ? "SPF"
+ : "S-SPF",
+ cap->msd);
}
/* Dump the generated table. */
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 3ecd2a6f65..4e180ead61 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -903,7 +903,7 @@ static int lsp_to_edge_cb(const uint8_t *id, uint32_t metric, bool old_metric,
struct ls_edge *edge, *dst;
struct ls_attributes *attr;
- te_debug(" |- Process Extended IS for %s", sysid_print(id));
+ te_debug(" |- Process Extended IS for %pSY", id);
/* Check parameters */
if (old_metric || !args || !tlvs)
@@ -1180,14 +1180,14 @@ static void isis_te_parse_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp)
ted = mta->ted;
- te_debug("ISIS-TE(%s): Parse LSP %s", lsp->area->area_tag,
- sysid_print(lsp->hdr.lsp_id));
+ te_debug("ISIS-TE(%s): Parse LSP %pSY", lsp->area->area_tag,
+ lsp->hdr.lsp_id);
/* First parse LSP to obtain the corresponding Vertex */
vertex = lsp_to_vertex(ted, lsp);
if (!vertex) {
- zlog_warn("Unable to build Vertex from LSP %s. Abort!",
- sysid_print(lsp->hdr.lsp_id));
+ zlog_warn("Unable to build Vertex from LSP %pSY. Abort!",
+ lsp->hdr.lsp_id);
return;
}
@@ -1251,8 +1251,8 @@ static void isis_te_delete_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp)
if (!IS_MPLS_TE(mta) || !mta->ted || !lsp)
return;
- te_debug("ISIS-TE(%s): Delete Link State TED objects from LSP %s",
- lsp->area->area_tag, sysid_print(lsp->hdr.lsp_id));
+ te_debug("ISIS-TE(%s): Delete Link State TED objects from LSP %pSY",
+ lsp->area->area_tag, lsp->hdr.lsp_id);
/* Compute Link State Node ID from IS-IS sysID ... */
if (lsp->level == ISIS_LEVEL1)
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index b52a38be7f..3b6db0ee17 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -661,7 +661,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
sbuf_push(
buf, indent,
"Lan-Adjacency-SID: %u, Weight: %hhu, Flags: F:%c B:%c, V:%c, L:%c, S:%c, P:%c\n"
- " Neighbor-ID: %s\n",
+ " Neighbor-ID: %pSY\n",
lan->sid, lan->weight,
lan->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG
? '1'
@@ -681,7 +681,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
lan->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG
? '1'
: '0',
- isis_format_id(lan->neighbor_id, 6));
+ lan->neighbor_id);
}
}
}
@@ -1590,14 +1590,14 @@ static void format_item_area_address(uint16_t mtid, struct isis_item *i,
int indent)
{
struct isis_area_address *addr = (struct isis_area_address *)i;
+ struct iso_address iso_addr;
- if (json) {
- json_object_string_add(json, "area-addr",
- isonet_print(addr->addr, addr->len));
- } else {
- sbuf_push(buf, indent, "Area Address: %s\n",
- isonet_print(addr->addr, addr->len));
- }
+ memcpy(iso_addr.area_addr, addr->addr, ISO_ADDR_SIZE);
+ iso_addr.addr_len = addr->len;
+ if (json)
+ json_object_string_addf(json, "area-addr", "%pIS", &iso_addr);
+ else
+ sbuf_push(buf, indent, "Area Address: %pIS\n", &iso_addr);
}
static void free_item_area_address(struct isis_item *i)
@@ -1678,17 +1678,18 @@ static void format_item_oldstyle_reach(uint16_t mtid, struct isis_item *i,
struct json_object *json, int indent)
{
struct isis_oldstyle_reach *r = (struct isis_oldstyle_reach *)i;
+ char sys_id[ISO_SYSID_STRLEN];
+ snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pPN", r->id);
if (json) {
struct json_object *old_json;
old_json = json_object_new_object();
json_object_object_add(json, "old-reach-style", old_json);
- json_object_string_add(old_json, "is-reach",
- isis_format_id(r->id, 7));
+ json_object_string_add(old_json, "is-reach", sys_id);
json_object_int_add(old_json, "metric", r->metric);
} else
sbuf_push(buf, indent, "IS Reachability: %s (Metric: %hhu)\n",
- isis_format_id(r->id, 7), r->metric);
+ sys_id, r->metric);
}
static void free_item_oldstyle_reach(struct isis_item *i)
@@ -1760,13 +1761,13 @@ static void format_item_lan_neighbor(uint16_t mtid, struct isis_item *i,
int indent)
{
struct isis_lan_neighbor *n = (struct isis_lan_neighbor *)i;
+ char sys_id[ISO_SYSID_STRLEN];
- if (json) {
- json_object_string_add(json, "lan-neighbor",
- isis_format_id(n->mac, 6));
- } else
- sbuf_push(buf, indent, "LAN Neighbor: %s\n",
- isis_format_id(n->mac, 6));
+ snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pSY", n->mac);
+ if (json)
+ json_object_string_add(json, "lan-neighbor", sys_id);
+ else
+ sbuf_push(buf, indent, "LAN Neighbor: %s\n", sys_id);
}
static void free_item_lan_neighbor(struct isis_item *i)
@@ -1831,23 +1832,25 @@ static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i,
int indent)
{
struct isis_lsp_entry *e = (struct isis_lsp_entry *)i;
+ char sys_id[ISO_SYSID_STRLEN];
+ snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pLS", e->id);
if (json) {
char buf[255];
struct json_object *lsp_json;
lsp_json = json_object_new_object();
json_object_object_add(json, "lsp-entry", lsp_json);
- json_object_string_add(lsp_json, "id", isis_format_id(e->id, 8));
+ json_object_string_add(lsp_json, "id", sys_id);
snprintfrr(buf,sizeof(buf),"0x%08x",e->seqno);
json_object_string_add(lsp_json, "seq", buf);
snprintfrr(buf,sizeof(buf),"0x%04hx",e->checksum);
json_object_string_add(lsp_json, "chksum", buf);
json_object_int_add(lsp_json, "lifetime", e->checksum);
} else
- sbuf_push(buf, indent,
- "LSP Entry: %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus\n",
- isis_format_id(e->id, 8), e->seqno, e->checksum,
- e->rem_lifetime);
+ sbuf_push(
+ buf, indent,
+ "LSP Entry: %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus\n",
+ sys_id, e->seqno, e->checksum, e->rem_lifetime);
}
static void free_item_lsp_entry(struct isis_item *i)
@@ -1919,7 +1922,9 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i,
struct json_object *json, int indent)
{
struct isis_extended_reach *r = (struct isis_extended_reach *)i;
+ char sys_id[ISO_SYSID_STRLEN];
+ snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pPN", r->id);
if (json) {
struct json_object *reach_json;
reach_json = json_object_new_object();
@@ -1927,8 +1932,7 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i,
json_object_string_add(
reach_json, "mt-id",
(mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT");
- json_object_string_add(reach_json, "id",
- isis_format_id(r->id, 7));
+ json_object_string_add(reach_json, "id", sys_id);
json_object_int_add(reach_json, "metric", r->metric);
if (mtid != ISIS_MT_IPV4_UNICAST)
json_object_string_add(reach_json, "mt-name",
@@ -1940,7 +1944,7 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i,
} else {
sbuf_push(buf, indent, "%s Reachability: %s (Metric: %u)",
(mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT",
- isis_format_id(r->id, 7), r->metric);
+ sys_id, r->metric);
if (mtid != ISIS_MT_IPV4_UNICAST)
sbuf_push(buf, 0, " %s", isis_mtid2str(mtid));
sbuf_push(buf, 0, "\n");
@@ -3125,9 +3129,12 @@ static void
format_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj,
struct sbuf *buf, struct json_object *json, int indent)
{
+ char sys_id[ISO_SYSID_STRLEN];
+
if (!threeway_adj)
return;
+ snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pSY", threeway_adj->neighbor_id);
if (json) {
struct json_object *three_json;
three_json = json_object_new_object();
@@ -3140,9 +3147,7 @@ format_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj,
threeway_adj->local_circuit_id);
if (!threeway_adj->neighbor_set)
return;
- json_object_string_add(
- three_json, "neigh-system-id",
- isis_format_id(threeway_adj->neighbor_id, 6));
+ json_object_string_add(three_json, "neigh-system-id", sys_id);
json_object_int_add(three_json, "neigh-ext-circuit-id",
threeway_adj->neighbor_circuit_id);
} else {
@@ -3155,8 +3160,7 @@ format_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj,
if (!threeway_adj->neighbor_set)
return;
- sbuf_push(buf, indent, " Neighbor System ID: %s\n",
- isis_format_id(threeway_adj->neighbor_id, 6));
+ sbuf_push(buf, indent, " Neighbor System ID: %s\n", sys_id);
sbuf_push(buf, indent, " Neighbor Extended Circuit ID: %u\n",
threeway_adj->neighbor_circuit_id);
}
@@ -3988,33 +3992,29 @@ static void format_tlv_purge_originator(struct isis_purge_originator *poi,
struct sbuf *buf,
struct json_object *json, int indent)
{
+ char sen_id[ISO_SYSID_STRLEN];
+ char gen_id[ISO_SYSID_STRLEN];
+
if (!poi)
return;
+ snprintfrr(gen_id, ISO_SYSID_STRLEN, "%pSY", poi->generator);
+ if (poi->sender_set)
+ snprintfrr(sen_id, ISO_SYSID_STRLEN, "%pSY", poi->sender);
+
if (json) {
struct json_object *purge_json;
purge_json = json_object_new_object();
json_object_object_add(json, "purge_originator", purge_json);
- json_object_string_add(
- purge_json, "id",
- isis_format_id(poi->generator, sizeof(poi->generator)));
- if (poi->sender_set) {
- json_object_string_add(
- purge_json, "rec-from",
- isis_format_id(poi->sender,
- sizeof(poi->sender)));
- }
+ json_object_string_add(purge_json, "id", gen_id);
+ if (poi->sender_set)
+ json_object_string_add(purge_json, "rec-from", sen_id);
} else {
sbuf_push(buf, indent, "Purge Originator Identification:\n");
- sbuf_push(
- buf, indent, " Generator: %s\n",
- isis_format_id(poi->generator, sizeof(poi->generator)));
- if (poi->sender_set) {
- sbuf_push(buf, indent, " Received-From: %s\n",
- isis_format_id(poi->sender,
- sizeof(poi->sender)));
- }
+ sbuf_push(buf, indent, " Generator: %s\n", gen_id);
+ if (poi->sender_set)
+ sbuf_push(buf, indent, " Received-From: %s\n", sen_id);
}
}
@@ -5271,14 +5271,14 @@ void isis_tlvs_add_area_addresses(struct isis_tlvs *tlvs,
struct list *addresses)
{
struct listnode *node;
- struct area_addr *area_addr;
+ struct iso_address *area_addr;
for (ALL_LIST_ELEMENTS_RO(addresses, node, area_addr)) {
struct isis_area_address *a =
XCALLOC(MTYPE_ISIS_TLV, sizeof(*a));
a->len = area_addr->addr_len;
- memcpy(a->addr, area_addr->area_addr, 20);
+ memcpy(a->addr, area_addr->area_addr, ISO_ADDR_SIZE);
append_item(&tlvs->area_addresses, (struct isis_item *)a);
}
}
@@ -5475,7 +5475,7 @@ bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs,
for (struct isis_area_address *addr = addr_head; addr;
addr = addr->next) {
struct listnode *node;
- struct area_addr *a;
+ struct iso_address *a;
for (ALL_LIST_ELEMENTS_RO(addresses, node, a)) {
if (a->addr_len == addr->len
diff --git a/isisd/isis_tx_queue.c b/isisd/isis_tx_queue.c
index ec2d50d60a..caf97f1174 100644
--- a/isisd/isis_tx_queue.c
+++ b/isisd/isis_tx_queue.c
@@ -126,12 +126,12 @@ void _isis_tx_queue_add(struct isis_tx_queue *queue,
return;
if (IS_DEBUG_TX_QUEUE) {
- zlog_debug("Add LSP %s to %s queue as %s LSP. (From %s %s:%d)",
- rawlspid_print(lsp->hdr.lsp_id),
- queue->circuit->interface->name,
- (type == TX_LSP_CIRCUIT_SCOPED) ?
- "circuit scoped" : "regular",
- func, file, line);
+ zlog_debug(
+ "Add LSP %pLS to %s queue as %s LSP. (From %s %s:%d)",
+ lsp->hdr.lsp_id, queue->circuit->interface->name,
+ (type == TX_LSP_CIRCUIT_SCOPED) ? "circuit scoped"
+ : "regular",
+ func, file, line);
}
struct isis_tx_queue_entry *e = tx_queue_find(queue, lsp);
@@ -164,9 +164,8 @@ void _isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp,
return;
if (IS_DEBUG_TX_QUEUE) {
- zlog_debug("Remove LSP %s from %s queue. (From %s %s:%d)",
- rawlspid_print(lsp->hdr.lsp_id),
- queue->circuit->interface->name,
+ zlog_debug("Remove LSP %pLS from %s queue. (From %s %s:%d)",
+ lsp->hdr.lsp_id, queue->circuit->interface->name,
func, file, line);
}
diff --git a/isisd/isisd.c b/isisd/isisd.c
index c6369a884e..fd6b91b42e 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -272,7 +272,7 @@ void isis_area_del_circuit(struct isis_area *area, struct isis_circuit *circuit)
static void delete_area_addr(void *arg)
{
- struct area_addr *addr = (struct area_addr *)arg;
+ struct iso_address *addr = (struct iso_address *)arg;
XFREE(MTYPE_ISIS_AREA_ADDR, addr);
}
@@ -809,8 +809,8 @@ static void area_set_mt_overload(struct isis_area *area, uint16_t mtid,
int area_net_title(struct vty *vty, const char *net_title)
{
VTY_DECLVAR_CONTEXT(isis_area, area);
- struct area_addr *addr;
- struct area_addr *addrp;
+ struct iso_address *addr;
+ struct iso_address *addrp;
struct listnode *node;
uint8_t buff[255];
@@ -823,14 +823,14 @@ int area_net_title(struct vty *vty, const char *net_title)
return CMD_ERR_NOTHING_TODO;
}
- addr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr));
+ addr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct iso_address));
addr->addr_len = dotformat2buff(buff, net_title);
memcpy(addr->area_addr, buff, addr->addr_len);
#ifdef EXTREME_DEBUG
zlog_debug("added area address %s for area %s (address length %d)",
net_title, area->area_tag, addr->addr_len);
#endif /* EXTREME_DEBUG */
- if (addr->addr_len < 8 || addr->addr_len > 20) {
+ if (addr->addr_len < ISO_ADDR_MIN || addr->addr_len > ISO_ADDR_SIZE) {
vty_out(vty,
"area address must be at least 8..20 octets long (%d)\n",
addr->addr_len);
@@ -852,8 +852,8 @@ int area_net_title(struct vty *vty, const char *net_title)
memcpy(area->isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
area->isis->sysid_set = 1;
if (IS_DEBUG_EVENTS)
- zlog_debug("Router has SystemID %s",
- sysid_print(area->isis->sysid));
+ zlog_debug("Router has SystemID %pSY",
+ area->isis->sysid);
} else {
/*
* Check that the SystemID portions match
@@ -899,12 +899,12 @@ int area_net_title(struct vty *vty, const char *net_title)
int area_clear_net_title(struct vty *vty, const char *net_title)
{
VTY_DECLVAR_CONTEXT(isis_area, area);
- struct area_addr addr, *addrp = NULL;
+ struct iso_address addr, *addrp = NULL;
struct listnode *node;
uint8_t buff[255];
addr.addr_len = dotformat2buff(buff, net_title);
- if (addr.addr_len < 8 || addr.addr_len > 20) {
+ if (addr.addr_len < ISO_ADDR_MIN || addr.addr_len > ISO_ADDR_SIZE) {
vty_out(vty,
"Unsupported area address length %d, should be 8...20 \n",
addr.addr_len);
@@ -2348,11 +2348,11 @@ static void common_isis_summary_json(struct json_object *json,
time_t cur;
char uptime[MONOTIME_STRLEN];
char stier[5];
+
json_object_string_add(json, "vrf", isis->name);
json_object_int_add(json, "process-id", isis->process_id);
if (isis->sysid_set)
- json_object_string_add(json, "system-id",
- sysid_print(isis->sysid));
+ json_object_string_addf(json, "system-id", "%pSY", isis->sysid);
cur = time(NULL);
cur -= isis->uptime;
@@ -2380,16 +2380,11 @@ static void common_isis_summary_json(struct json_object *json,
}
if (listcount(area->area_addrs) > 0) {
- struct area_addr *area_addr;
+ struct iso_address *area_addr;
for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2,
- area_addr)) {
- json_object_string_add(
- area_json, "net",
- isonet_print(area_addr->area_addr,
- area_addr->addr_len +
- ISIS_SYS_ID_LEN +
- 1));
- }
+ area_addr))
+ json_object_string_addf(area_json, "net",
+ "%pISl", area_addr);
}
tx_pdu_json = json_object_new_object();
@@ -2462,8 +2457,7 @@ static void common_isis_summary_vty(struct vty *vty, struct isis *isis)
vty_out(vty, "vrf : %s\n", isis->name);
vty_out(vty, "Process Id : %ld\n", isis->process_id);
if (isis->sysid_set)
- vty_out(vty, "System Id : %s\n",
- sysid_print(isis->sysid));
+ vty_out(vty, "System Id : %pSY\n", isis->sysid);
vty_out(vty, "Up time : ");
vty_out_timestr(vty, isis->uptime);
@@ -2485,15 +2479,10 @@ static void common_isis_summary_vty(struct vty *vty, struct isis *isis)
}
if (listcount(area->area_addrs) > 0) {
- struct area_addr *area_addr;
+ struct iso_address *area_addr;
for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2,
- area_addr)) {
- vty_out(vty, " Net: %s\n",
- isonet_print(area_addr->area_addr,
- area_addr->addr_len
- + ISIS_SYS_ID_LEN
- + 1));
- }
+ area_addr))
+ vty_out(vty, " Net: %pISl\n", area_addr);
}
vty_out(vty, " TX counters per PDU type:\n");
@@ -3497,15 +3486,10 @@ static int isis_config_write(struct vty *vty)
write++;
/* ISIS - Net */
if (listcount(area->area_addrs) > 0) {
- struct area_addr *area_addr;
+ struct iso_address *area_addr;
for (ALL_LIST_ELEMENTS_RO(area->area_addrs,
node2, area_addr)) {
- vty_out(vty, " net %s\n",
- isonet_print(
- area_addr->area_addr,
- area_addr->addr_len
- + ISIS_SYS_ID_LEN
- + 1));
+ vty_out(vty, " net %pISl\n", area_addr);
write++;
}
}
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 0b1f1cb620..12d9cd36c4 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -24,6 +24,7 @@
#include "isis_lfa.h"
#include "qobj.h"
#include "ldp_sync.h"
+#include "iso.h"
DECLARE_MGROUP(ISISD);
@@ -87,7 +88,7 @@ struct isis {
uint32_t router_id; /* Router ID from zebra */
struct list *area_list; /* list of IS-IS areas */
uint8_t max_area_addrs; /* maximumAreaAdresses */
- struct area_addr *man_area_addrs; /* manualAreaAddresses */
+ struct iso_address *man_area_addrs; /* manualAreaAddresses */
time_t uptime; /* when did we start */
struct event *t_dync_clean; /* dynamic hostname cache cleanup thread */
uint32_t circuit_ids_used[8]; /* 256 bits to track circuit ids 1 through 255 */
@@ -195,6 +196,8 @@ struct isis_area {
int ip_circuits;
/* logging adjacency changes? */
uint8_t log_adj_changes;
+ /* logging pdu drops? */
+ uint8_t log_pdu_drops;
/* multi topology settings */
struct list *mt_settings;
/* MPLS-TE settings */
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index 4a5bc36198..5895924a5e 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* route-map for interface.
* Copyright (C) 1999 Kunihiro Ishiguro
+ * Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
@@ -10,7 +11,9 @@
#include "memory.h"
#include "if.h"
#include "if_rmap.h"
-#include "ripd/ripd.h"
+#include "northbound_cli.h"
+
+#include "lib/if_rmap_clippy.c"
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX, "Interface route map container");
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX_NAME,
@@ -18,8 +21,6 @@ DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX_NAME,
DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map");
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name");
-static struct list *if_rmap_ctx_list;
-
static struct if_rmap *if_rmap_new(void)
{
struct if_rmap *new;
@@ -31,7 +32,9 @@ static struct if_rmap *if_rmap_new(void)
static void if_rmap_free(struct if_rmap *if_rmap)
{
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->ifname);
+ char *no_const_ifname = (char *)if_rmap->ifname;
+
+ XFREE(MTYPE_IF_RMAP_NAME, no_const_ifname);
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
@@ -41,22 +44,16 @@ static void if_rmap_free(struct if_rmap *if_rmap)
struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx, const char *ifname)
{
- struct if_rmap key;
+ struct if_rmap key = {.ifname = ifname};
struct if_rmap *if_rmap;
- /* temporary copy */
- key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
-
if_rmap = hash_lookup(ctx->ifrmaphash, &key);
- XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
-
return if_rmap;
}
void if_rmap_hook_add(struct if_rmap_ctx *ctx,
- void (*func)(struct if_rmap_ctx *ctx,
- struct if_rmap *))
+ void (*func)(struct if_rmap_ctx *ctx, struct if_rmap *))
{
ctx->if_rmap_add_hook = func;
}
@@ -81,16 +78,11 @@ static void *if_rmap_hash_alloc(void *arg)
static struct if_rmap *if_rmap_get(struct if_rmap_ctx *ctx, const char *ifname)
{
- struct if_rmap key;
+ struct if_rmap key = {.ifname = ifname};
struct if_rmap *ret;
- /* temporary copy */
- key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
-
ret = hash_get(ctx->ifrmaphash, &key, if_rmap_hash_alloc);
- XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
-
return ret;
}
@@ -109,147 +101,171 @@ static bool if_rmap_hash_cmp(const void *arg1, const void *arg2)
return strcmp(if_rmap1->ifname, if_rmap2->ifname) == 0;
}
-static struct if_rmap *if_rmap_set(struct if_rmap_ctx *ctx,
- const char *ifname, enum if_rmap_type type,
- const char *routemap_name)
+static void if_rmap_set(struct if_rmap_ctx *ctx, const char *ifname,
+ enum if_rmap_type type, const char *routemap_name)
{
- struct if_rmap *if_rmap;
-
- if_rmap = if_rmap_get(ctx, ifname);
+ struct if_rmap *if_rmap = if_rmap_get(ctx, ifname);
- if (type == IF_RMAP_IN) {
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
- if_rmap->routemap[IF_RMAP_IN] =
- XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
- }
- if (type == IF_RMAP_OUT) {
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
- if_rmap->routemap[IF_RMAP_OUT] =
- XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
- }
+ assert(type == IF_RMAP_IN || type == IF_RMAP_OUT);
+ XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[type]);
+ if_rmap->routemap[type] = XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
if (ctx->if_rmap_add_hook)
(ctx->if_rmap_add_hook)(ctx, if_rmap);
-
- return if_rmap;
}
-static int if_rmap_unset(struct if_rmap_ctx *ctx,
- const char *ifname, enum if_rmap_type type,
- const char *routemap_name)
+static void if_rmap_unset(struct if_rmap_ctx *ctx, const char *ifname,
+ enum if_rmap_type type)
{
- struct if_rmap *if_rmap;
+ struct if_rmap *if_rmap = if_rmap_lookup(ctx, ifname);
- if_rmap = if_rmap_lookup(ctx, ifname);
if (!if_rmap)
- return 0;
-
- if (type == IF_RMAP_IN) {
- if (!if_rmap->routemap[IF_RMAP_IN])
- return 0;
- if (strcmp(if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0)
- return 0;
-
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
- }
+ return;
- if (type == IF_RMAP_OUT) {
- if (!if_rmap->routemap[IF_RMAP_OUT])
- return 0;
- if (strcmp(if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0)
- return 0;
+ assert(type == IF_RMAP_IN || type == IF_RMAP_OUT);
+ if (!if_rmap->routemap[type])
+ return;
- XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
- }
+ XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[type]);
if (ctx->if_rmap_delete_hook)
ctx->if_rmap_delete_hook(ctx, if_rmap);
- if (if_rmap->routemap[IF_RMAP_IN] == NULL
- && if_rmap->routemap[IF_RMAP_OUT] == NULL) {
+ if (if_rmap->routemap[IF_RMAP_IN] == NULL &&
+ if_rmap->routemap[IF_RMAP_OUT] == NULL) {
hash_release(ctx->ifrmaphash, if_rmap);
if_rmap_free(if_rmap);
}
-
- return 1;
}
-DEFUN (if_rmap,
- if_rmap_cmd,
- "route-map RMAP_NAME <in|out> IFNAME",
- "Route map set\n"
- "Route map name\n"
- "Route map set for input filtering\n"
- "Route map set for output filtering\n"
- "Route map interface name\n")
+static int if_route_map_handler(struct vty *vty, bool no, const char *dir,
+ const char *other_dir, const char *ifname,
+ const char *route_map)
{
- int idx_rmap_name = 1;
- int idx_in_out = 2;
- int idx_ifname = 3;
- enum if_rmap_type type;
- struct if_rmap_ctx *ctx;
+ enum nb_operation op = no ? NB_OP_DESTROY : NB_OP_MODIFY;
const struct lyd_node *dnode;
- struct rip *rip;
-
- dnode = yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
- rip = nb_running_get_entry(dnode, NULL, true);
- ctx = rip->if_rmap_ctx;
-
- if (strncmp(argv[idx_in_out]->text, "in", 1) == 0)
- type = IF_RMAP_IN;
- else if (strncmp(argv[idx_in_out]->text, "out", 1) == 0)
- type = IF_RMAP_OUT;
- else {
- vty_out(vty, "route-map direction must be [in|out]\n");
- return CMD_WARNING_CONFIG_FAILED;
+ char xpath[XPATH_MAXLEN];
+
+ if (!no) {
+ snprintf(
+ xpath, sizeof(xpath),
+ "./if-route-maps/if-route-map[interface='%s']/%s-route-map",
+ ifname, dir);
+ } else {
+ /*
+ * If we are deleting the last policy for this interface,
+ * (i.e., no `in` or `out` policy). delete the interface list
+ * node instead.
+ */
+ dnode = yang_dnode_get(vty->candidate_config->dnode,
+ VTY_CURR_XPATH);
+ if (yang_dnode_existsf(
+ dnode,
+ "./if-route-maps/if-route-map[interface='%s']/%s-route-map",
+ ifname, other_dir)) {
+ snprintf(
+ xpath, sizeof(xpath),
+ "./if-route-maps/if-route-map[interface='%s']/%s-route-map",
+ ifname, dir);
+ } else {
+ /* both dir will be empty so delete the list node */
+ snprintf(xpath, sizeof(xpath),
+ "./if-route-maps/if-route-map[interface='%s']",
+ ifname);
+ }
}
+ nb_cli_enqueue_change(vty, xpath, op, route_map);
- if_rmap_set(ctx, argv[idx_ifname]->arg,
- type, argv[idx_rmap_name]->arg);
+ return nb_cli_apply_changes(vty, NULL);
+}
- return CMD_SUCCESS;
+DEFPY_YANG(if_ipv4_route_map, if_ipv4_route_map_cmd,
+ "route-map ROUTE-MAP <in$in|out> IFNAME",
+ "Route map set\n"
+ "Route map name\n"
+ "Route map set for input filtering\n"
+ "Route map set for output filtering\n" INTERFACE_STR)
+{
+ const char *dir = in ? "in" : "out";
+ const char *other_dir = in ? "out" : "in";
+
+ return if_route_map_handler(vty, false, dir, other_dir, ifname,
+ route_map);
}
-DEFUN (no_if_rmap,
- no_if_rmap_cmd,
- "no route-map ROUTEMAP_NAME <in|out> IFNAME",
- NO_STR
- "Route map unset\n"
- "Route map name\n"
- "Route map for input filtering\n"
- "Route map for output filtering\n"
- "Route map interface name\n")
+DEFPY_YANG(no_if_ipv4_route_map, no_if_ipv4_route_map_cmd,
+ "no route-map [ROUTE-MAP] <in$in|out> IFNAME",
+ NO_STR
+ "Route map set\n"
+ "Route map name\n"
+ "Route map set for input filtering\n"
+ "Route map set for output filtering\n" INTERFACE_STR)
{
- int idx_routemap_name = 2;
- int idx_in_out = 3;
- int idx_ifname = 4;
- int ret;
- enum if_rmap_type type;
- struct if_rmap_ctx *ctx =
- (struct if_rmap_ctx *)listnode_head(if_rmap_ctx_list);
-
- if (strncmp(argv[idx_in_out]->arg, "i", 1) == 0)
- type = IF_RMAP_IN;
- else if (strncmp(argv[idx_in_out]->arg, "o", 1) == 0)
- type = IF_RMAP_OUT;
- else {
- vty_out(vty, "route-map direction must be [in|out]\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ const char *dir = in ? "in" : "out";
+ const char *other_dir = in ? "out" : "in";
- ret = if_rmap_unset(ctx, argv[idx_ifname]->arg, type,
- argv[idx_routemap_name]->arg);
- if (!ret) {
- vty_out(vty, "route-map doesn't exist\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- return CMD_SUCCESS;
+ return if_route_map_handler(vty, true, dir, other_dir, ifname,
+ route_map);
+}
+
+/*
+ * CLI infra requires new handlers for ripngd
+ */
+DEFPY_YANG(if_ipv6_route_map, if_ipv6_route_map_cmd,
+ "route-map ROUTE-MAP <in$in|out> IFNAME",
+ "Route map set\n"
+ "Route map name\n"
+ "Route map set for input filtering\n"
+ "Route map set for output filtering\n" INTERFACE_STR)
+{
+ const char *dir = in ? "in" : "out";
+ const char *other_dir = in ? "out" : "in";
+
+ return if_route_map_handler(vty, false, dir, other_dir, ifname,
+ route_map);
+}
+
+DEFPY_YANG(no_if_ipv6_route_map, no_if_ipv6_route_map_cmd,
+ "no route-map [ROUTE-MAP] <in$in|out> IFNAME",
+ NO_STR
+ "Route map set\n"
+ "Route map name\n"
+ "Route map set for input filtering\n"
+ "Route map set for output filtering\n" INTERFACE_STR)
+{
+ const char *dir = in ? "in" : "out";
+ const char *other_dir = in ? "out" : "in";
+
+ return if_route_map_handler(vty, true, dir, other_dir, ifname,
+ route_map);
+}
+
+
+void if_rmap_yang_modify_cb(struct if_rmap_ctx *ctx,
+ const struct lyd_node *dnode,
+ enum if_rmap_type type, bool del)
+{
+
+ const char *mapname = yang_dnode_get_string(dnode, NULL);
+ const char *ifname = yang_dnode_get_string(dnode, "../interface");
+
+ if (del)
+ if_rmap_unset(ctx, ifname, type);
+ else
+ if_rmap_set(ctx, ifname, type, mapname);
+}
+
+void if_rmap_yang_destroy_cb(struct if_rmap_ctx *ctx,
+ const struct lyd_node *dnode)
+{
+ const char *ifname = yang_dnode_get_string(dnode, "interface");
+ if_rmap_unset(ctx, ifname, IF_RMAP_IN);
+ if_rmap_unset(ctx, ifname, IF_RMAP_OUT);
}
/* Configuration write function. */
-int config_write_if_rmap(struct vty *vty,
- struct if_rmap_ctx *ctx)
+int config_write_if_rmap(struct vty *vty, struct if_rmap_ctx *ctx)
{
unsigned int i;
struct hash_bucket *mp;
@@ -281,10 +297,8 @@ int config_write_if_rmap(struct vty *vty,
void if_rmap_ctx_delete(struct if_rmap_ctx *ctx)
{
- listnode_delete(if_rmap_ctx_list, ctx);
hash_clean_and_free(&ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
- if (ctx->name)
- XFREE(MTYPE_IF_RMAP_CTX_NAME, ctx);
+ XFREE(MTYPE_IF_RMAP_CTX_NAME, ctx->name);
XFREE(MTYPE_IF_RMAP_CTX, ctx);
}
@@ -296,27 +310,23 @@ struct if_rmap_ctx *if_rmap_ctx_create(const char *name)
ctx = XCALLOC(MTYPE_IF_RMAP_CTX, sizeof(struct if_rmap_ctx));
ctx->name = XSTRDUP(MTYPE_IF_RMAP_CTX_NAME, name);
- ctx->ifrmaphash = hash_create_size(4, if_rmap_hash_make, if_rmap_hash_cmp,
- "Interface Route-Map Hash");
- if (!if_rmap_ctx_list)
- if_rmap_ctx_list = list_new();
- listnode_add(if_rmap_ctx_list, ctx);
+ ctx->ifrmaphash =
+ hash_create_size(4, if_rmap_hash_make, if_rmap_hash_cmp,
+ "Interface Route-Map Hash");
return ctx;
}
void if_rmap_init(int node)
{
- if (node == RIPNG_NODE) {
- } else if (node == RIP_NODE) {
- install_element(RIP_NODE, &if_rmap_cmd);
- install_element(RIP_NODE, &no_if_rmap_cmd);
+ if (node == RIP_NODE) {
+ install_element(RIP_NODE, &if_ipv4_route_map_cmd);
+ install_element(RIP_NODE, &no_if_ipv4_route_map_cmd);
+ } else if (node == RIPNG_NODE) {
+ install_element(RIPNG_NODE, &if_ipv6_route_map_cmd);
+ install_element(RIPNG_NODE, &no_if_ipv6_route_map_cmd);
}
- if_rmap_ctx_list = list_new();
}
void if_rmap_terminate(void)
{
- if (!if_rmap_ctx_list)
- return;
- list_delete(&if_rmap_ctx_list);
}
diff --git a/lib/if_rmap.h b/lib/if_rmap.h
index 3bdbc2a3b2..6f5fb578f0 100644
--- a/lib/if_rmap.h
+++ b/lib/if_rmap.h
@@ -6,15 +6,20 @@
#ifndef _ZEBRA_IF_RMAP_H
#define _ZEBRA_IF_RMAP_H
+#include "typesafe.h"
+
#ifdef __cplusplus
extern "C" {
#endif
+struct lyd_node;
+struct vty;
+
enum if_rmap_type { IF_RMAP_IN, IF_RMAP_OUT, IF_RMAP_MAX };
struct if_rmap {
/* Name of the interface. */
- char *ifname;
+ const char *ifname;
char *routemap[IF_RMAP_MAX];
};
@@ -45,6 +50,11 @@ void if_rmap_hook_delete(struct if_rmap_ctx *ctx,
struct if_rmap *));
extern struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx,
const char *ifname);
+extern void if_rmap_yang_modify_cb(struct if_rmap_ctx *ctx,
+ const struct lyd_node *dnode,
+ enum if_rmap_type type, bool del);
+extern void if_rmap_yang_destroy_cb(struct if_rmap_ctx *ctx,
+ const struct lyd_node *dnode);
extern int config_write_if_rmap(struct vty *, struct if_rmap_ctx *ctx);
#ifdef __cplusplus
diff --git a/lib/iso.c b/lib/iso.c
new file mode 100644
index 0000000000..fe97776ade
--- /dev/null
+++ b/lib/iso.c
@@ -0,0 +1,144 @@
+/*
+ * ISO Network functions - iso_net.c
+ *
+ * Author: Olivier Dugeon <olivier.dugeon@orange.com>
+ *
+ * Copyright (C) 2023 Orange http://www.orange.com
+ *
+ * This file is part of Free Range Routing (FRR).
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "compiler.h"
+
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "printfrr.h"
+#include "iso.h"
+
+/**
+ * Print ISO System ID as 0000.0000.0000
+ *
+ * @param Print buffer
+ * @param Print argument
+ * @param Pointer to the System ID to be printed
+ *
+ * @return Number of printed characters
+ */
+printfrr_ext_autoreg_p("SY", printfrr_iso_sysid);
+static ssize_t printfrr_iso_sysid(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *vptr)
+{
+ const uint8_t *id = vptr;
+
+ if (!id)
+ return bputs(buf, "(null)");
+
+ return bprintfrr(buf, "%02x%02x.%02x%02x.%02x%02x",
+ id[0], id[1], id[2], id[3], id[4], id[5]);
+}
+
+/**
+ * Print ISO Pseudo Node system ID as 0000.0000.0000.00
+ *
+ * @param Print buffer
+ * @param Print argument
+ * @param Pointer to the System ID to be printed
+ *
+ * @return Number of printed characters
+ */
+printfrr_ext_autoreg_p("PN", printfrr_iso_pseudo);
+static ssize_t printfrr_iso_pseudo(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *vptr)
+{
+ const uint8_t *id = vptr;
+
+ if (!id)
+ return bputs(buf, "(null)");
+
+ return bprintfrr(buf, "%02x%02x.%02x%02x.%02x%02x.%02x",
+ id[0], id[1], id[2], id[3], id[4], id[5], id[6]);
+}
+
+/**
+ * Print ISO LSP Fragment System ID as 0000.0000.0000.00-00
+ *
+ * @param Print buffer
+ * @param Print argument
+ * @param Pointer to the System ID to be printed
+ *
+ * @return Number of printed characters
+ */
+printfrr_ext_autoreg_p("LS", printfrr_iso_frag_id);
+static ssize_t printfrr_iso_frag_id(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *vptr)
+{
+ const uint8_t *id = vptr;
+
+ if (!id)
+ return bputs(buf, "(null)");
+
+ return bprintfrr(buf, "%02x%02x.%02x%02x.%02x%02x.%02x-%02x",
+ id[0], id[1], id[2], id[3], id[4], id[5], id[6],
+ id[7]);
+}
+
+/**
+ * Print ISO Network address as 00.0000.0000.0000 ... with the System ID
+ * as 0000.0000.0000.00 when long 'l' option is added to '%pIS'
+ *
+ * @param Print buffer
+ * @param Print argument
+ * @param Pointer to the ISO Network address
+ *
+ * @return Number of printed characters
+ */
+printfrr_ext_autoreg_p("IS", printfrr_iso_addr);
+static ssize_t printfrr_iso_addr(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *vptr)
+{
+ const struct iso_address *ia = vptr;
+ uint8_t len = 0;
+ int i = 0;
+ ssize_t ret = 0;
+
+ if (ea->fmt[0] == 'l') {
+ len = 7; /* ISO SYSTEM ID + 1 */
+ ea->fmt++;
+ }
+
+ if (!ia)
+ return bputs(buf, "(null)");
+
+ len += ia->addr_len;
+ while (i < len) {
+ /* No dot for odd index and at the end of address */
+ if ((i & 1) || (i == (len - 1)))
+ ret += bprintfrr(buf, "%02x", ia->area_addr[i]);
+ else
+ ret += bprintfrr(buf, "%02x.", ia->area_addr[i]);
+ i++;
+ }
+
+ return ret;
+}
+
diff --git a/lib/iso.h b/lib/iso.h
new file mode 100644
index 0000000000..975d3c154b
--- /dev/null
+++ b/lib/iso.h
@@ -0,0 +1,49 @@
+/*
+ * ISO Network definition - iso_net.h
+ *
+ * Author: Olivier Dugeon <olivier.dugeon@orange.com>
+ *
+ * Copyright (C) 2023 Orange http://www.orange.com
+ *
+ * This file is part of Free Range Routing (FRR).
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LIB_ISO_H_
+#define LIB_ISO_H_
+
+#include "compiler.h"
+
+/* len of "xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx" + '\0' */
+#define ISO_ADDR_STRLEN 51
+#define ISO_ADDR_MIN 8
+#define ISO_ADDR_SIZE 20
+struct iso_address {
+ uint8_t addr_len;
+ uint8_t area_addr[ISO_ADDR_SIZE];
+};
+
+/* len of "xxxx.xxxx.xxxx.xx-xx" + '\0' */
+#define ISO_SYSID_STRLEN 21
+
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+#pragma FRR printfrr_ext "%pSY" (uint8_t *)
+#pragma FRR printfrr_ext "%pPN" (uint8_t *)
+#pragma FRR printfrr_ext "%pLS" (uint8_t *)
+#pragma FRR printfrr_ext "%pIS" (struct iso_address *)
+#endif
+
+#endif /* LIB_ISO_H_ */
diff --git a/lib/link_state.c b/lib/link_state.c
index 0aba021b1a..7f20cdcf5e 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -26,6 +26,7 @@
#include "printfrr.h"
#include <lib/json.h>
#include "link_state.h"
+#include "iso.h"
/* Link State Memory allocation */
DEFINE_MTYPE_STATIC(LIB, LS_DB, "Link State Database");
@@ -1906,6 +1907,20 @@ void ls_delete_msg(struct ls_message *msg)
if (msg == NULL)
return;
+ if (msg->event == LS_MSG_EVENT_DELETE) {
+ switch (msg->type) {
+ case LS_MSG_TYPE_NODE:
+ ls_node_del(msg->data.node);
+ break;
+ case LS_MSG_TYPE_ATTRIBUTES:
+ ls_attributes_del(msg->data.attr);
+ break;
+ case LS_MSG_TYPE_PREFIX:
+ ls_prefix_del(msg->data.prefix);
+ break;
+ }
+ }
+
XFREE(MTYPE_LS_DB, msg);
}
@@ -1966,13 +1981,9 @@ static const char *const status2txt[] = {
static const char *ls_node_id_to_text(struct ls_node_id lnid, char *str,
size_t size)
{
- if (lnid.origin == ISIS_L1 || lnid.origin == ISIS_L2) {
- uint8_t *id;
-
- id = lnid.id.iso.sys_id;
- snprintfrr(str, size, "%02x%02x.%02x%02x.%02x%02x", id[0],
- id[1], id[2], id[3], id[4], id[5]);
- } else
+ if (lnid.origin == ISIS_L1 || lnid.origin == ISIS_L2)
+ snprintfrr(str, size, "%pSY", lnid.id.iso.sys_id);
+ else
snprintfrr(str, size, "%pI4", &lnid.id.ip.addr);
return str;
diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c
index 36c78052bc..7437eedfc7 100644
--- a/lib/mgmt_be_client.c
+++ b/lib/mgmt_be_client.c
@@ -16,17 +16,17 @@
#include "sockopt.h"
#ifdef REDIRECT_DEBUG_TO_STDERR
-#define MGMTD_BE_CLIENT_DBG(fmt, ...) \
+#define MGMTD_BE_CLIENT_DBG(fmt, ...) \
fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__)
-#define MGMTD_BE_CLIENT_ERR(fmt, ...) \
+#define MGMTD_BE_CLIENT_ERR(fmt, ...) \
fprintf(stderr, "%s: ERROR, " fmt "\n", __func__, ##__VA_ARGS__)
#else /* REDIRECT_DEBUG_TO_STDERR */
-#define MGMTD_BE_CLIENT_DBG(fmt, ...) \
+#define MGMTD_BE_CLIENT_DBG(fmt, ...) \
do { \
- if (mgmt_debug_be_client) \
- zlog_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
+ if (mgmt_debug_be_client) \
+ zlog_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
-#define MGMTD_BE_CLIENT_ERR(fmt, ...) \
+#define MGMTD_BE_CLIENT_ERR(fmt, ...) \
zlog_err("%s: ERROR: " fmt, __func__, ##__VA_ARGS__)
#endif /* REDIRECT_DEBUG_TO_STDERR */
@@ -597,7 +597,8 @@ static int mgmt_be_txn_cfg_prepare(struct mgmt_be_txn_ctx *txn)
MGMTD_BE_CLIENT_DBG(
"Avg-nb-edit-duration %lu uSec, nb-prep-duration %lu (avg: %lu) uSec, batch size %u",
client_ctx->avg_edit_nb_cfg_tm, prep_nb_cfg_tm,
- client_ctx->avg_prep_nb_cfg_tm, (uint32_t)num_processed);
+ client_ctx->avg_prep_nb_cfg_tm,
+ (uint32_t)num_processed);
if (error)
mgmt_be_txn_cfg_abort(txn);
diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c
index a2c4fd6572..7cb9aa3def 100644
--- a/lib/mgmt_fe_client.c
+++ b/lib/mgmt_fe_client.c
@@ -109,8 +109,8 @@ mgmt_fe_find_session_by_session_id(struct mgmt_fe_client_ctx *client_ctx,
FOREACH_SESSION_IN_LIST (client_ctx, session) {
if (session->session_id == session_id) {
MGMTD_FE_CLIENT_DBG(
- "Found session %p for session-id %llu.", session,
- (unsigned long long)session_id);
+ "Found session %p for session-id %llu.",
+ session, (unsigned long long)session_id);
return session;
}
}
@@ -274,7 +274,8 @@ mgmt_fe_send_lockds_req(struct mgmt_fe_client_ctx *client_ctx,
MGMTD_FE_CLIENT_DBG(
"Sending %sLOCK_REQ message for Ds:%d session %llu to MGMTD Frontend server",
- lock ? "" : "UN", ds_id, (unsigned long long)session->client_id);
+ lock ? "" : "UN", ds_id,
+ (unsigned long long)session->client_id);
return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
}
@@ -310,12 +311,12 @@ mgmt_fe_send_setcfg_req(struct mgmt_fe_client_ctx *client_ctx,
return mgmt_fe_client_send_msg(client_ctx, &fe_msg);
}
-static int
-mgmt_fe_send_commitcfg_req(struct mgmt_fe_client_ctx *client_ctx,
- struct mgmt_fe_client_session *session,
- uint64_t req_id, Mgmtd__DatastoreId src_ds_id,
- Mgmtd__DatastoreId dest_ds_id, bool validate_only,
- bool abort)
+static int mgmt_fe_send_commitcfg_req(struct mgmt_fe_client_ctx *client_ctx,
+ struct mgmt_fe_client_session *session,
+ uint64_t req_id,
+ Mgmtd__DatastoreId src_ds_id,
+ Mgmtd__DatastoreId dest_ds_id,
+ bool validate_only, bool abort)
{
(void)req_id;
Mgmtd__FeMessage fe_msg;
@@ -450,15 +451,17 @@ mgmt_fe_client_handle_msg(struct mgmt_fe_client_ctx *client_ctx,
if (session && fe_msg->session_reply->success) {
MGMTD_FE_CLIENT_DBG(
"Session Create for client-id %llu successful.",
- (unsigned long long)fe_msg
- ->session_reply->client_conn_id);
+ (unsigned long long)
+ fe_msg->session_reply
+ ->client_conn_id);
session->session_id =
fe_msg->session_reply->session_id;
} else {
MGMTD_FE_CLIENT_ERR(
"Session Create for client-id %llu failed.",
- (unsigned long long)fe_msg
- ->session_reply->client_conn_id);
+ (unsigned long long)
+ fe_msg->session_reply
+ ->client_conn_id);
}
} else if (!fe_msg->session_reply->create) {
MGMTD_FE_CLIENT_DBG(
diff --git a/lib/subdir.am b/lib/subdir.am
index 0f5bbef0b2..dcc58b31ae 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -47,6 +47,7 @@ lib_libfrr_la_SOURCES = \
lib/if_rmap.c \
lib/imsg-buffer.c \
lib/imsg.c \
+ lib/iso.c \
lib/jhash.c \
lib/json.c \
lib/keychain.c \
@@ -173,6 +174,7 @@ clippy_scan += \
lib/affinitymap_cli.c \
lib/if.c \
lib/filter_cli.c \
+ lib/if_rmap.c \
lib/log_vty.c \
lib/nexthop_group.c \
lib/northbound_cli.c \
@@ -224,6 +226,7 @@ pkginclude_HEADERS += \
lib/if_rmap.h \
lib/imsg.h \
lib/ipaddr.h \
+ lib/iso.h \
lib/jhash.h \
lib/json.h \
lib/keychain.h \
diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c
index af43cf3eae..cf7d705943 100644
--- a/mgmtd/mgmt_be_adapter.c
+++ b/mgmtd/mgmt_be_adapter.c
@@ -80,23 +80,23 @@ static const struct mgmt_be_xpath_map_reg xpath_static_map_reg[] = {
.be_clients =
(enum mgmt_be_client_id[]){
#if HAVE_STATICD
- MGMTD_BE_CLIENT_ID_STATICD,
+ MGMTD_BE_CLIENT_ID_STATICD,
#endif
MGMTD_BE_CLIENT_ID_MAX}},
{.xpath_regexp = "/frr-interface:lib/*",
.be_clients =
(enum mgmt_be_client_id[]){
#if HAVE_STATICD
- MGMTD_BE_CLIENT_ID_STATICD,
+ MGMTD_BE_CLIENT_ID_STATICD,
#endif
MGMTD_BE_CLIENT_ID_MAX}},
{.xpath_regexp =
- "/frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/*",
+ "/frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-staticd:staticd'][name='staticd'][vrf='default']/frr-staticd:staticd/*",
.be_clients =
(enum mgmt_be_client_id[]){
#if HAVE_STATICD
- MGMTD_BE_CLIENT_ID_STATICD,
+ MGMTD_BE_CLIENT_ID_STATICD,
#endif
MGMTD_BE_CLIENT_ID_MAX}},
};
@@ -347,8 +347,8 @@ mgmt_be_adapter_cleanup_old_conn(struct mgmt_be_client_adapter *adapter)
struct mgmt_be_client_adapter *old;
FOREACH_ADAPTER_IN_LIST (old) {
- if (old != adapter
- && !strncmp(adapter->name, old->name, sizeof(adapter->name))) {
+ if (old != adapter &&
+ !strncmp(adapter->name, old->name, sizeof(adapter->name))) {
/*
* We have a Zombie lingering around
*/
diff --git a/mgmtd/mgmt_be_server.c b/mgmtd/mgmt_be_server.c
index 0fa7ddd6d6..aa77464524 100644
--- a/mgmtd/mgmt_be_server.c
+++ b/mgmtd/mgmt_be_server.c
@@ -119,7 +119,7 @@ static void mgmt_be_server_start(const char *hostname)
return;
mgmt_be_server_start_failed:
- if (sock)
+ if (sock > 0)
close(sock);
mgmt_be_listen_fd = -1;
diff --git a/mgmtd/mgmt_ds.c b/mgmtd/mgmt_ds.c
index 10b3cecb92..58c49b8789 100644
--- a/mgmtd/mgmt_ds.c
+++ b/mgmtd/mgmt_ds.c
@@ -174,6 +174,7 @@ static int mgmt_ds_load_cfg_from_file(const char *filepath,
void mgmt_ds_reset_candidate(void)
{
struct lyd_node *dnode = mm->candidate_ds->root.cfg_root->dnode;
+
if (dnode)
yang_dnode_free(dnode);
@@ -499,12 +500,12 @@ int mgmt_ds_delete_data_nodes(struct mgmt_ds_ctx *ds_ctx, const char *xpath)
*/
return NB_ERR_NOT_FOUND;
/* destroy dependant */
- if (nb_node->dep_cbs.get_dependant_xpath) {
+ if (nb_node && nb_node->dep_cbs.get_dependant_xpath) {
nb_node->dep_cbs.get_dependant_xpath(dnode, dep_xpath);
dep_dnode = yang_dnode_get(
ds_ctx->config_ds ? ds_ctx->root.cfg_root->dnode
- : ds_ctx->root.dnode_root,
+ : ds_ctx->root.dnode_root,
dep_xpath);
if (dep_dnode)
lyd_free_tree(dep_dnode);
diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c
index 5826b17de7..90e6870fd4 100644
--- a/mgmtd/mgmt_fe_adapter.c
+++ b/mgmtd/mgmt_fe_adapter.c
@@ -495,7 +495,8 @@ static int mgmt_fe_send_setcfg_reply(struct mgmt_fe_session_ctx *session,
if (implicit_commit) {
if (mm->perf_stats_en)
- gettimeofday(&session->adapter->cmt_stats.last_end, NULL);
+ gettimeofday(&session->adapter->cmt_stats.last_end,
+ NULL);
mgmt_fe_session_compute_commit_timers(
&session->adapter->cmt_stats);
}
@@ -715,8 +716,8 @@ mgmt_fe_adapter_cleanup_old_conn(struct mgmt_fe_client_adapter *adapter)
struct mgmt_fe_client_adapter *old;
FOREACH_ADAPTER_IN_LIST (old) {
- if (old != adapter
- && !strncmp(adapter->name, old->name, sizeof(adapter->name))) {
+ if (old != adapter &&
+ !strncmp(adapter->name, old->name, sizeof(adapter->name))) {
/*
* We have a Zombie lingering around
*/
@@ -1109,8 +1110,8 @@ mgmt_fe_session_handle_getdata_req_msg(struct mgmt_fe_session_ctx *session,
MGMTD_TXN_TYPE_SHOW);
if (session->txn_id == MGMTD_SESSION_ID_NONE) {
mgmt_fe_send_getdata_reply(
- session, getdata_req->ds_id, getdata_req->req_id,
- false, NULL,
+ session, getdata_req->ds_id,
+ getdata_req->req_id, false, NULL,
"Failed to create a Show transaction!");
goto mgmt_fe_sess_handle_getdata_req_failed;
}
@@ -1780,8 +1781,8 @@ mgmt_fe_adapter_cmt_stats_write(struct vty *vty,
sizeof(buf)));
vty_out(vty, " Apply-Config Start: \t\t%s\n",
mgmt_realtime_to_string(
- &adapter->cmt_stats.apply_cfg_start, buf,
- sizeof(buf)));
+ &adapter->cmt_stats.apply_cfg_start,
+ buf, sizeof(buf)));
vty_out(vty, " Apply-Config End: \t\t%s\n",
mgmt_realtime_to_string(
&adapter->cmt_stats.apply_cfg_end, buf,
@@ -1818,8 +1819,9 @@ mgmt_fe_adapter_setcfg_stats_write(struct vty *vty,
adapter->setcfg_stats.avg_tm);
vty_out(vty, " Last-Set-Cfg-Details:\n");
vty_out(vty, " Set-Cfg Start: \t\t\t%s\n",
- mgmt_realtime_to_string(&adapter->setcfg_stats.last_start,
- buf, sizeof(buf)));
+ mgmt_realtime_to_string(
+ &adapter->setcfg_stats.last_start, buf,
+ sizeof(buf)));
vty_out(vty, " Set-Cfg End: \t\t\t%s\n",
mgmt_realtime_to_string(&adapter->setcfg_stats.last_end,
buf, sizeof(buf)));
@@ -1894,9 +1896,11 @@ void mgmt_fe_adapter_reset_perf_stats(struct vty *vty)
struct mgmt_fe_session_ctx *session;
FOREACH_ADAPTER_IN_LIST (adapter) {
- memset(&adapter->setcfg_stats, 0, sizeof(adapter->setcfg_stats));
+ memset(&adapter->setcfg_stats, 0,
+ sizeof(adapter->setcfg_stats));
FOREACH_SESSION_IN_LIST (adapter, session) {
- memset(&adapter->cmt_stats, 0, sizeof(adapter->cmt_stats));
+ memset(&adapter->cmt_stats, 0,
+ sizeof(adapter->cmt_stats));
}
}
}
diff --git a/mgmtd/mgmt_fe_server.c b/mgmtd/mgmt_fe_server.c
index 6097c23aac..e8bbe139bb 100644
--- a/mgmtd/mgmt_fe_server.c
+++ b/mgmtd/mgmt_fe_server.c
@@ -119,7 +119,7 @@ static void mgmt_fe_server_start(const char *hostname)
return;
mgmt_fe_server_start_failed:
- if (sock)
+ if (sock > 0)
close(sock);
mgmt_fe_listen_fd = -1;
diff --git a/mgmtd/mgmt_history.c b/mgmtd/mgmt_history.c
index 6f9f2dd63f..2251c49f1c 100644
--- a/mgmtd/mgmt_history.c
+++ b/mgmtd/mgmt_history.c
@@ -33,7 +33,7 @@ DECLARE_DLIST(mgmt_cmt_infos, struct mgmt_cmt_info_t, cmts);
* The only instance of VTY session that has triggered an ongoing
* config rollback operation.
*/
-static struct vty *rollback_vty = NULL;
+static struct vty *rollback_vty;
static bool mgmt_history_record_exists(char *file_path)
{
@@ -82,7 +82,7 @@ static struct mgmt_cmt_info_t *mgmt_history_create_cmt_rec(void)
mgmt_realtime_to_string(&cmt_recd_tv, new->time_str,
sizeof(new->time_str));
mgmt_history_hash(new->time_str, new->cmtid_str);
- snprintf(new->cmt_json_file, sizeof(new->cmt_json_file),
+ snprintf(new->cmt_json_file, sizeof(new->cmt_json_file) - 1,
MGMTD_COMMIT_FILE_PATH, new->cmtid_str);
if (mgmt_cmt_infos_count(&mm->cmts) == MGMTD_MAX_COMMIT_LIST) {
@@ -100,7 +100,8 @@ static struct mgmt_cmt_info_t *mgmt_history_create_cmt_rec(void)
return new;
}
-static struct mgmt_cmt_info_t *mgmt_history_find_cmt_record(const char *cmtid_str)
+static struct mgmt_cmt_info_t *
+mgmt_history_find_cmt_record(const char *cmtid_str)
{
struct mgmt_cmt_info_t *cmt_info;
@@ -129,7 +130,8 @@ static bool mgmt_history_read_cmt_record_index(void)
while ((fread(&cmt_info, sizeof(cmt_info), 1, fp)) > 0) {
if (cnt < MGMTD_MAX_COMMIT_LIST) {
- if (!mgmt_history_record_exists(cmt_info.cmt_json_file)) {
+ if (!mgmt_history_record_exists(
+ cmt_info.cmt_json_file)) {
zlog_err(
"Commit record present in index_file, but commit file %s missing",
cmt_info.cmt_json_file);
@@ -282,7 +284,8 @@ int mgmt_history_rollback_by_id(struct vty *vty, const char *cmtid_str)
FOREACH_CMT_REC (mm, cmt_info) {
if (strncmp(cmt_info->cmtid_str, cmtid_str,
MGMTD_MD5_HASH_STR_HEX_LEN) == 0) {
- ret = mgmt_history_rollback_to_cmt(vty, cmt_info, false);
+ ret = mgmt_history_rollback_to_cmt(vty, cmt_info,
+ false);
return ret;
}
@@ -321,7 +324,8 @@ int mgmt_history_rollback_n(struct vty *vty, int num_cmts)
FOREACH_CMT_REC (mm, cmt_info) {
if (cnt == num_cmts) {
- ret = mgmt_history_rollback_to_cmt(vty, cmt_info, false);
+ ret = mgmt_history_rollback_to_cmt(vty, cmt_info,
+ false);
return ret;
}
@@ -356,6 +360,7 @@ void show_mgmt_cmt_history(struct vty *vty)
void mgmt_history_new_record(struct mgmt_ds_ctx *ds_ctx)
{
struct mgmt_cmt_info_t *cmt_info = mgmt_history_create_cmt_rec();
+
mgmt_ds_dump_ds_to_file(cmt_info->cmt_json_file, ds_ctx);
mgmt_history_dump_cmt_record_index();
}
diff --git a/mgmtd/mgmt_history.h b/mgmtd/mgmt_history.h
index 29a1d7738e..5f96cf90e1 100644
--- a/mgmtd/mgmt_history.h
+++ b/mgmtd/mgmt_history.h
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (C) 2021 Vmware, Inc.
- * Pushpasis Sarkar <spushpasis@vmware.com>
- * Copyright (c) 2023, LabN Consulting, L.L.C.
- *
- */
+ * Copyright (C) 2021 Vmware, Inc.
+ * Pushpasis Sarkar <spushpasis@vmware.com>
+ * Copyright (c) 2023, LabN Consulting, L.L.C.
+ *
+ */
#ifndef _FRR_MGMTD_HISTORY_H_
#define _FRR_MGMTD_HISTORY_H_
diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c
index 5fa8aabfd6..2ba0cb413a 100644
--- a/mgmtd/mgmt_txn.c
+++ b/mgmtd/mgmt_txn.c
@@ -1258,6 +1258,7 @@ static int mgmt_txn_prepare_config(struct mgmt_txn_ctx *txn)
char err_buf[1024] = {0};
nb_ctx.client = NB_CLIENT_MGMTD_SERVER;
nb_ctx.user = (void *)txn;
+
ret = nb_candidate_validate_yang(nb_config, false, err_buf,
sizeof(err_buf) - 1);
if (ret != NB_OK) {
@@ -1787,27 +1788,10 @@ static int mgmt_txn_get_config(struct mgmt_txn_ctx *txn,
struct mgmt_txn_req *txn_req,
struct mgmt_ds_ctx *ds_ctx)
{
- struct mgmt_txn_reqs_head *req_list = NULL;
- struct mgmt_txn_reqs_head *pending_list = NULL;
int indx;
struct mgmt_get_data_req *get_data;
struct mgmt_get_data_reply *get_reply;
- switch (txn_req->req_event) {
- case MGMTD_TXN_PROC_GETCFG:
- req_list = &txn->get_cfg_reqs;
- break;
- case MGMTD_TXN_PROC_GETDATA:
- req_list = &txn->get_data_reqs;
- break;
- case MGMTD_TXN_PROC_SETCFG:
- case MGMTD_TXN_PROC_COMMITCFG:
- case MGMTD_TXN_COMMITCFG_TIMEOUT:
- case MGMTD_TXN_CLEANUP:
- assert(!"Wrong txn request type!");
- break;
- }
-
get_data = txn_req->req.get_data;
if (!get_data->reply) {
@@ -1852,24 +1836,11 @@ static int mgmt_txn_get_config(struct mgmt_txn_ctx *txn,
mgmt_txn_get_config_failed:
- if (pending_list) {
- /*
- * Move the transaction to corresponding pending list.
- */
- if (req_list)
- mgmt_txn_reqs_del(req_list, txn_req);
- txn_req->pending_be_proc = true;
- mgmt_txn_reqs_add_tail(pending_list, txn_req);
- MGMTD_TXN_DBG(
- "Moved Req: %p for Txn: %p from Req-List to Pending-List",
- txn_req, txn_req->txn);
- } else {
- /*
- * Delete the txn request. It will also remove it from request
- * list.
- */
- mgmt_txn_req_free(&txn_req);
- }
+ /*
+ * Delete the txn request. It will also remove it from request
+ * list.
+ */
+ mgmt_txn_req_free(&txn_req);
return 0;
}
diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c
index cb09544fdc..fa34d90c75 100644
--- a/mgmtd/mgmt_vty.c
+++ b/mgmtd/mgmt_vty.c
@@ -391,6 +391,7 @@ static struct cmd_node debug_node = {
static int config_write_mgmt_debug_helper(struct vty *vty, bool config)
{
int n = mgmt_debug_be + mgmt_debug_fe + mgmt_debug_ds + mgmt_debug_txn;
+
if (!n)
return 0;
@@ -442,6 +443,7 @@ DEFPY(debug_mgmt, debug_mgmt_cmd,
"Transaction debug\n")
{
bool set = !no;
+
if (all)
be = fe = ds = txn = set ? all : NULL;
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 649ba70e02..5742ece1f7 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -651,6 +651,8 @@ int ospf_if_new_hook(struct interface *ifp)
ifp->info = XCALLOC(MTYPE_OSPF_IF_INFO, sizeof(struct ospf_if_info));
+ IF_OSPF_IF_INFO(ifp)->oii_fd = -1;
+
IF_OIFS(ifp) = route_table_init();
IF_OIFS_PARAMS(ifp) = route_table_init();
@@ -691,6 +693,8 @@ static int ospf_if_delete_hook(struct interface *ifp)
{
int rc = 0;
struct route_node *rn;
+ struct ospf_if_info *oii;
+
rc = ospf_opaque_del_if(ifp);
/*
@@ -707,6 +711,13 @@ static int ospf_if_delete_hook(struct interface *ifp)
route_table_finish(IF_OIFS(ifp));
route_table_finish(IF_OIFS_PARAMS(ifp));
+ /* Close per-interface socket */
+ oii = ifp->info;
+ if (oii && oii->oii_fd > 0) {
+ close(oii->oii_fd);
+ oii->oii_fd = -1;
+ }
+
XFREE(MTYPE_OSPF_IF_INFO, ifp->info);
return rc;
@@ -1367,6 +1378,16 @@ static int ospf_ifp_up(struct interface *ifp)
struct ospf_interface *oi;
struct route_node *rn;
struct ospf_if_info *oii = ifp->info;
+ struct ospf *ospf;
+
+ if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+ zlog_debug("Zebra: Interface[%s] state change to up.",
+ ifp->name);
+
+ /* Open per-intf write socket if configured */
+ ospf = ifp->vrf->info;
+ if (ospf && ospf->intf_socket_enabled)
+ ospf_ifp_sock_init(ifp);
ospf_if_recalculate_output_cost(ifp);
@@ -1384,10 +1405,6 @@ static int ospf_ifp_up(struct interface *ifp)
return 0;
}
- if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug("Zebra: Interface[%s] state change to up.",
- ifp->name);
-
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
if ((oi = rn->info) == NULL)
continue;
@@ -1416,6 +1433,9 @@ static int ospf_ifp_down(struct interface *ifp)
ospf_if_down(oi);
}
+ /* Close per-interface write socket if configured */
+ ospf_ifp_sock_close(ifp);
+
return 0;
}
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index 8625a72ac1..649df437a4 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -121,6 +121,9 @@ struct ospf_if_info {
membership_counts[MEMBER_MAX]; /* multicast group refcnts */
uint32_t curr_mtu;
+
+ /* Per-interface write socket, configured via 'ospf' object */
+ int oii_fd;
};
struct ospf_interface;
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 87b683b15d..9e2dd7a457 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -2013,7 +2013,7 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
struct ospf_lsa *type7,
struct ospf_lsa *type5)
{
- struct ospf_lsa *new;
+ struct ospf_lsa *new, *translated_lsa;
struct as_external_lsa *extnew;
if (ospf->gr_info.restart_in_progress) {
@@ -2027,7 +2027,8 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
* the OSPF_LSA_LOCAL_XLT flag, must originate by hand
*/
- if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) {
+ if ((translated_lsa = ospf_lsa_translated_nssa_new(ospf, type7)) ==
+ NULL) {
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"%s: Could not translate Type-7, Id %pI4, to Type-5",
@@ -2035,16 +2036,17 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
return NULL;
}
- extnew = (struct as_external_lsa *)new->data;
+ extnew = (struct as_external_lsa *)translated_lsa->data;
/* Update LSA sequence number from translated Type-5 LSA */
if (type5)
- new->data->ls_seqnum = lsa_seqnum_increment(type5);
+ translated_lsa->data->ls_seqnum = lsa_seqnum_increment(type5);
- if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) {
+ if ((new = ospf_lsa_install(ospf, NULL, translated_lsa)) == NULL) {
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
"%s: Could not install LSA id %pI4", __func__,
&type7->data->id);
+ ospf_lsa_free(translated_lsa);
return NULL;
}
@@ -2067,7 +2069,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
struct ospf_lsa *type7,
struct ospf_lsa *type5)
{
- struct ospf_lsa *new = NULL;
+ struct ospf_lsa *new = NULL, *translated_lsa = NULL;
struct as_external_lsa *extold = NULL;
uint32_t ls_seqnum = 0;
@@ -2143,7 +2145,8 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
ospf_ls_retransmit_delete_nbr_as(ospf, type5);
/* create new translated LSA */
- if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) {
+ if ((translated_lsa = ospf_lsa_translated_nssa_new(ospf, type7)) ==
+ NULL) {
if (IS_DEBUG_OSPF_NSSA)
zlog_debug(
"%s: Could not translate Type-7 for %pI4 to Type-5",
@@ -2153,13 +2156,14 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
if (type7->area->suppress_fa == 1) {
if (extold->e[0].fwd_addr.s_addr == 0)
- new->data->ls_seqnum = htonl(ls_seqnum + 1);
+ translated_lsa->data->ls_seqnum = htonl(ls_seqnum + 1);
}
- if (!(new = ospf_lsa_install(ospf, NULL, new))) {
+ if (!(new = ospf_lsa_install(ospf, NULL, translated_lsa))) {
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
"%s: Could not install translated LSA, Id %pI4",
__func__, &type7->data->id);
+ ospf_lsa_free(translated_lsa);
return NULL;
}
diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c
index d3f30ce1ee..aff8ed05c7 100644
--- a/ospfd/ospf_network.c
+++ b/ospfd/ospf_network.c
@@ -15,6 +15,7 @@
#include "sockopt.h"
#include "privs.h"
#include "lib_errors.h"
+#include "lib/table.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_network.h"
@@ -111,7 +112,7 @@ int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p,
"can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllDRouters): %s",
top->fd, &p->u.prefix4, ifindex,
safe_strerror(errno));
- else
+ else if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"interface %pI4 [%u] leave AllDRouters Multicast group.",
&p->u.prefix4, ifindex);
@@ -119,62 +120,60 @@ int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p,
return ret;
}
-int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
+int ospf_if_ipmulticast(int fd, struct prefix *p, ifindex_t ifindex)
{
uint8_t val;
int ret, len;
/* Prevent receiving self-origined multicast packets. */
- ret = setsockopt_ipv4_multicast_loop(top->fd, 0);
+ ret = setsockopt_ipv4_multicast_loop(fd, 0);
if (ret < 0)
flog_err(EC_LIB_SOCKET,
"can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
- top->fd, safe_strerror(errno));
+ fd, safe_strerror(errno));
/* Explicitly set multicast ttl to 1 -- endo. */
val = 1;
len = sizeof(val);
- ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val,
- len);
+ ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len);
if (ret < 0)
flog_err(EC_LIB_SOCKET,
"can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
- top->fd, safe_strerror(errno));
+ fd, safe_strerror(errno));
#ifndef GNU_LINUX
/* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
* packet out of ifindex. Below would be used Non Linux system.
*/
- ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
+ ret = setsockopt_ipv4_multicast_if(fd, p->u.prefix4, ifindex);
if (ret < 0)
flog_err(EC_LIB_SOCKET,
"can't setsockopt IP_MULTICAST_IF(fd %d, addr %pI4, ifindex %u): %s",
- top->fd, &p->u.prefix4, ifindex,
+ fd, &p->u.prefix4, ifindex,
safe_strerror(errno));
#endif
return ret;
}
-int ospf_sock_init(struct ospf *ospf)
+/*
+ * Helper to open and set up a socket; returns the new fd on success,
+ * -1 on error.
+ */
+static int sock_init_common(vrf_id_t vrf_id, const char *name, int *pfd)
{
int ospf_sock;
int ret, hincl = 1;
- int bufsize = (8 * 1024 * 1024);
-
- /* silently ignore. already done */
- if (ospf->fd > 0)
- return -1;
- if (ospf->vrf_id == VRF_UNKNOWN) {
+ if (vrf_id == VRF_UNKNOWN) {
/* silently return since VRF is not ready */
return -1;
}
+
frr_with_privs(&ospfd_privs) {
ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP,
- ospf->vrf_id, ospf->name);
+ vrf_id, name);
if (ospf_sock < 0) {
- flog_err(EC_LIB_SOCKET,
- "ospf_read_sock_init: socket: %s",
+ flog_err(EC_LIB_SOCKET, "%s: socket: %s", __func__,
safe_strerror(errno));
return -1;
}
@@ -213,9 +212,102 @@ int ospf_sock_init(struct ospf *ospf)
ospf_sock);
}
- setsockopt_so_sendbuf(ospf_sock, bufsize);
- setsockopt_so_recvbuf(ospf_sock, bufsize);
+ *pfd = ospf_sock;
- ospf->fd = ospf_sock;
return ret;
}
+
+/*
+ * Update a socket bufsize(s), based on its ospf instance
+ */
+void ospf_sock_bufsize_update(const struct ospf *ospf, int sock,
+ enum ospf_sock_type_e type)
+{
+ int bufsize;
+
+ if (type == OSPF_SOCK_BOTH || type == OSPF_SOCK_RECV) {
+ bufsize = ospf->recv_sock_bufsize;
+ setsockopt_so_recvbuf(sock, bufsize);
+ }
+
+ if (type == OSPF_SOCK_BOTH || type == OSPF_SOCK_SEND) {
+ bufsize = ospf->send_sock_bufsize;
+ setsockopt_so_sendbuf(sock, bufsize);
+ }
+}
+
+int ospf_sock_init(struct ospf *ospf)
+{
+ int ret;
+
+ /* silently ignore. already done */
+ if (ospf->fd > 0)
+ return -1;
+
+ ret = sock_init_common(ospf->vrf_id, ospf->name, &(ospf->fd));
+
+ if (ret >= 0) /* Update socket buffer sizes */
+ ospf_sock_bufsize_update(ospf, ospf->fd, OSPF_SOCK_BOTH);
+
+ return ret;
+}
+
+/*
+ * Open per-interface write socket
+ */
+int ospf_ifp_sock_init(struct interface *ifp)
+{
+ struct ospf_if_info *oii;
+ struct ospf_interface *oi;
+ struct ospf *ospf;
+ struct route_node *rn;
+ int ret;
+
+ oii = IF_OSPF_IF_INFO(ifp);
+ if (oii == NULL)
+ return -1;
+
+ if (oii->oii_fd > 0)
+ return 0;
+
+ rn = route_top(IF_OIFS(ifp));
+ if (rn && rn->info) {
+ oi = rn->info;
+ ospf = oi->ospf;
+ } else
+ return -1;
+
+ ret = sock_init_common(ifp->vrf->vrf_id, ifp->name, &oii->oii_fd);
+
+ if (ret >= 0) /* Update socket buffer sizes */
+ ospf_sock_bufsize_update(ospf, oii->oii_fd, OSPF_SOCK_BOTH);
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ifp %s, oii %p, fd %d", __func__, ifp->name,
+ oii, oii->oii_fd);
+
+ return ret;
+}
+
+/*
+ * Close per-interface write socket
+ */
+int ospf_ifp_sock_close(struct interface *ifp)
+{
+ struct ospf_if_info *oii;
+
+ oii = IF_OSPF_IF_INFO(ifp);
+ if (oii == NULL)
+ return 0;
+
+ if (oii->oii_fd > 0) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ifp %s, oii %p, fd %d", __func__,
+ ifp->name, oii, oii->oii_fd);
+
+ close(oii->oii_fd);
+ oii->oii_fd = -1;
+ }
+
+ return 0;
+}
diff --git a/ospfd/ospf_network.h b/ospfd/ospf_network.h
index 33fd8980bf..b810bad50b 100644
--- a/ospfd/ospf_network.h
+++ b/ospfd/ospf_network.h
@@ -13,7 +13,20 @@ extern int ospf_if_drop_allspfrouters(struct ospf *, struct prefix *,
ifindex_t);
extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
-extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
+extern int ospf_if_ipmulticast(int fd, struct prefix *, ifindex_t);
extern int ospf_sock_init(struct ospf *ospf);
+/* Open, close per-interface write socket */
+int ospf_ifp_sock_init(struct interface *ifp);
+int ospf_ifp_sock_close(struct interface *ifp);
+
+enum ospf_sock_type_e {
+ OSPF_SOCK_NONE = 0,
+ OSPF_SOCK_RECV,
+ OSPF_SOCK_SEND,
+ OSPF_SOCK_BOTH
+};
+
+void ospf_sock_bufsize_update(const struct ospf *ospf, int sock,
+ enum ospf_sock_type_e type);
#endif /* _ZEBRA_OSPF_NETWORK_H */
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 5f7d49e0bb..552acfd6d3 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -618,7 +618,7 @@ static void ospf_write(struct event *thread)
struct msghdr msg;
struct iovec iov[2];
uint8_t type;
- int ret;
+ int ret, fd;
int flags = 0;
struct listnode *node;
#ifdef WANT_OSPF_WRITE_FRAGMENT
@@ -633,11 +633,12 @@ static void ospf_write(struct event *thread)
struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
struct in_pktinfo *pi;
#endif
+ fd = ospf->fd;
- if (ospf->fd < 0 || ospf->oi_running == 0) {
+ if (fd < 0 || ospf->oi_running == 0) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s failed to send, fd %d, instance %u",
- __func__, ospf->fd, ospf->oi_running);
+ __func__, fd, ospf->oi_running);
return;
}
@@ -657,6 +658,15 @@ static void ospf_write(struct event *thread)
/* convenience - max OSPF data per packet */
maxdatasize = oi->ifp->mtu - sizeof(struct ip);
#endif /* WANT_OSPF_WRITE_FRAGMENT */
+
+ /* Reset socket fd to use. */
+ fd = ospf->fd;
+
+ /* Check for per-interface socket */
+ if (ospf->intf_socket_enabled &&
+ (IF_OSPF_IF_INFO(oi->ifp))->oii_fd > 0)
+ fd = (IF_OSPF_IF_INFO(oi->ifp))->oii_fd;
+
/* Get one packet from queue. */
op = ospf_fifo_head(oi->obuf);
assert(op);
@@ -664,8 +674,7 @@ static void ospf_write(struct event *thread)
if (op->dst.s_addr == htonl(OSPF_ALLSPFROUTERS)
|| op->dst.s_addr == htonl(OSPF_ALLDROUTERS))
- ospf_if_ipmulticast(ospf, oi->address,
- oi->ifp->ifindex);
+ ospf_if_ipmulticast(fd, oi->address, oi->ifp->ifindex);
/* Rewrite the md5 signature & update the seq */
ospf_make_md5_digest(oi, op);
@@ -760,13 +769,13 @@ static void ospf_write(struct event *thread)
#ifdef WANT_OSPF_WRITE_FRAGMENT
if (op->length > maxdatasize)
- ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize,
+ ospf_write_frags(fd, op, &iph, &msg, maxdatasize,
oi->ifp->mtu, flags, type);
#endif /* WANT_OSPF_WRITE_FRAGMENT */
/* send final fragment (could be first) */
sockopt_iphdrincl_swab_htosys(&iph);
- ret = sendmsg(ospf->fd, &msg, flags);
+ ret = sendmsg(fd, &msg, flags);
sockopt_iphdrincl_swab_systoh(&iph);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 9398021e97..edec27fc09 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -35,12 +35,11 @@
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_zebra.h"
-/*#include "ospfd/ospf_routemap.h" */
#include "ospfd/ospf_vty.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_bfd.h"
#include "ospfd/ospf_ldp_sync.h"
-
+#include "ospfd/ospf_network.h"
FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES,
{ .val_bool = true, .match_profile = "datacenter", },
@@ -3403,6 +3402,23 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
/* show LDP-Sync status */
ospf_ldp_sync_show_info(vty, ospf, json_vrf, json ? 1 : 0);
+ /* Socket buffer sizes */
+ if (json) {
+ if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
+ json_object_int_add(json_vrf, "recvSockBufsize",
+ ospf->recv_sock_bufsize);
+ if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
+ json_object_int_add(json_vrf, "sendSockBufsize",
+ ospf->send_sock_bufsize);
+ } else {
+ if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
+ vty_out(vty, " Receive socket bufsize: %u\n",
+ ospf->recv_sock_bufsize);
+ if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
+ vty_out(vty, " Send socket bufsize: %u\n",
+ ospf->send_sock_bufsize);
+ }
+
/* Show each area status. */
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
show_ip_ospf_area(vty, area, json_areas, json ? 1 : 0);
@@ -12503,6 +12519,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
if (ospf->fr_configured)
vty_out(vty, " flood-reduction\n");
+ if (!ospf->intf_socket_enabled)
+ vty_out(vty, " no socket-per-interface\n");
+
/* Redistribute information print. */
config_write_ospf_redistribute(vty, ospf);
@@ -12559,6 +12578,22 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
/* LDP-Sync print */
ospf_ldp_sync_write_config(vty, ospf);
+ /* Socket buffer sizes */
+ if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE) {
+ if (ospf->send_sock_bufsize == ospf->recv_sock_bufsize)
+ vty_out(vty, " socket buffer all %u\n",
+ ospf->recv_sock_bufsize);
+ else
+ vty_out(vty, " socket buffer recv %u\n",
+ ospf->recv_sock_bufsize);
+ }
+
+ if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE &&
+ ospf->send_sock_bufsize != ospf->recv_sock_bufsize)
+ vty_out(vty, " socket buffer send %u\n",
+ ospf->send_sock_bufsize);
+
+
vty_out(vty, "exit\n");
write++;
@@ -13015,6 +13050,71 @@ DEFPY(no_flood_reduction_area, no_flood_reduction_area_cmd,
return CMD_SUCCESS;
}
+DEFPY(ospf_socket_bufsizes,
+ ospf_socket_bufsizes_cmd,
+ "[no] socket buffer <send$send_val | recv$recv_val | all$all_val> \
+ ![(1-4000000000)$bufsize]",
+ NO_STR
+ "Socket parameters\n"
+ "Buffer size configuration\n"
+ "Send buffer size\n"
+ "Receive buffer size\n"
+ "Both send and receive buffer sizes\n"
+ "Buffer size, in bytes\n")
+{
+ VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+ uint32_t recvsz, sendsz;
+
+ if (no)
+ bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
+
+ if (all_val) {
+ recvsz = bufsize;
+ sendsz = bufsize;
+ } else if (send_val) {
+ sendsz = bufsize;
+ recvsz = ospf->recv_sock_bufsize;
+ } else if (recv_val) {
+ recvsz = bufsize;
+ sendsz = ospf->send_sock_bufsize;
+ } else
+ return CMD_SUCCESS;
+
+ /* React to a change by modifying existing sockets */
+ ospf_update_bufsize(ospf, recvsz, sendsz);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (per_intf_socket,
+ per_intf_socket_cmd,
+ "[no] socket-per-interface",
+ NO_STR
+ "Use write socket per interface\n")
+{
+ VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+ struct listnode *node;
+ struct ospf_interface *oi;
+
+ if (no) {
+ if (ospf->intf_socket_enabled) {
+ ospf->intf_socket_enabled = false;
+
+ /* Iterate and close any sockets */
+ for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
+ ospf_ifp_sock_close(oi->ifp);
+ }
+ } else if (!ospf->intf_socket_enabled) {
+ ospf->intf_socket_enabled = true;
+
+ /* Iterate and open sockets */
+ for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
+ ospf_ifp_sock_init(oi->ifp);
+ }
+
+ return CMD_SUCCESS;
+}
+
void ospf_vty_clear_init(void)
{
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
@@ -13178,6 +13278,9 @@ void ospf_vty_init(void)
install_element(OSPF_NODE, &flood_reduction_area_cmd);
install_element(OSPF_NODE, &no_flood_reduction_area_cmd);
+ install_element(OSPF_NODE, &ospf_socket_bufsizes_cmd);
+ install_element(OSPF_NODE, &per_intf_socket_cmd);
+
/* Init interface related vty commands. */
ospf_vty_if_init();
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 4737643bc4..7e83714c0a 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -419,6 +419,10 @@ struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
QOBJ_REG(new, ospf);
new->fd = -1;
+ new->intf_socket_enabled = true;
+
+ new->recv_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
+ new->send_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
return new;
}
@@ -2180,6 +2184,32 @@ int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr)
return 1;
}
+/*
+ * Update socket bufsize(s), usually after config change
+ */
+void ospf_update_bufsize(struct ospf *ospf, uint32_t recvsize,
+ uint32_t sendsize)
+{
+ enum ospf_sock_type_e type = OSPF_SOCK_NONE;
+
+ /* Figure out whether there's been a change */
+ if (recvsize != ospf->recv_sock_bufsize) {
+ type = OSPF_SOCK_RECV;
+ ospf->recv_sock_bufsize = recvsize;
+
+ if (sendsize != ospf->send_sock_bufsize) {
+ type = OSPF_SOCK_BOTH;
+ ospf->send_sock_bufsize = sendsize;
+ }
+ } else if (sendsize != ospf->send_sock_bufsize) {
+ type = OSPF_SOCK_SEND;
+ ospf->send_sock_bufsize = sendsize;
+ }
+
+ if (type != OSPF_SOCK_NONE)
+ ospf_sock_bufsize_update(ospf, ospf->fd, type);
+}
+
void ospf_master_init(struct event_loop *master)
{
memset(&ospf_master, 0, sizeof(ospf_master));
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index af60e6cad0..1f8d1a32e6 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -67,6 +67,9 @@
#define OSPF_LS_REFRESH_SHIFT (60 * 15)
#define OSPF_LS_REFRESH_JITTER 60
+/* Default socket buffer size */
+#define OSPF_DEFAULT_SOCK_BUFSIZE (8 * 1024 * 1024)
+
struct ospf_external {
unsigned short instance;
struct route_table *external_info;
@@ -424,6 +427,13 @@ struct ospf {
/* Flood Reduction configuration state */
bool fr_configured;
+ /* Socket buffer sizes */
+ uint32_t recv_sock_bufsize;
+ uint32_t send_sock_bufsize;
+
+ /* Per-interface write socket */
+ bool intf_socket_enabled;
+
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(ospf);
@@ -793,6 +803,9 @@ int ospf_area_nssa_no_summary_set(struct ospf *ospf, struct in_addr area_id);
const char *ospf_get_name(const struct ospf *ospf);
extern struct ospf_interface *add_ospf_interface(struct connected *co,
struct ospf_area *area);
+/* Update socket bufsize(s), after config change */
+void ospf_update_bufsize(struct ospf *ospf, uint32_t recvsize,
+ uint32_t sendsize);
extern int p_spaces_compare_func(const struct p_space *a,
const struct p_space *b);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 8c75b0a5b5..2e90cf9053 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -67,7 +67,7 @@ static struct cmd_node debug_node = {
};
static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
- const int argc, int *idx)
+ const int argc, int *idx, bool uj)
{
struct vrf *vrf;
@@ -76,9 +76,13 @@ static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
else
vrf = vrf_lookup_by_id(VRF_DEFAULT);
- if (!vrf)
- vty_out(vty, "Specified VRF: %s does not exist\n",
- argv[*idx]->arg);
+ if (!vrf) {
+ if (uj)
+ vty_json_empty(vty);
+ else
+ vty_out(vty, "Specified VRF: %s does not exist\n",
+ argv[*idx]->arg);
+ }
return vrf;
}
@@ -822,19 +826,172 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
}
}
-static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
+static void igmp_source_json_helper(struct gm_source *src,
+ json_object *json_sources, char *source_str,
+ char *mmss, char *uptime)
+{
+ json_object *json_source = NULL;
+
+ json_source = json_object_new_object();
+ if (!json_source)
+ return;
+
+ json_object_string_add(json_source, "source", source_str);
+ json_object_string_add(json_source, "timer", mmss);
+ json_object_boolean_add(json_source, "forwarded",
+ IGMP_SOURCE_TEST_FORWARDING(src->source_flags));
+ json_object_string_add(json_source, "uptime", uptime);
+ json_object_array_add(json_sources, json_source);
+}
+
+static void igmp_group_print(struct interface *ifp, struct vty *vty, bool uj,
+ json_object *json, struct gm_group *grp,
+ time_t now, bool detail)
{
- struct interface *ifp;
- time_t now;
- json_object *json = NULL;
json_object *json_iface = NULL;
json_object *json_group = NULL;
json_object *json_groups = NULL;
+ char group_str[INET_ADDRSTRLEN];
+ char hhmmss[PIM_TIME_STRLEN];
+ char uptime[PIM_TIME_STRLEN];
+
+ pim_inet4_dump("<group?>", grp->group_addr, group_str,
+ sizeof(group_str));
+ pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
+ pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
+
+ if (uj) {
+ json_object_object_get_ex(json, ifp->name, &json_iface);
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ if (!json_iface)
+ return;
+ json_object_pim_ifp_add(json_iface, ifp);
+ json_object_object_add(json, ifp->name, json_iface);
+ json_groups = json_object_new_array();
+ if (!json_groups)
+ return;
+ json_object_object_add(json_iface, "groups",
+ json_groups);
+ }
+
+ json_object_object_get_ex(json_iface, "groups", &json_groups);
+ if (json_groups) {
+ json_group = json_object_new_object();
+ if (!json_group)
+ return;
+
+ json_object_string_add(json_group, "group", group_str);
+ if (grp->igmp_version == IGMP_DEFAULT_VERSION)
+ json_object_string_add(
+ json_group, "mode",
+ grp->group_filtermode_isexcl
+ ? "EXCLUDE"
+ : "INCLUDE");
+
+ json_object_string_add(json_group, "timer", hhmmss);
+ json_object_int_add(
+ json_group, "sourcesCount",
+ grp->group_source_list
+ ? listcount(grp->group_source_list)
+ : 0);
+ json_object_int_add(json_group, "version",
+ grp->igmp_version);
+ json_object_string_add(json_group, "uptime", uptime);
+ json_object_array_add(json_groups, json_group);
+
+ if (detail) {
+ struct listnode *srcnode;
+ struct gm_source *src;
+ json_object *json_sources = NULL;
+
+ json_sources = json_object_new_array();
+ if (!json_sources)
+ return;
+
+ json_object_object_add(json_group, "sources",
+ json_sources);
+
+ for (ALL_LIST_ELEMENTS_RO(
+ grp->group_source_list, srcnode,
+ src)) {
+ char source_str[INET_ADDRSTRLEN];
+ char mmss[PIM_TIME_STRLEN];
+ char src_uptime[PIM_TIME_STRLEN];
+
+ pim_inet4_dump(
+ "<source?>", src->source_addr,
+ source_str, sizeof(source_str));
+ pim_time_timer_to_mmss(
+ mmss, sizeof(mmss),
+ src->t_source_timer);
+ pim_time_uptime(
+ src_uptime, sizeof(src_uptime),
+ now - src->source_creation);
+
+ igmp_source_json_helper(
+ src, json_sources, source_str,
+ mmss, src_uptime);
+ }
+ }
+ }
+ } else {
+ if (detail) {
+ struct listnode *srcnode;
+ struct gm_source *src;
+
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ srcnode, src)) {
+ char source_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<source?>", src->source_addr,
+ source_str, sizeof(source_str));
+
+ vty_out(vty,
+ "%-16s %-15s %4s %8s %-15s %d %8s\n",
+ ifp->name, group_str,
+ grp->igmp_version == 3
+ ? (grp->group_filtermode_isexcl
+ ? "EXCL"
+ : "INCL")
+ : "----",
+ hhmmss, source_str, grp->igmp_version,
+ uptime);
+ }
+ return;
+ }
+
+ vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n", ifp->name,
+ group_str,
+ grp->igmp_version == 3
+ ? (grp->group_filtermode_isexcl ? "EXCL"
+ : "INCL")
+ : "----",
+ hhmmss,
+ grp->group_source_list
+ ? listcount(grp->group_source_list)
+ : 0,
+ grp->igmp_version, uptime);
+ }
+}
+
+static void igmp_show_groups_interface_single(struct pim_instance *pim,
+ struct vty *vty, bool uj,
+ const char *ifname,
+ const char *grp_str, bool detail)
+{
+ struct interface *ifp;
+ time_t now;
+ json_object *json = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ struct gm_group *grp;
now = pim_time_monotonic_sec();
if (uj) {
json = json_object_new_object();
+ if (!json)
+ return;
json_object_int_add(json, "totalGroups", pim->gm_group_count);
json_object_int_add(json, "watermarkLimit",
pim->gm_watermark_limit);
@@ -843,8 +1000,87 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
vty_out(vty, "Watermark warn limit(%s): %u\n",
pim->gm_watermark_limit ? "Set" : "Not Set",
pim->gm_watermark_limit);
- vty_out(vty,
- "Interface Group Mode Timer Srcs V Uptime \n");
+
+ if (!detail)
+ vty_out(vty,
+ "Interface Group Mode Timer Srcs V Uptime\n");
+ else
+ vty_out(vty,
+ "Interface Group Mode Timer Source V Uptime\n");
+ }
+
+ ifp = if_lookup_by_name(ifname, pim->vrf->vrf_id);
+ if (!ifp) {
+ if (uj)
+ vty_json(vty, json);
+ return;
+ }
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ if (uj)
+ vty_json(vty, json);
+ return;
+ }
+
+ if (grp_str) {
+ struct in_addr group_addr;
+ struct gm_sock *igmp;
+
+ if (inet_pton(AF_INET, grp_str, &group_addr) == 1) {
+ igmp = pim_igmp_sock_lookup_ifaddr(
+ pim_ifp->gm_socket_list,
+ pim_ifp->primary_address);
+ if (igmp) {
+ grp = find_group_by_addr(igmp, group_addr);
+ if (grp)
+ igmp_group_print(ifp, vty, uj, json,
+ grp, now, detail);
+ }
+ }
+ } else {
+ struct listnode *grpnode;
+
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode, grp))
+ igmp_group_print(ifp, vty, uj, json, grp, now, detail);
+ }
+
+ if (uj) {
+ if (detail)
+ vty_json_no_pretty(vty, json);
+ else
+ vty_json(vty, json);
+ }
+}
+
+static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj,
+ const char *grp_str, bool detail)
+{
+ struct interface *ifp;
+ time_t now;
+ json_object *json = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj) {
+ json = json_object_new_object();
+ if (!json)
+ return;
+ json_object_int_add(json, "totalGroups", pim->gm_group_count);
+ json_object_int_add(json, "watermarkLimit",
+ pim->gm_watermark_limit);
+ } else {
+ vty_out(vty, "Total IGMP groups: %u\n", pim->gm_group_count);
+ vty_out(vty, "Watermark warn limit(%s): %u\n",
+ pim->gm_watermark_limit ? "Set" : "Not Set",
+ pim->gm_watermark_limit);
+ if (!detail)
+ vty_out(vty,
+ "Interface Group Mode Timer Srcs V Uptime\n");
+ else
+ vty_out(vty,
+ "Interface Group Mode Timer Source V Uptime\n");
}
/* scan interfaces */
@@ -856,78 +1092,38 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
if (!pim_ifp)
continue;
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
- grp)) {
- char group_str[INET_ADDRSTRLEN];
- char hhmmss[10];
- char uptime[10];
-
- pim_inet4_dump("<group?>", grp->group_addr, group_str,
- sizeof(group_str));
- pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
- grp->t_group_timer);
- pim_time_uptime(uptime, sizeof(uptime),
- now - grp->group_creation);
-
- if (uj) {
- json_object_object_get_ex(json, ifp->name,
- &json_iface);
-
- if (!json_iface) {
- json_iface = json_object_new_object();
- json_object_pim_ifp_add(json_iface,
- ifp);
- json_object_object_add(json, ifp->name,
- json_iface);
- json_groups = json_object_new_array();
- json_object_object_add(json_iface,
- "groups",
- json_groups);
+ if (grp_str) {
+ struct in_addr group_addr;
+ struct gm_sock *igmp;
+
+ if (inet_pton(AF_INET, grp_str, &group_addr) == 1) {
+ igmp = pim_igmp_sock_lookup_ifaddr(
+ pim_ifp->gm_socket_list,
+ pim_ifp->primary_address);
+ if (igmp) {
+ grp = find_group_by_addr(igmp,
+ group_addr);
+ if (grp)
+ igmp_group_print(ifp, vty, uj,
+ json, grp, now,
+ detail);
}
-
- json_group = json_object_new_object();
- json_object_string_add(json_group, "group",
- group_str);
-
- if (grp->igmp_version == 3)
- json_object_string_add(
- json_group, "mode",
- grp->group_filtermode_isexcl
- ? "EXCLUDE"
- : "INCLUDE");
-
- json_object_string_add(json_group, "timer",
- hhmmss);
- json_object_int_add(
- json_group, "sourcesCount",
- grp->group_source_list ? listcount(
- grp->group_source_list)
- : 0);
- json_object_int_add(json_group, "version",
- grp->igmp_version);
- json_object_string_add(json_group, "uptime",
- uptime);
- json_object_array_add(json_groups, json_group);
- } else {
- vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n",
- ifp->name, group_str,
- grp->igmp_version == 3
- ? (grp->group_filtermode_isexcl
- ? "EXCL"
- : "INCL")
- : "----",
- hhmmss,
- grp->group_source_list ? listcount(
- grp->group_source_list)
- : 0,
- grp->igmp_version, uptime);
}
- } /* scan igmp groups */
- } /* scan interfaces */
+ } else {
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list,
+ grpnode, grp))
+ igmp_group_print(ifp, vty, uj, json, grp, now,
+ detail);
+ }
+ } /* scan interfaces */
- if (uj)
- vty_json(vty, json);
+ if (uj) {
+ if (detail)
+ vty_json_no_pretty(vty, json);
+ else
+ vty_json(vty, json);
+ }
}
static void igmp_show_group_retransmission(struct pim_instance *pim,
@@ -981,24 +1177,175 @@ static void igmp_show_group_retransmission(struct pim_instance *pim,
} /* scan interfaces */
}
+static void igmp_sources_print(struct interface *ifp, char *group_str,
+ struct gm_source *src, time_t now,
+ json_object *json, struct vty *vty, bool uj)
+{
+ json_object *json_iface = NULL;
+ json_object *json_group = NULL;
+ json_object *json_sources = NULL;
+ char source_str[INET_ADDRSTRLEN];
+ char mmss[PIM_TIME_STRLEN];
+ char uptime[PIM_TIME_STRLEN];
+
+ pim_inet4_dump("<source?>", src->source_addr, source_str,
+ sizeof(source_str));
+ pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
+ pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
+
+ if (uj) {
+ json_object_object_get_ex(json, ifp->name, &json_iface);
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ if (!json_iface)
+ return;
+ json_object_string_add(json_iface, "name", ifp->name);
+ json_object_object_add(json, ifp->name, json_iface);
+ }
+
+ json_object_object_get_ex(json_iface, group_str, &json_group);
+ if (!json_group) {
+ json_group = json_object_new_object();
+ if (!json_group)
+ return;
+ json_object_string_add(json_group, "group", group_str);
+ json_object_object_add(json_iface, group_str,
+ json_group);
+ json_sources = json_object_new_array();
+ if (!json_sources)
+ return;
+ json_object_object_add(json_group, "sources",
+ json_sources);
+ }
+
+ json_object_object_get_ex(json_group, "sources", &json_sources);
+ if (json_sources)
+ igmp_source_json_helper(src, json_sources, source_str,
+ mmss, uptime);
+ } else {
+ vty_out(vty, "%-16s %-15s %-15s %5s %3s %8s\n", ifp->name,
+ group_str, source_str, mmss,
+ IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y"
+ : "N",
+ uptime);
+ }
+}
+
+static void igmp_show_sources_interface_single(struct pim_instance *pim,
+ struct vty *vty, bool uj,
+ const char *ifname,
+ const char *grp_str)
+{
+ struct interface *ifp;
+ time_t now;
+ json_object *json = NULL;
+ struct pim_interface *pim_ifp;
+ struct gm_group *grp;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj) {
+ json = json_object_new_object();
+ if (!json)
+ return;
+ } else {
+ vty_out(vty,
+ "Interface Group Source Timer Fwd Uptime \n");
+ }
+
+ ifp = if_lookup_by_name(ifname, pim->vrf->vrf_id);
+ if (!ifp) {
+ if (uj)
+ vty_json(vty, json);
+ return;
+ }
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ if (uj)
+ vty_json(vty, json);
+ return;
+ }
+
+ if (grp_str) {
+ struct in_addr group_addr;
+ struct gm_sock *igmp;
+ struct listnode *srcnode;
+ struct gm_source *src;
+ char group_str[INET_ADDRSTRLEN];
+ int res;
+
+ res = inet_pton(AF_INET, grp_str, &group_addr);
+ if (res <= 0) {
+ if (uj)
+ vty_json(vty, json);
+ return;
+ }
+
+ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->gm_socket_list,
+ pim_ifp->primary_address);
+ if (!igmp) {
+ if (uj)
+ vty_json(vty, json);
+ return;
+ }
+
+ grp = find_group_by_addr(igmp, group_addr);
+ if (!grp) {
+ if (uj)
+ vty_json(vty, json);
+ return;
+ }
+ pim_inet4_dump("<group?>", grp->group_addr, group_str,
+ sizeof(group_str));
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src))
+ igmp_sources_print(ifp, group_str, src, now, json, vty,
+ uj);
+ } else {
+ struct listnode *grpnode;
+
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
+ grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ struct listnode *srcnode;
+ struct gm_source *src;
+
+ pim_inet4_dump("<group?>", grp->group_addr, group_str,
+ sizeof(group_str));
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ srcnode, src))
+ igmp_sources_print(ifp, group_str, src, now,
+ json, vty, uj);
+
+ } /* scan igmp groups */
+ }
+
+ if (uj)
+ vty_json(vty, json);
+}
+
static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
bool uj)
{
struct interface *ifp;
time_t now;
json_object *json = NULL;
- json_object *json_iface = NULL;
- json_object *json_group = NULL;
- json_object *json_source = NULL;
- json_object *json_sources = NULL;
now = pim_time_monotonic_sec();
- if (uj)
+ if (uj) {
json = json_object_new_object();
- else
+ if (!json)
+ return;
+ } else {
vty_out(vty,
- "Interface Group Source Timer Fwd Uptime \n");
+ "Interface Group Source Timer Fwd Uptime\n");
+ }
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -1021,82 +1368,12 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
/* scan group sources */
for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
- srcnode, src)) {
- char source_str[INET_ADDRSTRLEN];
- char mmss[10];
- char uptime[10];
-
- pim_inet4_dump("<source?>", src->source_addr,
- source_str, sizeof(source_str));
-
- pim_time_timer_to_mmss(mmss, sizeof(mmss),
- src->t_source_timer);
-
- pim_time_uptime(uptime, sizeof(uptime),
- now - src->source_creation);
-
- if (uj) {
- json_object_object_get_ex(
- json, ifp->name, &json_iface);
- if (!json_iface) {
- json_iface =
- json_object_new_object();
- json_object_string_add(
- json_iface, "name",
- ifp->name);
- json_object_object_add(
- json, ifp->name,
- json_iface);
- }
- json_object_object_get_ex(json_iface,
- group_str,
- &json_group);
-
- if (!json_group) {
- json_group =
- json_object_new_object();
- json_object_string_add(
- json_group, "group",
- group_str);
- json_object_object_add(
- json_iface, group_str,
- json_group);
- json_sources =
- json_object_new_array();
- json_object_object_add(
- json_group, "sources",
- json_sources);
- }
- json_source = json_object_new_object();
- json_object_string_add(json_source,
- "source",
- source_str);
- json_object_string_add(json_source,
- "timer", mmss);
- json_object_boolean_add(
- json_source, "forwarded",
- IGMP_SOURCE_TEST_FORWARDING(
- src->source_flags));
- json_object_string_add(
- json_source, "uptime", uptime);
- json_object_array_add(json_sources,
- json_source);
-
- } else {
- vty_out(vty,
- "%-16s %-15s %-15s %5s %3s %8s\n",
- ifp->name, group_str,
- source_str, mmss,
- IGMP_SOURCE_TEST_FORWARDING(
- src->source_flags)
- ? "Y"
- : "N",
- uptime);
- }
-
- } /* scan group sources */
+ srcnode, src))
+ igmp_sources_print(ifp, group_str, src, now,
+ json, vty, uj);
} /* scan igmp groups */
} /* scan interfaces */
+
if (uj)
vty_json(vty, json);
}
@@ -1227,7 +1504,7 @@ DEFUN (clear_ip_interfaces,
VRF_CMD_HELP_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1247,7 +1524,7 @@ DEFUN (clear_ip_igmp_interfaces,
"Reset IGMP interfaces\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1355,7 +1632,7 @@ DEFUN (clear_ip_pim_bsr_db,
"Reset pim bsr data\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1378,8 +1655,8 @@ DEFUN (show_ip_igmp_interface,
JSON_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
bool uj = use_json(argc, argv);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -1444,8 +1721,8 @@ DEFUN (show_ip_igmp_join,
JSON_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
bool uj = use_json(argc, argv);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -1487,39 +1764,47 @@ DEFUN (show_ip_igmp_join_vrf_all,
return CMD_SUCCESS;
}
-DEFUN (show_ip_igmp_groups,
- show_ip_igmp_groups_cmd,
- "show ip igmp [vrf NAME] groups [json]",
- SHOW_STR
- IP_STR
- IGMP_STR
- VRF_CMD_HELP_STR
- IGMP_GROUP_STR
- JSON_STR)
+DEFPY(show_ip_igmp_groups,
+ show_ip_igmp_groups_cmd,
+ "show ip igmp [vrf NAME$vrf_name] groups [INTERFACE$ifname [GROUP$grp_str]] [detail$detail] [json$json]",
+ SHOW_STR
+ IP_STR
+ IGMP_STR
+ VRF_CMD_HELP_STR
+ IGMP_GROUP_STR
+ "Interface name\n"
+ "Group address\n"
+ "Detailed 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 vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, !!json);
if (!vrf)
return CMD_WARNING;
- igmp_show_groups(vrf->info, vty, uj);
+ if (ifname)
+ igmp_show_groups_interface_single(vrf->info, vty, !!json,
+ ifname, grp_str, !!detail);
+ else
+ igmp_show_groups(vrf->info, vty, !!json, NULL, !!detail);
return CMD_SUCCESS;
}
-DEFUN (show_ip_igmp_groups_vrf_all,
- show_ip_igmp_groups_vrf_all_cmd,
- "show ip igmp vrf all groups [json]",
- SHOW_STR
- IP_STR
- IGMP_STR
- VRF_CMD_HELP_STR
- IGMP_GROUP_STR
- JSON_STR)
+DEFPY(show_ip_igmp_groups_vrf_all,
+ show_ip_igmp_groups_vrf_all_cmd,
+ "show ip igmp vrf all groups [GROUP$grp_str] [detail$detail] [json$json]",
+ SHOW_STR
+ IP_STR
+ IGMP_STR
+ VRF_CMD_HELP_STR
+ IGMP_GROUP_STR
+ "Group address\n"
+ "Detailed Information\n"
+ JSON_STR)
{
- bool uj = use_json(argc, argv);
+ bool uj = !!json;
struct vrf *vrf;
bool first = true;
@@ -1533,7 +1818,7 @@ DEFUN (show_ip_igmp_groups_vrf_all,
first = false;
} else
vty_out(vty, "VRF: %s\n", vrf->name);
- igmp_show_groups(vrf->info, vty, uj);
+ igmp_show_groups(vrf->info, vty, uj, grp_str, !!detail);
}
if (uj)
vty_out(vty, "}\n");
@@ -1552,7 +1837,7 @@ DEFUN (show_ip_igmp_groups_retransmissions,
"IGMP group retransmissions\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1562,23 +1847,29 @@ DEFUN (show_ip_igmp_groups_retransmissions,
return CMD_SUCCESS;
}
-DEFUN (show_ip_igmp_sources,
- show_ip_igmp_sources_cmd,
- "show ip igmp [vrf NAME] sources [json]",
- SHOW_STR
- IP_STR
- IGMP_STR
- VRF_CMD_HELP_STR
- IGMP_SOURCE_STR
- JSON_STR)
+DEFPY(show_ip_igmp_sources,
+ show_ip_igmp_sources_cmd,
+ "show ip igmp [vrf NAME$vrf_name] sources [INTERFACE$ifname [GROUP$grp_str]] [json$json]",
+ SHOW_STR
+ IP_STR
+ IGMP_STR
+ VRF_CMD_HELP_STR
+ IGMP_SOURCE_STR
+ "Interface name\n"
+ "Group address\n"
+ JSON_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, !!json);
if (!vrf)
return CMD_WARNING;
- igmp_show_sources(vrf->info, vty, use_json(argc, argv));
+ if (ifname)
+ igmp_show_sources_interface_single(vrf->info, vty, !!json,
+ ifname, grp_str);
+ else
+ igmp_show_sources(vrf->info, vty, !!json);
return CMD_SUCCESS;
}
@@ -1594,7 +1885,7 @@ DEFUN (show_ip_igmp_sources_retransmissions,
"IGMP source retransmissions\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1617,8 +1908,8 @@ DEFUN (show_ip_igmp_statistics,
JSON_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
bool uj = use_json(argc, argv);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -1746,7 +2037,7 @@ DEFUN (show_ip_pim_assert,
"PIM interface assert\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1766,7 +2057,7 @@ DEFUN (show_ip_pim_assert_internal,
"PIM interface internal assert state\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1786,7 +2077,7 @@ DEFUN (show_ip_pim_assert_metric,
"PIM interface assert metric\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -1806,7 +2097,7 @@ DEFUN (show_ip_pim_assert_winner_metric,
"PIM interface assert winner metric\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -2125,8 +2416,8 @@ DEFUN(show_ip_pim_mlag_up, show_ip_pim_mlag_up_cmd,
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 vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf || !vrf->info) {
vty_out(vty, "%s: VRF or Info missing\n", __func__);
@@ -2598,7 +2889,7 @@ DEFUN (show_ip_rib,
"Unicast address\n")
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
struct in_addr addr;
const char *addr_str;
struct pim_nexthop nexthop;
@@ -2686,7 +2977,7 @@ DEFUN (show_ip_ssmpingd,
VRF_CMD_HELP_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
if (!vrf)
return CMD_WARNING;
@@ -3141,8 +3432,8 @@ DEFUN (show_ip_pim_ssm_range,
JSON_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
bool uj = use_json(argc, argv);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -3192,8 +3483,8 @@ DEFUN (show_ip_pim_group_type,
JSON_STR)
{
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
bool uj = use_json(argc, argv);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -5086,7 +5377,7 @@ DEFUN (show_ip_msdp_mesh_group,
bool uj = use_json(argc, argv);
int idx = 2;
struct pim_msdp_mg *mg;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
struct pim_instance *pim;
struct json_object *json = NULL;
@@ -5322,7 +5613,7 @@ DEFUN (show_ip_msdp_peer_detail,
{
bool uj = use_json(argc, argv);
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -5562,7 +5853,7 @@ DEFUN (show_ip_msdp_sa_detail,
{
bool uj = use_json(argc, argv);
int idx = 2;
- struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -5677,7 +5968,7 @@ DEFUN (show_ip_msdp_sa_sg,
struct vrf *vrf;
int idx = 2;
- vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -5947,7 +6238,7 @@ DEFUN (show_ip_pim_vxlan_sg,
struct vrf *vrf;
int idx = 2;
- vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
@@ -6007,7 +6298,7 @@ DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
struct vrf *vrf;
int idx = 2;
- vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
if (!vrf)
return CMD_WARNING;
diff --git a/pimd/pim_cmd.h b/pimd/pim_cmd.h
index fb6693491b..d39d77cd2f 100644
--- a/pimd/pim_cmd.h
+++ b/pimd/pim_cmd.h
@@ -60,4 +60,5 @@
void pim_cmd_init(void);
+#define PIM_TIME_STRLEN 10
#endif /* PIM_CMD_H */
diff --git a/ripd/rip_nb.c b/ripd/rip_nb.c
index c332b2a5b7..1a7b34adde 100644
--- a/ripd/rip_nb.c
+++ b/ripd/rip_nb.c
@@ -166,6 +166,27 @@ const struct frr_yang_module_info frr_ripd_info = {
},
},
{
+ .xpath = "/frr-ripd:ripd/instance/if-route-maps/if-route-map",
+ .cbs = {
+ .create = ripd_instance_if_route_maps_if_route_map_create,
+ .destroy = ripd_instance_if_route_maps_if_route_map_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/if-route-maps/if-route-map/in-route-map",
+ .cbs = {
+ .modify = ripd_instance_if_route_maps_if_route_map_in_route_map_modify,
+ .destroy = ripd_instance_if_route_maps_if_route_map_in_route_map_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-ripd:ripd/instance/if-route-maps/if-route-map/out-route-map",
+ .cbs = {
+ .modify = ripd_instance_if_route_maps_if_route_map_out_route_map_modify,
+ .destroy = ripd_instance_if_route_maps_if_route_map_out_route_map_destroy,
+ }
+ },
+ {
.xpath = "/frr-ripd:ripd/instance/static-route",
.cbs = {
.cli_show = cli_show_rip_route,
diff --git a/ripd/rip_nb.h b/ripd/rip_nb.h
index a30e579e1c..ebc60fefb4 100644
--- a/ripd/rip_nb.h
+++ b/ripd/rip_nb.h
@@ -52,6 +52,18 @@ int ripd_instance_redistribute_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args);
int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args);
+int ripd_instance_if_route_maps_if_route_map_create(
+ struct nb_cb_create_args *args);
+int ripd_instance_if_route_maps_if_route_map_destroy(
+ struct nb_cb_destroy_args *args);
+int ripd_instance_if_route_maps_if_route_map_in_route_map_modify(
+ struct nb_cb_modify_args *args);
+int ripd_instance_if_route_maps_if_route_map_in_route_map_destroy(
+ struct nb_cb_destroy_args *args);
+int ripd_instance_if_route_maps_if_route_map_out_route_map_modify(
+ struct nb_cb_modify_args *args);
+int ripd_instance_if_route_maps_if_route_map_out_route_map_destroy(
+ struct nb_cb_destroy_args *args);
int ripd_instance_static_route_create(struct nb_cb_create_args *args);
int ripd_instance_static_route_destroy(struct nb_cb_destroy_args *args);
int ripd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args);
diff --git a/ripd/rip_nb_config.c b/ripd/rip_nb_config.c
index 2277ddc204..343bb9bb57 100644
--- a/ripd/rip_nb_config.c
+++ b/ripd/rip_nb_config.c
@@ -3,6 +3,7 @@
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
* Copyright (C) 2018 NetDEF, Inc.
* Renato Westphal
+ * Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
@@ -13,6 +14,7 @@
#include "prefix.h"
#include "table.h"
#include "command.h"
+#include "if_rmap.h"
#include "routemap.h"
#include "northbound.h"
#include "libfrr.h"
@@ -681,6 +683,94 @@ int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args)
}
/*
+ * XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map
+ */
+int ripd_instance_if_route_maps_if_route_map_create(
+ struct nb_cb_create_args *args)
+{
+ /* if_rmap is created when first routemap is added */
+ return NB_OK;
+}
+
+int ripd_instance_if_route_maps_if_route_map_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct rip *rip;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ /*
+ * YANG will prune edit deletes up to the most general deleted node so
+ * we need to handle deleting any existing state underneath and not
+ * count on those more specific callbacks being called individually.
+ */
+
+ rip = nb_running_get_entry(args->dnode, NULL, true);
+ if_rmap_yang_destroy_cb(rip->if_rmap_ctx, args->dnode);
+
+ return NB_OK;
+}
+
+static void if_route_map_modify(const struct lyd_node *dnode,
+ enum if_rmap_type type, bool delete)
+{
+ struct rip *rip = nb_running_get_entry(dnode, NULL, true);
+
+ if_rmap_yang_modify_cb(rip->if_rmap_ctx, dnode, type, delete);
+}
+
+/*
+ * XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map/in-route-map
+ */
+int ripd_instance_if_route_maps_if_route_map_in_route_map_modify(
+ struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_IN, false);
+
+ return NB_OK;
+}
+
+int ripd_instance_if_route_maps_if_route_map_in_route_map_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_IN, true);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map/out-route-map
+ */
+int ripd_instance_if_route_maps_if_route_map_out_route_map_modify(
+ struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_OUT, false);
+
+ return NB_OK;
+}
+
+int ripd_instance_if_route_maps_if_route_map_out_route_map_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_OUT, true);
+
+ return NB_OK;
+}
+
+/*
* XPath: /frr-ripd:ripd/instance/static-route
*/
int ripd_instance_static_route_create(struct nb_cb_create_args *args)
diff --git a/ripd/ripd.c b/ripd/ripd.c
index ae4d93b4f5..7dbe2bbccf 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -1500,7 +1500,7 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to,
ret = sendmsg(rip->sock, &msg, 0);
if (IS_RIP_DEBUG_EVENT)
- zlog_debug("SEND to %pI4%d", &sin.sin_addr,
+ zlog_debug("SEND to %pI4 port %d", &sin.sin_addr,
ntohs(sin.sin_port));
if (ret < 0)
@@ -2836,16 +2836,11 @@ uint8_t rip_distance_apply(struct rip *rip, struct rip_info *rinfo)
if (access_list_apply(alist, &rinfo->rp->p)
== FILTER_DENY)
return 0;
-
- return rdistance->distance;
- } else
- return rdistance->distance;
+ }
+ return rdistance->distance;
}
- if (rip->distance)
- return rip->distance;
-
- return 0;
+ return rip->distance;
}
static void rip_distance_show(struct vty *vty, struct rip *rip)
diff --git a/ripngd/ripng_nb.c b/ripngd/ripng_nb.c
index 63144d866b..2f412e5197 100644
--- a/ripngd/ripng_nb.c
+++ b/ripngd/ripng_nb.c
@@ -115,6 +115,27 @@ const struct frr_yang_module_info frr_ripngd_info = {
},
},
{
+ .xpath = "/frr-ripngd:ripngd/instance/if-route-maps/if-route-map",
+ .cbs = {
+ .create = ripngd_instance_if_route_maps_if_route_map_create,
+ .destroy = ripngd_instance_if_route_maps_if_route_map_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-ripngd:ripngd/instance/if-route-maps/if-route-map/in-route-map",
+ .cbs = {
+ .modify = ripngd_instance_if_route_maps_if_route_map_in_route_map_modify,
+ .destroy = ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map",
+ .cbs = {
+ .modify = ripngd_instance_if_route_maps_if_route_map_out_route_map_modify,
+ .destroy = ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy,
+ }
+ },
+ {
.xpath = "/frr-ripngd:ripngd/instance/static-route",
.cbs = {
.cli_show = cli_show_ripng_route,
diff --git a/ripngd/ripng_nb.h b/ripngd/ripng_nb.h
index 675cef7c92..1c0e63c241 100644
--- a/ripngd/ripng_nb.h
+++ b/ripngd/ripng_nb.h
@@ -39,6 +39,18 @@ int ripngd_instance_redistribute_route_map_destroy(
int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args);
int ripngd_instance_redistribute_metric_destroy(
struct nb_cb_destroy_args *args);
+int ripngd_instance_if_route_maps_if_route_map_create(
+ struct nb_cb_create_args *args);
+int ripngd_instance_if_route_maps_if_route_map_destroy(
+ struct nb_cb_destroy_args *args);
+int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify(
+ struct nb_cb_modify_args *args);
+int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy(
+ struct nb_cb_destroy_args *args);
+int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify(
+ struct nb_cb_modify_args *args);
+int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy(
+ struct nb_cb_destroy_args *args);
int ripngd_instance_static_route_create(struct nb_cb_create_args *args);
int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args *args);
int ripngd_instance_aggregate_address_create(struct nb_cb_create_args *args);
diff --git a/ripngd/ripng_nb_config.c b/ripngd/ripng_nb_config.c
index 006bf79ce8..30f707e061 100644
--- a/ripngd/ripng_nb_config.c
+++ b/ripngd/ripng_nb_config.c
@@ -3,6 +3,7 @@
* Copyright (C) 1998 Kunihiro Ishiguro
* Copyright (C) 2018 NetDEF, Inc.
* Renato Westphal
+ * Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
@@ -13,6 +14,7 @@
#include "prefix.h"
#include "table.h"
#include "command.h"
+#include "if_rmap.h"
#include "routemap.h"
#include "agg_table.h"
#include "northbound.h"
@@ -503,6 +505,93 @@ int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args)
}
/*
+ * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map
+ */
+int ripngd_instance_if_route_maps_if_route_map_create(
+ struct nb_cb_create_args *args)
+{
+ /* if_rmap is created when first routemap is added */
+ return NB_OK;
+}
+
+int ripngd_instance_if_route_maps_if_route_map_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct ripng *ripng;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ /*
+ * YANG will prune edit deletes up to the most general deleted node so
+ * we need to handle deleting any existing state underneath and not
+ * count on those more specific callbacks being called individually.
+ */
+
+ ripng = nb_running_get_entry(args->dnode, NULL, true);
+ if_rmap_yang_destroy_cb(ripng->if_rmap_ctx, args->dnode);
+
+ return NB_OK;
+}
+
+static void if_route_map_modify(const struct lyd_node *dnode,
+ enum if_rmap_type type, bool delete)
+{
+ struct ripng *ripng = nb_running_get_entry(dnode, NULL, true);
+
+ if_rmap_yang_modify_cb(ripng->if_rmap_ctx, dnode, type, delete);
+}
+/*
+ * XPath: /frr-ripng:ripng/instance/if-route-maps/if-route-map/in-route-map
+ */
+int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify(
+ struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_IN, false);
+
+ return NB_OK;
+}
+
+int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_IN, true);
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map
+ */
+int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify(
+ struct nb_cb_modify_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_OUT, false);
+
+ return NB_OK;
+}
+
+int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ if_route_map_modify(args->dnode, IF_RMAP_OUT, true);
+
+ return NB_OK;
+}
+
+/*
* XPath: /frr-ripngd:ripngd/instance/static-route
*/
int ripngd_instance_static_route_create(struct nb_cb_create_args *args)
diff --git a/tests/lib/subdir.am b/tests/lib/subdir.am
index 1bc092a49e..e950d0120d 100644
--- a/tests/lib/subdir.am
+++ b/tests/lib/subdir.am
@@ -15,7 +15,7 @@ tests_lib_test_frrscript_CFLAGS = $(TESTS_CFLAGS)
tests_lib_test_frrscript_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_test_frrscript_LDADD = $(ALL_TESTS_LDADD)
tests_lib_test_frrscript_SOURCES = tests/lib/test_frrscript.c
-EXTRA_DIST += tests/lib/test_frrscript.py
+EXTRA_DIST += tests/lib/test_frrscript.py tests/lib/script1.lua
##############################################################################
diff --git a/tests/topotests/bgp_evpn_vxlan_svd_topo1/test_bgp_evpn_vxlan_svd.py b/tests/topotests/bgp_evpn_vxlan_svd_topo1/test_bgp_evpn_vxlan_svd.py
index 8b9631175a..65c0c3532a 100755
--- a/tests/topotests/bgp_evpn_vxlan_svd_topo1/test_bgp_evpn_vxlan_svd.py
+++ b/tests/topotests/bgp_evpn_vxlan_svd_topo1/test_bgp_evpn_vxlan_svd.py
@@ -83,6 +83,7 @@ def build_topo(tgen):
switch.add_link(tgen.gears["PE2"])
switch.add_link(tgen.gears["host2"])
+
def setup_pe_router(tgen, pe_name, tunnel_local_ip, svi_ip, intf):
pe = tgen.gears[pe_name]
@@ -100,7 +101,9 @@ def setup_pe_router(tgen, pe_name, tunnel_local_ip, svi_ip, intf):
# setup single vxlan device
pe.run(
- "ip link add dev vxlan0 type vxlan dstport 4789 local {0} nolearning external".format(tunnel_local_ip)
+ "ip link add dev vxlan0 type vxlan dstport 4789 local {0} nolearning external".format(
+ tunnel_local_ip
+ )
)
pe.run("ip link set dev vxlan0 master bridge")
pe.run("bridge link set dev vxlan0 vlan_tunnel on")
@@ -136,10 +139,12 @@ def setup_pe_router(tgen, pe_name, tunnel_local_ip, svi_ip, intf):
pe.run("bridge vlan add dev vxlan0 vid 300")
pe.run("bridge vlan add dev vxlan0 vid 300 tunnel_info id 300")
+
def setup_p_router(tgen, p_name):
p1 = tgen.gears[p_name]
p1.run("sysctl -w net.ipv4.ip_forward=1")
+
def setup_module(mod):
"Sets up the pytest environment"
@@ -180,7 +185,7 @@ def teardown_module(mod):
"Teardown the pytest environment"
tgen = get_topogen()
- #tgen.mininet_cli()
+ # tgen.mininet_cli()
# This function tears down the whole topology.
tgen.stop_topology()
@@ -204,17 +209,21 @@ def check_vni_macs_present(tgen, router, vni, maclist):
)
return None
+
def check_flood_entry_present(pe, vni, vtep):
if not topotest.iproute2_is_fdb_get_capable():
return None
- output = pe.run("bridge fdb get 00:00:00:00:00:00 dev vxlan0 vni {} self".format(vni))
+ output = pe.run(
+ "bridge fdb get 00:00:00:00:00:00 dev vxlan0 vni {} self".format(vni)
+ )
if str(vtep) not in output:
return output
return None
+
def test_pe1_converge_evpn():
"Wait for protocol convergence"
@@ -231,6 +240,15 @@ def test_pe1_converge_evpn():
_, result = topotest.run_and_expect(test_func, None, count=45, wait=1)
assertmsg = '"{}" JSON output mismatches'.format(pe1.name)
+ # Let's ensure that the hosts have actually tried talking to
+ # each other. Otherwise under certain startup conditions
+ # they may not actually do any l2 arp'ing and as such
+ # the bridges won't know about the hosts on their networks
+ host1 = tgen.gears["host1"]
+ host1.run("ping -c 1 10.10.1.56")
+ host2 = tgen.gears["host2"]
+ host2.run("ping -c 1 10.10.1.55")
+
test_func = partial(
check_vni_macs_present,
tgen,
@@ -249,11 +267,12 @@ def test_pe1_converge_evpn():
assertmsg = '"{}" Flood FDB Entry for VTEP {} not found'.format(pe1.name, vtep)
assert result is None, assertmsg
+
def test_pe2_converge_evpn():
"Wait for protocol convergence"
tgen = get_topogen()
-#Don't run this test if we have any failure.
+ # Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
@@ -284,6 +303,7 @@ def test_pe2_converge_evpn():
assertmsg = '"{}" Flood FDB Entry for VTEP {} not found'.format(pe2.name, vtep)
assert result is None, assertmsg
+
def mac_learn_test(host, local):
"check the host MAC gets learned by the VNI"
@@ -389,11 +409,11 @@ def ip_learn_test(tgen, host, local, remote, ip_addr):
if "HWaddr" in line_items[0]:
mac = line_items[1]
break
- #print(host_output)
+ # print(host_output)
# check we have a local association between the MAC and IP
local_output = local.vtysh_cmd("show evpn mac vni 101 mac {} json".format(mac))
- #print(local_output)
+ # print(local_output)
local_output_json = json.loads(local_output)
mac_type = local_output_json[mac]["type"]
assertmsg = "Failed to learn local IP address on host {}".format(host.name)
@@ -417,7 +437,7 @@ def ip_learn_test(tgen, host, local, remote, ip_addr):
remote_output = remote.vtysh_cmd(
"show evpn mac vni 101 mac {} json".format(mac)
)
- #print(remote_output)
+ # print(remote_output)
remote_output_json = json.loads(remote_output)
type = remote_output_json[mac]["type"]
if not remote_output_json[mac]["neighbors"] == "none":
@@ -431,12 +451,12 @@ def ip_learn_test(tgen, host, local, remote, ip_addr):
count += 1
sleep(1)
- #print("tries: {}".format(count))
+ # print("tries: {}".format(count))
assertmsg = "{} remote learned mac no address: {} ".format(host.name, mac)
# some debug for this failure
if not converged == True:
log_output = remote.run("cat zebra.log")
- #print(log_output)
+ # print(log_output)
assert converged == True, assertmsg
if remote_output_json[mac]["neighbors"]["active"]:
@@ -463,8 +483,8 @@ def test_ip_pe1_learn():
host1 = tgen.gears["host1"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- #pe2.vtysh_cmd("debug zebra vxlan")
- #pe2.vtysh_cmd("debug zebra kernel")
+ # pe2.vtysh_cmd("debug zebra vxlan")
+ # pe2.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host1.run("ping -c1 10.10.1.1")
ip_learn_test(tgen, host1, pe1, pe2, "10.10.1.55")
@@ -482,13 +502,14 @@ def test_ip_pe2_learn():
host2 = tgen.gears["host2"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- #pe1.vtysh_cmd("debug zebra vxlan")
- #pe1.vtysh_cmd("debug zebra kernel")
+ # pe1.vtysh_cmd("debug zebra vxlan")
+ # pe1.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host2.run("ping -c1 10.10.1.3")
ip_learn_test(tgen, host2, pe2, pe1, "10.10.1.56")
# tgen.mininet_cli()
+
def show_dvni_route(pe, vni, prefix, vrf):
output = pe.vtysh_cmd("show ip route vrf {} {}".format(vrf, prefix))
@@ -502,6 +523,7 @@ def show_dvni_route(pe, vni, prefix, vrf):
return None
+
def test_dvni():
"test Downstream VNI works as expected importing into PE1"
@@ -517,7 +539,7 @@ def test_dvni():
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assertmsg = '"{}" DVNI route {} not found'.format(pe1.name, prefix)
assert result is None, assertmsg
- #tgen.mininet_cli()
+ # tgen.mininet_cli()
def test_memory_leak():
diff --git a/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py b/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py
index 6561833d6e..2884043012 100755
--- a/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py
+++ b/tests/topotests/bgp_evpn_vxlan_topo1/test_bgp_evpn_vxlan.py
@@ -164,6 +164,15 @@ def test_pe1_converge_evpn():
_, result = topotest.run_and_expect(test_func, None, count=45, wait=1)
assertmsg = '"{}" JSON output mismatches'.format(pe1.name)
+ # Let's ensure that the hosts have actually tried talking to
+ # each other. Otherwise under certain startup conditions
+ # they may not actually do any l2 arp'ing and as such
+ # the bridges won't know about the hosts on their networks
+ host1 = tgen.gears["host1"]
+ host1.run("ping -c 1 10.10.1.56")
+ host2 = tgen.gears["host2"]
+ host2.run("ping -c 1 10.10.1.55")
+
test_func = partial(
check_vni_macs_present,
tgen,
@@ -171,6 +180,7 @@ def test_pe1_converge_evpn():
101,
(("host1", "host1-eth0"), ("host2", "host2-eth0")),
)
+
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
if result:
logger.warning("%s", result)
@@ -385,8 +395,8 @@ def test_ip_pe1_learn():
host1 = tgen.gears["host1"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- #pe2.vtysh_cmd("debug zebra vxlan")
- #pe2.vtysh_cmd("debug zebra kernel")
+ # pe2.vtysh_cmd("debug zebra vxlan")
+ # pe2.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host1.run("ping -c1 10.10.1.1")
ip_learn_test(tgen, host1, pe1, pe2, "10.10.1.55")
@@ -404,8 +414,8 @@ def test_ip_pe2_learn():
host2 = tgen.gears["host2"]
pe1 = tgen.gears["PE1"]
pe2 = tgen.gears["PE2"]
- #pe1.vtysh_cmd("debug zebra vxlan")
- #pe1.vtysh_cmd("debug zebra kernel")
+ # pe1.vtysh_cmd("debug zebra vxlan")
+ # pe1.vtysh_cmd("debug zebra kernel")
# lets populate that arp cache
host2.run("ping -c1 10.10.1.3")
ip_learn_test(tgen, host2, pe2, pe1, "10.10.1.56")
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py
index eaa6aa4c30..46993c7d9a 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_up.py
@@ -62,6 +62,25 @@ else:
"pass",
"Adding {} routes".format(num),
)
+ luCommand(
+ "ce1",
+ 'vtysh -c "show ip route summ" | grep "sharp" | cut -d " " -f 33',
+ str(num),
+ "wait",
+ "See all sharp routes in rib on ce1",
+ wait,
+ wait_time=10,
+ )
+ luCommand(
+ "ce2",
+ 'vtysh -c "show ip route summ" | grep "sharp" | cut -d " " -f 33',
+ str(num),
+ "wait",
+ "See all sharp routes in rib on ce2",
+ wait,
+ wait_time=10,
+ )
+
rtrs = ["ce1", "ce2", "ce3"]
for rtr in rtrs:
luCommand(
diff --git a/tests/topotests/bgp_lu_explicitnull/r1/bgpd.conf b/tests/topotests/bgp_lu_explicitnull/r1/bgpd.conf
new file mode 100644
index 0000000000..a31439c984
--- /dev/null
+++ b/tests/topotests/bgp_lu_explicitnull/r1/bgpd.conf
@@ -0,0 +1,15 @@
+router bgp 65500
+ bgp router-id 192.0.2.1
+ no bgp ebgp-requires-policy
+ bgp labeled-unicast explicit-null
+ neighbor 192.0.2.2 remote-as 65501
+!
+ address-family ipv4 unicast
+ no neighbor 192.0.2.2 activate
+ network 192.168.2.1/32
+ exit-address-family
+ !
+ address-family ipv4 labeled-unicast
+ neighbor 192.0.2.2 activate
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_lu_explicitnull/r1/zebra.conf b/tests/topotests/bgp_lu_explicitnull/r1/zebra.conf
new file mode 100644
index 0000000000..b84574891e
--- /dev/null
+++ b/tests/topotests/bgp_lu_explicitnull/r1/zebra.conf
@@ -0,0 +1,6 @@
+interface r1-eth0
+ ip address 192.0.2.1/24
+!
+interface r1-eth1
+ ip address 192.168.2.1/32
+! \ No newline at end of file
diff --git a/tests/topotests/bgp_lu_explicitnull/r2/bgpd.conf b/tests/topotests/bgp_lu_explicitnull/r2/bgpd.conf
new file mode 100644
index 0000000000..41c2b9b6fa
--- /dev/null
+++ b/tests/topotests/bgp_lu_explicitnull/r2/bgpd.conf
@@ -0,0 +1,15 @@
+router bgp 65501
+ bgp router-id 192.0.2.2
+ no bgp ebgp-requires-policy
+ bgp labeled-unicast explicit-null
+ neighbor 192.0.2.1 remote-as 65500
+!
+ address-family ipv4 unicast
+ no neighbor 192.0.2.1 activate
+ network 192.168.2.2/32
+ exit-address-family
+ !
+ address-family ipv4 labeled-unicast
+ neighbor 192.0.2.1 activate
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_lu_explicitnull/r2/zebra.conf b/tests/topotests/bgp_lu_explicitnull/r2/zebra.conf
new file mode 100644
index 0000000000..9a639610c1
--- /dev/null
+++ b/tests/topotests/bgp_lu_explicitnull/r2/zebra.conf
@@ -0,0 +1,6 @@
+interface r2-eth0
+ ip address 192.0.2.2/24
+!
+interface r2-eth1
+ ip address 192.168.2.2/32
+!
diff --git a/tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py b/tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py
new file mode 100644
index 0000000000..d53ac68e84
--- /dev/null
+++ b/tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+#
+# test_bgp_explicitnull.py
+#
+# Part of NetDEF Topology Tests
+#
+# Copyright 2023 by 6WIND S.A.
+#
+
+"""
+test_bgp_lu_explicitnull.py: Test BGP LU label allocation
+"""
+
+import os
+import sys
+import json
+import functools
+import pytest
+
+# 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
+
+
+pytestmark = [pytest.mark.bgpd]
+
+
+# Basic scenario for BGP-LU. Nodes are directly connected.
+# The 192.168.2.2/32 prefix is advertised from r2 to r1
+# The explicit-null label should be used
+# The 192.168.2.1/32 prefix is advertised from r1 to r2
+# The explicit-null label should be used
+# Traffic from 192.168.2.1 to 192.168.2.2 should use explicit-null label
+#
+# AS65500 BGP-LU AS65501
+# +-----+ +-----+
+# | |.1 .2| |
+# | 1 +----------------+ 2 + 192.168.0.2/32
+# | | 192.0.2.0/24 | |
+# +-----+ +-----+
+
+
+def build_topo(tgen):
+ "Build function"
+
+ # Create routers
+ tgen.add_router("r1")
+ tgen.add_router("r2")
+
+ # r1-r2
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ # r1
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["r1"])
+
+ # r2
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ # This function initiates the topology build with Topogen...
+ tgen = Topogen(build_topo, mod.__name__)
+
+ # Skip if no mpls support
+ if not tgen.hasmpls:
+ logger.info("MPLS is not available, skipping test")
+ pytest.skip("MPLS is not available, skipping")
+ return
+
+ # ... and here it calls Mininet initialization functions.
+ tgen.start_topology()
+
+ # This is a sample of configuration loading.
+ router_list = tgen.routers()
+
+ # Enable mpls input for routers, so we can ping
+ sval = "net.mpls.conf.{}.input"
+ topotest.sysctl_assure(router_list["r2"], sval.format("r2-eth0"), 1)
+ topotest.sysctl_assure(router_list["r1"], sval.format("r1-eth0"), 1)
+
+ # For all registred routers, load the zebra configuration file
+ for rname, router in router_list.items():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ # After loading the configurations, this function loads configured daemons.
+ 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 check_show_ip_label_prefix_found(router, ipversion, prefix, label):
+ output = json.loads(
+ router.vtysh_cmd("show {} route {} json".format(ipversion, prefix))
+ )
+ expected = {prefix: [{"prefix": prefix, "nexthops": [{"fib": True, "labels": [label]}]}]}
+ ret = topotest.json_cmp(output, expected)
+ if ret is None:
+ return "not good"
+ return None
+
+def test_converge_bgplu():
+ "Wait for protocol convergence"
+
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # tgen.mininet_cli();
+ r1 = tgen.gears["r1"]
+ r2 = tgen.gears["r2"]
+ # Check r1 gets prefix 192.168.2.2/32
+ test_func = functools.partial(
+ check_show_ip_label_prefix_found,
+ tgen.gears["r1"],
+ "ip",
+ "192.168.2.2/32",
+ "0",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert (
+ success
+ ), "r1, prefix 192.168.2.2/32 from r2 not present"
+
+ # Check r2 gets prefix 192.168.2.1/32
+ test_func = functools.partial(
+ check_show_ip_label_prefix_found,
+ tgen.gears["r2"],
+ "ip",
+ "192.168.2.1/32",
+ "0",
+ )
+ success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+ assert (
+ success
+ ), "r2, prefix 192.168.2.1/32 from r1 not present"
+
+def test_traffic_connectivity():
+ "Wait for protocol convergence"
+
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ def _check_ping(name, dest_addr, src_addr):
+ tgen = get_topogen()
+ output = tgen.gears[name].run("ping {} -c 1 -w 1 -I {}".format(dest_addr, src_addr))
+ logger.info(output)
+ if " 0% packet loss" not in output:
+ return True
+
+ logger.info("r1, check ping 192.168.2.2 from 192.168.2.1 is OK")
+ tgen = get_topogen()
+ func = functools.partial(_check_ping, "r1", "192.168.2.2", "192.168.2.1")
+ # tgen.mininet_cli()
+ success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
+ assert result is None, "r1, ping to 192.168.2.2 from 192.168.2.1 fails"
+
+def test_memory_leak():
+ "Run the memory leak test and report results."
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/multicast_pim_sm_topo3/igmp_group_all_detail.json b/tests/topotests/multicast_pim_sm_topo3/igmp_group_all_detail.json
new file mode 100644
index 0000000000..715aa1de72
--- /dev/null
+++ b/tests/topotests/multicast_pim_sm_topo3/igmp_group_all_detail.json
@@ -0,0 +1 @@
+{"totalGroups":5,"watermarkLimit":0,"l1-i1-eth1":{"name":"l1-i1-eth1","state":"up","address":"10.0.8.2","index":"*","flagMulticast":true,"flagBroadcast":true,"lanDelayEnabled":true,"groups":[{"group":"225.1.1.2","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.1","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.3","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.5","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.4","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]}]}}
diff --git a/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_brief.json b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_brief.json
new file mode 100644
index 0000000000..3bbcce1370
--- /dev/null
+++ b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_brief.json
@@ -0,0 +1,51 @@
+{
+ "totalGroups":5,
+ "watermarkLimit":0,
+ "l1-i1-eth1":{
+ "name":"l1-i1-eth1",
+ "state":"up",
+ "address":"10.0.8.2",
+ "index":"*",
+ "flagMulticast":true,
+ "flagBroadcast":true,
+ "lanDelayEnabled":true,
+ "groups":[
+ {
+ "group":"225.1.1.1",
+ "timer":"*",
+ "sourcesCount":1,
+ "version":2,
+ "uptime":"*"
+ },
+ {
+ "group":"225.1.1.2",
+ "timer":"*",
+ "sourcesCount":1,
+ "version":2,
+ "uptime":"*"
+ },
+ {
+ "group":"225.1.1.3",
+ "timer":"*",
+ "sourcesCount":1,
+ "version":2,
+ "uptime":"*"
+ },
+ {
+ "group":"225.1.1.4",
+ "timer":"*",
+ "sourcesCount":1,
+ "version":2,
+ "uptime":"*"
+ },
+ {
+ "group":"225.1.1.5",
+ "timer":"*",
+ "sourcesCount":1,
+ "version":2,
+ "uptime":"*"
+ }
+ ]
+ }
+}
+
diff --git a/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_detail.json b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_detail.json
new file mode 100644
index 0000000000..876befa1b8
--- /dev/null
+++ b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_group_all_detail.json
@@ -0,0 +1 @@
+{"totalGroups":5,"watermarkLimit":0,"l1-i1-eth1":{"name":"l1-i1-eth1","state":"up","address":"10.0.8.2","index":"*","flagMulticast":true,"flagBroadcast":true,"lanDelayEnabled":true,"groups":[{"group":"225.1.1.1","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.2","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.3","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.4","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]},{"group":"225.1.1.5","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]}]}}
diff --git a/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_brief.json b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_brief.json
new file mode 100644
index 0000000000..a3fb496d25
--- /dev/null
+++ b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_brief.json
@@ -0,0 +1,22 @@
+{
+ "totalGroups":5,
+ "watermarkLimit":0,
+ "l1-i1-eth1":{
+ "name":"l1-i1-eth1",
+ "state":"up",
+ "address":"10.0.8.2",
+ "index":"*",
+ "flagMulticast":true,
+ "flagBroadcast":true,
+ "lanDelayEnabled":true,
+ "groups":[
+ {
+ "group":"225.1.1.5",
+ "timer":"*",
+ "sourcesCount":1,
+ "version":2,
+ "uptime":"*"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_detail.json b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_detail.json
new file mode 100644
index 0000000000..11ac5a01e7
--- /dev/null
+++ b/tests/topotests/multicast_pim_sm_topo3/igmp_single_if_single_group_detail.json
@@ -0,0 +1 @@
+{"totalGroups":5,"watermarkLimit":0,"l1-i1-eth1":{"name":"l1-i1-eth1","state":"up","address":"10.0.8.2","index":"*","flagMulticast":true,"flagBroadcast":true,"lanDelayEnabled":true,"groups":[{"group":"225.1.1.5","timer":"*","sourcesCount":1,"version":2,"uptime":"*","sources":[{"source":"*","timer":"*","forwarded":true,"uptime":"*"}]}]}}
diff --git a/tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_group_all.json b/tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_group_all.json
new file mode 100644
index 0000000000..10ae1afc90
--- /dev/null
+++ b/tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_group_all.json
@@ -0,0 +1,61 @@
+{
+ "l1-i1-eth1":{
+ "name":"l1-i1-eth1",
+ "225.1.1.1":{
+ "group":"225.1.1.1",
+ "sources":[
+ {
+ "source":"*",
+ "timer":"*",
+ "forwarded":true,
+ "uptime":"*"
+ }
+ ]
+ },
+ "225.1.1.2":{
+ "group":"225.1.1.2",
+ "sources":[
+ {
+ "source":"*",
+ "timer":"*",
+ "forwarded":true,
+ "uptime":"*"
+ }
+ ]
+ },
+ "225.1.1.3":{
+ "group":"225.1.1.3",
+ "sources":[
+ {
+ "source":"*",
+ "timer":"*",
+ "forwarded":true,
+ "uptime":"*"
+ }
+ ]
+ },
+ "225.1.1.4":{
+ "group":"225.1.1.4",
+ "sources":[
+ {
+ "source":"*",
+ "timer":"*",
+ "forwarded":true,
+ "uptime":"*"
+ }
+ ]
+ },
+ "225.1.1.5":{
+ "group":"225.1.1.5",
+ "sources":[
+ {
+ "source":"*",
+ "timer":"*",
+ "forwarded":true,
+ "uptime":"*"
+ }
+ ]
+ }
+ }
+}
+
diff --git a/tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_single_group.json b/tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_single_group.json
new file mode 100644
index 0000000000..7a19975bee
--- /dev/null
+++ b/tests/topotests/multicast_pim_sm_topo3/igmp_source_single_if_single_group.json
@@ -0,0 +1,16 @@
+{
+ "l1-i1-eth1":{
+ "name":"l1-i1-eth1",
+ "225.1.1.4":{
+ "group":"225.1.1.4",
+ "sources":[
+ {
+ "source":"*",
+ "timer":"*",
+ "forwarded":true,
+ "uptime":"*"
+ }
+ ]
+ }
+ }
+}
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 2ffd3a3ac0..2c1241c0cc 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
@@ -42,6 +42,8 @@ import time
import datetime
import pytest
from time import sleep
+import json
+import functools
pytestmark = pytest.mark.pimd
@@ -54,8 +56,8 @@ sys.path.append(os.path.join(CWD, "../lib/"))
# pylint: disable=C0413
# Import topogen and topotest helpers
-from lib.topogen import Topogen, get_topogen
-
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.common_config import (
start_topology,
write_test_header,
@@ -1510,6 +1512,108 @@ def test_verify_remove_add_igmp_config_to_receiver_interface_p0(request):
)
assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+ # IGMP JSON verification
+ step("Verify IGMP group and source JSON for single interface and group")
+ router = tgen.gears["l1"]
+
+ reffile = os.path.join(CWD, "igmp_group_all_detail.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip igmp vrf default groups detail json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "IGMP group detailed output on l1 for all interfaces and all groups is not as expected. Expected: {}".format(
+ expected
+ )
+ assert res is None, assertmsg
+
+ reffile = os.path.join(CWD, "igmp_single_if_group_all_brief.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip igmp vrf default groups l1-i1-eth1 json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "IGMP group output on l1 for all groups in interface l1-i1-eth1 is not as expected. Expected: {}".format(
+ expected
+ )
+ assert res is None, assertmsg
+
+ reffile = os.path.join(CWD, "igmp_single_if_group_all_detail.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip igmp vrf default groups l1-i1-eth1 detail json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "IGMP group detailed output on l1 for all groups in interface l1-i1-eth1 is not as expected. Expected: {}".format(
+ expected
+ )
+ assert res is None, assertmsg
+
+ reffile = os.path.join(CWD, "igmp_single_if_single_group_brief.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip igmp vrf default groups l1-i1-eth1 225.1.1.5 json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "IGMP group output on l1 for interface l1-i1-eth1 and group 225.1.1.5 is not as expected. Expected: {}".format(
+ expected
+ )
+ assert res is None, assertmsg
+
+ reffile = os.path.join(CWD, "igmp_single_if_single_group_detail.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip igmp vrf default groups l1-i1-eth1 225.1.1.5 detail json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "IGMP group detailed output on l1 for interface l1-i1-eth1 and group 225.1.1.5 is not as expected. Expected: {}".format(
+ expected
+ )
+ assert res is None, assertmsg
+
+ reffile = os.path.join(CWD, "igmp_source_single_if_group_all.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip igmp sources l1-i1-eth1 json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "IGMP source output on l1 for interface l1-i1-eth1 is not as expected. Expected: {}".format(
+ expected
+ )
+ assert res is None, assertmsg
+
+ reffile = os.path.join(CWD, "igmp_source_single_if_single_group.json")
+ expected = json.loads(open(reffile).read())
+ test_func = functools.partial(
+ topotest.router_json_cmp,
+ router,
+ "show ip igmp sources l1-i1-eth1 225.1.1.4 json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "IGMP source output on l1 for interface l1-i1-eth1 and group 225.1.1.4 is not as expected. Expected: {}".format(
+ expected
+ )
+ assert res is None, assertmsg
+
step(
"Remove igmp 'no ip igmp' and 'no ip igmp version 2' from"
" receiver interface of FRR1"
diff --git a/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py b/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py
index 138e364339..b0ba146984 100644
--- a/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py
+++ b/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py
@@ -52,7 +52,9 @@ def test_rip_allow_ecmp():
r1 = tgen.gears["r1"]
def _show_rip_routes():
- output = json.loads(r1.vtysh_cmd("show yang operational-data /frr-ripd:ripd ripd"))
+ output = json.loads(
+ r1.vtysh_cmd("show yang operational-data /frr-ripd:ripd ripd")
+ )
try:
output = output["frr-ripd:ripd"]["instance"][0]["state"]["routes"]
except KeyError:
@@ -83,7 +85,6 @@ def test_rip_allow_ecmp():
]
},
"metric": 2,
- "next-hop": "192.168.1.2"
},
]
}
diff --git a/yang/frr-if-rmap.yang b/yang/frr-if-rmap.yang
new file mode 100644
index 0000000000..0fa2c5eddf
--- /dev/null
+++ b/yang/frr-if-rmap.yang
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: BSD-2-Clause
+module frr-if-rmap {
+ yang-version 1.1;
+ namespace "http://frrouting.org/yang/frr-if-rmap";
+ prefix frr-if-map;
+
+ import frr-interface {
+ prefix frr-interface;
+ }
+
+ import frr-route-map {
+ prefix frr-route-map;
+ }
+
+ organization
+ "FRRouting";
+ contact
+ "FRR Users List: <mailto:frog@lists.frrouting.org>
+ FRR Development List: <mailto:dev@lists.frrouting.org>";
+ description
+ "This module defines route map settings
+
+ Copyright 2023 LabN Consulting L.L.C
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
+
+ revision 2023-04-09 {
+ description
+ "Initial revision";
+ reference "FRRouting";
+ }
+
+ grouping if-route-maps-group {
+ description "Grouping for interface route maps";
+
+ container if-route-maps {
+ description "Collection of interface route-maps";
+
+ list if-route-map {
+ must "in-route-map or out-route-map";
+ key "interface";
+ description "Collection of route-maps for an interface";
+
+ leaf "interface" {
+ type frr-interface:interface-ref;
+ description "The interface the route maps are associated with";
+ }
+ leaf "in-route-map" {
+ type frr-route-map:route-map-name;
+ description "Name of the ingress route map";
+ }
+ leaf "out-route-map" {
+ type frr-route-map:route-map-name;
+ description "Name of the egress route map";
+ }
+ }
+ }
+ }
+}
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index 66ec6a410d..de925b4823 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -1594,6 +1594,13 @@ module frr-isisd {
"Log changes to the IS-IS adjacencies in this area.";
}
+ leaf log-pdu-drops {
+ type boolean;
+ default "false";
+ description
+ "Log any dropped PDUs in this area.";
+ }
+
container mpls-te {
presence "Present if MPLS-TE is enabled.";
description
diff --git a/yang/frr-ripd.yang b/yang/frr-ripd.yang
index 24fe588854..d2088e589e 100644
--- a/yang/frr-ripd.yang
+++ b/yang/frr-ripd.yang
@@ -10,6 +10,9 @@ module frr-ripd {
import ietf-yang-types {
prefix yang;
}
+ import frr-if-rmap {
+ prefix frr-if-rmap;
+ }
import frr-interface {
prefix frr-interface;
}
@@ -282,6 +285,9 @@ module frr-ripd {
is 0.";
}
}
+
+ uses frr-if-rmap:if-route-maps-group;
+
leaf-list static-route {
type inet:ipv4-prefix;
description
diff --git a/yang/frr-ripngd.yang b/yang/frr-ripngd.yang
index d7de4c398a..7b2b135fb5 100644
--- a/yang/frr-ripngd.yang
+++ b/yang/frr-ripngd.yang
@@ -10,6 +10,9 @@ module frr-ripngd {
import ietf-yang-types {
prefix yang;
}
+ import frr-if-rmap {
+ prefix frr-if-rmap;
+ }
import frr-interface {
prefix frr-interface;
}
@@ -196,6 +199,9 @@ module frr-ripngd {
is 0.";
}
}
+
+ uses frr-if-rmap:if-route-maps-group;
+
leaf-list static-route {
type inet:ipv6-prefix;
description
diff --git a/yang/subdir.am b/yang/subdir.am
index 82a6a01474..eb17c38dbc 100644
--- a/yang/subdir.am
+++ b/yang/subdir.am
@@ -24,6 +24,7 @@ dist_yangmodels_DATA += yang/frr-filter.yang
dist_yangmodels_DATA += yang/frr-module-translator.yang
dist_yangmodels_DATA += yang/frr-nexthop.yang
dist_yangmodels_DATA += yang/frr-test-module.yang
+dist_yangmodels_DATA += yang/frr-if-rmap.yang
dist_yangmodels_DATA += yang/frr-interface.yang
dist_yangmodels_DATA += yang/frr-route-map.yang
dist_yangmodels_DATA += yang/frr-zebra-route-map.yang
diff --git a/zebra/interface.c b/zebra/interface.c
index 03376afc09..496a85e676 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -137,6 +137,8 @@ static int if_zebra_new_hook(struct interface *ifp)
zebra_if->multicast = IF_ZEBRA_DATA_UNSPEC;
zebra_if->shutdown = IF_ZEBRA_DATA_OFF;
+ zebra_if->link_nsid = NS_UNKNOWN;
+
zebra_if_nhg_dependents_init(zebra_if);
zebra_ptm_if_init(zebra_if);
@@ -305,6 +307,14 @@ struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns,
return NULL;
}
+struct interface *if_lookup_by_index_per_nsid(ns_id_t ns_id, uint32_t ifindex)
+{
+ struct zebra_ns *zns;
+
+ zns = zebra_ns_lookup(ns_id);
+ return zns ? if_lookup_by_index_per_ns(zns, ifindex) : NULL;
+}
+
const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
{
struct interface *ifp;
@@ -991,7 +1001,6 @@ void if_up(struct interface *ifp, bool install_connected)
{
struct zebra_if *zif;
struct interface *link_if;
- struct zebra_vrf *zvrf = ifp->vrf->info;
zif = ifp->info;
zif->up_count++;
@@ -1024,8 +1033,7 @@ void if_up(struct interface *ifp, bool install_connected)
link_if = ifp;
zebra_vxlan_svi_up(ifp, link_if);
} else if (IS_ZEBRA_IF_VLAN(ifp)) {
- link_if = if_lookup_by_index_per_ns(zvrf->zns,
- zif->link_ifindex);
+ link_if = zif->link;
if (link_if)
zebra_vxlan_svi_up(ifp, link_if);
} else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
@@ -1049,7 +1057,6 @@ void if_down(struct interface *ifp)
{
struct zebra_if *zif;
struct interface *link_if;
- struct zebra_vrf *zvrf = ifp->vrf->info;
zif = ifp->info;
zif->down_count++;
@@ -1068,8 +1075,7 @@ void if_down(struct interface *ifp)
link_if = ifp;
zebra_vxlan_svi_down(ifp, link_if);
} else if (IS_ZEBRA_IF_VLAN(ifp)) {
- link_if = if_lookup_by_index_per_ns(zvrf->zns,
- zif->link_ifindex);
+ link_if = zif->link;
if (link_if)
zebra_vxlan_svi_down(ifp, link_if);
} else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
@@ -1109,6 +1115,7 @@ void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
if (IS_ZEBRA_IF_VETH(ifp))
return;
zif = (struct zebra_if *)ifp->info;
+ zif->link_nsid = ns_id;
zif->link_ifindex = link_ifindex;
zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
link_ifindex);
@@ -1145,8 +1152,8 @@ void zebra_if_update_all_links(struct zebra_ns *zns)
/* update SVI linkages */
if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
- zif->link = if_lookup_by_index_per_ns(
- zns, zif->link_ifindex);
+ zif->link = if_lookup_by_index_per_nsid(
+ zif->link_nsid, zif->link_ifindex);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("interface %s/%d's lower fixup to %s/%d",
ifp->name, ifp->ifindex,
diff --git a/zebra/interface.h b/zebra/interface.h
index 4c6ebaa11d..e5545d6ba0 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -195,6 +195,7 @@ struct zebra_if {
struct list *mac_list;
/* Link fields - for sub-interfaces. */
+ ns_id_t link_nsid;
ifindex_t link_ifindex;
struct interface *link;
@@ -259,6 +260,8 @@ extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, uint32_t);
extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *,
const char *);
extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *);
+extern struct interface *if_lookup_by_index_per_nsid(ns_id_t nsid,
+ uint32_t ifindex);
extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int);
extern void if_unlink_per_ns(struct interface *);
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index fb1ebc6827..e821572c5d 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -3745,6 +3745,11 @@ dplane_route_update_internal(struct route_node *rn,
NEXTHOP_FLAG_FIB);
}
+ if ((op == DPLANE_OP_ROUTE_UPDATE) && old_re && re &&
+ (old_re != re) &&
+ !CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
+ SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+
dplane_ctx_free(&ctx);
return ZEBRA_DPLANE_REQUEST_SUCCESS;
}
@@ -6853,10 +6858,6 @@ void zebra_dplane_shutdown(void)
zdplane_info.dg_run = false;
- if (zdplane_info.dg_t_update)
- event_cancel_async(zdplane_info.dg_t_update->master,
- &zdplane_info.dg_t_update, NULL);
-
frr_pthread_stop(zdplane_info.dg_pthread, NULL);
/* Destroy pthread */
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 32cfa4d04c..adcaf64044 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3766,6 +3766,9 @@ static void rib_meta_queue_gr_run_free(struct meta_queue *mq, struct list *l,
continue;
XFREE(MTYPE_WQ_WRAPPER, gr_run);
+ node->data = NULL;
+ list_delete_node(l, node);
+ mq->size--;
}
}