summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfdd/bfd.c4
-rw-r--r--bfdd/bfd.h25
-rw-r--r--bfdd/bfd_packet.c4
-rw-r--r--bgpd/bgp_evpn.c12
-rw-r--r--bgpd/bgp_packet.c18
-rw-r--r--bgpd/bgp_vty.c28
-rw-r--r--bgpd/bgp_zebra.c20
-rw-r--r--bgpd/bgpd.c27
-rw-r--r--configure.ac3
-rw-r--r--doc/user/pim.rst77
-rw-r--r--doc/user/pimv6.rst47
-rw-r--r--isisd/isis_adjacency.c2
-rw-r--r--isisd/isis_lsp.c24
-rw-r--r--isisd/isis_nb_config.c7
-rw-r--r--isisd/isis_spf.c3
-rw-r--r--isisd/isisd.c10
-rw-r--r--lib/command.h2
-rw-r--r--lib/event.c50
-rw-r--r--lib/frrcu.h2
-rw-r--r--lib/hash.h12
-rw-r--r--lib/libfrr.h29
-rw-r--r--lib/libospf.h1
-rw-r--r--lib/linklist.h12
-rw-r--r--lib/openbsd-queue.h16
-rw-r--r--lib/openbsd-tree.h15
-rw-r--r--lib/seqlock.c33
-rw-r--r--nhrpd/nhrp_peer.c9
-rw-r--r--nhrpd/nhrp_vty.c8
-rw-r--r--ospfd/ospf_flood.c26
-rw-r--r--ospfd/ospf_flood.h23
-rw-r--r--ospfd/ospf_interface.c44
-rw-r--r--ospfd/ospf_interface.h17
-rw-r--r--ospfd/ospf_ism.c14
-rw-r--r--ospfd/ospf_main.c30
-rw-r--r--ospfd/ospf_packet.c243
-rw-r--r--ospfd/ospf_packet.h5
-rw-r--r--pimd/pim6_cmd.c1127
-rw-r--r--pimd/pim_addr.h2
-rw-r--r--pimd/pim_cmd.c2801
-rw-r--r--pimd/pim_cmd_common.c188
-rw-r--r--pimd/pim_cmd_common.h2
-rw-r--r--pimd/pim_instance.c21
-rw-r--r--pimd/pim_msdp.c18
-rw-r--r--pimd/pim_msdp.h11
-rw-r--r--pimd/pim_nb.h4
-rw-r--r--pimd/pim_rp.c13
-rw-r--r--pimd/pim_rp.h3
-rw-r--r--pimd/pim_vty.c68
-rw-r--r--ripd/ripd.c5
-rw-r--r--ripngd/ripngd.c5
-rw-r--r--staticd/static_zebra.c3
-rw-r--r--tests/lib/test_atomlist.c18
-rw-r--r--tests/lib/test_seqlock.c5
-rw-r--r--tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py2
-rw-r--r--tests/topotests/bgp_oad/test_bgp_oad.py2
-rw-r--r--tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json2
-rw-r--r--tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json2
-rw-r--r--tests/topotests/bgp_remote_as_auto/r1/frr.conf6
-rw-r--r--tests/topotests/bgp_remote_as_auto/r4/frr.conf10
-rw-r--r--tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py33
-rwxr-xr-xtests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py3
-rwxr-xr-xtests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py3
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py3
-rw-r--r--tests/topotests/bgp_vrf_different_asn/__init__.py0
-rw-r--r--tests/topotests/bgp_vrf_different_asn/r1/frr.conf18
-rw-r--r--tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py107
-rw-r--r--tests/topotests/isis_topo1/test_isis_topo1.py3
-rw-r--r--tests/topotests/lib/common_check.py27
-rw-r--r--tests/topotests/ospf_metric_propagation/r1/frr.conf6
-rw-r--r--tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json19
-rw-r--r--tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json19
-rw-r--r--tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json19
-rw-r--r--tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json19
-rw-r--r--tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json19
-rw-r--r--tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json19
-rw-r--r--tests/topotests/ospf_metric_propagation/r2/frr.conf6
-rw-r--r--tests/topotests/ospf_metric_propagation/r3/frr.conf6
-rw-r--r--tests/topotests/ospf_metric_propagation/r4/frr.conf6
-rw-r--r--tests/topotests/ospf_metric_propagation/ra/frr.conf6
-rw-r--r--tests/topotests/ospf_metric_propagation/rb/frr.conf6
-rw-r--r--tests/topotests/ospf_metric_propagation/rc/frr.conf4
-rw-r--r--tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py12
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py97
-rw-r--r--tests/topotests/rip_topo1/r1/show_ip_rip.ref5
-rw-r--r--tests/topotests/rip_topo1/r2/show_ip_rip.ref5
-rw-r--r--tests/topotests/rip_topo1/r3/show_ip_rip.ref5
-rw-r--r--tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref5
-rw-r--r--tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref5
-rw-r--r--tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref5
-rwxr-xr-xtools/frr-reload.py68
-rw-r--r--vtysh/vtysh.c92
-rw-r--r--vtysh/vtysh_config.c5
-rw-r--r--yang/frr-bfdd.yang3
-rw-r--r--yang/frr-eigrpd.yang2
-rw-r--r--yang/frr-zebra.yang1
-rw-r--r--zebra/interface.c36
-rw-r--r--zebra/zebra_dplane.c4
-rw-r--r--zebra/zebra_rib.c3
98 files changed, 4582 insertions, 1342 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 3096f47d5c..b6b437a791 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -410,8 +410,8 @@ static uint32_t ptm_bfd_gen_ID(void)
* random session identification numbers.
*/
do {
- session_id = ((frr_weak_random() << 16) & 0xFFFF0000)
- | (frr_weak_random() & 0x0000FFFF);
+ session_id = CHECK_FLAG((frr_weak_random() << 16), 0xFFFF0000) |
+ CHECK_FLAG(frr_weak_random(), 0x0000FFFF);
} while (session_id == 0 || bfd_id_lookup(session_id) != NULL);
return session_id;
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index f4ff884e00..be04e655ab 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -97,8 +97,9 @@ struct bfd_echo_pkt {
/* Macros for manipulating control packets */
#define BFD_VERMASK 0x07
#define BFD_DIAGMASK 0x1F
-#define BFD_GETVER(diag) ((diag >> 5) & BFD_VERMASK)
-#define BFD_SETVER(diag, val) ((diag) |= (val & BFD_VERMASK) << 5)
+#define BFD_GETVER(diag) (CHECK_FLAG((diag >> 5), BFD_VERMASK))
+#define BFD_SETVER(diag, val) \
+ SET_FLAG((diag), CHECK_FLAG(val, BFD_VERMASK) << 5)
#define BFD_VERSION 1
#define BFD_PBIT 0x20
#define BFD_FBIT 0x10
@@ -106,36 +107,36 @@ struct bfd_echo_pkt {
#define BFD_ABIT 0x04
#define BFD_DEMANDBIT 0x02
#define BFD_MBIT 0x01
-#define BFD_GETMBIT(flags) (flags & BFD_MBIT)
+#define BFD_GETMBIT(flags) (CHECK_FLAG(flags, BFD_MBIT))
#define BFD_SETDEMANDBIT(flags, val) \
{ \
if ((val)) \
- flags |= BFD_DEMANDBIT; \
+ SET_FLAG(flags, BFD_DEMANDBIT); \
}
#define BFD_SETPBIT(flags, val) \
{ \
if ((val)) \
- flags |= BFD_PBIT; \
+ SET_FLAG(flags, BFD_PBIT); \
}
-#define BFD_GETPBIT(flags) (flags & BFD_PBIT)
+#define BFD_GETPBIT(flags) (CHECK_FLAG(flags, BFD_PBIT))
#define BFD_SETFBIT(flags, val) \
{ \
if ((val)) \
- flags |= BFD_FBIT; \
+ SET_FLAG(flags, BFD_FBIT); \
}
-#define BFD_GETFBIT(flags) (flags & BFD_FBIT)
+#define BFD_GETFBIT(flags) (CHECK_FLAG(flags, BFD_FBIT))
#define BFD_SETSTATE(flags, val) \
{ \
if ((val)) \
- flags |= (val & 0x3) << 6; \
+ SET_FLAG(flags, (CHECK_FLAG(val, 0x3) << 6)); \
}
-#define BFD_GETSTATE(flags) ((flags >> 6) & 0x3)
+#define BFD_GETSTATE(flags) (CHECK_FLAG((flags >> 6), 0x3))
#define BFD_SETCBIT(flags, val) \
{ \
if ((val)) \
- flags |= val; \
+ SET_FLAG(flags, val); \
}
-#define BFD_GETCBIT(flags) (flags & BFD_CBIT)
+#define BFD_GETCBIT(flags) (CHECK_FLAG(flags, BFD_CBIT))
#define BFD_ECHO_VERSION 1
#define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt)
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 8110f434c2..f9397fa128 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -982,7 +982,7 @@ void bfd_recv_cb(struct event *t)
}
/* Save remote diagnostics before state switch. */
- bfd->remote_diag = cp->diag & BFD_DIAGMASK;
+ bfd->remote_diag = CHECK_FLAG(cp->diag, BFD_DIAGMASK);
/* Update remote timers settings. */
bfd->remote_timers.desired_min_tx = ntohl(cp->timers.desired_min_tx);
@@ -1738,7 +1738,7 @@ void bfd_peer_mac_set(int sd, struct bfd_session *bfd,
if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_MAC_SET))
return;
- if (ifp->flags & IFF_NOARP)
+ if (CHECK_FLAG(ifp->flags, IFF_NOARP))
return;
if (peer->sa_sin.sin_family == AF_INET) {
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 75a7d85e88..baf1d4ca6d 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -6333,16 +6333,16 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
{
struct bgp_dest *dest = NULL;
- uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head);
+ struct bgp_dest *dest_next = NULL;
- while (ann_count) {
- dest = zebra_announce_pop(&bm->zebra_announce_head);
- ann_count--;
+ for (dest = zebra_announce_first(&bm->zebra_announce_head); dest;
+ dest = dest_next) {
+ dest_next = zebra_announce_next(&bm->zebra_announce_head, dest);
if (dest->za_vpn == vpn) {
bgp_path_info_unlock(dest->za_bgp_pi);
bgp_dest_unlock_node(dest);
- } else
- zebra_announce_add_tail(&bm->zebra_announce_head, dest);
+ zebra_announce_del(&bm->zebra_announce_head, dest);
+ }
}
bgp_evpn_remote_ip_hash_destroy(vpn);
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 4625f15778..0fb59a94c2 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -651,6 +651,7 @@ void bgp_open_send(struct peer_connection *connection)
uint16_t send_holdtime;
as_t local_as;
struct peer *peer = connection->peer;
+ bool ext_opt_params = false;
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
send_holdtime = peer->holdtime;
@@ -677,15 +678,17 @@ void bgp_open_send(struct peer_connection *connection)
/* Set capabilities */
if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) {
- (void)bgp_open_capability(s, peer, true);
+ ext_opt_params = true;
+ (void)bgp_open_capability(s, peer, ext_opt_params);
} else {
struct stream *tmp = stream_new(STREAM_SIZE(s));
stream_copy(tmp, s);
- if (bgp_open_capability(tmp, peer, false)
- > BGP_OPEN_NON_EXT_OPT_LEN) {
+ if (bgp_open_capability(tmp, peer, ext_opt_params) >
+ BGP_OPEN_NON_EXT_OPT_LEN) {
stream_free(tmp);
- (void)bgp_open_capability(s, peer, true);
+ ext_opt_params = true;
+ (void)bgp_open_capability(s, peer, ext_opt_params);
} else {
stream_copy(s, tmp);
stream_free(tmp);
@@ -696,9 +699,10 @@ void bgp_open_send(struct peer_connection *connection)
bgp_packet_set_size(s);
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%pBP fd %d sending OPEN, version %d, my as %u, holdtime %d, id %pI4",
- peer, peer->connection->fd, BGP_VERSION_4, local_as,
- send_holdtime, &peer->local_id);
+ zlog_debug("%pBP fd %d sending OPEN%s, version %d, my as %u, holdtime %d, id %pI4",
+ peer, peer->connection->fd,
+ ext_opt_params ? " (Extended)" : "", BGP_VERSION_4,
+ local_as, send_holdtime, &peer->local_id);
/* Dump packet if debug option is set. */
/* bgp_packet_dump (s); */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 0ef1351835..bce8202377 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1701,6 +1701,10 @@ 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->vrf_flags, BGP_VRF_AUTO))
+ continue;
+
if (CHECK_FLAG(
tmp_bgp->af_flags[AFI_IP]
[SAFI_UNICAST],
@@ -10567,12 +10571,20 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
vrf_bgp = bgp_lookup_by_name(import_name);
if (!vrf_bgp) {
- if (strcmp(import_name, VRF_DEFAULT_NAME) == 0)
+ if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) {
vrf_bgp = bgp_default;
- else
+ } else {
/* Auto-create assuming the same AS */
ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type,
NULL, ASNOTATION_UNDEFINED);
+
+ /* Auto created VRF instances should be marked
+ * properly, otherwise we have a state after bgpd
+ * restart where VRF instance has default VRF's ASN.
+ */
+ SET_FLAG(vrf_bgp->vrf_flags, BGP_VRF_AUTO);
+ }
+
if (ret) {
vty_out(vty,
"VRF %s is not configured as a bgp instance\n",
@@ -12745,6 +12757,9 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
vty_out(vty, "{\n");
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+ continue;
+
nbr_output = true;
if (use_json) {
if (!is_first)
@@ -16130,6 +16145,9 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
vty_out(vty, "{\n");
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+ continue;
+
nbr_output = true;
if (use_json) {
if (!(json = json_object_new_object())) {
@@ -16689,6 +16707,9 @@ static int bgp_show_all_instance_route_leak_vty(struct vty *vty, afi_t afi,
if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
vrf_name = bgp->name;
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+ continue;
+
if (use_json) {
json_vrf = json_object_new_object();
} else {
@@ -16779,6 +16800,9 @@ static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
struct bgp *bgp;
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+ continue;
+
if (!uj)
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 3508f2d341..72620de7d9 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1556,7 +1556,6 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info,
struct peer *peer;
uint32_t metric;
route_tag_t tag;
- bool is_add;
uint32_t nhg_id = 0;
struct bgp_table *table = bgp_dest_table(dest);
const struct prefix *p = bgp_dest_get_prefix(dest);
@@ -1610,9 +1609,7 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info,
table->afi, table->safi, &nhg_id,
&metric, &tag, &allow_recursion);
- is_add = (valid_nh_count || nhg_id) ? true : false;
-
- if (is_add && CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) {
+ if (CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) {
struct bgp_zebra_opaque bzo = {};
const char *reason =
bgp_path_selection_reason2str(dest->reason);
@@ -1668,18 +1665,17 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info,
}
if (bgp_debug_zebra(p)) {
- zlog_debug("Tx route %s %s %pFX metric %u tag %" ROUTE_TAG_PRI
+ zlog_debug("Tx route add %s (table id %u) %pFX metric %u tag %" ROUTE_TAG_PRI
" count %d nhg %d",
- is_add ? "add" : "delete", bgp->name_pretty,
- &api.prefix, api.metric, api.tag, api.nexthop_num,
- nhg_id);
+ bgp->name_pretty, api.tableid, &api.prefix,
+ api.metric, api.tag, api.nexthop_num, nhg_id);
bgp_debug_zebra_nh(&api);
zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)",
__func__, p, (allow_recursion ? "" : "NOT "));
}
- return zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
- zclient, &api);
+
+ return zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
}
@@ -1761,8 +1757,8 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest,
}
if (bgp_debug_zebra(p))
- zlog_debug("Tx route delete %s %pFX", bgp->name_pretty,
- &api.prefix);
+ zlog_debug("Tx route delete %s (table id %u) %pFX",
+ bgp->name_pretty, api.tableid, &api.prefix);
return zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 3810413adc..476a01b8ef 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3936,21 +3936,34 @@ int bgp_delete(struct bgp *bgp)
safi_t safi;
int i;
struct bgp_dest *dest = NULL;
+ struct bgp_dest *dest_next = NULL;
+ struct bgp_table *dest_table = NULL;
struct graceful_restart_info *gr_info;
- uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head);
+ uint32_t cnt_before, cnt_after;
assert(bgp);
- while (ann_count) {
- dest = zebra_announce_pop(&bm->zebra_announce_head);
- ann_count--;
- if (dest->za_bgp_pi->peer->bgp == bgp) {
+ /*
+ * Iterate the pending dest list and remove all the dest pertaininig to
+ * the bgp under delete.
+ */
+ cnt_before = zebra_announce_count(&bm->zebra_announce_head);
+ for (dest = zebra_announce_first(&bm->zebra_announce_head); dest;
+ dest = dest_next) {
+ dest_next = zebra_announce_next(&bm->zebra_announce_head, dest);
+ dest_table = bgp_dest_table(dest);
+ if (dest_table->bgp == bgp) {
bgp_path_info_unlock(dest->za_bgp_pi);
bgp_dest_unlock_node(dest);
- } else
- zebra_announce_add_tail(&bm->zebra_announce_head, dest);
+ zebra_announce_del(&bm->zebra_announce_head, dest);
+ }
}
+ cnt_after = zebra_announce_count(&bm->zebra_announce_head);
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("Zebra Announce Fifo cleanup count before %u and after %u during BGP %s deletion",
+ cnt_before, cnt_after, bgp->name_pretty);
+
bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL);
/* make sure we withdraw any exported routes */
diff --git a/configure.ac b/configure.ac
index ec409aaf1d..59636194f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2913,7 +2913,8 @@ compiler : ${CC}
compiler flags : ${CFLAGS} ${WERROR} ${AC_CFLAGS} ${SAN_FLAGS}
make : ${MAKE-make}
linker flags : ${LDFLAGS} ${SAN_FLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM}
-state file directory : ${e_frr_runstatedir}
+local state file dir : ${e_frr_libstatedir}
+run state file dir : ${e_frr_runstatedir}
config file directory : ${e_frr_sysconfdir}
module directory : ${e_moduledir}
script directory : ${e_scriptdir}
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index b19bb9d1b3..90d37b2d7e 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -55,16 +55,22 @@ Certain signals have special meanings to *pimd*.
*pimd* invocation options. Common options that can be specified
(:ref:`common-invocation-options`).
-.. clicmd:: ip pim rp A.B.C.D A.B.C.D/M
+PIM Routers
+-----------
+
+.. clicmd:: router pim [vrf NAME]
+ Configure global PIM protocol
+
+.. clicmd:: rp A.B.C.D A.B.C.D/M
In order to use pim, it is necessary to configure a RP for join messages to
be sent to. Currently the only methodology to do this is via static rp
commands. All routers in the pim network must agree on these values. The
first ip address is the RP's address and the second value is the matching
prefix of group ranges covered. This command is vrf aware, to configure for
- a vrf, enter the vrf submode.
+ a vrf, specify the vrf in the router pim block.
-.. clicmd:: ip pim rp keep-alive-timer (1-65535)
+.. clicmd:: rp keep-alive-timer (1-65535)
Modify the time out value for a S,G flow from 1-65535 seconds at RP.
The normal keepalive period for the KAT(S,G) defaults to 210 seconds.
@@ -74,41 +80,41 @@ Certain signals have special meanings to *pimd*.
max(Keepalive_Period, RP_Keepalive_Period) when a Register-Stop is sent.
If choosing a value below 31 seconds be aware that some hardware platforms
cannot see data flowing in better than 30 second chunks. This command is
- vrf aware, to configure for a vrf, enter the vrf submode.
+ vrf aware, to configure for a vrf, specify the vrf in the router pim block.
-.. clicmd:: ip pim register-accept-list PLIST
+.. clicmd:: register-accept-list PLIST
When pim receives a register packet the source of the packet will be compared
to the prefix-list specified, PLIST, and if a permit is received normal
processing continues. If a deny is returned for the source address of the
register packet a register stop message is sent to the source.
-.. clicmd:: ip pim spt-switchover infinity-and-beyond [prefix-list PLIST]
+.. clicmd:: spt-switchover infinity-and-beyond [prefix-list PLIST]
On the last hop router if it is desired to not switch over to the SPT tree
configure this command. Optional parameter prefix-list can be use to control
which groups to switch or not switch. If a group is PERMIT as per the
PLIST, then the SPT switchover does not happen for it and if it is DENY,
then the SPT switchover happens.
- This command is vrf aware, to configure for a vrf,
- enter the vrf submode.
+ This command is vrf aware, to configure for a vrf, specify the vrf in the
+ router pim block.
-.. clicmd:: ip pim ecmp
+.. clicmd:: ecmp
If pim has the a choice of ECMP nexthops for a particular RPF, pim will
cause S,G flows to be spread out amongst the nexthops. If this command is
not specified then the first nexthop found will be used. This command is vrf
- aware, to configure for a vrf, enter the vrf submode.
+ aware, to configure for a vrf, specify the vrf in the router pim block.
-.. clicmd:: ip pim ecmp rebalance
+.. clicmd:: ecmp rebalance
If pim is using ECMP and an interface goes down, cause pim to rebalance all
S,G flows across the remaining nexthops. If this command is not configured
pim only modifies those S,G flows that were using the interface that went
- down. This command is vrf aware, to configure for a vrf, enter the vrf
- submode.
+ down. This command is vrf aware, to configure for a vrf, specify the vrf in
+ the router pim block.
-.. clicmd:: ip pim join-prune-interval (1-65535)
+.. clicmd:: join-prune-interval (1-65535)
Modify the join/prune interval that pim uses to the new value. Time is
specified in seconds. This command is vrf aware, to configure for a vrf,
@@ -116,39 +122,42 @@ Certain signals have special meanings to *pimd*.
a value smaller than 60 seconds be aware that this can and will affect
convergence at scale.
-.. clicmd:: ip pim keep-alive-timer (1-65535)
+.. clicmd:: keep-alive-timer (1-65535)
Modify the time out value for a S,G flow from 1-65535 seconds. If choosing
a value below 31 seconds be aware that some hardware platforms cannot see data
flowing in better than 30 second chunks. This command is vrf aware, to
- configure for a vrf, enter the vrf submode.
+ configure for a vrf, specify the vrf in the router pim block.
-.. clicmd:: ip pim packets (1-255)
+.. clicmd:: packets (1-255)
When processing packets from a neighbor process the number of packets
incoming at one time before moving on to the next task. The default value is
3 packets. This command is only useful at scale when you can possibly have
a large number of pim control packets flowing. This command is vrf aware, to
- configure for a vrf, enter the vrf submode.
+ configure for a vrf, specify the vrf in the router pim block.
-.. clicmd:: ip pim register-suppress-time (1-65535)
+.. clicmd:: register-suppress-time (1-65535)
Modify the time that pim will register suppress a FHR will send register
notifications to the kernel. This command is vrf aware, to configure for a
- vrf, enter the vrf submode.
+ vrf, specify the vrf in the router pim block.
-.. clicmd:: ip pim send-v6-secondary
+.. clicmd:: send-v6-secondary
When sending pim hello packets tell pim to send any v6 secondary addresses
on the interface. This information is used to allow pim to use v6 nexthops
in it's decision for RPF lookup. This command is vrf aware, to configure for
- a vrf, enter the vrf submode.
+ a vrf, specify the vrf in the router pim block.
-.. clicmd:: ip pim ssm prefix-list WORD
+.. clicmd:: ssm prefix-list WORD
Specify a range of group addresses via a prefix-list that forces pim to
- never do SM over. This command is vrf aware, to configure for a vrf, enter
- the vrf submode.
+ never do SM over. This command is vrf aware, to configure for a vrf, specify
+ the vrf in the router pim block.
+
+Global Multicast
+----------------
.. clicmd:: ip multicast rpf-lookup-mode WORD
@@ -334,11 +343,12 @@ MSDP can be setup in different ways:
.. note::
MSDP default peer and SA filtering is not implemented.
+ MSDP configuration is available under 'router pim'
Commands available for MSDP:
-.. clicmd:: ip msdp timers (1-65535) (1-65535) [(1-65535)]
+.. clicmd:: msdp timers (1-65535) (1-65535) [(1-65535)]
Configure global MSDP timers.
@@ -354,16 +364,16 @@ Commands available for MSDP:
configures the interval between connection attempts. The default value
is 30 seconds.
-.. clicmd:: ip msdp mesh-group WORD member A.B.C.D
+.. clicmd:: msdp mesh-group WORD member A.B.C.D
Create or update a mesh group to include the specified MSDP peer.
-.. clicmd:: ip msdp mesh-group WORD source A.B.C.D
+.. clicmd:: msdp mesh-group WORD source A.B.C.D
Create or update a mesh group to set the source address used to connect to
peers.
-.. clicmd:: ip msdp peer A.B.C.D source A.B.C.D
+.. clicmd:: msdp peer A.B.C.D source A.B.C.D
Create a regular MSDP session with peer using the specified source address.
@@ -576,11 +586,11 @@ cause great confusion.
Display current bsr, its uptime and last received bsm age.
-.. clicmd:: show ip pim bsrp-info
+.. clicmd:: show ip pim bsrp-info [vrf NAME] [json]
Display group-to-rp mappings received from E-BSR.
-.. clicmd:: show ip pim bsm-database
+.. clicmd:: show ip pim bsm-database [vrf NAME] [json]
Display all fragments of stored bootstrap message in user readable format.
@@ -734,8 +744,9 @@ Sample configuration
! You may want to enable ssmpingd for troubleshooting
! See http://www.venaas.no/multicast/ssmping/
!
- ip ssmpingd 1.1.1.1
- ip ssmpingd 2.2.2.2
+ router pim
+ ssmpingd 1.1.1.1
+ ssmpingd 2.2.2.2
! HINTS:
! - Enable "ip pim ssm" on the interface directly attached to the
diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst
index b8567e4863..edf7a82015 100644
--- a/doc/user/pimv6.rst
+++ b/doc/user/pimv6.rst
@@ -47,21 +47,28 @@ Certain signals have special meanings to *pim6d*.
*pim6d* invocation options. Common options that can be specified
(:ref:`common-invocation-options`).
-.. clicmd:: ipv6 pim rp X:X::X:X Y:Y::Y:Y/M
+PIMv6 Router
+------------
+
+.. clicmd:: router pim6 [vrf NAME]
+
+ Configure the global PIMv6 protocol
+
+.. clicmd:: rp X:X::X:X Y:Y::Y:Y/M
In order to use pimv6, it is necessary to configure a RP for join messages to
be sent to. Currently the only methodology to do this is via static rp
commands. All routers in the pimv6 network must agree on these values. The
first ipv6 address is the RP's address and the second value is the matching
prefix of group ranges covered. This command is vrf aware, to configure for
- a vrf, enter the vrf submode.
+ a vrf, specify the vrf in the router pim6 block.
-.. clicmd:: ipv6 pim rp X:X::X:X prefix-list WORD
+.. clicmd:: rp X:X::X:X prefix-list WORD
This CLI helps in configuring RP address for a range of groups specified
by the prefix-list.
-.. clicmd:: ipv6 pim rp keep-alive-timer (1-65535)
+.. clicmd:: rp keep-alive-timer (1-65535)
Modify the time out value for a S,G flow from 1-65535 seconds at RP.
The normal keepalive period for the KAT(S,G) defaults to 210 seconds.
@@ -71,19 +78,19 @@ Certain signals have special meanings to *pim6d*.
max(Keepalive_Period, RP_Keepalive_Period) when a Register-Stop is sent.
If choosing a value below 31 seconds be aware that some hardware platforms
cannot see data flowing in better than 30 second chunks. This command is
- vrf aware, to configure for a vrf, enter the vrf submode.
+ vrf aware, to configure for a vrf, specify the vrf in the router pim6 block.
-.. clicmd:: ipv6 pim spt-switchover infinity-and-beyond [prefix-list PLIST]
+.. clicmd:: spt-switchover infinity-and-beyond [prefix-list PLIST]
On the last hop router if it is desired to not switch over to the SPT tree
configure this command. Optional parameter prefix-list can be use to control
which groups to switch or not switch. If a group is PERMIT as per the
PLIST, then the SPT switchover does not happen for it and if it is DENY,
then the SPT switchover happens.
- This command is vrf aware, to configure for a vrf,
- enter the vrf submode.
+ This command is vrf aware, to configure for a vrf, specify the vrf in the
+ router pim6 block.
-.. clicmd:: ipv6 pim join-prune-interval (1-65535)
+.. clicmd:: join-prune-interval (1-65535)
Modify the join/prune interval that pim uses to the new value. Time is
specified in seconds. This command is vrf aware, to configure for a vrf,
@@ -91,28 +98,28 @@ Certain signals have special meanings to *pim6d*.
a value smaller than 60 seconds be aware that this can and will affect
convergence at scale.
-.. clicmd:: ipv6 pim keep-alive-timer (1-65535)
+.. clicmd:: keep-alive-timer (1-65535)
Modify the time out value for a S,G flow from 1-65535 seconds. If choosing
a value below 31 seconds be aware that some hardware platforms cannot see data
flowing in better than 30 second chunks. This command is vrf aware, to
- configure for a vrf, enter the vrf submode.
+ configure for a vrf, specify the vrf in the router pim6 block.
-.. clicmd:: ipv6 pim packets (1-255)
+.. clicmd:: packets (1-255)
When processing packets from a neighbor process the number of packets
incoming at one time before moving on to the next task. The default value is
3 packets. This command is only useful at scale when you can possibly have
a large number of pim control packets flowing. This command is vrf aware, to
- configure for a vrf, enter the vrf submode.
+ configure for a vrf, specify the vrf in the router pim6 block.
-.. clicmd:: ipv6 pim register-suppress-time (1-65535)
+.. clicmd:: register-suppress-time (1-65535)
Modify the time that pim will register suppress a FHR will send register
notifications to the kernel. This command is vrf aware, to configure for a
- vrf, enter the vrf submode.
+ vrf, specify the vrf in the router pim6 block.
-.. clicmd:: ipv6 ssmpingd [X:X::X:X]
+.. clicmd:: ssmpingd [X:X::X:X]
Enable ipv6 ssmpingd configuration. A network level management tool
to check whether one can receive multicast packets via SSM from host.
@@ -388,11 +395,11 @@ General multicast routing state
Display current bsr, its uptime and last received bsm age.
-.. clicmd:: show ipv6 pim bsrp-info
+.. clicmd:: show ipv6 pim bsrp-info [vrf NAME] [json]
Display group-to-rp mappings received from E-BSR.
-.. clicmd:: show ipv6 pim bsm-database
+.. clicmd:: show ipv6 pim bsm-database [vrf NAME] [json]
Display all fragments of stored bootstrap message in user readable format.
@@ -417,7 +424,7 @@ Clear commands reset various variables.
.. clicmd:: clear ipv6 pim [vrf NAME] interface traffic
- When this command is issued, resets the information about the
+ When this command is issued, resets the information about the
number of PIM protocol packets sent/received on an interface.
.. clicmd:: clear ipv6 pim oil
@@ -494,7 +501,7 @@ the config was written out.
.. clicmd:: debug mld trace [detail]
- This traces mld code and how it is running.
+ This traces mld code and how it is running.
.. clicmd:: debug pimv6 bsm
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index b81a0cc2f0..3ed6fe95f5 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -293,7 +293,7 @@ const char *isis_adj_name(const struct isis_adjacency *adj)
struct isis_dynhn *dyn;
dyn = dynhn_find_by_id(adj->circuit->isis, adj->sysid);
- if (dyn)
+ if (adj->circuit->area->dynhostname && dyn)
return dyn->hostname;
snprintfrr(buf, sizeof(buf), "%pSY", adj->sysid);
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 13f5148d4a..bda7ed89a4 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -482,13 +482,19 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
lsp->tlvs = tlvs;
- if (area->dynhostname && lsp->tlvs->hostname
- && lsp->hdr.rem_lifetime) {
- isis_dynhn_insert(
- area->isis, lsp->hdr.lsp_id, lsp->tlvs->hostname,
- (lsp->hdr.lsp_bits & LSPBIT_IST) == IS_LEVEL_1_AND_2
- ? IS_LEVEL_2
- : IS_LEVEL_1);
+ if (area->dynhostname && lsp->hdr.rem_lifetime) {
+ if (lsp->tlvs->hostname) {
+ isis_dynhn_insert(area->isis, lsp->hdr.lsp_id,
+ lsp->tlvs->hostname,
+ (lsp->hdr.lsp_bits & LSPBIT_IST) ==
+ IS_LEVEL_1_AND_2
+ ? IS_LEVEL_2
+ : IS_LEVEL_1);
+ } else {
+ if (!LSP_PSEUDO_ID(lsp->hdr.lsp_id) &&
+ !LSP_FRAGMENT(lsp->hdr.lsp_id))
+ isis_dynhn_remove(area->isis, lsp->hdr.lsp_id);
+ }
}
return;
@@ -2220,6 +2226,10 @@ void lsp_tick(struct event *thread)
&area->lspdb[level],
next);
+ if (!LSP_PSEUDO_ID(lsp->hdr.lsp_id))
+ isis_dynhn_remove(area->isis,
+ lsp->hdr.lsp_id);
+
lspdb_del(&area->lspdb[level], lsp);
lsp_destroy(lsp);
lsp = NULL;
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 30c90baa54..8926b624ea 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -252,11 +252,12 @@ int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args)
return NB_ERR_INCONSISTENCY;
listnode_delete(area->area_addrs, addrp);
- XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
/*
* Last area address - reset the SystemID for this router
*/
- if (listcount(area->area_addrs) == 0) {
+ if (!memcmp(addrp->area_addr + addrp->addr_len, area->isis->sysid,
+ ISIS_SYS_ID_LEN) &&
+ listcount(area->area_addrs) == 0) {
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit))
for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) {
if (circuit->u.bc.is_dr[lvl - 1])
@@ -268,6 +269,8 @@ int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args)
zlog_debug("Router has no SystemID");
}
+ XFREE(MTYPE_ISIS_AREA_ADDR, addrp);
+
return NB_OK;
}
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 7aa9147e71..86302076f8 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -873,6 +873,9 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree,
|| (mt_router_info && !mt_router_info->overload));
lspfragloop:
+ if (!lsp->tlvs)
+ return ISIS_OK;
+
if (lsp->hdr.seqno == 0) {
zlog_warn("%s: lsp with 0 seq_num - ignore", __func__);
return ISIS_WARNING;
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 982df0839b..8db6295b66 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -496,6 +496,7 @@ void isis_area_destroy(struct isis_area *area)
{
struct listnode *node, *nnode;
struct isis_circuit *circuit;
+ struct iso_address *addr;
QOBJ_UNREG(area);
@@ -545,6 +546,15 @@ void isis_area_destroy(struct isis_area *area)
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
isis_redist_area_finish(area);
+ if (listcount(area->area_addrs) > 0) {
+ addr = listgetdata(listhead(area->area_addrs));
+ if (!memcmp(addr->area_addr + addr->addr_len, area->isis->sysid,
+ ISIS_SYS_ID_LEN)) {
+ memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 0;
+ }
+ }
+
list_delete(&area->area_addrs);
for (int i = SPF_PREFIX_PRIO_CRITICAL; i <= SPF_PREFIX_PRIO_MEDIUM;
diff --git a/lib/command.h b/lib/command.h
index 6f819c7e36..57e3b9cda0 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -182,6 +182,8 @@ enum node_type {
ISIS_SRV6_NODE_MSD_NODE, /* ISIS SRv6 Node MSDs node */
MGMTD_NODE, /* MGMTD node. */
RPKI_VRF_NODE, /* RPKI node for VRF */
+ PIM_NODE, /* PIM protocol mode */
+ PIM6_NODE, /* PIM protocol for IPv6 mode */
NODE_TYPE_MAX, /* maximum */
};
/* clang-format on */
diff --git a/lib/event.c b/lib/event.c
index fc46a11c0b..f4aa7c58b9 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -304,9 +304,6 @@ static uint8_t parse_filter(const char *filterstr)
return filter;
}
-#if CONFDATE > 20240707
- CPP_NOTICE("Remove `show thread ...` commands")
-#endif
DEFUN_NOSH (show_event_cpu,
show_event_cpu_cmd,
"show event cpu [FILTER]",
@@ -332,14 +329,6 @@ DEFUN_NOSH (show_event_cpu,
return CMD_SUCCESS;
}
-ALIAS(show_event_cpu,
- show_thread_cpu_cmd,
- "show thread cpu [FILTER]",
- SHOW_STR
- "Thread information\n"
- "Thread CPU usage\n"
- "Display filter (rwtex)\n")
-
DEFPY (service_cputime_stats,
service_cputime_stats_cmd,
"[no] service cputime-stats",
@@ -440,19 +429,15 @@ DEFUN_NOSH (show_event_poll,
return CMD_SUCCESS;
}
-ALIAS(show_event_poll,
- show_thread_poll_cmd,
- "show thread poll",
- SHOW_STR
- "Thread information\n"
- "Show poll FD's and information\n")
-
-DEFUN (clear_thread_cpu,
- clear_thread_cpu_cmd,
- "clear thread cpu [FILTER]",
+#if CONFDATE > 20241231
+CPP_NOTICE("Remove `clear thread cpu` command")
+#endif
+DEFUN (clear_event_cpu,
+ clear_event_cpu_cmd,
+ "clear event cpu [FILTER]",
"Clear stored data in all pthreads\n"
- "Thread information\n"
- "Thread CPU usage\n"
+ "Event information\n"
+ "Event CPU usage\n"
"Display filter (rwtexb)\n")
{
uint8_t filter = (uint8_t)-1U;
@@ -472,6 +457,14 @@ DEFUN (clear_thread_cpu,
return CMD_SUCCESS;
}
+ALIAS (clear_event_cpu,
+ clear_thread_cpu_cmd,
+ "clear thread cpu [FILTER]",
+ "Clear stored data in all pthreads\n"
+ "Thread information\n"
+ "Thread CPU usage\n"
+ "Display filter (rwtexb)\n")
+
static void show_event_timers_helper(struct vty *vty, struct event_loop *m)
{
const char *name = m->name ? m->name : "main";
@@ -507,26 +500,17 @@ DEFPY_NOSH (show_event_timers,
return CMD_SUCCESS;
}
-ALIAS(show_event_timers,
- show_thread_timers_cmd,
- "show thread timers",
- SHOW_STR
- "Thread information\n"
- "Show all timers and how long they have in the system\n")
-
void event_cmd_init(void)
{
- install_element(VIEW_NODE, &show_thread_cpu_cmd);
install_element(VIEW_NODE, &show_event_cpu_cmd);
- install_element(VIEW_NODE, &show_thread_poll_cmd);
install_element(VIEW_NODE, &show_event_poll_cmd);
install_element(ENABLE_NODE, &clear_thread_cpu_cmd);
+ install_element(ENABLE_NODE, &clear_event_cpu_cmd);
install_element(CONFIG_NODE, &service_cputime_stats_cmd);
install_element(CONFIG_NODE, &service_cputime_warning_cmd);
install_element(CONFIG_NODE, &service_walltime_warning_cmd);
- install_element(VIEW_NODE, &show_thread_timers_cmd);
install_element(VIEW_NODE, &show_event_timers_cmd);
}
/* CLI end ------------------------------------------------------------------ */
diff --git a/lib/frrcu.h b/lib/frrcu.h
index 9f07a69b52..81ab5528a9 100644
--- a/lib/frrcu.h
+++ b/lib/frrcu.h
@@ -156,7 +156,7 @@ extern void rcu_enqueue(struct rcu_head *head, const struct rcu_action *action);
#define rcu_call(func, ptr, field) \
do { \
typeof(ptr) _ptr = (ptr); \
- void (*fptype)(typeof(ptr)); \
+ void (*_fptype)(typeof(ptr)); \
struct rcu_head *_rcu_head = &_ptr->field; \
static const struct rcu_action _rcu_action = { \
.type = RCUA_CALL, \
diff --git a/lib/hash.h b/lib/hash.h
index 2d00a334be..efa7011bc2 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -13,6 +13,18 @@
extern "C" {
#endif
+/*
+ * NOTICE:
+ *
+ * If you are reading this file in an effort to add a new hash structure
+ * this is the wrong place to be using it. Please see the typesafe
+ * data structures, or ask one of the other developers.
+ *
+ * If you are reading this file as a way to update an existing usage
+ * of this data structure, please consider just converting the data
+ * structure to one of the typesafe data structures instead.
+ */
+
/* Default hash table size. */
#define HASH_INITIAL_SIZE 256
/* Expansion threshold */
diff --git a/lib/libfrr.h b/lib/libfrr.h
index db9cfbcb1f..8018672c1a 100644
--- a/lib/libfrr.h
+++ b/lib/libfrr.h
@@ -222,10 +222,39 @@ extern void frr_fini(void);
extern char config_default[512];
extern char frr_zclientpath[512];
+
+/* refer to lib/config_paths.h (generated during ./configure) for build config
+ * values of the following:
+ */
+
+/* sysconfdir is generally /etc/frr/, some BSDs may use /usr/local/etc/frr/.
+ * Will NOT include "pathspace" (namespace) suffix from -N. (libfrr.c handles
+ * pathspace'ing config files.) Has a slash at the end for "historical"
+ * reasons.
+ */
extern const char frr_sysconfdir[];
+
+/* runstatedir is *ephemeral* across reboots. It may either be a ramdisk,
+ * or be wiped during boot. Use only for pid files, sockets, and the like,
+ * not state. Commonly /run/frr or /var/run/frr.
+ * Will include "pathspace" (namespace) suffix from -N.
+ */
extern char frr_runstatedir[256];
+
+/* libstatedir is *persistent*. It's the place to put state like sequence
+ * numbers or databases. Commonly /var/lib/frr.
+ * Will include "pathspace" (namespace) suffix from -N.
+ */
extern char frr_libstatedir[256];
+
+/* moduledir is something along the lines of /usr/lib/frr/modules or
+ * /usr/lib/x86_64-linux-gnu/frr/modules. It is not guaranteed to be a
+ * subdirectory of the directory that the daemon binaries reside in. (e.g.
+ * the "x86_64-linux-gnu" component will be absent from daemon paths.)
+ */
extern const char frr_moduledir[];
+
+/* scriptdir is for Lua scripts, generally ${frr_sysconfdir}/scripts */
extern const char frr_scriptdir[];
extern char frr_protoname[];
diff --git a/lib/libospf.h b/lib/libospf.h
index f2dc5d61d9..8a208beb3c 100644
--- a/lib/libospf.h
+++ b/lib/libospf.h
@@ -61,6 +61,7 @@ extern "C" {
#define OSPF_RETRANSMIT_WINDOW_DEFAULT 50 /* milliseconds */
#define OSPF_TRANSMIT_DELAY_DEFAULT 1
#define OSPF_DEFAULT_BANDWIDTH 10000 /* Mbps */
+#define OSPF_ACK_DELAY_DEFAULT 1
#define OSPF_DEFAULT_REF_BANDWIDTH 100000 /* Kbps */
diff --git a/lib/linklist.h b/lib/linklist.h
index fd953d0769..f922891df9 100644
--- a/lib/linklist.h
+++ b/lib/linklist.h
@@ -10,6 +10,18 @@
extern "C" {
#endif
+/*
+ * NOTICE:
+ *
+ * If you are reading this file in an effort to add a new list structure
+ * this is the wrong place to be using it. Please see the typesafe
+ * data structures, or ask one of the other developers.
+ *
+ * If you are reading this file as a way to update an existing usage
+ * of this data structure, please consider just converting the data
+ * structure to one of the typesafe data structures instead.
+ */
+
/* listnodes must always contain data to be valid. Adding an empty node
* to a list is invalid
*/
diff --git a/lib/openbsd-queue.h b/lib/openbsd-queue.h
index df3bbd720f..a2df521f58 100644
--- a/lib/openbsd-queue.h
+++ b/lib/openbsd-queue.h
@@ -17,6 +17,22 @@ extern "C" {
#endif
/*
+ * NOTICE:
+ *
+ * If you are reading this file in an effort to add a new queue structure
+ * this is the wrong place to be using it. Please see the typesafe
+ * data structures, or ask one of the other developers.
+ *
+ * If you are reading this file as a way to update an existing usage
+ * of this data structure, please consider just converting the data
+ * structure to one of the typesafe data structures instead. However,
+ * among converting datastrucutres, the the BSD ones are the lowest
+ * priority / should be converted last. They are already typesafe and
+ * use inline linking nodes, so the only gain is consistency. Please
+ * convert uses of linklist.h and hash.h first.
+ */
+
+/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues and XOR simple queues.
*
diff --git a/lib/openbsd-tree.h b/lib/openbsd-tree.h
index 4f3985bbca..ecc3a68f15 100644
--- a/lib/openbsd-tree.h
+++ b/lib/openbsd-tree.h
@@ -10,6 +10,21 @@
#ifdef __cplusplus
extern "C" {
#endif
+/*
+ * NOTICE:
+ *
+ * If you are reading this file in an effort to add a new tree structure
+ * this is the wrong place to be using it. Please see the typesafe
+ * data structures, or ask one of the other developers.
+ *
+ * If you are reading this file as a way to update an existing usage
+ * of this data structure, please consider just converting the data
+ * structure to one of the typesafe data structures instead. However,
+ * among converting datastrucutres, the the BSD ones are the lowest
+ * priority / should be converted last. They are already typesafe and
+ * use inline linking nodes, so the only gain is consistency. Please
+ * convert uses of linklist.h and hash.h first.
+ */
/*
* This file defines data structures for different types of trees:
diff --git a/lib/seqlock.c b/lib/seqlock.c
index 62ce316920..e74e6718bf 100644
--- a/lib/seqlock.c
+++ b/lib/seqlock.c
@@ -26,6 +26,39 @@
* OS specific synchronization wrappers *
****************************************/
+#ifndef __has_feature /* not available on old GCC */
+#define __has_feature(x) 0
+#endif
+
+#if (defined(__SANITIZE_THREAD__) || __has_feature(thread_sanitizer))
+/* TSAN really does not understand what is going on with the low-level
+ * futex/umtx calls. This leads to a whole bunch of warnings, a lot of which
+ * also have _extremely_ misleading text - since TSAN does not understand that
+ * there is in fact a synchronization primitive involved, it can end up pulling
+ * in completely unrelated things.
+ *
+ * What does work is the "unsupported platform" seqlock implementation based
+ * on a pthread mutex + condvar, since TSAN of course suppports these.
+ *
+ * It may be possible to also fix this with TSAN annotations (__tsan_acquire
+ * and __tsan_release), but using those (correctly) is not easy either, and
+ * for now just get things rolling.
+ */
+
+#ifdef HAVE_SYNC_LINUX_FUTEX
+#undef HAVE_SYNC_LINUX_FUTEX
+#endif
+
+#ifdef HAVE_SYNC_OPENBSD_FUTEX
+#undef HAVE_SYNC_OPENBSD_FUTEX
+#endif
+
+#ifdef HAVE_SYNC_UMTX_OP
+#undef HAVE_SYNC_UMTX_OP
+#endif
+
+#endif /* TSAN */
+
/*
* Linux: sys_futex()
*/
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 2414541bfa..0407b86be8 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -1046,6 +1046,13 @@ static void nhrp_peer_forward(struct nhrp_peer *p,
zbuf_put(zb, extpl.head, len);
}
break;
+ case NHRP_EXTENSION_AUTHENTICATION:
+ /* At this point, received packet has been authenticated.
+ * Just need to regenerate auth extension before forwarding.
+ * This will be done below in nhrp_packet_complete_auth().
+ */
+ break;
+
default:
if (htons(ext->type) & NHRP_EXTENSION_FLAG_COMPULSORY)
/* FIXME: RFC says to just copy, but not
@@ -1064,7 +1071,7 @@ static void nhrp_peer_forward(struct nhrp_peer *p,
nhrp_ext_complete(zb, dst);
}
- nhrp_packet_complete_auth(zb, hdr, pp->ifp, false);
+ nhrp_packet_complete_auth(zb, hdr, pp->ifp, true);
nhrp_peer_send(p, zb);
zbuf_free(zb);
zbuf_free(zb_copy);
diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c
index b938ae4cf0..22b6bdcec7 100644
--- a/nhrpd/nhrp_vty.c
+++ b/nhrpd/nhrp_vty.c
@@ -481,8 +481,10 @@ DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd,
return CMD_WARNING_CONFIG_FAILED;
}
- if (nifp->auth_token)
+ if (nifp->auth_token) {
zbuf_free(nifp->auth_token);
+ nifp->auth_token = NULL;
+ }
nifp->auth_token = zbuf_alloc(pass_len + sizeof(uint32_t));
auth = (struct nhrp_cisco_authentication_extension *)
@@ -505,8 +507,10 @@ DEFPY(if_no_nhrp_authentication, if_no_nhrp_authentication_cmd,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct nhrp_interface *nifp = ifp->info;
- if (nifp->auth_token)
+ if (nifp->auth_token) {
zbuf_free(nifp->auth_token);
+ nifp->auth_token = NULL;
+ }
return CMD_SUCCESS;
}
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index e9797ce935..2af4ae3170 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -110,6 +110,9 @@ void ospf_area_update_fr_state(struct ospf_area *area)
static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr,
struct ospf_lsa *lsa)
{
+ struct ospf_lsa_list_entry *ls_ack_list_entry;
+ struct ospf_interface *oi = inbr->oi;
+
/* LSA is more recent than database copy, but was not
flooded back out receiving interface. Delayed
acknowledgment sent. If interface is in Backup state
@@ -122,12 +125,27 @@ static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr,
worked out previously */
/* Deal with router as BDR */
- if (inbr->oi->state == ISM_Backup && !NBR_IS_DR(inbr))
+ if (oi->state == ISM_Backup && !NBR_IS_DR(inbr))
return;
- /* Schedule a delayed LSA Ack to be sent */
- listnode_add(inbr->oi->ls_ack,
- ospf_lsa_lock(lsa)); /* delayed LSA Ack */
+ if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
+ zlog_debug("%s:Add LSA[Type%d:%pI4:%pI4]: seq 0x%x age %u NBR %pI4 (%s) ack queue",
+ __func__, lsa->data->type, &lsa->data->id,
+ &lsa->data->adv_router, ntohl(lsa->data->ls_seqnum),
+ ntohs(lsa->data->ls_age), &inbr->router_id,
+ IF_NAME(inbr->oi));
+
+ /* Add the LSA to the interface delayed Ack list. */
+ ls_ack_list_entry = XCALLOC(MTYPE_OSPF_LSA_LIST,
+ sizeof(struct ospf_lsa_list_entry));
+ ls_ack_list_entry->lsa = ospf_lsa_lock(lsa);
+ ospf_lsa_list_add_tail(&oi->ls_ack_delayed, ls_ack_list_entry);
+
+ /* Set LS Ack timer if it is not already scheduled. */
+ if (!oi->t_ls_ack_delayed)
+ OSPF_ISM_TIMER_ON(oi->t_ls_ack_delayed,
+ ospf_ls_ack_delayed_timer,
+ oi->v_ls_ack_delayed);
}
/* Check LSA is related to external info. */
diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h
index d9d9537351..2412052970 100644
--- a/ospfd/ospf_flood.h
+++ b/ospfd/ospf_flood.h
@@ -7,6 +7,8 @@
#ifndef _ZEBRA_OSPF_FLOOD_H
#define _ZEBRA_OSPF_FLOOD_H
+#include "typesafe.h"
+
/*
* OSPF Temporal LSA List
*/
@@ -16,14 +18,25 @@ struct ospf_lsa_list_entry {
/* Linkage for LSA List */
struct ospf_lsa_list_item list_linkage;
- /*
- * Time associated with the list entry. For example, for a neigbhor
- * link retransmission list, this is the retransmission time.
- */
- struct timeval list_entry_time;
+ union {
+ /*
+ * Time associated with the list entry. For example, for a
+ * neigbhor link retransmission list, this is the
+ * retransmission time.
+ */
+ struct timeval list_entry_timeval;
+
+ /*
+ * Destanation address specific to the LSA list. For example,
+ * the distination for an associated direct LS acknowledgment.
+ */
+ struct in_addr list_entry_dst_addr;
+ } u;
struct ospf_lsa *lsa;
};
+#define list_entry_time u.list_entry_timeval
+#define list_entry_dst u.list_entry_dst_addr
DECLARE_DLIST(ospf_lsa_list, struct ospf_lsa_list_entry, list_linkage);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 803c36861d..c4210eb70c 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -186,10 +186,12 @@ static void ospf_if_default_variables(struct ospf_interface *oi)
oi->crypt_seqnum = 0;
- /* This must be short, (less than RxmtInterval)
- - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being
- held back for too long - MAG */
- oi->v_ls_ack = 1;
+ /*
+ * The OSPF LS ACK Delay timer must be less than the LS Retransmision
+ * timer. As per RFC 2328 Section 13.5 paragraph 3, Set to 1 second
+ * to avoid Acks being held back for too long
+ */
+ oi->v_ls_ack_delayed = OSPF_ACK_DELAY_DEFAULT;
}
/* lookup oi for specified prefix/ifp */
@@ -272,9 +274,9 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
/* Initialize static neighbor list. */
oi->nbr_nbma = list_new();
- /* Initialize Link State Acknowledgment list. */
- oi->ls_ack = list_new();
- oi->ls_ack_direct.ls_ack = list_new();
+ /* Initialize Link State Acknowledgment lists. */
+ ospf_lsa_list_init(&oi->ls_ack_delayed);
+ ospf_lsa_list_init(&oi->ls_ack_direct);
/* Set default values. */
ospf_if_default_variables(oi);
@@ -306,6 +308,22 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
return oi;
}
+/*
+ * Cleanup Interface Ack List
+ */
+static void ospf_if_cleanup_ack_list(struct ospf_lsa_list_head *ls_ack_list)
+{
+ struct ospf_lsa_list_entry *ls_ack_list_entry;
+ struct ospf_lsa *lsa;
+
+ frr_each_safe (ospf_lsa_list, ls_ack_list, ls_ack_list_entry) {
+ lsa = ls_ack_list_entry->lsa;
+ ospf_lsa_list_del(ls_ack_list, ls_ack_list_entry);
+ XFREE(MTYPE_OSPF_LSA_LIST, ls_ack_list_entry);
+ ospf_lsa_unlock(&lsa);
+ }
+}
+
/* Restore an interface to its pre UP state
Used from ism_interface_down only */
void ospf_if_cleanup(struct ospf_interface *oi)
@@ -314,7 +332,6 @@ void ospf_if_cleanup(struct ospf_interface *oi)
struct listnode *node, *nnode;
struct ospf_neighbor *nbr;
struct ospf_nbr_nbma *nbr_nbma;
- struct ospf_lsa *lsa;
/* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
/* delete all static neighbors attached to this interface */
@@ -338,10 +355,9 @@ void ospf_if_cleanup(struct ospf_interface *oi)
OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
}
- /* Cleanup Link State Acknowlegdment list. */
- for (ALL_LIST_ELEMENTS(oi->ls_ack, node, nnode, lsa))
- ospf_lsa_unlock(&lsa); /* oi->ls_ack */
- list_delete_all_node(oi->ls_ack);
+ /* Cleanup Link State Delayed Acknowlegdment list. */
+ ospf_if_cleanup_ack_list(&oi->ls_ack_delayed);
+ ospf_if_cleanup_ack_list(&oi->ls_ack_direct);
oi->crypt_seqnum = 0;
@@ -377,8 +393,8 @@ void ospf_if_free(struct ospf_interface *oi)
/* Free any lists that should be freed */
list_delete(&oi->nbr_nbma);
- list_delete(&oi->ls_ack);
- list_delete(&oi->ls_ack_direct.ls_ack);
+ ospf_if_cleanup_ack_list(&oi->ls_ack_delayed);
+ ospf_if_cleanup_ack_list(&oi->ls_ack_direct);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf interface %s vrf %s id %u deleted",
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index a944847b5d..78a4fb9e59 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -13,6 +13,7 @@
#include "keychain.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_spf.h"
+#include <ospfd/ospf_flood.h>
#define IF_OSPF_IF_INFO(I) ((struct ospf_if_info *)((I)->info))
#define IF_DEF_PARAMS(I) (IF_OSPF_IF_INFO (I)->def_params)
@@ -265,20 +266,20 @@ struct ospf_interface {
struct route_table *ls_upd_queue;
- struct list *ls_ack; /* Link State Acknowledgment list. */
-
- struct {
- struct list *ls_ack;
- struct in_addr dst;
- } ls_ack_direct;
+ /*
+ * List of LSAs for delayed and direct link
+ * state acknowledgment transmission.
+ */
+ struct ospf_lsa_list_head ls_ack_delayed;
+ struct ospf_lsa_list_head ls_ack_direct;
/* Timer values. */
- uint32_t v_ls_ack; /* Delayed Link State Acknowledgment */
+ uint32_t v_ls_ack_delayed; /* Delayed Link State Acknowledgment */
/* Threads. */
struct event *t_hello; /* timer */
struct event *t_wait; /* timer */
- struct event *t_ls_ack; /* timer */
+ struct event *t_ls_ack_delayed; /* timer */
struct event *t_ls_ack_direct; /* event */
struct event *t_ls_upd_event; /* event */
struct event *t_opaque_lsa_self; /* Type-9 Opaque-LSAs */
diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c
index 878ab725bd..377e7a6bcc 100644
--- a/ospfd/ospf_ism.c
+++ b/ospfd/ospf_ism.c
@@ -285,7 +285,7 @@ static void ism_timer_set(struct ospf_interface *oi)
reset also. */
EVENT_OFF(oi->t_hello);
EVENT_OFF(oi->t_wait);
- EVENT_OFF(oi->t_ls_ack);
+ EVENT_OFF(oi->t_ls_ack_delayed);
EVENT_OFF(oi->gr.hello_delay.t_grace_send);
break;
case ISM_Loopback:
@@ -293,7 +293,7 @@ static void ism_timer_set(struct ospf_interface *oi)
unavailable for regular data traffic. */
EVENT_OFF(oi->t_hello);
EVENT_OFF(oi->t_wait);
- EVENT_OFF(oi->t_ls_ack);
+ EVENT_OFF(oi->t_ls_ack_delayed);
EVENT_OFF(oi->gr.hello_delay.t_grace_send);
break;
case ISM_Waiting:
@@ -304,7 +304,7 @@ static void ism_timer_set(struct ospf_interface *oi)
OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1);
OSPF_ISM_TIMER_ON(oi->t_wait, ospf_wait_timer,
OSPF_IF_PARAM(oi, v_wait));
- EVENT_OFF(oi->t_ls_ack);
+ EVENT_OFF(oi->t_ls_ack_delayed);
break;
case ISM_PointToPoint:
/* The interface connects to a physical Point-to-point network
@@ -314,8 +314,6 @@ static void ism_timer_set(struct ospf_interface *oi)
/* send first hello immediately */
OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1);
EVENT_OFF(oi->t_wait);
- OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
- oi->v_ls_ack);
break;
case ISM_DROther:
/* The network type of the interface is broadcast or NBMA
@@ -324,8 +322,6 @@ static void ism_timer_set(struct ospf_interface *oi)
Backup Designated Router. */
OSPF_HELLO_TIMER_ON(oi);
EVENT_OFF(oi->t_wait);
- OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
- oi->v_ls_ack);
break;
case ISM_Backup:
/* The network type of the interface is broadcast os NBMA
@@ -333,8 +329,6 @@ static void ism_timer_set(struct ospf_interface *oi)
and the router is Backup Designated Router. */
OSPF_HELLO_TIMER_ON(oi);
EVENT_OFF(oi->t_wait);
- OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
- oi->v_ls_ack);
break;
case ISM_DR:
/* The network type of the interface is broadcast or NBMA
@@ -342,8 +336,6 @@ static void ism_timer_set(struct ospf_interface *oi)
and the router is Designated Router. */
OSPF_HELLO_TIMER_ON(oi);
EVENT_OFF(oi->t_wait);
- OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,
- oi->v_ls_ack);
break;
}
}
diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c
index fdb4e5c587..5c11027506 100644
--- a/ospfd/ospf_main.c
+++ b/ospfd/ospf_main.c
@@ -48,14 +48,20 @@
#include "ospfd/ospf_apiserver.h"
#define OSPFD_STATE_NAME "%s/ospfd.json", frr_libstatedir
-#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i
+#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_libstatedir, i
/* this one includes the path... because the instance number was in the path
* before :( ... which totally didn't have a mkdir anywhere.
+ *
+ * ... and libstatedir & runstatedir got switched around while changing this;
+ * for non-instance it read the wrong path, for instance it wrote the wrong
+ * path. (There is no COMPAT2 for non-instance because it was writing to the
+ * right place, i.e. no extra path to check exists from reading a wrong path.)
*/
-#define OSPFD_COMPAT_STATE_NAME "%s/ospfd-gr.json", frr_libstatedir
-#define OSPFD_COMPAT_INST_STATE_NAME(i) \
+#define OSPFD_COMPAT_STATE_NAME "%s/ospfd-gr.json", frr_runstatedir
+#define OSPFD_COMPAT1_INST_STATE_NAME(i) \
"%s-%d/ospfd-gr.json", frr_runstatedir, i
+#define OSPFD_COMPAT2_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i
/* ospfd privileges */
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
@@ -139,10 +145,12 @@ static const struct frr_yang_module_info *const ospfd_yang_modules[] = {
/* actual paths filled in main() */
static char state_path[512];
-static char state_compat_path[512];
+static char state_compat1_path[512];
+static char state_compat2_path[512];
static char *state_paths[] = {
state_path,
- state_compat_path,
+ state_compat1_path,
+ state_compat2_path, /* NULLed out if not needed */
NULL,
};
@@ -242,12 +250,18 @@ int main(int argc, char **argv)
if (ospf_instance) {
snprintf(state_path, sizeof(state_path),
OSPFD_INST_STATE_NAME(ospf_instance));
- snprintf(state_compat_path, sizeof(state_compat_path),
- OSPFD_COMPAT_INST_STATE_NAME(ospf_instance));
+ snprintf(state_compat1_path, sizeof(state_compat1_path),
+ OSPFD_COMPAT1_INST_STATE_NAME(ospf_instance));
+ snprintf(state_compat2_path, sizeof(state_compat2_path),
+ OSPFD_COMPAT2_INST_STATE_NAME(ospf_instance));
} else {
snprintf(state_path, sizeof(state_path), OSPFD_STATE_NAME);
- snprintf(state_compat_path, sizeof(state_compat_path),
+ snprintf(state_compat1_path, sizeof(state_compat1_path),
OSPFD_COMPAT_STATE_NAME);
+ /* no COMPAT2 here since it was reading that was broken,
+ * there is no additional path that would've been written
+ */
+ state_paths[2] = NULL;
}
/* OSPF master init. */
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 86f877b621..2d15a7ecca 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -369,19 +369,16 @@ void ospf_ls_rxmt_timer(struct event *thread)
ospf_ls_retransmit_set_timer(nbr);
}
-void ospf_ls_ack_timer(struct event *thread)
+void ospf_ls_ack_delayed_timer(struct event *thread)
{
struct ospf_interface *oi;
oi = EVENT_ARG(thread);
- oi->t_ls_ack = NULL;
+ oi->t_ls_ack_delayed = NULL;
/* Send Link State Acknowledgment. */
- if (listcount(oi->ls_ack) > 0)
+ if (ospf_lsa_list_count(&oi->ls_ack_delayed))
ospf_ls_ack_send_delayed(oi);
-
- /* Set LS Ack timer. */
- OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
}
#ifdef WANT_OSPF_WRITE_FRAGMENT
@@ -1820,7 +1817,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
if (IS_LSA_MAXAGE(lsa) && !current
&& ospf_check_nbr_status(oi->ospf)) {
/* (4a) Response Link State Acknowledgment. */
- ospf_ls_ack_send(nbr, lsa);
+ ospf_ls_ack_send_direct(nbr, lsa);
/* (4b) Discard LSA. */
if (IS_DEBUG_OSPF(lsa, LSA)) {
@@ -1845,7 +1842,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
if (IS_LSA_MAXAGE(lsa)) {
zlog_info("LSA[%s]: Boomerang effect?",
dump_lsa_key(lsa));
- ospf_ls_ack_send(nbr, lsa);
+ ospf_ls_ack_send_direct(nbr, lsa);
ospf_lsa_discard(lsa);
if (current != NULL && !IS_LSA_MAXAGE(current))
@@ -1879,7 +1876,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
SET_FLAG(lsa->flags, OSPF_LSA_SELF);
- ospf_ls_ack_send(nbr, lsa);
+ ospf_ls_ack_send_direct(nbr, lsa);
if (!ospf->gr_info.restart_in_progress) {
ospf_opaque_self_originated_lsa_received(
@@ -2018,9 +2015,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
*/
if (oi->state == ISM_Backup)
if (NBR_IS_DR(nbr))
- listnode_add(
- oi->ls_ack,
- ospf_lsa_lock(lsa));
+ ospf_ls_ack_send_direct(nbr,
+ lsa);
DISCARD_LSA(lsa, 6);
} else
@@ -2029,7 +2025,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
receiving
interface. */
{
- ospf_ls_ack_send(nbr, lsa);
+ ospf_ls_ack_send_direct(nbr, lsa);
DISCARD_LSA(lsa, 7);
}
}
@@ -3331,17 +3327,36 @@ static int ospf_make_ls_upd(struct ospf_interface *oi, struct list *update,
return length;
}
-static int ospf_make_ls_ack(struct ospf_interface *oi, struct list *ack,
- struct stream *s)
+static int ospf_make_ls_ack(struct ospf_interface *oi,
+ struct ospf_lsa_list_head *ls_ack_list,
+ bool direct_ack, bool delete_ack, struct stream *s)
{
- struct listnode *node, *nnode;
+ struct ospf_lsa_list_entry *ls_ack_list_first;
+ struct ospf_lsa_list_entry *ls_ack_list_entry;
uint16_t length = OSPF_LS_ACK_MIN_SIZE;
- unsigned long delta = OSPF_LSA_HEADER_SIZE;
struct ospf_lsa *lsa;
+ struct in_addr first_dst_addr;
- for (ALL_LIST_ELEMENTS(ack, node, nnode, lsa)) {
+ /*
+ * For direct LS Acks, assure the destination address doesn't
+ * change between queued acknowledgments.
+ */
+ if (direct_ack) {
+ ls_ack_list_first = ospf_lsa_list_first(ls_ack_list);
+ if (ls_ack_list_first)
+ first_dst_addr.s_addr =
+ ls_ack_list_first->list_entry_dst.s_addr;
+ } else
+ first_dst_addr.s_addr = INADDR_ANY;
+
+ frr_each_safe (ospf_lsa_list, ls_ack_list, ls_ack_list_entry) {
+ lsa = ls_ack_list_entry->lsa;
assert(lsa);
+ if (direct_ack && (ls_ack_list_entry->list_entry_dst.s_addr !=
+ first_dst_addr.s_addr))
+ break;
+
/* LS Ack packet overflows interface MTU
* delta is just number of bytes required for
* 1 LS Ack(1 LS Hdr) ospf_packet_max will return
@@ -3350,19 +3365,46 @@ static int ospf_make_ls_ack(struct ospf_interface *oi, struct list *ack,
* against ospf_packet_max to check if it can fit
* another ls header in the same packet.
*/
- if ((length + delta) > ospf_packet_max(oi))
+ if ((length + OSPF_LSA_HEADER_SIZE) > ospf_packet_max(oi))
break;
stream_put(s, lsa->data, OSPF_LSA_HEADER_SIZE);
length += OSPF_LSA_HEADER_SIZE;
- listnode_delete(ack, lsa);
- ospf_lsa_unlock(&lsa); /* oi->ls_ack_direct.ls_ack */
+ if (delete_ack) {
+ ospf_lsa_list_del(ls_ack_list, ls_ack_list_entry);
+ XFREE(MTYPE_OSPF_LSA_LIST, ls_ack_list_entry);
+ ospf_lsa_unlock(&lsa);
+ }
}
return length;
}
+/*
+ * On non-braodcast networks, the same LS acks must be sent to multiple
+ * neighbors and deletion must be deferred until after the LS Ack packet
+ * is sent to all neighbors.
+ */
+static void ospf_delete_ls_ack_delayed(struct ospf_interface *oi)
+{
+ struct ospf_lsa_list_entry *ls_ack_list_entry;
+ struct ospf_lsa *lsa;
+ uint16_t length = OSPF_LS_ACK_MIN_SIZE;
+
+ frr_each_safe (ospf_lsa_list, &oi->ls_ack_delayed, ls_ack_list_entry) {
+ lsa = ls_ack_list_entry->lsa;
+ assert(lsa);
+ if ((length + OSPF_LSA_HEADER_SIZE) > ospf_packet_max(oi))
+ break;
+
+ length += OSPF_LSA_HEADER_SIZE;
+ ospf_lsa_list_del(&oi->ls_ack_delayed, ls_ack_list_entry);
+ XFREE(MTYPE_OSPF_LSA_LIST, ls_ack_list_entry);
+ ospf_lsa_unlock(&lsa);
+ }
+}
+
static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr)
{
struct ospf_packet *op;
@@ -3934,10 +3976,13 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag,
&oi->t_ls_upd_event);
}
-static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
+static void ospf_ls_ack_send_list(struct ospf_interface *oi,
+ struct ospf_lsa_list_head *ls_ack_list,
+ bool direct_ack, bool delete_ack,
struct in_addr dst)
{
struct ospf_packet *op;
+ struct ospf_lsa_list_entry *ls_ack_list_first;
uint16_t length = OSPF_HEADER_SIZE;
op = ospf_packet_new(oi->ifp->mtu);
@@ -3945,8 +3990,18 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
/* Prepare OSPF common header. */
ospf_make_header(OSPF_MSG_LS_ACK, oi, op->s);
+ /* Determine the destination address - for direct acks,
+ * the list entries always include the distination address.
+ */
+ if (direct_ack) {
+ ls_ack_list_first = ospf_lsa_list_first(ls_ack_list);
+ op->dst.s_addr = ls_ack_list_first->list_entry_dst.s_addr;
+ } else
+ op->dst.s_addr = dst.s_addr;
+
/* Prepare OSPF Link State Acknowledgment body. */
- length += ospf_make_ls_ack(oi, ack, op->s);
+ length += ospf_make_ls_ack(oi, ls_ack_list, direct_ack, delete_ack,
+ op->s);
/* Fill OSPF header. */
ospf_fill_header(oi, op->s, length);
@@ -3954,14 +4009,6 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
/* Set packet length. */
op->length = length;
- /* Decide destination address. */
- if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
- (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT &&
- !oi->p2mp_non_broadcast))
- op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
- else
- op->dst.s_addr = dst.s_addr;
-
/* Add packet to the interface output queue. */
ospf_packet_add(oi, op);
@@ -3969,34 +4016,96 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
OSPF_ISM_WRITE_ON(oi->ospf);
}
-static void ospf_ls_ack_send_event(struct event *thread)
+static void ospf_ls_ack_send_direct_event(struct event *thread)
{
struct ospf_interface *oi = EVENT_ARG(thread);
+ struct in_addr dst = { INADDR_ANY };
oi->t_ls_ack_direct = NULL;
- while (listcount(oi->ls_ack_direct.ls_ack))
- ospf_ls_ack_send_list(oi, oi->ls_ack_direct.ls_ack,
- oi->ls_ack_direct.dst);
+ while (ospf_lsa_list_count(&oi->ls_ack_direct))
+ ospf_ls_ack_send_list(oi, &(oi->ls_ack_direct), true, true, dst);
}
-void ospf_ls_ack_send(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
+void ospf_ls_ack_send_direct(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
{
+ struct ospf_lsa_list_entry *ls_ack_list_entry;
struct ospf_interface *oi = nbr->oi;
+ if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
+ zlog_debug("%s:Add LSA[Type%d:%pI4:%pI4]: seq 0x%x age %u NBR %pI4 (%s) ack queue",
+ __func__, lsa->data->type, &lsa->data->id,
+ &lsa->data->adv_router, ntohl(lsa->data->ls_seqnum),
+ ntohs(lsa->data->ls_age), &nbr->router_id,
+ IF_NAME(nbr->oi));
+
+ /*
+ * On Point-to-Multipoint broadcast-capabile interfaces,
+ * where direct acks from are sent to the ALLSPFRouters
+ * address and one direct ack send event, may include LSAs
+ * from multiple neighbors, there is a possibility of the same
+ * LSA being processed more than once in the same send event.
+ * In this case, the instances subsequent to the first can be
+ * ignored.
+ */
+ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT && !oi->p2mp_non_broadcast) {
+ struct ospf_lsa_list_entry *ls_ack_list_entry;
+ struct ospf_lsa *ack_queue_lsa;
+
+ frr_each (ospf_lsa_list, &oi->ls_ack_direct, ls_ack_list_entry) {
+ ack_queue_lsa = ls_ack_list_entry->lsa;
+ if ((lsa == ack_queue_lsa) ||
+ ((lsa->data->type == ack_queue_lsa->data->type) &&
+ (lsa->data->id.s_addr ==
+ ack_queue_lsa->data->id.s_addr) &&
+ (lsa->data->adv_router.s_addr ==
+ ack_queue_lsa->data->adv_router.s_addr) &&
+ (lsa->data->ls_seqnum ==
+ ack_queue_lsa->data->ls_seqnum))) {
+ if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
+ zlog_debug("%s:LSA[Type%d:%pI4:%pI4]: seq 0x%x age %u NBR %pI4 (%s) ack queue duplicate",
+ __func__, lsa->data->type,
+ &lsa->data->id,
+ &lsa->data->adv_router,
+ ntohl(lsa->data->ls_seqnum),
+ ntohs(lsa->data->ls_age),
+ &nbr->router_id,
+ IF_NAME(nbr->oi));
+ return;
+ }
+ }
+ }
+
if (IS_GRACE_LSA(lsa)) {
if (IS_DEBUG_OSPF_GR)
zlog_debug("%s, Sending GRACE ACK to Restarter.",
__func__);
}
- if (listcount(oi->ls_ack_direct.ls_ack) == 0)
- oi->ls_ack_direct.dst = nbr->address.u.prefix4;
+ ls_ack_list_entry = XCALLOC(MTYPE_OSPF_LSA_LIST,
+ sizeof(struct ospf_lsa_list_entry));
- listnode_add(oi->ls_ack_direct.ls_ack, ospf_lsa_lock(lsa));
+ /*
+ * Determine the destination address - Direct LS acknowledgments
+ * are sent the AllSPFRouters multicast address on Point-to-Point
+ * and Point-to-Multipoint broadcast-capable interfaces. For all other
+ * interface types, they are unicast directly to the neighbor.
+ */
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
+ (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT &&
+ !oi->p2mp_non_broadcast))
+ ls_ack_list_entry->list_entry_dst.s_addr =
+ htonl(OSPF_ALLSPFROUTERS);
+ else
+ ls_ack_list_entry->list_entry_dst.s_addr =
+ nbr->address.u.prefix4.s_addr;
- event_add_event(master, ospf_ls_ack_send_event, oi, 0,
- &oi->t_ls_ack_direct);
+ ls_ack_list_entry->lsa = ospf_lsa_lock(lsa);
+ ospf_lsa_list_add_tail(&nbr->oi->ls_ack_direct, ls_ack_list_entry);
+
+ if (oi->t_ls_ack_direct == NULL)
+ event_add_event(master, ospf_ls_ack_send_direct_event, oi, 0,
+ &oi->t_ls_ack_direct);
}
/* Send Link State Acknowledgment delayed. */
@@ -4013,33 +4122,39 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi)
struct ospf_neighbor *nbr;
struct route_node *rn;
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
- nbr = rn->info;
+ while (ospf_lsa_list_count(&oi->ls_ack_delayed)) {
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+ nbr = rn->info;
- if (!nbr)
- continue;
+ if (!nbr)
+ continue;
- if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
- while (listcount(oi->ls_ack))
- ospf_ls_ack_send_list(
- oi, oi->ls_ack,
- nbr->address.u.prefix4);
+ if (nbr != oi->nbr_self &&
+ nbr->state >= NSM_Exchange)
+ ospf_ls_ack_send_list(oi,
+ &oi->ls_ack_delayed,
+ false, false,
+ nbr->address.u
+ .prefix4);
+ }
+ ospf_delete_ls_ack_delayed(oi);
}
- return;
- }
- if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
- dst.s_addr = oi->vl_data->peer_addr.s_addr;
- else if (oi->state == ISM_DR || oi->state == ISM_Backup)
- dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
- else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
- dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
- else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
- dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
- else
- dst.s_addr = htonl(OSPF_ALLDROUTERS);
+ } else {
+ if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+ dst.s_addr = oi->vl_data->peer_addr.s_addr;
+ else if (oi->state == ISM_DR || oi->state == ISM_Backup)
+ dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
+ else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
+ else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
+ dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
+ else
+ dst.s_addr = htonl(OSPF_ALLDROUTERS);
- while (listcount(oi->ls_ack))
- ospf_ls_ack_send_list(oi, oi->ls_ack, dst);
+ while (ospf_lsa_list_count(&oi->ls_ack_delayed))
+ ospf_ls_ack_send_list(oi, &oi->ls_ack_delayed, false,
+ true, dst);
+ }
}
/*
diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
index 2c9dba6c88..84e4b027e6 100644
--- a/ospfd/ospf_packet.h
+++ b/ospfd/ospf_packet.h
@@ -135,13 +135,14 @@ extern void ospf_ls_upd_send(struct ospf_neighbor *, struct list *, int, int);
extern void ospf_ls_upd_queue_send(struct ospf_interface *oi,
struct list *update, struct in_addr addr,
int send_lsupd_now);
-extern void ospf_ls_ack_send(struct ospf_neighbor *, struct ospf_lsa *);
+extern void ospf_ls_ack_send_direct(struct ospf_neighbor *nbr,
+ struct ospf_lsa *lsa);
extern void ospf_ls_ack_send_delayed(struct ospf_interface *);
extern void ospf_ls_retransmit(struct ospf_interface *, struct ospf_lsa *);
extern void ospf_ls_req_event(struct ospf_neighbor *);
extern void ospf_ls_rxmt_timer(struct event *thread);
-extern void ospf_ls_ack_timer(struct event *thread);
+extern void ospf_ls_ack_delayed_timer(struct event *thread);
extern void ospf_poll_timer(struct event *thread);
extern void ospf_hello_reply_timer(struct event *thread);
diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c
index ec912700d1..99f1474712 100644
--- a/pimd/pim6_cmd.c
+++ b/pimd/pim6_cmd.c
@@ -41,45 +41,207 @@ static struct cmd_node debug_node = {
.config_write = pim_debug_config_write,
};
-DEFPY (ipv6_pim_joinprune_time,
- ipv6_pim_joinprune_time_cmd,
- "ipv6 pim join-prune-interval (1-65535)$jpi",
- IPV6_STR
- PIM_STR
+DEFPY_NOSH (router_pim6,
+ router_pim6_cmd,
+ "router pim6 [vrf NAME]",
+ "Enable a routing process\n"
+ "Start PIM6 configuration\n"
+ VRF_CMD_HELP_STR)
+{
+ char xpath[XPATH_MAXLEN];
+ const char *vrf_name;
+
+ if (vrf)
+ vrf_name = vrf;
+ else
+ vrf_name = VRF_DEFAULT_NAME;
+
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim",
+ vrf_name, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) != CMD_SUCCESS)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (no_router_pim6,
+ no_router_pim6_cmd,
+ "no router pim6 [vrf NAME]",
+ NO_STR
+ "Enable a routing process\n"
+ "Start PIM6 configuration\n"
+ VRF_CMD_HELP_STR)
+{
+ char xpath[XPATH_MAXLEN];
+ const char *vrf_name;
+
+ if (vrf)
+ vrf_name = vrf;
+ else
+ vrf_name = VRF_DEFAULT_NAME;
+
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim",
+ vrf_name, FRR_PIM_AF_XPATH_VAL);
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY (pim6_joinprune_time,
+ pim6_joinprune_time_cmd,
+ "join-prune-interval (1-65535)$jpi",
"Join Prune Send Interval\n"
"Seconds\n")
{
return pim_process_join_prune_cmd(vty, jpi_str);
}
+DEFPY_ATTR(ipv6_joinprune_time,
+ ipv6_pim_joinprune_time_cmd,
+ "ipv6 pim join-prune-interval (1-65535)$jpi",
+ IPV6_STR PIM_STR
+ "Join Prune Send Interval\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_join_prune_cmd(vty, jpi_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_joinprune_time,
- no_ipv6_pim_joinprune_time_cmd,
- "no ipv6 pim join-prune-interval [(1-65535)]",
+DEFPY (no_pim6_joinprune_time,
+ no_pim6_joinprune_time_cmd,
+ "no join-prune-interval [(1-65535)]",
NO_STR
- IPV6_STR
- PIM_STR
"Join Prune Send Interval\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_join_prune_cmd(vty);
}
+DEFPY_ATTR(no_ipv6_pim_joinprune_time,
+ no_ipv6_pim_joinprune_time_cmd,
+ "no ipv6 pim join-prune-interval [(1-65535)]",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "Join Prune Send Interval\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_join_prune_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (ipv6_pim_spt_switchover_infinity,
- ipv6_pim_spt_switchover_infinity_cmd,
- "ipv6 pim spt-switchover infinity-and-beyond",
- IPV6_STR
- PIM_STR
+DEFPY (pim6_spt_switchover_infinity,
+ pim6_spt_switchover_infinity_cmd,
+ "spt-switchover infinity-and-beyond",
"SPT-Switchover\n"
"Never switch to SPT Tree\n")
{
return pim_process_spt_switchover_infinity_cmd(vty);
}
+DEFPY_ATTR(ipv6_spt_switchover_infinity,
+ ipv6_pim_spt_switchover_infinity_cmd,
+ "ipv6 pim spt-switchover infinity-and-beyond",
+ IPV6_STR
+ PIM_STR
+ "SPT-Switchover\n"
+ "Never switch to SPT Tree\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_spt_switchover_infinity_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (ipv6_pim_spt_switchover_infinity_plist,
- ipv6_pim_spt_switchover_infinity_plist_cmd,
- "ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist",
- IPV6_STR
- PIM_STR
+DEFPY (pim6_spt_switchover_infinity_plist,
+ pim6_spt_switchover_infinity_plist_cmd,
+ "spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist",
"SPT-Switchover\n"
"Never switch to SPT Tree\n"
"Prefix-List to control which groups to switch\n"
@@ -87,25 +249,104 @@ DEFPY (ipv6_pim_spt_switchover_infinity_plist,
{
return pim_process_spt_switchover_prefixlist_cmd(vty, plist);
}
+DEFPY_ATTR(ipv6_spt_switchover_infinity_plist,
+ ipv6_pim_spt_switchover_infinity_plist_cmd,
+ "ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist",
+ IPV6_STR
+ PIM_STR
+ "SPT-Switchover\n"
+ "Never switch to SPT Tree\n"
+ "Prefix-List to control which groups to switch\n"
+ "Prefix-List name\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_spt_switchover_prefixlist_cmd(vty, plist);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_spt_switchover_infinity,
- no_ipv6_pim_spt_switchover_infinity_cmd,
- "no ipv6 pim spt-switchover infinity-and-beyond",
+DEFPY (no_pim6_spt_switchover_infinity,
+ no_pim6_spt_switchover_infinity_cmd,
+ "no spt-switchover infinity-and-beyond",
NO_STR
- IPV6_STR
- PIM_STR
"SPT_Switchover\n"
"Never switch to SPT Tree\n")
{
return pim_process_no_spt_switchover_cmd(vty);
}
+DEFPY_ATTR(no_ipv6_pim_spt_switchover_infinity,
+ no_ipv6_pim_spt_switchover_infinity_cmd,
+ "no ipv6 pim spt-switchover infinity-and-beyond",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "SPT_Switchover\n"
+ "Never switch to SPT Tree\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_spt_switchover_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_spt_switchover_infinity_plist,
- no_ipv6_pim_spt_switchover_infinity_plist_cmd,
- "no ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME",
+DEFPY (no_pim6_spt_switchover_infinity_plist,
+ no_pim6_spt_switchover_infinity_plist_cmd,
+ "no spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME",
NO_STR
- IPV6_STR
- PIM_STR
"SPT_Switchover\n"
"Never switch to SPT Tree\n"
"Prefix-List to control which groups to switch\n"
@@ -113,100 +354,453 @@ DEFPY (no_ipv6_pim_spt_switchover_infinity_plist,
{
return pim_process_no_spt_switchover_cmd(vty);
}
+DEFPY_ATTR(no_ipv6_pim_spt_switchover_infinity_plist,
+ no_ipv6_pim_spt_switchover_infinity_plist_cmd,
+ "no ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "SPT_Switchover\n"
+ "Never switch to SPT Tree\n"
+ "Prefix-List to control which groups to switch\n"
+ "Prefix-List name\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_spt_switchover_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (ipv6_pim_packets,
- ipv6_pim_packets_cmd,
- "ipv6 pim packets (1-255)",
- IPV6_STR
- PIM_STR
+DEFPY (pim6_packets,
+ pim6_packets_cmd,
+ "packets (1-255)",
"packets to process at one time per fd\n"
"Number of packets\n")
{
return pim_process_pim_packet_cmd(vty, packets_str);
}
+DEFPY_ATTR(ipv6_pim_packets,
+ ipv6_pim_packets_cmd,
+ "ipv6 pim packets (1-255)",
+ IPV6_STR
+ PIM_STR
+ "packets to process at one time per fd\n"
+ "Number of packets\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_pim_packet_cmd(vty, packets_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_packets,
- no_ipv6_pim_packets_cmd,
- "no ipv6 pim packets [(1-255)]",
+DEFPY (no_pim6_packets,
+ no_pim6_packets_cmd,
+ "no packets [(1-255)]",
NO_STR
- IPV6_STR
- PIM_STR
"packets to process at one time per fd\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_pim_packet_cmd(vty);
}
+DEFPY_ATTR(no_ipv6_pim_packets,
+ no_ipv6_pim_packets_cmd,
+ "no ipv6 pim packets [(1-255)]",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "packets to process at one time per fd\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
-DEFPY (ipv6_pim_keep_alive,
- ipv6_pim_keep_alive_cmd,
- "ipv6 pim keep-alive-timer (1-65535)$kat",
- IPV6_STR
- PIM_STR
+ ret = pim_process_no_pim_packet_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim6_keep_alive,
+ pim6_keep_alive_cmd,
+ "keep-alive-timer (1-65535)$kat",
"Keep alive Timer\n"
"Seconds\n")
{
return pim_process_keepalivetimer_cmd(vty, kat_str);
}
+DEFPY_ATTR(ipv6_pim_keep_alive,
+ ipv6_pim_keep_alive_cmd,
+ "ipv6 pim keep-alive-timer (1-65535)$kat",
+ IPV6_STR
+ PIM_STR
+ "Keep alive Timer\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_keepalivetimer_cmd(vty, kat_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_keep_alive,
- no_ipv6_pim_keep_alive_cmd,
- "no ipv6 pim keep-alive-timer [(1-65535)]",
+DEFPY (no_pim6_keep_alive,
+ no_pim6_keep_alive_cmd,
+ "no keep-alive-timer [(1-65535)]",
NO_STR
- IPV6_STR
- PIM_STR
"Keep alive Timer\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_keepalivetimer_cmd(vty);
}
+DEFPY_ATTR(no_ipv6_pim_keep_alive,
+ no_ipv6_pim_keep_alive_cmd,
+ "no ipv6 pim keep-alive-timer [(1-65535)]",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "Keep alive Timer\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_keepalivetimer_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (ipv6_pim_rp_keep_alive,
- ipv6_pim_rp_keep_alive_cmd,
- "ipv6 pim rp keep-alive-timer (1-65535)$kat",
- IPV6_STR
- PIM_STR
+DEFPY (pim6_rp_keep_alive,
+ pim6_rp_keep_alive_cmd,
+ "rp keep-alive-timer (1-65535)$kat",
"Rendezvous Point\n"
"Keep alive Timer\n"
"Seconds\n")
{
return pim_process_rp_kat_cmd(vty, kat_str);
}
+DEFPY_ATTR(ipv6_pim_rp_keep_alive,
+ ipv6_pim_rp_keep_alive_cmd,
+ "ipv6 pim rp keep-alive-timer (1-65535)$kat",
+ IPV6_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "Keep alive Timer\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_rp_kat_cmd(vty, kat_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_rp_keep_alive,
- no_ipv6_pim_rp_keep_alive_cmd,
- "no ipv6 pim rp keep-alive-timer [(1-65535)]",
+DEFPY (no_pim6_rp_keep_alive,
+ no_pim6_rp_keep_alive_cmd,
+ "no rp keep-alive-timer [(1-65535)]",
NO_STR
- IPV6_STR
- PIM_STR
"Rendezvous Point\n"
"Keep alive Timer\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_rp_kat_cmd(vty);
}
+DEFPY_ATTR(no_ipv6_pim_rp_keep_alive,
+ no_ipv6_pim_rp_keep_alive_cmd,
+ "no ipv6 pim rp keep-alive-timer [(1-65535)]",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "Keep alive Timer\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
-DEFPY (ipv6_pim_register_suppress,
- ipv6_pim_register_suppress_cmd,
- "ipv6 pim register-suppress-time (1-65535)$rst",
- IPV6_STR
- PIM_STR
+ ret = pim_process_no_rp_kat_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim6_register_suppress,
+ pim6_register_suppress_cmd,
+ "register-suppress-time (1-65535)$rst",
"Register Suppress Timer\n"
"Seconds\n")
{
return pim_process_register_suppress_cmd(vty, rst_str);
}
+DEFPY_ATTR(ipv6_pim_register_suppress,
+ ipv6_pim_register_suppress_cmd,
+ "ipv6 pim register-suppress-time (1-65535)$rst",
+ IPV6_STR
+ PIM_STR
+ "Register Suppress Timer\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_register_suppress_cmd(vty, rst_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_register_suppress,
- no_ipv6_pim_register_suppress_cmd,
- "no ipv6 pim register-suppress-time [(1-65535)]",
+DEFPY (no_pim6_register_suppress,
+ no_pim6_register_suppress_cmd,
+ "no register-suppress-time [(1-65535)]",
NO_STR
- IPV6_STR
- PIM_STR
"Register Suppress Timer\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_register_suppress_cmd(vty);
}
+DEFPY_ATTR(no_ipv6_pim_register_suppress,
+ no_ipv6_pim_register_suppress_cmd,
+ "no ipv6 pim register-suppress-time [(1-65535)]",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "Register Suppress Timer\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_register_suppress_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
DEFPY (interface_ipv6_pim,
interface_ipv6_pim_cmd,
@@ -405,11 +999,9 @@ DEFPY (interface_no_ipv6_mroute,
source_str);
}
-DEFPY (ipv6_pim_rp,
- ipv6_pim_rp_cmd,
- "ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp",
- IPV6_STR
- PIM_STR
+DEFPY (pim6_rp,
+ pim6_rp_cmd,
+ "rp X:X::X:X$rp [X:X::X:X/M]$gp",
"Rendezvous Point\n"
"ipv6 address of RP\n"
"Group Address range to cover\n")
@@ -418,13 +1010,53 @@ DEFPY (ipv6_pim_rp,
return pim_process_rp_cmd(vty, rp_str, group_str);
}
+DEFPY_ATTR(ipv6_pim_rp,
+ ipv6_pim_rp_cmd,
+ "ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp",
+ IPV6_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ipv6 address of RP\n"
+ "Group Address range to cover\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *group_str = (gp_str) ? gp_str : "FF00::0/8";
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_rp_cmd(vty, rp_str, group_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_rp,
- no_ipv6_pim_rp_cmd,
- "no ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp",
+DEFPY (no_pim6_rp,
+ no_pim6_rp_cmd,
+ "no rp X:X::X:X$rp [X:X::X:X/M]$gp",
NO_STR
- IPV6_STR
- PIM_STR
"Rendezvous Point\n"
"ipv6 address of RP\n"
"Group Address range to cover\n")
@@ -433,12 +1065,53 @@ DEFPY (no_ipv6_pim_rp,
return pim_process_no_rp_cmd(vty, rp_str, group_str);
}
+DEFPY_ATTR(no_ipv6_pim_rp,
+ no_ipv6_pim_rp_cmd,
+ "no ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ipv6 address of RP\n"
+ "Group Address range to cover\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *group_str = (gp_str) ? gp_str : "FF00::0/8";
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
-DEFPY (ipv6_pim_rp_prefix_list,
- ipv6_pim_rp_prefix_list_cmd,
- "ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
- IPV6_STR
- PIM_STR
+ ret = pim_process_no_rp_cmd(vty, rp_str, group_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim6_rp_prefix_list,
+ pim6_rp_prefix_list_cmd,
+ "rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
"Rendezvous Point\n"
"ipv6 address of RP\n"
"group prefix-list filter\n"
@@ -446,13 +1119,53 @@ DEFPY (ipv6_pim_rp_prefix_list,
{
return pim_process_rp_plist_cmd(vty, rp_str, plist);
}
+DEFPY_ATTR(ipv6_pim_rp_prefix_list,
+ ipv6_pim_rp_prefix_list_cmd,
+ "ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
+ IPV6_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ipv6 address of RP\n"
+ "group prefix-list filter\n"
+ "Name of a prefix-list\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_rp_plist_cmd(vty, rp_str, plist);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ipv6_pim_rp_prefix_list,
- no_ipv6_pim_rp_prefix_list_cmd,
- "no ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
+DEFPY (no_pim6_rp_prefix_list,
+ no_pim6_rp_prefix_list_cmd,
+ "no rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
NO_STR
- IPV6_STR
- PIM_STR
"Rendezvous Point\n"
"ipv6 address of RP\n"
"group prefix-list filter\n"
@@ -460,6 +1173,49 @@ DEFPY (no_ipv6_pim_rp_prefix_list,
{
return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
}
+DEFPY_ATTR(no_ipv6_pim_rp_prefix_list,
+ no_ipv6_pim_rp_prefix_list_cmd,
+ "no ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ipv6 address of RP\n"
+ "group prefix-list filter\n"
+ "Name of a prefix-list\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_rp_plist_cmd(vty, rp_str, plist);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
DEFPY (ipv6_pim_bsm,
ipv6_pim_bsm_cmd,
@@ -503,10 +1259,9 @@ DEFPY (no_ipv6_pim_ucast_bsm,
return pim_process_no_unicast_bsm_cmd(vty);
}
-DEFPY (ipv6_ssmpingd,
- ipv6_ssmpingd_cmd,
- "ipv6 ssmpingd [X:X::X:X]$source",
- IPV6_STR
+DEFPY (pim6_ssmpingd,
+ pim6_ssmpingd_cmd,
+ "ssmpingd [X:X::X:X]$source",
CONF_SSMPINGD_STR
"Source address\n")
{
@@ -514,20 +1269,99 @@ DEFPY (ipv6_ssmpingd,
return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
}
+DEFPY_ATTR(ipv6_ssmpingd,
+ ipv6_ssmpingd_cmd,
+ "ipv6 ssmpingd [X:X::X:X]$source",
+ IPV6_STR
+ CONF_SSMPINGD_STR
+ "Source address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *src_str = (source_str) ? source_str : "::";
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ ret = pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
-DEFPY (no_ipv6_ssmpingd,
- no_ipv6_ssmpingd_cmd,
- "no ipv6 ssmpingd [X:X::X:X]$source",
- NO_STR
- IPV6_STR
- CONF_SSMPINGD_STR
- "Source address\n")
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (no_pim6_ssmpingd,
+ no_pim6_ssmpingd_cmd,
+ "no ssmpingd [X:X::X:X]$source",
+ NO_STR
+ CONF_SSMPINGD_STR
+ "Source address\n")
{
const char *src_str = (source_str) ? source_str : "::";
return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
}
+DEFPY_ATTR(no_ipv6_ssmpingd,
+ no_ipv6_ssmpingd_cmd,
+ "no ipv6 ssmpingd [X:X::X:X]$source",
+ NO_STR
+ IPV6_STR
+ CONF_SSMPINGD_STR
+ "Source address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *src_str = (source_str) ? source_str : "::";
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM6_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
DEFPY (interface_ipv6_mld_join,
interface_ipv6_mld_join_cmd,
@@ -1733,12 +2567,16 @@ DEFPY (debug_pimv6_bsm,
return CMD_SUCCESS;
}
-void pim_cmd_init(void)
-{
- if_cmd_init(pim_interface_config_write);
-
- install_node(&debug_node);
+struct cmd_node pim6_node = {
+ .name = "pim6",
+ .node = PIM6_NODE,
+ .parent_node = CONFIG_NODE,
+ .prompt = "%s(config-pim6)# ",
+ .config_write = pim_router_config_write,
+};
+static void pim_install_deprecated(void)
+{
install_element(CONFIG_NODE, &ipv6_pim_joinprune_time_cmd);
install_element(CONFIG_NODE, &no_ipv6_pim_joinprune_time_cmd);
install_element(CONFIG_NODE, &ipv6_pim_spt_switchover_infinity_cmd);
@@ -1753,6 +2591,60 @@ void pim_cmd_init(void)
install_element(CONFIG_NODE, &no_ipv6_pim_rp_keep_alive_cmd);
install_element(CONFIG_NODE, &ipv6_pim_register_suppress_cmd);
install_element(CONFIG_NODE, &no_ipv6_pim_register_suppress_cmd);
+ install_element(CONFIG_NODE, &ipv6_pim_rp_cmd);
+ install_element(VRF_NODE, &ipv6_pim_rp_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_pim_rp_cmd);
+ install_element(VRF_NODE, &no_ipv6_pim_rp_cmd);
+ install_element(CONFIG_NODE, &ipv6_pim_rp_prefix_list_cmd);
+ install_element(VRF_NODE, &ipv6_pim_rp_prefix_list_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
+ install_element(VRF_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
+ install_element(CONFIG_NODE, &ipv6_ssmpingd_cmd);
+ install_element(VRF_NODE, &ipv6_ssmpingd_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_ssmpingd_cmd);
+ install_element(VRF_NODE, &no_ipv6_ssmpingd_cmd);
+}
+
+void pim_cmd_init(void)
+{
+ if_cmd_init(pim_interface_config_write);
+
+ install_node(&debug_node);
+
+ pim_install_deprecated();
+
+ install_element(CONFIG_NODE, &router_pim6_cmd);
+ install_element(CONFIG_NODE, &no_router_pim6_cmd);
+
+ install_node(&pim6_node);
+ install_default(PIM6_NODE);
+
+ install_element(PIM6_NODE, &pim6_joinprune_time_cmd);
+ install_element(PIM6_NODE, &no_pim6_joinprune_time_cmd);
+ install_element(PIM6_NODE, &pim6_spt_switchover_infinity_cmd);
+ install_element(PIM6_NODE, &pim6_spt_switchover_infinity_plist_cmd);
+ install_element(PIM6_NODE, &no_pim6_spt_switchover_infinity_cmd);
+ install_element(PIM6_NODE, &no_pim6_spt_switchover_infinity_plist_cmd);
+ install_element(PIM6_NODE, &pim6_packets_cmd);
+ install_element(PIM6_NODE, &no_pim6_packets_cmd);
+ install_element(PIM6_NODE, &pim6_keep_alive_cmd);
+ install_element(PIM6_NODE, &no_pim6_keep_alive_cmd);
+ install_element(PIM6_NODE, &pim6_rp_keep_alive_cmd);
+ install_element(PIM6_NODE, &no_pim6_rp_keep_alive_cmd);
+ install_element(PIM6_NODE, &pim6_register_suppress_cmd);
+ install_element(PIM6_NODE, &no_pim6_register_suppress_cmd);
+ install_element(PIM6_NODE, &pim6_rp_cmd);
+ install_element(PIM6_NODE, &no_pim6_rp_cmd);
+ install_element(PIM6_NODE, &pim6_rp_prefix_list_cmd);
+ install_element(PIM6_NODE, &no_pim6_rp_prefix_list_cmd);
+ install_element(PIM6_NODE, &pim6_ssmpingd_cmd);
+ install_element(PIM6_NODE, &no_pim6_ssmpingd_cmd);
+
+ install_element(CONFIG_NODE, &ipv6_mld_group_watermark_cmd);
+ install_element(VRF_NODE, &ipv6_mld_group_watermark_cmd);
+ install_element(CONFIG_NODE, &no_ipv6_mld_group_watermark_cmd);
+ install_element(VRF_NODE, &no_ipv6_mld_group_watermark_cmd);
+
install_element(INTERFACE_NODE, &interface_ipv6_pim_cmd);
install_element(INTERFACE_NODE, &interface_no_ipv6_pim_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_pim_drprio_cmd);
@@ -1764,10 +2656,8 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_no_ipv6_pim_ssm_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_pim_sm_cmd);
install_element(INTERFACE_NODE, &interface_no_ipv6_pim_sm_cmd);
- install_element(INTERFACE_NODE,
- &interface_ipv6_pim_boundary_oil_cmd);
- install_element(INTERFACE_NODE,
- &interface_no_ipv6_pim_boundary_oil_cmd);
+ install_element(INTERFACE_NODE, &interface_ipv6_pim_boundary_oil_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ipv6_pim_boundary_oil_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_mroute_cmd);
install_element(INTERFACE_NODE, &interface_no_ipv6_mroute_cmd);
/* Install BSM command */
@@ -1775,18 +2665,7 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &no_ipv6_pim_bsm_cmd);
install_element(INTERFACE_NODE, &ipv6_pim_ucast_bsm_cmd);
install_element(INTERFACE_NODE, &no_ipv6_pim_ucast_bsm_cmd);
- install_element(CONFIG_NODE, &ipv6_pim_rp_cmd);
- install_element(VRF_NODE, &ipv6_pim_rp_cmd);
- install_element(CONFIG_NODE, &no_ipv6_pim_rp_cmd);
- install_element(VRF_NODE, &no_ipv6_pim_rp_cmd);
- install_element(CONFIG_NODE, &ipv6_pim_rp_prefix_list_cmd);
- install_element(VRF_NODE, &ipv6_pim_rp_prefix_list_cmd);
- install_element(CONFIG_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
- install_element(VRF_NODE, &no_ipv6_pim_rp_prefix_list_cmd);
- install_element(CONFIG_NODE, &ipv6_ssmpingd_cmd);
- install_element(VRF_NODE, &ipv6_ssmpingd_cmd);
- install_element(CONFIG_NODE, &no_ipv6_ssmpingd_cmd);
- install_element(VRF_NODE, &no_ipv6_ssmpingd_cmd);
+
install_element(INTERFACE_NODE, &interface_ipv6_mld_cmd);
install_element(INTERFACE_NODE, &interface_no_ipv6_mld_cmd);
install_element(INTERFACE_NODE, &interface_ipv6_mld_join_cmd);
@@ -1796,10 +2675,6 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_ipv6_mld_query_interval_cmd);
install_element(INTERFACE_NODE,
&interface_no_ipv6_mld_query_interval_cmd);
- install_element(CONFIG_NODE, &ipv6_mld_group_watermark_cmd);
- install_element(VRF_NODE, &ipv6_mld_group_watermark_cmd);
- install_element(CONFIG_NODE, &no_ipv6_mld_group_watermark_cmd);
- install_element(VRF_NODE, &no_ipv6_mld_group_watermark_cmd);
install_element(INTERFACE_NODE,
&interface_ipv6_mld_query_max_response_time_cmd);
install_element(INTERFACE_NODE,
diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h
index 7b0c3f0350..c1416e1dd0 100644
--- a/pimd/pim_addr.h
+++ b/pimd/pim_addr.h
@@ -26,6 +26,7 @@ typedef struct prefix_ipv4 prefix_pim;
#define PIM_MAX_BITLEN IPV4_MAX_BITLEN
#define PIM_AF_NAME "ip"
#define PIM_AF_DBG "pim"
+#define PIM_AF_ROUTER "pim"
#define GM_AF_DBG "igmp"
#define PIM_MROUTE_DBG "mroute"
#define PIMREG "pimreg"
@@ -58,6 +59,7 @@ typedef struct prefix_ipv6 prefix_pim;
#define PIM_MAX_BITLEN IPV6_MAX_BITLEN
#define PIM_AF_NAME "ipv6"
#define PIM_AF_DBG "pimv6"
+#define PIM_AF_ROUTER "pim6"
#define GM_AF_DBG "mld"
#define PIM_MROUTE_DBG "mroute6"
#define PIMREG "pim6reg"
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index a2d756a96a..2b8d3e56e5 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -1457,19 +1457,13 @@ static void clear_interfaces(struct pim_instance *pim)
static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
const char *gname)
{
- const char *vrfname;
char xpath_value[XPATH_MAXLEN];
char xpath_member_value[XPATH_MAXLEN];
const struct lyd_node *member_dnode;
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return;
-
/* Get mesh group base XPath. */
snprintf(xpath_value, sizeof(xpath_value),
- FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname);
/* Group must exists, otherwise just quit. */
if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
return;
@@ -1477,8 +1471,7 @@ static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
/* Group members check: */
strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
strlcat(xpath_member_value, "/members", sizeof(xpath_member_value));
- if (yang_dnode_exists(vty->candidate_config->dnode,
- xpath_member_value)) {
+ if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value)) {
member_dnode = yang_dnode_get(vty->candidate_config->dnode,
xpath_member_value);
if (!member_dnode || !yang_is_last_list_dnode(member_dnode))
@@ -2989,22 +2982,108 @@ DEFUN (show_ip_ssmpingd,
return CMD_SUCCESS;
}
-DEFUN (ip_pim_spt_switchover_infinity,
- ip_pim_spt_switchover_infinity_cmd,
- "ip pim spt-switchover infinity-and-beyond",
- IP_STR
- PIM_STR
+DEFPY_NOSH (router_pim,
+ router_pim_cmd,
+ "router pim [vrf NAME]",
+ "Enable a routing process\n"
+ "Start PIM configuration\n"
+ VRF_CMD_HELP_STR)
+{
+ char xpath[XPATH_MAXLEN];
+ const char *vrf_name;
+
+ if (vrf)
+ vrf_name = vrf;
+ else
+ vrf_name = VRF_DEFAULT_NAME;
+
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim",
+ vrf_name, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) != CMD_SUCCESS)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ return CMD_SUCCESS;
+}
+
+DEFPY (no_router_pim,
+ no_router_pim_cmd,
+ "no router pim [vrf NAME]",
+ NO_STR
+ "Enable a routing process\n"
+ "Start PIM configuration\n"
+ VRF_CMD_HELP_STR)
+{
+ char xpath[XPATH_MAXLEN];
+ const char *vrf_name;
+
+ if (vrf)
+ vrf_name = vrf;
+ else
+ vrf_name = VRF_DEFAULT_NAME;
+
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim",
+ vrf_name, FRR_PIM_AF_XPATH_VAL);
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+
+DEFPY (pim_spt_switchover_infinity,
+ pim_spt_switchover_infinity_cmd,
+ "spt-switchover infinity-and-beyond",
"SPT-Switchover\n"
"Never switch to SPT Tree\n")
{
return pim_process_spt_switchover_infinity_cmd(vty);
}
+DEFPY_ATTR(ip_pim_spt_switchover_infinity,
+ ip_pim_spt_switchover_infinity_cmd,
+ "ip pim spt-switchover infinity-and-beyond",
+ IP_STR
+ PIM_STR
+ "SPT-Switchover\n"
+ "Never switch to SPT Tree\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFPY (ip_pim_spt_switchover_infinity_plist,
- ip_pim_spt_switchover_infinity_plist_cmd,
- "ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist",
- IP_STR
- PIM_STR
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_spt_switchover_infinity_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_spt_switchover_infinity_plist,
+ pim_spt_switchover_infinity_plist_cmd,
+ "spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist",
"SPT-Switchover\n"
"Never switch to SPT Tree\n"
"Prefix-List to control which groups to switch\n"
@@ -3012,25 +3091,104 @@ DEFPY (ip_pim_spt_switchover_infinity_plist,
{
return pim_process_spt_switchover_prefixlist_cmd(vty, plist);
}
+DEFPY_ATTR(ip_pim_spt_switchover_infinity_plist,
+ ip_pim_spt_switchover_infinity_plist_cmd,
+ "ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist",
+ IP_STR
+ PIM_STR
+ "SPT-Switchover\n"
+ "Never switch to SPT Tree\n"
+ "Prefix-List to control which groups to switch\n"
+ "Prefix-List name\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_spt_switchover_prefixlist_cmd(vty, plist);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFUN (no_ip_pim_spt_switchover_infinity,
- no_ip_pim_spt_switchover_infinity_cmd,
- "no ip pim spt-switchover infinity-and-beyond",
+DEFPY (no_pim_spt_switchover_infinity,
+ no_pim_spt_switchover_infinity_cmd,
+ "no spt-switchover infinity-and-beyond",
NO_STR
- IP_STR
- PIM_STR
"SPT_Switchover\n"
"Never switch to SPT Tree\n")
{
return pim_process_no_spt_switchover_cmd(vty);
}
+DEFPY_ATTR(no_ip_pim_spt_switchover_infinity,
+ no_ip_pim_spt_switchover_infinity_cmd,
+ "no ip pim spt-switchover infinity-and-beyond",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "SPT_Switchover\n"
+ "Never switch to SPT Tree\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_spt_switchover_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFUN (no_ip_pim_spt_switchover_infinity_plist,
- no_ip_pim_spt_switchover_infinity_plist_cmd,
- "no ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME",
+DEFPY (no_pim_spt_switchover_infinity_plist,
+ no_pim_spt_switchover_infinity_plist_cmd,
+ "no spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME",
NO_STR
- IP_STR
- PIM_STR
"SPT_Switchover\n"
"Never switch to SPT Tree\n"
"Prefix-List to control which groups to switch\n"
@@ -3038,28 +3196,61 @@ DEFUN (no_ip_pim_spt_switchover_infinity_plist,
{
return pim_process_no_spt_switchover_cmd(vty);
}
+DEFPY_ATTR(no_ip_pim_spt_switchover_infinity_plist,
+ no_ip_pim_spt_switchover_infinity_plist_cmd,
+ "no ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "SPT_Switchover\n"
+ "Never switch to SPT Tree\n"
+ "Prefix-List to control which groups to switch\n"
+ "Prefix-List name\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_spt_switchover_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
DEFPY (pim_register_accept_list,
pim_register_accept_list_cmd,
- "[no] ip pim register-accept-list PREFIXLIST4_NAME$word",
+ "[no] register-accept-list PREFIXLIST4_NAME$word",
NO_STR
- IP_STR
- PIM_STR
"Only accept registers from a specific source prefix list\n"
"Prefix-List name\n")
{
- const char *vrfname;
char reg_alist_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- "frr-routing:ipv4");
- strlcat(reg_alist_xpath, "/register-accept-list",
- sizeof(reg_alist_xpath));
+ "./register-accept-list");
if (no)
nb_cli_enqueue_change(vty, reg_alist_xpath,
@@ -3070,123 +3261,560 @@ DEFPY (pim_register_accept_list,
return nb_cli_apply_changes(vty, NULL);
}
+DEFPY_ATTR(ip_pim_register_accept_list,
+ ip_pim_register_accept_list_cmd,
+ "[no] ip pim register-accept-list PREFIXLIST4_NAME$word",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Only accept registers from a specific source prefix list\n"
+ "Prefix-List name\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char reg_alist_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFPY (ip_pim_joinprune_time,
- ip_pim_joinprune_time_cmd,
- "ip pim join-prune-interval (1-65535)$jpi",
- IP_STR
- "pim multicast routing\n"
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
+ "./register-accept-list");
+
+ if (no)
+ nb_cli_enqueue_change(vty, reg_alist_xpath, NB_OP_DESTROY, NULL);
+ else
+ nb_cli_enqueue_change(vty, reg_alist_xpath, NB_OP_MODIFY, word);
+
+ ret = nb_cli_apply_changes(vty, NULL);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_joinprune_time,
+ pim_joinprune_time_cmd,
+ "join-prune-interval (1-65535)$jpi",
"Join Prune Send Interval\n"
"Seconds\n")
{
return pim_process_join_prune_cmd(vty, jpi_str);
}
+DEFPY_ATTR(ip_pim_joinprune_time,
+ ip_pim_joinprune_time_cmd,
+ "ip pim join-prune-interval (1-65535)$jpi",
+ IP_STR
+ PIM_STR
+ "Join Prune Send Interval\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_join_prune_cmd(vty, jpi_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFUN (no_ip_pim_joinprune_time,
- no_ip_pim_joinprune_time_cmd,
- "no ip pim join-prune-interval [(1-65535)]",
+DEFPY (no_pim_joinprune_time,
+ no_pim_joinprune_time_cmd,
+ "no join-prune-interval [(1-65535)]",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Join Prune Send Interval\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_join_prune_cmd(vty);
}
+DEFPY_ATTR(no_ip_pim_joinprune_time,
+ no_ip_pim_joinprune_time_cmd,
+ "no ip pim join-prune-interval [(1-65535)]",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Join Prune Send Interval\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFPY (ip_pim_register_suppress,
- ip_pim_register_suppress_cmd,
- "ip pim register-suppress-time (1-65535)$rst",
- IP_STR
- "pim multicast routing\n"
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_join_prune_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_register_suppress,
+ pim_register_suppress_cmd,
+ "register-suppress-time (1-65535)$rst",
"Register Suppress Timer\n"
"Seconds\n")
{
return pim_process_register_suppress_cmd(vty, rst_str);
}
+DEFPY_ATTR(ip_pim_register_suppress,
+ ip_pim_register_suppress_cmd,
+ "ip pim register-suppress-time (1-65535)$rst",
+ IP_STR
+ PIM_STR
+ "Register Suppress Timer\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_register_suppress_cmd(vty, rst_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFUN (no_ip_pim_register_suppress,
- no_ip_pim_register_suppress_cmd,
- "no ip pim register-suppress-time [(1-65535)]",
+DEFPY (no_pim_register_suppress,
+ no_pim_register_suppress_cmd,
+ "no register-suppress-time [(1-65535)]",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Register Suppress Timer\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_register_suppress_cmd(vty);
}
+DEFPY_ATTR(no_ip_pim_register_suppress,
+ no_ip_pim_register_suppress_cmd,
+ "no ip pim register-suppress-time [(1-65535)]",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Register Suppress Timer\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFPY (ip_pim_rp_keep_alive,
- ip_pim_rp_keep_alive_cmd,
- "ip pim rp keep-alive-timer (1-65535)$kat",
- IP_STR
- "pim multicast routing\n"
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_register_suppress_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_rp_keep_alive,
+ pim_rp_keep_alive_cmd,
+ "rp keep-alive-timer (1-65535)$kat",
"Rendezvous Point\n"
"Keep alive Timer\n"
"Seconds\n")
{
return pim_process_rp_kat_cmd(vty, kat_str);
}
+DEFPY_ATTR(ip_pim_rp_keep_alive,
+ ip_pim_rp_keep_alive_cmd,
+ "ip pim rp keep-alive-timer (1-65535)$kat",
+ IP_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "Keep alive Timer\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_rp_kat_cmd(vty, kat_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFUN (no_ip_pim_rp_keep_alive,
- no_ip_pim_rp_keep_alive_cmd,
- "no ip pim rp keep-alive-timer [(1-65535)]",
+DEFPY (no_pim_rp_keep_alive,
+ no_pim_rp_keep_alive_cmd,
+ "no rp keep-alive-timer [(1-65535)]",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Rendezvous Point\n"
"Keep alive Timer\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_rp_kat_cmd(vty);
}
+DEFPY_ATTR(no_ip_pim_rp_keep_alive,
+ no_ip_pim_rp_keep_alive_cmd,
+ "no ip pim rp keep-alive-timer [(1-65535)]",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "Keep alive Timer\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFPY (ip_pim_keep_alive,
- ip_pim_keep_alive_cmd,
- "ip pim keep-alive-timer (1-65535)$kat",
- IP_STR
- "pim multicast routing\n"
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_rp_kat_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_keep_alive,
+ pim_keep_alive_cmd,
+ "keep-alive-timer (1-65535)$kat",
"Keep alive Timer\n"
"Seconds\n")
{
return pim_process_keepalivetimer_cmd(vty, kat_str);
}
+DEFPY_ATTR(ip_pim_keep_alive,
+ ip_pim_keep_alive_cmd,
+ "ip pim keep-alive-timer (1-65535)$kat",
+ IP_STR
+ PIM_STR
+ "Keep alive Timer\n"
+ "Seconds\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_keepalivetimer_cmd(vty, kat_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFUN (no_ip_pim_keep_alive,
- no_ip_pim_keep_alive_cmd,
- "no ip pim keep-alive-timer [(1-65535)]",
+DEFPY (no_pim_keep_alive,
+ no_pim_keep_alive_cmd,
+ "no keep-alive-timer [(1-65535)]",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Keep alive Timer\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_keepalivetimer_cmd(vty);
}
+DEFPY_ATTR(no_ip_pim_keep_alive,
+ no_ip_pim_keep_alive_cmd,
+ "no ip pim keep-alive-timer [(1-65535)]",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Keep alive Timer\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFPY (ip_pim_packets,
- ip_pim_packets_cmd,
- "ip pim packets (1-255)",
- IP_STR
- "pim multicast routing\n"
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_keepalivetimer_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_packets,
+ pim_packets_cmd,
+ "packets (1-255)",
"packets to process at one time per fd\n"
"Number of packets\n")
{
return pim_process_pim_packet_cmd(vty, packets_str);
}
+DEFPY_ATTR(ip_pim_packets,
+ ip_pim_packets_cmd,
+ "ip pim packets (1-255)",
+ IP_STR
+ PIM_STR
+ "packets to process at one time per fd\n"
+ "Number of packets\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFUN (no_ip_pim_packets,
- no_ip_pim_packets_cmd,
- "no ip pim packets [(1-255)]",
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_pim_packet_cmd(vty, packets_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (no_pim_packets,
+ no_pim_packets_cmd,
+ "no packets [(1-255)]",
NO_STR
- IP_STR
- "pim multicast routing\n"
"packets to process at one time per fd\n"
IGNORED_IN_NO_STR)
{
return pim_process_no_pim_packet_cmd(vty);
}
+DEFPY_ATTR(no_ip_pim_packets,
+ no_ip_pim_packets_cmd,
+ "no ip pim packets [(1-255)]",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "packets to process at one time per fd\n"
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_pim_packet_cmd(vty);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
DEFPY (ip_igmp_group_watermark,
ip_igmp_group_watermark_cmd,
@@ -3217,64 +3845,131 @@ DEFPY (no_ip_igmp_group_watermark,
return CMD_SUCCESS;
}
-DEFUN (ip_pim_v6_secondary,
- ip_pim_v6_secondary_cmd,
- "ip pim send-v6-secondary",
- IP_STR
- "pim multicast routing\n"
+DEFPY (pim_v6_secondary,
+ pim_v6_secondary_cmd,
+ "send-v6-secondary",
"Send v6 secondary addresses\n")
{
- const char *vrfname;
char send_v6_secondary_xpath[XPATH_MAXLEN];
+ snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
+ "./send-v6-secondary");
+
+ nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
+ "true");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(ip_pim_v6_secondary,
+ ip_pim_v6_secondary_cmd,
+ "ip pim send-v6-secondary",
+ IP_STR
+ PIM_STR
+ "Send v6 secondary addresses\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char send_v6_secondary_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
- sizeof(send_v6_secondary_xpath));
-
+ "./send-v6-secondary");
nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
"true");
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFUN (no_ip_pim_v6_secondary,
- no_ip_pim_v6_secondary_cmd,
- "no ip pim send-v6-secondary",
+DEFPY (no_pim_v6_secondary,
+ no_pim_v6_secondary_cmd,
+ "no send-v6-secondary",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Send v6 secondary addresses\n")
{
- const char *vrfname;
char send_v6_secondary_xpath[XPATH_MAXLEN];
+ snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
+ "./send-v6-secondary");
+
+ nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
+ "false");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(no_ip_pim_v6_secondary,
+ no_ip_pim_v6_secondary_cmd,
+ "no ip pim send-v6-secondary",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Send v6 secondary addresses\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char send_v6_secondary_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
- sizeof(send_v6_secondary_xpath));
-
+ "./send-v6-secondary");
nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
"false");
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFPY (ip_pim_rp,
- ip_pim_rp_cmd,
- "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
- IP_STR
- "pim multicast routing\n"
+DEFPY (pim_rp,
+ pim_rp_cmd,
+ "rp A.B.C.D$rp [A.B.C.D/M]$gp",
"Rendezvous Point\n"
"ip address of RP\n"
"Group Address range to cover\n")
@@ -3283,12 +3978,52 @@ DEFPY (ip_pim_rp,
return pim_process_rp_cmd(vty, rp_str, group_str);
}
+DEFPY_ATTR(ip_pim_rp,
+ ip_pim_rp_cmd,
+ "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
+ IP_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ip address of RP\n"
+ "Group Address range to cover\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFPY (ip_pim_rp_prefix_list,
- ip_pim_rp_prefix_list_cmd,
- "ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
- IP_STR
- "pim multicast routing\n"
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_rp_cmd(vty, rp_str, group_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_rp_prefix_list,
+ pim_rp_prefix_list_cmd,
+ "rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
"Rendezvous Point\n"
"ip address of RP\n"
"group prefix-list filter\n"
@@ -3296,13 +4031,53 @@ DEFPY (ip_pim_rp_prefix_list,
{
return pim_process_rp_plist_cmd(vty, rp_str, plist);
}
+DEFPY_ATTR(ip_pim_rp_prefix_list,
+ ip_pim_rp_prefix_list_cmd,
+ "ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
+ IP_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ip address of RP\n"
+ "group prefix-list filter\n"
+ "Name of a prefix-list\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_rp_plist_cmd(vty, rp_str, plist);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ip_pim_rp,
- no_ip_pim_rp_cmd,
- "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
+DEFPY (no_pim_rp,
+ no_pim_rp_cmd,
+ "no rp A.B.C.D$rp [A.B.C.D/M]$gp",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Rendezvous Point\n"
"ip address of RP\n"
"Group Address range to cover\n")
@@ -3311,13 +4086,54 @@ DEFPY (no_ip_pim_rp,
return pim_process_no_rp_cmd(vty, rp_str, group_str);
}
+DEFPY_ATTR(no_ip_pim_rp,
+ no_ip_pim_rp_cmd,
+ "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ip address of RP\n"
+ "Group Address range to cover\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_rp_cmd(vty, rp_str, group_str);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY (no_ip_pim_rp_prefix_list,
- no_ip_pim_rp_prefix_list_cmd,
- "no ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
+DEFPY (no_pim_rp_prefix_list,
+ no_pim_rp_prefix_list_cmd,
+ "no rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Rendezvous Point\n"
"ip address of RP\n"
"group prefix-list filter\n"
@@ -3325,104 +4141,264 @@ DEFPY (no_ip_pim_rp_prefix_list,
{
return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
}
+DEFPY_ATTR(no_ip_pim_rp_prefix_list,
+ no_ip_pim_rp_prefix_list_cmd,
+ "no ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Rendezvous Point\n"
+ "ip address of RP\n"
+ "group prefix-list filter\n"
+ "Name of a prefix-list\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
-DEFUN (ip_pim_ssm_prefix_list,
- ip_pim_ssm_prefix_list_cmd,
- "ip pim ssm prefix-list PREFIXLIST4_NAME",
- IP_STR
- "pim multicast routing\n"
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = pim_process_no_rp_plist_cmd(vty, rp_str, plist);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+DEFPY (pim_ssm_prefix_list,
+ pim_ssm_prefix_list_cmd,
+ "ssm prefix-list PREFIXLIST4_NAME$plist",
"Source Specific Multicast\n"
"group range prefix-list filter\n"
"Name of a prefix-list\n")
{
- const char *vrfname;
char ssm_plist_xpath[XPATH_MAXLEN];
+ snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list");
+
+ nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, plist);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(ip_pim_ssm_prefix_list,
+ ip_pim_ssm_prefix_list_cmd,
+ "ip pim ssm prefix-list PREFIXLIST4_NAME$plist",
+ IP_STR
+ PIM_STR
+ "Source Specific Multicast\n"
+ "group range prefix-list filter\n"
+ "Name of a prefix-list\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char ssm_plist_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
+ snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list");
+ nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, plist);
+ ret = nb_cli_apply_changes(vty, NULL);
- nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
- return nb_cli_apply_changes(vty, NULL);
+ return ret;
}
-DEFUN (no_ip_pim_ssm_prefix_list,
- no_ip_pim_ssm_prefix_list_cmd,
- "no ip pim ssm prefix-list",
+DEFPY (no_pim_ssm_prefix_list,
+ no_pim_ssm_prefix_list_cmd,
+ "no ssm prefix-list",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Source Specific Multicast\n"
"group range prefix-list filter\n")
{
- const char *vrfname;
char ssm_plist_xpath[XPATH_MAXLEN];
+ snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list");
+
+ nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(no_ip_pim_ssm_prefix_list,
+ no_ip_pim_ssm_prefix_list_cmd,
+ "no ip pim ssm prefix-list",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Source Specific Multicast\n"
+ "group range prefix-list filter\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char ssm_plist_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
-
+ snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list");
nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFUN (no_ip_pim_ssm_prefix_list_name,
- no_ip_pim_ssm_prefix_list_name_cmd,
- "no ip pim ssm prefix-list PREFIXLIST4_NAME",
+DEFPY (no_pim_ssm_prefix_list_name,
+ no_pim_ssm_prefix_list_name_cmd,
+ "no ssm prefix-list PREFIXLIST4_NAME$plist",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Source Specific Multicast\n"
"group range prefix-list filter\n"
"Name of a prefix-list\n")
{
- const char *vrfname;
const struct lyd_node *ssm_plist_dnode;
char ssm_plist_xpath[XPATH_MAXLEN];
const char *ssm_plist_name;
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
- snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
+ snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "%s/ssm-prefix-list",
+ VTY_CURR_XPATH);
ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
ssm_plist_xpath);
if (!ssm_plist_dnode) {
- vty_out(vty,
- "%% pim ssm prefix-list %s doesn't exist\n",
- argv[5]->arg);
+ vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", plist);
return CMD_WARNING_CONFIG_FAILED;
}
ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
- if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) {
- nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY,
- NULL);
-
+ if (ssm_plist_name && !strcmp(ssm_plist_name, plist)) {
+ nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
- vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
+ vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", plist);
return CMD_WARNING_CONFIG_FAILED;
}
+DEFPY_ATTR(no_ip_pim_ssm_prefix_list_name,
+ no_ip_pim_ssm_prefix_list_name_cmd,
+ "no ip pim ssm prefix-list PREFIXLIST4_NAME$plist",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Source Specific Multicast\n"
+ "group range prefix-list filter\n"
+ "Name of a prefix-list\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ const struct lyd_node *ssm_plist_dnode;
+ char ssm_plist_xpath[XPATH_MAXLEN];
+ const char *ssm_plist_name;
+ int ret = CMD_WARNING_CONFIG_FAILED;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "%s/ssm-prefix-list",
+ VTY_CURR_XPATH);
+ ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
+ ssm_plist_xpath);
+ if (ssm_plist_dnode) {
+ ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
+ if (ssm_plist_name && !strcmp(ssm_plist_name, plist)) {
+ nb_cli_enqueue_change(vty, ssm_plist_xpath,
+ NB_OP_DESTROY, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
+ } else {
+ vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n",
+ plist);
+ }
+ } else {
+ vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", plist);
+ }
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
DEFUN (show_ip_pim_ssm_range,
show_ip_pim_ssm_range_cmd,
@@ -3511,135 +4487,354 @@ DEFPY (show_ip_pim_bsr,
return pim_show_bsr_helper(vrf, vty, !!json);
}
-DEFUN (ip_ssmpingd,
- ip_ssmpingd_cmd,
- "ip ssmpingd [A.B.C.D]",
- IP_STR
+DEFPY (pim_ssmpingd,
+ pim_ssmpingd_cmd,
+ "ssmpingd [A.B.C.D]$src",
CONF_SSMPINGD_STR
"Source address\n")
{
- int idx_ipv4 = 2;
- const char *src_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
+ if (src_str)
+ return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
+ else
+ return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, "0.0.0.0");
+}
+DEFPY_ATTR(ip_pim_ssmpingd,
+ ip_ssmpingd_cmd,
+ "ip ssmpingd [A.B.C.D]$src",
+ IP_STR
+ CONF_SSMPINGD_STR
+ "Source address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
+ if (src_str)
+ ret = pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
+ else
+ ret = pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, "0.0.0.0");
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFUN (no_ip_ssmpingd,
- no_ip_ssmpingd_cmd,
- "no ip ssmpingd [A.B.C.D]",
+DEFPY (no_pim_ssmpingd,
+ no_pim_ssmpingd_cmd,
+ "no ssmpingd [A.B.C.D]$src",
NO_STR
- IP_STR
CONF_SSMPINGD_STR
"Source address\n")
{
- int idx_ipv4 = 3;
- const char *src_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+ if (src_str)
+ return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
+ else
+ return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, "0.0.0.0");
+}
+DEFPY_ATTR(no_ip_pim_ssmpingd,
+ no_ip_ssmpingd_cmd,
+ "no ip ssmpingd [A.B.C.D]$src",
+ NO_STR
+ IP_STR
+ CONF_SSMPINGD_STR
+ "Source address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
- return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (src_str)
+ ret = pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
+ else
+ ret = pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, "0.0.0.0");
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFUN (ip_pim_ecmp,
- ip_pim_ecmp_cmd,
- "ip pim ecmp",
- IP_STR
- "pim multicast routing\n"
+DEFPY (pim_ecmp,
+ pim_ecmp_cmd,
+ "ecmp",
"Enable PIM ECMP \n")
{
- const char *vrfname;
char ecmp_xpath[XPATH_MAXLEN];
+ snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp");
+ nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(ip_pim_ecmp,
+ ip_pim_ecmp_cmd,
+ "ip pim ecmp",
+ IP_STR
+ PIM_STR
+ "Enable PIM ECMP \n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char ecmp_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
-
+ snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp");
nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
- return nb_cli_apply_changes(vty, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFUN (no_ip_pim_ecmp,
- no_ip_pim_ecmp_cmd,
- "no ip pim ecmp",
+DEFPY (no_pim_ecmp,
+ no_pim_ecmp_cmd,
+ "no ecmp",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Disable PIM ECMP \n")
{
- const char *vrfname;
char ecmp_xpath[XPATH_MAXLEN];
+ snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp");
+ nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(no_ip_pim_ecmp,
+ no_ip_pim_ecmp_cmd,
+ "no ip pim ecmp",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Disable PIM ECMP \n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char ecmp_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
-
+ snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp");
nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false");
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFUN (ip_pim_ecmp_rebalance,
- ip_pim_ecmp_rebalance_cmd,
- "ip pim ecmp rebalance",
- IP_STR
- "pim multicast routing\n"
+DEFPY (pim_ecmp_rebalance,
+ pim_ecmp_rebalance_cmd,
+ "ecmp rebalance",
"Enable PIM ECMP \n"
"Enable PIM ECMP Rebalance\n")
{
- const char *vrfname;
char ecmp_xpath[XPATH_MAXLEN];
char ecmp_rebalance_xpath[XPATH_MAXLEN];
+ snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp");
+ snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
+ "./ecmp-rebalance");
+
+ nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
+ nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(ip_pim_ecmp_rebalance,
+ ip_pim_ecmp_rebalance_cmd,
+ "ip pim ecmp rebalance",
+ IP_STR
+ PIM_STR
+ "Enable PIM ECMP \n"
+ "Enable PIM ECMP Rebalance\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char ecmp_xpath[XPATH_MAXLEN];
+ char ecmp_rebalance_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
+ snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp");
snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
- sizeof(ecmp_rebalance_xpath));
-
+ "./ecmp-rebalance");
nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true");
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFUN (no_ip_pim_ecmp_rebalance,
- no_ip_pim_ecmp_rebalance_cmd,
- "no ip pim ecmp rebalance",
+DEFPY (no_pim_ecmp_rebalance,
+ no_pim_ecmp_rebalance_cmd,
+ "no ecmp rebalance",
NO_STR
- IP_STR
- "pim multicast routing\n"
"Disable PIM ECMP \n"
"Disable PIM ECMP Rebalance\n")
{
- const char *vrfname;
char ecmp_rebalance_xpath[XPATH_MAXLEN];
+ snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
+ "./ecmp-rebalance");
+
+ nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(no_ip_pim_ecmp_rebalance,
+ no_ip_pim_ecmp_rebalance_cmd,
+ "no ip pim ecmp rebalance",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "Disable PIM ECMP \n"
+ "Disable PIM ECMP Rebalance\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char ecmp_rebalance_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
- sizeof(ecmp_rebalance_xpath));
-
+ "./ecmp-rebalance");
nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false");
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
DEFUN (interface_ip_igmp,
@@ -4648,15 +5843,24 @@ DEFPY (debug_pim_zebra,
return CMD_SUCCESS;
}
-DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
- DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
+DEFUN(debug_pim_mlag,
+ debug_pim_mlag_cmd,
+ "debug pim mlag",
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_MLAG_STR)
{
PIM_DO_DEBUG_MLAG;
return CMD_SUCCESS;
}
-DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
- NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
+DEFUN(no_debug_pim_mlag,
+ no_debug_pim_mlag_cmd,
+ "no debug pim mlag",
+ NO_STR
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_MLAG_STR)
{
PIM_DONT_DEBUG_MLAG;
return CMD_SUCCESS;
@@ -5016,145 +6220,333 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
"Desired min transmit interval\n")
#endif /* !HAVE_BFDD */
-DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
- "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
- IP_STR
+DEFPY(pim_msdp_peer, pim_msdp_peer_cmd,
+ "msdp peer A.B.C.D$peer source A.B.C.D$source",
CFG_MSDP_STR
"Configure MSDP peer\n"
"Peer IP address\n"
"Source address for TCP connection\n"
"Local IP address\n")
{
- const char *vrfname;
- char temp_xpath[XPATH_MAXLEN];
char msdp_peer_source_xpath[XPATH_MAXLEN];
+ snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
+ "./msdp-peer[peer-ip='%s']/source-ip", peer_str);
+ nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
+ source_str);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(ip_pim_msdp_peer,
+ ip_msdp_peer_cmd,
+ "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP peer\n"
+ "Peer IP address\n"
+ "Source address for TCP connection\n"
+ "Local IP address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char msdp_peer_source_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- "frr-routing:ipv4");
- snprintf(temp_xpath, sizeof(temp_xpath),
- "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
- strlcat(msdp_peer_source_xpath, temp_xpath,
- sizeof(msdp_peer_source_xpath));
-
+ "./msdp-peer[peer-ip='%s']/source-ip", peer_str);
nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
source_str);
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty,
- FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
- "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
- IP_STR
+DEFPY(pim_msdp_timers, pim_msdp_timers_cmd,
+ "msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
CFG_MSDP_STR
"MSDP timers configuration\n"
"Keep alive period (in seconds)\n"
"Hold time period (in seconds)\n"
"Connection retry period (in seconds)\n")
{
+ nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_MODIFY,
+ holdtime_str);
+ nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_MODIFY,
+ keepalive_str);
+ if (connretry_str)
+ nb_cli_enqueue_change(vty, "./msdp/connection-retry",
+ NB_OP_MODIFY, connretry_str);
+ else
+ nb_cli_enqueue_change(vty, "./msdp/connection-retry",
+ NB_OP_DESTROY, NULL);
+
+ nb_cli_apply_changes(vty, NULL);
+ return CMD_SUCCESS;
+}
+DEFPY_ATTR(ip_pim_msdp_timers,
+ ip_msdp_timers_cmd,
+ "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
+ IP_STR
+ CFG_MSDP_STR
+ "MSDP timers configuration\n"
+ "Keep alive period (in seconds)\n"
+ "Hold time period (in seconds)\n"
+ "Connection retry period (in seconds)\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
- nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
+ nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_MODIFY,
+ holdtime_str);
+ nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_MODIFY,
+ keepalive_str);
if (connretry_str)
- nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
- connretry_str);
+ nb_cli_enqueue_change(vty, "./msdp/connection-retry",
+ NB_OP_MODIFY, connretry_str);
else
- nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
- NULL);
+ nb_cli_enqueue_change(vty, "./msdp/connection-retry",
+ NB_OP_DESTROY, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
- nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
- vrfname, "frr-routing:ipv4");
- return CMD_SUCCESS;
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFPY(no_ip_msdp_timers, no_ip_msdp_timers_cmd,
- "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
+DEFPY(no_pim_msdp_timers, no_pim_msdp_timers_cmd,
+ "no msdp timers [(1-65535) (1-65535) [(1-65535)]]",
NO_STR
- IP_STR
CFG_MSDP_STR
"MSDP timers configuration\n"
IGNORED_IN_NO_STR
IGNORED_IN_NO_STR
IGNORED_IN_NO_STR)
{
+ nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_DESTROY, NULL);
+ nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_DESTROY, NULL);
+ nb_cli_enqueue_change(vty, "./msdp/connection-retry", NB_OP_DESTROY,
+ NULL);
+ nb_cli_apply_changes(vty, NULL);
+ return CMD_SUCCESS;
+}
+DEFPY_ATTR(no_ip_pim_msdp_timers,
+ no_ip_msdp_timers_cmd,
+ "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "MSDP timers configuration\n"
+ IGNORED_IN_NO_STR
+ IGNORED_IN_NO_STR
+ IGNORED_IN_NO_STR,
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ int ret;
const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- nb_cli_enqueue_change(vty, "./hold-time", NB_OP_DESTROY, NULL);
- nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_DESTROY, NULL);
- nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, NULL);
+ nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_DESTROY, NULL);
+ nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_DESTROY, NULL);
+ nb_cli_enqueue_change(vty, "./msdp/connection-retry", NB_OP_DESTROY,
+ NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
- nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
- vrfname, "frr-routing:ipv4");
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (no_ip_msdp_peer,
- no_ip_msdp_peer_cmd,
- "no ip msdp peer A.B.C.D",
+DEFPY (no_pim_msdp_peer,
+ no_pim_msdp_peer_cmd,
+ "no msdp peer A.B.C.D",
NO_STR
- IP_STR
CFG_MSDP_STR
"Delete MSDP peer\n"
"peer ip address\n")
{
- const char *vrfname;
char msdp_peer_xpath[XPATH_MAXLEN];
- char temp_xpath[XPATH_MAXLEN];
+
+ snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
+ "./msdp-peer[peer-ip='%s']", peer_str);
+ nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(no_ip_pim_msdp_peer,
+ no_ip_msdp_peer_cmd,
+ "no ip msdp peer A.B.C.D",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP peer\n"
+ "peer ip address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char msdp_peer_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- snprintf(temp_xpath, sizeof(temp_xpath),
- "/msdp-peer[peer-ip='%s']",
- argv[4]->arg);
-
- strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath));
-
+ "./msdp-peer[peer-ip='%s']", peer_str);
nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFPY(ip_msdp_mesh_group_member,
- ip_msdp_mesh_group_member_cmd,
- "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
- IP_STR
+DEFPY(pim_msdp_mesh_group_member,
+ pim_msdp_mesh_group_member_cmd,
+ "msdp mesh-group WORD$gname member A.B.C.D$maddr",
CFG_MSDP_STR
"Configure MSDP mesh-group\n"
"Mesh group name\n"
"Mesh group member\n"
"Peer IP address\n")
{
- const char *vrfname;
char xpath_value[XPATH_MAXLEN];
+ /* Create mesh group. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ "./msdp-mesh-groups[name='%s']", gname);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+
+ /* Create mesh group member. */
+ strlcat(xpath_value, "/members[address='", sizeof(xpath_value));
+ strlcat(xpath_value, maddr_str, sizeof(xpath_value));
+ strlcat(xpath_value, "']", sizeof(xpath_value));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(ip_pim_msdp_mesh_group_member,
+ ip_msdp_mesh_group_member_cmd,
+ "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP mesh-group\n"
+ "Mesh group name\n"
+ "Mesh group member\n"
+ "Peer IP address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char xpath_value[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
/* Create mesh group. */
snprintf(xpath_value, sizeof(xpath_value),
- FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ "./msdp-mesh-groups[name='%s']", gname);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
/* Create mesh group member. */
@@ -5162,33 +6554,32 @@ DEFPY(ip_msdp_mesh_group_member,
strlcat(xpath_value, maddr_str, sizeof(xpath_value));
strlcat(xpath_value, "']", sizeof(xpath_value));
nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFPY(no_ip_msdp_mesh_group_member,
- no_ip_msdp_mesh_group_member_cmd,
- "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
+DEFPY(no_pim_msdp_mesh_group_member,
+ no_pim_msdp_mesh_group_member_cmd,
+ "no msdp mesh-group WORD$gname member A.B.C.D$maddr",
NO_STR
- IP_STR
CFG_MSDP_STR
"Delete MSDP mesh-group member\n"
"Mesh group name\n"
"Mesh group member\n"
"Peer IP address\n")
{
- const char *vrfname;
char xpath_value[XPATH_MAXLEN];
char xpath_member_value[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
/* Get mesh group base XPath. */
snprintf(xpath_value, sizeof(xpath_value),
- FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname);
if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
vty_out(vty, "%% mesh-group does not exist\n");
@@ -5217,59 +6608,221 @@ DEFPY(no_ip_msdp_mesh_group_member,
return nb_cli_apply_changes(vty, NULL);
}
+DEFPY_ATTR(no_ip_pim_msdp_mesh_group_member,
+ no_ip_msdp_mesh_group_member_cmd,
+ "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group member\n"
+ "Mesh group name\n"
+ "Mesh group member\n"
+ "Peer IP address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char xpath_value[XPATH_MAXLEN];
+ char xpath_member_value[XPATH_MAXLEN];
+ int ret = CMD_WARNING_CONFIG_FAILED;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Get mesh group base XPath. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname);
+
+ if (yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
+ /* Remove mesh group member. */
+ strlcpy(xpath_member_value, xpath_value,
+ sizeof(xpath_member_value));
+ strlcat(xpath_member_value, "/members[address='",
+ sizeof(xpath_member_value));
+ strlcat(xpath_member_value, maddr_str,
+ sizeof(xpath_member_value));
+ strlcat(xpath_member_value, "']", sizeof(xpath_member_value));
+ if (yang_dnode_exists(vty->candidate_config->dnode,
+ xpath_member_value)) {
+ nb_cli_enqueue_change(vty, xpath_member_value,
+ NB_OP_DESTROY, NULL);
+
+ /*
+ * If this is the last member, then we must remove the group altogether
+ * to not break legacy CLI behaviour.
+ */
+ pim_cli_legacy_mesh_group_behavior(vty, gname);
+ ret = nb_cli_apply_changes(vty, NULL);
+ } else {
+ vty_out(vty, "%% mesh-group member does not exist\n");
+ }
+ } else {
+ vty_out(vty, "%% mesh-group does not exist\n");
+ }
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
-DEFPY(ip_msdp_mesh_group_source,
- ip_msdp_mesh_group_source_cmd,
- "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
- IP_STR
+DEFPY(pim_msdp_mesh_group_source,
+ pim_msdp_mesh_group_source_cmd,
+ "msdp mesh-group WORD$gname source A.B.C.D$saddr",
CFG_MSDP_STR
"Configure MSDP mesh-group\n"
"Mesh group name\n"
"Mesh group local address\n"
"Source IP address for the TCP connection\n")
{
- const char *vrfname;
char xpath_value[XPATH_MAXLEN];
+ /* Create mesh group. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ "./msdp-mesh-groups[name='%s']", gname);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+
+ /* Create mesh group source. */
+ strlcat(xpath_value, "/source", sizeof(xpath_value));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(ip_pim_msdp_mesh_group_source,
+ ip_msdp_mesh_group_source_cmd,
+ "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP mesh-group\n"
+ "Mesh group name\n"
+ "Mesh group local address\n"
+ "Source IP address for the TCP connection\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char xpath_value[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
/* Create mesh group. */
snprintf(xpath_value, sizeof(xpath_value),
- FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ "./msdp-mesh-groups[name='%s']", gname);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
-
/* Create mesh group source. */
strlcat(xpath_value, "/source", sizeof(xpath_value));
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFPY(no_ip_msdp_mesh_group_source,
- no_ip_msdp_mesh_group_source_cmd,
- "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
+DEFPY(no_pim_msdp_mesh_group_source,
+ no_pim_msdp_mesh_group_source_cmd,
+ "no msdp mesh-group WORD$gname source [A.B.C.D]",
NO_STR
- IP_STR
CFG_MSDP_STR
"Delete MSDP mesh-group source\n"
"Mesh group name\n"
"Mesh group source\n"
"Mesh group local address\n")
{
- const char *vrfname;
char xpath_value[XPATH_MAXLEN];
+ /* Get mesh group base XPath. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ "./msdp-mesh-groups[name='%s']", gname);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
+
+ /* Create mesh group source. */
+ strlcat(xpath_value, "/source", sizeof(xpath_value));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
+
+ /*
+ * If this is the last member, then we must remove the group altogether
+ * to not break legacy CLI behaviour.
+ */
+ pim_cli_legacy_mesh_group_behavior(vty, gname);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(no_ip_pim_msdp_mesh_group_source,
+ no_ip_msdp_mesh_group_source_cmd,
+ "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group source\n"
+ "Mesh group name\n"
+ "Mesh group source\n"
+ "Mesh group local address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char xpath_value[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
/* Get mesh group base XPath. */
snprintf(xpath_value, sizeof(xpath_value),
- FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ "./msdp-mesh-groups[name='%s']", gname);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
/* Create mesh group source. */
@@ -5281,36 +6834,83 @@ DEFPY(no_ip_msdp_mesh_group_source,
* to not break legacy CLI behaviour.
*/
pim_cli_legacy_mesh_group_behavior(vty, gname);
+ ret = nb_cli_apply_changes(vty, NULL);
- return nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
}
-DEFPY(no_ip_msdp_mesh_group,
- no_ip_msdp_mesh_group_cmd,
- "no ip msdp mesh-group WORD$gname",
+DEFPY(no_pim_msdp_mesh_group,
+ no_pim_msdp_mesh_group_cmd,
+ "no msdp mesh-group WORD$gname",
NO_STR
- IP_STR
CFG_MSDP_STR
"Delete MSDP mesh-group\n"
"Mesh group name\n")
{
- const char *vrfname;
char xpath_value[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
/* Get mesh group base XPath. */
snprintf(xpath_value, sizeof(xpath_value),
- FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname);
if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
return CMD_SUCCESS;
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
+DEFPY_ATTR(no_ip_pim_msdp_mesh_group,
+ no_ip_msdp_mesh_group_cmd,
+ "no ip msdp mesh-group WORD$gname",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group\n"
+ "Mesh group name\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char xpath_value[XPATH_MAXLEN];
+ int ret = CMD_SUCCESS;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Get mesh group base XPath. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname);
+ if (yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
+ }
+
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
struct json_object *json)
@@ -5329,7 +6929,8 @@ static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
if (json) {
/* currently there is only one mesh group but we should still
* make
- * it a dict with mg-name as key */
+ * it a dict with mg-name as key
+ */
json_mg_row = json_object_new_object();
json_object_string_add(json_mg_row, "name",
mg->mesh_group_name);
@@ -6311,31 +7912,66 @@ DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
return CMD_SUCCESS;
}
-DEFUN_HIDDEN (no_ip_pim_mlag,
- no_ip_pim_mlag_cmd,
- "no ip pim mlag",
+DEFPY_HIDDEN (no_pim_mlag,
+ no_pim_mlag_cmd,
+ "no mlag",
NO_STR
- IP_STR
- PIM_STR
"MLAG\n")
{
char mlag_xpath[XPATH_MAXLEN];
- snprintf(mlag_xpath, sizeof(mlag_xpath), FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
- strlcat(mlag_xpath, "/mlag", sizeof(mlag_xpath));
+ snprintf(mlag_xpath, sizeof(mlag_xpath), "./mlag");
+ nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+DEFPY_ATTR(no_ip_pim_mlag,
+ no_ip_pim_mlag_cmd,
+ "no ip pim mlag",
+ NO_STR
+ IP_STR
+ PIM_STR
+ "MLAG\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
+{
+ char mlag_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ snprintf(mlag_xpath, sizeof(mlag_xpath), "./mlag");
nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL);
+ ret = nb_cli_apply_changes(vty, NULL);
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
- return nb_cli_apply_changes(vty, NULL);
+ return ret;
}
-DEFUN_HIDDEN (ip_pim_mlag,
- ip_pim_mlag_cmd,
- "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
- IP_STR
- PIM_STR
+DEFPY_HIDDEN (pim_mlag,
+ pim_mlag_cmd,
+ "mlag INTERFACE$iface role [primary|secondary]$role state [up|down]$state addr A.B.C.D$addr",
"MLAG\n"
"peerlink sub interface\n"
"MLAG role\n"
@@ -6347,83 +7983,153 @@ DEFUN_HIDDEN (ip_pim_mlag,
"configure PIP\n"
"unique ip address\n")
{
- int idx;
char mlag_peerlink_rif_xpath[XPATH_MAXLEN];
char mlag_my_role_xpath[XPATH_MAXLEN];
char mlag_peer_state_xpath[XPATH_MAXLEN];
char mlag_reg_address_xpath[XPATH_MAXLEN];
snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
- strlcat(mlag_peerlink_rif_xpath, "/mlag/peerlink-rif",
- sizeof(mlag_peerlink_rif_xpath));
-
- idx = 3;
- nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY,
- argv[idx]->arg);
+ "./mlag/peerlink-rif");
+ nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY, iface);
snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
- strlcat(mlag_my_role_xpath, "/mlag/my-role",
- sizeof(mlag_my_role_xpath));
-
- idx += 2;
- if (!strcmp(argv[idx]->arg, "primary")) {
+ "./mlag/my-role");
+ if (!strcmp(role, "primary")) {
nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
"MLAG_ROLE_PRIMARY");
-
- } else if (!strcmp(argv[idx]->arg, "secondary")) {
+ } else if (!strcmp(role, "secondary")) {
nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
"MLAG_ROLE_SECONDARY");
-
} else {
- vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
+ vty_out(vty, "unknown MLAG role %s\n", role);
return CMD_WARNING;
}
snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
- strlcat(mlag_peer_state_xpath, "/mlag/peer-state",
- sizeof(mlag_peer_state_xpath));
-
- idx += 2;
- if (!strcmp(argv[idx]->arg, "up")) {
+ "./mlag/peer-state");
+ if (!strcmp(state, "up")) {
nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
"true");
-
- } else if (strcmp(argv[idx]->arg, "down")) {
+ } else if (strcmp(state, "down")) {
nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
"false");
-
} else {
- vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
+ vty_out(vty, "unknown MLAG state %s\n", state);
return CMD_WARNING;
}
snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath),
- FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
- strlcat(mlag_reg_address_xpath, "/mlag/reg-address",
- sizeof(mlag_reg_address_xpath));
-
- idx += 2;
+ "./mlag/reg-address");
nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY,
- argv[idx]->arg);
+ addr_str);
return nb_cli_apply_changes(vty, NULL);
}
-
-void pim_cmd_init(void)
+DEFPY_ATTR(ip_pim_mlag,
+ ip_pim_mlag_cmd,
+ "ip pim mlag INTERFACE$iface role [primary|secondary]$role state [up|down]$state addr A.B.C.D$addr",
+ IP_STR
+ PIM_STR
+ "MLAG\n"
+ "peerlink sub interface\n"
+ "MLAG role\n"
+ "MLAG role primary\n"
+ "MLAG role secondary\n"
+ "peer session state\n"
+ "peer session state up\n"
+ "peer session state down\n"
+ "configure PIP\n"
+ "unique ip address\n",
+ CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED)
{
- if_cmd_init(pim_interface_config_write);
+ char mlag_peerlink_rif_xpath[XPATH_MAXLEN];
+ char mlag_my_role_xpath[XPATH_MAXLEN];
+ char mlag_peer_state_xpath[XPATH_MAXLEN];
+ char mlag_reg_address_xpath[XPATH_MAXLEN];
+ int ret;
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+ int orig_node = -1;
- install_node(&debug_node);
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname) {
+ snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (nb_cli_apply_changes_clear_pending(vty, NULL) ==
+ CMD_SUCCESS) {
+ orig_node = vty->node;
+ VTY_PUSH_XPATH(PIM_NODE, xpath);
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ vty_out(vty, "%% Failed to determine vrf name\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
+ snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath),
+ "./mlag/peerlink-rif");
+ nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY, iface);
+
+ snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath),
+ "./mlag/my-role");
+ if (!strcmp(role, "primary")) {
+ nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
+ "MLAG_ROLE_PRIMARY");
+ } else if (!strcmp(role, "secondary")) {
+ nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
+ "MLAG_ROLE_SECONDARY");
+ } else {
+ vty_out(vty, "unknown MLAG role %s\n", role);
+ ret = CMD_WARNING;
+ goto done;
+ }
+
+ snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath),
+ "./mlag/peer-state");
+ if (!strcmp(state, "up")) {
+ nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
+ "true");
+ } else if (strcmp(state, "down")) {
+ nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
+ "false");
+ } else {
+ vty_out(vty, "unknown MLAG state %s\n", state);
+ ret = CMD_WARNING;
+ goto done;
+ }
+
+ snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath),
+ "./mlag/reg-address");
+ nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY,
+ addr_str);
+
+ ret = nb_cli_apply_changes(vty, NULL);
+done:
+ if (orig_node != -1) {
+ vty->node = orig_node;
+ vty->xpath_index--;
+ }
+
+ return ret;
+}
+
+struct cmd_node pim_node = {
+ .name = "pim",
+ .node = PIM_NODE,
+ .parent_node = CONFIG_NODE,
+ .prompt = "%s(config-pim)# ",
+ .config_write = pim_router_config_write,
+};
+
+/* This function installs all of the deprecated PIM configuration commands that live in the global config and/or VRF nodes
+ * This configuration has been moved to the new 'router pim' config node instead like all the other routing protocols.
+ * No new commands should be added here.
+ */
+static void pim_install_deprecated(void)
+{
install_element(CONFIG_NODE, &ip_pim_rp_cmd);
install_element(VRF_NODE, &ip_pim_rp_cmd);
install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
@@ -6449,8 +8155,8 @@ void pim_cmd_init(void)
install_element(CONFIG_NODE,
&no_ip_pim_spt_switchover_infinity_plist_cmd);
install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
- install_element(CONFIG_NODE, &pim_register_accept_list_cmd);
- install_element(VRF_NODE, &pim_register_accept_list_cmd);
+ install_element(CONFIG_NODE, &ip_pim_register_accept_list_cmd);
+ install_element(VRF_NODE, &ip_pim_register_accept_list_cmd);
install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
@@ -6467,14 +8173,6 @@ void pim_cmd_init(void)
install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
- install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
- install_element(VRF_NODE, &ip_ssmpingd_cmd);
- install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
- install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
- install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
- install_element(VRF_NODE, &ip_msdp_peer_cmd);
- install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
- install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
install_element(VRF_NODE, &ip_pim_ecmp_cmd);
install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
@@ -6485,10 +8183,87 @@ void pim_cmd_init(void)
install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
- install_element(CONFIG_NODE, &ip_igmp_group_watermark_cmd);
- install_element(VRF_NODE, &ip_igmp_group_watermark_cmd);
- install_element(CONFIG_NODE, &no_ip_igmp_group_watermark_cmd);
- install_element(VRF_NODE, &no_ip_igmp_group_watermark_cmd);
+
+ install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
+ install_element(VRF_NODE, &ip_ssmpingd_cmd);
+ install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
+ install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
+
+ install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
+ install_element(VRF_NODE, &ip_msdp_peer_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
+ install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
+ install_element(VRF_NODE, &ip_msdp_timers_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd);
+ install_element(VRF_NODE, &no_ip_msdp_timers_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
+ install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
+ install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
+ install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
+ install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd);
+ install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd);
+}
+
+void pim_cmd_init(void)
+{
+ if_cmd_init(pim_interface_config_write);
+
+ install_node(&debug_node);
+
+ install_element(CONFIG_NODE, &router_pim_cmd);
+ install_element(CONFIG_NODE, &no_router_pim_cmd);
+
+ install_node(&pim_node);
+ install_default(PIM_NODE);
+
+ install_element(PIM_NODE, &pim_rp_cmd);
+ install_element(PIM_NODE, &no_pim_rp_cmd);
+ install_element(PIM_NODE, &pim_rp_prefix_list_cmd);
+ install_element(PIM_NODE, &no_pim_rp_prefix_list_cmd);
+ install_element(PIM_NODE, &no_pim_ssm_prefix_list_cmd);
+ install_element(PIM_NODE, &no_pim_ssm_prefix_list_name_cmd);
+ install_element(PIM_NODE, &pim_ssm_prefix_list_cmd);
+ install_element(PIM_NODE, &pim_register_suppress_cmd);
+ install_element(PIM_NODE, &no_pim_register_suppress_cmd);
+ install_element(PIM_NODE, &pim_spt_switchover_infinity_cmd);
+ install_element(PIM_NODE, &pim_spt_switchover_infinity_plist_cmd);
+ install_element(PIM_NODE, &no_pim_spt_switchover_infinity_cmd);
+ install_element(PIM_NODE, &no_pim_spt_switchover_infinity_plist_cmd);
+ install_element(PIM_NODE, &pim_register_accept_list_cmd);
+ install_element(PIM_NODE, &pim_joinprune_time_cmd);
+ install_element(PIM_NODE, &no_pim_joinprune_time_cmd);
+ install_element(PIM_NODE, &pim_keep_alive_cmd);
+ install_element(PIM_NODE, &pim_rp_keep_alive_cmd);
+ install_element(PIM_NODE, &no_pim_keep_alive_cmd);
+ install_element(PIM_NODE, &no_pim_rp_keep_alive_cmd);
+ install_element(PIM_NODE, &pim_packets_cmd);
+ install_element(PIM_NODE, &no_pim_packets_cmd);
+ install_element(PIM_NODE, &pim_v6_secondary_cmd);
+ install_element(PIM_NODE, &no_pim_v6_secondary_cmd);
+ install_element(PIM_NODE, &pim_ecmp_cmd);
+ install_element(PIM_NODE, &no_pim_ecmp_cmd);
+ install_element(PIM_NODE, &pim_ecmp_rebalance_cmd);
+ install_element(PIM_NODE, &no_pim_ecmp_rebalance_cmd);
+ install_element(PIM_NODE, &pim_mlag_cmd);
+ install_element(PIM_NODE, &no_pim_mlag_cmd);
+
+ install_element(PIM_NODE, &pim_ssmpingd_cmd);
+ install_element(PIM_NODE, &no_pim_ssmpingd_cmd);
+
+ install_element(PIM_NODE, &pim_msdp_peer_cmd);
+ install_element(PIM_NODE, &no_pim_msdp_peer_cmd);
+ install_element(PIM_NODE, &pim_msdp_timers_cmd);
+ install_element(PIM_NODE, &no_pim_msdp_timers_cmd);
+ install_element(PIM_NODE, &pim_msdp_mesh_group_member_cmd);
+ install_element(PIM_NODE, &no_pim_msdp_mesh_group_member_cmd);
+ install_element(PIM_NODE, &pim_msdp_mesh_group_source_cmd);
+ install_element(PIM_NODE, &no_pim_msdp_mesh_group_source_cmd);
+ install_element(PIM_NODE, &no_pim_msdp_mesh_group_cmd);
install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
@@ -6534,6 +8309,22 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
+ install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
+ install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
+ /* Install BSM command */
+ install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
+ install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
+ /* Install BFD command */
+ install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
+ install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
+#if HAVE_BFDD == 0
+ install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
+#endif /* !HAVE_BFDD */
+
install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
@@ -6590,6 +8381,20 @@ void pim_cmd_init(void)
install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
+
+ install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
@@ -6604,134 +8409,98 @@ void pim_cmd_init(void)
install_element(ENABLE_NODE, &show_debugging_pim_cmd);
install_element(ENABLE_NODE, &debug_igmp_cmd);
- install_element(ENABLE_NODE, &no_debug_igmp_cmd);
- install_element(ENABLE_NODE, &debug_igmp_events_cmd);
- install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
- install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
- install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
- install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
- install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
- install_element(ENABLE_NODE, &debug_igmp_trace_detail_cmd);
- install_element(ENABLE_NODE, &no_debug_igmp_trace_detail_cmd);
- install_element(ENABLE_NODE, &debug_mroute_cmd);
- install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
- install_element(ENABLE_NODE, &no_debug_mroute_cmd);
- install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
- install_element(ENABLE_NODE, &debug_pim_static_cmd);
- install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
- install_element(ENABLE_NODE, &debug_pim_cmd);
- install_element(ENABLE_NODE, &debug_pim_nht_cmd);
- install_element(ENABLE_NODE, &debug_pim_nht_det_cmd);
- install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
- install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
- install_element(ENABLE_NODE, &debug_pim_events_cmd);
- install_element(ENABLE_NODE, &debug_pim_packets_cmd);
- install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
- install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
- install_element(ENABLE_NODE, &debug_pim_trace_cmd);
- install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
- install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
- install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
- install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
- install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
- install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
- install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
- install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
- install_element(ENABLE_NODE, &debug_msdp_cmd);
- install_element(ENABLE_NODE, &no_debug_msdp_cmd);
- install_element(ENABLE_NODE, &debug_msdp_events_cmd);
- install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
- install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
- install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
- install_element(ENABLE_NODE, &debug_mtrace_cmd);
- install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
- install_element(ENABLE_NODE, &debug_bsm_cmd);
- install_element(ENABLE_NODE, &no_debug_bsm_cmd);
-
install_element(CONFIG_NODE, &debug_igmp_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_cmd);
install_element(CONFIG_NODE, &no_debug_igmp_cmd);
+ install_element(ENABLE_NODE, &debug_igmp_events_cmd);
install_element(CONFIG_NODE, &debug_igmp_events_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
+ install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
+ install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
+ install_element(ENABLE_NODE, &debug_igmp_trace_detail_cmd);
install_element(CONFIG_NODE, &debug_igmp_trace_detail_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_trace_detail_cmd);
install_element(CONFIG_NODE, &no_debug_igmp_trace_detail_cmd);
+ install_element(ENABLE_NODE, &debug_mroute_cmd);
install_element(CONFIG_NODE, &debug_mroute_cmd);
+ install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
+ install_element(ENABLE_NODE, &no_debug_mroute_cmd);
install_element(CONFIG_NODE, &no_debug_mroute_cmd);
+ install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
+ install_element(ENABLE_NODE, &debug_pim_static_cmd);
install_element(CONFIG_NODE, &debug_pim_static_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
+ install_element(ENABLE_NODE, &debug_pim_cmd);
install_element(CONFIG_NODE, &debug_pim_cmd);
+ install_element(ENABLE_NODE, &debug_pim_nht_cmd);
install_element(CONFIG_NODE, &debug_pim_nht_cmd);
+ install_element(ENABLE_NODE, &debug_pim_nht_det_cmd);
install_element(CONFIG_NODE, &debug_pim_nht_det_cmd);
+ install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
+ install_element(ENABLE_NODE, &debug_pim_events_cmd);
install_element(CONFIG_NODE, &debug_pim_events_cmd);
+ install_element(ENABLE_NODE, &debug_pim_packets_cmd);
install_element(CONFIG_NODE, &debug_pim_packets_cmd);
+ install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
install_element(CONFIG_NODE, &debug_pim_packetdump_send_cmd);
+ install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
install_element(CONFIG_NODE, &debug_pim_packetdump_recv_cmd);
+ install_element(ENABLE_NODE, &debug_pim_trace_cmd);
install_element(CONFIG_NODE, &debug_pim_trace_cmd);
+ install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
+ install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
+ install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
+ install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
+ install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
install_element(CONFIG_NODE, &debug_pim_mlag_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd);
+ install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
+ install_element(ENABLE_NODE, &debug_msdp_cmd);
install_element(CONFIG_NODE, &debug_msdp_cmd);
+ install_element(ENABLE_NODE, &no_debug_msdp_cmd);
install_element(CONFIG_NODE, &no_debug_msdp_cmd);
+ install_element(ENABLE_NODE, &debug_msdp_events_cmd);
install_element(CONFIG_NODE, &debug_msdp_events_cmd);
+ install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
+ install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
+ install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
+ install_element(ENABLE_NODE, &debug_mtrace_cmd);
install_element(CONFIG_NODE, &debug_mtrace_cmd);
+ install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
+ install_element(ENABLE_NODE, &debug_bsm_cmd);
install_element(CONFIG_NODE, &debug_bsm_cmd);
+ install_element(ENABLE_NODE, &no_debug_bsm_cmd);
install_element(CONFIG_NODE, &no_debug_bsm_cmd);
- install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
- install_element(VRF_NODE, &ip_msdp_timers_cmd);
- install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd);
- install_element(VRF_NODE, &no_ip_msdp_timers_cmd);
- install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
- install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
- install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
- install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
- install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
- install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
- install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
- install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
- install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd);
- install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
- install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
- install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
- install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
- install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
- install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
- install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
- install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
- /* Install BSM command */
- install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
- install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
- install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
- install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
- /* Install BFD command */
- install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
- install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
- install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd);
- install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
-#if HAVE_BFDD == 0
- install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
-#endif /* !HAVE_BFDD */
+ install_element(CONFIG_NODE, &ip_igmp_group_watermark_cmd);
+ install_element(VRF_NODE, &ip_igmp_group_watermark_cmd);
+ install_element(CONFIG_NODE, &no_ip_igmp_group_watermark_cmd);
+ install_element(VRF_NODE, &no_ip_igmp_group_watermark_cmd);
+
+ pim_install_deprecated();
}
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index 5e50a09355..c6cb28c097 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -100,25 +100,13 @@ int pim_process_no_join_prune_cmd(struct vty *vty)
int pim_process_spt_switchover_infinity_cmd(struct vty *vty)
{
- const char *vrfname;
char spt_plist_xpath[XPATH_MAXLEN];
char spt_action_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
snprintf(spt_plist_xpath, sizeof(spt_plist_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(spt_plist_xpath, "/spt-switchover/spt-infinity-prefix-list",
- sizeof(spt_plist_xpath));
-
+ "%s/spt-switchover/spt-infinity-prefix-list", VTY_CURR_XPATH);
snprintf(spt_action_xpath, sizeof(spt_action_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(spt_action_xpath, "/spt-switchover/spt-action",
- sizeof(spt_action_xpath));
+ "%s/spt-switchover/spt-action", VTY_CURR_XPATH);
if (yang_dnode_exists(vty->candidate_config->dnode, spt_plist_xpath))
nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_DESTROY,
@@ -132,55 +120,30 @@ int pim_process_spt_switchover_infinity_cmd(struct vty *vty)
int pim_process_spt_switchover_prefixlist_cmd(struct vty *vty,
const char *plist)
{
- const char *vrfname;
char spt_plist_xpath[XPATH_MAXLEN];
char spt_action_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
snprintf(spt_plist_xpath, sizeof(spt_plist_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(spt_plist_xpath, "/spt-switchover/spt-infinity-prefix-list",
- sizeof(spt_plist_xpath));
-
+ "./spt-switchover/spt-infinity-prefix-list");
snprintf(spt_action_xpath, sizeof(spt_action_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(spt_action_xpath, "/spt-switchover/spt-action",
- sizeof(spt_action_xpath));
+ "./spt-switchover/spt-action");
nb_cli_enqueue_change(vty, spt_action_xpath, NB_OP_MODIFY,
"PIM_SPT_INFINITY");
- nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_MODIFY,
- plist);
+ nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_MODIFY, plist);
return nb_cli_apply_changes(vty, NULL);
}
int pim_process_no_spt_switchover_cmd(struct vty *vty)
{
- const char *vrfname;
char spt_plist_xpath[XPATH_MAXLEN];
char spt_action_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
snprintf(spt_plist_xpath, sizeof(spt_plist_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(spt_plist_xpath, "/spt-switchover/spt-infinity-prefix-list",
- sizeof(spt_plist_xpath));
-
+ "./spt-switchover/spt-infinity-prefix-list");
snprintf(spt_action_xpath, sizeof(spt_action_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(spt_action_xpath, "/spt-switchover/spt-action",
- sizeof(spt_action_xpath));
+ "./spt-switchover/spt-action");
nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_DESTROY, NULL);
nb_cli_enqueue_change(vty, spt_action_xpath, NB_OP_MODIFY,
@@ -217,35 +180,20 @@ int pim_process_no_pim_packet_cmd(struct vty *vty)
int pim_process_keepalivetimer_cmd(struct vty *vty, const char *kat)
{
- const char *vrfname;
char ka_timer_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
- snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
- strlcat(ka_timer_xpath, "/keep-alive-timer", sizeof(ka_timer_xpath));
+ snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), "./keep-alive-timer");
- nb_cli_enqueue_change(vty, ka_timer_xpath, NB_OP_MODIFY,
- kat);
+ nb_cli_enqueue_change(vty, ka_timer_xpath, NB_OP_MODIFY, kat);
return nb_cli_apply_changes(vty, NULL);
}
int pim_process_no_keepalivetimer_cmd(struct vty *vty)
{
- const char *vrfname;
char ka_timer_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
- snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), FRR_PIM_VRF_XPATH,
- "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL);
- strlcat(ka_timer_xpath, "/keep-alive-timer", sizeof(ka_timer_xpath));
+ snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), "./keep-alive-timer");
nb_cli_enqueue_change(vty, ka_timer_xpath, NB_OP_DESTROY, NULL);
@@ -254,35 +202,25 @@ int pim_process_no_keepalivetimer_cmd(struct vty *vty)
int pim_process_rp_kat_cmd(struct vty *vty, const char *rpkat)
{
- const char *vrfname;
char rp_ka_timer_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
snprintf(rp_ka_timer_xpath, sizeof(rp_ka_timer_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(rp_ka_timer_xpath, "/rp-keep-alive-timer",
- sizeof(rp_ka_timer_xpath));
+ "./rp-keep-alive-timer");
- nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY,
- rpkat);
+ nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY, rpkat);
return nb_cli_apply_changes(vty, NULL);
}
int pim_process_no_rp_kat_cmd(struct vty *vty)
{
- const char *vrfname;
char rp_ka_timer[6];
char rp_ka_timer_xpath[XPATH_MAXLEN];
uint v;
char rs_timer_xpath[XPATH_MAXLEN];
- snprintf(rs_timer_xpath, sizeof(rs_timer_xpath),
- FRR_PIM_ROUTER_XPATH, FRR_PIM_AF_XPATH_VAL);
+ snprintf(rs_timer_xpath, sizeof(rs_timer_xpath), FRR_PIM_ROUTER_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
strlcat(rs_timer_xpath, "/register-suppress-time",
sizeof(rs_timer_xpath));
@@ -301,18 +239,10 @@ int pim_process_no_rp_kat_cmd(struct vty *vty)
v = UINT16_MAX;
snprintf(rp_ka_timer, sizeof(rp_ka_timer), "%u", v);
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
snprintf(rp_ka_timer_xpath, sizeof(rp_ka_timer_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
- strlcat(rp_ka_timer_xpath, "/rp-keep-alive-timer",
- sizeof(rp_ka_timer_xpath));
+ "./rp-keep-alive-timer");
- nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY,
- rp_ka_timer);
+ nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY, rp_ka_timer);
return nb_cli_apply_changes(vty, NULL);
}
@@ -531,9 +461,7 @@ int pim_process_no_ip_mroute_cmd(struct vty *vty, const char *interface,
int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
const char *group_str)
{
- const char *vrfname;
char group_xpath[XPATH_MAXLEN];
- char rp_xpath[XPATH_MAXLEN];
int printed;
int result = 0;
struct prefix group;
@@ -575,14 +503,9 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
}
#endif
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
- snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
- "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
printed = snprintf(group_xpath, sizeof(group_xpath),
- "%s/group-list[.='%s']", rp_xpath, group_str);
+ "./" FRR_PIM_STATIC_RP_XPATH "/group-list[.='%s']",
+ rp_str, group_str);
if (printed >= (int)(sizeof(group_xpath))) {
vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
@@ -601,15 +524,10 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
char group_xpath[XPATH_MAXLEN];
char rp_xpath[XPATH_MAXLEN];
int printed;
- const char *vrfname;
const struct lyd_node *group_dnode;
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
- snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
- "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
+ snprintf(rp_xpath, sizeof(rp_xpath), "%s/" FRR_PIM_STATIC_RP_XPATH,
+ VTY_CURR_XPATH, rp_str);
printed = snprintf(group_xpath, sizeof(group_xpath),
"%s/group-list[.='%s']", rp_xpath, group_str);
@@ -636,16 +554,10 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
int pim_process_rp_plist_cmd(struct vty *vty, const char *rp_str,
const char *prefix_list)
{
- const char *vrfname;
char rp_plist_xpath[XPATH_MAXLEN];
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
snprintf(rp_plist_xpath, sizeof(rp_plist_xpath),
- FRR_PIM_STATIC_RP_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL, rp_str);
+ "./" FRR_PIM_STATIC_RP_XPATH, rp_str);
strlcat(rp_plist_xpath, "/prefix-list", sizeof(rp_plist_xpath));
nb_cli_enqueue_change(vty, rp_plist_xpath, NB_OP_MODIFY, prefix_list);
@@ -658,19 +570,12 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
{
char rp_xpath[XPATH_MAXLEN];
char plist_xpath[XPATH_MAXLEN];
- const char *vrfname;
const struct lyd_node *plist_dnode;
const char *plist;
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
- snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
- "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
-
- snprintf(plist_xpath, sizeof(plist_xpath), FRR_PIM_STATIC_RP_XPATH,
- "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
+ snprintf(rp_xpath, sizeof(rp_xpath), "%s/" FRR_PIM_STATIC_RP_XPATH,
+ VTY_CURR_XPATH, rp_str);
+ snprintf(plist_xpath, sizeof(plist_xpath), "%s", rp_xpath);
strlcat(plist_xpath, "/prefix-list", sizeof(plist_xpath));
plist_dnode = yang_dnode_get(vty->candidate_config->dnode, plist_xpath);
@@ -679,7 +584,7 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
return NB_OK;
}
- plist = yang_dnode_get_string(plist_dnode, "%s", plist_xpath);
+ plist = yang_dnode_get_string(plist_dnode, NULL);
if (strcmp(prefix_list, plist)) {
vty_out(vty, "%% Unable to find specified RP\n");
return NB_OK;
@@ -3408,21 +3313,11 @@ int gm_process_no_last_member_query_interval_cmd(struct vty *vty)
int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
const char *src_str)
{
- const char *vrfname;
- char ssmpingd_ip_xpath[XPATH_MAXLEN];
char ssmpingd_src_ip_xpath[XPATH_MAXLEN];
int printed;
- vrfname = pim_cli_get_vrf_name(vty);
- if (vrfname == NULL)
- return CMD_WARNING_CONFIG_FAILED;
-
- snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
- FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL);
printed = snprintf(ssmpingd_src_ip_xpath, sizeof(ssmpingd_src_ip_xpath),
- "%s/ssm-pingd-source-ip[.='%s']", ssmpingd_ip_xpath,
- src_str);
+ "./ssm-pingd-source-ip[.='%s']", src_str);
if (printed >= (int)sizeof(ssmpingd_src_ip_xpath)) {
vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
XPATH_MAXLEN);
@@ -5705,3 +5600,34 @@ int pim_show_bsm_db_helper(const char *vrf, struct vty *vty, bool uj)
return CMD_SUCCESS;
}
+
+int pim_router_config_write(struct vty *vty)
+{
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ int writes = 0;
+ char framestr[64] = { 0 };
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ pim = vrf->info;
+
+ if (!pim)
+ continue;
+
+ snprintfrr(framestr, sizeof(framestr), "router %s",
+ PIM_AF_ROUTER);
+ if (vrf->vrf_id != VRF_DEFAULT) {
+ strlcat(framestr, " vrf ", sizeof(framestr));
+ strlcat(framestr, vrf->name, sizeof(framestr));
+ }
+ vty_frame(vty, "%s\n", framestr);
+ ++writes;
+
+ writes += pim_global_config_write_worker(pim, vty);
+
+ vty_endframe(vty, "exit\n");
+ ++writes;
+ }
+
+ return writes;
+}
diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h
index e30203fad7..da2e44be58 100644
--- a/pimd/pim_cmd_common.h
+++ b/pimd/pim_cmd_common.h
@@ -182,6 +182,8 @@ int pim_show_interface_traffic_helper(const char *vrf, const char *if_name,
void clear_pim_interfaces(struct pim_instance *pim);
void pim_show_bsr(struct pim_instance *pim, struct vty *vty, bool uj);
int pim_show_bsr_helper(const char *vrf, struct vty *vty, bool uj);
+int pim_router_config_write(struct vty *vty);
+
/*
* Special Macro to allow us to get the correct pim_instance;
*/
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index b3410d15af..a9eec9a9d2 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -201,6 +201,7 @@ static int pim_vrf_config_write(struct vty *vty)
{
struct vrf *vrf;
struct pim_instance *pim;
+ char spaces[10];
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
pim = vrf->info;
@@ -208,10 +209,24 @@ static int pim_vrf_config_write(struct vty *vty)
if (!pim)
continue;
- if (vrf->vrf_id != VRF_DEFAULT)
+ if (vrf->vrf_id != VRF_DEFAULT) {
vty_frame(vty, "vrf %s\n", vrf->name);
-
- pim_global_config_write_worker(pim, vty);
+ snprintf(spaces, sizeof(spaces), "%s", " ");
+ } else {
+ snprintf(spaces, sizeof(spaces), "%s", "");
+ }
+
+ /* Global IGMP/MLD configuration */
+ if (pim->gm_watermark_limit != 0) {
+#if PIM_IPV == 4
+ vty_out(vty,
+ "%s" PIM_AF_NAME " igmp watermark-warn %u\n",
+ spaces, pim->gm_watermark_limit);
+#else
+ vty_out(vty, "%s" PIM_AF_NAME " mld watermark-warn %u\n",
+ spaces, pim->gm_watermark_limit);
+#endif
+ }
if (vrf->vrf_id != VRF_DEFAULT)
vty_endframe(vty, "exit-vrf\n!\n");
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 623c14bb03..04b4d296dd 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1276,8 +1276,7 @@ static void pim_msdp_src_del(struct pim_msdp_mg *mg)
}
/*********************** MSDP feature APIs *********************************/
-int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
- const char *spaces)
+int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty)
{
struct pim_msdp_mg *mg;
struct listnode *mbrnode;
@@ -1292,14 +1291,14 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
if (mg->src_ip.s_addr != INADDR_ANY) {
pim_inet4_dump("<src?>", mg->src_ip, src_str,
sizeof(src_str));
- vty_out(vty, "%sip msdp mesh-group %s source %s\n",
- spaces, mg->mesh_group_name, src_str);
+ vty_out(vty, " msdp mesh-group %s source %s\n",
+ mg->mesh_group_name, src_str);
++count;
}
for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
- vty_out(vty, "%sip msdp mesh-group %s member %pI4\n",
- spaces, mg->mesh_group_name, &mbr->mbr_ip);
+ vty_out(vty, " msdp mesh-group %s member %pI4\n",
+ mg->mesh_group_name, &mbr->mbr_ip);
++count;
}
}
@@ -1307,8 +1306,7 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
return count;
}
-bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
- const char *spaces)
+bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim)
{
struct pim_msdp_peer *mp;
struct listnode *node;
@@ -1319,8 +1317,8 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
continue;
- vty_out(vty, "%sip msdp peer %pI4 source %pI4\n", spaces,
- &mp->peer, &mp->local);
+ vty_out(vty, " msdp peer %pI4 source %pI4\n", &mp->peer,
+ &mp->local);
written = true;
}
diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h
index ddc015f9b6..80ca003dc5 100644
--- a/pimd/pim_msdp.h
+++ b/pimd/pim_msdp.h
@@ -228,10 +228,8 @@ void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp);
void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state);
void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str);
void pim_msdp_write(struct event *thread);
-int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
- const char *spaces);
-bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
- const char *spaces);
+int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty);
+bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim);
void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp);
void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
pim_sgaddr *sg, struct in_addr rp);
@@ -339,14 +337,13 @@ static inline void pim_msdp_sa_local_del(struct pim_instance *pim,
}
static inline int pim_msdp_config_write(struct pim_instance *pim,
- struct vty *vty, const char *spaces)
+ struct vty *vty)
{
return 0;
}
static inline bool pim_msdp_peer_config_write(struct vty *vty,
- struct pim_instance *pim,
- const char *spaces)
+ struct pim_instance *pim)
{
return false;
}
diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h
index 0321d076f0..2d854d73de 100644
--- a/pimd/pim_nb.h
+++ b/pimd/pim_nb.h
@@ -207,9 +207,6 @@ int routing_control_plane_protocols_name_validate(
"./frr-pim:pim/address-family[address-family='%s']/" \
"mroute[source-addr='%s'][group-addr='%s']"
#define FRR_PIM_STATIC_RP_XPATH \
- "/frr-routing:routing/control-plane-protocols/" \
- "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \
- "frr-pim:pim/address-family[address-family='%s']/" \
"frr-pim-rp:rp/static-rp/rp-list[rp-address='%s']"
#define FRR_GMP_INTERFACE_XPATH \
"./frr-gmp:gmp/address-family[address-family='%s']"
@@ -218,6 +215,5 @@ int routing_control_plane_protocols_name_validate(
#define FRR_GMP_JOIN_XPATH \
"./frr-gmp:gmp/address-family[address-family='%s']/" \
"static-group[group-addr='%s'][source-addr='%s']"
-#define FRR_PIM_MSDP_XPATH FRR_PIM_VRF_XPATH "/msdp"
#endif /* _FRR_PIM_NB_H_ */
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 49be9c0a73..0f8940bb16 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -1129,8 +1129,7 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
return 1;
}
-int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
- const char *spaces)
+int pim_rp_config_write(struct pim_instance *pim, struct vty *vty)
{
struct listnode *node;
struct rp_info *rp_info;
@@ -1146,13 +1145,11 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
rp_addr = rp_info->rp.rpf_addr;
if (rp_info->plist)
- vty_out(vty,
- "%s" PIM_AF_NAME
- " pim rp %pPA prefix-list %s\n",
- spaces, &rp_addr, rp_info->plist);
+ vty_out(vty, " rp %pPA prefix-list %s\n", &rp_addr,
+ rp_info->plist);
else
- vty_out(vty, "%s" PIM_AF_NAME " pim rp %pPA %pFX\n",
- spaces, &rp_addr, &rp_info->group);
+ vty_out(vty, " rp %pPA %pFX\n", &rp_addr,
+ &rp_info->group);
count++;
}
diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h
index 9416a9a8a8..32c6306740 100644
--- a/pimd/pim_rp.h
+++ b/pimd/pim_rp.h
@@ -46,8 +46,7 @@ int pim_rp_change(struct pim_instance *pim, pim_addr new_rp_addr,
void pim_rp_prefix_list_update(struct pim_instance *pim,
struct prefix_list *plist);
-int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
- const char *spaces);
+int pim_rp_config_write(struct pim_instance *pim, struct vty *vty);
void pim_rp_setup(struct pim_instance *pim);
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 0f6547ee2e..1910a68495 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -172,89 +172,66 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
{
int writes = 0;
struct pim_ssm *ssm = pim->ssm_info;
- char spaces[10];
- if (pim->vrf->vrf_id == VRF_DEFAULT)
- snprintf(spaces, sizeof(spaces), "%s", "");
- else
- snprintf(spaces, sizeof(spaces), "%s", " ");
-
- writes += pim_msdp_peer_config_write(vty, pim, spaces);
- writes += pim_msdp_config_write(pim, vty, spaces);
+ writes += pim_msdp_peer_config_write(vty, pim);
+ writes += pim_msdp_config_write(pim, vty);
if (!pim->send_v6_secondary) {
- vty_out(vty, "%sno ip pim send-v6-secondary\n", spaces);
+ vty_out(vty, " no send-v6-secondary\n");
++writes;
}
- writes += pim_rp_config_write(pim, vty, spaces);
+ writes += pim_rp_config_write(pim, vty);
if (pim->vrf->vrf_id == VRF_DEFAULT) {
if (router->register_suppress_time
!= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT) {
- vty_out(vty, "%s" PIM_AF_NAME " pim register-suppress-time %d\n",
- spaces, router->register_suppress_time);
+ vty_out(vty, " register-suppress-time %d\n",
+ router->register_suppress_time);
++writes;
}
if (router->t_periodic != PIM_DEFAULT_T_PERIODIC) {
- vty_out(vty, "%s" PIM_AF_NAME " pim join-prune-interval %d\n",
- spaces, router->t_periodic);
+ vty_out(vty, " join-prune-interval %d\n",
+ router->t_periodic);
++writes;
}
if (router->packet_process != PIM_DEFAULT_PACKET_PROCESS) {
- vty_out(vty, "%s" PIM_AF_NAME " pim packets %d\n", spaces,
- router->packet_process);
+ vty_out(vty, " packets %d\n", router->packet_process);
++writes;
}
}
if (pim->keep_alive_time != PIM_KEEPALIVE_PERIOD) {
- vty_out(vty, "%s" PIM_AF_NAME " pim keep-alive-timer %d\n",
- spaces, pim->keep_alive_time);
+ vty_out(vty, " keep-alive-timer %d\n", pim->keep_alive_time);
++writes;
}
if (pim->rp_keep_alive_time != (unsigned int)PIM_RP_KEEPALIVE_PERIOD) {
- vty_out(vty, "%s" PIM_AF_NAME " pim rp keep-alive-timer %d\n",
- spaces, pim->rp_keep_alive_time);
+ vty_out(vty, " rp keep-alive-timer %d\n",
+ pim->rp_keep_alive_time);
++writes;
}
if (ssm->plist_name) {
- vty_out(vty, "%sip pim ssm prefix-list %s\n", spaces,
- ssm->plist_name);
+ vty_out(vty, " ssm prefix-list %s\n", ssm->plist_name);
++writes;
}
if (pim->register_plist) {
- vty_out(vty, "%sip pim register-accept-list %s\n", spaces,
- pim->register_plist);
+ vty_out(vty, " register-accept-list %s\n", pim->register_plist);
++writes;
}
if (pim->spt.switchover == PIM_SPT_INFINITY) {
if (pim->spt.plist)
vty_out(vty,
- "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond prefix-list %s\n",
- spaces, pim->spt.plist);
+ " spt-switchover infinity-and-beyond prefix-list %s\n",
+ pim->spt.plist);
else
- vty_out(vty,
- "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond\n",
- spaces);
+ vty_out(vty, " spt-switchover infinity-and-beyond\n");
++writes;
}
if (pim->ecmp_rebalance_enable) {
- vty_out(vty, "%sip pim ecmp rebalance\n", spaces);
+ vty_out(vty, " ecmp rebalance\n");
++writes;
} else if (pim->ecmp_enable) {
- vty_out(vty, "%sip pim ecmp\n", spaces);
- ++writes;
- }
-
- if (pim->gm_watermark_limit != 0) {
-#if PIM_IPV == 4
- vty_out(vty, "%s" PIM_AF_NAME " igmp watermark-warn %u\n",
- spaces, pim->gm_watermark_limit);
-#else
- vty_out(vty, "%s" PIM_AF_NAME " mld watermark-warn %u\n",
- spaces, pim->gm_watermark_limit);
-#endif
+ vty_out(vty, " ecmp\n");
++writes;
}
@@ -263,8 +240,7 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
struct ssmpingd_sock *ss;
++writes;
for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
- vty_out(vty, "%s" PIM_AF_NAME " ssmpingd %pPA\n",
- spaces, &ss->source_addr);
+ vty_out(vty, " ssmpingd %pPA\n", &ss->source_addr);
++writes;
}
}
@@ -272,8 +248,8 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
if (pim->msdp.hold_time != PIM_MSDP_PEER_HOLD_TIME
|| pim->msdp.keep_alive != PIM_MSDP_PEER_KA_TIME
|| pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) {
- vty_out(vty, "%sip msdp timers %u %u", spaces,
- pim->msdp.hold_time, pim->msdp.keep_alive);
+ vty_out(vty, " msdp timers %u %u", pim->msdp.hold_time,
+ pim->msdp.keep_alive);
if (pim->msdp.connection_retry
!= PIM_MSDP_PEER_CONNECT_RETRY_TIME)
vty_out(vty, " %u", pim->msdp.connection_retry);
diff --git a/ripd/ripd.c b/ripd/ripd.c
index ab4ffe5a92..8768819fe2 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -3054,7 +3054,10 @@ DEFUN (show_ip_rip,
}
vty_out(vty,
- "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n"
+ "Codes: K - kernel route, C - connected, L - local, S - static,\n"
+ " R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,\n"
+ " T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,\n"
+ " f - OpenFabric, t - Table-Direct\n"
"Sub-codes:\n"
" (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
" (i) - interface\n\n"
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index f4dadf377d..0aa2a9e486 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -2070,7 +2070,10 @@ DEFUN (show_ipv6_ripng,
/* Header of display. */
vty_out(vty,
- "Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP\n"
+ "Codes: K - kernel route, C - connected, L - local, S - static,\n"
+ " R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,\n"
+ " T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,\n"
+ " f - OpenFabric, t - Table-Direct\n"
"Sub-codes:\n"
" (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n"
" (i) - interface, (a/S) - aggregated/Suppressed\n\n"
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index c4efc14a9d..420ed7903b 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -341,7 +341,8 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
/* refresh with existing data */
afi_t afi = prefix_afi(&lookup.nh);
- if (nh->state == STATIC_NOT_INSTALLED)
+ if (nh->state == STATIC_NOT_INSTALLED ||
+ nh->state == STATIC_SENT_TO_ZEBRA)
nh->state = STATIC_START;
static_nht_update(&rn->p, &nhtd->nh, nhtd->nh_num, afi,
si->safi, nh->nh_vrf_id);
diff --git a/tests/lib/test_atomlist.c b/tests/lib/test_atomlist.c
index b50216cf92..afcfa98791 100644
--- a/tests/lib/test_atomlist.c
+++ b/tests/lib/test_atomlist.c
@@ -62,7 +62,7 @@ static struct asort_head shead;
static struct testthread {
pthread_t pt;
struct seqlock sqlo;
- size_t counter, nullops;
+ _Atomic size_t counter, nullops;
} thr[NTHREADS];
struct testrun {
@@ -97,10 +97,10 @@ static void trfunc_##name(unsigned int offset) \
{ \
size_t i = 0, n = 0;
-#define endtestrun \
- thr[offset].counter = i; \
- thr[offset].nullops = n; \
-}
+#define endtestrun \
+ atomic_store_explicit(&thr[offset].counter, i, memory_order_seq_cst); \
+ atomic_store_explicit(&thr[offset].nullops, n, memory_order_seq_cst); \
+ }
deftestrun(add, "add vs. add", 0, false)
for (; i < NITEM / NTHREADS; i++)
@@ -288,10 +288,10 @@ static void run_tr(struct testrun *tr)
sv = seqlock_bump(&sqlo) - SEQLOCK_INCR;
for (size_t i = 0; i < NTHREADS; i++) {
seqlock_wait(&thr[i].sqlo, seqlock_cur(&sqlo));
- s += thr[i].counter;
- n += thr[i].nullops;
- thr[i].counter = 0;
- thr[i].nullops = 0;
+ s += atomic_load_explicit(&thr[i].counter, memory_order_seq_cst);
+ n += atomic_load_explicit(&thr[i].nullops, memory_order_seq_cst);
+ atomic_store_explicit(&thr[i].counter, 0, memory_order_seq_cst);
+ atomic_store_explicit(&thr[i].nullops, 0, memory_order_seq_cst);
}
delta = monotime_since(&tv, NULL);
diff --git a/tests/lib/test_seqlock.c b/tests/lib/test_seqlock.c
index 288d4a8c25..937b3f34f5 100644
--- a/tests/lib/test_seqlock.c
+++ b/tests/lib/test_seqlock.c
@@ -82,11 +82,11 @@ int main(int argc, char **argv)
assert(seqlock_held(&sqlo));
assert(seqlock_cur(&sqlo) == 1);
- assert(seqlock_bump(&sqlo) == 1);
- assert(seqlock_cur(&sqlo) == 5);
assert(seqlock_bump(&sqlo) == 5);
+ assert(seqlock_cur(&sqlo) == 5);
assert(seqlock_bump(&sqlo) == 9);
assert(seqlock_bump(&sqlo) == 13);
+ assert(seqlock_bump(&sqlo) == 17);
assert(seqlock_cur(&sqlo) == 17);
assert(seqlock_held(&sqlo));
@@ -111,4 +111,5 @@ int main(int argc, char **argv)
writestr("main @release\n");
seqlock_release(&sqlo);
sleep(1);
+ pthread_join(thr1, NULL);
}
diff --git a/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py
index 955881e6f9..83fae71bf5 100644
--- a/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py
+++ b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py
@@ -320,7 +320,7 @@ def check_ipv4_prefix_recursive_with_multiple_nexthops(
)
test_func = functools.partial(
- ip_check_path_selection, tgen.gears["r1"], prefix, expected
+ ip_check_path_selection, tgen.gears["r1"], prefix, expected, check_fib=True
)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert (
diff --git a/tests/topotests/bgp_oad/test_bgp_oad.py b/tests/topotests/bgp_oad/test_bgp_oad.py
index a2ca37a2b7..bb779462db 100644
--- a/tests/topotests/bgp_oad/test_bgp_oad.py
+++ b/tests/topotests/bgp_oad/test_bgp_oad.py
@@ -46,7 +46,7 @@ def teardown_module(mod):
tgen.stop_topology()
-def test_bgp_dynamic_capability_role():
+def test_bgp_oad():
tgen = get_topogen()
if tgen.routers_have_failure():
diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json
index 22ec2c298b..483165c0f3 100644
--- a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json
+++ b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json
@@ -23,7 +23,7 @@
"recursive":true
},
{
- "fib":true,
+ "duplicate":true,
"ip":"10.0.3.2",
"active":true
}
diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json
index facddcda46..638a825395 100644
--- a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json
+++ b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json
@@ -23,7 +23,7 @@
"recursive":true
},
{
- "fib":true,
+ "duplicate":true,
"ip":"10.0.3.2",
"active":true
}
diff --git a/tests/topotests/bgp_remote_as_auto/r1/frr.conf b/tests/topotests/bgp_remote_as_auto/r1/frr.conf
index aec0e76a3f..2f1bcd275f 100644
--- a/tests/topotests/bgp_remote_as_auto/r1/frr.conf
+++ b/tests/topotests/bgp_remote_as_auto/r1/frr.conf
@@ -2,6 +2,9 @@
int r1-eth0
ip address 192.168.1.1/24
!
+int r1-eth1
+ ip address 192.168.14.1/24
+!
router bgp 65001
no bgp ebgp-requires-policy
no bgp network import-check
@@ -11,6 +14,9 @@ router bgp 65001
neighbor 192.168.1.3 remote-as auto
neighbor 192.168.1.3 timers 1 3
neighbor 192.168.1.3 timers connect 1
+ neighbor r1-eth1 interface remote-as auto
+ neighbor r1-eth1 timers 1 3
+ neighbor r1-eth1 timers connect 1
address-family ipv4 unicast
network 10.0.0.1/32
exit-address-family
diff --git a/tests/topotests/bgp_remote_as_auto/r4/frr.conf b/tests/topotests/bgp_remote_as_auto/r4/frr.conf
new file mode 100644
index 0000000000..e280a6c6e8
--- /dev/null
+++ b/tests/topotests/bgp_remote_as_auto/r4/frr.conf
@@ -0,0 +1,10 @@
+!
+int r4-eth0
+ ip address 192.168.14.4/24
+!
+router bgp 65004
+ no bgp ebgp-requires-policy
+ neighbor r4-eth0 interface remote-as auto
+ neighbor r4-eth0 timers 1 3
+ neighbor r4-eth0 timers connect 1
+!
diff --git a/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py b/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py
index b932920e09..1db6d98a42 100644
--- a/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py
+++ b/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py
@@ -23,7 +23,7 @@ pytestmark = [pytest.mark.bgpd]
def setup_module(mod):
- topodef = {"s1": ("r1", "r2", "r3")}
+ topodef = {"s1": ("r1", "r2", "r3"), "s2": ("r1", "r4")}
tgen = Topogen(topodef, mod.__name__)
tgen.start_topology()
@@ -49,11 +49,18 @@ def test_bgp_remote_as_auto():
r1 = tgen.gears["r1"]
r2 = tgen.gears["r2"]
r3 = tgen.gears["r3"]
+ r4 = tgen.gears["r4"]
def _bgp_converge():
output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast summary json"))
expected = {
"peers": {
+ "r1-eth1": {
+ "hostname": "r4",
+ "remoteAs": 65004,
+ "localAs": 65001,
+ "state": "Established",
+ },
"192.168.1.2": {
"hostname": "r2",
"remoteAs": 65001,
@@ -124,6 +131,30 @@ def test_bgp_remote_as_auto():
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, "Can't see automatic eBGP peering"
+ def _bgp_converge_external_unnumbered():
+ output = json.loads(r4.vtysh_cmd("show bgp ipv4 unicast 10.0.0.1/32 json"))
+ expected = {
+ "paths": [
+ {
+ "aspath": {
+ "string": "65001",
+ },
+ "valid": True,
+ "peer": {
+ "hostname": "r1",
+ "type": "external",
+ },
+ }
+ ]
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(
+ _bgp_converge_external_unnumbered,
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result is None, "Can't see automatic unnumbered eBGP peering"
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
index 5d18083fd5..a6938668ad 100755
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
@@ -92,7 +92,8 @@ def setup_module(mod):
tgen.start_topology()
router_list = tgen.routers()
for rname, router in tgen.routers().items():
- router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
+ if os.path.exists("{}/{}/setup.sh".format(CWD, rname)):
+ router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
)
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py
index 38baf43442..3e21875503 100755
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py
@@ -56,7 +56,8 @@ def setup_module(mod):
tgen = Topogen(build_topo, mod.__name__)
tgen.start_topology()
for rname, router in tgen.routers().items():
- router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
+ if os.path.exists("{}/{}/setup.sh".format(CWD, rname)):
+ router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
)
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
index 92a30788fc..2400cd2853 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
@@ -53,7 +53,8 @@ def setup_module(mod):
tgen = Topogen(build_topo, mod.__name__)
tgen.start_topology()
for rname, router in tgen.routers().items():
- router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
+ if os.path.exists("{}/{}/setup.sh".format(CWD, rname)):
+ router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
)
diff --git a/tests/topotests/bgp_vrf_different_asn/__init__.py b/tests/topotests/bgp_vrf_different_asn/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_vrf_different_asn/__init__.py
diff --git a/tests/topotests/bgp_vrf_different_asn/r1/frr.conf b/tests/topotests/bgp_vrf_different_asn/r1/frr.conf
new file mode 100644
index 0000000000..b325dfb7f0
--- /dev/null
+++ b/tests/topotests/bgp_vrf_different_asn/r1/frr.conf
@@ -0,0 +1,18 @@
+!
+vrf vrf100
+ vni 10100
+exit-vrf
+!
+interface r1-eth0 vrf vrf100
+ ip address 192.168.1.1/24
+!
+router bgp 65000
+ address-family ipv4 unicast
+ import vrf vrf100
+ exit-address-family
+!
+router bgp 65100 vrf vrf100
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py b/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py
new file mode 100644
index 0000000000..9a1a9ec766
--- /dev/null
+++ b/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+
+#
+# Copyright (c) 2024 by
+# Donatas Abraitis <donatas@opensourcerouting.org>
+#
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+ for routern in range(1, 2):
+ tgen.add_router("r{}".format(routern))
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+
+
+def setup_module(mod):
+ tgen = Topogen(build_topo, mod.__name__)
+ tgen.start_topology()
+
+ r1 = tgen.gears["r1"]
+ r1.run("ip link add vrf100 type vrf table 1001")
+ r1.run("ip link set up dev vrf100")
+ r1.run("ip link set r1-eth0 master vrf100")
+
+ router_list = tgen.routers()
+
+ for _, (rname, router) in enumerate(router_list.items(), 1):
+ router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname)))
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_vrf_different_asn():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ def _bgp_check_instances():
+ output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp vrf all json"))
+ expected = {
+ "default": {
+ "vrfName": "default",
+ "localAS": 65000,
+ },
+ "vrf100": {
+ "vrfName": "vrf100",
+ "localAS": 65100,
+ },
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_check_instances)
+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result is None, "Can't see vrf100 to be under 65100 ASN"
+
+ def _bgp_check_imported_route():
+ output = json.loads(
+ tgen.gears["r1"].vtysh_cmd("show ip route 192.168.1.0/24 json")
+ )
+ expected = {
+ "192.168.1.0/24": [
+ {
+ "installed": True,
+ "selected": True,
+ "nexthops": [
+ {
+ "interfaceName": "vrf100",
+ "vrf": "vrf100",
+ "active": True,
+ }
+ ],
+ }
+ ]
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_check_imported_route)
+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result is None, "Can't see 192.168.1.0/24 being imported into a default VRF"
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py
index 8b6fb98612..a574f43d89 100644
--- a/tests/topotests/isis_topo1/test_isis_topo1.py
+++ b/tests/topotests/isis_topo1/test_isis_topo1.py
@@ -679,6 +679,9 @@ def _check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
)
database_json = json.loads(isis_database_output)
+ if "lsps" not in database_json["areas"][0]["levels"][1]:
+ return "The LSP of {} has not been synchronized yet ".format(router.name)
+
att_p_ol = database_json["areas"][0]["levels"][1]["lsps"][0]["attPOl"]
if att_p_ol == att_p_ol_expected:
return True
diff --git a/tests/topotests/lib/common_check.py b/tests/topotests/lib/common_check.py
index be3241fd20..19f02dbadc 100644
--- a/tests/topotests/lib/common_check.py
+++ b/tests/topotests/lib/common_check.py
@@ -10,11 +10,13 @@ import json
from lib import topotest
-def ip_check_path_selection(router, ipaddr_str, expected, vrf_name=None):
+def ip_check_path_selection(
+ router, ipaddr_str, expected, vrf_name=None, check_fib=False
+):
if vrf_name:
- cmdstr = f'show ip route vrf {vrf_name} {ipaddr_str} json'
+ cmdstr = f"show ip route vrf {vrf_name} {ipaddr_str} json"
else:
- cmdstr = f'show ip route {ipaddr_str} json'
+ cmdstr = f"show ip route {ipaddr_str} json"
try:
output = json.loads(router.vtysh_cmd(cmdstr))
except:
@@ -25,6 +27,21 @@ def ip_check_path_selection(router, ipaddr_str, expected, vrf_name=None):
num_nh_expected = len(expected[ipaddr_str][0]["nexthops"])
num_nh_observed = len(output[ipaddr_str][0]["nexthops"])
if num_nh_expected == num_nh_observed:
+ if check_fib:
+ # special case: when fib flag is unset,
+ # an extra test should be done to check that the flag is really unset
+ for nh_output, nh_expected in zip(
+ output[ipaddr_str][0]["nexthops"],
+ expected[ipaddr_str][0]["nexthops"],
+ ):
+ if (
+ "fib" in nh_output.keys()
+ and nh_output["fib"]
+ and ("fib" not in nh_expected.keys() or not nh_expected["fib"])
+ ):
+ return "{}, prefix {} nexthop {} has the fib flag set, whereas it is not expected".format(
+ router.name, ipaddr_str, nh_output["ip"]
+ )
return ret
return "{}, prefix {} does not have the correct number of nexthops : observed {}, expected {}".format(
router.name, ipaddr_str, num_nh_observed, num_nh_expected
@@ -37,9 +54,9 @@ def iproute2_check_path_selection(router, ipaddr_str, expected, vrf_name=None):
return None
if vrf_name:
- cmdstr = f'ip -json route show vrf {vrf_name} {ipaddr_str}'
+ cmdstr = f"ip -json route show vrf {vrf_name} {ipaddr_str}"
else:
- cmdstr = f'ip -json route show {ipaddr_str}'
+ cmdstr = f"ip -json route show {ipaddr_str}"
try:
output = json.loads(cmdstr)
except:
diff --git a/tests/topotests/ospf_metric_propagation/r1/frr.conf b/tests/topotests/ospf_metric_propagation/r1/frr.conf
index 85230494dd..4966e6a9da 100644
--- a/tests/topotests/ospf_metric_propagation/r1/frr.conf
+++ b/tests/topotests/ospf_metric_propagation/r1/frr.conf
@@ -8,18 +8,18 @@ interface r1-eth0
ip address 10.0.1.1/24
ip ospf cost 100
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface r1-eth1 vrf blue
ip address 10.0.10.1/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
!
interface r1-eth2 vrf green
ip address 10.0.91.1/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
!
router ospf
diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json
index 4f1ced81fb..2392b40fa9 100644
--- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json
+++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json
@@ -2,32 +2,15 @@
"10.0.94.0/24":[
{
"prefix":"10.0.94.0/24",
- "prefixLen":24,
"protocol":"bgp",
"vrfName":"green",
- "selected":true,
- "destSelected":true,
- "distance":20,
"metric":34,
"installed":true,
- "table":12,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthopGroupId":"*",
- "installedNexthopGroupId":"*",
- "uptime":"*",
"nexthops":[
{
- "flags":3,
- "fib":true,
"ip":"10.0.10.5",
- "afi":"ipv4",
"interfaceName":"r1-eth1",
- "vrf":"blue",
- "active":true,
- "weight":1
+ "vrf":"blue"
}
]
}
diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json
index 882d3ca4f0..9a3d3d87b7 100644
--- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json
+++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json
@@ -2,32 +2,15 @@
"10.0.94.0/24":[
{
"prefix":"10.0.94.0/24",
- "prefixLen":24,
"protocol":"bgp",
"vrfName":"green",
- "selected":true,
- "destSelected":true,
- "distance":20,
"metric":136,
"installed":true,
- "table":12,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthopGroupId":"*",
- "installedNexthopGroupId":"*",
- "uptime":"*",
"nexthops":[
{
- "flags":3,
- "fib":true,
"ip":"10.0.1.2",
- "afi":"ipv4",
"interfaceName":"r1-eth0",
- "vrf":"default",
- "active":true,
- "weight":1
+ "vrf":"default"
}
]
}
diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json
index cd528459ab..5f0331f3cd 100644
--- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json
+++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json
@@ -2,32 +2,15 @@
"10.0.94.0/24":[
{
"prefix":"10.0.94.0/24",
- "prefixLen":24,
"protocol":"bgp",
"vrfName":"green",
- "selected":true,
- "destSelected":true,
- "distance":20,
"metric":1138,
"installed":true,
- "table":12,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthopGroupId":"*",
- "installedNexthopGroupId":"*",
- "uptime":"*",
"nexthops":[
{
- "flags":3,
- "fib":true,
"ip":"10.0.1.2",
- "afi":"ipv4",
"interfaceName":"r1-eth0",
- "vrf":"default",
- "active":true,
- "weight":1
+ "vrf":"default"
}
]
}
diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json
index 133f37549e..f312291e86 100644
--- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json
+++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json
@@ -2,32 +2,15 @@
"10.0.94.0/24":[
{
"prefix":"10.0.94.0/24",
- "prefixLen":24,
"protocol":"bgp",
"vrfName":"green",
- "selected":true,
- "destSelected":true,
- "distance":20,
"metric":1218,
"installed":true,
- "table":12,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthopGroupId":"*",
- "installedNexthopGroupId":"*",
- "uptime":"*",
"nexthops":[
{
- "flags":3,
- "fib":true,
"ip":"10.0.1.2",
- "afi":"ipv4",
"interfaceName":"r1-eth0",
- "vrf":"default",
- "active":true,
- "weight":1
+ "vrf":"default"
}
]
}
diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json
index 5d80509021..e88c037174 100644
--- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json
+++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json
@@ -2,32 +2,15 @@
"10.0.94.0/24":[
{
"prefix":"10.0.94.0/24",
- "prefixLen":24,
"protocol":"bgp",
"vrfName":"green",
- "selected":true,
- "destSelected":true,
- "distance":20,
"metric":238,
"installed":true,
- "table":12,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthopGroupId":"*",
- "installedNexthopGroupId":"*",
- "uptime":"*",
"nexthops":[
{
- "flags":3,
- "fib":true,
"ip":"10.0.1.2",
- "afi":"ipv4",
"interfaceName":"r1-eth0",
- "vrf":"default",
- "active":true,
- "weight":1
+ "vrf":"default"
}
]
}
diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json
index 1b59707b98..f1fec860a9 100644
--- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json
+++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json
@@ -2,32 +2,15 @@
"10.0.94.0/24":[
{
"prefix":"10.0.94.0/24",
- "prefixLen":24,
"protocol":"bgp",
"vrfName":"green",
- "selected":true,
- "destSelected":true,
- "distance":20,
"metric":136,
"installed":true,
- "table":12,
- "internalStatus":16,
- "internalFlags":8,
- "internalNextHopNum":1,
- "internalNextHopActiveNum":1,
- "nexthopGroupId":"*",
- "installedNexthopGroupId":"*",
- "uptime":"*",
"nexthops":[
{
- "flags":3,
- "fib":true,
"ip":"10.0.10.5",
- "afi":"ipv4",
"interfaceName":"r1-eth1",
- "vrf":"blue",
- "active":true,
- "weight":1
+ "vrf":"blue"
}
]
}
diff --git a/tests/topotests/ospf_metric_propagation/r2/frr.conf b/tests/topotests/ospf_metric_propagation/r2/frr.conf
index e67a374ff5..0ac5001b1b 100644
--- a/tests/topotests/ospf_metric_propagation/r2/frr.conf
+++ b/tests/topotests/ospf_metric_propagation/r2/frr.conf
@@ -8,18 +8,18 @@ interface r2-eth0
ip address 10.0.1.2/24
ip ospf cost 100
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface r2-eth1 vrf blue
ip address 10.0.20.2/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface r2-eth2 vrf green
ip address 10.0.70.2/24
ip ospf cost 1000
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
router ospf
ospf router-id 10.0.255.2
diff --git a/tests/topotests/ospf_metric_propagation/r3/frr.conf b/tests/topotests/ospf_metric_propagation/r3/frr.conf
index 175851d427..0859173f79 100644
--- a/tests/topotests/ospf_metric_propagation/r3/frr.conf
+++ b/tests/topotests/ospf_metric_propagation/r3/frr.conf
@@ -8,18 +8,18 @@ interface r3-eth0
ip address 10.0.3.3/24
ip ospf cost 100
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface r3-eth1 vrf blue
ip address 10.0.30.3/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface r3-eth2 vrf green
ip address 10.0.80.3/24
ip ospf cost 1000
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
router ospf
ospf router-id 10.0.255.3
diff --git a/tests/topotests/ospf_metric_propagation/r4/frr.conf b/tests/topotests/ospf_metric_propagation/r4/frr.conf
index 70a47e34fa..743da27272 100644
--- a/tests/topotests/ospf_metric_propagation/r4/frr.conf
+++ b/tests/topotests/ospf_metric_propagation/r4/frr.conf
@@ -8,17 +8,17 @@ interface r4-eth0
ip address 10.0.3.4/24
ip ospf cost 100
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface r4-eth1 vrf blue
ip address 10.0.40.4/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface r4-eth2 vrf green
ip address 10.0.94.4/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
router ospf
ospf router-id 10.0.255.4
diff --git a/tests/topotests/ospf_metric_propagation/ra/frr.conf b/tests/topotests/ospf_metric_propagation/ra/frr.conf
index 7be9e5c33e..2434faeabc 100644
--- a/tests/topotests/ospf_metric_propagation/ra/frr.conf
+++ b/tests/topotests/ospf_metric_propagation/ra/frr.conf
@@ -7,17 +7,17 @@ ip forwarding
interface ra-eth0
ip address 10.0.50.5/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface ra-eth1
ip address 10.0.10.5/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface ra-eth2
ip address 10.0.20.5/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
router ospf
ospf router-id 10.0.255.5
diff --git a/tests/topotests/ospf_metric_propagation/rb/frr.conf b/tests/topotests/ospf_metric_propagation/rb/frr.conf
index a7dbf82278..b83532a840 100644
--- a/tests/topotests/ospf_metric_propagation/rb/frr.conf
+++ b/tests/topotests/ospf_metric_propagation/rb/frr.conf
@@ -7,17 +7,17 @@ ip forwarding
interface rb-eth0
ip address 10.0.50.6/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface rb-eth1
ip address 10.0.30.6/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface rb-eth2
ip address 10.0.40.6/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
router ospf
ospf router-id 10.0.255.6
diff --git a/tests/topotests/ospf_metric_propagation/rc/frr.conf b/tests/topotests/ospf_metric_propagation/rc/frr.conf
index f5a2ed7c4f..dd8077c394 100644
--- a/tests/topotests/ospf_metric_propagation/rc/frr.conf
+++ b/tests/topotests/ospf_metric_propagation/rc/frr.conf
@@ -7,12 +7,12 @@ ip forwarding
interface rc-eth0
ip address 10.0.70.7/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
interface rc-eth1
ip address 10.0.80.7/24
ip ospf hello-interval 1
- ip ospf dead-interval 30
+ ip ospf dead-interval 40
!
router ospf
ospf router-id 10.0.255.7
diff --git a/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py b/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py
index b9c63622f0..b97b86bff9 100644
--- a/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py
+++ b/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py
@@ -282,7 +282,7 @@ def test_link_1_2_3_4_down():
assert result is None, assertmsg
-def test_link_1_2_4_down():
+def test_link_1_2_4_down_3_up():
"Test path R1 -> R2 -> Rc -> R3 -> R4"
tgen = get_topogen()
@@ -304,7 +304,7 @@ def test_link_1_2_4_down():
assert result is None, assertmsg
-def test_link_1_4_down():
+def test_link_1_4_down_2_up():
"Test path R1 -> R2 -> Ra -> Rb -> R3 -> R4"
tgen = get_topogen()
@@ -320,13 +320,13 @@ def test_link_1_4_down():
test_func = partial(
topotest.router_json_cmp, r1, "show ip route vrf green 10.0.94.2 json", expected
)
- _, result = topotest.run_and_expect(test_func, None, count=60, wait=1)
+ _, result = topotest.run_and_expect(test_func, None, count=120, wait=2)
assertmsg = "r1 JSON output mismatches"
assert result is None, assertmsg
-def test_link_4_down():
+def test_link_4_down_1_up():
"Test path R1 -> Ra -> Rb -> R3 -> R4"
tgen = get_topogen()
@@ -342,7 +342,7 @@ def test_link_4_down():
test_func = partial(
topotest.router_json_cmp, r1, "show ip route vrf green 10.0.94.2 json", expected
)
- _, result = topotest.run_and_expect(test_func, None, count=60, wait=1)
+ _, result = topotest.run_and_expect(test_func, None, count=120, wait=2)
assertmsg = "r1 JSON output mismatches"
assert result is None, assertmsg
@@ -364,7 +364,7 @@ def test_link_1_2_3_4_up():
test_func = partial(
topotest.router_json_cmp, r1, "show ip route vrf green 10.0.94.2 json", expected
)
- _, result = topotest.run_and_expect(test_func, None, count=60, wait=1)
+ _, result = topotest.run_and_expect(test_func, None, count=120, wait=2)
assertmsg = "r1 JSON output mismatches"
assert result is None, assertmsg
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
index 15e0f5316e..d981a84597 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
@@ -388,6 +388,11 @@ def test_ospfv3_hello_tc10_p0(request):
step("Bring up the base config as per the topology")
reset_config_on_routers(tgen)
+ ospf_covergence = verify_ospf6_neighbor(tgen)
+ assert (
+ ospf_covergence is True
+ ), "Testcase {} [01]: Reset Failed \n Error: {}".format(tc_name, ospf_covergence)
+
step("modify hello timer from default value to some other value on r1")
topo1 = {
@@ -402,7 +407,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [02]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step(
"verify that new timer value is configured and applied using "
@@ -422,7 +429,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
}
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [03]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("modify hello timer from default value to r1 hello timer on r2")
@@ -438,7 +447,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [04]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {
@@ -455,12 +466,14 @@ def test_ospfv3_hello_tc10_p0(request):
}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [05]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
- ospf_covergence
+ assert ospf_covergence is True, "Testcase {} [06]: Failed \n Error: {}".format(
+ tc_name, ospf_covergence
)
step("reconfigure the default hello timer value to default on r1 and r2")
@@ -477,7 +490,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [07]: Failed \n Error: {}".format(
+ tc_name, result
+ )
topo1 = {
"r1": {
@@ -491,7 +506,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [08]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {
@@ -508,12 +525,14 @@ def test_ospfv3_hello_tc10_p0(request):
}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [09]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
- ospf_covergence
+ assert ospf_covergence is True, "Testcase {} [10]: Failed \n Error: {}".format(
+ tc_name, ospf_covergence
)
step("reconfigure the default hello timer value to default on r1 and r2")
@@ -530,7 +549,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [11]: Failed \n Error: {}".format(
+ tc_name, result
+ )
topo1 = {
"r1": {
@@ -544,7 +565,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [12]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {
@@ -561,12 +584,14 @@ def test_ospfv3_hello_tc10_p0(request):
}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [13]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
- ospf_covergence
+ assert ospf_covergence is True, "Testcase {} [14]: Failed \n Error: {}".format(
+ tc_name, ospf_covergence
)
step("configure hello timer = 1 on r1 and r2")
@@ -582,7 +607,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [15]: Failed \n Error: {}".format(
+ tc_name, result
+ )
topo1 = {
"r1": {
@@ -596,7 +623,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [16]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {
@@ -613,12 +642,14 @@ def test_ospfv3_hello_tc10_p0(request):
}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [17]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase Failed \n Error: {}".format(
- ospf_covergence
+ assert ospf_covergence is True, "Testcase {} [18]: Failed \n Error: {}".format(
+ tc_name, ospf_covergence
)
step(" Configure hello timer = 65535")
@@ -634,7 +665,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [19]: Failed \n Error: {}".format(
+ tc_name, result
+ )
topo1 = {
"r1": {
@@ -648,7 +681,9 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [20]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that new timer value is configured.")
input_dict = {
@@ -665,11 +700,13 @@ def test_ospfv3_hello_tc10_p0(request):
}
dut = "r0"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [21]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("verify that ospf neighbours are full")
ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut)
- assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format(
+ assert ospf_covergence is True, "Testcase {} [22]: Failed \n Error: {}".format(
tc_name, ospf_covergence
)
step(" Try configuring timer values outside range for example 65536")
@@ -687,7 +724,7 @@ def test_ospfv3_hello_tc10_p0(request):
result = create_interfaces_cfg(tgen, topo1)
assert (
result is not True
- ), "Testcase {} : Failed \n Create interface failed. Error: {}".format(
+ ), "Testcase {} [23]: Failed \n Create interface failed. Error: {}".format(
tc_name, result
)
@@ -706,13 +743,17 @@ def test_ospfv3_hello_tc10_p0(request):
}
result = create_interfaces_cfg(tgen, topo1)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [24]: Failed \n Error: {}".format(
+ tc_name, result
+ )
step("Verify that timer value is deleted from intf & set to default value 40 sec.")
input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigHello": 10}}}}}
dut = "r1"
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
- assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+ assert result is True, "Testcase {} [25]: Failed \n Error: {}".format(
+ tc_name, result
+ )
write_test_footer(tc_name)
diff --git a/tests/topotests/rip_topo1/r1/show_ip_rip.ref b/tests/topotests/rip_topo1/r1/show_ip_rip.ref
index a0b77c886e..b49a042dac 100644
--- a/tests/topotests/rip_topo1/r1/show_ip_rip.ref
+++ b/tests/topotests/rip_topo1/r1/show_ip_rip.ref
@@ -1,4 +1,7 @@
-Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct
Sub-codes:
(n) - normal, (s) - static, (d) - default, (r) - redistribute,
(i) - interface
diff --git a/tests/topotests/rip_topo1/r2/show_ip_rip.ref b/tests/topotests/rip_topo1/r2/show_ip_rip.ref
index b61fb45eac..d0e7e81bc5 100644
--- a/tests/topotests/rip_topo1/r2/show_ip_rip.ref
+++ b/tests/topotests/rip_topo1/r2/show_ip_rip.ref
@@ -1,4 +1,7 @@
-Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct
Sub-codes:
(n) - normal, (s) - static, (d) - default, (r) - redistribute,
(i) - interface
diff --git a/tests/topotests/rip_topo1/r3/show_ip_rip.ref b/tests/topotests/rip_topo1/r3/show_ip_rip.ref
index 1df299b5e6..bb4afc76b7 100644
--- a/tests/topotests/rip_topo1/r3/show_ip_rip.ref
+++ b/tests/topotests/rip_topo1/r3/show_ip_rip.ref
@@ -1,4 +1,7 @@
-Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct
Sub-codes:
(n) - normal, (s) - static, (d) - default, (r) - redistribute,
(i) - interface
diff --git a/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref b/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref
index 30d0f31e18..8645979cc0 100644
--- a/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref
+++ b/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref
@@ -1,4 +1,7 @@
-Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct
Sub-codes:
(n) - normal, (s) - static, (d) - default, (r) - redistribute,
(i) - interface, (a/S) - aggregated/Suppressed
diff --git a/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref b/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref
index fe5bcc8b31..2c4db1ab54 100644
--- a/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref
+++ b/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref
@@ -1,4 +1,7 @@
-Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct
Sub-codes:
(n) - normal, (s) - static, (d) - default, (r) - redistribute,
(i) - interface, (a/S) - aggregated/Suppressed
diff --git a/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref b/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref
index 909ad663ba..2ba0aa6d8f 100644
--- a/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref
+++ b/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref
@@ -1,4 +1,7 @@
-Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP
+Codes: K - kernel route, C - connected, L - local, S - static,
+ R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+ T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
+ f - OpenFabric, t - Table-Direct
Sub-codes:
(n) - normal, (s) - static, (d) - default, (r) - redistribute,
(i) - interface, (a/S) - aggregated/Suppressed
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 461f0e8c61..342c57964c 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -94,7 +94,7 @@ class Vtysh(object):
output = self("configure")
- if "VTY configuration is locked by other VTY" in output:
+ if "configuration is locked" in output.lower():
log.error("vtysh 'configure' returned\n%s\n" % (output))
return False
@@ -261,6 +261,8 @@ ctx_keywords = {
"router ospf6": {},
"router eigrp ": {},
"router babel": {},
+ "router pim": {},
+ "router pim6": {},
"mpls ldp": {"address-family ": {"interface ": {}}},
"l2vpn ": {"member pseudowire ": {}},
"key chain ": {"key ": {}},
@@ -306,12 +308,65 @@ class Config(object):
file_output = self.vtysh.mark_file(filename)
+ vrf_context = None
+ pim_vrfs = []
+
for line in file_output.split("\n"):
line = line.strip()
# Compress duplicate whitespaces
line = " ".join(line.split())
+ # Detect when we are within a vrf context for converting legacy PIM commands
+ if vrf_context:
+ re_vrf = re.match("^(exit-vrf|exit|end)$", line)
+ if re_vrf:
+ vrf_context = None
+ else:
+ re_vrf = re.match("^vrf ([a-z]+)$", line)
+ if re_vrf:
+ vrf_context = re_vrf.group(1)
+
+ # Detect legacy pim commands that need to move under the router pim context
+ re_pim = re.match(
+ "^ip(v6)? pim ((ecmp|join|keep|mlag|packets|register|rp|send|spt|ssm).*)$",
+ line,
+ )
+ if re_pim and re_pim.group(2):
+ router_pim = "router pim"
+ if re_pim.group(1):
+ router_pim += "6"
+ if vrf_context:
+ router_pim += " vrf " + vrf_context
+
+ if vrf_context:
+ pim_vrfs.append(router_pim)
+ pim_vrfs.append(re_pim.group(2))
+ pim_vrfs.append("exit")
+ line = "# PIM VRF LINE MOVED TO ROUTER PIM"
+ else:
+ self.lines.append(router_pim)
+ self.lines.append(re_pim.group(2))
+ line = "exit"
+
+ re_pim = re.match("^ip(v6)? ((ssmpingd|msdp).*)$", line)
+ if re_pim and re_pim.group(2):
+ router_pim = "router pim"
+ if re_pim.group(1):
+ router_pim += "6"
+ if vrf_context:
+ router_pim += " vrf " + vrf_context
+
+ if vrf_context:
+ pim_vrfs.append(router_pim)
+ pim_vrfs.append(re_pim.group(2))
+ pim_vrfs.append("exit")
+ line = "# PIM VRF LINE MOVED TO ROUTER PIM"
+ else:
+ self.lines.append(router_pim)
+ self.lines.append(re_pim.group(2))
+ line = "exit"
+
# Remove 'vrf <vrf_name>' from 'interface <x> vrf <vrf_name>'
if line.startswith("interface ") and "vrf" in line:
line = get_normalized_interface_vrf(line)
@@ -348,6 +403,9 @@ class Config(object):
self.lines.append(line)
+ if len(pim_vrfs) > 0:
+ self.lines.append(pim_vrfs)
+
self.load_contexts()
def load_from_show_running(self, daemon):
@@ -1683,9 +1741,11 @@ def compare_context_objects(newconf, running):
lines_to_del.append((running_ctx_keys, None))
# We cannot do 'no interface' or 'no vrf' in FRR, and so deal with it
- elif running_ctx_keys[0].startswith("interface") or running_ctx_keys[
- 0
- ].startswith("vrf"):
+ elif (
+ running_ctx_keys[0].startswith("interface")
+ or running_ctx_keys[0].startswith("vrf")
+ or running_ctx_keys[0].startswith("router pim")
+ ):
for line in running_ctx.lines:
lines_to_del.append((running_ctx_keys, line))
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 573320667c..e657aa8af0 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -1677,6 +1677,24 @@ static struct cmd_node bfd_profile_node = {
};
#endif /* HAVE_BFDD */
+#ifdef HAVE_PIMD
+static struct cmd_node pim_node = {
+ .name = "pim",
+ .node = PIM_NODE,
+ .parent_node = CONFIG_NODE,
+ .prompt = "%s(config-pim)# ",
+};
+#endif /* HAVE_PIMD */
+
+#ifdef HAVE_PIM6D
+static struct cmd_node pim6_node = {
+ .name = "pim6",
+ .node = PIM6_NODE,
+ .parent_node = CONFIG_NODE,
+ .prompt = "%s(config-pim6)# ",
+};
+#endif /* HAVE_PIM6D */
+
/* Defined in lib/vty.c */
extern struct cmd_node vty_node;
@@ -2413,6 +2431,30 @@ DEFUNSH(VTYSH_BFDD, bfd_profile_enter, bfd_profile_enter_cmd,
}
#endif /* HAVE_BFDD */
+#ifdef HAVE_PIMD
+DEFUNSH(VTYSH_PIMD, router_pim, router_pim_cmd,
+ "router pim [vrf NAME]",
+ ROUTER_STR
+ "Start PIM configuration\n"
+ VRF_CMD_HELP_STR)
+{
+ vty->node = PIM_NODE;
+ return CMD_SUCCESS;
+}
+#endif /* HAVE_PIMD */
+
+#ifdef HAVE_PIM6D
+DEFUNSH(VTYSH_PIM6D, router_pim6, router_pim6_cmd,
+ "router pim6 [vrf NAME]",
+ ROUTER_STR
+ "Start PIMv6 configuration\n"
+ VRF_CMD_HELP_STR)
+{
+ vty->node = PIM6_NODE;
+ return CMD_SUCCESS;
+}
+#endif /* HAVE_PIM6D*/
+
DEFUNSH(VTYSH_ALL, vtysh_line_vty, vtysh_line_vty_cmd, "line vty",
"Configure a terminal line\n"
"Virtual terminal\n")
@@ -2826,6 +2868,34 @@ DEFUNSH(VTYSH_PATHD, vtysh_quit_pathd, vtysh_quit_pathd_cmd, "quit",
}
#endif /* HAVE_PATHD */
+#ifdef HAVE_PIMD
+DEFUNSH(VTYSH_PIMD, vtysh_exit_pimd, vtysh_exit_pimd_cmd, "exit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit(vty);
+}
+
+DEFUNSH(VTYSH_PIMD, vtysh_quit_pimd, vtysh_quit_pimd_cmd, "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_pimd(self, vty, argc, argv);
+}
+#endif /* HAVE_PIMD */
+
+#ifdef HAVE_PIM6D
+DEFUNSH(VTYSH_PIM6D, vtysh_exit_pim6d, vtysh_exit_pim6d_cmd, "exit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit(vty);
+}
+
+DEFUNSH(VTYSH_PIM6D, vtysh_quit_pim6d, vtysh_quit_pim6d_cmd, "quit",
+ "Exit current mode and down to previous mode\n")
+{
+ return vtysh_exit_pim6d(self, vty, argc, argv);
+}
+#endif /* HAVE_PIM6D */
+
DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit",
"Exit current mode and down to previous mode\n")
{
@@ -2988,9 +3058,6 @@ static int show_one_daemon(struct vty *vty, struct cmd_token **argv, int argc,
return ret;
}
-#if CONFDATE > 20240707
- CPP_NOTICE("Remove `show thread ...` commands")
-#endif
DEFUN (vtysh_show_event_timer,
vtysh_show_event_timer_cmd,
"show event timers",
@@ -5293,6 +5360,25 @@ void vtysh_init_vty(void)
install_element(INTERFACE_NODE, &vtysh_exit_interface_cmd);
install_element(INTERFACE_NODE, &vtysh_quit_interface_cmd);
+ /* pimd */
+#ifdef HAVE_PIMD
+ install_node(&pim_node);
+ install_element(CONFIG_NODE, &router_pim_cmd);
+ install_element(PIM_NODE, &vtysh_exit_pimd_cmd);
+ install_element(PIM_NODE, &vtysh_quit_pimd_cmd);
+ install_element(PIM_NODE, &vtysh_end_all_cmd);
+#endif /* HAVE_PIMD */
+
+ /* pim6d */
+#ifdef HAVE_PIM6D
+ install_node(&pim6_node);
+ install_element(CONFIG_NODE, &router_pim6_cmd);
+ install_element(PIM6_NODE, &vtysh_exit_pim6d_cmd);
+ install_element(PIM6_NODE, &vtysh_quit_pim6d_cmd);
+ install_element(PIM6_NODE, &vtysh_end_all_cmd);
+#endif /* HAVE_PIM6D */
+
+ /* zebra and all, cont. */
install_node(&link_params_node);
install_element(INTERFACE_NODE, &vtysh_link_params_cmd);
install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index c207e4d427..8f7cd84818 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -497,6 +497,11 @@ void vtysh_config_parse_line(void *arg, const char *line)
config = config_get(BFD_NODE, line);
else if (strncmp(line, "rpki", strlen("rpki")) == 0)
config = config_get(RPKI_NODE, line);
+ else if (strncmp(line, "router pim", strlen("router pim")) == 0)
+ config = config_get(PIM_NODE, line);
+ else if (strncmp(line, "router pim6", strlen("router pim6")) ==
+ 0)
+ config = config_get(PIM6_NODE, line);
else {
if (strncmp(line, "log", strlen("log")) == 0 ||
strncmp(line, "hostname", strlen("hostname")) == 0 ||
diff --git a/yang/frr-bfdd.yang b/yang/frr-bfdd.yang
index ffba42b53b..02ed921459 100644
--- a/yang/frr-bfdd.yang
+++ b/yang/frr-bfdd.yang
@@ -16,9 +16,6 @@ module frr-bfdd {
import frr-vrf {
prefix frr-vrf;
}
- import frr-route-types {
- prefix frr-route-types;
- }
organization "FRRouting";
contact
diff --git a/yang/frr-eigrpd.yang b/yang/frr-eigrpd.yang
index f672dd5571..d3d9db2f62 100644
--- a/yang/frr-eigrpd.yang
+++ b/yang/frr-eigrpd.yang
@@ -75,7 +75,7 @@ module frr-eigrpd {
typedef autonomous-system {
description "Administrative domain identification for a network";
type uint16 {
- range 1..65535;
+ range "1..65535";
}
}
diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang
index 79c524a40a..1c7d1c8ef4 100644
--- a/yang/frr-zebra.yang
+++ b/yang/frr-zebra.yang
@@ -626,6 +626,7 @@ module frr-zebra {
leaf table-id {
type uint32;
+ default "254";
description
"Routing Table id (default id - 254).";
}
diff --git a/zebra/interface.c b/zebra/interface.c
index f1f24cc29f..b3adc4483e 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -1483,23 +1483,27 @@ static void interface_vrf_change(enum dplane_op_e op, ifindex_t ifindex,
"DPLANE_OP_INTF_UPDATE for VRF %s(%u) table %u",
name, ifindex, tableid);
- if (!vrf_lookup_by_id((vrf_id_t)ifindex)) {
- vrf_id_t exist_id;
-
- exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);
- if (exist_id != VRF_DEFAULT) {
- vrf = vrf_lookup_by_id(exist_id);
-
- if (vrf)
- flog_err(EC_ZEBRA_VRF_MISCONFIGURED,
- "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
- name, ifindex, vrf->name,
- vrf->vrf_id);
- else
- flog_err(EC_ZEBRA_VRF_NOT_FOUND,
- "VRF %s id %u does not exist",
- name, ifindex);
+ /*
+ * For a given tableid, if there already exists a vrf and it
+ * is different from the current vrf to be operated, then there
+ * is a misconfiguration and zebra will exit.
+ */
+ vrf_id_t exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);
+
+ if (exist_id != VRF_DEFAULT) {
+ vrf = vrf_lookup_by_id(exist_id);
+
+ if (!vrf_lookup_by_id((vrf_id_t)ifindex) && !vrf) {
+ flog_err(EC_ZEBRA_VRF_NOT_FOUND,
+ "VRF %s id %u does not exist", name,
+ ifindex);
+ exit(-1);
+ }
+ if (vrf && strcmp(name, vrf->name)) {
+ flog_err(EC_ZEBRA_VRF_MISCONFIGURED,
+ "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
+ name, ifindex, vrf->name, vrf->vrf_id);
exit(-1);
}
}
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 7910559c4b..0844b34672 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -4315,6 +4315,10 @@ dplane_route_update_internal(struct route_node *rn,
continue;
if (CHECK_FLAG(nexthop->flags,
+ NEXTHOP_FLAG_DUPLICATE))
+ continue;
+
+ if (CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_ACTIVE))
SET_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b176ea2fe6..142f83fb36 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1659,6 +1659,9 @@ static bool rib_update_nhg_from_ctx(struct nexthop_group *re_nhg,
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
continue;
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
+ continue;
+
/* Check for a FIB nexthop corresponding to the RIB nexthop */
if (!nexthop_same(ctx_nexthop, nexthop)) {
/* If the FIB doesn't know about the nexthop,