diff options
67 files changed, 4304 insertions, 1145 deletions
diff --git a/.clang-format b/.clang-format index 06769c9661..7aefafa58f 100644 --- a/.clang-format +++ b/.clang-format @@ -224,4 +224,8 @@ WhitespaceSensitiveMacros: - "DEFUN_YANG_NOSH" - "DEFUNSH" - "DEFUNSH_HIDDEN" + - "ALIAS" + - "ALIAS_HIDDEN" + - "ALIAS_YANG" + - "ALIAS_DEPRECATED" ... 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..7706a3eca4 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) { + zebra_announce_del(&bm->zebra_announce_head, dest); bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); - } else - zebra_announce_add_tail(&bm->zebra_announce_head, dest); + } } bgp_evpn_remote_ip_hash_destroy(vpn); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 90881621b3..a1d0a8512c 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -280,7 +280,8 @@ done: * * Sending this vrf-label association is qualified by a) whether vrf->vpn * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list - * are set) and b) whether vpn-policy label is set. + * are set), b) whether vpn-policy label is set and c) the vrf loopback + * interface is up. * * If any of these conditions do not hold, then we send MPLS_LABEL_NONE * for this vrf, which zebra interprets to mean "delete this vrf-label @@ -288,6 +289,7 @@ done: */ void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi) { + struct interface *ifp; mpls_label_t label = MPLS_LABEL_NONE; int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL); @@ -301,7 +303,9 @@ void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi) } if (vpn_leak_to_vpn_active(bgp, afi, NULL, false)) { - label = bgp->vpn_policy[afi].tovpn_label; + ifp = if_get_vrf_loopback(bgp->vrf_id); + if (ifp && if_is_vrf(ifp) && if_is_up(ifp)) + label = bgp->vpn_policy[afi].tovpn_label; } if (debug) { 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 72620de7d9..a40f8177c7 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -234,7 +234,7 @@ static int bgp_ifp_up(struct interface *ifp) hook_call(bgp_vrf_status_changed, bgp, ifp); bgp_nht_ifp_up(ifp); - if (bgp_get_default() && if_is_loopback(ifp)) { + if (bgp_get_default() && if_is_vrf(ifp)) { vpn_leak_zebra_vrf_label_update(bgp, AFI_IP); vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6); vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP); @@ -289,7 +289,7 @@ static int bgp_ifp_down(struct interface *ifp) hook_call(bgp_vrf_status_changed, bgp, ifp); bgp_nht_ifp_down(ifp); - if (bgp_get_default() && if_is_loopback(ifp)) { + if (bgp_get_default() && if_is_vrf(ifp)) { vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP); vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6); vpn_leak_zebra_vrf_sid_withdraw(bgp, AFI_IP); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 3810413adc..043a6e201c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2283,7 +2283,7 @@ static void peer_group2peer_config_copy_af(struct peer_group *group, flags_tmp = conf->af_flags[afi][safi] & ~pflags_ovrd; flags_tmp ^= conf->af_flags_invert[afi][safi] ^ peer->af_flags_invert[afi][safi]; - flags_tmp &= ~pflags_ovrd; + UNSET_FLAG(flags_tmp, pflags_ovrd); UNSET_FLAG(peer->af_flags[afi][safi], ~pflags_ovrd); SET_FLAG(peer->af_flags[afi][safi], flags_tmp); @@ -2523,10 +2523,10 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi) group = peer->group; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) { - ret |= peer_activate_af(tmp_peer, afi, safi); + SET_FLAG(ret, peer_activate_af(tmp_peer, afi, safi)); } } else { - ret |= peer_activate_af(peer, afi, safi); + SET_FLAG(ret, peer_activate_af(peer, afi, safi)); } /* If this is the first peer to be activated for this @@ -2625,10 +2625,11 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) group = peer->group; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) { - ret |= non_peergroup_deactivate_af(tmp_peer, afi, safi); + SET_FLAG(ret, non_peergroup_deactivate_af(tmp_peer, afi, + safi)); } } else { - ret |= non_peergroup_deactivate_af(peer, afi, safi); + SET_FLAG(ret, non_peergroup_deactivate_af(peer, afi, safi)); } bgp = peer->bgp; @@ -2930,9 +2931,9 @@ static void peer_group2peer_config_copy(struct peer_group *group, peer->gtsm_hops = conf->gtsm_hops; /* peer flags apply */ - flags_tmp = conf->flags & ~peer->flags_override; + flags_tmp = CHECK_FLAG(conf->flags, ~peer->flags_override); flags_tmp ^= conf->flags_invert ^ peer->flags_invert; - flags_tmp &= ~peer->flags_override; + UNSET_FLAG(flags_tmp, peer->flags_override); UNSET_FLAG(peer->flags, ~peer->flags_override); SET_FLAG(peer->flags, flags_tmp); @@ -3936,21 +3937,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) { + zebra_announce_del(&bm->zebra_announce_head, dest); bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); - } else - zebra_announce_add_tail(&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 */ @@ -4745,7 +4759,7 @@ static int peer_flag_action_set(const struct peer_flag_action *action_list, if (match->flag == 0) break; - if (match->flag & flag) { + if (CHECK_FLAG(match->flag, flag)) { found = 1; if (match->type == peer_change_reset_in) @@ -5072,15 +5086,17 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, ptype = peer_sort(peer); /* Special check for reflector client. */ - if (flag & PEER_FLAG_REFLECTOR_CLIENT && ptype != BGP_PEER_IBGP) + if (CHECK_FLAG(flag, PEER_FLAG_REFLECTOR_CLIENT) && + ptype != BGP_PEER_IBGP) return BGP_ERR_NOT_INTERNAL_PEER; /* Special check for remove-private-AS. */ - if (flag & PEER_FLAG_REMOVE_PRIVATE_AS && ptype == BGP_PEER_IBGP) + if (CHECK_FLAG(flag, PEER_FLAG_REMOVE_PRIVATE_AS) && + ptype == BGP_PEER_IBGP) return BGP_ERR_REMOVE_PRIVATE_AS; /* as-override is not allowed for IBGP peers */ - if (flag & PEER_FLAG_AS_OVERRIDE && ptype == BGP_PEER_IBGP) + if (CHECK_FLAG(flag, PEER_FLAG_AS_OVERRIDE) && ptype == BGP_PEER_IBGP) return BGP_ERR_AS_OVERRIDE; /* Handle flag updates where desired state matches current state. */ @@ -5131,7 +5147,7 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, * If the peer is a route server client let's not * muck with the nexthop on the way out the door */ - if (flag & PEER_FLAG_RSERVER_CLIENT) { + if (CHECK_FLAG(flag, PEER_FLAG_RSERVER_CLIENT)) { if (set) SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED); 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_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/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/libfrr.c b/lib/libfrr.c index 338a7d0340..328c6ec8b2 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -1051,7 +1051,17 @@ void frr_config_fork(void) zlog_tls_buffer_init(); } -void frr_vty_serv_start(void) +static void frr_check_detach(void) +{ + if (nodetach_term || nodetach_daemon) + return; + + if (daemon_ctl_sock != -1) + close(daemon_ctl_sock); + daemon_ctl_sock = -1; +} + +void frr_vty_serv_start(bool check_detach) { /* allow explicit override of vty_path in the future * (not currently set anywhere) */ @@ -1074,6 +1084,9 @@ void frr_vty_serv_start(void) } vty_serv_start(di->vty_addr, di->vty_port, di->vty_path); + + if (check_detach) + frr_check_detach(); } void frr_vty_serv_stop(void) @@ -1084,16 +1097,6 @@ void frr_vty_serv_stop(void) unlink(di->vty_path); } -static void frr_check_detach(void) -{ - if (nodetach_term || nodetach_daemon) - return; - - if (daemon_ctl_sock != -1) - close(daemon_ctl_sock); - daemon_ctl_sock = -1; -} - static void frr_terminal_close(int isexit) { int nullfd; @@ -1179,7 +1182,7 @@ void frr_run(struct event_loop *master) char instanceinfo[64] = ""; if (!(di->flags & FRR_MANUAL_VTY_START)) - frr_vty_serv_start(); + frr_vty_serv_start(false); if (di->instance) snprintf(instanceinfo, sizeof(instanceinfo), "instance %u ", @@ -1217,7 +1220,8 @@ void frr_run(struct event_loop *master) close(nullfd); } - frr_check_detach(); + if (!(di->flags & FRR_MANUAL_VTY_START)) + frr_check_detach(); } /* end fixed stderr startup logging */ diff --git a/lib/libfrr.h b/lib/libfrr.h index db9cfbcb1f..3248670c83 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -202,7 +202,7 @@ extern void frr_config_fork(void); extern void frr_run(struct event_loop *master); extern void frr_detach(void); -extern void frr_vty_serv_start(void); +extern void frr_vty_serv_start(bool check_detach); extern void frr_vty_serv_stop(void); extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, @@ -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[]; @@ -3502,7 +3502,7 @@ static void vty_mgmt_server_connected(struct mgmt_fe_client *client, /* Start or stop listening for vty connections */ if (connected) - frr_vty_serv_start(); + frr_vty_serv_start(true); else frr_vty_serv_stop(); } @@ -3591,8 +3591,9 @@ static void vty_mgmt_set_config_result_notified( vty_out(vty, "%s\n", errmsg_if_any); } else { debug_fe_client("SET_CONFIG request for client 0x%" PRIx64 - " req-id %" PRIu64 " was successfull", - client_id, req_id); + " req-id %" PRIu64 " was successfull%s%s", + client_id, req_id, errmsg_if_any ? ": " : "", + errmsg_if_any ?: ""); } if (implicit_commit) { @@ -3624,8 +3625,9 @@ static void vty_mgmt_commit_config_result_notified( vty_out(vty, "%s\n", errmsg_if_any); } else { debug_fe_client("COMMIT_CONFIG request for client 0x%" PRIx64 - " req-id %" PRIu64 " was successfull", - client_id, req_id); + " req-id %" PRIu64 " was successfull%s%s", + client_id, req_id, errmsg_if_any ? ": " : "", + errmsg_if_any ?: ""); if (errmsg_if_any) vty_out(vty, "MGMTD: %s\n", errmsg_if_any); } @@ -3656,8 +3658,9 @@ static int vty_mgmt_get_data_result_notified( } debug_fe_client("GET_DATA request succeeded, client 0x%" PRIx64 - " req-id %" PRIu64, - client_id, req_id); + " req-id %" PRIu64 "%s%s", + client_id, req_id, errmsg_if_any ? ": " : "", + errmsg_if_any ?: ""); if (req_id != mgmt_last_req_id) { mgmt_last_req_id = req_id; diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 0a80b3bbf7..0f0cccbbd4 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -980,8 +980,8 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req, } if (!chg_clients) - __log_err("No connected daemon is interested in XPATH %s", - xpath); + __dbg("Daemons interested in XPATH are not currently connected: %s", + xpath); cmtcfg_req->clients |= chg_clients; @@ -992,7 +992,7 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req, if (!num_chgs) { (void)mgmt_txn_send_commit_cfg_reply(txn_req->txn, MGMTD_NO_CFG_CHANGES, - "No changes found to commit!"); + "No connected daemons interested in changes"); return -1; } 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_ldp_sync.c b/ospfd/ospf_ldp_sync.c index d1ef85c9a6..496ae5b4bd 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -901,7 +901,7 @@ DEFPY (no_mpls_ldp_sync, * stop holddown timer if running * restore ospf cost */ - SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); + UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT; ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; EVENT_OFF(ldp_sync_info->t_holddown); 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/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..92214eced4 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_value[XPATH_MAXLEN + 26]; 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; + + 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 (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 +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]; + char ssm_plist_xpath[XPATH_MAXLEN + 16]; 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 + 16]; + 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; + } + + 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"); - return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str); + 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_value[XPATH_MAXLEN + 26]; 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 + 26]; + char xpath_member_value[XPATH_MAXLEN]; + int ret = CMD_WARNING_CONFIG_FAILED; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -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 + 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(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; + char xpath_value[XPATH_MAXLEN + 26]; /* 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 + 26]; + 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..d1368ff1ff 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; + char spt_plist_xpath[XPATH_MAXLEN + 40]; + char spt_action_xpath[XPATH_MAXLEN + 26]; 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), "./keep-alive-timer"); - 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)); - - 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, @@ -599,17 +522,12 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str, const char *group_str) { char group_xpath[XPATH_MAXLEN]; - char rp_xpath[XPATH_MAXLEN]; + char rp_xpath[XPATH_MAXLEN + 47]; 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); @@ -656,21 +568,14 @@ int pim_process_rp_plist_cmd(struct vty *vty, const char *rp_str, int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str, const char *prefix_list) { - char rp_xpath[XPATH_MAXLEN]; - char plist_xpath[XPATH_MAXLEN]; - const char *vrfname; + char rp_xpath[XPATH_MAXLEN + 47]; + char plist_xpath[XPATH_MAXLEN + 1070]; 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_nb_config.c b/pimd/pim_nb_config.c index 4f1a4a1852..be0be8588b 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -1504,11 +1504,19 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_re */ int lib_interface_pim_address_family_create(struct nb_cb_create_args *args) { + struct interface *ifp; + switch (args->event) { case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: case NB_EV_APPLY: + case NB_EV_ABORT: + break; + case NB_EV_PREPARE: + ifp = nb_running_get_entry(args->dnode, NULL, true); + if (ifp->info) + return NB_OK; + + pim_if_new(ifp, false, false, false, false); break; } 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/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/topotests/bgp_evpn_rt5/r1/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf index ccbeae6ed7..c8c4faf222 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf @@ -20,7 +20,11 @@ router bgp 65000 vrf r1-vrf-101 address-family ipv4 unicast network 192.168.102.21/32 exit-address-family + address-family ipv6 unicast + network fd00::1/128 + exit-address-family address-family l2vpn evpn advertise ipv4 unicast + advertise ipv6 unicast exit-address-family ! diff --git a/tests/topotests/bgp_evpn_rt5/r1/zebra.conf b/tests/topotests/bgp_evpn_rt5/r1/zebra.conf index 4f1804c676..c3d508c2b6 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/zebra.conf +++ b/tests/topotests/bgp_evpn_rt5/r1/zebra.conf @@ -17,6 +17,7 @@ interface r1-eth0 ! interface loop101 vrf r1-vrf-101 ip address 192.168.102.21/32 + ipv6 address fd00::1/128 ! diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf index 744c259d9a..de5a0efc44 100644 --- a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf @@ -21,7 +21,11 @@ router bgp 65000 vrf r2-vrf-101 address-family ipv4 unicast network 192.168.101.41/32 exit-address-family + address-family ipv6 unicast + network fd00::2/128 + exit-address-family address-family l2vpn evpn advertise ipv4 unicast + advertise ipv6 unicast exit-address-family ! diff --git a/tests/topotests/bgp_evpn_rt5/r2/zebra.conf b/tests/topotests/bgp_evpn_rt5/r2/zebra.conf index 7d19a5b381..7db40cb59c 100644 --- a/tests/topotests/bgp_evpn_rt5/r2/zebra.conf +++ b/tests/topotests/bgp_evpn_rt5/r2/zebra.conf @@ -11,6 +11,7 @@ vrf r2-vrf-101 ! interface loop101 vrf r2-vrf-101 ip address 192.168.101.41/32 + ipv6 address fd00::2/128 ! interface r2-eth0 ip address 192.168.100.41/24 diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py index d9177b4d25..2d027081cb 100644 --- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py +++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py @@ -25,6 +25,8 @@ sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest +from lib.bgp import verify_bgp_rib +from lib.common_config import apply_raw_config from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger @@ -179,12 +181,18 @@ def test_protocols_convergence(): output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101 ipv4", isjson=False) logger.info("==== result from show bgp vrf r1-vrf-101 ipv4") logger.info(output) + output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101 ipv6", isjson=False) + logger.info("==== result from show bgp vrf r1-vrf-101 ipv6") + logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101", isjson=False) logger.info("==== result from show bgp vrf r1-vrf-101 ") logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show ip route vrf r1-vrf-101", isjson=False) logger.info("==== result from show ip route vrf r1-vrf-101") logger.info(output) + output = tgen.gears["r1"].vtysh_cmd("show ipv6 route vrf r1-vrf-101", isjson=False) + logger.info("==== result from show ipv6 route vrf r1-vrf-101") + logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show evpn vni detail", isjson=False) logger.info("==== result from show evpn vni detail") logger.info(output) @@ -192,8 +200,49 @@ def test_protocols_convergence(): logger.info("==== result from show evpn next-hops vni all") logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show evpn rmac vni all", isjson=False) - logger.info("==== result from show evpn next-hops vni all") + logger.info("==== result from show evpn rmac vni all") logger.info(output) + + expected = { + "fd00::2/128": [ + { + "prefix": "fd00::2/128", + "vrfName": "r1-vrf-101", + "nexthops": [ + { + "ip": "::ffff:c0a8:6429", + } + ], + } + ] + } + result = topotest.router_json_cmp( + tgen.gears["r1"], "show ipv6 route vrf r1-vrf-101 fd00::2/128 json", expected + ) + assert result is None, "ipv6 route check failed" + + expected = { + "101": { + "numNextHops": 2, + "192.168.100.41": { + "nexthopIp": "192.168.100.41", + }, + "::ffff:c0a8:6429": { + "nexthopIp": "::ffff:c0a8:6429", + }, + } + } + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn next-hops vni all json", expected + ) + assert result is None, "evpn next-hops check failed" + + expected = {"101": {"numRmacs": 1}} + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn rmac vni all json", expected + ) + assert result is None, "evpn rmac number check failed" + # Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn) pingrouter = tgen.gears["r1"] logger.info( @@ -209,6 +258,80 @@ def test_protocols_convergence(): else: logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK") + logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(r2-vrf-101 = fd00::2)") + output = pingrouter.run("ip netns exec r1-vrf-101 ping fd00::2 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok" + else: + logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK") + + config_no_ipv6 = { + "r2": { + "raw_config": [ + "router bgp 65000 vrf r2-vrf-101", + "address-family ipv6 unicast", + "no network fd00::2/128", + ] + } + } + + logger.info("==== Remove IPv6 network on R2") + result = apply_raw_config(tgen, config_no_ipv6) + assert result is True, "Failed to remove IPv6 network on R2, Error: {} ".format( + result + ) + ipv6_routes = { + "r1": { + "static_routes": [ + { + "vrf": "r1-vrf-101", + "network": ["fd00::2/128"], + } + ] + } + } + result = verify_bgp_rib(tgen, "ipv6", "r1", ipv6_routes, expected=False) + assert result is not True, "expect IPv6 route fd00::2/128 withdrawn" + output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False) + logger.info("==== result from show evpn next-hops vni all") + logger.info(output) + output = tgen.gears["r1"].vtysh_cmd("show evpn rmac vni all", isjson=False) + logger.info("==== result from show evpn next-hops vni all") + logger.info(output) + + expected = { + "101": { + "numNextHops": 1, + "192.168.100.41": { + "nexthopIp": "192.168.100.41", + }, + } + } + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn next-hops vni all json", expected + ) + assert result is None, "evpn next-hops check failed" + + expected = {"101": {"numRmacs": 1}} + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn rmac vni all json", expected + ) + assert result is None, "evpn rmac number check failed" + + logger.info( + "Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)" + ) + output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = ( + "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok" + ) + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK") + def test_memory_leak(): "Run the memory leak test and report results." 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 b75d0d8751..c47980744a 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 @@ -55,7 +55,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_tilfa_topo1/rt5/step10/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref index 06f432c455..ff8ace25be 100644 --- a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref @@ -457,8 +457,7 @@ "fib":true, "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6", - "active":true + "interfaceName":"eth-rt6" } ] } diff --git a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref index 6c27a10427..846be5b849 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref @@ -5,8 +5,8 @@ "ldpIgpSyncState":"Sync achieved" }, "r2-eth2":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" } } diff --git a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref index 889f69ed7f..ad3b8b5ca4 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref @@ -5,8 +5,8 @@ "ldpIgpSyncState":"Holding down until Sync" }, "r2-eth2":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" } } diff --git a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref index d9036e124b..d5e4b88d07 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref @@ -1,7 +1,7 @@ { "r2-eth2":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" } } diff --git a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref index b417ab040a..5b9542d5a9 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref @@ -1,8 +1,8 @@ { "r3-eth1":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" }, "r3-eth2":{ "ldpIgpSyncEnabled":true, diff --git a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref index b417ab040a..5b9542d5a9 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref @@ -1,8 +1,8 @@ { "r3-eth1":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" }, "r3-eth2":{ "ldpIgpSyncEnabled":true, diff --git a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref index b417ab040a..5b9542d5a9 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref @@ -1,8 +1,8 @@ { "r3-eth1":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" }, "r3-eth2":{ "ldpIgpSyncEnabled":true, 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/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/ietf/frr-deviations-ietf-routing.yang b/yang/ietf/frr-deviations-ietf-routing.yang index 15ceb6b929..5c0ae30bea 100644 --- a/yang/ietf/frr-deviations-ietf-routing.yang +++ b/yang/ietf/frr-deviations-ietf-routing.yang @@ -6,6 +6,9 @@ module frr-deviations-ietf-routing { import ietf-routing { prefix ietf-routing; } + import ietf-rip { + prefix ietf-rip; + } organization "FRRouting"; diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 0844b34672..1cee1ebb93 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -6003,6 +6003,14 @@ int dplane_show_helper(struct vty *vty, bool detailed) vty_out(vty, "Zebra dataplane:\nRoute updates: %"PRIu64"\n", incoming); vty_out(vty, "Route update errors: %"PRIu64"\n", errs); + + incoming = atomic_load_explicit(&zdplane_info.dg_nexthops_in, + memory_order_relaxed); + errs = atomic_load_explicit(&zdplane_info.dg_nexthop_errors, + memory_order_relaxed); + vty_out(vty, "Nexthop updates: %" PRIu64 "\n", incoming); + vty_out(vty, "Nexthop update errors: %" PRIu64 "\n", errs); + vty_out(vty, "Other errors : %"PRIu64"\n", other_errs); vty_out(vty, "Route update queue limit: %"PRIu64"\n", limit); vty_out(vty, "Route update queue depth: %"PRIu64"\n", queued); diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 55920102bb..b4e25daad8 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1050,8 +1050,27 @@ static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid) } /* Update validity of nexthops depending on it */ - frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) + frr_each (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) { + if (!valid) { + /* + * Grab the first nexthop from the depending nexthop group + * then let's find the nexthop in that group that matches + * my individual nexthop and mark it as no longer ACTIVE + */ + struct nexthop *nexthop = rb_node_dep->nhe->nhg.nexthop; + + while (nexthop) { + if (nexthop_same(nexthop, nhe->nhg.nexthop)) + break; + + nexthop = nexthop->next; + } + + if (nexthop) + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + } zebra_nhg_set_valid(rb_node_dep->nhe, valid); + } } void zebra_nhg_check_valid(struct nhg_hash_entry *nhe) @@ -1059,6 +1078,13 @@ void zebra_nhg_check_valid(struct nhg_hash_entry *nhe) struct nhg_connected *rb_node_dep = NULL; bool valid = false; + /* + * If I have other nhe's depending on me, then this is a + * singleton nhe so set this nexthops flag as appropriate. + */ + if (nhg_connected_tree_count(&nhe->nhg_depends)) + UNSET_FLAG(nhe->nhg.nexthop->flags, NEXTHOP_FLAG_ACTIVE); + /* If anthing else in the group is valid, the group is valid */ frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) { if (CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_VALID)) { diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 858e503031..5742c38e23 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -215,7 +215,7 @@ static char re_status_output_char(const struct route_entry *re, if (is_fib) { star_p = !!CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_FIB); - } else + } else if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_ACTIVE)) star_p = true; } diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index b8c11e186a..f1ae42e320 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1356,6 +1356,18 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, { struct zebra_mac *zrmac = NULL; struct ipaddr *vtep = NULL; + struct ipaddr ipv4_vtep; + + /* vtep_ip may be v4 or v6-mapped-v4. But zrmac->fwd_info + * can only contain v4 version. So convert if needed + */ + memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); + ipv4_vtep.ipa_type = IPADDR_V4; + if (vtep_ip->ipa_type == IPADDR_V6) + ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6, + &(ipv4_vtep.ipaddr_v4)); + else + IPV4_ADDR_COPY(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4); zrmac = zl3vni_rmac_lookup(zl3vni, rmac); if (!zrmac) { @@ -1369,7 +1381,7 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, return -1; } memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info)); - zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4; + zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4; vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr)); memcpy(vtep, vtep_ip, sizeof(struct ipaddr)); @@ -1383,14 +1395,14 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, /* install rmac in kernel */ zl3vni_rmac_install(zl3vni, zrmac); } else if (!IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip, - &vtep_ip->ipaddr_v4)) { + &(ipv4_vtep.ipaddr_v4))) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA", zl3vni->vni, &zrmac->fwd_info.r_vtep_ip, vtep_ip, rmac); - zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4; + zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4; vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr)); memcpy(vtep, vtep_ip, sizeof(struct ipaddr)); @@ -1410,36 +1422,29 @@ static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac, struct ipaddr *vtep_ip) { - struct ipaddr ipv4_vtep; - if (!zl3vni_nh_lookup(zl3vni, vtep_ip)) { - memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); - ipv4_vtep.ipa_type = IPADDR_V4; - if (vtep_ip->ipa_type == IPADDR_V6) - ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6, - &ipv4_vtep.ipaddr_v4); - else - memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4, - sizeof(struct in_addr)); - /* remove nh from rmac's list */ - l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, &ipv4_vtep); - /* delete nh is same as current selected, fall back to - * one present in the list - */ - if (IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip, - &ipv4_vtep.ipaddr_v4) && - listcount(zrmac->nh_list)) { + l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, vtep_ip); + /* If there are remaining entries, use IPv4 from one */ + if (listcount(zrmac->nh_list)) { struct ipaddr *vtep; + struct ipaddr ipv4_vtep; vtep = listgetdata(listhead(zrmac->nh_list)); - zrmac->fwd_info.r_vtep_ip = vtep->ipaddr_v4; + memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); + ipv4_vtep.ipa_type = IPADDR_V4; + if (vtep->ipa_type == IPADDR_V6) + ipv4_mapped_ipv6_to_ipv4(&vtep->ipaddr_v6, + &(ipv4_vtep.ipaddr_v4)); + else + IPV4_ADDR_COPY(&(ipv4_vtep.ipaddr_v4), + &vtep->ipaddr_v4); + zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA", - zl3vni->vni, &ipv4_vtep, - &zrmac->fwd_info.r_vtep_ip, - &zrmac->macaddr); + zlog_debug("L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA", + zl3vni->vni, vtep_ip, + &zrmac->fwd_info.r_vtep_ip, + &zrmac->macaddr); /* install rmac in kernel */ zl3vni_rmac_install(zl3vni, zrmac); @@ -2531,7 +2536,6 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, const struct prefix *host_prefix) { struct zebra_l3vni *zl3vni = NULL; - struct ipaddr ipv4_vtep; zl3vni = zl3vni_from_vrf(vrf_id); if (!zl3vni || !is_l3vni_oper_up(zl3vni)) @@ -2547,24 +2551,10 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, svd_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix); /* - * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4 - * address. Rmac is programmed against the ipv4 vtep because we only - * support ipv4 tunnels in the h/w right now - */ - memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); - ipv4_vtep.ipa_type = IPADDR_V4; - if (vtep_ip->ipa_type == IPADDR_V6) - ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6, - &(ipv4_vtep.ipaddr_v4)); - else - memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4, - sizeof(struct in_addr)); - - /* - * add the rmac - remote rmac to be installed is against the ipv4 + * add the rmac - remote rmac to be installed is against the * nexthop address */ - zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep); + zl3vni_remote_rmac_add(zl3vni, rmac, vtep_ip); } /* handle evpn vrf route delete */ |
