]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
Merge pull request #10770 from chiragshah6/evpn_dev3
[mirror_frr.git] / pimd / pim_cmd.c
CommitLineData
12e41d03 1/*
896014f4
DL
2 * PIM for Quagga
3 * Copyright (C) 2008 Everton da Silva Marques
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
12e41d03 19
12e41d03
DL
20#include <zebra.h>
21
9bf3c633 22#include "lib/json.h"
12e41d03
DL
23#include "command.h"
24#include "if.h"
25#include "prefix.h"
26#include "zclient.h"
dfe43e25 27#include "plist.h"
cba44481
CS
28#include "hash.h"
29#include "nexthop.h"
02a16316 30#include "vrf.h"
37664928 31#include "ferr.h"
12e41d03
DL
32
33#include "pimd.h"
9867746a 34#include "pim_mroute.h"
12e41d03
DL
35#include "pim_cmd.h"
36#include "pim_iface.h"
37#include "pim_vty.h"
38#include "pim_mroute.h"
39#include "pim_str.h"
40#include "pim_igmp.h"
41#include "pim_igmpv3.h"
42#include "pim_sock.h"
43#include "pim_time.h"
44#include "pim_util.h"
45#include "pim_oil.h"
46#include "pim_neighbor.h"
47#include "pim_pim.h"
48#include "pim_ifchannel.h"
49#include "pim_hello.h"
50#include "pim_msg.h"
51#include "pim_upstream.h"
52#include "pim_rpf.h"
53#include "pim_macro.h"
54#include "pim_ssmpingd.h"
55#include "pim_zebra.h"
6250610a 56#include "pim_static.h"
a920d6e7 57#include "pim_rp.h"
05b0d0d0 58#include "pim_zlookup.h"
2a333e0f 59#include "pim_msdp.h"
15a5dafe 60#include "pim_ssm.h"
cba44481 61#include "pim_nht.h"
ba4eb1bc 62#include "pim_bfd.h"
f1e2901a 63#include "pim_vxlan.h"
36b5b98f 64#include "pim_mlag.h"
ba4eb1bc 65#include "bfd.h"
4616b2e9 66#include "pim_bsm.h"
b0475d5a
SP
67#include "lib/northbound_cli.h"
68#include "pim_errors.h"
69#include "pim_nb.h"
26cd3d66 70#include "pim_cmd_common.h"
12e41d03 71
414d885a
DS
72#ifndef VTYSH_EXTRACT_PL
73#include "pimd/pim_cmd_clippy.c"
74#endif
75
62b346ee 76static struct cmd_node debug_node = {
f4b8291f 77 .name = "debug",
62b346ee
DL
78 .node = DEBUG_NODE,
79 .prompt = "",
612c2c15 80 .config_write = pim_debug_config_write,
62b346ee 81};
eb7a976a 82
62f59b58
DL
83static inline bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match)
84{
85 return (pim_addr_is_any(match.grp) ||
86 !pim_addr_cmp(match.grp, item.grp)) &&
87 (pim_addr_is_any(match.src) ||
88 !pim_addr_cmp(match.src, item.src));
89}
90
02a16316
DS
91static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
92 const int argc, int *idx)
93{
94 struct vrf *vrf;
95
96 if (argv_find(argv, argc, "NAME", idx))
97 vrf = vrf_lookup_by_name(argv[*idx]->arg);
98 else
99 vrf = vrf_lookup_by_id(VRF_DEFAULT);
100
101 if (!vrf)
102 vty_out(vty, "Specified VRF: %s does not exist\n",
103 argv[*idx]->arg);
104
105 return vrf;
106}
107
1a8a3da8
DS
108static void pim_show_assert_helper(struct vty *vty,
109 struct pim_interface *pim_ifp,
996c9314 110 struct pim_ifchannel *ch, time_t now)
1a8a3da8 111{
1a8a3da8
DS
112 char winner_str[INET_ADDRSTRLEN];
113 struct in_addr ifaddr;
114 char uptime[10];
115 char timer[10];
ee2bbf7c 116 char buf[PREFIX_STRLEN];
1a8a3da8
DS
117
118 ifaddr = pim_ifp->primary_address;
119
1a8a3da8
DS
120 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
121 sizeof(winner_str));
122
996c9314
LB
123 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
124 pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
1a8a3da8 125
8e8be741 126 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-6s %-15s %-8s %-5s\n",
ee2bbf7c 127 ch->interface->name,
8e8be741
DL
128 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
129 &ch->sg.grp, pim_ifchannel_ifassert_name(ch->ifassert_state),
ee2bbf7c 130 winner_str, uptime, timer);
1a8a3da8
DS
131}
132
64c86530 133static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
12e41d03 134{
d62a17ae 135 struct pim_interface *pim_ifp;
136 struct pim_ifchannel *ch;
1a8a3da8 137 struct interface *ifp;
d62a17ae 138 time_t now;
139
140 now = pim_time_monotonic_sec();
141
142 vty_out(vty,
ff415346 143 "Interface Address Source Group State Winner Uptime Timer\n");
d62a17ae 144
451fda4f 145 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 146 pim_ifp = ifp->info;
d62a17ae 147 if (!pim_ifp)
148 continue;
149
a2addae8 150 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
35e5ef55
DS
151 if (ch->ifassert_state == PIM_IFASSERT_NOINFO)
152 continue;
153
1a8a3da8
DS
154 pim_show_assert_helper(vty, pim_ifp, ch, now);
155 } /* scan interface channels */
156 }
157}
d62a17ae 158
1a8a3da8
DS
159static void pim_show_assert_internal_helper(struct vty *vty,
160 struct pim_interface *pim_ifp,
161 struct pim_ifchannel *ch)
162{
1a8a3da8 163 struct in_addr ifaddr;
ee2bbf7c 164 char buf[PREFIX_STRLEN];
d62a17ae 165
1a8a3da8
DS
166 ifaddr = pim_ifp->primary_address;
167
8e8be741 168 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-3s %-3s %-4s\n",
ee2bbf7c 169 ch->interface->name,
8e8be741
DL
170 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
171 &ch->sg.grp,
1a8a3da8
DS
172 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
173 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
996c9314 174 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
521c5b9d 175 : "no",
996c9314 176 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
12e41d03
DL
177}
178
64c86530 179static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
12e41d03 180{
d62a17ae 181 struct pim_interface *pim_ifp;
d62a17ae 182 struct pim_ifchannel *ch;
1a8a3da8 183 struct interface *ifp;
d62a17ae 184
185 vty_out(vty,
186 "CA: CouldAssert\n"
187 "ECA: Evaluate CouldAssert\n"
188 "ATD: AssertTrackingDesired\n"
189 "eATD: Evaluate AssertTrackingDesired\n\n");
190
191 vty_out(vty,
ff415346 192 "Interface Address Source Group CA eCA ATD eATD\n");
451fda4f 193 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 194 pim_ifp = ifp->info;
d62a17ae 195 if (!pim_ifp)
196 continue;
197
a2addae8 198 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
199 pim_show_assert_internal_helper(vty, pim_ifp, ch);
200 } /* scan interface channels */
201 }
202}
203
204static void pim_show_assert_metric_helper(struct vty *vty,
205 struct pim_interface *pim_ifp,
206 struct pim_ifchannel *ch)
207{
1a8a3da8
DS
208 char addr_str[INET_ADDRSTRLEN];
209 struct pim_assert_metric am;
210 struct in_addr ifaddr;
ee2bbf7c 211 char buf[PREFIX_STRLEN];
1a8a3da8
DS
212
213 ifaddr = pim_ifp->primary_address;
214
215 am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
216 pim_ifp->primary_address);
d62a17ae 217
996c9314 218 pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
1a8a3da8 219
8e8be741 220 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %4u %6u %-15s\n",
ee2bbf7c 221 ch->interface->name,
8e8be741
DL
222 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
223 &ch->sg.grp, am.rpt_bit_flag ? "yes" : "no",
ee2bbf7c 224 am.metric_preference, am.route_metric, addr_str);
12e41d03
DL
225}
226
64c86530 227static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
12e41d03 228{
d62a17ae 229 struct pim_interface *pim_ifp;
d62a17ae 230 struct pim_ifchannel *ch;
1a8a3da8 231 struct interface *ifp;
ea4a71fc 232
d62a17ae 233 vty_out(vty,
ff415346 234 "Interface Address Source Group RPT Pref Metric Address \n");
12e41d03 235
451fda4f 236 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 237 pim_ifp = ifp->info;
d62a17ae 238 if (!pim_ifp)
239 continue;
12e41d03 240
a2addae8 241 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
242 pim_show_assert_metric_helper(vty, pim_ifp, ch);
243 } /* scan interface channels */
244 }
245}
12e41d03 246
1a8a3da8
DS
247static void pim_show_assert_winner_metric_helper(struct vty *vty,
248 struct pim_interface *pim_ifp,
249 struct pim_ifchannel *ch)
250{
1a8a3da8
DS
251 char addr_str[INET_ADDRSTRLEN];
252 struct pim_assert_metric *am;
253 struct in_addr ifaddr;
a2dc7057
DL
254 char pref_str[16];
255 char metr_str[16];
ee2bbf7c 256 char buf[PREFIX_STRLEN];
1a8a3da8
DS
257
258 ifaddr = pim_ifp->primary_address;
259
260 am = &ch->ifassert_winner_metric;
261
996c9314 262 pim_inet4_dump("<addr?>", am->ip_address, addr_str, sizeof(addr_str));
1a8a3da8
DS
263
264 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
265 snprintf(pref_str, sizeof(pref_str), "INFI");
266 else
267 snprintf(pref_str, sizeof(pref_str), "%4u",
268 am->metric_preference);
269
270 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
271 snprintf(metr_str, sizeof(metr_str), "INFI");
272 else
996c9314 273 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
1a8a3da8 274
8e8be741 275 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-4s %-6s %-15s\n",
ee2bbf7c 276 ch->interface->name,
8e8be741
DL
277 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
278 &ch->sg.grp, am->rpt_bit_flag ? "yes" : "no", pref_str,
279 metr_str, addr_str);
12e41d03
DL
280}
281
64c86530
DS
282static void pim_show_assert_winner_metric(struct pim_instance *pim,
283 struct vty *vty)
12e41d03 284{
d62a17ae 285 struct pim_interface *pim_ifp;
d62a17ae 286 struct pim_ifchannel *ch;
1a8a3da8 287 struct interface *ifp;
d62a17ae 288
289 vty_out(vty,
ff415346 290 "Interface Address Source Group RPT Pref Metric Address \n");
d62a17ae 291
451fda4f 292 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 293 pim_ifp = ifp->info;
d62a17ae 294 if (!pim_ifp)
295 continue;
12e41d03 296
a2addae8 297 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
298 pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
299 } /* scan interface channels */
300 }
12e41d03
DL
301}
302
d62a17ae 303static void json_object_pim_ifp_add(struct json_object *json,
304 struct interface *ifp)
e775c0a4 305{
d62a17ae 306 struct pim_interface *pim_ifp;
e775c0a4 307
d62a17ae 308 pim_ifp = ifp->info;
309 json_object_string_add(json, "name", ifp->name);
310 json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
b0d5264e
DA
311 json_object_string_addf(json, "address", "%pI4",
312 &pim_ifp->primary_address);
d62a17ae 313 json_object_int_add(json, "index", ifp->ifindex);
e775c0a4 314
d62a17ae 315 if (if_is_multicast(ifp))
316 json_object_boolean_true_add(json, "flagMulticast");
e775c0a4 317
d62a17ae 318 if (if_is_broadcast(ifp))
319 json_object_boolean_true_add(json, "flagBroadcast");
e775c0a4 320
d62a17ae 321 if (ifp->flags & IFF_ALLMULTI)
322 json_object_boolean_true_add(json, "flagAllMulticast");
e775c0a4 323
d62a17ae 324 if (ifp->flags & IFF_PROMISC)
325 json_object_boolean_true_add(json, "flagPromiscuous");
e775c0a4 326
d62a17ae 327 if (PIM_IF_IS_DELETED(ifp))
328 json_object_boolean_true_add(json, "flagDeleted");
e775c0a4 329
d62a17ae 330 if (pim_if_lan_delay_enabled(ifp))
331 json_object_boolean_true_add(json, "lanDelayEnabled");
e775c0a4
DW
332}
333
1a8a3da8
DS
334static void pim_show_membership_helper(struct vty *vty,
335 struct pim_interface *pim_ifp,
336 struct pim_ifchannel *ch,
337 struct json_object *json)
338{
8e8be741 339 char ch_grp_str[PIM_ADDRSTRLEN];
1a8a3da8
DS
340 json_object *json_iface = NULL;
341 json_object *json_row = NULL;
342
996c9314 343 json_object_object_get_ex(json, ch->interface->name, &json_iface);
1a8a3da8
DS
344 if (!json_iface) {
345 json_iface = json_object_new_object();
346 json_object_pim_ifp_add(json_iface, ch->interface);
996c9314 347 json_object_object_add(json, ch->interface->name, json_iface);
1a8a3da8
DS
348 }
349
8e8be741
DL
350 snprintfrr(ch_grp_str, sizeof(ch_grp_str), "%pPAs", &ch->sg.grp);
351
1a8a3da8 352 json_row = json_object_new_object();
8e8be741 353 json_object_string_addf(json_row, "source", "%pPAs", &ch->sg.src);
1a8a3da8 354 json_object_string_add(json_row, "group", ch_grp_str);
996c9314
LB
355 json_object_string_add(json_row, "localMembership",
356 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
521c5b9d
MS
357 ? "NOINFO"
358 : "INCLUDE");
1a8a3da8 359 json_object_object_add(json_iface, ch_grp_str, json_row);
1a8a3da8 360}
8e8be741 361
64c86530 362static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
088f1098 363 bool uj)
12e41d03 364{
d62a17ae 365 struct pim_interface *pim_ifp;
d62a17ae 366 struct pim_ifchannel *ch;
1a8a3da8 367 struct interface *ifp;
d62a17ae 368 enum json_type type;
369 json_object *json = NULL;
d62a17ae 370 json_object *json_tmp = NULL;
371
372 json = json_object_new_object();
373
451fda4f 374 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 375 pim_ifp = ifp->info;
d62a17ae 376 if (!pim_ifp)
377 continue;
378
a2addae8 379 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8
DS
380 pim_show_membership_helper(vty, pim_ifp, ch, json);
381 } /* scan interface channels */
382 }
d62a17ae 383
384 if (uj) {
9d303b37 385 vty_out(vty, "%s\n", json_object_to_json_string_ext(
521c5b9d 386 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 387 } else {
388 vty_out(vty,
ff415346 389 "Interface Address Source Group Membership\n");
d62a17ae 390
391 /*
392 * Example of the json data we are traversing
393 *
394 * {
395 * "swp3":{
396 * "name":"swp3",
397 * "state":"up",
398 * "address":"10.1.20.1",
399 * "index":5,
400 * "flagMulticast":true,
401 * "flagBroadcast":true,
402 * "lanDelayEnabled":true,
403 * "226.10.10.10":{
404 * "source":"*",
405 * "group":"226.10.10.10",
406 * "localMembership":"INCLUDE"
407 * }
408 * }
409 * }
410 */
411
412 /* foreach interface */
413 json_object_object_foreach(json, key, val)
414 {
415
416 /* Find all of the keys where the val is an object. In
417 * the example
418 * above the only one is 226.10.10.10
419 */
420 json_object_object_foreach(val, if_field_key,
421 if_field_val)
422 {
423 type = json_object_get_type(if_field_val);
424
425 if (type == json_type_object) {
ff415346 426 vty_out(vty, "%-16s ", key);
d62a17ae 427
428 json_object_object_get_ex(
429 val, "address", &json_tmp);
430 vty_out(vty, "%-15s ",
431 json_object_get_string(
432 json_tmp));
433
434 json_object_object_get_ex(if_field_val,
435 "source",
436 &json_tmp);
437 vty_out(vty, "%-15s ",
438 json_object_get_string(
439 json_tmp));
440
441 /* Group */
442 vty_out(vty, "%-15s ", if_field_key);
443
444 json_object_object_get_ex(
445 if_field_val, "localMembership",
446 &json_tmp);
447 vty_out(vty, "%-10s\n",
448 json_object_get_string(
449 json_tmp));
450 }
451 }
452 }
453 }
454
455 json_object_free(json);
456}
457
c532e503 458static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp)
d62a17ae 459{
460 vty_out(vty, "Flags\n");
461 vty_out(vty, "-----\n");
462 vty_out(vty, "All Multicast : %s\n",
463 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
464 vty_out(vty, "Broadcast : %s\n",
465 if_is_broadcast(ifp) ? "yes" : "no");
466 vty_out(vty, "Deleted : %s\n",
467 PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
468 vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
469 vty_out(vty, "Multicast : %s\n",
470 if_is_multicast(ifp) ? "yes" : "no");
d62a17ae 471 vty_out(vty, "Promiscuous : %s\n",
472 (ifp->flags & IFF_PROMISC) ? "yes" : "no");
473 vty_out(vty, "\n");
474 vty_out(vty, "\n");
a268493f
DW
475}
476
64c86530 477static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
088f1098 478 bool uj)
12e41d03 479{
d62a17ae 480 struct interface *ifp;
481 time_t now;
ee2bbf7c 482 char buf[PREFIX_STRLEN];
d62a17ae 483 json_object *json = NULL;
484 json_object *json_row = NULL;
485
486 now = pim_time_monotonic_sec();
487
488 if (uj)
489 json = json_object_new_object();
490 else
491 vty_out(vty,
9a7cee26 492 "Interface State Address V Querier QuerierIp Query Timer Uptime\n");
d62a17ae 493
451fda4f 494 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 495 struct pim_interface *pim_ifp;
496 struct listnode *sock_node;
c5f76fad 497 struct gm_sock *igmp;
d62a17ae 498
499 pim_ifp = ifp->info;
500
501 if (!pim_ifp)
502 continue;
503
18adcff1 504 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
d62a17ae 505 igmp)) {
506 char uptime[10];
507 char query_hhmmss[10];
508
509 pim_time_uptime(uptime, sizeof(uptime),
510 now - igmp->sock_creation);
511 pim_time_timer_to_hhmmss(query_hhmmss,
512 sizeof(query_hhmmss),
513 igmp->t_igmp_query_timer);
514
515 if (uj) {
516 json_row = json_object_new_object();
517 json_object_pim_ifp_add(json_row, ifp);
518 json_object_string_add(json_row, "upTime",
519 uptime);
520 json_object_int_add(json_row, "version",
29e58225 521 pim_ifp->igmp_version);
d62a17ae 522
523 if (igmp->t_igmp_query_timer) {
524 json_object_boolean_true_add(json_row,
525 "querier");
526 json_object_string_add(json_row,
527 "queryTimer",
528 query_hhmmss);
529 }
b0d5264e
DA
530 json_object_string_addf(json_row, "querierIp",
531 "%pI4",
532 &igmp->querier_addr);
d62a17ae 533
534 json_object_object_add(json, ifp->name,
535 json_row);
536
f83f3966
MS
537 if (igmp->mtrace_only) {
538 json_object_boolean_true_add(
539 json_row, "mtraceOnly");
540 }
d62a17ae 541 } else {
542 vty_out(vty,
9a7cee26 543 "%-16s %5s %15s %d %7s %17pI4 %11s %8s\n",
d62a17ae 544 ifp->name,
f83f3966 545 if_is_up(ifp)
9a7cee26 546 ? (igmp->mtrace_only ? "mtrc"
547 : "up")
548 : "down",
549 inet_ntop(AF_INET, &igmp->ifaddr, buf,
550 sizeof(buf)),
29e58225 551 pim_ifp->igmp_version,
d62a17ae 552 igmp->t_igmp_query_timer ? "local"
9a7cee26 553 : "other",
554 &igmp->querier_addr, query_hhmmss,
555 uptime);
d62a17ae 556 }
557 }
558 }
559
3757f964
DA
560 if (uj)
561 vty_json(vty, json);
d62a17ae 562}
563
64c86530
DS
564static void igmp_show_interfaces_single(struct pim_instance *pim,
565 struct vty *vty, const char *ifname,
088f1098 566 bool uj)
d62a17ae 567{
c5f76fad 568 struct gm_sock *igmp;
d62a17ae 569 struct interface *ifp;
d62a17ae 570 struct listnode *sock_node;
571 struct pim_interface *pim_ifp;
572 char uptime[10];
573 char query_hhmmss[10];
574 char other_hhmmss[10];
575 int found_ifname = 0;
576 int sqi;
d62a17ae 577 long gmi_msec; /* Group Membership Interval */
578 long lmqt_msec;
579 long ohpi_msec;
580 long oqpi_msec; /* Other Querier Present Interval */
581 long qri_msec;
582 time_t now;
59115451 583 int lmqc;
d62a17ae 584
585 json_object *json = NULL;
586 json_object *json_row = NULL;
587
588 if (uj)
589 json = json_object_new_object();
590
591 now = pim_time_monotonic_sec();
592
451fda4f 593 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 594 pim_ifp = ifp->info;
595
596 if (!pim_ifp)
597 continue;
598
599 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
600 continue;
601
18adcff1 602 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
d62a17ae 603 igmp)) {
604 found_ifname = 1;
605 pim_time_uptime(uptime, sizeof(uptime),
606 now - igmp->sock_creation);
607 pim_time_timer_to_hhmmss(query_hhmmss,
608 sizeof(query_hhmmss),
609 igmp->t_igmp_query_timer);
610 pim_time_timer_to_hhmmss(other_hhmmss,
611 sizeof(other_hhmmss),
612 igmp->t_other_querier_timer);
613
614 gmi_msec = PIM_IGMP_GMI_MSEC(
615 igmp->querier_robustness_variable,
616 igmp->querier_query_interval,
18adcff1 617 pim_ifp->gm_query_max_response_time_dsec);
d62a17ae 618
18adcff1 619 sqi = PIM_IGMP_SQI(pim_ifp->gm_default_query_interval);
d62a17ae 620
621 oqpi_msec = PIM_IGMP_OQPI_MSEC(
622 igmp->querier_robustness_variable,
623 igmp->querier_query_interval,
18adcff1 624 pim_ifp->gm_query_max_response_time_dsec);
d62a17ae 625
626 lmqt_msec = PIM_IGMP_LMQT_MSEC(
18adcff1
SG
627 pim_ifp->gm_specific_query_max_response_time_dsec,
628 pim_ifp->gm_last_member_query_count);
d62a17ae 629
630 ohpi_msec =
631 PIM_IGMP_OHPI_DSEC(
632 igmp->querier_robustness_variable,
633 igmp->querier_query_interval,
18adcff1
SG
634 pim_ifp->gm_query_max_response_time_dsec) *
635 100;
d62a17ae 636
18adcff1
SG
637 qri_msec =
638 pim_ifp->gm_query_max_response_time_dsec * 100;
18adcff1 639 lmqc = pim_ifp->gm_last_member_query_count;
d62a17ae 640
641 if (uj) {
642 json_row = json_object_new_object();
643 json_object_pim_ifp_add(json_row, ifp);
644 json_object_string_add(json_row, "upTime",
645 uptime);
646 json_object_string_add(json_row, "querier",
647 igmp->t_igmp_query_timer
521c5b9d
MS
648 ? "local"
649 : "other");
b0d5264e
DA
650 json_object_string_addf(json_row, "querierIp",
651 "%pI4",
652 &igmp->querier_addr);
d62a17ae 653 json_object_int_add(json_row, "queryStartCount",
654 igmp->startup_query_count);
655 json_object_string_add(json_row,
656 "queryQueryTimer",
657 query_hhmmss);
658 json_object_string_add(json_row,
659 "queryOtherTimer",
660 other_hhmmss);
661 json_object_int_add(json_row, "version",
29e58225 662 pim_ifp->igmp_version);
d62a17ae 663 json_object_int_add(
664 json_row,
665 "timerGroupMembershipIntervalMsec",
666 gmi_msec);
59115451
SP
667 json_object_int_add(json_row,
668 "lastMemberQueryCount",
669 lmqc);
d62a17ae 670 json_object_int_add(json_row,
671 "timerLastMemberQueryMsec",
672 lmqt_msec);
673 json_object_int_add(
674 json_row,
675 "timerOlderHostPresentIntervalMsec",
676 ohpi_msec);
677 json_object_int_add(
678 json_row,
679 "timerOtherQuerierPresentIntervalMsec",
680 oqpi_msec);
681 json_object_int_add(
682 json_row, "timerQueryInterval",
683 igmp->querier_query_interval);
684 json_object_int_add(
685 json_row,
686 "timerQueryResponseIntervalMsec",
687 qri_msec);
688 json_object_int_add(
689 json_row, "timerRobustnessVariable",
690 igmp->querier_robustness_variable);
691 json_object_int_add(json_row,
692 "timerStartupQueryInterval",
693 sqi);
694
695 json_object_object_add(json, ifp->name,
696 json_row);
697
f83f3966
MS
698 if (igmp->mtrace_only) {
699 json_object_boolean_true_add(
700 json_row, "mtraceOnly");
701 }
d62a17ae 702 } else {
703 vty_out(vty, "Interface : %s\n", ifp->name);
704 vty_out(vty, "State : %s\n",
521c5b9d
MS
705 if_is_up(ifp) ? (igmp->mtrace_only ?
706 "mtrace"
707 : "up")
708 : "down");
ee2bbf7c
MS
709 vty_out(vty, "Address : %pI4\n",
710 &pim_ifp->primary_address);
d62a17ae 711 vty_out(vty, "Uptime : %s\n", uptime);
712 vty_out(vty, "Version : %d\n",
29e58225 713 pim_ifp->igmp_version);
d62a17ae 714 vty_out(vty, "\n");
715 vty_out(vty, "\n");
716
717 vty_out(vty, "Querier\n");
718 vty_out(vty, "-------\n");
719 vty_out(vty, "Querier : %s\n",
720 igmp->t_igmp_query_timer ? "local"
521c5b9d 721 : "other");
9a7cee26 722 vty_out(vty, "QuerierIp : %pI4",
723 &igmp->querier_addr);
724 if (pim_ifp->primary_address.s_addr
725 == igmp->querier_addr.s_addr)
726 vty_out(vty, " (this router)\n");
727 else
728 vty_out(vty, "\n");
729
d62a17ae 730 vty_out(vty, "Start Count : %d\n",
731 igmp->startup_query_count);
732 vty_out(vty, "Query Timer : %s\n",
733 query_hhmmss);
734 vty_out(vty, "Other Timer : %s\n",
735 other_hhmmss);
736 vty_out(vty, "\n");
737 vty_out(vty, "\n");
738
739 vty_out(vty, "Timers\n");
740 vty_out(vty, "------\n");
741 vty_out(vty,
742 "Group Membership Interval : %lis\n",
743 gmi_msec / 1000);
59115451
SP
744 vty_out(vty,
745 "Last Member Query Count : %d\n",
746 lmqc);
d62a17ae 747 vty_out(vty,
748 "Last Member Query Time : %lis\n",
749 lmqt_msec / 1000);
750 vty_out(vty,
751 "Older Host Present Interval : %lis\n",
752 ohpi_msec / 1000);
753 vty_out(vty,
754 "Other Querier Present Interval : %lis\n",
755 oqpi_msec / 1000);
756 vty_out(vty,
757 "Query Interval : %ds\n",
758 igmp->querier_query_interval);
759 vty_out(vty,
760 "Query Response Interval : %lis\n",
761 qri_msec / 1000);
762 vty_out(vty,
763 "Robustness Variable : %d\n",
764 igmp->querier_robustness_variable);
765 vty_out(vty,
766 "Startup Query Interval : %ds\n",
767 sqi);
768 vty_out(vty, "\n");
769 vty_out(vty, "\n");
770
c532e503 771 pim_print_ifp_flags(vty, ifp);
d62a17ae 772 }
773 }
774 }
775
3757f964
DA
776 if (uj)
777 vty_json(vty, json);
778 else if (!found_ifname)
779 vty_out(vty, "%% No such interface\n");
12e41d03
DL
780}
781
85c82866 782static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty,
783 bool uj)
12e41d03 784{
d62a17ae 785 struct interface *ifp;
786 time_t now;
85c82866 787 json_object *json = NULL;
788 json_object *json_iface = NULL;
789 json_object *json_grp = NULL;
790 json_object *json_grp_arr = NULL;
d62a17ae 791
792 now = pim_time_monotonic_sec();
793
85c82866 794 if (uj) {
795 json = json_object_new_object();
796 json_object_string_add(json, "vrf",
d3cc1e45 797 vrf_id_to_name(pim->vrf->vrf_id));
85c82866 798 } else {
799 vty_out(vty,
800 "Interface Address Source Group Socket Uptime \n");
801 }
d62a17ae 802
451fda4f 803 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 804 struct pim_interface *pim_ifp;
805 struct listnode *join_node;
7caa9451 806 struct gm_join *ij;
d62a17ae 807 struct in_addr pri_addr;
808 char pri_addr_str[INET_ADDRSTRLEN];
809
810 pim_ifp = ifp->info;
811
812 if (!pim_ifp)
813 continue;
814
18adcff1 815 if (!pim_ifp->gm_join_list)
d62a17ae 816 continue;
817
818 pri_addr = pim_find_primary_addr(ifp);
819 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
820 sizeof(pri_addr_str));
821
18adcff1 822 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_join_list, join_node,
29e58225 823 ij)) {
d62a17ae 824 char group_str[INET_ADDRSTRLEN];
825 char source_str[INET_ADDRSTRLEN];
826 char uptime[10];
827
828 pim_time_uptime(uptime, sizeof(uptime),
829 now - ij->sock_creation);
830 pim_inet4_dump("<grp?>", ij->group_addr, group_str,
831 sizeof(group_str));
832 pim_inet4_dump("<src?>", ij->source_addr, source_str,
833 sizeof(source_str));
834
85c82866 835 if (uj) {
836 json_object_object_get_ex(json, ifp->name,
837 &json_iface);
838
839 if (!json_iface) {
840 json_iface = json_object_new_object();
841 json_object_string_add(
842 json_iface, "name", ifp->name);
843 json_object_object_add(json, ifp->name,
844 json_iface);
845 json_grp_arr = json_object_new_array();
846 json_object_object_add(json_iface,
847 "groups",
848 json_grp_arr);
849 }
850
851 json_grp = json_object_new_object();
852 json_object_string_add(json_grp, "source",
853 source_str);
854 json_object_string_add(json_grp, "group",
855 group_str);
856 json_object_string_add(json_grp, "primaryAddr",
857 pri_addr_str);
858 json_object_int_add(json_grp, "sockFd",
859 ij->sock_fd);
860 json_object_string_add(json_grp, "upTime",
861 uptime);
862 json_object_array_add(json_grp_arr, json_grp);
863 } else {
864 vty_out(vty,
865 "%-16s %-15s %-15s %-15s %6d %8s\n",
866 ifp->name, pri_addr_str, source_str,
867 group_str, ij->sock_fd, uptime);
868 }
18adcff1 869 } /* for (pim_ifp->gm_join_list) */
d62a17ae 870
871 } /* for (iflist) */
85c82866 872
3757f964
DA
873 if (uj)
874 vty_json(vty, json);
d62a17ae 875}
876
64c86530
DS
877static void pim_show_interfaces_single(struct pim_instance *pim,
878 struct vty *vty, const char *ifname,
17823cdd 879 bool mlag, bool uj)
d62a17ae 880{
881 struct in_addr ifaddr;
882 struct interface *ifp;
883 struct listnode *neighnode;
d62a17ae 884 struct pim_interface *pim_ifp;
885 struct pim_neighbor *neigh;
886 struct pim_upstream *up;
887 time_t now;
888 char dr_str[INET_ADDRSTRLEN];
889 char dr_uptime[10];
890 char expire[10];
891 char grp_str[INET_ADDRSTRLEN];
892 char hello_period[10];
893 char hello_timer[10];
894 char neigh_src_str[INET_ADDRSTRLEN];
895 char src_str[INET_ADDRSTRLEN];
896 char stat_uptime[10];
897 char uptime[10];
d62a17ae 898 int found_ifname = 0;
899 int print_header;
900 json_object *json = NULL;
901 json_object *json_row = NULL;
902 json_object *json_pim_neighbor = NULL;
903 json_object *json_pim_neighbors = NULL;
904 json_object *json_group = NULL;
905 json_object *json_group_source = NULL;
906 json_object *json_fhr_sources = NULL;
907 struct pim_secondary_addr *sec_addr;
908 struct listnode *sec_node;
909
910 now = pim_time_monotonic_sec();
911
912 if (uj)
913 json = json_object_new_object();
914
451fda4f 915 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 916 pim_ifp = ifp->info;
917
918 if (!pim_ifp)
919 continue;
920
17823cdd
DS
921 if (mlag == true && pim_ifp->activeactive == false)
922 continue;
923
d62a17ae 924 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
925 continue;
926
927 found_ifname = 1;
928 ifaddr = pim_ifp->primary_address;
929 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
930 sizeof(dr_str));
931 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
932 pim_ifp->pim_dr_election_last);
933 pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
934 pim_ifp->t_pim_hello_timer);
935 pim_time_mmss(hello_period, sizeof(hello_period),
936 pim_ifp->pim_hello_period);
937 pim_time_uptime(stat_uptime, sizeof(stat_uptime),
938 now - pim_ifp->pim_ifstat_start);
d62a17ae 939
940 if (uj) {
941 char pbuf[PREFIX2STR_BUFFER];
942 json_row = json_object_new_object();
943 json_object_pim_ifp_add(json_row, ifp);
944
945 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
b0d5264e
DA
946 json_object_string_addf(
947 json_row, "useSource", "%pI4",
948 &pim_ifp->update_source);
d62a17ae 949 }
950 if (pim_ifp->sec_addr_list) {
951 json_object *sec_list = NULL;
952
953 sec_list = json_object_new_array();
954 for (ALL_LIST_ELEMENTS_RO(
955 pim_ifp->sec_addr_list, sec_node,
956 sec_addr)) {
957 json_object_array_add(
958 sec_list,
959 json_object_new_string(
960 prefix2str(
961 &sec_addr->addr,
962 pbuf,
963 sizeof(pbuf))));
964 }
965 json_object_object_add(json_row,
966 "secondaryAddressList",
967 sec_list);
968 }
969
970 // PIM neighbors
971 if (pim_ifp->pim_neighbor_list->count) {
972 json_pim_neighbors = json_object_new_object();
973
974 for (ALL_LIST_ELEMENTS_RO(
975 pim_ifp->pim_neighbor_list,
976 neighnode, neigh)) {
977 json_pim_neighbor =
978 json_object_new_object();
979 pim_inet4_dump("<src?>",
980 neigh->source_addr,
981 neigh_src_str,
982 sizeof(neigh_src_str));
983 pim_time_uptime(uptime, sizeof(uptime),
984 now - neigh->creation);
985 pim_time_timer_to_hhmmss(
986 expire, sizeof(expire),
987 neigh->t_expire_timer);
988
989 json_object_string_add(
990 json_pim_neighbor, "address",
991 neigh_src_str);
992 json_object_string_add(
993 json_pim_neighbor, "upTime",
994 uptime);
995 json_object_string_add(
996 json_pim_neighbor, "holdtime",
997 expire);
998
999 json_object_object_add(
1000 json_pim_neighbors,
1001 neigh_src_str,
1002 json_pim_neighbor);
1003 }
1004
1005 json_object_object_add(json_row, "neighbors",
1006 json_pim_neighbors);
1007 }
1008
1009 json_object_string_add(json_row, "drAddress", dr_str);
1010 json_object_int_add(json_row, "drPriority",
1011 pim_ifp->pim_dr_priority);
1012 json_object_string_add(json_row, "drUptime", dr_uptime);
1013 json_object_int_add(json_row, "drElections",
1014 pim_ifp->pim_dr_election_count);
1015 json_object_int_add(json_row, "drChanges",
1016 pim_ifp->pim_dr_election_changes);
1017
1018 // FHR
dd3364cb 1019 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
5fe58e3d
DS
1020 if (ifp != up->rpf.source_nexthop.interface)
1021 continue;
1022
1023 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1024 continue;
1025
1026 if (!json_fhr_sources)
1027 json_fhr_sources =
1028 json_object_new_object();
1029
8e8be741
DL
1030 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
1031 &up->sg.grp);
1032 snprintfrr(src_str, sizeof(src_str), "%pPAs",
1033 &up->sg.src);
5fe58e3d
DS
1034 pim_time_uptime(uptime, sizeof(uptime),
1035 now - up->state_transition);
1036
1037 /*
1038 * Does this group live in json_fhr_sources?
1039 * If not create it.
1040 */
1041 json_object_object_get_ex(json_fhr_sources,
996c9314 1042 grp_str, &json_group);
5fe58e3d
DS
1043
1044 if (!json_group) {
1045 json_group = json_object_new_object();
996c9314
LB
1046 json_object_object_add(json_fhr_sources,
1047 grp_str,
1048 json_group);
d62a17ae 1049 }
5fe58e3d
DS
1050
1051 json_group_source = json_object_new_object();
1052 json_object_string_add(json_group_source,
1053 "source", src_str);
1054 json_object_string_add(json_group_source,
1055 "group", grp_str);
1056 json_object_string_add(json_group_source,
1057 "upTime", uptime);
1058 json_object_object_add(json_group, src_str,
1059 json_group_source);
d62a17ae 1060 }
1061
1062 if (json_fhr_sources) {
1063 json_object_object_add(json_row,
1064 "firstHopRouter",
1065 json_fhr_sources);
1066 }
1067
1068 json_object_int_add(json_row, "helloPeriod",
1069 pim_ifp->pim_hello_period);
899dd339
MR
1070 json_object_int_add(json_row, "holdTime",
1071 PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
d62a17ae 1072 json_object_string_add(json_row, "helloTimer",
1073 hello_timer);
1074 json_object_string_add(json_row, "helloStatStart",
1075 stat_uptime);
1076 json_object_int_add(json_row, "helloReceived",
1077 pim_ifp->pim_ifstat_hello_recv);
1078 json_object_int_add(json_row, "helloReceivedFailed",
1079 pim_ifp->pim_ifstat_hello_recvfail);
1080 json_object_int_add(json_row, "helloSend",
1081 pim_ifp->pim_ifstat_hello_sent);
1082 json_object_int_add(json_row, "hellosendFailed",
1083 pim_ifp->pim_ifstat_hello_sendfail);
1084 json_object_int_add(json_row, "helloGenerationId",
1085 pim_ifp->pim_generation_id);
d62a17ae 1086
1087 json_object_int_add(
1088 json_row, "effectivePropagationDelay",
1089 pim_if_effective_propagation_delay_msec(ifp));
1090 json_object_int_add(
1091 json_row, "effectiveOverrideInterval",
1092 pim_if_effective_override_interval_msec(ifp));
1093 json_object_int_add(
1094 json_row, "joinPruneOverrideInterval",
1095 pim_if_jp_override_interval_msec(ifp));
1096
1097 json_object_int_add(
1098 json_row, "propagationDelay",
1099 pim_ifp->pim_propagation_delay_msec);
1100 json_object_int_add(
1101 json_row, "propagationDelayHighest",
1102 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1103 json_object_int_add(
1104 json_row, "overrideInterval",
1105 pim_ifp->pim_override_interval_msec);
1106 json_object_int_add(
1107 json_row, "overrideIntervalHighest",
1108 pim_ifp->pim_neighbors_highest_override_interval_msec);
6eedc1a5 1109 if (pim_ifp->bsm_enable)
1110 json_object_boolean_true_add(json_row,
1111 "bsmEnabled");
1112 if (pim_ifp->ucast_bsm_accept)
1113 json_object_boolean_true_add(json_row,
1114 "ucastBsmEnabled");
d62a17ae 1115 json_object_object_add(json, ifp->name, json_row);
1116
1117 } else {
1118 vty_out(vty, "Interface : %s\n", ifp->name);
1119 vty_out(vty, "State : %s\n",
1120 if_is_up(ifp) ? "up" : "down");
1121 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
ee2bbf7c
MS
1122 vty_out(vty, "Use Source : %pI4\n",
1123 &pim_ifp->update_source);
d62a17ae 1124 }
1125 if (pim_ifp->sec_addr_list) {
ee2bbf7c
MS
1126 vty_out(vty, "Address : %pI4 (primary)\n",
1127 &ifaddr);
d62a17ae 1128 for (ALL_LIST_ELEMENTS_RO(
1129 pim_ifp->sec_addr_list, sec_node,
2dbe669b
DA
1130 sec_addr))
1131 vty_out(vty, " %pFX\n",
1132 &sec_addr->addr);
d62a17ae 1133 } else {
ee2bbf7c
MS
1134 vty_out(vty, "Address : %pI4\n",
1135 &ifaddr);
d62a17ae 1136 }
1137 vty_out(vty, "\n");
1138
1139 // PIM neighbors
1140 print_header = 1;
1141
1142 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
1143 neighnode, neigh)) {
1144
1145 if (print_header) {
1146 vty_out(vty, "PIM Neighbors\n");
1147 vty_out(vty, "-------------\n");
1148 print_header = 0;
1149 }
1150
1151 pim_inet4_dump("<src?>", neigh->source_addr,
1152 neigh_src_str,
1153 sizeof(neigh_src_str));
1154 pim_time_uptime(uptime, sizeof(uptime),
1155 now - neigh->creation);
1156 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1157 neigh->t_expire_timer);
1158 vty_out(vty,
1159 "%-15s : up for %s, holdtime expires in %s\n",
1160 neigh_src_str, uptime, expire);
1161 }
1162
1163 if (!print_header) {
1164 vty_out(vty, "\n");
1165 vty_out(vty, "\n");
1166 }
1167
1168 vty_out(vty, "Designated Router\n");
1169 vty_out(vty, "-----------------\n");
1170 vty_out(vty, "Address : %s\n", dr_str);
f116689e 1171 vty_out(vty, "Priority : %u(%d)\n",
a0bf54c7
DS
1172 pim_ifp->pim_dr_priority,
1173 pim_ifp->pim_dr_num_nondrpri_neighbors);
d62a17ae 1174 vty_out(vty, "Uptime : %s\n", dr_uptime);
1175 vty_out(vty, "Elections : %d\n",
1176 pim_ifp->pim_dr_election_count);
1177 vty_out(vty, "Changes : %d\n",
1178 pim_ifp->pim_dr_election_changes);
1179 vty_out(vty, "\n");
1180 vty_out(vty, "\n");
1181
1182 // FHR
1183 print_header = 1;
dd3364cb 1184 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
859ea2de
DS
1185 if (!up->rpf.source_nexthop.interface)
1186 continue;
5fe58e3d
DS
1187
1188 if (strcmp(ifp->name,
996c9314 1189 up->rpf.source_nexthop
521c5b9d 1190 .interface->name)
996c9314 1191 != 0)
5fe58e3d
DS
1192 continue;
1193
1194 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1195 continue;
1196
1197 if (print_header) {
1198 vty_out(vty,
1199 "FHR - First Hop Router\n");
1200 vty_out(vty,
1201 "----------------------\n");
1202 print_header = 0;
d62a17ae 1203 }
5fe58e3d 1204
5fe58e3d
DS
1205 pim_time_uptime(uptime, sizeof(uptime),
1206 now - up->state_transition);
1207 vty_out(vty,
8e8be741
DL
1208 "%pPAs : %pPAs is a source, uptime is %s\n",
1209 &up->sg.grp, &up->sg.src, uptime);
d62a17ae 1210 }
1211
1212 if (!print_header) {
1213 vty_out(vty, "\n");
1214 vty_out(vty, "\n");
1215 }
1216
1217 vty_out(vty, "Hellos\n");
1218 vty_out(vty, "------\n");
1219 vty_out(vty, "Period : %d\n",
1220 pim_ifp->pim_hello_period);
899dd339
MR
1221 vty_out(vty, "HoldTime : %d\n",
1222 PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
d62a17ae 1223 vty_out(vty, "Timer : %s\n", hello_timer);
1224 vty_out(vty, "StatStart : %s\n", stat_uptime);
1225 vty_out(vty, "Receive : %d\n",
1226 pim_ifp->pim_ifstat_hello_recv);
1227 vty_out(vty, "Receive Failed : %d\n",
1228 pim_ifp->pim_ifstat_hello_recvfail);
1229 vty_out(vty, "Send : %d\n",
1230 pim_ifp->pim_ifstat_hello_sent);
1231 vty_out(vty, "Send Failed : %d\n",
1232 pim_ifp->pim_ifstat_hello_sendfail);
1233 vty_out(vty, "Generation ID : %08x\n",
1234 pim_ifp->pim_generation_id);
1235 vty_out(vty, "\n");
1236 vty_out(vty, "\n");
1237
c532e503 1238 pim_print_ifp_flags(vty, ifp);
d62a17ae 1239
1240 vty_out(vty, "Join Prune Interval\n");
1241 vty_out(vty, "-------------------\n");
1242 vty_out(vty, "LAN Delay : %s\n",
1243 pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
1244 vty_out(vty, "Effective Propagation Delay : %d msec\n",
1245 pim_if_effective_propagation_delay_msec(ifp));
1246 vty_out(vty, "Effective Override Interval : %d msec\n",
1247 pim_if_effective_override_interval_msec(ifp));
1248 vty_out(vty, "Join Prune Override Interval : %d msec\n",
1249 pim_if_jp_override_interval_msec(ifp));
1250 vty_out(vty, "\n");
1251 vty_out(vty, "\n");
1252
1253 vty_out(vty, "LAN Prune Delay\n");
1254 vty_out(vty, "---------------\n");
1255 vty_out(vty, "Propagation Delay : %d msec\n",
1256 pim_ifp->pim_propagation_delay_msec);
1257 vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
1258 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1259 vty_out(vty, "Override Interval : %d msec\n",
1260 pim_ifp->pim_override_interval_msec);
1261 vty_out(vty, "Override Interval (Highest) : %d msec\n",
1262 pim_ifp->pim_neighbors_highest_override_interval_msec);
1263 vty_out(vty, "\n");
1264 vty_out(vty, "\n");
6eedc1a5 1265
1266 vty_out(vty, "BSM Status\n");
1267 vty_out(vty, "----------\n");
1268 vty_out(vty, "Bsm Enabled : %s\n",
1269 pim_ifp->bsm_enable ? "yes" : "no");
1270 vty_out(vty, "Unicast Bsm Enabled : %s\n",
1271 pim_ifp->ucast_bsm_accept ? "yes" : "no");
1272 vty_out(vty, "\n");
1273 vty_out(vty, "\n");
d62a17ae 1274 }
1275 }
1276
3757f964
DA
1277 if (uj)
1278 vty_json(vty, json);
1279 else if (!found_ifname)
1280 vty_out(vty, "%% No such interface\n");
12e41d03
DL
1281}
1282
21313cbf 1283static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
088f1098 1284 const char *ifname, bool uj)
21313cbf
MS
1285{
1286 struct interface *ifp;
f2058cb4 1287 struct igmp_stats igmp_stats;
42982834
DA
1288 bool found_ifname = false;
1289 json_object *json = NULL;
21313cbf 1290
f2058cb4 1291 igmp_stats_init(&igmp_stats);
21313cbf 1292
42982834
DA
1293 if (uj)
1294 json = json_object_new_object();
1295
21313cbf
MS
1296 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1297 struct pim_interface *pim_ifp;
1e02f2f9 1298 struct listnode *sock_node, *source_node, *group_node;
c5f76fad 1299 struct gm_sock *igmp;
1e02f2f9
DA
1300 struct gm_group *group;
1301 struct gm_source *src;
21313cbf
MS
1302
1303 pim_ifp = ifp->info;
1304
1305 if (!pim_ifp)
1306 continue;
1307
1308 if (ifname && strcmp(ifname, ifp->name))
1309 continue;
1310
42982834
DA
1311 found_ifname = true;
1312
f2058cb4
DA
1313 igmp_stats.joins_failed += pim_ifp->igmp_ifstat_joins_failed;
1314 igmp_stats.joins_sent += pim_ifp->igmp_ifstat_joins_sent;
1315 igmp_stats.total_groups +=
1e02f2f9
DA
1316 pim_ifp->gm_group_list
1317 ? listcount(pim_ifp->gm_group_list)
1318 : 0;
3e5d8665
DA
1319 igmp_stats.peak_groups += pim_ifp->igmp_peak_group_count;
1320
1e02f2f9
DA
1321
1322 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, group_node,
1323 group)) {
1324 for (ALL_LIST_ELEMENTS_RO(group->group_source_list,
1325 source_node, src)) {
1326 if (pim_addr_is_any(src->source_addr))
1327 continue;
1328
f2058cb4 1329 igmp_stats.total_source_groups++;
1e02f2f9
DA
1330 }
1331 }
1332
18adcff1 1333 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
21313cbf 1334 igmp)) {
f2058cb4 1335 igmp_stats_add(&igmp_stats, &igmp->igmp_stats);
21313cbf
MS
1336 }
1337 }
21313cbf 1338
42982834
DA
1339 if (!found_ifname) {
1340 if (uj)
1341 vty_json(vty, json);
1342 else
1343 vty_out(vty, "%% No such interface\n");
1344 return;
1345 }
1346
1347 if (uj) {
1348 json_object *json_row = json_object_new_object();
21313cbf 1349
42982834
DA
1350 json_object_string_add(json_row, "name",
1351 ifname ? ifname : "global");
f2058cb4
DA
1352 json_object_int_add(json_row, "queryV1", igmp_stats.query_v1);
1353 json_object_int_add(json_row, "queryV2", igmp_stats.query_v2);
1354 json_object_int_add(json_row, "queryV3", igmp_stats.query_v3);
1355 json_object_int_add(json_row, "leaveV2", igmp_stats.leave_v2);
1356 json_object_int_add(json_row, "reportV1", igmp_stats.report_v1);
1357 json_object_int_add(json_row, "reportV2", igmp_stats.report_v2);
1358 json_object_int_add(json_row, "reportV3", igmp_stats.report_v3);
21313cbf 1359 json_object_int_add(json_row, "mtraceResponse",
f2058cb4 1360 igmp_stats.mtrace_rsp);
21313cbf 1361 json_object_int_add(json_row, "mtraceRequest",
f2058cb4 1362 igmp_stats.mtrace_req);
21313cbf 1363 json_object_int_add(json_row, "unsupported",
f2058cb4 1364 igmp_stats.unsupported);
ca3e7807
DA
1365 json_object_int_add(json_row, "totalReceivedMessages",
1366 igmp_stats.total_recv_messages);
3e5d8665
DA
1367 json_object_int_add(json_row, "peakGroups",
1368 igmp_stats.peak_groups);
1e02f2f9 1369 json_object_int_add(json_row, "totalGroups",
f2058cb4 1370 igmp_stats.total_groups);
1e02f2f9 1371 json_object_int_add(json_row, "totalSourceGroups",
f2058cb4
DA
1372 igmp_stats.total_source_groups);
1373 json_object_int_add(json_row, "joinsFailed",
1374 igmp_stats.joins_failed);
1375 json_object_int_add(json_row, "joinsSent",
1376 igmp_stats.joins_sent);
278912ea
DA
1377 json_object_int_add(json_row, "generalQueriesSent",
1378 igmp_stats.general_queries_sent);
1379 json_object_int_add(json_row, "groupQueriesSent",
1380 igmp_stats.group_queries_sent);
21313cbf
MS
1381 json_object_object_add(json, ifname ? ifname : "global",
1382 json_row);
3757f964 1383 vty_json(vty, json);
21313cbf 1384 } else {
f2058cb4 1385 vty_out(vty, "IGMP statistics\n");
ca3e7807 1386 vty_out(vty, "Interface : %s\n",
21313cbf 1387 ifname ? ifname : "global");
ca3e7807 1388 vty_out(vty, "V1 query : %u\n",
278912ea 1389 igmp_stats.query_v1);
ca3e7807 1390 vty_out(vty, "V2 query : %u\n",
278912ea 1391 igmp_stats.query_v2);
ca3e7807 1392 vty_out(vty, "V3 query : %u\n",
278912ea 1393 igmp_stats.query_v3);
ca3e7807 1394 vty_out(vty, "V2 leave : %u\n",
278912ea 1395 igmp_stats.leave_v2);
ca3e7807 1396 vty_out(vty, "V1 report : %u\n",
f2058cb4 1397 igmp_stats.report_v1);
ca3e7807 1398 vty_out(vty, "V2 report : %u\n",
f2058cb4 1399 igmp_stats.report_v2);
ca3e7807 1400 vty_out(vty, "V3 report : %u\n",
f2058cb4 1401 igmp_stats.report_v3);
ca3e7807 1402 vty_out(vty, "mtrace response : %u\n",
f2058cb4 1403 igmp_stats.mtrace_rsp);
ca3e7807 1404 vty_out(vty, "mtrace request : %u\n",
f2058cb4 1405 igmp_stats.mtrace_req);
ca3e7807 1406 vty_out(vty, "unsupported : %u\n",
f2058cb4 1407 igmp_stats.unsupported);
ca3e7807
DA
1408 vty_out(vty, "total received messages : %u\n",
1409 igmp_stats.total_recv_messages);
1410 vty_out(vty, "joins failed : %u\n",
f2058cb4 1411 igmp_stats.joins_failed);
ca3e7807 1412 vty_out(vty, "joins sent : %u\n",
f2058cb4 1413 igmp_stats.joins_sent);
ca3e7807 1414 vty_out(vty, "general queries sent : %u\n",
278912ea 1415 igmp_stats.general_queries_sent);
ca3e7807 1416 vty_out(vty, "group queries sent : %u\n",
278912ea 1417 igmp_stats.group_queries_sent);
3e5d8665
DA
1418 vty_out(vty, "peak groups : %u\n",
1419 igmp_stats.peak_groups);
ca3e7807 1420 vty_out(vty, "total groups : %u\n",
f2058cb4 1421 igmp_stats.total_groups);
ca3e7807 1422 vty_out(vty, "total source groups : %u\n",
f2058cb4 1423 igmp_stats.total_source_groups);
21313cbf
MS
1424 }
1425}
1426
64c86530 1427static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
17823cdd 1428 bool mlag, bool uj)
12e41d03 1429{
d62a17ae 1430 struct interface *ifp;
d62a17ae 1431 struct pim_interface *pim_ifp;
1432 struct pim_upstream *up;
1433 int fhr = 0;
1434 int pim_nbrs = 0;
1435 int pim_ifchannels = 0;
1436 json_object *json = NULL;
1437 json_object *json_row = NULL;
1438 json_object *json_tmp;
1439
1440 json = json_object_new_object();
1441
451fda4f 1442 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1443 pim_ifp = ifp->info;
1444
1445 if (!pim_ifp)
1446 continue;
1447
17823cdd
DS
1448 if (mlag == true && pim_ifp->activeactive == false)
1449 continue;
1450
d62a17ae 1451 pim_nbrs = pim_ifp->pim_neighbor_list->count;
ad7b74c4 1452 pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
d62a17ae 1453 fhr = 0;
1454
dd3364cb 1455 frr_each (rb_pim_upstream, &pim->upstream_head, up)
d62a17ae 1456 if (ifp == up->rpf.source_nexthop.interface)
1457 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
1458 fhr++;
1459
1460 json_row = json_object_new_object();
1461 json_object_pim_ifp_add(json_row, ifp);
1462 json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
1463 json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
15507b63 1464 json_object_int_add(json_row, "firstHopRouterCount", fhr);
b0d5264e
DA
1465 json_object_string_addf(json_row, "pimDesignatedRouter", "%pI4",
1466 &pim_ifp->pim_dr_addr);
d62a17ae 1467
1468 if (pim_ifp->pim_dr_addr.s_addr
1469 == pim_ifp->primary_address.s_addr)
1470 json_object_boolean_true_add(
1471 json_row, "pimDesignatedRouterLocal");
1472
1473 json_object_object_add(json, ifp->name, json_row);
1474 }
1475
1476 if (uj) {
9d303b37 1477 vty_out(vty, "%s\n", json_object_to_json_string_ext(
521c5b9d 1478 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1479 } else {
1480 vty_out(vty,
ff415346 1481 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
d62a17ae 1482
1483 json_object_object_foreach(json, key, val)
1484 {
ff415346 1485 vty_out(vty, "%-16s ", key);
d62a17ae 1486
1487 json_object_object_get_ex(val, "state", &json_tmp);
1488 vty_out(vty, "%5s ", json_object_get_string(json_tmp));
1489
1490 json_object_object_get_ex(val, "address", &json_tmp);
1491 vty_out(vty, "%15s ",
1492 json_object_get_string(json_tmp));
1493
1494 json_object_object_get_ex(val, "pimNeighbors",
1495 &json_tmp);
1496 vty_out(vty, "%8d ", json_object_get_int(json_tmp));
1497
1498 if (json_object_object_get_ex(
1499 val, "pimDesignatedRouterLocal",
1500 &json_tmp)) {
1501 vty_out(vty, "%15s ", "local");
1502 } else {
1503 json_object_object_get_ex(
1504 val, "pimDesignatedRouter", &json_tmp);
1505 vty_out(vty, "%15s ",
1506 json_object_get_string(json_tmp));
1507 }
1508
1509 json_object_object_get_ex(val, "firstHopRouter",
1510 &json_tmp);
1511 vty_out(vty, "%3d ", json_object_get_int(json_tmp));
1512
1513 json_object_object_get_ex(val, "pimIfChannels",
1514 &json_tmp);
1515 vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
1516 }
1517 }
1518
1519 json_object_free(json);
1520}
1521
64c86530 1522static void pim_show_interface_traffic(struct pim_instance *pim,
088f1098 1523 struct vty *vty, bool uj)
d62a17ae 1524{
1525 struct interface *ifp = NULL;
1526 struct pim_interface *pim_ifp = NULL;
d62a17ae 1527 json_object *json = NULL;
1528 json_object *json_row = NULL;
1529
1530 if (uj)
1531 json = json_object_new_object();
1532 else {
1533 vty_out(vty, "\n");
4616b2e9 1534 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
ff415346
DS
1535 "Interface", " HELLO", " JOIN",
1536 " PRUNE", " REGISTER", "REGISTER-STOP",
4616b2e9 1537 " ASSERT", " BSM");
1538 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
ff415346 1539 " Rx/Tx", " Rx/Tx", " Rx/Tx",
4616b2e9 1540 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1541 " Rx/Tx");
d62a17ae 1542 vty_out(vty,
1543 "---------------------------------------------------------------------------------------------------------------\n");
1544 }
1545
451fda4f 1546 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1547 pim_ifp = ifp->info;
1548
1549 if (!pim_ifp)
1550 continue;
1551
1552 if (pim_ifp->pim_sock_fd < 0)
1553 continue;
1554 if (uj) {
1555 json_row = json_object_new_object();
1556 json_object_pim_ifp_add(json_row, ifp);
1557 json_object_int_add(json_row, "helloRx",
1558 pim_ifp->pim_ifstat_hello_recv);
1559 json_object_int_add(json_row, "helloTx",
1560 pim_ifp->pim_ifstat_hello_sent);
1561 json_object_int_add(json_row, "joinRx",
1562 pim_ifp->pim_ifstat_join_recv);
1563 json_object_int_add(json_row, "joinTx",
1564 pim_ifp->pim_ifstat_join_send);
a7a5472e
SP
1565 json_object_int_add(json_row, "pruneTx",
1566 pim_ifp->pim_ifstat_prune_send);
1567 json_object_int_add(json_row, "pruneRx",
1568 pim_ifp->pim_ifstat_prune_recv);
d62a17ae 1569 json_object_int_add(json_row, "registerRx",
1570 pim_ifp->pim_ifstat_reg_recv);
1571 json_object_int_add(json_row, "registerTx",
1572 pim_ifp->pim_ifstat_reg_recv);
1573 json_object_int_add(json_row, "registerStopRx",
1574 pim_ifp->pim_ifstat_reg_stop_recv);
1575 json_object_int_add(json_row, "registerStopTx",
1576 pim_ifp->pim_ifstat_reg_stop_send);
1577 json_object_int_add(json_row, "assertRx",
1578 pim_ifp->pim_ifstat_assert_recv);
1579 json_object_int_add(json_row, "assertTx",
521c5b9d 1580 pim_ifp->pim_ifstat_assert_send);
4616b2e9 1581 json_object_int_add(json_row, "bsmRx",
521c5b9d 1582 pim_ifp->pim_ifstat_bsm_rx);
4616b2e9 1583 json_object_int_add(json_row, "bsmTx",
521c5b9d 1584 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1585 json_object_object_add(json, ifp->name, json_row);
1586 } else {
1587 vty_out(vty,
9a8a7b0e 1588 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64 "/%-7" PRIu64 "\n",
d62a17ae 1589 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1590 pim_ifp->pim_ifstat_hello_sent,
1591 pim_ifp->pim_ifstat_join_recv,
1592 pim_ifp->pim_ifstat_join_send,
1593 pim_ifp->pim_ifstat_prune_recv,
1594 pim_ifp->pim_ifstat_prune_send,
1595 pim_ifp->pim_ifstat_reg_recv,
1596 pim_ifp->pim_ifstat_reg_send,
1597 pim_ifp->pim_ifstat_reg_stop_recv,
1598 pim_ifp->pim_ifstat_reg_stop_send,
1599 pim_ifp->pim_ifstat_assert_recv,
4616b2e9 1600 pim_ifp->pim_ifstat_assert_send,
1601 pim_ifp->pim_ifstat_bsm_rx,
1602 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1603 }
1604 }
3757f964
DA
1605 if (uj)
1606 vty_json(vty, json);
d62a17ae 1607}
1608
64c86530
DS
1609static void pim_show_interface_traffic_single(struct pim_instance *pim,
1610 struct vty *vty,
088f1098 1611 const char *ifname, bool uj)
d62a17ae 1612{
1613 struct interface *ifp = NULL;
1614 struct pim_interface *pim_ifp = NULL;
d62a17ae 1615 json_object *json = NULL;
1616 json_object *json_row = NULL;
1617 uint8_t found_ifname = 0;
1618
1619 if (uj)
1620 json = json_object_new_object();
1621 else {
1622 vty_out(vty, "\n");
4616b2e9 1623 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
d62a17ae 1624 "Interface", " HELLO", " JOIN", " PRUNE",
4616b2e9 1625 " REGISTER", " REGISTER-STOP", " ASSERT",
1626 " BSM");
1627 vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
d62a17ae 1628 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
4616b2e9 1629 " Rx/Tx", " Rx/Tx", " Rx/Tx");
d62a17ae 1630 vty_out(vty,
4616b2e9 1631 "-------------------------------------------------------------------------------------------------------------------------------\n");
d62a17ae 1632 }
1633
451fda4f 1634 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1635 if (strcmp(ifname, ifp->name))
1636 continue;
1637
1638 pim_ifp = ifp->info;
1639
1640 if (!pim_ifp)
1641 continue;
1642
1643 if (pim_ifp->pim_sock_fd < 0)
1644 continue;
1645
1646 found_ifname = 1;
1647 if (uj) {
1648 json_row = json_object_new_object();
1649 json_object_pim_ifp_add(json_row, ifp);
1650 json_object_int_add(json_row, "helloRx",
1651 pim_ifp->pim_ifstat_hello_recv);
1652 json_object_int_add(json_row, "helloTx",
1653 pim_ifp->pim_ifstat_hello_sent);
1654 json_object_int_add(json_row, "joinRx",
1655 pim_ifp->pim_ifstat_join_recv);
1656 json_object_int_add(json_row, "joinTx",
1657 pim_ifp->pim_ifstat_join_send);
1658 json_object_int_add(json_row, "registerRx",
1659 pim_ifp->pim_ifstat_reg_recv);
1660 json_object_int_add(json_row, "registerTx",
1661 pim_ifp->pim_ifstat_reg_recv);
1662 json_object_int_add(json_row, "registerStopRx",
1663 pim_ifp->pim_ifstat_reg_stop_recv);
1664 json_object_int_add(json_row, "registerStopTx",
1665 pim_ifp->pim_ifstat_reg_stop_send);
1666 json_object_int_add(json_row, "assertRx",
1667 pim_ifp->pim_ifstat_assert_recv);
1668 json_object_int_add(json_row, "assertTx",
1669 pim_ifp->pim_ifstat_assert_send);
4616b2e9 1670 json_object_int_add(json_row, "bsmRx",
1671 pim_ifp->pim_ifstat_bsm_rx);
1672 json_object_int_add(json_row, "bsmTx",
1673 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1674
1675 json_object_object_add(json, ifp->name, json_row);
1676 } else {
1677 vty_out(vty,
9a8a7b0e 1678 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64 "/%-7" PRIu64 "\n",
d62a17ae 1679 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1680 pim_ifp->pim_ifstat_hello_sent,
1681 pim_ifp->pim_ifstat_join_recv,
1682 pim_ifp->pim_ifstat_join_send,
1683 pim_ifp->pim_ifstat_prune_recv,
1684 pim_ifp->pim_ifstat_prune_send,
1685 pim_ifp->pim_ifstat_reg_recv,
1686 pim_ifp->pim_ifstat_reg_send,
1687 pim_ifp->pim_ifstat_reg_stop_recv,
1688 pim_ifp->pim_ifstat_reg_stop_send,
1689 pim_ifp->pim_ifstat_assert_recv,
4616b2e9 1690 pim_ifp->pim_ifstat_assert_send,
1691 pim_ifp->pim_ifstat_bsm_rx,
1692 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1693 }
1694 }
3757f964
DA
1695 if (uj)
1696 vty_json(vty, json);
1697 else if (!found_ifname)
1698 vty_out(vty, "%% No such interface\n");
39438188
CS
1699}
1700
996c9314
LB
1701static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
1702 struct pim_ifchannel *ch, json_object *json,
088f1098 1703 time_t now, bool uj)
1a8a3da8 1704{
1a8a3da8
DS
1705 json_object *json_iface = NULL;
1706 json_object *json_row = NULL;
1707 json_object *json_grp = NULL;
1708 struct in_addr ifaddr;
1709 char uptime[10];
1710 char expire[10];
1711 char prune[10];
ee2bbf7c 1712 char buf[PREFIX_STRLEN];
1a8a3da8
DS
1713
1714 ifaddr = pim_ifp->primary_address;
1715
996c9314 1716 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
1a8a3da8
DS
1717 pim_time_timer_to_mmss(expire, sizeof(expire),
1718 ch->t_ifjoin_expiry_timer);
1719 pim_time_timer_to_mmss(prune, sizeof(prune),
1720 ch->t_ifjoin_prune_pending_timer);
1721
1722 if (uj) {
8e8be741
DL
1723 char ch_grp_str[PIM_ADDRSTRLEN];
1724 char ch_src_str[PIM_ADDRSTRLEN];
1725
1726 snprintfrr(ch_grp_str, sizeof(ch_grp_str), "%pPAs",
1727 &ch->sg.grp);
1728 snprintfrr(ch_src_str, sizeof(ch_src_str), "%pPAs",
1729 &ch->sg.src);
1730
1a8a3da8
DS
1731 json_object_object_get_ex(json, ch->interface->name,
1732 &json_iface);
1733
1734 if (!json_iface) {
1735 json_iface = json_object_new_object();
996c9314
LB
1736 json_object_pim_ifp_add(json_iface, ch->interface);
1737 json_object_object_add(json, ch->interface->name,
1738 json_iface);
1a8a3da8
DS
1739 }
1740
1741 json_row = json_object_new_object();
1742 json_object_string_add(json_row, "source", ch_src_str);
1743 json_object_string_add(json_row, "group", ch_grp_str);
1744 json_object_string_add(json_row, "upTime", uptime);
1745 json_object_string_add(json_row, "expire", expire);
1746 json_object_string_add(json_row, "prune", prune);
1747 json_object_string_add(
1748 json_row, "channelJoinName",
996c9314 1749 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
77a2f8e5
DA
1750 if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) {
1751#if CONFDATE > 20230131
1752CPP_NOTICE("Remove JSON object commands with keys starting with capital")
1753#endif
1a8a3da8 1754 json_object_int_add(json_row, "SGRpt", 1);
77a2f8e5
DA
1755 json_object_int_add(json_row, "sgRpt", 1);
1756 }
9443810e
SP
1757 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch->flags))
1758 json_object_int_add(json_row, "protocolPim", 1);
1759 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch->flags))
1760 json_object_int_add(json_row, "protocolIgmp", 1);
996c9314 1761 json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
1a8a3da8
DS
1762 if (!json_grp) {
1763 json_grp = json_object_new_object();
996c9314 1764 json_object_object_add(json_grp, ch_src_str, json_row);
1a8a3da8
DS
1765 json_object_object_add(json_iface, ch_grp_str,
1766 json_grp);
1767 } else
996c9314 1768 json_object_object_add(json_grp, ch_src_str, json_row);
1a8a3da8 1769 } else {
8e8be741 1770 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-10s %8s %-6s %5s\n",
ee2bbf7c
MS
1771 ch->interface->name,
1772 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
8e8be741 1773 &ch->sg.src, &ch->sg.grp,
996c9314 1774 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
1a8a3da8
DS
1775 uptime, expire, prune);
1776 }
1777}
1778
6de45bcc 1779static void pim_show_join(struct pim_instance *pim, struct vty *vty,
6fff2cc6 1780 pim_sgaddr *sg, bool uj)
12e41d03 1781{
d62a17ae 1782 struct pim_interface *pim_ifp;
d62a17ae 1783 struct pim_ifchannel *ch;
1a8a3da8 1784 struct interface *ifp;
d62a17ae 1785 time_t now;
1786 json_object *json = NULL;
d62a17ae 1787
1788 now = pim_time_monotonic_sec();
1789
1790 if (uj)
1791 json = json_object_new_object();
1792 else
1793 vty_out(vty,
ff415346 1794 "Interface Address Source Group State Uptime Expire Prune\n");
d62a17ae 1795
451fda4f 1796 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 1797 pim_ifp = ifp->info;
d62a17ae 1798 if (!pim_ifp)
1799 continue;
1800
a2addae8 1801 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
62f59b58 1802 if (!pim_sgaddr_match(ch->sg, *sg))
975a328e 1803 continue;
a2addae8 1804 pim_show_join_helper(vty, pim_ifp, ch, json, now, uj);
1a8a3da8
DS
1805 } /* scan interface channels */
1806 }
d62a17ae 1807
3757f964
DA
1808 if (uj)
1809 vty_json(vty, json);
d62a17ae 1810}
1811
64c86530 1812static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
088f1098 1813 const char *neighbor, bool uj)
d62a17ae 1814{
d62a17ae 1815 struct listnode *neighnode;
1816 struct interface *ifp;
1817 struct pim_interface *pim_ifp;
1818 struct pim_neighbor *neigh;
1819 time_t now;
1820 int found_neighbor = 0;
1821 int option_address_list;
1822 int option_dr_priority;
1823 int option_generation_id;
1824 int option_holdtime;
1825 int option_lan_prune_delay;
1826 int option_t_bit;
1827 char uptime[10];
1828 char expire[10];
1829 char neigh_src_str[INET_ADDRSTRLEN];
1830
1831 json_object *json = NULL;
1832 json_object *json_ifp = NULL;
1833 json_object *json_row = NULL;
1834
1835 now = pim_time_monotonic_sec();
1836
1837 if (uj)
1838 json = json_object_new_object();
1839
451fda4f 1840 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1841 pim_ifp = ifp->info;
1842
1843 if (!pim_ifp)
1844 continue;
1845
1846 if (pim_ifp->pim_sock_fd < 0)
1847 continue;
1848
1849 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
1850 neigh)) {
1851 pim_inet4_dump("<src?>", neigh->source_addr,
1852 neigh_src_str, sizeof(neigh_src_str));
1853
1854 /*
1855 * The user can specify either the interface name or the
1856 * PIM neighbor IP.
1857 * If this pim_ifp matches neither then skip.
1858 */
1859 if (strcmp(neighbor, "detail")
1860 && strcmp(neighbor, ifp->name)
1861 && strcmp(neighbor, neigh_src_str))
1862 continue;
1863
1864 found_neighbor = 1;
1865 pim_time_uptime(uptime, sizeof(uptime),
1866 now - neigh->creation);
1867 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1868 neigh->t_expire_timer);
1869
1870 option_address_list = 0;
1871 option_dr_priority = 0;
1872 option_generation_id = 0;
1873 option_holdtime = 0;
1874 option_lan_prune_delay = 0;
1875 option_t_bit = 0;
1876
1877 if (PIM_OPTION_IS_SET(neigh->hello_options,
1878 PIM_OPTION_MASK_ADDRESS_LIST))
1879 option_address_list = 1;
1880
1881 if (PIM_OPTION_IS_SET(neigh->hello_options,
1882 PIM_OPTION_MASK_DR_PRIORITY))
1883 option_dr_priority = 1;
1884
1885 if (PIM_OPTION_IS_SET(neigh->hello_options,
1886 PIM_OPTION_MASK_GENERATION_ID))
1887 option_generation_id = 1;
1888
1889 if (PIM_OPTION_IS_SET(neigh->hello_options,
1890 PIM_OPTION_MASK_HOLDTIME))
1891 option_holdtime = 1;
1892
1893 if (PIM_OPTION_IS_SET(neigh->hello_options,
1894 PIM_OPTION_MASK_LAN_PRUNE_DELAY))
1895 option_lan_prune_delay = 1;
1896
1897 if (PIM_OPTION_IS_SET(
1898 neigh->hello_options,
1899 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
1900 option_t_bit = 1;
1901
1902 if (uj) {
1903
1904 /* Does this ifp live in json? If not create
1905 * it. */
1906 json_object_object_get_ex(json, ifp->name,
1907 &json_ifp);
1908
1909 if (!json_ifp) {
1910 json_ifp = json_object_new_object();
1911 json_object_pim_ifp_add(json_ifp, ifp);
1912 json_object_object_add(json, ifp->name,
1913 json_ifp);
1914 }
1915
1916 json_row = json_object_new_object();
1917 json_object_string_add(json_row, "interface",
1918 ifp->name);
1919 json_object_string_add(json_row, "address",
1920 neigh_src_str);
1921 json_object_string_add(json_row, "upTime",
1922 uptime);
1923 json_object_string_add(json_row, "holdtime",
1924 expire);
1925 json_object_int_add(json_row, "drPriority",
1926 neigh->dr_priority);
1927 json_object_int_add(json_row, "generationId",
1928 neigh->generation_id);
1929
1930 if (option_address_list)
1931 json_object_boolean_true_add(
1932 json_row,
1933 "helloOptionAddressList");
1934
1935 if (option_dr_priority)
1936 json_object_boolean_true_add(
1937 json_row,
1938 "helloOptionDrPriority");
1939
1940 if (option_generation_id)
1941 json_object_boolean_true_add(
1942 json_row,
1943 "helloOptionGenerationId");
1944
1945 if (option_holdtime)
1946 json_object_boolean_true_add(
1947 json_row,
1948 "helloOptionHoldtime");
1949
1950 if (option_lan_prune_delay)
1951 json_object_boolean_true_add(
1952 json_row,
1953 "helloOptionLanPruneDelay");
1954
1955 if (option_t_bit)
1956 json_object_boolean_true_add(
1957 json_row, "helloOptionTBit");
1958
1959 json_object_object_add(json_ifp, neigh_src_str,
1960 json_row);
1961
1962 } else {
1963 vty_out(vty, "Interface : %s\n", ifp->name);
1964 vty_out(vty, "Neighbor : %s\n", neigh_src_str);
1965 vty_out(vty,
1966 " Uptime : %s\n",
1967 uptime);
1968 vty_out(vty,
1969 " Holdtime : %s\n",
1970 expire);
1971 vty_out(vty,
1972 " DR Priority : %d\n",
1973 neigh->dr_priority);
1974 vty_out(vty,
1975 " Generation ID : %08x\n",
1976 neigh->generation_id);
1977 vty_out(vty,
1978 " Override Interval (msec) : %d\n",
1979 neigh->override_interval_msec);
1980 vty_out(vty,
1981 " Propagation Delay (msec) : %d\n",
1982 neigh->propagation_delay_msec);
1983 vty_out(vty,
1984 " Hello Option - Address List : %s\n",
1985 option_address_list ? "yes" : "no");
1986 vty_out(vty,
1987 " Hello Option - DR Priority : %s\n",
1988 option_dr_priority ? "yes" : "no");
1989 vty_out(vty,
1990 " Hello Option - Generation ID : %s\n",
1991 option_generation_id ? "yes" : "no");
1992 vty_out(vty,
1993 " Hello Option - Holdtime : %s\n",
1994 option_holdtime ? "yes" : "no");
1995 vty_out(vty,
1996 " Hello Option - LAN Prune Delay : %s\n",
1997 option_lan_prune_delay ? "yes" : "no");
1998 vty_out(vty,
1999 " Hello Option - T-bit : %s\n",
2000 option_t_bit ? "yes" : "no");
1f3e6bf5
RZ
2001 bfd_sess_show(vty, json_ifp,
2002 neigh->bfd_session);
d62a17ae 2003 vty_out(vty, "\n");
2004 }
2005 }
2006 }
2007
3757f964
DA
2008 if (uj)
2009 vty_json(vty, json);
2010 else if (!found_neighbor)
2011 vty_out(vty, "%% No such interface or neighbor\n");
d62a17ae 2012}
2013
64c86530 2014static void pim_show_state(struct pim_instance *pim, struct vty *vty,
088f1098 2015 const char *src_or_group, const char *group, bool uj)
d62a17ae 2016{
2017 struct channel_oil *c_oil;
d62a17ae 2018 json_object *json = NULL;
2019 json_object *json_group = NULL;
2020 json_object *json_ifp_in = NULL;
2021 json_object *json_ifp_out = NULL;
2022 json_object *json_source = NULL;
2023 time_t now;
2024 int first_oif;
2025 now = pim_time_monotonic_sec();
2026
2027 if (uj) {
2028 json = json_object_new_object();
2029 } else {
2030 vty_out(vty,
5923b739 2031 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
d62a17ae 2032 vty_out(vty,
9929a2a9 2033 "\nActive Source Group RPT IIF OIL\n");
d62a17ae 2034 }
2035
7315ecda 2036 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
d62a17ae 2037 char grp_str[INET_ADDRSTRLEN];
2038 char src_str[INET_ADDRSTRLEN];
2039 char in_ifname[INTERFACE_NAMSIZ + 1];
2040 char out_ifname[INTERFACE_NAMSIZ + 1];
2041 int oif_vif_index;
2042 struct interface *ifp_in;
9929a2a9 2043 bool isRpt;
d62a17ae 2044 first_oif = 1;
2045
9929a2a9 2046 if ((c_oil->up &&
521c5b9d
MS
2047 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil->up->flags)) ||
2048 c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
9929a2a9
AK
2049 isRpt = true;
2050 else
2051 isRpt = false;
2052
d62a17ae 2053 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
2054 sizeof(grp_str));
2055 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
2056 sizeof(src_str));
7cfc7bcf 2057 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 2058
2059 if (ifp_in)
c35b7e6b 2060 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
d62a17ae 2061 else
c35b7e6b 2062 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 2063
2064 if (src_or_group) {
2065 if (strcmp(src_or_group, src_str)
2066 && strcmp(src_or_group, grp_str))
2067 continue;
2068
2069 if (group && strcmp(group, grp_str))
2070 continue;
2071 }
2072
2073 if (uj) {
2074
2075 /* Find the group, create it if it doesn't exist */
2076 json_object_object_get_ex(json, grp_str, &json_group);
2077
2078 if (!json_group) {
2079 json_group = json_object_new_object();
2080 json_object_object_add(json, grp_str,
2081 json_group);
2082 }
2083
2084 /* Find the source nested under the group, create it if
2085 * it doesn't exist */
2086 json_object_object_get_ex(json_group, src_str,
2087 &json_source);
2088
2089 if (!json_source) {
2090 json_source = json_object_new_object();
2091 json_object_object_add(json_group, src_str,
2092 json_source);
2093 }
2094
2095 /* Find the inbound interface nested under the source,
2096 * create it if it doesn't exist */
2097 json_object_object_get_ex(json_source, in_ifname,
2098 &json_ifp_in);
2099
2100 if (!json_ifp_in) {
2101 json_ifp_in = json_object_new_object();
2102 json_object_object_add(json_source, in_ifname,
2103 json_ifp_in);
2104 json_object_int_add(json_source, "Installed",
2105 c_oil->installed);
77a2f8e5
DA
2106 json_object_int_add(json_source, "installed",
2107 c_oil->installed);
9929a2a9
AK
2108 if (isRpt)
2109 json_object_boolean_true_add(
521c5b9d 2110 json_source, "isRpt");
9929a2a9
AK
2111 else
2112 json_object_boolean_false_add(
521c5b9d 2113 json_source, "isRpt");
d62a17ae 2114 json_object_int_add(json_source, "RefCount",
2115 c_oil->oil_ref_count);
77a2f8e5
DA
2116 json_object_int_add(json_source, "refCount",
2117 c_oil->oil_ref_count);
d62a17ae 2118 json_object_int_add(json_source, "OilListSize",
2119 c_oil->oil_size);
77a2f8e5
DA
2120 json_object_int_add(json_source, "oilListSize",
2121 c_oil->oil_size);
d62a17ae 2122 json_object_int_add(
2123 json_source, "OilRescan",
2124 c_oil->oil_inherited_rescan);
77a2f8e5
DA
2125 json_object_int_add(
2126 json_source, "oilRescan",
2127 c_oil->oil_inherited_rescan);
d62a17ae 2128 json_object_int_add(json_source, "LastUsed",
2129 c_oil->cc.lastused);
77a2f8e5
DA
2130 json_object_int_add(json_source, "lastUsed",
2131 c_oil->cc.lastused);
d62a17ae 2132 json_object_int_add(json_source, "PacketCount",
2133 c_oil->cc.pktcnt);
77a2f8e5
DA
2134 json_object_int_add(json_source, "packetCount",
2135 c_oil->cc.pktcnt);
d62a17ae 2136 json_object_int_add(json_source, "ByteCount",
2137 c_oil->cc.bytecnt);
77a2f8e5
DA
2138 json_object_int_add(json_source, "byteCount",
2139 c_oil->cc.bytecnt);
d62a17ae 2140 json_object_int_add(json_source,
2141 "WrongInterface",
2142 c_oil->cc.wrong_if);
77a2f8e5
DA
2143 json_object_int_add(json_source,
2144 "wrongInterface",
2145 c_oil->cc.wrong_if);
d62a17ae 2146 }
2147 } else {
9929a2a9 2148 vty_out(vty, "%-6d %-15s %-15s %-3s %-16s ",
521c5b9d
MS
2149 c_oil->installed, src_str, grp_str,
2150 isRpt ? "y" : "n", in_ifname);
d62a17ae 2151 }
2152
2153 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
2154 ++oif_vif_index) {
2155 struct interface *ifp_out;
2156 char oif_uptime[10];
2157 int ttl;
2158
2159 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2160 if (ttl < 1)
2161 continue;
2162
7cfc7bcf 2163 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 2164 pim_time_uptime(
2165 oif_uptime, sizeof(oif_uptime),
2166 now - c_oil->oif_creation[oif_vif_index]);
2167
2168 if (ifp_out)
c35b7e6b 2169 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
d62a17ae 2170 else
c35b7e6b 2171 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 2172
2173 if (uj) {
2174 json_ifp_out = json_object_new_object();
2175 json_object_string_add(json_ifp_out, "source",
2176 src_str);
2177 json_object_string_add(json_ifp_out, "group",
2178 grp_str);
2179 json_object_string_add(json_ifp_out,
2180 "inboundInterface",
2181 in_ifname);
2182 json_object_string_add(json_ifp_out,
2183 "outboundInterface",
2184 out_ifname);
2185 json_object_int_add(json_ifp_out, "installed",
2186 c_oil->installed);
2187
2188 json_object_object_add(json_ifp_in, out_ifname,
2189 json_ifp_out);
2190 } else {
2191 if (first_oif) {
2192 first_oif = 0;
5923b739
AK
2193 vty_out(vty, "%s(%c%c%c%c%c)",
2194 out_ifname,
d62a17ae 2195 (c_oil->oif_flags[oif_vif_index]
2196 & PIM_OIF_FLAG_PROTO_IGMP)
521c5b9d
MS
2197 ? 'I'
2198 : ' ',
d62a17ae 2199 (c_oil->oif_flags[oif_vif_index]
2200 & PIM_OIF_FLAG_PROTO_PIM)
521c5b9d
MS
2201 ? 'J'
2202 : ' ',
ee31c9fd
AK
2203 (c_oil->oif_flags[oif_vif_index]
2204 & PIM_OIF_FLAG_PROTO_VXLAN)
521c5b9d
MS
2205 ? 'V'
2206 : ' ',
d62a17ae 2207 (c_oil->oif_flags[oif_vif_index]
2208 & PIM_OIF_FLAG_PROTO_STAR)
521c5b9d
MS
2209 ? '*'
2210 : ' ',
5923b739
AK
2211 (c_oil->oif_flags[oif_vif_index]
2212 & PIM_OIF_FLAG_MUTE)
521c5b9d
MS
2213 ? 'M'
2214 : ' ');
d62a17ae 2215 } else
5923b739 2216 vty_out(vty, ", %s(%c%c%c%c%c)",
d62a17ae 2217 out_ifname,
2218 (c_oil->oif_flags[oif_vif_index]
2219 & PIM_OIF_FLAG_PROTO_IGMP)
521c5b9d
MS
2220 ? 'I'
2221 : ' ',
d62a17ae 2222 (c_oil->oif_flags[oif_vif_index]
2223 & PIM_OIF_FLAG_PROTO_PIM)
521c5b9d
MS
2224 ? 'J'
2225 : ' ',
ee31c9fd
AK
2226 (c_oil->oif_flags[oif_vif_index]
2227 & PIM_OIF_FLAG_PROTO_VXLAN)
521c5b9d
MS
2228 ? 'V'
2229 : ' ',
d62a17ae 2230 (c_oil->oif_flags[oif_vif_index]
2231 & PIM_OIF_FLAG_PROTO_STAR)
521c5b9d
MS
2232 ? '*'
2233 : ' ',
5923b739
AK
2234 (c_oil->oif_flags[oif_vif_index]
2235 & PIM_OIF_FLAG_MUTE)
521c5b9d
MS
2236 ? 'M'
2237 : ' ');
d62a17ae 2238 }
2239 }
2240
2241 if (!uj)
2242 vty_out(vty, "\n");
2243 }
2244
2245
3757f964
DA
2246 if (uj)
2247 vty_json(vty, json);
2248 else
d62a17ae 2249 vty_out(vty, "\n");
31a21c9c
DW
2250}
2251
64c86530 2252static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
088f1098 2253 bool uj)
12e41d03 2254{
d62a17ae 2255 struct listnode *neighnode;
2256 struct interface *ifp;
2257 struct pim_interface *pim_ifp;
2258 struct pim_neighbor *neigh;
2259 time_t now;
2260 char uptime[10];
2261 char expire[10];
2262 char neigh_src_str[INET_ADDRSTRLEN];
2263 json_object *json = NULL;
2264 json_object *json_ifp_rows = NULL;
2265 json_object *json_row = NULL;
2266
2267 now = pim_time_monotonic_sec();
2268
2269 if (uj) {
2270 json = json_object_new_object();
2271 } else {
2272 vty_out(vty,
ff415346 2273 "Interface Neighbor Uptime Holdtime DR Pri\n");
d62a17ae 2274 }
2275
451fda4f 2276 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2277 pim_ifp = ifp->info;
2278
2279 if (!pim_ifp)
2280 continue;
2281
2282 if (pim_ifp->pim_sock_fd < 0)
2283 continue;
2284
2285 if (uj)
2286 json_ifp_rows = json_object_new_object();
2287
2288 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2289 neigh)) {
2290 pim_inet4_dump("<src?>", neigh->source_addr,
2291 neigh_src_str, sizeof(neigh_src_str));
2292 pim_time_uptime(uptime, sizeof(uptime),
2293 now - neigh->creation);
2294 pim_time_timer_to_hhmmss(expire, sizeof(expire),
2295 neigh->t_expire_timer);
2296
2297 if (uj) {
2298 json_row = json_object_new_object();
2299 json_object_string_add(json_row, "interface",
2300 ifp->name);
2301 json_object_string_add(json_row, "neighbor",
2302 neigh_src_str);
2303 json_object_string_add(json_row, "upTime",
2304 uptime);
2305 json_object_string_add(json_row, "holdTime",
2306 expire);
2307 json_object_int_add(json_row, "holdTimeMax",
2308 neigh->holdtime);
2309 json_object_int_add(json_row, "drPriority",
2310 neigh->dr_priority);
2311 json_object_object_add(json_ifp_rows,
2312 neigh_src_str, json_row);
2313
2314 } else {
ff415346 2315 vty_out(vty, "%-16s %15s %8s %8s %6d\n",
d62a17ae 2316 ifp->name, neigh_src_str, uptime,
2317 expire, neigh->dr_priority);
2318 }
2319 }
2320
2321 if (uj) {
2322 json_object_object_add(json, ifp->name, json_ifp_rows);
2323 json_ifp_rows = NULL;
2324 }
2325 }
2326
3757f964
DA
2327 if (uj)
2328 vty_json(vty, json);
12e41d03
DL
2329}
2330
64c86530
DS
2331static void pim_show_neighbors_secondary(struct pim_instance *pim,
2332 struct vty *vty)
12e41d03 2333{
d62a17ae 2334 struct interface *ifp;
12e41d03 2335
d62a17ae 2336 vty_out(vty,
ff415346 2337 "Interface Address Neighbor Secondary \n");
12e41d03 2338
451fda4f 2339 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2340 struct pim_interface *pim_ifp;
2341 struct in_addr ifaddr;
2342 struct listnode *neighnode;
2343 struct pim_neighbor *neigh;
ee2bbf7c 2344 char buf[PREFIX_STRLEN];
12e41d03 2345
d62a17ae 2346 pim_ifp = ifp->info;
12e41d03 2347
d62a17ae 2348 if (!pim_ifp)
2349 continue;
12e41d03 2350
d62a17ae 2351 if (pim_ifp->pim_sock_fd < 0)
2352 continue;
12e41d03 2353
d62a17ae 2354 ifaddr = pim_ifp->primary_address;
12e41d03 2355
d62a17ae 2356 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2357 neigh)) {
2358 char neigh_src_str[INET_ADDRSTRLEN];
2359 struct listnode *prefix_node;
2360 struct prefix *p;
12e41d03 2361
d62a17ae 2362 if (!neigh->prefix_list)
2363 continue;
12e41d03 2364
d62a17ae 2365 pim_inet4_dump("<src?>", neigh->source_addr,
2366 neigh_src_str, sizeof(neigh_src_str));
12e41d03 2367
d62a17ae 2368 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
2dbe669b
DA
2369 prefix_node, p))
2370 vty_out(vty, "%-16s %-15s %-15s %-15pFX\n",
ee2bbf7c
MS
2371 ifp->name,
2372 inet_ntop(AF_INET, &ifaddr,
2373 buf, sizeof(buf)),
2dbe669b 2374 neigh_src_str, p);
d62a17ae 2375 }
2376 }
12e41d03
DL
2377}
2378
d62a17ae 2379static void json_object_pim_upstream_add(json_object *json,
2380 struct pim_upstream *up)
9bf3c633 2381{
d62a17ae 2382 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
2383 json_object_boolean_true_add(json, "drJoinDesired");
9bf3c633 2384
d62a17ae 2385 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
2386 json_object_boolean_true_add(json, "drJoinDesiredUpdated");
9bf3c633 2387
d62a17ae 2388 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
2389 json_object_boolean_true_add(json, "firstHopRouter");
9bf3c633 2390
d62a17ae 2391 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
2392 json_object_boolean_true_add(json, "sourceIgmp");
9bf3c633 2393
d62a17ae 2394 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
2395 json_object_boolean_true_add(json, "sourcePim");
7667c556 2396
d62a17ae 2397 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
2398 json_object_boolean_true_add(json, "sourceStream");
9bf3c633 2399
d62a17ae 2400 /* XXX: need to print ths flag in the plain text display as well */
2401 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
2402 json_object_boolean_true_add(json, "sourceMsdp");
e134b399
DS
2403
2404 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
2405 json_object_boolean_true_add(json, "sendSGRptPrune");
2406
2407 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
2408 json_object_boolean_true_add(json, "lastHopRouter");
2409
2410 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY)
2411 json_object_boolean_true_add(json, "disableKATExpiry");
2412
2413 if (up->flags & PIM_UPSTREAM_FLAG_MASK_STATIC_IIF)
2414 json_object_boolean_true_add(json, "staticIncomingInterface");
2415
2416 if (up->flags & PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL)
2417 json_object_boolean_true_add(json,
2418 "allowIncomingInterfaceinOil");
2419
2420 if (up->flags & PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA)
2421 json_object_boolean_true_add(json, "noPimRegistrationData");
2422
2423 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG)
2424 json_object_boolean_true_add(json, "forcePimRegistration");
2425
2426 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG)
2427 json_object_boolean_true_add(json, "sourceVxlanOrigination");
2428
2429 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
2430 json_object_boolean_true_add(json, "sourceVxlanTermination");
2431
2432 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
2433 json_object_boolean_true_add(json, "mlagVxlan");
2434
2435 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
2436 json_object_boolean_true_add(json,
2437 "mlagNonDesignatedForwarder");
755210ab 2438}
2439
2440static const char *
d62a17ae 2441pim_upstream_state2brief_str(enum pim_upstream_state join_state,
c35b7e6b 2442 char *state_str, size_t state_str_len)
d62a17ae 2443{
2444 switch (join_state) {
2445 case PIM_UPSTREAM_NOTJOINED:
c35b7e6b 2446 strlcpy(state_str, "NotJ", state_str_len);
d62a17ae 2447 break;
2448 case PIM_UPSTREAM_JOINED:
c35b7e6b 2449 strlcpy(state_str, "J", state_str_len);
d62a17ae 2450 break;
2451 default:
c35b7e6b 2452 strlcpy(state_str, "Unk", state_str_len);
d62a17ae 2453 }
2454 return state_str;
2455}
2456
2457static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
c35b7e6b 2458 char *state_str, size_t state_str_len)
d62a17ae 2459{
2460 switch (reg_state) {
2461 case PIM_REG_NOINFO:
c35b7e6b 2462 strlcpy(state_str, "RegNI", state_str_len);
d62a17ae 2463 break;
2464 case PIM_REG_JOIN:
c35b7e6b 2465 strlcpy(state_str, "RegJ", state_str_len);
d62a17ae 2466 break;
2467 case PIM_REG_JOIN_PENDING:
2468 case PIM_REG_PRUNE:
c35b7e6b 2469 strlcpy(state_str, "RegP", state_str_len);
d62a17ae 2470 break;
d62a17ae 2471 }
2472 return state_str;
755210ab 2473}
2474
64c86530 2475static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
6fff2cc6 2476 pim_sgaddr *sg, bool uj)
12e41d03 2477{
d62a17ae 2478 struct pim_upstream *up;
2479 time_t now;
2480 json_object *json = NULL;
2481 json_object *json_group = NULL;
2482 json_object *json_row = NULL;
2483
2484 now = pim_time_monotonic_sec();
2485
2486 if (uj)
2487 json = json_object_new_object();
2488 else
2489 vty_out(vty,
ff415346 2490 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
d62a17ae 2491
dd3364cb 2492 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
d62a17ae 2493 char uptime[10];
2494 char join_timer[10];
2495 char rs_timer[10];
2496 char ka_timer[10];
2497 char msdp_reg_timer[10];
2498 char state_str[PIM_REG_STATE_STR_LEN];
2499
62f59b58 2500 if (!pim_sgaddr_match(up->sg, *sg))
dff5cedb
DS
2501 continue;
2502
d62a17ae 2503 pim_time_uptime(uptime, sizeof(uptime),
2504 now - up->state_transition);
2505 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
2506 up->t_join_timer);
2507
2508 /*
d8bed89d
SP
2509 * If the upstream is not dummy and it has a J/P timer for the
2510 * neighbor display that
d62a17ae 2511 */
d8bed89d 2512 if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
d62a17ae 2513 struct pim_neighbor *nbr;
2514
9bb93fa0 2515 nbr = pim_neighbor_find_prefix(
d62a17ae 2516 up->rpf.source_nexthop.interface,
9bb93fa0 2517 &up->rpf.rpf_addr);
d62a17ae 2518 if (nbr)
2519 pim_time_timer_to_hhmmss(join_timer,
2520 sizeof(join_timer),
2521 nbr->jp_timer);
2522 }
2523
2524 pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
2525 up->t_rs_timer);
2526 pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
2527 up->t_ka_timer);
2528 pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
2529 up->t_msdp_reg_timer);
2530
c35b7e6b 2531 pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str));
d62a17ae 2532 if (up->reg_state != PIM_REG_NOINFO) {
2533 char tmp_str[PIM_REG_STATE_STR_LEN];
08808541 2534 char tmp[sizeof(state_str) + 1];
d62a17ae 2535
772270f3
QY
2536 snprintf(tmp, sizeof(tmp), ",%s",
2537 pim_reg_state2brief_str(up->reg_state, tmp_str,
2538 sizeof(tmp_str)));
2539 strlcat(state_str, tmp, sizeof(state_str));
d62a17ae 2540 }
2541
2542 if (uj) {
8e8be741
DL
2543 char grp_str[PIM_ADDRSTRLEN];
2544 char src_str[PIM_ADDRSTRLEN];
2545
2546 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
2547 &up->sg.grp);
2548 snprintfrr(src_str, sizeof(src_str), "%pPAs",
2549 &up->sg.src);
2550
d62a17ae 2551 json_object_object_get_ex(json, grp_str, &json_group);
2552
2553 if (!json_group) {
2554 json_group = json_object_new_object();
2555 json_object_object_add(json, grp_str,
2556 json_group);
2557 }
2558
2559 json_row = json_object_new_object();
2560 json_object_pim_upstream_add(json_row, up);
2561 json_object_string_add(
521c5b9d
MS
2562 json_row, "inboundInterface",
2563 up->rpf.source_nexthop.interface
d8bed89d
SP
2564 ? up->rpf.source_nexthop.interface->name
2565 : "Unknown");
48f41fe8
DS
2566
2567 /*
2568 * The RPF address we use is slightly different
2569 * based upon what we are looking up.
2570 * If we have a S, list that unless
2571 * we are the FHR, else we just put
2572 * the RP as the rpfAddress
2573 */
2a27f13b
DL
2574 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR ||
2575 pim_addr_is_any(up->sg.src)) {
48f41fe8
DS
2576 char rpf[PREFIX_STRLEN];
2577 struct pim_rpf *rpg;
2578
2579 rpg = RP(pim, up->sg.grp);
2580 pim_inet4_dump("<rpf?>",
996c9314
LB
2581 rpg->rpf_addr.u.prefix4, rpf,
2582 sizeof(rpf));
2583 json_object_string_add(json_row, "rpfAddress",
2584 rpf);
48f41fe8 2585 } else {
996c9314
LB
2586 json_object_string_add(json_row, "rpfAddress",
2587 src_str);
48f41fe8
DS
2588 }
2589
d62a17ae 2590 json_object_string_add(json_row, "source", src_str);
2591 json_object_string_add(json_row, "group", grp_str);
2592 json_object_string_add(json_row, "state", state_str);
2593 json_object_string_add(
2594 json_row, "joinState",
2595 pim_upstream_state2str(up->join_state));
2596 json_object_string_add(
2597 json_row, "regState",
c35b7e6b 2598 pim_reg_state2str(up->reg_state, state_str, sizeof(state_str)));
d62a17ae 2599 json_object_string_add(json_row, "upTime", uptime);
2600 json_object_string_add(json_row, "joinTimer",
2601 join_timer);
2602 json_object_string_add(json_row, "resetTimer",
2603 rs_timer);
2604 json_object_string_add(json_row, "keepaliveTimer",
2605 ka_timer);
2606 json_object_string_add(json_row, "msdpRegTimer",
2607 msdp_reg_timer);
2608 json_object_int_add(json_row, "refCount",
2609 up->ref_count);
2610 json_object_int_add(json_row, "sptBit", up->sptbit);
2611 json_object_object_add(json_group, src_str, json_row);
2612 } else {
2613 vty_out(vty,
8e8be741 2614 "%-16s%-15pPAs %-15pPAs %-11s %-8s %-9s %-9s %-9s %6d\n",
d8bed89d 2615 up->rpf.source_nexthop.interface
521c5b9d
MS
2616 ? up->rpf.source_nexthop.interface->name
2617 : "Unknown",
8e8be741
DL
2618 &up->sg.src, &up->sg.grp, state_str, uptime,
2619 join_timer, rs_timer, ka_timer, up->ref_count);
d62a17ae 2620 }
2621 }
2622
3757f964
DA
2623 if (uj)
2624 vty_json(vty, json);
12e41d03
DL
2625}
2626
5c9a72ef 2627static void pim_show_channel_helper(struct pim_instance *pim,
521c5b9d
MS
2628 struct vty *vty,
2629 struct pim_interface *pim_ifp,
2630 struct pim_ifchannel *ch,
2631 json_object *json, bool uj)
12e41d03 2632{
1a8a3da8
DS
2633 struct pim_upstream *up = ch->upstream;
2634 json_object *json_group = NULL;
d62a17ae 2635 json_object *json_row = NULL;
2636
1a8a3da8 2637 if (uj) {
8e8be741
DL
2638 char grp_str[PIM_ADDRSTRLEN];
2639 char src_str[PIM_ADDRSTRLEN];
2640
2641 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
2642 snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
2643
1a8a3da8 2644 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 2645
1a8a3da8
DS
2646 if (!json_group) {
2647 json_group = json_object_new_object();
996c9314 2648 json_object_object_add(json, grp_str, json_group);
1a8a3da8 2649 }
d62a17ae 2650
1a8a3da8
DS
2651 json_row = json_object_new_object();
2652 json_object_pim_upstream_add(json_row, up);
2653 json_object_string_add(json_row, "interface",
2654 ch->interface->name);
2655 json_object_string_add(json_row, "source", src_str);
2656 json_object_string_add(json_row, "group", grp_str);
d62a17ae 2657
1a8a3da8 2658 if (pim_macro_ch_lost_assert(ch))
996c9314 2659 json_object_boolean_true_add(json_row, "lostAssert");
d62a17ae 2660
1a8a3da8
DS
2661 if (pim_macro_chisin_joins(ch))
2662 json_object_boolean_true_add(json_row, "joins");
d62a17ae 2663
1a8a3da8 2664 if (pim_macro_chisin_pim_include(ch))
996c9314 2665 json_object_boolean_true_add(json_row, "pimInclude");
d62a17ae 2666
1a8a3da8 2667 if (pim_upstream_evaluate_join_desired(pim, up))
996c9314
LB
2668 json_object_boolean_true_add(json_row,
2669 "evaluateJoinDesired");
d62a17ae 2670
1a8a3da8 2671 json_object_object_add(json_group, src_str, json_row);
d62a17ae 2672
1a8a3da8 2673 } else {
8e8be741
DL
2674 vty_out(vty, "%-16s %-15pPAs %-15pPAs %-10s %-5s %-10s %-11s %-6s\n",
2675 ch->interface->name, &up->sg.src, &up->sg.grp,
1a8a3da8
DS
2676 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2677 pim_macro_chisin_joins(ch) ? "yes" : "no",
2678 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
996c9314 2679 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
521c5b9d
MS
2680 ? "yes"
2681 : "no",
996c9314 2682 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
521c5b9d 2683 : "no");
1a8a3da8
DS
2684 }
2685}
d62a17ae 2686
5c9a72ef 2687static void pim_show_channel(struct pim_instance *pim, struct vty *vty,
521c5b9d 2688 bool uj)
1a8a3da8 2689{
1a8a3da8
DS
2690 struct pim_interface *pim_ifp;
2691 struct pim_ifchannel *ch;
2692 struct interface *ifp;
d62a17ae 2693
1a8a3da8 2694 json_object *json = NULL;
d62a17ae 2695
1a8a3da8
DS
2696 if (uj)
2697 json = json_object_new_object();
2698 else
2699 vty_out(vty,
ff415346 2700 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
1a8a3da8
DS
2701
2702 /* scan per-interface (S,G) state */
451fda4f 2703 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8
DS
2704 pim_ifp = ifp->info;
2705 if (!pim_ifp)
2706 continue;
2707
ad7b74c4 2708
a2addae8 2709 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8 2710 /* scan all interfaces */
5c9a72ef 2711 pim_show_channel_helper(pim, vty, pim_ifp, ch,
521c5b9d 2712 json, uj);
d62a17ae 2713 }
2714 }
2715
3757f964
DA
2716 if (uj)
2717 vty_json(vty, json);
12e41d03
DL
2718}
2719
8ff637c8
AK
2720static void pim_show_join_desired_helper(struct pim_instance *pim,
2721 struct vty *vty,
2722 struct pim_upstream *up,
2723 json_object *json, bool uj)
2724{
2725 json_object *json_group = NULL;
8ff637c8
AK
2726 json_object *json_row = NULL;
2727
8ff637c8 2728 if (uj) {
8e8be741
DL
2729 char grp_str[PIM_ADDRSTRLEN];
2730 char src_str[PIM_ADDRSTRLEN];
2731
2732 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
2733 snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
2734
8ff637c8
AK
2735 json_object_object_get_ex(json, grp_str, &json_group);
2736
2737 if (!json_group) {
2738 json_group = json_object_new_object();
2739 json_object_object_add(json, grp_str, json_group);
2740 }
2741
2742 json_row = json_object_new_object();
2743 json_object_pim_upstream_add(json_row, up);
2744 json_object_string_add(json_row, "source", src_str);
2745 json_object_string_add(json_row, "group", grp_str);
2746
2747 if (pim_upstream_evaluate_join_desired(pim, up))
2748 json_object_boolean_true_add(json_row,
2749 "evaluateJoinDesired");
2750
2751 json_object_object_add(json_group, src_str, json_row);
2752
2753 } else {
8e8be741
DL
2754 vty_out(vty, "%-15pPAs %-15pPAs %-6s\n",
2755 &up->sg.src, &up->sg.grp,
8ff637c8 2756 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
521c5b9d 2757 : "no");
8ff637c8
AK
2758 }
2759}
2760
2761static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
2762 bool uj)
2763{
8ff637c8
AK
2764 struct pim_upstream *up;
2765
2766 json_object *json = NULL;
2767
2768 if (uj)
2769 json = json_object_new_object();
2770 else
2771 vty_out(vty,
2772 "Source Group EvalJD\n");
2773
dd3364cb 2774 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
8ff637c8
AK
2775 /* scan all interfaces */
2776 pim_show_join_desired_helper(pim, vty, up,
521c5b9d 2777 json, uj);
8ff637c8
AK
2778 }
2779
3757f964
DA
2780 if (uj)
2781 vty_json(vty, json);
8ff637c8
AK
2782}
2783
64c86530 2784static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
088f1098 2785 bool uj)
12e41d03 2786{
d62a17ae 2787 struct pim_upstream *up;
2788 json_object *json = NULL;
2789 json_object *json_group = NULL;
2790 json_object *json_row = NULL;
2791
2792 if (uj)
2793 json = json_object_new_object();
2794 else
2795 vty_out(vty,
ff415346 2796 "Source Group RpfIface RibNextHop RpfAddress \n");
d62a17ae 2797
dd3364cb 2798 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
d62a17ae 2799 char rpf_nexthop_str[PREFIX_STRLEN];
2800 char rpf_addr_str[PREFIX_STRLEN];
2801 struct pim_rpf *rpf;
2802 const char *rpf_ifname;
2803
2804 rpf = &up->rpf;
2805
d62a17ae 2806 pim_addr_dump("<nexthop?>",
2807 &rpf->source_nexthop.mrib_nexthop_addr,
2808 rpf_nexthop_str, sizeof(rpf_nexthop_str));
2809 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2810 sizeof(rpf_addr_str));
2811
9d303b37 2812 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2813
2814 if (uj) {
8e8be741
DL
2815 char grp_str[PIM_ADDRSTRLEN];
2816 char src_str[PIM_ADDRSTRLEN];
2817
2818 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
2819 &up->sg.grp);
2820 snprintfrr(src_str, sizeof(src_str), "%pPAs",
2821 &up->sg.src);
2822
d62a17ae 2823 json_object_object_get_ex(json, grp_str, &json_group);
2824
2825 if (!json_group) {
2826 json_group = json_object_new_object();
2827 json_object_object_add(json, grp_str,
2828 json_group);
2829 }
2830
2831 json_row = json_object_new_object();
2832 json_object_pim_upstream_add(json_row, up);
2833 json_object_string_add(json_row, "source", src_str);
2834 json_object_string_add(json_row, "group", grp_str);
2835 json_object_string_add(json_row, "rpfInterface",
2836 rpf_ifname);
2837 json_object_string_add(json_row, "ribNexthop",
2838 rpf_nexthop_str);
2839 json_object_string_add(json_row, "rpfAddress",
2840 rpf_addr_str);
2841 json_object_object_add(json_group, src_str, json_row);
2842 } else {
8e8be741
DL
2843 vty_out(vty, "%-15pPAs %-15pPAs %-16s %-15s %-15s\n",
2844 &up->sg.src, &up->sg.grp, rpf_ifname,
2845 rpf_nexthop_str, rpf_addr_str);
d62a17ae 2846 }
2847 }
2848
3757f964
DA
2849 if (uj)
2850 vty_json(vty, json);
d62a17ae 2851}
2852
da11e325
DS
2853static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
2854 time_t now, json_object *json)
d62a17ae 2855{
2856 char refresh_uptime[10];
2857
2858 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
bfc92019 2859 pim->rpf_cache_refresh_last);
d62a17ae 2860
2861 if (json) {
2862 json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
da03883e 2863 router->rpf_cache_refresh_delay_msec);
d62a17ae 2864 json_object_int_add(
2865 json, "rpfCacheRefreshTimer",
da11e325 2866 pim_time_timer_remain_msec(pim->rpf_cache_refresher));
d62a17ae 2867 json_object_int_add(json, "rpfCacheRefreshRequests",
bfc92019 2868 pim->rpf_cache_refresh_requests);
d62a17ae 2869 json_object_int_add(json, "rpfCacheRefreshEvents",
bfc92019 2870 pim->rpf_cache_refresh_events);
d62a17ae 2871 json_object_string_add(json, "rpfCacheRefreshLast",
2872 refresh_uptime);
2873 json_object_int_add(json, "nexthopLookups",
bfc92019 2874 pim->nexthop_lookups);
d62a17ae 2875 json_object_int_add(json, "nexthopLookupsAvoided",
bfc92019 2876 pim->nexthop_lookups_avoided);
d62a17ae 2877 } else {
2878 vty_out(vty,
2879 "RPF Cache Refresh Delay: %ld msecs\n"
2880 "RPF Cache Refresh Timer: %ld msecs\n"
2881 "RPF Cache Refresh Requests: %lld\n"
2882 "RPF Cache Refresh Events: %lld\n"
2883 "RPF Cache Refresh Last: %s\n"
2884 "Nexthop Lookups: %lld\n"
2885 "Nexthop Lookups Avoided: %lld\n",
da03883e 2886 router->rpf_cache_refresh_delay_msec,
da11e325 2887 pim_time_timer_remain_msec(pim->rpf_cache_refresher),
bfc92019
DS
2888 (long long)pim->rpf_cache_refresh_requests,
2889 (long long)pim->rpf_cache_refresh_events,
2890 refresh_uptime, (long long)pim->nexthop_lookups,
2891 (long long)pim->nexthop_lookups_avoided);
d62a17ae 2892 }
12e41d03
DL
2893}
2894
64c86530 2895static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2896 time_t now)
12e41d03 2897{
d62a17ae 2898 char uptime_scan_oil[10];
2899 char uptime_mroute_add[10];
2900 char uptime_mroute_del[10];
12e41d03 2901
d62a17ae 2902 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
bfc92019 2903 pim->scan_oil_last);
d62a17ae 2904 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
c68ba0d7 2905 pim->mroute_add_last);
d62a17ae 2906 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
c68ba0d7 2907 pim->mroute_del_last);
12e41d03 2908
d62a17ae 2909 vty_out(vty,
2910 "Scan OIL - Last: %s Events: %lld\n"
2911 "MFC Add - Last: %s Events: %lld\n"
2912 "MFC Del - Last: %s Events: %lld\n",
bfc92019 2913 uptime_scan_oil, (long long)pim->scan_oil_events,
c68ba0d7
DS
2914 uptime_mroute_add, (long long)pim->mroute_add_events,
2915 uptime_mroute_del, (long long)pim->mroute_del_events);
12e41d03
DL
2916}
2917
088f1098 2918static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
12e41d03 2919{
d62a17ae 2920 struct pim_upstream *up;
2921 time_t now = pim_time_monotonic_sec();
2922 json_object *json = NULL;
2923 json_object *json_group = NULL;
2924 json_object *json_row = NULL;
2925
2926 if (uj) {
2927 json = json_object_new_object();
da11e325 2928 show_rpf_refresh_stats(vty, pim, now, json);
d62a17ae 2929 } else {
da11e325 2930 show_rpf_refresh_stats(vty, pim, now, json);
d62a17ae 2931 vty_out(vty, "\n");
2932 vty_out(vty,
ff415346 2933 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
d62a17ae 2934 }
cba44481 2935
dd3364cb 2936 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
d62a17ae 2937 char rpf_addr_str[PREFIX_STRLEN];
2938 char rib_nexthop_str[PREFIX_STRLEN];
2939 const char *rpf_ifname;
2940 struct pim_rpf *rpf = &up->rpf;
2941
d62a17ae 2942 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2943 sizeof(rpf_addr_str));
2944 pim_addr_dump("<nexthop?>",
2945 &rpf->source_nexthop.mrib_nexthop_addr,
2946 rib_nexthop_str, sizeof(rib_nexthop_str));
2947
9d303b37 2948 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2949
2950 if (uj) {
8e8be741
DL
2951 char grp_str[PIM_ADDRSTRLEN];
2952 char src_str[PIM_ADDRSTRLEN];
2953
2954 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
2955 &up->sg.grp);
2956 snprintfrr(src_str, sizeof(src_str), "%pPAs",
2957 &up->sg.src);
2958
d62a17ae 2959 json_object_object_get_ex(json, grp_str, &json_group);
2960
2961 if (!json_group) {
2962 json_group = json_object_new_object();
2963 json_object_object_add(json, grp_str,
2964 json_group);
2965 }
2966
2967 json_row = json_object_new_object();
2968 json_object_string_add(json_row, "source", src_str);
2969 json_object_string_add(json_row, "group", grp_str);
2970 json_object_string_add(json_row, "rpfInterface",
2971 rpf_ifname);
2972 json_object_string_add(json_row, "rpfAddress",
2973 rpf_addr_str);
2974 json_object_string_add(json_row, "ribNexthop",
2975 rib_nexthop_str);
2976 json_object_int_add(
2977 json_row, "routeMetric",
2978 rpf->source_nexthop.mrib_route_metric);
2979 json_object_int_add(
2980 json_row, "routePreference",
2981 rpf->source_nexthop.mrib_metric_preference);
2982 json_object_object_add(json_group, src_str, json_row);
2983
2984 } else {
8e8be741
DL
2985 vty_out(vty, "%-15pPAs %-15pPAs %-16s %-15s %-15s %6d %4d\n",
2986 &up->sg.src, &up->sg.grp, rpf_ifname,
2987 rpf_addr_str, rib_nexthop_str,
d62a17ae 2988 rpf->source_nexthop.mrib_route_metric,
2989 rpf->source_nexthop.mrib_metric_preference);
2990 }
2991 }
2992
3757f964
DA
2993 if (uj)
2994 vty_json(vty, json);
cba44481
CS
2995}
2996
c68ba0d7
DS
2997struct pnc_cache_walk_data {
2998 struct vty *vty;
2999 struct pim_instance *pim;
3000};
3001
e3b78da8 3002static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
12e41d03 3003{
e3b78da8 3004 struct pim_nexthop_cache *pnc = bucket->data;
c68ba0d7
DS
3005 struct pnc_cache_walk_data *cwd = arg;
3006 struct vty *vty = cwd->vty;
3007 struct pim_instance *pim = cwd->pim;
d62a17ae 3008 struct nexthop *nh_node = NULL;
3009 ifindex_t first_ifindex;
3010 struct interface *ifp = NULL;
ee2bbf7c 3011 char buf[PREFIX_STRLEN];
d62a17ae 3012
d62a17ae 3013 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
3014 first_ifindex = nh_node->ifindex;
d3cc1e45 3015 ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
d62a17ae 3016
ee2bbf7c
MS
3017 vty_out(vty, "%-15s ", inet_ntop(AF_INET,
3018 &pnc->rpf.rpf_addr.u.prefix4,
3019 buf, sizeof(buf)));
ff415346 3020 vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
ee2bbf7c 3021 vty_out(vty, "%pI4 ", &nh_node->gate.ipv4);
d62a17ae 3022 vty_out(vty, "\n");
3023 }
3024 return CMD_SUCCESS;
3025}
3026
64c86530 3027static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
d62a17ae 3028{
c68ba0d7 3029 struct pnc_cache_walk_data cwd;
d62a17ae 3030
c68ba0d7
DS
3031 cwd.vty = vty;
3032 cwd.pim = pim;
3033 vty_out(vty, "Number of registered addresses: %lu\n",
3034 pim->rpf_hash->count);
ff415346
DS
3035 vty_out(vty, "Address Interface Nexthop\n");
3036 vty_out(vty, "---------------------------------------------\n");
12e41d03 3037
c68ba0d7 3038 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
d62a17ae 3039}
3040
0d1a4e24 3041/* Display the bsm database details */
3042static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
3043{
0d1a4e24 3044 int count = 0;
3045 int fragment = 1;
d4a4525c 3046 struct bsm_frag *bsfrag;
0d1a4e24 3047 json_object *json = NULL;
3048 json_object *json_group = NULL;
3049 json_object *json_row = NULL;
3050
d4a4525c 3051 count = bsm_frags_count(pim->global_scope.bsm_frags);
0d1a4e24 3052
3053 if (uj) {
3054 json = json_object_new_object();
3055 json_object_int_add(json, "Number of the fragments", count);
3056 } else {
3057 vty_out(vty, "Scope Zone: Global\n");
3058 vty_out(vty, "Number of the fragments: %d\n", count);
3059 vty_out(vty, "\n");
3060 }
3061
d4a4525c 3062 frr_each (bsm_frags, pim->global_scope.bsm_frags, bsfrag) {
93a5bc80 3063 char grp_str[PREFIX_STRLEN];
0d1a4e24 3064 char rp_str[INET_ADDRSTRLEN];
3065 char bsr_str[INET_ADDRSTRLEN];
3066 struct bsmmsg_grpinfo *group;
3067 struct bsmmsg_rpinfo *rpaddr;
3068 struct prefix grp;
3069 struct bsm_hdr *hdr;
3070 uint32_t offset = 0;
3071 uint8_t *buf;
3072 uint32_t len = 0;
3073 uint32_t frag_rp_cnt = 0;
3074
d4a4525c
DL
3075 buf = bsfrag->data;
3076 len = bsfrag->size;
0d1a4e24 3077
3078 /* skip pim header */
3079 buf += PIM_MSG_HEADER_LEN;
3080 len -= PIM_MSG_HEADER_LEN;
3081
3082 hdr = (struct bsm_hdr *)buf;
3083
3084 /* BSM starts with bsr header */
3085 buf += sizeof(struct bsm_hdr);
3086 len -= sizeof(struct bsm_hdr);
3087
3088 pim_inet4_dump("<BSR Address?>", hdr->bsr_addr.addr, bsr_str,
3089 sizeof(bsr_str));
3090
3091
3092 if (uj) {
3093 json_object_string_add(json, "BSR address", bsr_str);
3094 json_object_int_add(json, "BSR priority",
3095 hdr->bsr_prio);
3096 json_object_int_add(json, "Hashmask Length",
3097 hdr->hm_len);
3098 json_object_int_add(json, "Fragment Tag",
3099 ntohs(hdr->frag_tag));
3100 } else {
3101 vty_out(vty, "BSM Fragment : %d\n", fragment);
3102 vty_out(vty, "------------------\n");
3103 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3104 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3105 vty_out(vty, "%-15s %-15d %-15d %-15d\n", bsr_str,
3106 hdr->bsr_prio, hdr->hm_len,
3107 ntohs(hdr->frag_tag));
3108 }
3109
3110 vty_out(vty, "\n");
3111
3112 while (offset < len) {
3113 group = (struct bsmmsg_grpinfo *)buf;
3114
3115 if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
3116 grp.family = AF_INET;
3117
3118 grp.prefixlen = group->group.mask;
3119 grp.u.prefix4.s_addr = group->group.addr.s_addr;
3120
3121 prefix2str(&grp, grp_str, sizeof(grp_str));
3122
3123 buf += sizeof(struct bsmmsg_grpinfo);
3124 offset += sizeof(struct bsmmsg_grpinfo);
3125
3126 if (uj) {
3127 json_object_object_get_ex(json, grp_str,
3128 &json_group);
3129 if (!json_group) {
3130 json_group = json_object_new_object();
3131 json_object_int_add(json_group,
3132 "Rp Count",
3133 group->rp_count);
3134 json_object_int_add(
3135 json_group, "Fragment Rp count",
3136 group->frag_rp_count);
3137 json_object_object_add(json, grp_str,
3138 json_group);
3139 }
3140 } else {
3141 vty_out(vty, "Group : %s\n", grp_str);
3142 vty_out(vty, "-------------------\n");
3143 vty_out(vty, "Rp Count:%d\n", group->rp_count);
3144 vty_out(vty, "Fragment Rp Count : %d\n",
3145 group->frag_rp_count);
3146 }
3147
3148 frag_rp_cnt = group->frag_rp_count;
3149
3150 if (!frag_rp_cnt)
3151 continue;
3152
3153 if (!uj)
3154 vty_out(vty,
3155 "RpAddress HoldTime Priority\n");
3156
3157 while (frag_rp_cnt--) {
3158 rpaddr = (struct bsmmsg_rpinfo *)buf;
3159
3160 buf += sizeof(struct bsmmsg_rpinfo);
3161 offset += sizeof(struct bsmmsg_rpinfo);
3162
3163 pim_inet4_dump("<Rp addr?>",
3164 rpaddr->rpaddr.addr, rp_str,
3165 sizeof(rp_str));
3166
3167 if (uj) {
3168 json_row = json_object_new_object();
3169 json_object_string_add(
3170 json_row, "Rp Address", rp_str);
3171 json_object_int_add(
3172 json_row, "Rp HoldTime",
3173 ntohs(rpaddr->rp_holdtime));
3174 json_object_int_add(json_row,
3175 "Rp Priority",
3176 rpaddr->rp_pri);
3177 json_object_object_add(
3178 json_group, rp_str, json_row);
3179 } else {
3180 vty_out(vty, "%-15s %-12d %d\n", rp_str,
3181 ntohs(rpaddr->rp_holdtime),
3182 rpaddr->rp_pri);
3183 }
3184 }
3185 vty_out(vty, "\n");
3186 }
3187
3188 fragment++;
3189 }
3190
3757f964
DA
3191 if (uj)
3192 vty_json(vty, json);
0d1a4e24 3193}
3194
321295c1 3195/*Display the group-rp mappings */
3196static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
3197 struct vty *vty, bool uj)
3198{
3199 struct bsgrp_node *bsgrp;
321295c1 3200 struct bsm_rpinfo *bsm_rp;
3201 struct route_node *rn;
3202 char bsr_str[INET_ADDRSTRLEN];
3203 json_object *json = NULL;
3204 json_object *json_group = NULL;
3205 json_object *json_row = NULL;
3206
3207 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY)
fbd74c7d 3208 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
321295c1 3209
3210 else
3211 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str,
3212 sizeof(bsr_str));
3213
3214 if (uj) {
3215 json = json_object_new_object();
3216 json_object_string_add(json, "BSR Address", bsr_str);
3217 } else {
3218 vty_out(vty, "BSR Address %s\n", bsr_str);
3219 }
3220
3221 for (rn = route_top(pim->global_scope.bsrp_table); rn;
3222 rn = route_next(rn)) {
3223 bsgrp = (struct bsgrp_node *)rn->info;
3224
3225 if (!bsgrp)
3226 continue;
3227
93a5bc80 3228 char grp_str[PREFIX_STRLEN];
321295c1 3229
3230 prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
3231
3232 if (uj) {
3233 json_object_object_get_ex(json, grp_str, &json_group);
3234 if (!json_group) {
3235 json_group = json_object_new_object();
3236 json_object_object_add(json, grp_str,
3237 json_group);
3238 }
3239 } else {
2dbe669b 3240 vty_out(vty, "Group Address %pFX\n", &bsgrp->group);
321295c1 3241 vty_out(vty, "--------------------------\n");
3242 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3243 "priority", "Holdtime", "Hash");
3244
3245 vty_out(vty, "(ACTIVE)\n");
3246 }
3247
fdab2940
DL
3248 frr_each (bsm_rpinfos, bsgrp->bsrp_list, bsm_rp) {
3249 char rp_str[INET_ADDRSTRLEN];
321295c1 3250
fdab2940
DL
3251 pim_inet4_dump("<Rp Address?>", bsm_rp->rp_address,
3252 rp_str, sizeof(rp_str));
321295c1 3253
fdab2940
DL
3254 if (uj) {
3255 json_row = json_object_new_object();
3256 json_object_string_add(json_row, "Rp Address",
3257 rp_str);
3258 json_object_int_add(json_row, "Rp HoldTime",
3259 bsm_rp->rp_holdtime);
3260 json_object_int_add(json_row, "Rp Priority",
3261 bsm_rp->rp_prio);
3262 json_object_int_add(json_row, "Hash Val",
3263 bsm_rp->hash);
3264 json_object_object_add(json_group, rp_str,
3265 json_row);
321295c1 3266
fdab2940
DL
3267 } else {
3268 vty_out(vty, "%-15s %-15u %-15u %-15u\n",
3269 rp_str, bsm_rp->rp_prio,
3270 bsm_rp->rp_holdtime, bsm_rp->hash);
321295c1 3271 }
321295c1 3272 }
fdab2940
DL
3273 if (!bsm_rpinfos_count(bsgrp->bsrp_list) && !uj)
3274 vty_out(vty, "Active List is empty.\n");
321295c1 3275
3276 if (uj) {
3277 json_object_int_add(json_group, "Pending RP count",
3278 bsgrp->pend_rp_cnt);
3279 } else {
3280 vty_out(vty, "(PENDING)\n");
3281 vty_out(vty, "Pending RP count :%d\n",
3282 bsgrp->pend_rp_cnt);
3283 if (bsgrp->pend_rp_cnt)
3284 vty_out(vty, "%-15s %-15s %-15s %-15s\n",
3285 "Rp Address", "priority", "Holdtime",
3286 "Hash");
3287 }
3288
fdab2940
DL
3289 frr_each (bsm_rpinfos, bsgrp->partial_bsrp_list, bsm_rp) {
3290 char rp_str[INET_ADDRSTRLEN];
321295c1 3291
fdab2940
DL
3292 pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address, rp_str,
3293 sizeof(rp_str));
321295c1 3294
fdab2940
DL
3295 if (uj) {
3296 json_row = json_object_new_object();
3297 json_object_string_add(json_row, "Rp Address",
3298 rp_str);
3299 json_object_int_add(json_row, "Rp HoldTime",
3300 bsm_rp->rp_holdtime);
3301 json_object_int_add(json_row, "Rp Priority",
3302 bsm_rp->rp_prio);
3303 json_object_int_add(json_row, "Hash Val",
3304 bsm_rp->hash);
3305 json_object_object_add(json_group, rp_str,
3306 json_row);
3307 } else {
3308 vty_out(vty, "%-15s %-15u %-15u %-15u\n",
3309 rp_str, bsm_rp->rp_prio,
3310 bsm_rp->rp_holdtime, bsm_rp->hash);
321295c1 3311 }
321295c1 3312 }
fdab2940
DL
3313 if (!bsm_rpinfos_count(bsgrp->partial_bsrp_list) && !uj)
3314 vty_out(vty, "Partial List is empty\n");
321295c1 3315
3316 if (!uj)
3317 vty_out(vty, "\n");
3318 }
3319
3757f964
DA
3320 if (uj)
3321 vty_json(vty, json);
321295c1 3322}
3323
415f6350 3324/* pim statistics - just adding only bsm related now.
3325 * We can continue to add all pim related stats here.
3326 */
3327static void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
3328 const char *ifname, bool uj)
3329{
3330 json_object *json = NULL;
3331 struct interface *ifp;
3332
3333 if (uj) {
3334 json = json_object_new_object();
a5f610e4
QY
3335 json_object_int_add(json, "bsmRx", pim->bsm_rcvd);
3336 json_object_int_add(json, "bsmTx", pim->bsm_sent);
3337 json_object_int_add(json, "bsmDropped", pim->bsm_dropped);
415f6350 3338 } else {
3339 vty_out(vty, "BSM Statistics :\n");
3340 vty_out(vty, "----------------\n");
9a8a7b0e
DS
3341 vty_out(vty, "Number of Received BSMs : %" PRIu64 "\n",
3342 pim->bsm_rcvd);
3343 vty_out(vty, "Number of Forwared BSMs : %" PRIu64 "\n",
3344 pim->bsm_sent);
3345 vty_out(vty, "Number of Dropped BSMs : %" PRIu64 "\n",
415f6350 3346 pim->bsm_dropped);
3347 }
3348
3349 vty_out(vty, "\n");
3350
3351 /* scan interfaces */
3352 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3353 struct pim_interface *pim_ifp = ifp->info;
3354
3355 if (ifname && strcmp(ifname, ifp->name))
3356 continue;
3357
3358 if (!pim_ifp)
3359 continue;
3360
3361 if (!uj) {
3362 vty_out(vty, "Interface : %s\n", ifp->name);
3363 vty_out(vty, "-------------------\n");
3364 vty_out(vty,
3365 "Number of BSMs dropped due to config miss : %u\n",
3366 pim_ifp->pim_ifstat_bsm_cfg_miss);
3367 vty_out(vty, "Number of unicast BSMs dropped : %u\n",
3368 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3369 vty_out(vty,
3370 "Number of BSMs dropped due to invalid scope zone : %u\n",
3371 pim_ifp->pim_ifstat_bsm_invalid_sz);
3372 } else {
3373
3374 json_object *json_row = NULL;
3375
3376 json_row = json_object_new_object();
3377
3378 json_object_string_add(json_row, "If Name", ifp->name);
a5f610e4
QY
3379 json_object_int_add(json_row, "bsmDroppedConfig",
3380 pim_ifp->pim_ifstat_bsm_cfg_miss);
415f6350 3381 json_object_int_add(
a5f610e4 3382 json_row, "bsmDroppedUnicast",
415f6350 3383 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3384 json_object_int_add(json_row,
a5f610e4 3385 "bsmDroppedInvalidScopeZone",
415f6350 3386 pim_ifp->pim_ifstat_bsm_invalid_sz);
3387 json_object_object_add(json, ifp->name, json_row);
3388 }
3389 vty_out(vty, "\n");
3390 }
3391
3757f964
DA
3392 if (uj)
3393 vty_json(vty, json);
415f6350 3394}
3395
3396static void clear_pim_statistics(struct pim_instance *pim)
3397{
3398 struct interface *ifp;
3399
3400 pim->bsm_rcvd = 0;
3401 pim->bsm_sent = 0;
3402 pim->bsm_dropped = 0;
3403
3404 /* scan interfaces */
3405 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3406 struct pim_interface *pim_ifp = ifp->info;
3407
3408 if (!pim_ifp)
3409 continue;
3410
3411 pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
3412 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
3413 pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
3414 }
3415}
3416
088f1098 3417static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 3418{
d62a17ae 3419 struct interface *ifp;
3420 time_t now;
3421 json_object *json = NULL;
3422 json_object *json_iface = NULL;
4d360968 3423 json_object *json_group = NULL;
3424 json_object *json_groups = NULL;
d62a17ae 3425
3426 now = pim_time_monotonic_sec();
3427
339f7695 3428 if (uj) {
d62a17ae 3429 json = json_object_new_object();
339f7695 3430 json_object_int_add(json, "totalGroups", pim->igmp_group_count);
3431 json_object_int_add(json, "watermarkLimit",
3432 pim->igmp_watermark_limit);
3433 } else {
3434 vty_out(vty, "Total IGMP groups: %u\n", pim->igmp_group_count);
3435 vty_out(vty, "Watermark warn limit(%s): %u\n",
3436 pim->igmp_watermark_limit ? "Set" : "Not Set",
3437 pim->igmp_watermark_limit);
d62a17ae 3438 vty_out(vty,
dda4d23c 3439 "Interface Group Mode Timer Srcs V Uptime \n");
339f7695 3440 }
d62a17ae 3441
3442 /* scan interfaces */
451fda4f 3443 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3444 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 3445 struct listnode *grpnode;
a16db099 3446 struct gm_group *grp;
d62a17ae 3447
3448 if (!pim_ifp)
3449 continue;
3450
dda4d23c 3451 /* scan igmp groups */
18adcff1 3452 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 3453 grp)) {
dda4d23c
DL
3454 char group_str[INET_ADDRSTRLEN];
3455 char hhmmss[10];
3456 char uptime[10];
d62a17ae 3457
a1a4295a
DL
3458 pim_inet4_dump("<group?>", grp->group_addr, group_str,
3459 sizeof(group_str));
dda4d23c
DL
3460 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
3461 grp->t_group_timer);
3462 pim_time_uptime(uptime, sizeof(uptime),
3463 now - grp->group_creation);
d62a17ae 3464
dda4d23c 3465 if (uj) {
a1a4295a
DL
3466 json_object_object_get_ex(json, ifp->name,
3467 &json_iface);
d62a17ae 3468
dda4d23c 3469 if (!json_iface) {
a1a4295a
DL
3470 json_iface = json_object_new_object();
3471 json_object_pim_ifp_add(json_iface,
3472 ifp);
3473 json_object_object_add(json, ifp->name,
3474 json_iface);
3475 json_groups = json_object_new_array();
3476 json_object_object_add(json_iface,
3477 "groups",
3478 json_groups);
d62a17ae 3479 }
dda4d23c
DL
3480
3481 json_group = json_object_new_object();
a1a4295a 3482 json_object_string_add(json_group, "group",
dda4d23c
DL
3483 group_str);
3484
3485 if (grp->igmp_version == 3)
3486 json_object_string_add(
3487 json_group, "mode",
3488 grp->group_filtermode_isexcl
a1a4295a
DL
3489 ? "EXCLUDE"
3490 : "INCLUDE");
dda4d23c 3491
a1a4295a
DL
3492 json_object_string_add(json_group, "timer",
3493 hhmmss);
dda4d23c
DL
3494 json_object_int_add(
3495 json_group, "sourcesCount",
a1a4295a 3496 grp->group_source_list ? listcount(
dda4d23c 3497 grp->group_source_list)
a1a4295a
DL
3498 : 0);
3499 json_object_int_add(json_group, "version",
3500 grp->igmp_version);
3501 json_object_string_add(json_group, "uptime",
3502 uptime);
3503 json_object_array_add(json_groups, json_group);
dda4d23c 3504 } else {
a1a4295a 3505 vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n",
dda4d23c
DL
3506 ifp->name, group_str,
3507 grp->igmp_version == 3
a1a4295a
DL
3508 ? (grp->group_filtermode_isexcl
3509 ? "EXCL"
3510 : "INCL")
3511 : "----",
dda4d23c 3512 hhmmss,
a1a4295a 3513 grp->group_source_list ? listcount(
dda4d23c 3514 grp->group_source_list)
a1a4295a 3515 : 0,
dda4d23c
DL
3516 grp->igmp_version, uptime);
3517 }
3518 } /* scan igmp groups */
3519 } /* scan interfaces */
d62a17ae 3520
3757f964
DA
3521 if (uj)
3522 vty_json(vty, json);
12e41d03
DL
3523}
3524
64c86530
DS
3525static void igmp_show_group_retransmission(struct pim_instance *pim,
3526 struct vty *vty)
12e41d03 3527{
d62a17ae 3528 struct interface *ifp;
3529
3530 vty_out(vty,
dda4d23c 3531 "Interface Group RetTimer Counter RetSrcs\n");
d62a17ae 3532
3533 /* scan interfaces */
451fda4f 3534 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3535 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 3536 struct listnode *grpnode;
a16db099 3537 struct gm_group *grp;
d62a17ae 3538
3539 if (!pim_ifp)
3540 continue;
3541
dda4d23c 3542 /* scan igmp groups */
18adcff1 3543 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 3544 grp)) {
dda4d23c
DL
3545 char group_str[INET_ADDRSTRLEN];
3546 char grp_retr_mmss[10];
3547 struct listnode *src_node;
51700107 3548 struct gm_source *src;
dda4d23c 3549 int grp_retr_sources = 0;
d62a17ae 3550
a1a4295a
DL
3551 pim_inet4_dump("<group?>", grp->group_addr, group_str,
3552 sizeof(group_str));
dda4d23c
DL
3553 pim_time_timer_to_mmss(
3554 grp_retr_mmss, sizeof(grp_retr_mmss),
3555 grp->t_group_query_retransmit_timer);
d62a17ae 3556
dda4d23c
DL
3557
3558 /* count group sources with retransmission state
3559 */
a1a4295a
DL
3560 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
3561 src_node, src)) {
3562 if (src->source_query_retransmit_count > 0) {
dda4d23c 3563 ++grp_retr_sources;
d62a17ae 3564 }
dda4d23c 3565 }
d62a17ae 3566
a1a4295a
DL
3567 vty_out(vty, "%-16s %-15s %-8s %7d %7d\n", ifp->name,
3568 group_str, grp_retr_mmss,
dda4d23c
DL
3569 grp->group_specific_query_retransmit_count,
3570 grp_retr_sources);
d62a17ae 3571
dda4d23c
DL
3572 } /* scan igmp groups */
3573 } /* scan interfaces */
12e41d03
DL
3574}
3575
4527b70a
SG
3576static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
3577 bool uj)
12e41d03 3578{
d62a17ae 3579 struct interface *ifp;
3580 time_t now;
4527b70a
SG
3581 json_object *json = NULL;
3582 json_object *json_iface = NULL;
3583 json_object *json_group = NULL;
3584 json_object *json_source = NULL;
3585 json_object *json_sources = NULL;
d62a17ae 3586
3587 now = pim_time_monotonic_sec();
3588
4527b70a
SG
3589 if (uj)
3590 json = json_object_new_object();
3591 else
3592 vty_out(vty,
3593 "Interface Address Group Source Timer Fwd Uptime \n");
d62a17ae 3594
3595 /* scan interfaces */
451fda4f 3596 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3597 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 3598 struct listnode *grpnode;
a16db099 3599 struct gm_group *grp;
d62a17ae 3600
3601 if (!pim_ifp)
3602 continue;
3603
dda4d23c 3604 /* scan igmp groups */
18adcff1 3605 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 3606 grp)) {
dda4d23c
DL
3607 char group_str[INET_ADDRSTRLEN];
3608 struct listnode *srcnode;
51700107 3609 struct gm_source *src;
dda4d23c 3610
a1a4295a
DL
3611 pim_inet4_dump("<group?>", grp->group_addr, group_str,
3612 sizeof(group_str));
dda4d23c
DL
3613
3614 /* scan group sources */
a1a4295a
DL
3615 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
3616 srcnode, src)) {
dda4d23c
DL
3617 char source_str[INET_ADDRSTRLEN];
3618 char mmss[10];
3619 char uptime[10];
d62a17ae 3620
a1a4295a
DL
3621 pim_inet4_dump("<source?>", src->source_addr,
3622 source_str, sizeof(source_str));
d62a17ae 3623
a1a4295a
DL
3624 pim_time_timer_to_mmss(mmss, sizeof(mmss),
3625 src->t_source_timer);
d62a17ae 3626
a1a4295a
DL
3627 pim_time_uptime(uptime, sizeof(uptime),
3628 now - src->source_creation);
d62a17ae 3629
4527b70a
SG
3630 if (uj) {
3631 json_object_object_get_ex(
3632 json, ifp->name, &json_iface);
3633 if (!json_iface) {
3634 json_iface =
3635 json_object_new_object();
3636 json_object_string_add(
3637 json_iface, "name",
3638 ifp->name);
3639 json_object_object_add(
3640 json, ifp->name,
3641 json_iface);
3642 }
3643 json_object_object_get_ex(json_iface,
3644 group_str,
3645 &json_group);
3646
3647 if (!json_group) {
3648 json_group =
3649 json_object_new_object();
3650 json_object_string_add(
3651 json_group, "group",
3652 group_str);
3653 json_object_object_add(
3654 json_iface, group_str,
3655 json_group);
3656 json_sources =
3657 json_object_new_array();
3658 json_object_object_add(
3659 json_group, "sources",
3660 json_sources);
3661 }
3662 json_source = json_object_new_object();
3663 json_object_string_add(json_source,
3664 "source",
3665 source_str);
3666 json_object_string_add(json_source,
3667 "timer", mmss);
3668 json_object_boolean_add(
3669 json_source, "forwarded",
3670 IGMP_SOURCE_TEST_FORWARDING(
3671 src->source_flags));
3672 json_object_string_add(
3673 json_source, "uptime", uptime);
3674 json_object_array_add(json_sources,
3675 json_source);
3676
3677 } else {
3678 vty_out(vty,
3679 "%-16s %-15s %-15s %5s %3s %8s\n",
3680 ifp->name, group_str,
3681 source_str, mmss,
3682 IGMP_SOURCE_TEST_FORWARDING(
3683 src->source_flags)
3684 ? "Y"
3685 : "N",
3686 uptime);
3687 }
d62a17ae 3688
dda4d23c 3689 } /* scan group sources */
18adcff1 3690 } /* scan igmp groups */
dda4d23c 3691 } /* scan interfaces */
4527b70a
SG
3692 if (uj)
3693 vty_json(vty, json);
12e41d03
DL
3694}
3695
64c86530
DS
3696static void igmp_show_source_retransmission(struct pim_instance *pim,
3697 struct vty *vty)
12e41d03 3698{
d62a17ae 3699 struct interface *ifp;
3700
3701 vty_out(vty,
dda4d23c 3702 "Interface Group Source Counter\n");
d62a17ae 3703
3704 /* scan interfaces */
451fda4f 3705 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3706 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 3707 struct listnode *grpnode;
a16db099 3708 struct gm_group *grp;
d62a17ae 3709
3710 if (!pim_ifp)
3711 continue;
3712
dda4d23c 3713 /* scan igmp groups */
18adcff1 3714 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 3715 grp)) {
dda4d23c
DL
3716 char group_str[INET_ADDRSTRLEN];
3717 struct listnode *srcnode;
51700107 3718 struct gm_source *src;
d62a17ae 3719
a1a4295a
DL
3720 pim_inet4_dump("<group?>", grp->group_addr, group_str,
3721 sizeof(group_str));
d62a17ae 3722
dda4d23c 3723 /* scan group sources */
a1a4295a
DL
3724 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
3725 srcnode, src)) {
dda4d23c 3726 char source_str[INET_ADDRSTRLEN];
d62a17ae 3727
a1a4295a
DL
3728 pim_inet4_dump("<source?>", src->source_addr,
3729 source_str, sizeof(source_str));
d62a17ae 3730
a1a4295a 3731 vty_out(vty, "%-16s %-15s %-15s %7d\n",
dda4d23c
DL
3732 ifp->name, group_str, source_str,
3733 src->source_query_retransmit_count);
d62a17ae 3734
dda4d23c 3735 } /* scan group sources */
18adcff1 3736 } /* scan igmp groups */
dda4d23c 3737 } /* scan interfaces */
12e41d03
DL
3738}
3739
256392eb 3740static void pim_show_bsr(struct pim_instance *pim,
3741 struct vty *vty,
3742 bool uj)
3743{
3744 char uptime[10];
3745 char last_bsm_seen[10];
3746 time_t now;
3747 char bsr_state[20];
3748 char bsr_str[PREFIX_STRLEN];
3749 json_object *json = NULL;
3750
256392eb 3751 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) {
fbd74c7d 3752 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
256392eb 3753 pim_time_uptime(uptime, sizeof(uptime),
3754 pim->global_scope.current_bsr_first_ts);
3755 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3756 pim->global_scope.current_bsr_last_ts);
3757 }
3758
3759 else {
3760 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr,
3761 bsr_str, sizeof(bsr_str));
3762 now = pim_time_monotonic_sec();
3763 pim_time_uptime(uptime, sizeof(uptime),
3764 (now - pim->global_scope.current_bsr_first_ts));
3765 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3766 now - pim->global_scope.current_bsr_last_ts);
3767 }
3768
3769 switch (pim->global_scope.state) {
3770 case NO_INFO:
fbd74c7d 3771 strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
256392eb 3772 break;
3773 case ACCEPT_ANY:
fbd74c7d 3774 strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
256392eb 3775 break;
3776 case ACCEPT_PREFERRED:
fbd74c7d 3777 strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
256392eb 3778 break;
3779 default:
fbd74c7d 3780 strlcpy(bsr_state, "", sizeof(bsr_state));
256392eb 3781 }
3782
3783 if (uj) {
3784 json = json_object_new_object();
3785 json_object_string_add(json, "bsr", bsr_str);
3786 json_object_int_add(json, "priority",
3787 pim->global_scope.current_bsr_prio);
a5f610e4 3788 json_object_int_add(json, "fragmentTag",
256392eb 3789 pim->global_scope.bsm_frag_tag);
3790 json_object_string_add(json, "state", bsr_state);
3791 json_object_string_add(json, "upTime", uptime);
a5f610e4 3792 json_object_string_add(json, "lastBsmSeen", last_bsm_seen);
256392eb 3793 }
3794
3795 else {
36afe486 3796 vty_out(vty, "PIMv2 Bootstrap information\n");
256392eb 3797 vty_out(vty, "Current preferred BSR address: %s\n", bsr_str);
3798 vty_out(vty,
3799 "Priority Fragment-Tag State UpTime\n");
3800 vty_out(vty, " %-12d %-12d %-13s %7s\n",
3801 pim->global_scope.current_bsr_prio,
3802 pim->global_scope.bsm_frag_tag,
3803 bsr_state,
3804 uptime);
3805 vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
3806 }
3807
3757f964
DA
3808 if (uj)
3809 vty_json(vty, json);
256392eb 3810}
3811
c68ba0d7 3812static void clear_igmp_interfaces(struct pim_instance *pim)
12e41d03 3813{
d62a17ae 3814 struct interface *ifp;
12e41d03 3815
451fda4f 3816 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 3817 pim_if_addr_del_all_igmp(ifp);
12e41d03 3818
451fda4f 3819 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 3820 pim_if_addr_add_all(ifp);
12e41d03
DL
3821}
3822
c68ba0d7 3823static void clear_pim_interfaces(struct pim_instance *pim)
12e41d03 3824{
d62a17ae 3825 struct interface *ifp;
12e41d03 3826
451fda4f 3827 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3828 if (ifp->info) {
3829 pim_neighbor_delete_all(ifp, "interface cleared");
3830 }
3831 }
12e41d03
DL
3832}
3833
c68ba0d7 3834static void clear_interfaces(struct pim_instance *pim)
12e41d03 3835{
c68ba0d7
DS
3836 clear_igmp_interfaces(pim);
3837 clear_pim_interfaces(pim);
12e41d03
DL
3838}
3839
521c5b9d
MS
3840#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3841 pim_ifp = ifp->info; \
3842 if (!pim_ifp) { \
3843 vty_out(vty, \
21b3e44e 3844 "%% Enable PIM and/or IGMP on this interface first\n"); \
521c5b9d 3845 return CMD_WARNING_CONFIG_FAILED; \
21b3e44e
QY
3846 }
3847
e2809e61
RZ
3848/**
3849 * Compatibility function to keep the legacy mesh group CLI behavior:
3850 * Delete group when there are no more configurations in it.
3851 *
3852 * NOTE:
3853 * Don't forget to call `nb_cli_apply_changes` after this.
3854 */
3855static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
3856 const char *gname)
3857{
3858 const char *vrfname;
3859 char xpath_value[XPATH_MAXLEN];
3860 char xpath_member_value[XPATH_MAXLEN];
3861 const struct lyd_node *member_dnode;
3862
3863 vrfname = pim_cli_get_vrf_name(vty);
3864 if (vrfname == NULL)
3865 return;
3866
3867 /* Get mesh group base XPath. */
3868 snprintf(xpath_value, sizeof(xpath_value),
698f4147 3869 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
3870 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
3871 /* Group must exists, otherwise just quit. */
3872 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
3873 return;
3874
3875 /* Group members check: */
3876 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
3877 strlcat(xpath_member_value, "/members", sizeof(xpath_member_value));
3878 if (yang_dnode_exists(vty->candidate_config->dnode,
3879 xpath_member_value)) {
3880 member_dnode = yang_dnode_get(vty->candidate_config->dnode,
3881 xpath_member_value);
46877489 3882 if (!member_dnode || !yang_is_last_list_dnode(member_dnode))
e2809e61
RZ
3883 return;
3884 }
3885
3886 /* Source address check: */
3887 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
3888 strlcat(xpath_member_value, "/source", sizeof(xpath_member_value));
3889 if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value))
3890 return;
3891
3892 /* No configurations found: delete it. */
3893 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
3894}
3895
12e41d03
DL
3896DEFUN (clear_ip_interfaces,
3897 clear_ip_interfaces_cmd,
20a7e5fd 3898 "clear ip interfaces [vrf NAME]",
12e41d03
DL
3899 CLEAR_STR
3900 IP_STR
c68ba0d7
DS
3901 "Reset interfaces\n"
3902 VRF_CMD_HELP_STR)
12e41d03 3903{
c68ba0d7
DS
3904 int idx = 2;
3905 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3906
3907 if (!vrf)
3908 return CMD_WARNING;
3909
3910 clear_interfaces(vrf->info);
12e41d03 3911
d62a17ae 3912 return CMD_SUCCESS;
12e41d03
DL
3913}
3914
3915DEFUN (clear_ip_igmp_interfaces,
3916 clear_ip_igmp_interfaces_cmd,
20a7e5fd 3917 "clear ip igmp [vrf NAME] interfaces",
12e41d03
DL
3918 CLEAR_STR
3919 IP_STR
3920 CLEAR_IP_IGMP_STR
c68ba0d7 3921 VRF_CMD_HELP_STR
12e41d03
DL
3922 "Reset IGMP interfaces\n")
3923{
c68ba0d7
DS
3924 int idx = 2;
3925 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3926
3927 if (!vrf)
3928 return CMD_WARNING;
3929
3930 clear_igmp_interfaces(vrf->info);
12e41d03 3931
d62a17ae 3932 return CMD_SUCCESS;
12e41d03
DL
3933}
3934
415f6350 3935DEFUN (clear_ip_pim_statistics,
3936 clear_ip_pim_statistics_cmd,
3937 "clear ip pim statistics [vrf NAME]",
3938 CLEAR_STR
3939 IP_STR
3940 CLEAR_IP_PIM_STR
3941 VRF_CMD_HELP_STR
3942 "Reset PIM statistics\n")
3943{
3944 int idx = 2;
3945 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3946
3947 if (!vrf)
3948 return CMD_WARNING;
3949
3950 clear_pim_statistics(vrf->info);
3951 return CMD_SUCCESS;
3952}
3953
4a5e6e74 3954static void clear_mroute(struct pim_instance *pim)
3955{
3956 struct pim_upstream *up;
3957 struct interface *ifp;
3958
3959 /* scan interfaces */
3960 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3961 struct pim_interface *pim_ifp = ifp->info;
4a5e6e74 3962 struct pim_ifchannel *ch;
3963
3964 if (!pim_ifp)
3965 continue;
3966
3967 /* deleting all ifchannels */
3968 while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
3969 ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
3970
3971 pim_ifchannel_delete(ch);
3972 }
3973
5a46a3de 3974#if PIM_IPV == 4
4a5e6e74 3975 /* clean up all igmp groups */
5a46a3de 3976 struct gm_group *grp;
4a5e6e74 3977
18adcff1
SG
3978 if (pim_ifp->gm_group_list) {
3979 while (pim_ifp->gm_group_list->count) {
3980 grp = listnode_head(pim_ifp->gm_group_list);
dda4d23c 3981 igmp_group_delete(grp);
4a5e6e74 3982 }
4a5e6e74 3983 }
5a46a3de 3984#endif
4a5e6e74 3985 }
3986
3987 /* clean up all upstreams*/
521c5b9d 3988 while ((up = rb_pim_upstream_first(&pim->upstream_head)))
5e81f5dd 3989 pim_upstream_del(pim, up, __func__);
521c5b9d 3990
4a5e6e74 3991}
3992
12e41d03
DL
3993DEFUN (clear_ip_mroute,
3994 clear_ip_mroute_cmd,
20a7e5fd 3995 "clear ip mroute [vrf NAME]",
12e41d03
DL
3996 CLEAR_STR
3997 IP_STR
c68ba0d7
DS
3998 "Reset multicast routes\n"
3999 VRF_CMD_HELP_STR)
12e41d03 4000{
c68ba0d7
DS
4001 int idx = 2;
4002 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4003
4004 if (!vrf)
4005 return CMD_WARNING;
4006
4a5e6e74 4007 clear_mroute(vrf->info);
12e41d03 4008
d62a17ae 4009 return CMD_SUCCESS;
12e41d03
DL
4010}
4011
4012DEFUN (clear_ip_pim_interfaces,
4013 clear_ip_pim_interfaces_cmd,
20a7e5fd 4014 "clear ip pim [vrf NAME] interfaces",
12e41d03
DL
4015 CLEAR_STR
4016 IP_STR
4017 CLEAR_IP_PIM_STR
c68ba0d7 4018 VRF_CMD_HELP_STR
12e41d03
DL
4019 "Reset PIM interfaces\n")
4020{
c68ba0d7
DS
4021 int idx = 2;
4022 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4023
4024 if (!vrf)
4025 return CMD_WARNING;
4026
4027 clear_pim_interfaces(vrf->info);
12e41d03 4028
d62a17ae 4029 return CMD_SUCCESS;
12e41d03
DL
4030}
4031
39438188
CS
4032DEFUN (clear_ip_pim_interface_traffic,
4033 clear_ip_pim_interface_traffic_cmd,
20a7e5fd 4034 "clear ip pim [vrf NAME] interface traffic",
39438188
CS
4035 "Reset functions\n"
4036 "IP information\n"
4037 "PIM clear commands\n"
c68ba0d7 4038 VRF_CMD_HELP_STR
39438188
CS
4039 "Reset PIM interfaces\n"
4040 "Reset Protocol Packet counters\n")
4041{
c68ba0d7
DS
4042 int idx = 2;
4043 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 4044 struct interface *ifp = NULL;
4045 struct pim_interface *pim_ifp = NULL;
4046
c68ba0d7
DS
4047 if (!vrf)
4048 return CMD_WARNING;
4049
451fda4f 4050 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 4051 pim_ifp = ifp->info;
4052
4053 if (!pim_ifp)
4054 continue;
4055
4056 pim_ifp->pim_ifstat_hello_recv = 0;
4057 pim_ifp->pim_ifstat_hello_sent = 0;
4058 pim_ifp->pim_ifstat_join_recv = 0;
4059 pim_ifp->pim_ifstat_join_send = 0;
4060 pim_ifp->pim_ifstat_prune_recv = 0;
4061 pim_ifp->pim_ifstat_prune_send = 0;
4062 pim_ifp->pim_ifstat_reg_recv = 0;
4063 pim_ifp->pim_ifstat_reg_send = 0;
4064 pim_ifp->pim_ifstat_reg_stop_recv = 0;
4065 pim_ifp->pim_ifstat_reg_stop_send = 0;
4066 pim_ifp->pim_ifstat_assert_recv = 0;
4067 pim_ifp->pim_ifstat_assert_send = 0;
5164ad1e 4068 pim_ifp->pim_ifstat_bsm_rx = 0;
4069 pim_ifp->pim_ifstat_bsm_tx = 0;
f2058cb4
DA
4070 pim_ifp->igmp_ifstat_joins_sent = 0;
4071 pim_ifp->igmp_ifstat_joins_failed = 0;
3e5d8665 4072 pim_ifp->igmp_peak_group_count = 0;
d62a17ae 4073 }
39438188 4074
d62a17ae 4075 return CMD_SUCCESS;
39438188
CS
4076}
4077
12e41d03
DL
4078DEFUN (clear_ip_pim_oil,
4079 clear_ip_pim_oil_cmd,
20a7e5fd 4080 "clear ip pim [vrf NAME] oil",
12e41d03
DL
4081 CLEAR_STR
4082 IP_STR
4083 CLEAR_IP_PIM_STR
c68ba0d7 4084 VRF_CMD_HELP_STR
12e41d03
DL
4085 "Rescan PIM OIL (output interface list)\n")
4086{
c68ba0d7
DS
4087 int idx = 2;
4088 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4089
4090 if (!vrf)
4091 return CMD_WARNING;
4092
4093 pim_scan_oil(vrf->info);
12e41d03 4094
d62a17ae 4095 return CMD_SUCCESS;
12e41d03
DL
4096}
4097
e7016ceb 4098DEFUN (clear_ip_pim_bsr_db,
4099 clear_ip_pim_bsr_db_cmd,
4100 "clear ip pim [vrf NAME] bsr-data",
4101 CLEAR_STR
4102 IP_STR
4103 CLEAR_IP_PIM_STR
4104 VRF_CMD_HELP_STR
4105 "Reset pim bsr data\n")
4106{
4107 int idx = 2;
4108 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4109
4110 if (!vrf)
4111 return CMD_WARNING;
4112
b09bd804 4113 pim_bsm_clear(vrf->info);
e7016ceb 4114
4115 return CMD_SUCCESS;
4116}
4117
12e41d03
DL
4118DEFUN (show_ip_igmp_interface,
4119 show_ip_igmp_interface_cmd,
20a7e5fd 4120 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
4121 SHOW_STR
4122 IP_STR
4123 IGMP_STR
c68ba0d7 4124 VRF_CMD_HELP_STR
a268493f 4125 "IGMP interface information\n"
9b91bb50 4126 "Detailed output\n"
a268493f 4127 "interface name\n"
f5da2cc2 4128 JSON_STR)
12e41d03 4129{
c68ba0d7
DS
4130 int idx = 2;
4131 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4132 bool uj = use_json(argc, argv);
c68ba0d7
DS
4133
4134 if (!vrf)
4135 return CMD_WARNING;
72e81cf4 4136
d62a17ae 4137 if (argv_find(argv, argc, "detail", &idx)
4138 || argv_find(argv, argc, "WORD", &idx))
64c86530 4139 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 4140 else
64c86530 4141 igmp_show_interfaces(vrf->info, vty, uj);
12e41d03 4142
d62a17ae 4143 return CMD_SUCCESS;
12e41d03
DL
4144}
4145
a25de56b
DS
4146DEFUN (show_ip_igmp_interface_vrf_all,
4147 show_ip_igmp_interface_vrf_all_cmd,
4148 "show ip igmp vrf all interface [detail|WORD] [json]",
4149 SHOW_STR
4150 IP_STR
4151 IGMP_STR
4152 VRF_CMD_HELP_STR
4153 "IGMP interface information\n"
4154 "Detailed output\n"
4155 "interface name\n"
f5da2cc2 4156 JSON_STR)
a25de56b
DS
4157{
4158 int idx = 2;
9f049418 4159 bool uj = use_json(argc, argv);
a25de56b
DS
4160 struct vrf *vrf;
4161 bool first = true;
4162
4163 if (uj)
4164 vty_out(vty, "{ ");
a2addae8 4165 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4166 if (uj) {
4167 if (!first)
4168 vty_out(vty, ", ");
4169 vty_out(vty, " \"%s\": ", vrf->name);
4170 first = false;
4171 } else
4172 vty_out(vty, "VRF: %s\n", vrf->name);
4173 if (argv_find(argv, argc, "detail", &idx)
4174 || argv_find(argv, argc, "WORD", &idx))
4175 igmp_show_interfaces_single(vrf->info, vty,
4176 argv[idx]->arg, uj);
4177 else
4178 igmp_show_interfaces(vrf->info, vty, uj);
4179 }
4180 if (uj)
4181 vty_out(vty, "}\n");
4182
4183 return CMD_SUCCESS;
4184}
4185
12e41d03
DL
4186DEFUN (show_ip_igmp_join,
4187 show_ip_igmp_join_cmd,
85c82866 4188 "show ip igmp [vrf NAME] join [json]",
12e41d03
DL
4189 SHOW_STR
4190 IP_STR
4191 IGMP_STR
c68ba0d7 4192 VRF_CMD_HELP_STR
85c82866 4193 "IGMP static join information\n"
4194 JSON_STR)
12e41d03 4195{
c68ba0d7
DS
4196 int idx = 2;
4197 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
85c82866 4198 bool uj = use_json(argc, argv);
c68ba0d7
DS
4199
4200 if (!vrf)
4201 return CMD_WARNING;
4202
85c82866 4203 igmp_show_interface_join(vrf->info, vty, uj);
12e41d03 4204
d62a17ae 4205 return CMD_SUCCESS;
12e41d03
DL
4206}
4207
a25de56b
DS
4208DEFUN (show_ip_igmp_join_vrf_all,
4209 show_ip_igmp_join_vrf_all_cmd,
85c82866 4210 "show ip igmp vrf all join [json]",
a25de56b
DS
4211 SHOW_STR
4212 IP_STR
4213 IGMP_STR
4214 VRF_CMD_HELP_STR
85c82866 4215 "IGMP static join information\n"
4216 JSON_STR)
a25de56b 4217{
9f049418 4218 bool uj = use_json(argc, argv);
a25de56b
DS
4219 struct vrf *vrf;
4220 bool first = true;
4221
4222 if (uj)
4223 vty_out(vty, "{ ");
a2addae8 4224 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4225 if (uj) {
4226 if (!first)
4227 vty_out(vty, ", ");
4228 vty_out(vty, " \"%s\": ", vrf->name);
4229 first = false;
4230 } else
4231 vty_out(vty, "VRF: %s\n", vrf->name);
85c82866 4232 igmp_show_interface_join(vrf->info, vty, uj);
a25de56b
DS
4233 }
4234 if (uj)
4235 vty_out(vty, "}\n");
4236
4237 return CMD_SUCCESS;
4238}
4239
12e41d03
DL
4240DEFUN (show_ip_igmp_groups,
4241 show_ip_igmp_groups_cmd,
20a7e5fd 4242 "show ip igmp [vrf NAME] groups [json]",
12e41d03
DL
4243 SHOW_STR
4244 IP_STR
4245 IGMP_STR
c68ba0d7 4246 VRF_CMD_HELP_STR
9b91bb50 4247 IGMP_GROUP_STR
f5da2cc2 4248 JSON_STR)
12e41d03 4249{
c68ba0d7
DS
4250 int idx = 2;
4251 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4252 bool uj = use_json(argc, argv);
c68ba0d7
DS
4253
4254 if (!vrf)
4255 return CMD_WARNING;
4256
64c86530 4257 igmp_show_groups(vrf->info, vty, uj);
12e41d03 4258
d62a17ae 4259 return CMD_SUCCESS;
12e41d03
DL
4260}
4261
a25de56b
DS
4262DEFUN (show_ip_igmp_groups_vrf_all,
4263 show_ip_igmp_groups_vrf_all_cmd,
4264 "show ip igmp vrf all groups [json]",
4265 SHOW_STR
4266 IP_STR
4267 IGMP_STR
4268 VRF_CMD_HELP_STR
4269 IGMP_GROUP_STR
f5da2cc2 4270 JSON_STR)
a25de56b 4271{
9f049418 4272 bool uj = use_json(argc, argv);
a25de56b
DS
4273 struct vrf *vrf;
4274 bool first = true;
4275
4276 if (uj)
4277 vty_out(vty, "{ ");
a2addae8 4278 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4279 if (uj) {
4280 if (!first)
4281 vty_out(vty, ", ");
4282 vty_out(vty, " \"%s\": ", vrf->name);
4283 first = false;
4284 } else
4285 vty_out(vty, "VRF: %s\n", vrf->name);
4286 igmp_show_groups(vrf->info, vty, uj);
4287 }
4288 if (uj)
4289 vty_out(vty, "}\n");
4290
4291 return CMD_SUCCESS;
4292}
4293
12e41d03
DL
4294DEFUN (show_ip_igmp_groups_retransmissions,
4295 show_ip_igmp_groups_retransmissions_cmd,
20a7e5fd 4296 "show ip igmp [vrf NAME] groups retransmissions",
12e41d03
DL
4297 SHOW_STR
4298 IP_STR
4299 IGMP_STR
c68ba0d7 4300 VRF_CMD_HELP_STR
12e41d03
DL
4301 IGMP_GROUP_STR
4302 "IGMP group retransmissions\n")
4303{
c68ba0d7
DS
4304 int idx = 2;
4305 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4306
4307 if (!vrf)
4308 return CMD_WARNING;
4309
64c86530 4310 igmp_show_group_retransmission(vrf->info, vty);
12e41d03 4311
d62a17ae 4312 return CMD_SUCCESS;
12e41d03
DL
4313}
4314
12e41d03
DL
4315DEFUN (show_ip_igmp_sources,
4316 show_ip_igmp_sources_cmd,
4527b70a 4317 "show ip igmp [vrf NAME] sources [json]",
12e41d03
DL
4318 SHOW_STR
4319 IP_STR
4320 IGMP_STR
c68ba0d7 4321 VRF_CMD_HELP_STR
4527b70a
SG
4322 IGMP_SOURCE_STR
4323 JSON_STR)
12e41d03 4324{
c68ba0d7
DS
4325 int idx = 2;
4326 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4327
4328 if (!vrf)
4329 return CMD_WARNING;
4330
4527b70a 4331 igmp_show_sources(vrf->info, vty, use_json(argc, argv));
12e41d03 4332
d62a17ae 4333 return CMD_SUCCESS;
12e41d03
DL
4334}
4335
4336DEFUN (show_ip_igmp_sources_retransmissions,
4337 show_ip_igmp_sources_retransmissions_cmd,
20a7e5fd 4338 "show ip igmp [vrf NAME] sources retransmissions",
12e41d03
DL
4339 SHOW_STR
4340 IP_STR
4341 IGMP_STR
c68ba0d7 4342 VRF_CMD_HELP_STR
12e41d03
DL
4343 IGMP_SOURCE_STR
4344 "IGMP source retransmissions\n")
4345{
c68ba0d7
DS
4346 int idx = 2;
4347 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4348
4349 if (!vrf)
4350 return CMD_WARNING;
4351
64c86530 4352 igmp_show_source_retransmission(vrf->info, vty);
12e41d03 4353
d62a17ae 4354 return CMD_SUCCESS;
12e41d03
DL
4355}
4356
21313cbf
MS
4357DEFUN (show_ip_igmp_statistics,
4358 show_ip_igmp_statistics_cmd,
4359 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4360 SHOW_STR
4361 IP_STR
4362 IGMP_STR
4363 VRF_CMD_HELP_STR
4364 "IGMP statistics\n"
4365 "interface\n"
4366 "IGMP interface\n"
4367 JSON_STR)
4368{
4369 int idx = 2;
4370 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4371 bool uj = use_json(argc, argv);
21313cbf
MS
4372
4373 if (!vrf)
4374 return CMD_WARNING;
4375
4376 if (argv_find(argv, argc, "WORD", &idx))
4377 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
4378 else
4379 igmp_show_statistics(vrf->info, vty, NULL, uj);
4380
4381 return CMD_SUCCESS;
4382}
4383
17823cdd
DS
4384DEFUN (show_ip_pim_mlag_summary,
4385 show_ip_pim_mlag_summary_cmd,
4386 "show ip pim mlag summary [json]",
4387 SHOW_STR
4388 IP_STR
4389 PIM_STR
4390 "MLAG\n"
4391 "status and stats\n"
4392 JSON_STR)
4393{
4394 bool uj = use_json(argc, argv);
4395 char role_buf[MLAG_ROLE_STRSIZE];
4396 char addr_buf[INET_ADDRSTRLEN];
4397
4398 if (uj) {
4399 json_object *json = NULL;
4400 json_object *json_stat = NULL;
4401
4402 json = json_object_new_object();
4403 if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
4404 json_object_boolean_true_add(json, "mlagConnUp");
4405 if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
4406 json_object_boolean_true_add(json, "mlagPeerConnUp");
4407 if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
4408 json_object_boolean_true_add(json, "mlagPeerZebraUp");
4409 json_object_string_add(json, "mlagRole",
521c5b9d
MS
4410 mlag_role2str(router->mlag_role,
4411 role_buf, sizeof(role_buf)));
17823cdd 4412 inet_ntop(AF_INET, &router->local_vtep_ip,
521c5b9d 4413 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
4414 json_object_string_add(json, "localVtepIp", addr_buf);
4415 inet_ntop(AF_INET, &router->anycast_vtep_ip,
521c5b9d 4416 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
4417 json_object_string_add(json, "anycastVtepIp", addr_buf);
4418 json_object_string_add(json, "peerlinkRif",
521c5b9d 4419 router->peerlink_rif);
17823cdd
DS
4420
4421 json_stat = json_object_new_object();
4422 json_object_int_add(json_stat, "mlagConnFlaps",
521c5b9d 4423 router->mlag_stats.mlagd_session_downs);
17823cdd 4424 json_object_int_add(json_stat, "mlagPeerConnFlaps",
521c5b9d 4425 router->mlag_stats.peer_session_downs);
17823cdd 4426 json_object_int_add(json_stat, "mlagPeerZebraFlaps",
521c5b9d 4427 router->mlag_stats.peer_zebra_downs);
17823cdd 4428 json_object_int_add(json_stat, "mrouteAddRx",
521c5b9d 4429 router->mlag_stats.msg.mroute_add_rx);
17823cdd 4430 json_object_int_add(json_stat, "mrouteAddTx",
521c5b9d 4431 router->mlag_stats.msg.mroute_add_tx);
17823cdd 4432 json_object_int_add(json_stat, "mrouteDelRx",
521c5b9d 4433 router->mlag_stats.msg.mroute_del_rx);
17823cdd 4434 json_object_int_add(json_stat, "mrouteDelTx",
521c5b9d 4435 router->mlag_stats.msg.mroute_del_tx);
17823cdd 4436 json_object_int_add(json_stat, "mlagStatusUpdates",
521c5b9d 4437 router->mlag_stats.msg.mlag_status_updates);
17823cdd 4438 json_object_int_add(json_stat, "peerZebraStatusUpdates",
521c5b9d 4439 router->mlag_stats.msg.peer_zebra_status_updates);
17823cdd 4440 json_object_int_add(json_stat, "pimStatusUpdates",
521c5b9d 4441 router->mlag_stats.msg.pim_status_updates);
17823cdd 4442 json_object_int_add(json_stat, "vxlanUpdates",
521c5b9d 4443 router->mlag_stats.msg.vxlan_updates);
17823cdd
DS
4444 json_object_object_add(json, "connStats", json_stat);
4445
3757f964 4446 vty_json(vty, json);
17823cdd
DS
4447 return CMD_SUCCESS;
4448 }
4449
4450 vty_out(vty, "MLAG daemon connection: %s\n",
4451 (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
521c5b9d 4452 ? "up" : "down");
17823cdd
DS
4453 vty_out(vty, "MLAG peer state: %s\n",
4454 (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
521c5b9d 4455 ? "up" : "down");
17823cdd
DS
4456 vty_out(vty, "Zebra peer state: %s\n",
4457 (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
521c5b9d 4458 ? "up" : "down");
17823cdd
DS
4459 vty_out(vty, "MLAG role: %s\n",
4460 mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
4461 inet_ntop(AF_INET, &router->local_vtep_ip,
521c5b9d 4462 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
4463 vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
4464 inet_ntop(AF_INET, &router->anycast_vtep_ip,
521c5b9d 4465 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
4466 vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
4467 vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
4468 vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
521c5b9d
MS
4469 router->mlag_stats.mlagd_session_downs,
4470 router->mlag_stats.peer_session_downs,
4471 router->mlag_stats.peer_zebra_downs);
17823cdd
DS
4472 vty_out(vty, "Message Statistics:\n");
4473 vty_out(vty, " mroute adds: rx: %d, tx: %d\n",
521c5b9d
MS
4474 router->mlag_stats.msg.mroute_add_rx,
4475 router->mlag_stats.msg.mroute_add_tx);
17823cdd 4476 vty_out(vty, " mroute dels: rx: %d, tx: %d\n",
521c5b9d
MS
4477 router->mlag_stats.msg.mroute_del_rx,
4478 router->mlag_stats.msg.mroute_del_tx);
17823cdd 4479 vty_out(vty, " peer zebra status updates: %d\n",
521c5b9d 4480 router->mlag_stats.msg.peer_zebra_status_updates);
17823cdd 4481 vty_out(vty, " PIM status updates: %d\n",
521c5b9d 4482 router->mlag_stats.msg.pim_status_updates);
17823cdd 4483 vty_out(vty, " VxLAN updates: %d\n",
521c5b9d 4484 router->mlag_stats.msg.vxlan_updates);
17823cdd
DS
4485
4486 return CMD_SUCCESS;
4487}
4488
12e41d03
DL
4489DEFUN (show_ip_pim_assert,
4490 show_ip_pim_assert_cmd,
20a7e5fd 4491 "show ip pim [vrf NAME] assert",
12e41d03
DL
4492 SHOW_STR
4493 IP_STR
4494 PIM_STR
c68ba0d7 4495 VRF_CMD_HELP_STR
12e41d03
DL
4496 "PIM interface assert\n")
4497{
c68ba0d7
DS
4498 int idx = 2;
4499 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4500
4501 if (!vrf)
4502 return CMD_WARNING;
4503
64c86530 4504 pim_show_assert(vrf->info, vty);
12e41d03 4505
d62a17ae 4506 return CMD_SUCCESS;
12e41d03
DL
4507}
4508
4509DEFUN (show_ip_pim_assert_internal,
4510 show_ip_pim_assert_internal_cmd,
20a7e5fd 4511 "show ip pim [vrf NAME] assert-internal",
12e41d03
DL
4512 SHOW_STR
4513 IP_STR
4514 PIM_STR
c68ba0d7 4515 VRF_CMD_HELP_STR
12e41d03
DL
4516 "PIM interface internal assert state\n")
4517{
c68ba0d7
DS
4518 int idx = 2;
4519 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4520
4521 if (!vrf)
4522 return CMD_WARNING;
4523
64c86530 4524 pim_show_assert_internal(vrf->info, vty);
12e41d03 4525
d62a17ae 4526 return CMD_SUCCESS;
12e41d03
DL
4527}
4528
4529DEFUN (show_ip_pim_assert_metric,
4530 show_ip_pim_assert_metric_cmd,
20a7e5fd 4531 "show ip pim [vrf NAME] assert-metric",
12e41d03
DL
4532 SHOW_STR
4533 IP_STR
4534 PIM_STR
c68ba0d7 4535 VRF_CMD_HELP_STR
12e41d03
DL
4536 "PIM interface assert metric\n")
4537{
c68ba0d7
DS
4538 int idx = 2;
4539 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4540
4541 if (!vrf)
4542 return CMD_WARNING;
4543
64c86530 4544 pim_show_assert_metric(vrf->info, vty);
12e41d03 4545
d62a17ae 4546 return CMD_SUCCESS;
12e41d03
DL
4547}
4548
4549DEFUN (show_ip_pim_assert_winner_metric,
4550 show_ip_pim_assert_winner_metric_cmd,
20a7e5fd 4551 "show ip pim [vrf NAME] assert-winner-metric",
12e41d03
DL
4552 SHOW_STR
4553 IP_STR
4554 PIM_STR
c68ba0d7 4555 VRF_CMD_HELP_STR
12e41d03
DL
4556 "PIM interface assert winner metric\n")
4557{
c68ba0d7
DS
4558 int idx = 2;
4559 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4560
4561 if (!vrf)
4562 return CMD_WARNING;
4563
64c86530 4564 pim_show_assert_winner_metric(vrf->info, vty);
12e41d03 4565
d62a17ae 4566 return CMD_SUCCESS;
12e41d03
DL
4567}
4568
12e41d03
DL
4569DEFUN (show_ip_pim_interface,
4570 show_ip_pim_interface_cmd,
17823cdd 4571 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
4572 SHOW_STR
4573 IP_STR
4574 PIM_STR
17823cdd 4575 "MLAG\n"
c68ba0d7 4576 VRF_CMD_HELP_STR
a268493f 4577 "PIM interface information\n"
9b91bb50 4578 "Detailed output\n"
a268493f 4579 "interface name\n"
f5da2cc2 4580 JSON_STR)
12e41d03 4581{
c68ba0d7
DS
4582 int idx = 2;
4583 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4584 bool uj = use_json(argc, argv);
17823cdd 4585 bool mlag = false;
c68ba0d7
DS
4586
4587 if (!vrf)
4588 return CMD_WARNING;
72e81cf4 4589
17823cdd
DS
4590 if (argv_find(argv, argc, "mlag", &idx))
4591 mlag = true;
4592
d62a17ae 4593 if (argv_find(argv, argc, "WORD", &idx)
4594 || argv_find(argv, argc, "detail", &idx))
17823cdd
DS
4595 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, mlag,
4596 uj);
d62a17ae 4597 else
17823cdd 4598 pim_show_interfaces(vrf->info, vty, mlag, uj);
12e41d03 4599
d62a17ae 4600 return CMD_SUCCESS;
12e41d03
DL
4601}
4602
a25de56b
DS
4603DEFUN (show_ip_pim_interface_vrf_all,
4604 show_ip_pim_interface_vrf_all_cmd,
17823cdd 4605 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
a25de56b
DS
4606 SHOW_STR
4607 IP_STR
4608 PIM_STR
17823cdd 4609 "MLAG\n"
a25de56b
DS
4610 VRF_CMD_HELP_STR
4611 "PIM interface information\n"
4612 "Detailed output\n"
4613 "interface name\n"
f5da2cc2 4614 JSON_STR)
a25de56b 4615{
17823cdd 4616 int idx = 2;
9f049418 4617 bool uj = use_json(argc, argv);
a25de56b
DS
4618 struct vrf *vrf;
4619 bool first = true;
17823cdd 4620 bool mlag = false;
a25de56b 4621
17823cdd
DS
4622 if (argv_find(argv, argc, "mlag", &idx))
4623 mlag = true;
4624
4625 idx = 6;
a25de56b
DS
4626 if (uj)
4627 vty_out(vty, "{ ");
a2addae8 4628 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4629 if (uj) {
4630 if (!first)
4631 vty_out(vty, ", ");
4632 vty_out(vty, " \"%s\": ", vrf->name);
4633 first = false;
4634 } else
4635 vty_out(vty, "VRF: %s\n", vrf->name);
4636 if (argv_find(argv, argc, "WORD", &idx)
4637 || argv_find(argv, argc, "detail", &idx))
4638 pim_show_interfaces_single(vrf->info, vty,
17823cdd 4639 argv[idx]->arg, mlag, uj);
a25de56b 4640 else
17823cdd 4641 pim_show_interfaces(vrf->info, vty, mlag, uj);
a25de56b
DS
4642 }
4643 if (uj)
4644 vty_out(vty, "}\n");
4645
4646 return CMD_SUCCESS;
4647}
4648
6de45bcc 4649DEFPY (show_ip_pim_join,
12e41d03 4650 show_ip_pim_join_cmd,
6de45bcc 4651 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
4652 SHOW_STR
4653 IP_STR
4654 PIM_STR
c68ba0d7 4655 VRF_CMD_HELP_STR
a957a05b 4656 "PIM interface join information\n"
6de45bcc
DS
4657 "The Source or Group\n"
4658 "The Group\n"
a957a05b 4659 JSON_STR)
12e41d03 4660{
6fff2cc6 4661 pim_sgaddr sg = {0};
6de45bcc
DS
4662 struct vrf *v;
4663 bool uj = !!json;
4664 struct pim_instance *pim;
c68ba0d7 4665
6de45bcc
DS
4666 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4667
4668 if (!v) {
4669 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 4670 return CMD_WARNING;
6de45bcc
DS
4671 }
4672 pim = pim_get_pim_instance(v->vrf_id);
4673
4674 if (!pim) {
4675 vty_out(vty, "%% Unable to find pim instance\n");
4676 return CMD_WARNING;
4677 }
4678
3a6290bd
DA
4679 if (s_or_g.s_addr != INADDR_ANY) {
4680 if (g.s_addr != INADDR_ANY) {
6de45bcc
DS
4681 sg.src = s_or_g;
4682 sg.grp = g;
4683 } else
4684 sg.grp = s_or_g;
4685 }
c68ba0d7 4686
6de45bcc 4687 pim_show_join(pim, vty, &sg, uj);
12e41d03 4688
d62a17ae 4689 return CMD_SUCCESS;
12e41d03
DL
4690}
4691
a25de56b
DS
4692DEFUN (show_ip_pim_join_vrf_all,
4693 show_ip_pim_join_vrf_all_cmd,
4694 "show ip pim vrf all join [json]",
4695 SHOW_STR
4696 IP_STR
4697 PIM_STR
4698 VRF_CMD_HELP_STR
4699 "PIM interface join information\n"
4700 JSON_STR)
4701{
6fff2cc6 4702 pim_sgaddr sg = {0};
9f049418 4703 bool uj = use_json(argc, argv);
a25de56b
DS
4704 struct vrf *vrf;
4705 bool first = true;
4706
4707 if (uj)
4708 vty_out(vty, "{ ");
a2addae8 4709 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4710 if (uj) {
4711 if (!first)
4712 vty_out(vty, ", ");
4713 vty_out(vty, " \"%s\": ", vrf->name);
4714 first = false;
4715 } else
4716 vty_out(vty, "VRF: %s\n", vrf->name);
6de45bcc 4717 pim_show_join(vrf->info, vty, &sg, uj);
a25de56b
DS
4718 }
4719 if (uj)
4720 vty_out(vty, "}\n");
4721
4722 return CMD_WARNING;
4723}
4724
87b7cd5b 4725static void pim_show_jp_agg_helper(struct vty *vty,
521c5b9d
MS
4726 struct interface *ifp,
4727 struct pim_neighbor *neigh,
4728 struct pim_upstream *up,
4729 int is_join)
87b7cd5b 4730{
87b7cd5b
AK
4731 char rpf_str[INET_ADDRSTRLEN];
4732
521c5b9d 4733 /* pius->address.s_addr */
87b7cd5b
AK
4734 pim_inet4_dump("<rpf?>", neigh->source_addr, rpf_str, sizeof(rpf_str));
4735
8e8be741
DL
4736 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %5s\n", ifp->name, rpf_str,
4737 &up->sg.src, &up->sg.grp, is_join ? "J" : "P");
87b7cd5b
AK
4738}
4739
4740static void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
4741{
4742 struct interface *ifp;
4743 struct pim_interface *pim_ifp;
4744 struct listnode *n_node;
4745 struct pim_neighbor *neigh;
4746 struct listnode *jag_node;
4747 struct pim_jp_agg_group *jag;
4748 struct listnode *js_node;
4749 struct pim_jp_sources *js;
4750
4751 vty_out(vty,
521c5b9d 4752 "Interface RPF Nbr Source Group State\n");
87b7cd5b
AK
4753
4754 FOR_ALL_INTERFACES (pim->vrf, ifp) {
4755 pim_ifp = ifp->info;
4756 if (!pim_ifp)
4757 continue;
4758
4759 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
521c5b9d 4760 n_node, neigh)) {
87b7cd5b 4761 for (ALL_LIST_ELEMENTS_RO(neigh->upstream_jp_agg,
521c5b9d 4762 jag_node, jag)) {
87b7cd5b 4763 for (ALL_LIST_ELEMENTS_RO(jag->sources,
521c5b9d 4764 js_node, js)) {
87b7cd5b 4765 pim_show_jp_agg_helper(vty,
521c5b9d
MS
4766 ifp, neigh, js->up,
4767 js->is_join);
87b7cd5b
AK
4768 }
4769 }
4770 }
4771 }
4772}
4773
4774DEFPY (show_ip_pim_jp_agg,
4775 show_ip_pim_jp_agg_cmd,
4776 "show ip pim [vrf NAME] jp-agg",
4777 SHOW_STR
4778 IP_STR
4779 PIM_STR
4780 VRF_CMD_HELP_STR
4781 "join prune aggregation list\n")
4782{
4783 struct vrf *v;
4784 struct pim_instance *pim;
4785
4786 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4787
4788 if (!v) {
4789 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4790 return CMD_WARNING;
4791 }
4792 pim = pim_get_pim_instance(v->vrf_id);
4793
4794 if (!pim) {
4795 vty_out(vty, "%% Unable to find pim instance\n");
4796 return CMD_WARNING;
4797 }
4798
4799 pim_show_jp_agg_list(pim, vty);
4800
4801 return CMD_SUCCESS;
4802}
4803
12e41d03
DL
4804DEFUN (show_ip_pim_local_membership,
4805 show_ip_pim_local_membership_cmd,
20a7e5fd 4806 "show ip pim [vrf NAME] local-membership [json]",
12e41d03
DL
4807 SHOW_STR
4808 IP_STR
4809 PIM_STR
c68ba0d7 4810 VRF_CMD_HELP_STR
a957a05b
DS
4811 "PIM interface local-membership\n"
4812 JSON_STR)
12e41d03 4813{
c68ba0d7
DS
4814 int idx = 2;
4815 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4816 bool uj = use_json(argc, argv);
c68ba0d7
DS
4817
4818 if (!vrf)
4819 return CMD_WARNING;
4820
64c86530 4821 pim_show_membership(vrf->info, vty, uj);
12e41d03 4822
d62a17ae 4823 return CMD_SUCCESS;
12e41d03
DL
4824}
4825
f80427e9 4826static void pim_show_mlag_up_entry_detail(struct vrf *vrf,
521c5b9d
MS
4827 struct vty *vty,
4828 struct pim_upstream *up,
4829 char *src_str, char *grp_str,
4830 json_object *json)
f80427e9
AK
4831{
4832 if (json) {
4833 json_object *json_row = NULL;
4834 json_object *own_list = NULL;
4835 json_object *json_group = NULL;
4836
4837
4838 json_object_object_get_ex(json, grp_str, &json_group);
4839 if (!json_group) {
4840 json_group = json_object_new_object();
4841 json_object_object_add(json, grp_str,
521c5b9d 4842 json_group);
f80427e9
AK
4843 }
4844
4845 json_row = json_object_new_object();
4846 json_object_string_add(json_row, "source", src_str);
4847 json_object_string_add(json_row, "group", grp_str);
4848
4849 own_list = json_object_new_array();
4850 if (pim_up_mlag_is_local(up))
4851 json_object_array_add(own_list,
521c5b9d 4852 json_object_new_string("local"));
f80427e9
AK
4853 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
4854 json_object_array_add(own_list,
521c5b9d 4855 json_object_new_string("peer"));
f80427e9
AK
4856 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
4857 json_object_array_add(
4858 own_list, json_object_new_string("Interface"));
4859 json_object_object_add(json_row, "owners", own_list);
4860
4861 json_object_int_add(json_row, "localCost",
521c5b9d 4862 pim_up_mlag_local_cost(up));
f80427e9 4863 json_object_int_add(json_row, "peerCost",
521c5b9d 4864 pim_up_mlag_peer_cost(up));
f80427e9
AK
4865 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
4866 json_object_boolean_false_add(json_row, "df");
4867 else
4868 json_object_boolean_true_add(json_row, "df");
4869 json_object_object_add(json_group, src_str, json_row);
4870 } else {
4871 char own_str[6];
4872
4873 own_str[0] = '\0';
4874 if (pim_up_mlag_is_local(up))
6c1b7a8c 4875 strlcat(own_str, "L", sizeof(own_str));
f80427e9 4876 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
6c1b7a8c 4877 strlcat(own_str, "P", sizeof(own_str));
f80427e9 4878 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
6c1b7a8c 4879 strlcat(own_str, "I", sizeof(own_str));
f80427e9
AK
4880 /* XXX - fixup, print paragraph output */
4881 vty_out(vty,
521c5b9d
MS
4882 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4883 src_str, grp_str, own_str,
4884 pim_up_mlag_local_cost(up),
4885 pim_up_mlag_peer_cost(up),
4886 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
4887 ? "n" : "y");
f80427e9
AK
4888 }
4889}
4890
4891static void pim_show_mlag_up_detail(struct vrf *vrf,
521c5b9d
MS
4892 struct vty *vty, const char *src_or_group,
4893 const char *group, bool uj)
f80427e9 4894{
8e8be741
DL
4895 char src_str[PIM_ADDRSTRLEN];
4896 char grp_str[PIM_ADDRSTRLEN];
f80427e9
AK
4897 struct pim_upstream *up;
4898 struct pim_instance *pim = vrf->info;
4899 json_object *json = NULL;
4900
4901 if (uj)
4902 json = json_object_new_object();
4903 else
4904 vty_out(vty,
4905 "Source Group Owner Local-cost Peer-cost DF\n");
4906
4907 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
4908 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
4909 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
4910 && !pim_up_mlag_is_local(up))
4911 continue;
4912
8e8be741
DL
4913 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
4914 snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
4915
f80427e9
AK
4916 /* XXX: strcmps are clearly inefficient. we should do uint comps
4917 * here instead.
4918 */
4919 if (group) {
4920 if (strcmp(src_str, src_or_group) ||
6c1b7a8c 4921 strcmp(grp_str, group))
f80427e9
AK
4922 continue;
4923 } else {
4924 if (strcmp(src_str, src_or_group) &&
6c1b7a8c 4925 strcmp(grp_str, src_or_group))
f80427e9
AK
4926 continue;
4927 }
4928 pim_show_mlag_up_entry_detail(vrf, vty, up,
6c1b7a8c 4929 src_str, grp_str, json);
f80427e9
AK
4930 }
4931
3757f964
DA
4932 if (uj)
4933 vty_json(vty, json);
f80427e9
AK
4934}
4935
4936static void pim_show_mlag_up_vrf(struct vrf *vrf, struct vty *vty, bool uj)
4937{
4938 json_object *json = NULL;
4939 json_object *json_row;
4940 struct pim_upstream *up;
f80427e9
AK
4941 struct pim_instance *pim = vrf->info;
4942 json_object *json_group = NULL;
4943
4944 if (uj) {
4945 json = json_object_new_object();
4946 } else {
4947 vty_out(vty,
4948 "Source Group Owner Local-cost Peer-cost DF\n");
4949 }
4950
4951 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
4952 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
4953 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
4954 && !pim_up_mlag_is_local(up))
4955 continue;
f80427e9 4956 if (uj) {
8e8be741
DL
4957 char src_str[PIM_ADDRSTRLEN];
4958 char grp_str[PIM_ADDRSTRLEN];
f80427e9
AK
4959 json_object *own_list = NULL;
4960
8e8be741
DL
4961 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
4962 &up->sg.grp);
4963 snprintfrr(src_str, sizeof(src_str), "%pPAs",
4964 &up->sg.src);
4965
f80427e9
AK
4966 json_object_object_get_ex(json, grp_str, &json_group);
4967 if (!json_group) {
4968 json_group = json_object_new_object();
4969 json_object_object_add(json, grp_str,
521c5b9d 4970 json_group);
f80427e9
AK
4971 }
4972
4973 json_row = json_object_new_object();
4974 json_object_string_add(json_row, "vrf", vrf->name);
4975 json_object_string_add(json_row, "source", src_str);
4976 json_object_string_add(json_row, "group", grp_str);
4977
4978 own_list = json_object_new_array();
4979 if (pim_up_mlag_is_local(up)) {
4980
4981 json_object_array_add(own_list,
521c5b9d
MS
4982 json_object_new_string(
4983 "local"));
f80427e9
AK
4984 }
4985 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)) {
4986 json_object_array_add(own_list,
521c5b9d
MS
4987 json_object_new_string(
4988 "peer"));
f80427e9
AK
4989 }
4990 json_object_object_add(json_row, "owners", own_list);
4991
4992 json_object_int_add(json_row, "localCost",
521c5b9d 4993 pim_up_mlag_local_cost(up));
f80427e9 4994 json_object_int_add(json_row, "peerCost",
521c5b9d 4995 pim_up_mlag_peer_cost(up));
f80427e9
AK
4996 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
4997 json_object_boolean_false_add(json_row, "df");
4998 else
4999 json_object_boolean_true_add(json_row, "df");
5000 json_object_object_add(json_group, src_str, json_row);
5001 } else {
5002 char own_str[6];
5003
5004 own_str[0] = '\0';
5005 if (pim_up_mlag_is_local(up))
6c1b7a8c 5006 strlcat(own_str, "L", sizeof(own_str));
f80427e9 5007 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
6c1b7a8c 5008 strlcat(own_str, "P", sizeof(own_str));
f80427e9 5009 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
6c1b7a8c 5010 strlcat(own_str, "I", sizeof(own_str));
f80427e9 5011 vty_out(vty,
8e8be741
DL
5012 "%-15pPAs %-15pPAs %-6s %-11u %-10u %2s\n",
5013 &up->sg.src, &up->sg.grp, own_str,
f80427e9
AK
5014 pim_up_mlag_local_cost(up),
5015 pim_up_mlag_peer_cost(up),
5016 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
521c5b9d 5017 ? "n" : "y");
f80427e9
AK
5018 }
5019 }
3757f964
DA
5020 if (uj)
5021 vty_json(vty, json);
f80427e9
AK
5022}
5023
5024static void pim_show_mlag_help_string(struct vty *vty, bool uj)
5025{
5026 if (!uj) {
5027 vty_out(vty, "Owner codes:\n");
5028 vty_out(vty,
3efd0893 5029 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
f80427e9
AK
5030 }
5031}
5032
5033
5034DEFUN(show_ip_pim_mlag_up, show_ip_pim_mlag_up_cmd,
5035 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
5036 SHOW_STR
5037 IP_STR
5038 PIM_STR
5039 VRF_CMD_HELP_STR
5040 "MLAG\n"
5041 "upstream\n"
5042 "Unicast or Multicast address\n"
5043 "Multicast address\n" JSON_STR)
5044{
5045 const char *src_or_group = NULL;
5046 const char *group = NULL;
5047 int idx = 2;
5048 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5049 bool uj = use_json(argc, argv);
5050
5051 if (!vrf || !vrf->info) {
5052 vty_out(vty, "%s: VRF or Info missing\n", __func__);
5053 return CMD_WARNING;
5054 }
5055
5056 if (uj)
5057 argc--;
5058
5059 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
5060 src_or_group = argv[idx]->arg;
5061 if (idx + 1 < argc)
5062 group = argv[idx + 1]->arg;
5063 }
5064
5065 pim_show_mlag_help_string(vty, uj);
5066
6c1b7a8c 5067 if (src_or_group)
f80427e9
AK
5068 pim_show_mlag_up_detail(vrf, vty, src_or_group, group, uj);
5069 else
5070 pim_show_mlag_up_vrf(vrf, vty, uj);
5071
5072 return CMD_SUCCESS;
5073}
5074
5075
5076DEFUN(show_ip_pim_mlag_up_vrf_all, show_ip_pim_mlag_up_vrf_all_cmd,
5077 "show ip pim vrf all mlag upstream [json]",
5078 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5079 "MLAG\n"
5080 "upstream\n" JSON_STR)
5081{
5082 struct vrf *vrf;
5083 bool uj = use_json(argc, argv);
5084
5085 pim_show_mlag_help_string(vty, uj);
5086 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5087 pim_show_mlag_up_vrf(vrf, vty, uj);
5088 }
5089
5090 return CMD_SUCCESS;
5091}
5092
12e41d03
DL
5093DEFUN (show_ip_pim_neighbor,
5094 show_ip_pim_neighbor_cmd,
20a7e5fd 5095 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
12e41d03
DL
5096 SHOW_STR
5097 IP_STR
5098 PIM_STR
c68ba0d7 5099 VRF_CMD_HELP_STR
a268493f 5100 "PIM neighbor information\n"
9b91bb50 5101 "Detailed output\n"
a268493f 5102 "Name of interface or neighbor\n"
f5da2cc2 5103 JSON_STR)
12e41d03 5104{
c68ba0d7
DS
5105 int idx = 2;
5106 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5107 bool uj = use_json(argc, argv);
c68ba0d7
DS
5108
5109 if (!vrf)
5110 return CMD_WARNING;
72e81cf4 5111
d62a17ae 5112 if (argv_find(argv, argc, "detail", &idx)
5113 || argv_find(argv, argc, "WORD", &idx))
64c86530 5114 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 5115 else
64c86530 5116 pim_show_neighbors(vrf->info, vty, uj);
12e41d03 5117
d62a17ae 5118 return CMD_SUCCESS;
12e41d03
DL
5119}
5120
a25de56b
DS
5121DEFUN (show_ip_pim_neighbor_vrf_all,
5122 show_ip_pim_neighbor_vrf_all_cmd,
5123 "show ip pim vrf all neighbor [detail|WORD] [json]",
5124 SHOW_STR
5125 IP_STR
5126 PIM_STR
5127 VRF_CMD_HELP_STR
5128 "PIM neighbor information\n"
5129 "Detailed output\n"
5130 "Name of interface or neighbor\n"
f5da2cc2 5131 JSON_STR)
a25de56b
DS
5132{
5133 int idx = 2;
9f049418 5134 bool uj = use_json(argc, argv);
a25de56b
DS
5135 struct vrf *vrf;
5136 bool first = true;
5137
5138 if (uj)
5139 vty_out(vty, "{ ");
a2addae8 5140 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5141 if (uj) {
5142 if (!first)
5143 vty_out(vty, ", ");
5144 vty_out(vty, " \"%s\": ", vrf->name);
5145 first = false;
5146 } else
5147 vty_out(vty, "VRF: %s\n", vrf->name);
5148 if (argv_find(argv, argc, "detail", &idx)
5149 || argv_find(argv, argc, "WORD", &idx))
5150 pim_show_neighbors_single(vrf->info, vty,
5151 argv[idx]->arg, uj);
5152 else
5153 pim_show_neighbors(vrf->info, vty, uj);
5154 }
5155 if (uj)
5156 vty_out(vty, "}\n");
5157
5158 return CMD_SUCCESS;
5159}
5160
12e41d03
DL
5161DEFUN (show_ip_pim_secondary,
5162 show_ip_pim_secondary_cmd,
20a7e5fd 5163 "show ip pim [vrf NAME] secondary",
12e41d03
DL
5164 SHOW_STR
5165 IP_STR
5166 PIM_STR
c68ba0d7 5167 VRF_CMD_HELP_STR
12e41d03
DL
5168 "PIM neighbor addresses\n")
5169{
c68ba0d7
DS
5170 int idx = 2;
5171 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5172
5173 if (!vrf)
5174 return CMD_WARNING;
5175
64c86530 5176 pim_show_neighbors_secondary(vrf->info, vty);
12e41d03 5177
d62a17ae 5178 return CMD_SUCCESS;
12e41d03
DL
5179}
5180
31a21c9c
DW
5181DEFUN (show_ip_pim_state,
5182 show_ip_pim_state_cmd,
20a7e5fd 5183 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
31a21c9c
DW
5184 SHOW_STR
5185 IP_STR
5186 PIM_STR
c68ba0d7 5187 VRF_CMD_HELP_STR
31a21c9c
DW
5188 "PIM state information\n"
5189 "Unicast or Multicast address\n"
5190 "Multicast address\n"
f5da2cc2 5191 JSON_STR)
31a21c9c 5192{
d62a17ae 5193 const char *src_or_group = NULL;
5194 const char *group = NULL;
c68ba0d7
DS
5195 int idx = 2;
5196 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5197 bool uj = use_json(argc, argv);
c68ba0d7
DS
5198
5199 if (!vrf)
5200 return CMD_WARNING;
5201
d62a17ae 5202 if (uj)
5203 argc--;
31a21c9c 5204
56243c3a
DS
5205 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
5206 src_or_group = argv[idx]->arg;
5207 if (idx + 1 < argc)
5208 group = argv[idx + 1]->arg;
5209 }
31a21c9c 5210
64c86530 5211 pim_show_state(vrf->info, vty, src_or_group, group, uj);
31a21c9c 5212
d62a17ae 5213 return CMD_SUCCESS;
31a21c9c
DW
5214}
5215
a25de56b
DS
5216DEFUN (show_ip_pim_state_vrf_all,
5217 show_ip_pim_state_vrf_all_cmd,
5218 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5219 SHOW_STR
5220 IP_STR
5221 PIM_STR
5222 VRF_CMD_HELP_STR
5223 "PIM state information\n"
5224 "Unicast or Multicast address\n"
5225 "Multicast address\n"
f5da2cc2 5226 JSON_STR)
a25de56b
DS
5227{
5228 const char *src_or_group = NULL;
5229 const char *group = NULL;
5230 int idx = 2;
9f049418 5231 bool uj = use_json(argc, argv);
a25de56b
DS
5232 struct vrf *vrf;
5233 bool first = true;
5234
5235 if (uj) {
5236 vty_out(vty, "{ ");
5237 argc--;
5238 }
5239
5240 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
5241 src_or_group = argv[idx]->arg;
5242 if (idx + 1 < argc)
5243 group = argv[idx + 1]->arg;
5244 }
5245
a2addae8 5246 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5247 if (uj) {
5248 if (!first)
5249 vty_out(vty, ", ");
5250 vty_out(vty, " \"%s\": ", vrf->name);
5251 first = false;
5252 } else
5253 vty_out(vty, "VRF: %s\n", vrf->name);
5254 pim_show_state(vrf->info, vty, src_or_group, group, uj);
5255 }
5256 if (uj)
5257 vty_out(vty, "}\n");
5258
5259 return CMD_SUCCESS;
5260}
5261
dff5cedb 5262DEFPY (show_ip_pim_upstream,
12e41d03 5263 show_ip_pim_upstream_cmd,
dff5cedb 5264 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
5265 SHOW_STR
5266 IP_STR
5267 PIM_STR
c68ba0d7 5268 VRF_CMD_HELP_STR
a268493f 5269 "PIM upstream information\n"
dff5cedb
DS
5270 "The Source or Group\n"
5271 "The Group\n"
f5da2cc2 5272 JSON_STR)
12e41d03 5273{
6fff2cc6 5274 pim_sgaddr sg = {0};
dff5cedb
DS
5275 struct vrf *v;
5276 bool uj = !!json;
5277 struct pim_instance *pim;
c68ba0d7 5278
dff5cedb
DS
5279 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
5280
5281 if (!v) {
5282 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 5283 return CMD_WARNING;
dff5cedb
DS
5284 }
5285 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 5286
dff5cedb
DS
5287 if (!pim) {
5288 vty_out(vty, "%% Unable to find pim instance\n");
5289 return CMD_WARNING;
5290 }
5291
3a6290bd
DA
5292 if (s_or_g.s_addr != INADDR_ANY) {
5293 if (g.s_addr != INADDR_ANY) {
dff5cedb
DS
5294 sg.src = s_or_g;
5295 sg.grp = g;
5296 } else
5297 sg.grp = s_or_g;
5298 }
5299 pim_show_upstream(pim, vty, &sg, uj);
12e41d03 5300
d62a17ae 5301 return CMD_SUCCESS;
12e41d03
DL
5302}
5303
a25de56b
DS
5304DEFUN (show_ip_pim_upstream_vrf_all,
5305 show_ip_pim_upstream_vrf_all_cmd,
5306 "show ip pim vrf all upstream [json]",
5307 SHOW_STR
5308 IP_STR
5309 PIM_STR
5310 VRF_CMD_HELP_STR
5311 "PIM upstream information\n"
5312 JSON_STR)
5313{
6fff2cc6 5314 pim_sgaddr sg = {0};
9f049418 5315 bool uj = use_json(argc, argv);
a25de56b
DS
5316 struct vrf *vrf;
5317 bool first = true;
5318
5319 if (uj)
5320 vty_out(vty, "{ ");
a2addae8 5321 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5322 if (uj) {
5323 if (!first)
5324 vty_out(vty, ", ");
5325 vty_out(vty, " \"%s\": ", vrf->name);
5326 first = false;
5327 } else
5328 vty_out(vty, "VRF: %s\n", vrf->name);
dff5cedb 5329 pim_show_upstream(vrf->info, vty, &sg, uj);
a25de56b
DS
5330 }
5331
5332 return CMD_SUCCESS;
5333}
5334
5c9a72ef
AK
5335DEFUN (show_ip_pim_channel,
5336 show_ip_pim_channel_cmd,
5337 "show ip pim [vrf NAME] channel [json]",
12e41d03
DL
5338 SHOW_STR
5339 IP_STR
5340 PIM_STR
c68ba0d7 5341 VRF_CMD_HELP_STR
5c9a72ef 5342 "PIM downstream channel info\n"
f5da2cc2 5343 JSON_STR)
12e41d03 5344{
c68ba0d7
DS
5345 int idx = 2;
5346 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5347 bool uj = use_json(argc, argv);
c68ba0d7
DS
5348
5349 if (!vrf)
5350 return CMD_WARNING;
5351
5c9a72ef 5352 pim_show_channel(vrf->info, vty, uj);
12e41d03 5353
d62a17ae 5354 return CMD_SUCCESS;
12e41d03
DL
5355}
5356
12e41d03
DL
5357DEFUN (show_ip_pim_upstream_join_desired,
5358 show_ip_pim_upstream_join_desired_cmd,
20a7e5fd 5359 "show ip pim [vrf NAME] upstream-join-desired [json]",
12e41d03
DL
5360 SHOW_STR
5361 IP_STR
5362 PIM_STR
c68ba0d7 5363 VRF_CMD_HELP_STR
a268493f 5364 "PIM upstream join-desired\n"
f5da2cc2 5365 JSON_STR)
12e41d03 5366{
c68ba0d7
DS
5367 int idx = 2;
5368 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5369 bool uj = use_json(argc, argv);
c68ba0d7
DS
5370
5371 if (!vrf)
5372 return CMD_WARNING;
5373
64c86530 5374 pim_show_join_desired(vrf->info, vty, uj);
12e41d03 5375
d62a17ae 5376 return CMD_SUCCESS;
12e41d03
DL
5377}
5378
5379DEFUN (show_ip_pim_upstream_rpf,
5380 show_ip_pim_upstream_rpf_cmd,
20a7e5fd 5381 "show ip pim [vrf NAME] upstream-rpf [json]",
12e41d03
DL
5382 SHOW_STR
5383 IP_STR
5384 PIM_STR
c68ba0d7 5385 VRF_CMD_HELP_STR
a268493f 5386 "PIM upstream source rpf\n"
f5da2cc2 5387 JSON_STR)
12e41d03 5388{
c68ba0d7
DS
5389 int idx = 2;
5390 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5391 bool uj = use_json(argc, argv);
c68ba0d7
DS
5392
5393 if (!vrf)
5394 return CMD_WARNING;
5395
64c86530 5396 pim_show_upstream_rpf(vrf->info, vty, uj);
12e41d03 5397
d62a17ae 5398 return CMD_SUCCESS;
12e41d03
DL
5399}
5400
00d07c6f
DS
5401DEFUN (show_ip_pim_rp,
5402 show_ip_pim_rp_cmd,
8c0a7680 5403 "show ip pim [vrf NAME] rp-info [A.B.C.D/M] [json]",
00d07c6f
DS
5404 SHOW_STR
5405 IP_STR
5406 PIM_STR
c68ba0d7 5407 VRF_CMD_HELP_STR
a268493f 5408 "PIM RP information\n"
8c0a7680 5409 "Multicast Group range\n"
f5da2cc2 5410 JSON_STR)
00d07c6f 5411{
c68ba0d7
DS
5412 int idx = 2;
5413 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5414 bool uj = use_json(argc, argv);
8c0a7680 5415 struct prefix *range = NULL;
c68ba0d7
DS
5416
5417 if (!vrf)
5418 return CMD_WARNING;
5419
8c0a7680
DA
5420 if (argv_find(argv, argc, "A.B.C.D/M", &idx)) {
5421 range = prefix_new();
5422 (void)str2prefix(argv[idx]->arg, range);
5423 apply_mask(range);
5424 }
5425
5426 pim_rp_show_information(vrf->info, range, vty, uj);
00d07c6f 5427
d62a17ae 5428 return CMD_SUCCESS;
00d07c6f
DS
5429}
5430
a25de56b
DS
5431DEFUN (show_ip_pim_rp_vrf_all,
5432 show_ip_pim_rp_vrf_all_cmd,
8c0a7680 5433 "show ip pim vrf all rp-info [A.B.C.D/M] [json]",
a25de56b
DS
5434 SHOW_STR
5435 IP_STR
5436 PIM_STR
5437 VRF_CMD_HELP_STR
5438 "PIM RP information\n"
8c0a7680 5439 "Multicast Group range\n"
f5da2cc2 5440 JSON_STR)
a25de56b 5441{
8c0a7680 5442 int idx = 0;
9f049418 5443 bool uj = use_json(argc, argv);
a25de56b
DS
5444 struct vrf *vrf;
5445 bool first = true;
8c0a7680
DA
5446 struct prefix *range = NULL;
5447
5448 if (argv_find(argv, argc, "A.B.C.D/M", &idx)) {
5449 range = prefix_new();
5450 (void)str2prefix(argv[idx]->arg, range);
5451 apply_mask(range);
5452 }
a25de56b
DS
5453
5454 if (uj)
5455 vty_out(vty, "{ ");
a2addae8 5456 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5457 if (uj) {
5458 if (!first)
5459 vty_out(vty, ", ");
5460 vty_out(vty, " \"%s\": ", vrf->name);
5461 first = false;
5462 } else
5463 vty_out(vty, "VRF: %s\n", vrf->name);
8c0a7680 5464 pim_rp_show_information(vrf->info, range, vty, uj);
a25de56b
DS
5465 }
5466 if (uj)
5467 vty_out(vty, "}\n");
5468
5469 return CMD_SUCCESS;
5470}
5471
12e41d03
DL
5472DEFUN (show_ip_pim_rpf,
5473 show_ip_pim_rpf_cmd,
20a7e5fd 5474 "show ip pim [vrf NAME] rpf [json]",
12e41d03
DL
5475 SHOW_STR
5476 IP_STR
5477 PIM_STR
c68ba0d7 5478 VRF_CMD_HELP_STR
a268493f 5479 "PIM cached source rpf information\n"
f5da2cc2 5480 JSON_STR)
12e41d03 5481{
c68ba0d7
DS
5482 int idx = 2;
5483 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5484 bool uj = use_json(argc, argv);
c68ba0d7
DS
5485
5486 if (!vrf)
5487 return CMD_WARNING;
5488
64c86530 5489 pim_show_rpf(vrf->info, vty, uj);
12e41d03 5490
d62a17ae 5491 return CMD_SUCCESS;
12e41d03
DL
5492}
5493
a25de56b
DS
5494DEFUN (show_ip_pim_rpf_vrf_all,
5495 show_ip_pim_rpf_vrf_all_cmd,
5496 "show ip pim vrf all rpf [json]",
5497 SHOW_STR
5498 IP_STR
5499 PIM_STR
5500 VRF_CMD_HELP_STR
5501 "PIM cached source rpf information\n"
f5da2cc2 5502 JSON_STR)
a25de56b 5503{
9f049418 5504 bool uj = use_json(argc, argv);
a25de56b
DS
5505 struct vrf *vrf;
5506 bool first = true;
5507
5508 if (uj)
5509 vty_out(vty, "{ ");
a2addae8 5510 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5511 if (uj) {
5512 if (!first)
5513 vty_out(vty, ", ");
5514 vty_out(vty, " \"%s\": ", vrf->name);
5515 first = false;
5516 } else
5517 vty_out(vty, "VRF: %s\n", vrf->name);
5518 pim_show_rpf(vrf->info, vty, uj);
5519 }
5520 if (uj)
5521 vty_out(vty, "}\n");
5522
5523 return CMD_SUCCESS;
5524}
5525
cba44481
CS
5526DEFUN (show_ip_pim_nexthop,
5527 show_ip_pim_nexthop_cmd,
20a7e5fd 5528 "show ip pim [vrf NAME] nexthop",
cba44481
CS
5529 SHOW_STR
5530 IP_STR
5531 PIM_STR
c68ba0d7 5532 VRF_CMD_HELP_STR
cba44481
CS
5533 "PIM cached nexthop rpf information\n")
5534{
c68ba0d7
DS
5535 int idx = 2;
5536 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5537
5538 if (!vrf)
5539 return CMD_WARNING;
5540
64c86530 5541 pim_show_nexthop(vrf->info, vty);
cba44481 5542
d62a17ae 5543 return CMD_SUCCESS;
cba44481
CS
5544}
5545
5546DEFUN (show_ip_pim_nexthop_lookup,
5547 show_ip_pim_nexthop_lookup_cmd,
20a7e5fd 5548 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
cba44481
CS
5549 SHOW_STR
5550 IP_STR
5551 PIM_STR
c68ba0d7 5552 VRF_CMD_HELP_STR
cba44481
CS
5553 "PIM cached nexthop rpf lookup\n"
5554 "Source/RP address\n"
5555 "Multicast Group address\n")
5556{
d62a17ae 5557 struct prefix nht_p;
5558 int result = 0;
5559 struct in_addr src_addr, grp_addr;
5560 struct in_addr vif_source;
5561 const char *addr_str, *addr_str1;
5562 struct prefix grp;
5563 struct pim_nexthop nexthop;
5564 char nexthop_addr_str[PREFIX_STRLEN];
5565 char grp_str[PREFIX_STRLEN];
c68ba0d7
DS
5566 int idx = 2;
5567 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 5568
c68ba0d7
DS
5569 if (!vrf)
5570 return CMD_WARNING;
5571
5572 argv_find(argv, argc, "A.B.C.D", &idx);
5573 addr_str = argv[idx]->arg;
d62a17ae 5574 result = inet_pton(AF_INET, addr_str, &src_addr);
5575 if (result <= 0) {
5576 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5577 errno, safe_strerror(errno));
5578 return CMD_WARNING;
5579 }
5580
5581 if (pim_is_group_224_4(src_addr)) {
5582 vty_out(vty,
5583 "Invalid argument. Expected Valid Source Address.\n");
5584 return CMD_WARNING;
5585 }
5586
c68ba0d7 5587 addr_str1 = argv[idx + 1]->arg;
d62a17ae 5588 result = inet_pton(AF_INET, addr_str1, &grp_addr);
5589 if (result <= 0) {
5590 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5591 errno, safe_strerror(errno));
5592 return CMD_WARNING;
5593 }
5594
5595 if (!pim_is_group_224_4(grp_addr)) {
5596 vty_out(vty,
5597 "Invalid argument. Expected Valid Multicast Group Address.\n");
5598 return CMD_WARNING;
5599 }
5600
c68ba0d7
DS
5601 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
5602 grp_addr))
d62a17ae 5603 return CMD_SUCCESS;
5604
d62a17ae 5605 nht_p.family = AF_INET;
5606 nht_p.prefixlen = IPV4_MAX_BITLEN;
5607 nht_p.u.prefix4 = vif_source;
5608 grp.family = AF_INET;
5609 grp.prefixlen = IPV4_MAX_BITLEN;
5610 grp.u.prefix4 = grp_addr;
5611 memset(&nexthop, 0, sizeof(nexthop));
5612
43763b11 5613 result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
9993f22c
DS
5614
5615 if (!result) {
996c9314
LB
5616 vty_out(vty,
5617 "Nexthop Lookup failed, no usable routes returned.\n");
9993f22c
DS
5618 return CMD_SUCCESS;
5619 }
d62a17ae 5620
5621 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
5622 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
5623 nexthop_addr_str, sizeof(nexthop_addr_str));
5624 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
5625 nexthop_addr_str, nexthop.interface->name);
5626
5627 return CMD_SUCCESS;
cba44481
CS
5628}
5629
39438188
CS
5630DEFUN (show_ip_pim_interface_traffic,
5631 show_ip_pim_interface_traffic_cmd,
20a7e5fd 5632 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
39438188
CS
5633 SHOW_STR
5634 IP_STR
5635 PIM_STR
c68ba0d7 5636 VRF_CMD_HELP_STR
39438188
CS
5637 "PIM interface information\n"
5638 "Protocol Packet counters\n"
17d86e50 5639 "Interface name\n"
f5da2cc2 5640 JSON_STR)
39438188 5641{
c68ba0d7
DS
5642 int idx = 2;
5643 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5644 bool uj = use_json(argc, argv);
c68ba0d7
DS
5645
5646 if (!vrf)
5647 return CMD_WARNING;
39438188 5648
d62a17ae 5649 if (argv_find(argv, argc, "WORD", &idx))
64c86530 5650 pim_show_interface_traffic_single(vrf->info, vty,
c68ba0d7 5651 argv[idx]->arg, uj);
d62a17ae 5652 else
64c86530 5653 pim_show_interface_traffic(vrf->info, vty, uj);
39438188 5654
d62a17ae 5655 return CMD_SUCCESS;
39438188
CS
5656}
5657
0d1a4e24 5658DEFUN (show_ip_pim_bsm_db,
5659 show_ip_pim_bsm_db_cmd,
5660 "show ip pim bsm-database [vrf NAME] [json]",
5661 SHOW_STR
5662 IP_STR
5663 PIM_STR
0d1a4e24 5664 "PIM cached bsm packets information\n"
33b58e53 5665 VRF_CMD_HELP_STR
0d1a4e24 5666 JSON_STR)
5667{
5668 int idx = 2;
5669 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5670 bool uj = use_json(argc, argv);
5671
5672 if (!vrf)
5673 return CMD_WARNING;
5674
5675 pim_show_bsm_db(vrf->info, vty, uj);
5676 return CMD_SUCCESS;
5677}
321295c1 5678
5679DEFUN (show_ip_pim_bsrp,
5680 show_ip_pim_bsrp_cmd,
5681 "show ip pim bsrp-info [vrf NAME] [json]",
5682 SHOW_STR
5683 IP_STR
5684 PIM_STR
321295c1 5685 "PIM cached group-rp mappings information\n"
33b58e53 5686 VRF_CMD_HELP_STR
321295c1 5687 JSON_STR)
5688{
5689 int idx = 2;
5690 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5691 bool uj = use_json(argc, argv);
5692
5693 if (!vrf)
5694 return CMD_WARNING;
5695
5696 pim_show_group_rp_mappings_info(vrf->info, vty, uj);
5697
5698 return CMD_SUCCESS;
5699}
5700
415f6350 5701DEFUN (show_ip_pim_statistics,
5702 show_ip_pim_statistics_cmd,
33b58e53 5703 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
415f6350 5704 SHOW_STR
5705 IP_STR
5706 PIM_STR
5707 VRF_CMD_HELP_STR
5708 "PIM statistics\n"
33b58e53 5709 INTERFACE_STR
415f6350 5710 "PIM interface\n"
5711 JSON_STR)
5712{
5713 int idx = 2;
5714 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5715 bool uj = use_json(argc, argv);
5716
5717 if (!vrf)
5718 return CMD_WARNING;
5719
5720 if (argv_find(argv, argc, "WORD", &idx))
5721 pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
5722 else
5723 pim_show_statistics(vrf->info, vty, NULL, uj);
5724
5725 return CMD_SUCCESS;
5726}
5727
8c8d7031
SP
5728static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
5729 bool uj)
12e41d03 5730{
d62a17ae 5731 struct interface *ifp;
ee2bbf7c 5732 char buf[PREFIX_STRLEN];
8c8d7031
SP
5733 json_object *json = NULL;
5734 json_object *json_row = NULL;
d62a17ae 5735
5736 vty_out(vty, "\n");
5737
8c8d7031
SP
5738 if (uj)
5739 json = json_object_new_object();
5740 else
5741 vty_out(vty,
5742 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
d62a17ae 5743
451fda4f 5744 FOR_ALL_INTERFACES (pim->vrf, ifp) {
c68ba0d7
DS
5745 struct pim_interface *pim_ifp;
5746 struct in_addr ifaddr;
5747 struct sioc_vif_req vreq;
d62a17ae 5748
c68ba0d7 5749 pim_ifp = ifp->info;
d62a17ae 5750
c68ba0d7
DS
5751 if (!pim_ifp)
5752 continue;
d62a17ae 5753
c68ba0d7
DS
5754 memset(&vreq, 0, sizeof(vreq));
5755 vreq.vifi = pim_ifp->mroute_vif_index;
d62a17ae 5756
c68ba0d7
DS
5757 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
5758 zlog_warn(
5759 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5760 (unsigned long)SIOCGETVIFCNT, ifp->name,
5761 pim_ifp->mroute_vif_index, errno,
5762 safe_strerror(errno));
5763 }
ecca97ac 5764
c68ba0d7 5765 ifaddr = pim_ifp->primary_address;
8c8d7031
SP
5766 if (uj) {
5767 json_row = json_object_new_object();
5768 json_object_string_add(json_row, "name", ifp->name);
5769 json_object_string_add(json_row, "state",
5770 if_is_up(ifp) ? "up" : "down");
b0d5264e
DA
5771 json_object_string_addf(json_row, "address", "%pI4",
5772 &pim_ifp->primary_address);
8c8d7031
SP
5773 json_object_int_add(json_row, "ifIndex", ifp->ifindex);
5774 json_object_int_add(json_row, "vif",
5775 pim_ifp->mroute_vif_index);
5776 json_object_int_add(json_row, "pktsIn",
5777 (unsigned long)vreq.icount);
5778 json_object_int_add(json_row, "pktsOut",
5779 (unsigned long)vreq.ocount);
5780 json_object_int_add(json_row, "bytesIn",
5781 (unsigned long)vreq.ibytes);
5782 json_object_int_add(json_row, "bytesOut",
5783 (unsigned long)vreq.obytes);
5784 json_object_object_add(json, ifp->name, json_row);
5785 } else {
5786 vty_out(vty,
5787 "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
ee2bbf7c
MS
5788 ifp->name,
5789 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
5790 ifp->ifindex, pim_ifp->mroute_vif_index,
8c8d7031
SP
5791 (unsigned long)vreq.icount,
5792 (unsigned long)vreq.ocount,
5793 (unsigned long)vreq.ibytes,
5794 (unsigned long)vreq.obytes);
5795 }
5796 }
d62a17ae 5797
3757f964
DA
5798 if (uj)
5799 vty_json(vty, json);
12e41d03
DL
5800}
5801
a25de56b
DS
5802static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
5803 struct vty *vty)
12e41d03 5804{
a25de56b 5805 struct vrf *vrf = pim->vrf;
d62a17ae 5806 time_t now = pim_time_monotonic_sec();
d62a17ae 5807 char uptime[10];
afec9bba 5808 char mlag_role[80];
d62a17ae 5809
bc14b6c7
DS
5810 pim = vrf->info;
5811
afec9bba 5812 vty_out(vty, "Router MLAG Role: %s\n",
05ca004b 5813 mlag_role2str(router->mlag_role, mlag_role, sizeof(mlag_role)));
ecca97ac
DS
5814 vty_out(vty, "Mroute socket descriptor:");
5815
c68ba0d7 5816 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
12e41d03 5817
d62a17ae 5818 pim_time_uptime(uptime, sizeof(uptime),
c68ba0d7 5819 now - pim->mroute_socket_creation);
d62a17ae 5820 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
12e41d03 5821
d62a17ae 5822 vty_out(vty, "\n");
12e41d03 5823
d62a17ae 5824 pim_zebra_zclient_update(vty);
5825 pim_zlookup_show_ip_multicast(vty);
05b0d0d0 5826
d62a17ae 5827 vty_out(vty, "\n");
5828 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
12e41d03 5829
d62a17ae 5830 vty_out(vty, "\n");
5b45753e 5831 vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
d62a17ae 5832 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
4795fff7 5833 vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
d62a17ae 5834 vty_out(vty, "PIM ECMP Rebalance: %s\n",
4795fff7 5835 pim->ecmp_rebalance_enable ? "Enable" : "Disable");
12e41d03 5836
d62a17ae 5837 vty_out(vty, "\n");
12e41d03 5838
da11e325 5839 show_rpf_refresh_stats(vty, pim, now, NULL);
12e41d03 5840
d62a17ae 5841 vty_out(vty, "\n");
12e41d03 5842
64c86530 5843 show_scan_oil_stats(pim, vty, now);
12e41d03 5844
8c8d7031 5845 show_multicast_interfaces(pim, vty, false);
a25de56b
DS
5846}
5847
5848DEFUN (show_ip_multicast,
5849 show_ip_multicast_cmd,
5850 "show ip multicast [vrf NAME]",
5851 SHOW_STR
5852 IP_STR
5853 VRF_CMD_HELP_STR
5854 "Multicast global information\n")
5855{
5856 int idx = 2;
5857 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5858
5859 if (!vrf)
5860 return CMD_WARNING;
5861
5862 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5863
5864 return CMD_SUCCESS;
5865}
5866
5867DEFUN (show_ip_multicast_vrf_all,
5868 show_ip_multicast_vrf_all_cmd,
5869 "show ip multicast vrf all",
5870 SHOW_STR
5871 IP_STR
5872 VRF_CMD_HELP_STR
5873 "Multicast global information\n")
5874{
9f049418 5875 bool uj = use_json(argc, argv);
a25de56b
DS
5876 struct vrf *vrf;
5877 bool first = true;
5878
5879 if (uj)
5880 vty_out(vty, "{ ");
a2addae8 5881 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5882 if (uj) {
5883 if (!first)
5884 vty_out(vty, ", ");
5885 vty_out(vty, " \"%s\": ", vrf->name);
5886 first = false;
5887 } else
5888 vty_out(vty, "VRF: %s\n", vrf->name);
5889 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5890 }
5891 if (uj)
5892 vty_out(vty, "}\n");
12e41d03 5893
d62a17ae 5894 return CMD_SUCCESS;
12e41d03
DL
5895}
5896
8c8d7031
SP
5897DEFUN(show_ip_multicast_count,
5898 show_ip_multicast_count_cmd,
5899 "show ip multicast count [vrf NAME] [json]",
5900 SHOW_STR IP_STR
5901 "Multicast global information\n"
5902 "Data packet count\n"
5903 VRF_CMD_HELP_STR JSON_STR)
5904{
5905 int idx = 3;
5906 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5907 bool uj = use_json(argc, argv);
5908
5909 if (!vrf)
5910 return CMD_WARNING;
5911
5912 show_multicast_interfaces(vrf->info, vty, uj);
5913
5914 return CMD_SUCCESS;
5915}
5916
5917DEFUN(show_ip_multicast_count_vrf_all,
5918 show_ip_multicast_count_vrf_all_cmd,
5919 "show ip multicast count vrf all [json]",
5920 SHOW_STR IP_STR
5921 "Multicast global information\n"
5922 "Data packet count\n"
5923 VRF_CMD_HELP_STR JSON_STR)
5924{
5925 bool uj = use_json(argc, argv);
5926 struct vrf *vrf;
5927 bool first = true;
5928
5929 if (uj)
5930 vty_out(vty, "{ ");
5931
5932 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5933 if (uj) {
5934 if (!first)
5935 vty_out(vty, ", ");
5936
5937 vty_out(vty, " \"%s\": ", vrf->name);
5938 first = false;
5939 } else
5940 vty_out(vty, "VRF: %s\n", vrf->name);
5941
5942 show_multicast_interfaces(vrf->info, vty, uj);
5943 }
5944
5945 if (uj)
5946 vty_out(vty, "}\n");
5947
5948 return CMD_SUCCESS;
5949}
5950
c23c1d39 5951static void show_mroute(struct pim_instance *pim, struct vty *vty,
6fff2cc6 5952 pim_sgaddr *sg, bool fill, bool uj)
12e41d03 5953{
d62a17ae 5954 struct listnode *node;
5955 struct channel_oil *c_oil;
5956 struct static_route *s_route;
5957 time_t now;
5958 json_object *json = NULL;
5959 json_object *json_group = NULL;
5960 json_object *json_source = NULL;
5961 json_object *json_oil = NULL;
5962 json_object *json_ifp_out = NULL;
a2b6e694 5963 int found_oif;
5964 int first;
d62a17ae 5965 char grp_str[INET_ADDRSTRLEN];
5966 char src_str[INET_ADDRSTRLEN];
5967 char in_ifname[INTERFACE_NAMSIZ + 1];
5968 char out_ifname[INTERFACE_NAMSIZ + 1];
5969 int oif_vif_index;
5970 struct interface *ifp_in;
5971 char proto[100];
6a424619 5972 char state_str[PIM_REG_STATE_STR_LEN];
dfd12d02 5973 char mroute_uptime[10];
d62a17ae 5974
5975 if (uj) {
5976 json = json_object_new_object();
5977 } else {
6a424619 5978 vty_out(vty, "IP Multicast Routing Table\n");
5d06e8a6 5979 vty_out(vty, "Flags: S - Sparse, C - Connected, P - Pruned\n");
d62a17ae 5980 vty_out(vty,
e9376c88 5981 " R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n");
6a424619 5982 vty_out(vty,
cd72ad01 5983 "\nSource Group Flags Proto Input Output TTL Uptime\n");
d62a17ae 5984 }
5985
5986 now = pim_time_monotonic_sec();
5987
5988 /* print list of PIM and IGMP routes */
7315ecda 5989 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
d62a17ae 5990 found_oif = 0;
5991 first = 1;
91c0fb47 5992 if (!c_oil->installed)
d62a17ae 5993 continue;
5994
032a7412
DL
5995 if (!pim_addr_is_any(sg->grp) &&
5996 pim_addr_cmp(sg->grp, c_oil->oil.mfcc_mcastgrp))
c23c1d39 5997 continue;
032a7412
DL
5998 if (!pim_addr_is_any(sg->src) &&
5999 pim_addr_cmp(sg->src, c_oil->oil.mfcc_origin))
c23c1d39
DS
6000 continue;
6001
d62a17ae 6002 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
6003 sizeof(grp_str));
6004 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
6005 sizeof(src_str));
6a424619
SP
6006
6007 strlcpy(state_str, "S", sizeof(state_str));
6008 /* When a non DR receives a igmp join, it creates a (*,G)
6009 * channel_oil without any upstream creation */
6010 if (c_oil->up) {
6011 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil->up->flags))
6012 strlcat(state_str, "C", sizeof(state_str));
6013 if (pim_upstream_is_sg_rpt(c_oil->up))
6014 strlcat(state_str, "R", sizeof(state_str));
6015 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil->up->flags))
6016 strlcat(state_str, "F", sizeof(state_str));
6017 if (c_oil->up->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
6018 strlcat(state_str, "T", sizeof(state_str));
6019 }
6020 if (pim_channel_oil_empty(c_oil))
6021 strlcat(state_str, "P", sizeof(state_str));
6022
7cfc7bcf 6023 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 6024
6025 if (ifp_in)
c35b7e6b 6026 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
d62a17ae 6027 else
c35b7e6b 6028 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 6029
dfd12d02
SP
6030
6031 pim_time_uptime(mroute_uptime, sizeof(mroute_uptime),
6032 now - c_oil->mroute_creation);
6033
d62a17ae 6034 if (uj) {
6035
6036 /* Find the group, create it if it doesn't exist */
6037 json_object_object_get_ex(json, grp_str, &json_group);
6038
6039 if (!json_group) {
6040 json_group = json_object_new_object();
6041 json_object_object_add(json, grp_str,
6042 json_group);
6043 }
6044
6045 /* Find the source nested under the group, create it if
6a424619
SP
6046 * it doesn't exist
6047 */
d62a17ae 6048 json_object_object_get_ex(json_group, src_str,
6049 &json_source);
6050
6051 if (!json_source) {
6052 json_source = json_object_new_object();
6053 json_object_object_add(json_group, src_str,
6054 json_source);
6055 }
6056
6057 /* Find the inbound interface nested under the source,
6058 * create it if it doesn't exist */
6059 json_object_int_add(json_source, "installed",
6060 c_oil->installed);
6061 json_object_int_add(json_source, "refCount",
6062 c_oil->oil_ref_count);
6063 json_object_int_add(json_source, "oilSize",
6064 c_oil->oil_size);
6065 json_object_int_add(json_source, "OilInheritedRescan",
6066 c_oil->oil_inherited_rescan);
77a2f8e5
DA
6067 json_object_int_add(json_source, "oilInheritedRescan",
6068 c_oil->oil_inherited_rescan);
d62a17ae 6069 json_object_string_add(json_source, "iif", in_ifname);
dfd12d02
SP
6070 json_object_string_add(json_source, "upTime",
6071 mroute_uptime);
d62a17ae 6072 json_oil = NULL;
6073 }
6074
6075 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
6076 ++oif_vif_index) {
6077 struct interface *ifp_out;
d62a17ae 6078 int ttl;
6079
6080 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
6081 if (ttl < 1)
6082 continue;
6083
5923b739
AK
6084 /* do not display muted OIFs */
6085 if (c_oil->oif_flags[oif_vif_index]
521c5b9d 6086 & PIM_OIF_FLAG_MUTE)
5923b739
AK
6087 continue;
6088
60eb7e6b 6089 if (c_oil->oil.mfcc_parent == oif_vif_index &&
521c5b9d
MS
6090 !pim_mroute_allow_iif_in_oil(c_oil,
6091 oif_vif_index))
60eb7e6b
AK
6092 continue;
6093
7cfc7bcf 6094 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 6095 found_oif = 1;
6096
6097 if (ifp_out)
c35b7e6b 6098 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
d62a17ae 6099 else
c35b7e6b 6100 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 6101
6102 if (uj) {
6103 json_ifp_out = json_object_new_object();
6104 json_object_string_add(json_ifp_out, "source",
6105 src_str);
6106 json_object_string_add(json_ifp_out, "group",
6107 grp_str);
6108
6109 if (c_oil->oif_flags[oif_vif_index]
6110 & PIM_OIF_FLAG_PROTO_PIM)
6111 json_object_boolean_true_add(
6112 json_ifp_out, "protocolPim");
6113
6114 if (c_oil->oif_flags[oif_vif_index]
6115 & PIM_OIF_FLAG_PROTO_IGMP)
6116 json_object_boolean_true_add(
6117 json_ifp_out, "protocolIgmp");
6118
ee31c9fd
AK
6119 if (c_oil->oif_flags[oif_vif_index]
6120 & PIM_OIF_FLAG_PROTO_VXLAN)
6121 json_object_boolean_true_add(
6122 json_ifp_out, "protocolVxlan");
6123
d62a17ae 6124 if (c_oil->oif_flags[oif_vif_index]
6125 & PIM_OIF_FLAG_PROTO_STAR)
6126 json_object_boolean_true_add(
6127 json_ifp_out,
6128 "protocolInherited");
6129
6130 json_object_string_add(json_ifp_out,
6131 "inboundInterface",
6132 in_ifname);
6133 json_object_int_add(json_ifp_out, "iVifI",
6134 c_oil->oil.mfcc_parent);
6135 json_object_string_add(json_ifp_out,
6136 "outboundInterface",
6137 out_ifname);
6138 json_object_int_add(json_ifp_out, "oVifI",
6139 oif_vif_index);
6140 json_object_int_add(json_ifp_out, "ttl", ttl);
6141 json_object_string_add(json_ifp_out, "upTime",
e7cd85bd 6142 mroute_uptime);
922e7544 6143 json_object_string_add(json_source, "flags",
6144 state_str);
d62a17ae 6145 if (!json_oil) {
6146 json_oil = json_object_new_object();
6147 json_object_object_add(json_source,
6148 "oil", json_oil);
6149 }
6150 json_object_object_add(json_oil, out_ifname,
6151 json_ifp_out);
6152 } else {
f8ca1bb9 6153 proto[0] = '\0';
d62a17ae 6154 if (c_oil->oif_flags[oif_vif_index]
6155 & PIM_OIF_FLAG_PROTO_PIM) {
c35b7e6b 6156 strlcpy(proto, "PIM", sizeof(proto));
d62a17ae 6157 }
6158
6159 if (c_oil->oif_flags[oif_vif_index]
6160 & PIM_OIF_FLAG_PROTO_IGMP) {
c35b7e6b 6161 strlcpy(proto, "IGMP", sizeof(proto));
d62a17ae 6162 }
6163
ee31c9fd
AK
6164 if (c_oil->oif_flags[oif_vif_index]
6165 & PIM_OIF_FLAG_PROTO_VXLAN) {
c35b7e6b 6166 strlcpy(proto, "VxLAN", sizeof(proto));
ee31c9fd
AK
6167 }
6168
d62a17ae 6169 if (c_oil->oif_flags[oif_vif_index]
6170 & PIM_OIF_FLAG_PROTO_STAR) {
c35b7e6b 6171 strlcpy(proto, "STAR", sizeof(proto));
d62a17ae 6172 }
6173
6174 vty_out(vty,
cd72ad01 6175 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6a424619
SP
6176 src_str, grp_str, state_str, proto,
6177 in_ifname, out_ifname, ttl,
6178 mroute_uptime);
d62a17ae 6179
6180 if (first) {
6181 src_str[0] = '\0';
6182 grp_str[0] = '\0';
6183 in_ifname[0] = '\0';
6a424619 6184 state_str[0] = '\0';
dfd12d02 6185 mroute_uptime[0] = '\0';
d62a17ae 6186 first = 0;
6187 }
6188 }
6189 }
6190
6191 if (!uj && !found_oif) {
6a424619 6192 vty_out(vty,
530b12cf 6193 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6a424619
SP
6194 src_str, grp_str, state_str, "none", in_ifname,
6195 "none", 0, "--:--:--");
d62a17ae 6196 }
6197 }
6198
6199 /* Print list of static routes */
7cfc7bcf
DS
6200 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
6201 first = 1;
6202
6203 if (!s_route->c_oil.installed)
d62a17ae 6204 continue;
6205
7cfc7bcf
DS
6206 pim_inet4_dump("<group?>", s_route->group, grp_str,
6207 sizeof(grp_str));
6208 pim_inet4_dump("<source?>", s_route->source, src_str,
6209 sizeof(src_str));
6210 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
6211 found_oif = 0;
d62a17ae 6212
7cfc7bcf 6213 if (ifp_in)
c35b7e6b 6214 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
7cfc7bcf 6215 else
c35b7e6b 6216 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 6217
7cfc7bcf 6218 if (uj) {
d62a17ae 6219
7cfc7bcf
DS
6220 /* Find the group, create it if it doesn't exist */
6221 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 6222
7cfc7bcf
DS
6223 if (!json_group) {
6224 json_group = json_object_new_object();
6225 json_object_object_add(json, grp_str,
6226 json_group);
6227 }
d62a17ae 6228
7cfc7bcf
DS
6229 /* Find the source nested under the group, create it if
6230 * it doesn't exist */
6231 json_object_object_get_ex(json_group, src_str,
6232 &json_source);
d62a17ae 6233
7cfc7bcf
DS
6234 if (!json_source) {
6235 json_source = json_object_new_object();
6236 json_object_object_add(json_group, src_str,
6237 json_source);
6238 }
d62a17ae 6239
7cfc7bcf
DS
6240 json_object_string_add(json_source, "iif", in_ifname);
6241 json_oil = NULL;
6242 } else {
c35b7e6b 6243 strlcpy(proto, "STATIC", sizeof(proto));
7cfc7bcf 6244 }
d62a17ae 6245
7cfc7bcf
DS
6246 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
6247 ++oif_vif_index) {
6248 struct interface *ifp_out;
6249 char oif_uptime[10];
6250 int ttl;
d62a17ae 6251
7cfc7bcf
DS
6252 ttl = s_route->oif_ttls[oif_vif_index];
6253 if (ttl < 1)
6254 continue;
6255
6256 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
996c9314
LB
6257 pim_time_uptime(
6258 oif_uptime, sizeof(oif_uptime),
6259 now
521c5b9d
MS
6260 - s_route->c_oil
6261 .oif_creation[oif_vif_index]);
7cfc7bcf 6262 found_oif = 1;
d62a17ae 6263
7cfc7bcf 6264 if (ifp_out)
c35b7e6b 6265 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
7cfc7bcf 6266 else
c35b7e6b 6267 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 6268
7cfc7bcf
DS
6269 if (uj) {
6270 json_ifp_out = json_object_new_object();
6271 json_object_string_add(json_ifp_out, "source",
6272 src_str);
6273 json_object_string_add(json_ifp_out, "group",
6274 grp_str);
6275 json_object_boolean_true_add(json_ifp_out,
6276 "protocolStatic");
6277 json_object_string_add(json_ifp_out,
6278 "inboundInterface",
6279 in_ifname);
6280 json_object_int_add(
6281 json_ifp_out, "iVifI",
6282 s_route->c_oil.oil.mfcc_parent);
6283 json_object_string_add(json_ifp_out,
6284 "outboundInterface",
6285 out_ifname);
6286 json_object_int_add(json_ifp_out, "oVifI",
6287 oif_vif_index);
6288 json_object_int_add(json_ifp_out, "ttl", ttl);
6289 json_object_string_add(json_ifp_out, "upTime",
6290 oif_uptime);
6291 if (!json_oil) {
6292 json_oil = json_object_new_object();
6293 json_object_object_add(json_source,
6294 "oil", json_oil);
d62a17ae 6295 }
7cfc7bcf
DS
6296 json_object_object_add(json_oil, out_ifname,
6297 json_ifp_out);
6298 } else {
d62a17ae 6299 vty_out(vty,
530b12cf
JAG
6300 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6301 src_str, grp_str, "-", proto, in_ifname,
6302 out_ifname, ttl, oif_uptime);
45b7b092 6303 if (first && !fill) {
7cfc7bcf
DS
6304 src_str[0] = '\0';
6305 grp_str[0] = '\0';
6306 in_ifname[0] = '\0';
6307 first = 0;
6308 }
d62a17ae 6309 }
6310 }
7cfc7bcf
DS
6311
6312 if (!uj && !found_oif) {
6313 vty_out(vty,
530b12cf
JAG
6314 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6315 src_str, grp_str, "-", proto, in_ifname, "none",
6316 0, "--:--:--");
7cfc7bcf 6317 }
d62a17ae 6318 }
6319
3757f964
DA
6320 if (uj)
6321 vty_json(vty, json);
12e41d03
DL
6322}
6323
c23c1d39 6324DEFPY (show_ip_mroute,
12e41d03 6325 show_ip_mroute_cmd,
c23c1d39 6326 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
12e41d03
DL
6327 SHOW_STR
6328 IP_STR
a957a05b 6329 MROUTE_STR
c3169ac7 6330 VRF_CMD_HELP_STR
c23c1d39
DS
6331 "The Source or Group\n"
6332 "The Group\n"
45b7b092 6333 "Fill in Assumed data\n"
a957a05b 6334 JSON_STR)
12e41d03 6335{
6fff2cc6 6336 pim_sgaddr sg = {0};
c23c1d39
DS
6337 struct pim_instance *pim;
6338 struct vrf *v;
c68ba0d7 6339
c23c1d39
DS
6340 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
6341
6342 if (!v) {
6343 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 6344 return CMD_WARNING;
c23c1d39
DS
6345 }
6346 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 6347
c23c1d39
DS
6348 if (!pim) {
6349 vty_out(vty, "%% Unable to find pim instance\n");
6350 return CMD_WARNING;
6351 }
45b7b092 6352
3a6290bd
DA
6353 if (s_or_g.s_addr != INADDR_ANY) {
6354 if (g.s_addr != INADDR_ANY) {
c23c1d39
DS
6355 sg.src = s_or_g;
6356 sg.grp = g;
6357 } else
6358 sg.grp = s_or_g;
6359 }
6360 show_mroute(pim, vty, &sg, !!fill, !!json);
d62a17ae 6361 return CMD_SUCCESS;
12e41d03
DL
6362}
6363
b283a4ca
DS
6364DEFUN (show_ip_mroute_vrf_all,
6365 show_ip_mroute_vrf_all_cmd,
45b7b092 6366 "show ip mroute vrf all [fill] [json]",
b283a4ca
DS
6367 SHOW_STR
6368 IP_STR
6369 MROUTE_STR
6370 VRF_CMD_HELP_STR
45b7b092 6371 "Fill in Assumed data\n"
b283a4ca
DS
6372 JSON_STR)
6373{
6fff2cc6 6374 pim_sgaddr sg = {0};
9f049418 6375 bool uj = use_json(argc, argv);
45b7b092 6376 int idx = 4;
b283a4ca
DS
6377 struct vrf *vrf;
6378 bool first = true;
45b7b092
DS
6379 bool fill = false;
6380
6381 if (argv_find(argv, argc, "fill", &idx))
6382 fill = true;
b283a4ca
DS
6383
6384 if (uj)
6385 vty_out(vty, "{ ");
a2addae8 6386 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b283a4ca
DS
6387 if (uj) {
6388 if (!first)
6389 vty_out(vty, ", ");
6390 vty_out(vty, " \"%s\": ", vrf->name);
6391 first = false;
6392 } else
6393 vty_out(vty, "VRF: %s\n", vrf->name);
c23c1d39 6394 show_mroute(vrf->info, vty, &sg, fill, uj);
b283a4ca
DS
6395 }
6396 if (uj)
5cef40fc 6397 vty_out(vty, "}\n");
b283a4ca
DS
6398
6399 return CMD_SUCCESS;
6400}
6401
cd333cf9
DS
6402DEFUN (clear_ip_mroute_count,
6403 clear_ip_mroute_count_cmd,
6404 "clear ip mroute [vrf NAME] count",
6405 CLEAR_STR
6406 IP_STR
6407 MROUTE_STR
6408 VRF_CMD_HELP_STR
6409 "Route and packet count data\n")
6410{
6411 int idx = 2;
6412 struct listnode *node;
6413 struct channel_oil *c_oil;
6414 struct static_route *sr;
6415 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6416 struct pim_instance *pim;
6417
6418 if (!vrf)
6419 return CMD_WARNING;
6420
6421 pim = vrf->info;
7315ecda 6422 frr_each(rb_pim_oil, &pim->channel_oil_head, c_oil) {
cd333cf9
DS
6423 if (!c_oil->installed)
6424 continue;
6425
6426 pim_mroute_update_counters(c_oil);
6427 c_oil->cc.origpktcnt = c_oil->cc.pktcnt;
6428 c_oil->cc.origbytecnt = c_oil->cc.bytecnt;
6429 c_oil->cc.origwrong_if = c_oil->cc.wrong_if;
6430 }
6431
6432 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
6433 if (!sr->c_oil.installed)
6434 continue;
6435
6436 pim_mroute_update_counters(&sr->c_oil);
6437
6438 sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt;
6439 sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt;
6440 sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if;
6441 }
6442 return CMD_SUCCESS;
6443}
6444
922e7544 6445static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil,
6446 json_object *json,
6447 struct vty *vty)
12e41d03 6448{
922e7544 6449 char group_str[INET_ADDRSTRLEN];
6450 char source_str[INET_ADDRSTRLEN];
6451 json_object *json_group = NULL;
6452 json_object *json_source = NULL;
12e41d03 6453
922e7544 6454 if (!c_oil->installed)
6455 return;
12e41d03 6456
922e7544 6457 pim_mroute_update_counters(c_oil);
12e41d03 6458
922e7544 6459 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
6460 sizeof(group_str));
6461 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
6462 sizeof(source_str));
58302dc7 6463
922e7544 6464 if (json) {
6465 json_object_object_get_ex(json, group_str, &json_group);
12e41d03 6466
922e7544 6467 if (!json_group) {
6468 json_group = json_object_new_object();
6469 json_object_object_add(json, group_str, json_group);
6470 }
12e41d03 6471
922e7544 6472 json_source = json_object_new_object();
6473 json_object_object_add(json_group, source_str, json_source);
6474 json_object_int_add(json_source, "lastUsed",
6475 c_oil->cc.lastused / 100);
6476 json_object_int_add(json_source, "packets", c_oil->cc.pktcnt);
6477 json_object_int_add(json_source, "bytes", c_oil->cc.bytecnt);
6478 json_object_int_add(json_source, "wrongIf", c_oil->cc.wrong_if);
6250610a 6479
922e7544 6480 } else {
d62a17ae 6481 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6482 source_str, group_str, c_oil->cc.lastused / 100,
cd333cf9
DS
6483 c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
6484 c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
6485 c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
d62a17ae 6486 }
922e7544 6487}
d62a17ae 6488
922e7544 6489static void show_mroute_count(struct pim_instance *pim, struct vty *vty,
6490 bool uj)
6491{
6492 struct listnode *node;
6493 struct channel_oil *c_oil;
6494 struct static_route *sr;
6495 json_object *json = NULL;
6250610a 6496
922e7544 6497 if (uj)
6498 json = json_object_new_object();
6499 else {
6500 vty_out(vty, "\n");
6250610a 6501
922e7544 6502 vty_out(vty,
6503 "Source Group LastUsed Packets Bytes WrongIf \n");
6504 }
4e0bc0f0 6505
922e7544 6506 /* Print PIM and IGMP route counts */
6507 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil)
6508 show_mroute_count_per_channel_oil(c_oil, json, vty);
4e0bc0f0 6509
922e7544 6510 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr))
6511 show_mroute_count_per_channel_oil(&sr->c_oil, json, vty);
6512
3757f964
DA
6513 if (uj)
6514 vty_json(vty, json);
12e41d03
DL
6515}
6516
6517DEFUN (show_ip_mroute_count,
6518 show_ip_mroute_count_cmd,
922e7544 6519 "show ip mroute [vrf NAME] count [json]",
12e41d03
DL
6520 SHOW_STR
6521 IP_STR
6522 MROUTE_STR
c68ba0d7 6523 VRF_CMD_HELP_STR
922e7544 6524 "Route and packet count data\n"
6525 JSON_STR)
12e41d03 6526{
c68ba0d7 6527 int idx = 2;
922e7544 6528 bool uj = use_json(argc, argv);
c68ba0d7
DS
6529 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6530
e691f179
DS
6531 if (!vrf)
6532 return CMD_WARNING;
6533
922e7544 6534 show_mroute_count(vrf->info, vty, uj);
d62a17ae 6535 return CMD_SUCCESS;
12e41d03
DL
6536}
6537
5c3aac90
DS
6538DEFUN (show_ip_mroute_count_vrf_all,
6539 show_ip_mroute_count_vrf_all_cmd,
922e7544 6540 "show ip mroute vrf all count [json]",
5c3aac90
DS
6541 SHOW_STR
6542 IP_STR
6543 MROUTE_STR
6544 VRF_CMD_HELP_STR
922e7544 6545 "Route and packet count data\n"
6546 JSON_STR)
5c3aac90 6547{
9f049418 6548 bool uj = use_json(argc, argv);
5c3aac90
DS
6549 struct vrf *vrf;
6550 bool first = true;
6551
6552 if (uj)
6553 vty_out(vty, "{ ");
a2addae8 6554 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5c3aac90
DS
6555 if (uj) {
6556 if (!first)
6557 vty_out(vty, ", ");
6558 vty_out(vty, " \"%s\": ", vrf->name);
6559 first = false;
6560 } else
6561 vty_out(vty, "VRF: %s\n", vrf->name);
922e7544 6562 show_mroute_count(vrf->info, vty, uj);
5c3aac90
DS
6563 }
6564 if (uj)
6565 vty_out(vty, "}\n");
6566
6567 return CMD_SUCCESS;
6568}
6569
922e7544 6570static void show_mroute_summary(struct pim_instance *pim, struct vty *vty,
6571 json_object *json)
468b6f44
SP
6572{
6573 struct listnode *node;
6574 struct channel_oil *c_oil;
6575 struct static_route *s_route;
6576 uint32_t starg_sw_mroute_cnt = 0;
6577 uint32_t sg_sw_mroute_cnt = 0;
6578 uint32_t starg_hw_mroute_cnt = 0;
6579 uint32_t sg_hw_mroute_cnt = 0;
922e7544 6580 json_object *json_starg = NULL;
6581 json_object *json_sg = NULL;
468b6f44 6582
922e7544 6583 if (!json)
6584 vty_out(vty, "Mroute Type Installed/Total\n");
468b6f44 6585
7315ecda 6586 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
468b6f44
SP
6587 if (!c_oil->installed) {
6588 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
6589 starg_sw_mroute_cnt++;
6590 else
6591 sg_sw_mroute_cnt++;
6592 } else {
6593 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
6594 starg_hw_mroute_cnt++;
6595 else
6596 sg_hw_mroute_cnt++;
6597 }
6598 }
6599
6600 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
6601 if (!s_route->c_oil.installed) {
6602 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
6603 starg_sw_mroute_cnt++;
6604 else
6605 sg_sw_mroute_cnt++;
6606 } else {
6607 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
6608 starg_hw_mroute_cnt++;
6609 else
6610 sg_hw_mroute_cnt++;
6611 }
6612 }
6613
922e7544 6614 if (!json) {
6615 vty_out(vty, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt,
6616 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
6617 vty_out(vty, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt,
6618 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
6619 vty_out(vty, "------\n");
6620 vty_out(vty, "%-20s %u/%u\n", "Total",
6621 (starg_hw_mroute_cnt + sg_hw_mroute_cnt),
6622 (starg_sw_mroute_cnt + starg_hw_mroute_cnt
6623 + sg_sw_mroute_cnt + sg_hw_mroute_cnt));
6624 } else {
6625 /* (*,G) route details */
6626 json_starg = json_object_new_object();
6627 json_object_object_add(json, "wildcardGroup", json_starg);
6628
6629 json_object_int_add(json_starg, "installed",
6630 starg_hw_mroute_cnt);
6631 json_object_int_add(json_starg, "total",
6632 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
6633
6634 /* (S, G) route details */
6635 json_sg = json_object_new_object();
6636 json_object_object_add(json, "sourceGroup", json_sg);
6637
6638 json_object_int_add(json_sg, "installed", sg_hw_mroute_cnt);
6639 json_object_int_add(json_sg, "total",
6640 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
6641
6642 json_object_int_add(json, "totalNumOfInstalledMroutes",
6643 starg_hw_mroute_cnt + sg_hw_mroute_cnt);
6644 json_object_int_add(json, "totalNumOfMroutes",
6645 starg_sw_mroute_cnt + starg_hw_mroute_cnt
521c5b9d
MS
6646 + sg_sw_mroute_cnt
6647 + sg_hw_mroute_cnt);
922e7544 6648 }
468b6f44
SP
6649}
6650
6651DEFUN (show_ip_mroute_summary,
6652 show_ip_mroute_summary_cmd,
922e7544 6653 "show ip mroute [vrf NAME] summary [json]",
468b6f44
SP
6654 SHOW_STR
6655 IP_STR
6656 MROUTE_STR
6657 VRF_CMD_HELP_STR
922e7544 6658 "Summary of all mroutes\n"
6659 JSON_STR)
468b6f44
SP
6660{
6661 int idx = 2;
922e7544 6662 bool uj = use_json(argc, argv);
468b6f44 6663 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
922e7544 6664 json_object *json = NULL;
6665
6666 if (uj)
6667 json = json_object_new_object();
468b6f44
SP
6668
6669 if (!vrf)
6670 return CMD_WARNING;
6671
922e7544 6672 show_mroute_summary(vrf->info, vty, json);
6673
3757f964
DA
6674 if (uj)
6675 vty_json(vty, json);
468b6f44
SP
6676 return CMD_SUCCESS;
6677}
6678
6679DEFUN (show_ip_mroute_summary_vrf_all,
6680 show_ip_mroute_summary_vrf_all_cmd,
922e7544 6681 "show ip mroute vrf all summary [json]",
468b6f44
SP
6682 SHOW_STR
6683 IP_STR
6684 MROUTE_STR
6685 VRF_CMD_HELP_STR
922e7544 6686 "Summary of all mroutes\n"
6687 JSON_STR)
468b6f44
SP
6688{
6689 struct vrf *vrf;
922e7544 6690 bool uj = use_json(argc, argv);
6691 json_object *json = NULL;
6692 json_object *json_vrf = NULL;
6693
6694 if (uj)
6695 json = json_object_new_object();
468b6f44
SP
6696
6697 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
922e7544 6698 if (uj)
6699 json_vrf = json_object_new_object();
6700 else
6701 vty_out(vty, "VRF: %s\n", vrf->name);
6702
6703 show_mroute_summary(vrf->info, vty, json_vrf);
6704
6705 if (uj)
6706 json_object_object_add(json, vrf->name, json_vrf);
6707 }
6708
3757f964
DA
6709 if (uj)
6710 vty_json(vty, json);
468b6f44
SP
6711
6712 return CMD_SUCCESS;
6713}
6714
12e41d03
DL
6715DEFUN (show_ip_rib,
6716 show_ip_rib_cmd,
20a7e5fd 6717 "show ip rib [vrf NAME] A.B.C.D",
12e41d03
DL
6718 SHOW_STR
6719 IP_STR
6720 RIB_STR
c68ba0d7 6721 VRF_CMD_HELP_STR
12e41d03
DL
6722 "Unicast address\n")
6723{
c68ba0d7
DS
6724 int idx = 2;
6725 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 6726 struct in_addr addr;
6727 const char *addr_str;
6728 struct pim_nexthop nexthop;
6729 char nexthop_addr_str[PREFIX_STRLEN];
6730 int result;
6731
c68ba0d7
DS
6732 if (!vrf)
6733 return CMD_WARNING;
6734
d62a17ae 6735 memset(&nexthop, 0, sizeof(nexthop));
c68ba0d7
DS
6736 argv_find(argv, argc, "A.B.C.D", &idx);
6737 addr_str = argv[idx]->arg;
d62a17ae 6738 result = inet_pton(AF_INET, addr_str, &addr);
6739 if (result <= 0) {
6740 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
6741 errno, safe_strerror(errno));
6742 return CMD_WARNING;
6743 }
12e41d03 6744
ade155e1 6745 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
d62a17ae 6746 vty_out(vty,
6747 "Failure querying RIB nexthop for unicast address %s\n",
6748 addr_str);
6749 return CMD_WARNING;
6750 }
12e41d03 6751
d62a17ae 6752 vty_out(vty,
6753 "Address NextHop Interface Metric Preference\n");
12e41d03 6754
d62a17ae 6755 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
6756 nexthop_addr_str, sizeof(nexthop_addr_str));
12e41d03 6757
d62a17ae 6758 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
6759 nexthop.interface ? nexthop.interface->name : "<ifname?>",
6760 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
12e41d03 6761
d62a17ae 6762 return CMD_SUCCESS;
12e41d03
DL
6763}
6764
64c86530 6765static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
12e41d03 6766{
d62a17ae 6767 struct listnode *node;
6768 struct ssmpingd_sock *ss;
6769 time_t now;
12e41d03 6770
d62a17ae 6771 vty_out(vty,
6772 "Source Socket Address Port Uptime Requests\n");
12e41d03 6773
71ad9915 6774 if (!pim->ssmpingd_list)
d62a17ae 6775 return;
12e41d03 6776
d62a17ae 6777 now = pim_time_monotonic_sec();
12e41d03 6778
71ad9915 6779 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
d62a17ae 6780 char source_str[INET_ADDRSTRLEN];
6781 char ss_uptime[10];
6782 struct sockaddr_in bind_addr;
6783 socklen_t len = sizeof(bind_addr);
6784 char bind_addr_str[INET_ADDRSTRLEN];
12e41d03 6785
d62a17ae 6786 pim_inet4_dump("<src?>", ss->source_addr, source_str,
6787 sizeof(source_str));
12e41d03 6788
d62a17ae 6789 if (pim_socket_getsockname(
6790 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
6791 vty_out(vty,
6792 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6793 source_str, ss->sock_fd);
6794 }
12e41d03 6795
d62a17ae 6796 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
6797 sizeof(bind_addr_str));
6798 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
6799 now - ss->creation);
12e41d03 6800
d62a17ae 6801 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
6802 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
6803 ss_uptime, (long long)ss->requests);
6804 }
12e41d03
DL
6805}
6806
6807DEFUN (show_ip_ssmpingd,
6808 show_ip_ssmpingd_cmd,
20a7e5fd 6809 "show ip ssmpingd [vrf NAME]",
12e41d03
DL
6810 SHOW_STR
6811 IP_STR
c68ba0d7
DS
6812 SHOW_SSMPINGD_STR
6813 VRF_CMD_HELP_STR)
12e41d03 6814{
c68ba0d7
DS
6815 int idx = 2;
6816 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6817
6818 if (!vrf)
6819 return CMD_WARNING;
6820
64c86530 6821 show_ssmpingd(vrf->info, vty);
d62a17ae 6822 return CMD_SUCCESS;
12e41d03
DL
6823}
6824
a7b2b1e2
DS
6825DEFUN (ip_pim_spt_switchover_infinity,
6826 ip_pim_spt_switchover_infinity_cmd,
6827 "ip pim spt-switchover infinity-and-beyond",
6828 IP_STR
6829 PIM_STR
6830 "SPT-Switchover\n"
6831 "Never switch to SPT Tree\n")
6832{
fb991ce9 6833 return pim_process_spt_switchover_infinity_cmd(vty);
df94f9a9 6834}
a7b2b1e2 6835
fb991ce9 6836DEFPY (ip_pim_spt_switchover_infinity_plist,
df94f9a9 6837 ip_pim_spt_switchover_infinity_plist_cmd,
fb991ce9 6838 "ip pim spt-switchover infinity-and-beyond prefix-list WORD$plist",
df94f9a9
DS
6839 IP_STR
6840 PIM_STR
6841 "SPT-Switchover\n"
6842 "Never switch to SPT Tree\n"
6843 "Prefix-List to control which groups to switch\n"
6844 "Prefix-List name\n")
6845{
fb991ce9 6846 return pim_process_spt_switchover_prefixlist_cmd(vty, plist);
a7b2b1e2
DS
6847}
6848
6849DEFUN (no_ip_pim_spt_switchover_infinity,
6850 no_ip_pim_spt_switchover_infinity_cmd,
6851 "no ip pim spt-switchover infinity-and-beyond",
6852 NO_STR
6853 IP_STR
6854 PIM_STR
6855 "SPT_Switchover\n"
6856 "Never switch to SPT Tree\n")
6857{
fb991ce9 6858 return pim_process_no_spt_switchover_cmd(vty);
df94f9a9 6859}
a7b2b1e2 6860
df94f9a9
DS
6861DEFUN (no_ip_pim_spt_switchover_infinity_plist,
6862 no_ip_pim_spt_switchover_infinity_plist_cmd,
6863 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6864 NO_STR
6865 IP_STR
6866 PIM_STR
6867 "SPT_Switchover\n"
6868 "Never switch to SPT Tree\n"
6869 "Prefix-List to control which groups to switch\n"
6870 "Prefix-List name\n")
6871{
fb991ce9 6872 return pim_process_no_spt_switchover_cmd(vty);
a7b2b1e2
DS
6873}
6874
f4e74bd0
DS
6875DEFPY (pim_register_accept_list,
6876 pim_register_accept_list_cmd,
6877 "[no] ip pim register-accept-list WORD$word",
6878 NO_STR
6879 IP_STR
6880 PIM_STR
6881 "Only accept registers from a specific source prefix list\n"
6882 "Prefix-List name\n")
6883{
0c949724
SP
6884 const char *vrfname;
6885 char reg_alist_xpath[XPATH_MAXLEN];
6886
5a1a3920
RZ
6887 vrfname = pim_cli_get_vrf_name(vty);
6888 if (vrfname == NULL)
6889 return CMD_WARNING_CONFIG_FAILED;
0c949724
SP
6890
6891 snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
698f4147 6892 FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
0c949724
SP
6893 "frr-routing:ipv4");
6894 strlcat(reg_alist_xpath, "/register-accept-list",
6895 sizeof(reg_alist_xpath));
f4e74bd0
DS
6896
6897 if (no)
0c949724 6898 nb_cli_enqueue_change(vty, reg_alist_xpath,
521c5b9d 6899 NB_OP_DESTROY, NULL);
0c949724
SP
6900 else
6901 nb_cli_enqueue_change(vty, reg_alist_xpath,
521c5b9d 6902 NB_OP_MODIFY, word);
0c949724
SP
6903
6904 return nb_cli_apply_changes(vty, NULL);
f4e74bd0
DS
6905}
6906
c73113ea 6907DEFPY (ip_pim_joinprune_time,
ee1a0718 6908 ip_pim_joinprune_time_cmd,
c73113ea 6909 "ip pim join-prune-interval (1-65535)$jpi",
ee1a0718
DS
6910 IP_STR
6911 "pim multicast routing\n"
6912 "Join Prune Send Interval\n"
6913 "Seconds\n")
6914{
c73113ea 6915 return pim_process_join_prune_cmd(vty, jpi_str);
ee1a0718
DS
6916}
6917
6918DEFUN (no_ip_pim_joinprune_time,
6919 no_ip_pim_joinprune_time_cmd,
11ca3587 6920 "no ip pim join-prune-interval [(1-65535)]",
ee1a0718
DS
6921 NO_STR
6922 IP_STR
6923 "pim multicast routing\n"
6924 "Join Prune Send Interval\n"
11ca3587 6925 IGNORED_IN_NO_STR)
ee1a0718 6926{
c73113ea 6927 return pim_process_no_join_prune_cmd(vty);
ee1a0718
DS
6928}
6929
18ca7de5 6930DEFPY (ip_pim_register_suppress,
191f5695 6931 ip_pim_register_suppress_cmd,
18ca7de5 6932 "ip pim register-suppress-time (1-65535)$rst",
4304f95c
DS
6933 IP_STR
6934 "pim multicast routing\n"
191f5695
DS
6935 "Register Suppress Timer\n"
6936 "Seconds\n")
4304f95c 6937{
18ca7de5 6938 return pim_process_register_suppress_cmd(vty, rst_str);
4304f95c
DS
6939}
6940
191f5695
DS
6941DEFUN (no_ip_pim_register_suppress,
6942 no_ip_pim_register_suppress_cmd,
11ca3587 6943 "no ip pim register-suppress-time [(1-65535)]",
4304f95c
DS
6944 NO_STR
6945 IP_STR
6946 "pim multicast routing\n"
191f5695 6947 "Register Suppress Timer\n"
11ca3587 6948 IGNORED_IN_NO_STR)
4304f95c 6949{
18ca7de5 6950 return pim_process_no_register_suppress_cmd(vty);
4304f95c
DS
6951}
6952
2322b991 6953DEFPY (ip_pim_rp_keep_alive,
cc14df13 6954 ip_pim_rp_keep_alive_cmd,
2322b991 6955 "ip pim rp keep-alive-timer (1-65535)$kat",
cc14df13
DS
6956 IP_STR
6957 "pim multicast routing\n"
6958 "Rendevous Point\n"
6959 "Keep alive Timer\n"
6960 "Seconds\n")
6961{
2322b991 6962 return pim_process_rp_kat_cmd(vty, kat_str);
cc14df13
DS
6963}
6964
6965DEFUN (no_ip_pim_rp_keep_alive,
6966 no_ip_pim_rp_keep_alive_cmd,
11ca3587 6967 "no ip pim rp keep-alive-timer [(1-65535)]",
cc14df13
DS
6968 NO_STR
6969 IP_STR
6970 "pim multicast routing\n"
6971 "Rendevous Point\n"
6972 "Keep alive Timer\n"
11ca3587 6973 IGNORED_IN_NO_STR)
cc14df13 6974{
2322b991 6975 return pim_process_no_rp_kat_cmd(vty);
cc14df13
DS
6976}
6977
28e32366 6978DEFPY (ip_pim_keep_alive,
191f5695 6979 ip_pim_keep_alive_cmd,
28e32366 6980 "ip pim keep-alive-timer (1-65535)$kat",
01408ede
DS
6981 IP_STR
6982 "pim multicast routing\n"
01408ede
DS
6983 "Keep alive Timer\n"
6984 "Seconds\n")
6985{
28e32366 6986 return pim_process_keepalivetimer_cmd(vty, kat_str);
01408ede
DS
6987}
6988
191f5695
DS
6989DEFUN (no_ip_pim_keep_alive,
6990 no_ip_pim_keep_alive_cmd,
11ca3587 6991 "no ip pim keep-alive-timer [(1-65535)]",
01408ede
DS
6992 NO_STR
6993 IP_STR
6994 "pim multicast routing\n"
01408ede 6995 "Keep alive Timer\n"
11ca3587 6996 IGNORED_IN_NO_STR)
01408ede 6997{
28e32366 6998 return pim_process_no_keepalivetimer_cmd(vty);
01408ede
DS
6999}
7000
0da72f1f 7001DEFPY (ip_pim_packets,
8e4c9ef3 7002 ip_pim_packets_cmd,
11ca3587 7003 "ip pim packets (1-255)",
8e4c9ef3
DS
7004 IP_STR
7005 "pim multicast routing\n"
a957a05b
DS
7006 "packets to process at one time per fd\n"
7007 "Number of packets\n")
8e4c9ef3 7008{
0da72f1f 7009 return pim_process_pim_packet_cmd(vty, packets_str);
8e4c9ef3
DS
7010}
7011
7012DEFUN (no_ip_pim_packets,
7013 no_ip_pim_packets_cmd,
11ca3587 7014 "no ip pim packets [(1-255)]",
8e4c9ef3
DS
7015 NO_STR
7016 IP_STR
7017 "pim multicast routing\n"
a957a05b 7018 "packets to process at one time per fd\n"
11ca3587 7019 IGNORED_IN_NO_STR)
8e4c9ef3 7020{
0da72f1f 7021 return pim_process_no_pim_packet_cmd(vty);
8e4c9ef3
DS
7022}
7023
339f7695 7024DEFPY (igmp_group_watermark,
7025 igmp_group_watermark_cmd,
11ca3587 7026 "ip igmp watermark-warn (1-65535)$limit",
339f7695 7027 IP_STR
7028 IGMP_STR
7029 "Configure group limit for watermark warning\n"
7030 "Group count to generate watermark warning\n")
7031{
7032 PIM_DECLVAR_CONTEXT(vrf, pim);
7033 pim->igmp_watermark_limit = limit;
7034
7035 return CMD_SUCCESS;
7036}
7037
7038DEFPY (no_igmp_group_watermark,
7039 no_igmp_group_watermark_cmd,
11ca3587 7040 "no ip igmp watermark-warn [(1-65535)$limit]",
339f7695 7041 NO_STR
7042 IP_STR
7043 IGMP_STR
7044 "Unconfigure group limit for watermark warning\n"
11ca3587 7045 IGNORED_IN_NO_STR)
339f7695 7046{
7047 PIM_DECLVAR_CONTEXT(vrf, pim);
7048 pim->igmp_watermark_limit = 0;
7049
7050 return CMD_SUCCESS;
7051}
7052
71bbe73d
DS
7053DEFUN (ip_pim_v6_secondary,
7054 ip_pim_v6_secondary_cmd,
7055 "ip pim send-v6-secondary",
7056 IP_STR
7057 "pim multicast routing\n"
7058 "Send v6 secondary addresses\n")
7059{
db9cca95
SP
7060 const char *vrfname;
7061 char send_v6_secondary_xpath[XPATH_MAXLEN];
71bbe73d 7062
5a1a3920
RZ
7063 vrfname = pim_cli_get_vrf_name(vty);
7064 if (vrfname == NULL)
7065 return CMD_WARNING_CONFIG_FAILED;
db9cca95
SP
7066
7067 snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
698f4147 7068 FRR_PIM_VRF_XPATH,
db9cca95
SP
7069 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7070 strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
7071 sizeof(send_v6_secondary_xpath));
7072
7073 nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
521c5b9d 7074 "true");
db9cca95
SP
7075
7076 return nb_cli_apply_changes(vty, NULL);
71bbe73d
DS
7077}
7078
7079DEFUN (no_ip_pim_v6_secondary,
7080 no_ip_pim_v6_secondary_cmd,
7081 "no ip pim send-v6-secondary",
7082 NO_STR
7083 IP_STR
7084 "pim multicast routing\n"
7085 "Send v6 secondary addresses\n")
7086{
db9cca95
SP
7087 const char *vrfname;
7088 char send_v6_secondary_xpath[XPATH_MAXLEN];
71bbe73d 7089
5a1a3920
RZ
7090 vrfname = pim_cli_get_vrf_name(vty);
7091 if (vrfname == NULL)
7092 return CMD_WARNING_CONFIG_FAILED;
db9cca95
SP
7093
7094 snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
698f4147 7095 FRR_PIM_VRF_XPATH,
db9cca95
SP
7096 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7097 strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
7098 sizeof(send_v6_secondary_xpath));
7099
7100 nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
521c5b9d 7101 "false");
db9cca95
SP
7102
7103 return nb_cli_apply_changes(vty, NULL);
71bbe73d
DS
7104}
7105
13ddf7cf 7106DEFPY (ip_pim_rp,
981d6c7a 7107 ip_pim_rp_cmd,
13ddf7cf 7108 "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
981d6c7a 7109 IP_STR
9b34069d
QY
7110 "pim multicast routing\n"
7111 "Rendevous Point\n"
a957a05b
DS
7112 "ip address of RP\n"
7113 "Group Address range to cover\n")
981d6c7a 7114{
13ddf7cf 7115 const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
7003f636 7116
13ddf7cf 7117 return pim_process_rp_cmd(vty, rp_str, group_str);
dfe43e25
DW
7118}
7119
f39f3497 7120DEFPY (ip_pim_rp_prefix_list,
dfe43e25 7121 ip_pim_rp_prefix_list_cmd,
f39f3497 7122 "ip pim rp A.B.C.D$rp prefix-list WORD$plist",
dfe43e25
DW
7123 IP_STR
7124 "pim multicast routing\n"
f39f3497 7125 "Rendezvous Point\n"
dfe43e25
DW
7126 "ip address of RP\n"
7127 "group prefix-list filter\n"
7128 "Name of a prefix-list\n")
7129{
f39f3497 7130 return pim_process_rp_plist_cmd(vty, rp_str, plist);
981d6c7a
DS
7131}
7132
13ddf7cf 7133DEFPY (no_ip_pim_rp,
981d6c7a 7134 no_ip_pim_rp_cmd,
13ddf7cf 7135 "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
981d6c7a
DS
7136 NO_STR
7137 IP_STR
9b34069d
QY
7138 "pim multicast routing\n"
7139 "Rendevous Point\n"
a957a05b
DS
7140 "ip address of RP\n"
7141 "Group Address range to cover\n")
981d6c7a 7142{
13ddf7cf 7143 const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
7003f636 7144
13ddf7cf 7145 return pim_process_no_rp_cmd(vty, rp_str, group_str);
dfe43e25
DW
7146}
7147
f39f3497 7148DEFPY (no_ip_pim_rp_prefix_list,
dfe43e25 7149 no_ip_pim_rp_prefix_list_cmd,
f39f3497 7150 "no ip pim rp A.B.C.D$rp prefix-list WORD$plist",
dfe43e25
DW
7151 NO_STR
7152 IP_STR
7153 "pim multicast routing\n"
f39f3497 7154 "Rendezvous Point\n"
dfe43e25
DW
7155 "ip address of RP\n"
7156 "group prefix-list filter\n"
7157 "Name of a prefix-list\n")
7158{
f39f3497 7159 return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
15a5dafe 7160}
7161
7162DEFUN (ip_pim_ssm_prefix_list,
7163 ip_pim_ssm_prefix_list_cmd,
7164 "ip pim ssm prefix-list WORD",
7165 IP_STR
7166 "pim multicast routing\n"
7167 "Source Specific Multicast\n"
7168 "group range prefix-list filter\n"
7169 "Name of a prefix-list\n")
7170{
f206085e
SP
7171 const char *vrfname;
7172 char ssm_plist_xpath[XPATH_MAXLEN];
7173
5a1a3920
RZ
7174 vrfname = pim_cli_get_vrf_name(vty);
7175 if (vrfname == NULL)
7176 return CMD_WARNING_CONFIG_FAILED;
f206085e 7177
698f4147 7178 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_VRF_XPATH,
f206085e
SP
7179 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7180 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
7181
7182 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg);
7183
7184 return nb_cli_apply_changes(vty, NULL);
15a5dafe 7185}
7186
7187DEFUN (no_ip_pim_ssm_prefix_list,
7188 no_ip_pim_ssm_prefix_list_cmd,
7189 "no ip pim ssm prefix-list",
7190 NO_STR
7191 IP_STR
7192 "pim multicast routing\n"
7193 "Source Specific Multicast\n"
7194 "group range prefix-list filter\n")
7195{
f206085e
SP
7196 const char *vrfname;
7197 char ssm_plist_xpath[XPATH_MAXLEN];
7198
5a1a3920
RZ
7199 vrfname = pim_cli_get_vrf_name(vty);
7200 if (vrfname == NULL)
7201 return CMD_WARNING_CONFIG_FAILED;
f206085e
SP
7202
7203 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
698f4147 7204 FRR_PIM_VRF_XPATH,
f206085e
SP
7205 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7206 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
7207
7208 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
7209
7210 return nb_cli_apply_changes(vty, NULL);
15a5dafe 7211}
7212
7213DEFUN (no_ip_pim_ssm_prefix_list_name,
7214 no_ip_pim_ssm_prefix_list_name_cmd,
7215 "no ip pim ssm prefix-list WORD",
7216 NO_STR
7217 IP_STR
7218 "pim multicast routing\n"
7219 "Source Specific Multicast\n"
7220 "group range prefix-list filter\n"
7221 "Name of a prefix-list\n")
7222{
f206085e
SP
7223 const char *vrfname;
7224 const struct lyd_node *ssm_plist_dnode;
7225 char ssm_plist_xpath[XPATH_MAXLEN];
7226 const char *ssm_plist_name;
15a5dafe 7227
5a1a3920
RZ
7228 vrfname = pim_cli_get_vrf_name(vty);
7229 if (vrfname == NULL)
7230 return CMD_WARNING_CONFIG_FAILED;
f206085e
SP
7231
7232 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
698f4147 7233 FRR_PIM_VRF_XPATH,
f206085e
SP
7234 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7235 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
7236 ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
521c5b9d 7237 ssm_plist_xpath);
f206085e
SP
7238
7239 if (!ssm_plist_dnode) {
7240 vty_out(vty,
7241 "%% pim ssm prefix-list %s doesn't exist\n",
7242 argv[5]->arg);
7243 return CMD_WARNING_CONFIG_FAILED;
7244 }
7245
7246 ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
7247
7248 if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) {
7249 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY,
521c5b9d 7250 NULL);
f206085e
SP
7251
7252 return nb_cli_apply_changes(vty, NULL);
7253 }
15a5dafe 7254
9643e2c7 7255 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
15a5dafe 7256
d62a17ae 7257 return CMD_WARNING_CONFIG_FAILED;
15a5dafe 7258}
7259
64c86530 7260static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
088f1098 7261 struct vty *vty, bool uj)
15a5dafe 7262{
c68ba0d7 7263 struct pim_ssm *ssm = pim->ssm_info;
d62a17ae 7264 const char *range_str =
7265 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
15a5dafe 7266
d62a17ae 7267 if (uj) {
7268 json_object *json;
7269 json = json_object_new_object();
7270 json_object_string_add(json, "ssmGroups", range_str);
3757f964 7271 vty_json(vty, json);
d62a17ae 7272 } else
7273 vty_out(vty, "SSM group range : %s\n", range_str);
15a5dafe 7274}
7275
7276DEFUN (show_ip_pim_ssm_range,
7277 show_ip_pim_ssm_range_cmd,
20a7e5fd 7278 "show ip pim [vrf NAME] group-type [json]",
15a5dafe 7279 SHOW_STR
7280 IP_STR
7281 PIM_STR
c68ba0d7 7282 VRF_CMD_HELP_STR
15a5dafe 7283 "PIM group type\n"
f5da2cc2 7284 JSON_STR)
15a5dafe 7285{
c68ba0d7
DS
7286 int idx = 2;
7287 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 7288 bool uj = use_json(argc, argv);
c68ba0d7
DS
7289
7290 if (!vrf)
7291 return CMD_WARNING;
7292
64c86530 7293 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
15a5dafe 7294
d62a17ae 7295 return CMD_SUCCESS;
15a5dafe 7296}
7297
64c86530 7298static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
088f1098 7299 struct vty *vty, bool uj,
d62a17ae 7300 const char *group)
15a5dafe 7301{
d62a17ae 7302 struct in_addr group_addr;
7303 const char *type_str;
7304 int result;
15a5dafe 7305
d62a17ae 7306 result = inet_pton(AF_INET, group, &group_addr);
7307 if (result <= 0)
7308 type_str = "invalid";
7309 else {
7310 if (pim_is_group_224_4(group_addr))
c68ba0d7
DS
7311 type_str =
7312 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
d62a17ae 7313 else
7314 type_str = "not-multicast";
7315 }
15a5dafe 7316
d62a17ae 7317 if (uj) {
7318 json_object *json;
7319 json = json_object_new_object();
7320 json_object_string_add(json, "groupType", type_str);
3757f964 7321 vty_json(vty, json);
d62a17ae 7322 } else
7323 vty_out(vty, "Group type : %s\n", type_str);
15a5dafe 7324}
7325
7326DEFUN (show_ip_pim_group_type,
7327 show_ip_pim_group_type_cmd,
20a7e5fd 7328 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
15a5dafe 7329 SHOW_STR
7330 IP_STR
7331 PIM_STR
c68ba0d7 7332 VRF_CMD_HELP_STR
15a5dafe 7333 "multicast group type\n"
7334 "group address\n"
f5da2cc2 7335 JSON_STR)
15a5dafe 7336{
c68ba0d7
DS
7337 int idx = 2;
7338 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 7339 bool uj = use_json(argc, argv);
c68ba0d7
DS
7340
7341 if (!vrf)
7342 return CMD_WARNING;
7343
7344 argv_find(argv, argc, "A.B.C.D", &idx);
64c86530 7345 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
15a5dafe 7346
d62a17ae 7347 return CMD_SUCCESS;
15a5dafe 7348}
7349
256392eb 7350DEFUN (show_ip_pim_bsr,
7351 show_ip_pim_bsr_cmd,
7352 "show ip pim bsr [json]",
7353 SHOW_STR
7354 IP_STR
7355 PIM_STR
7356 "boot-strap router information\n"
7357 JSON_STR)
7358{
7359 int idx = 2;
7360 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
7361 bool uj = use_json(argc, argv);
7362
7363 if (!vrf)
7364 return CMD_WARNING;
7365
7366 pim_show_bsr(vrf->info, vty, uj);
7367
7368 return CMD_SUCCESS;
7369}
7370
12e41d03
DL
7371DEFUN (ip_ssmpingd,
7372 ip_ssmpingd_cmd,
7373 "ip ssmpingd [A.B.C.D]",
7374 IP_STR
7375 CONF_SSMPINGD_STR
7376 "Source address\n")
7377{
d62a17ae 7378 int idx_ipv4 = 2;
d62a17ae 7379 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
f206085e
SP
7380 const char *vrfname;
7381 char ssmpingd_ip_xpath[XPATH_MAXLEN];
12e41d03 7382
5a1a3920
RZ
7383 vrfname = pim_cli_get_vrf_name(vty);
7384 if (vrfname == NULL)
7385 return CMD_WARNING_CONFIG_FAILED;
12e41d03 7386
f206085e 7387 snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
698f4147 7388 FRR_PIM_VRF_XPATH,
f206085e
SP
7389 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7390 strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
7391 sizeof(ssmpingd_ip_xpath));
12e41d03 7392
f206085e 7393 nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_CREATE,
521c5b9d 7394 source_str);
12e41d03 7395
f206085e 7396 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
7397}
7398
7399DEFUN (no_ip_ssmpingd,
7400 no_ip_ssmpingd_cmd,
7401 "no ip ssmpingd [A.B.C.D]",
7402 NO_STR
7403 IP_STR
7404 CONF_SSMPINGD_STR
7405 "Source address\n")
7406{
f206085e 7407 const char *vrfname;
d62a17ae 7408 int idx_ipv4 = 3;
d62a17ae 7409 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
f206085e 7410 char ssmpingd_ip_xpath[XPATH_MAXLEN];
12e41d03 7411
5a1a3920
RZ
7412 vrfname = pim_cli_get_vrf_name(vty);
7413 if (vrfname == NULL)
7414 return CMD_WARNING_CONFIG_FAILED;
12e41d03 7415
f206085e 7416 snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
698f4147 7417 FRR_PIM_VRF_XPATH,
f206085e
SP
7418 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7419 strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
7420 sizeof(ssmpingd_ip_xpath));
12e41d03 7421
f206085e 7422 nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_DESTROY,
521c5b9d 7423 source_str);
f206085e
SP
7424
7425 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
7426}
7427
cba44481
CS
7428DEFUN (ip_pim_ecmp,
7429 ip_pim_ecmp_cmd,
7430 "ip pim ecmp",
7431 IP_STR
7432 "pim multicast routing\n"
7433 "Enable PIM ECMP \n")
7434{
49c6b2aa
SP
7435 const char *vrfname;
7436 char ecmp_xpath[XPATH_MAXLEN];
cba44481 7437
5a1a3920
RZ
7438 vrfname = pim_cli_get_vrf_name(vty);
7439 if (vrfname == NULL)
7440 return CMD_WARNING_CONFIG_FAILED;
49c6b2aa 7441
698f4147 7442 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
7443 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
7444 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
7445
7446 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
7447 return nb_cli_apply_changes(vty, NULL);
cba44481
CS
7448}
7449
7450DEFUN (no_ip_pim_ecmp,
7451 no_ip_pim_ecmp_cmd,
7452 "no ip pim ecmp",
7453 NO_STR
7454 IP_STR
7455 "pim multicast routing\n"
7456 "Disable PIM ECMP \n")
7457{
49c6b2aa
SP
7458 const char *vrfname;
7459 char ecmp_xpath[XPATH_MAXLEN];
cba44481 7460
5a1a3920
RZ
7461 vrfname = pim_cli_get_vrf_name(vty);
7462 if (vrfname == NULL)
7463 return CMD_WARNING_CONFIG_FAILED;
49c6b2aa 7464
698f4147 7465 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
7466 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
7467 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
7468
7469 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false");
7470
7471 return nb_cli_apply_changes(vty, NULL);
cba44481
CS
7472}
7473
7474DEFUN (ip_pim_ecmp_rebalance,
7475 ip_pim_ecmp_rebalance_cmd,
7476 "ip pim ecmp rebalance",
7477 IP_STR
7478 "pim multicast routing\n"
7479 "Enable PIM ECMP \n"
7480 "Enable PIM ECMP Rebalance\n")
7481{
49c6b2aa
SP
7482 const char *vrfname;
7483 char ecmp_xpath[XPATH_MAXLEN];
7484 char ecmp_rebalance_xpath[XPATH_MAXLEN];
cba44481 7485
5a1a3920
RZ
7486 vrfname = pim_cli_get_vrf_name(vty);
7487 if (vrfname == NULL)
7488 return CMD_WARNING_CONFIG_FAILED;
49c6b2aa 7489
698f4147 7490 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
7491 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
7492 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
7493 snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
698f4147 7494 FRR_PIM_VRF_XPATH,
7495 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
7496 strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
7497 sizeof(ecmp_rebalance_xpath));
7498
7499 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
7500 nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true");
7501
7502 return nb_cli_apply_changes(vty, NULL);
cba44481
CS
7503}
7504
7505DEFUN (no_ip_pim_ecmp_rebalance,
7506 no_ip_pim_ecmp_rebalance_cmd,
7507 "no ip pim ecmp rebalance",
7508 NO_STR
7509 IP_STR
7510 "pim multicast routing\n"
7511 "Disable PIM ECMP \n"
7512 "Disable PIM ECMP Rebalance\n")
7513{
49c6b2aa
SP
7514 const char *vrfname;
7515 char ecmp_rebalance_xpath[XPATH_MAXLEN];
cba44481 7516
5a1a3920
RZ
7517 vrfname = pim_cli_get_vrf_name(vty);
7518 if (vrfname == NULL)
7519 return CMD_WARNING_CONFIG_FAILED;
12e41d03 7520
49c6b2aa 7521 snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
698f4147 7522 FRR_PIM_VRF_XPATH,
7523 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
7524 strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
7525 sizeof(ecmp_rebalance_xpath));
12e41d03 7526
49c6b2aa
SP
7527 nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false");
7528
7529 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
7530}
7531
21419f59
DS
7532DEFUN (interface_ip_igmp,
7533 interface_ip_igmp_cmd,
7534 "ip igmp",
7535 IP_STR
7536 IFACE_IGMP_STR)
7537{
3051f443 7538 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
21419f59 7539
3051f443 7540 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7541 "frr-routing:ipv4");
21419f59
DS
7542}
7543
12e41d03
DL
7544DEFUN (interface_no_ip_igmp,
7545 interface_no_ip_igmp_cmd,
7546 "no ip igmp",
7547 NO_STR
7548 IP_STR
7549 IFACE_IGMP_STR)
7550{
b0475d5a 7551 const struct lyd_node *pim_enable_dnode;
d7073b21 7552 char pim_if_xpath[XPATH_MAXLEN];
12e41d03 7553
d7073b21
QY
7554 int printed =
7555 snprintf(pim_if_xpath, sizeof(pim_if_xpath),
7556 "%s/frr-pim:pim/address-family[address-family='%s']",
7557 VTY_CURR_XPATH, "frr-routing:ipv4");
7558
7559 if (printed >= (int)(sizeof(pim_if_xpath))) {
7560 vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
7561 XPATH_MAXLEN);
7562 return CMD_WARNING_CONFIG_FAILED;
7563 }
12e41d03 7564
3bb513c3 7565 pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7566 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7567 "frr-routing:ipv4");
b0475d5a
SP
7568 if (!pim_enable_dnode) {
7569 nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY, NULL);
7570 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7571 } else {
7572 if (!yang_dnode_get_bool(pim_enable_dnode, ".")) {
7573 nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY,
5c90f569 7574 NULL);
b0475d5a
SP
7575 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7576 } else
3051f443 7577 nb_cli_enqueue_change(vty, "./enable",
5c90f569 7578 NB_OP_MODIFY, "false");
d62a17ae 7579 }
12e41d03 7580
3051f443 7581 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7582 "frr-routing:ipv4");
12e41d03
DL
7583}
7584
7585DEFUN (interface_ip_igmp_join,
7586 interface_ip_igmp_join_cmd,
771ce8ad 7587 "ip igmp join A.B.C.D [A.B.C.D]",
12e41d03
DL
7588 IP_STR
7589 IFACE_IGMP_STR
7590 "IGMP join multicast group\n"
7591 "Multicast group address\n"
7592 "Source address\n")
7593{
b0475d5a
SP
7594 int idx_group = 3;
7595 int idx_source = 4;
d62a17ae 7596 const char *source_str;
b0475d5a 7597 char xpath[XPATH_MAXLEN];
d62a17ae 7598
b0475d5a
SP
7599 if (argc == 5) {
7600 source_str = argv[idx_source]->arg;
d62a17ae 7601
b0475d5a
SP
7602 if (strcmp(source_str, "0.0.0.0") == 0) {
7603 vty_out(vty, "Bad source address %s\n",
521c5b9d 7604 argv[idx_source]->arg);
771ce8ad
LM
7605 return CMD_WARNING_CONFIG_FAILED;
7606 }
b0475d5a
SP
7607 } else
7608 source_str = "0.0.0.0";
d62a17ae 7609
3051f443 7610 snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
521c5b9d 7611 "frr-routing:ipv4", argv[idx_group]->arg, source_str);
d62a17ae 7612
b0475d5a
SP
7613 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
7614
7615 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
7616}
7617
7618DEFUN (interface_no_ip_igmp_join,
7619 interface_no_ip_igmp_join_cmd,
771ce8ad 7620 "no ip igmp join A.B.C.D [A.B.C.D]",
12e41d03
DL
7621 NO_STR
7622 IP_STR
7623 IFACE_IGMP_STR
7624 "IGMP join multicast group\n"
7625 "Multicast group address\n"
7626 "Source address\n")
7627{
b0475d5a
SP
7628 int idx_group = 4;
7629 int idx_source = 5;
d62a17ae 7630 const char *source_str;
b0475d5a 7631 char xpath[XPATH_MAXLEN];
d62a17ae 7632
b0475d5a
SP
7633 if (argc == 6) {
7634 source_str = argv[idx_source]->arg;
d62a17ae 7635
b0475d5a
SP
7636 if (strcmp(source_str, "0.0.0.0") == 0) {
7637 vty_out(vty, "Bad source address %s\n",
521c5b9d 7638 argv[idx_source]->arg);
771ce8ad
LM
7639 return CMD_WARNING_CONFIG_FAILED;
7640 }
b0475d5a
SP
7641 } else
7642 source_str = "0.0.0.0";
d62a17ae 7643
3051f443 7644 snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
521c5b9d 7645 "frr-routing:ipv4", argv[idx_group]->arg, source_str);
d62a17ae 7646
b0475d5a 7647 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
d62a17ae 7648
b0475d5a 7649 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
7650}
7651
12e41d03
DL
7652DEFUN (interface_ip_igmp_query_interval,
7653 interface_ip_igmp_query_interval_cmd,
11ca3587 7654 "ip igmp query-interval (1-65535)",
12e41d03
DL
7655 IP_STR
7656 IFACE_IGMP_STR
7657 IFACE_IGMP_QUERY_INTERVAL_STR
7658 "Query interval in seconds\n")
7659{
b0475d5a 7660 const struct lyd_node *pim_enable_dnode;
d62a17ae 7661
3bb513c3
CH
7662 pim_enable_dnode =
7663 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7664 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7665 "frr-routing:ipv4");
b0475d5a 7666 if (!pim_enable_dnode) {
698f4147 7667 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7668 "true");
b0475d5a
SP
7669 } else {
7670 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 7671 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 7672 NB_OP_MODIFY, "true");
d62a17ae 7673 }
7674
b0475d5a 7675 nb_cli_enqueue_change(vty, "./query-interval", NB_OP_MODIFY,
521c5b9d 7676 argv[3]->arg);
d62a17ae 7677
3051f443 7678 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7679 "frr-routing:ipv4");
12e41d03
DL
7680}
7681
7682DEFUN (interface_no_ip_igmp_query_interval,
7683 interface_no_ip_igmp_query_interval_cmd,
11ca3587 7684 "no ip igmp query-interval [(1-65535)]",
12e41d03
DL
7685 NO_STR
7686 IP_STR
7687 IFACE_IGMP_STR
11ca3587
CH
7688 IFACE_IGMP_QUERY_INTERVAL_STR
7689 IGNORED_IN_NO_STR)
12e41d03 7690{
11ca3587 7691 nb_cli_enqueue_change(vty, "./query-interval", NB_OP_DESTROY, NULL);
12e41d03 7692
3051f443 7693 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7694 "frr-routing:ipv4");
12e41d03
DL
7695}
7696
b05b72e8
DW
7697DEFUN (interface_ip_igmp_version,
7698 interface_ip_igmp_version_cmd,
72e81cf4 7699 "ip igmp version (2-3)",
b05b72e8
DW
7700 IP_STR
7701 IFACE_IGMP_STR
7702 "IGMP version\n"
7703 "IGMP version number\n")
7704{
3051f443 7705 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7706 "true");
3051f443 7707 nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_MODIFY,
7708 argv[3]->arg);
d62a17ae 7709
3051f443 7710 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7711 "frr-routing:ipv4");
b05b72e8
DW
7712}
7713
7714DEFUN (interface_no_ip_igmp_version,
7715 interface_no_ip_igmp_version_cmd,
72e81cf4 7716 "no ip igmp version (2-3)",
b05b72e8
DW
7717 NO_STR
7718 IP_STR
7719 IFACE_IGMP_STR
7720 "IGMP version\n"
7721 "IGMP version number\n")
7722{
3051f443 7723 nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_DESTROY, NULL);
b05b72e8 7724
3051f443 7725 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7726 "frr-routing:ipv4");
b05b72e8
DW
7727}
7728
12e41d03
DL
7729DEFUN (interface_ip_igmp_query_max_response_time,
7730 interface_ip_igmp_query_max_response_time_cmd,
11ca3587 7731 "ip igmp query-max-response-time (1-65535)",
12e41d03
DL
7732 IP_STR
7733 IFACE_IGMP_STR
7734 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
58344b65 7735 "Query response value in deci-seconds\n")
12e41d03 7736{
b0475d5a 7737 const struct lyd_node *pim_enable_dnode;
12e41d03 7738
3bb513c3
CH
7739 pim_enable_dnode =
7740 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7741 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7742 "frr-routing:ipv4");
12e41d03 7743
b0475d5a 7744 if (!pim_enable_dnode) {
3051f443 7745 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7746 "true");
b0475d5a
SP
7747 } else {
7748 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 7749 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 7750 NB_OP_MODIFY, "true");
d62a17ae 7751 }
12e41d03 7752
b0475d5a 7753 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
521c5b9d 7754 argv[3]->arg);
12e41d03 7755
3051f443 7756 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7757 "frr-routing:ipv4");
12e41d03
DL
7758}
7759
7760DEFUN (interface_no_ip_igmp_query_max_response_time,
7761 interface_no_ip_igmp_query_max_response_time_cmd,
11ca3587 7762 "no ip igmp query-max-response-time [(1-65535)]",
12e41d03
DL
7763 NO_STR
7764 IP_STR
7765 IFACE_IGMP_STR
a957a05b 7766 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
11ca3587 7767 IGNORED_IN_NO_STR)
12e41d03 7768{
11ca3587
CH
7769 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
7770 NULL);
3051f443 7771 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7772 "frr-routing:ipv4");
12e41d03
DL
7773}
7774
58344b65
DS
7775DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
7776 interface_ip_igmp_query_max_response_time_dsec_cmd,
11ca3587 7777 "ip igmp query-max-response-time-dsec (1-65535)",
58344b65
DS
7778 IP_STR
7779 IFACE_IGMP_STR
7780 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7781 "Query response value in deciseconds\n")
12e41d03 7782{
b0475d5a 7783 const struct lyd_node *pim_enable_dnode;
d62a17ae 7784
3bb513c3
CH
7785 pim_enable_dnode =
7786 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7787 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7788 "frr-routing:ipv4");
b0475d5a 7789 if (!pim_enable_dnode) {
3051f443 7790 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7791 "true");
b0475d5a
SP
7792 } else {
7793 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 7794 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 7795 NB_OP_MODIFY, "true");
d62a17ae 7796 }
12e41d03 7797
b0475d5a 7798 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
521c5b9d 7799 argv[3]->arg);
12e41d03 7800
3051f443 7801 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7802 "frr-routing:ipv4");
12e41d03
DL
7803}
7804
58344b65
DS
7805DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
7806 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
11ca3587 7807 "no ip igmp query-max-response-time-dsec [(1-65535)]",
58344b65
DS
7808 NO_STR
7809 IP_STR
7810 IFACE_IGMP_STR
11ca3587
CH
7811 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7812 IGNORED_IN_NO_STR)
12e41d03 7813{
11ca3587
CH
7814 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
7815 NULL);
12e41d03 7816
3051f443 7817 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7818 "frr-routing:ipv4");
12e41d03
DL
7819}
7820
59115451
SP
7821DEFUN (interface_ip_igmp_last_member_query_count,
7822 interface_ip_igmp_last_member_query_count_cmd,
11ca3587 7823 "ip igmp last-member-query-count (1-255)",
59115451
SP
7824 IP_STR
7825 IFACE_IGMP_STR
7826 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7827 "Last member query count\n")
7828{
b0475d5a 7829 const struct lyd_node *pim_enable_dnode;
59115451 7830
3bb513c3
CH
7831 pim_enable_dnode =
7832 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7833 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7834 "frr-routing:ipv4");
b0475d5a 7835 if (!pim_enable_dnode) {
3051f443 7836 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7837 "true");
b0475d5a
SP
7838 } else {
7839 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 7840 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 7841 NB_OP_MODIFY, "true");
59115451
SP
7842 }
7843
b0475d5a 7844 nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_MODIFY,
521c5b9d 7845 argv[3]->arg);
59115451 7846
3051f443 7847 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7848 "frr-routing:ipv4");
59115451
SP
7849}
7850
7851DEFUN (interface_no_ip_igmp_last_member_query_count,
7852 interface_no_ip_igmp_last_member_query_count_cmd,
11ca3587 7853 "no ip igmp last-member-query-count [(1-255)]",
59115451
SP
7854 NO_STR
7855 IP_STR
7856 IFACE_IGMP_STR
bb9ff200 7857 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
11ca3587 7858 IGNORED_IN_NO_STR)
59115451 7859{
11ca3587
CH
7860 nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_DESTROY,
7861 NULL);
59115451 7862
3051f443 7863 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7864 "frr-routing:ipv4");
59115451
SP
7865}
7866
59115451
SP
7867DEFUN (interface_ip_igmp_last_member_query_interval,
7868 interface_ip_igmp_last_member_query_interval_cmd,
11ca3587 7869 "ip igmp last-member-query-interval (1-65535)",
59115451
SP
7870 IP_STR
7871 IFACE_IGMP_STR
7872 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7873 "Last member query interval in deciseconds\n")
7874{
b0475d5a 7875 const struct lyd_node *pim_enable_dnode;
59115451 7876
3bb513c3
CH
7877 pim_enable_dnode =
7878 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7879 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7880 "frr-routing:ipv4");
b0475d5a 7881 if (!pim_enable_dnode) {
3051f443 7882 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7883 "true");
b0475d5a
SP
7884 } else {
7885 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 7886 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 7887 NB_OP_MODIFY, "true");
59115451
SP
7888 }
7889
b0475d5a 7890 nb_cli_enqueue_change(vty, "./last-member-query-interval", NB_OP_MODIFY,
521c5b9d 7891 argv[3]->arg);
59115451 7892
3051f443 7893 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7894 "frr-routing:ipv4");
59115451
SP
7895}
7896
7897DEFUN (interface_no_ip_igmp_last_member_query_interval,
7898 interface_no_ip_igmp_last_member_query_interval_cmd,
11ca3587 7899 "no ip igmp last-member-query-interval [(1-65535)]",
59115451
SP
7900 NO_STR
7901 IP_STR
7902 IFACE_IGMP_STR
bb9ff200 7903 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
11ca3587 7904 IGNORED_IN_NO_STR)
59115451 7905{
11ca3587
CH
7906 nb_cli_enqueue_change(vty, "./last-member-query-interval",
7907 NB_OP_DESTROY, NULL);
59115451 7908
3051f443 7909 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7910 "frr-routing:ipv4");
59115451
SP
7911}
7912
dedccda6
DS
7913DEFUN (interface_ip_pim_drprio,
7914 interface_ip_pim_drprio_cmd,
b181fa04 7915 "ip pim drpriority (1-4294967295)",
dedccda6
DS
7916 IP_STR
7917 PIM_STR
7918 "Set the Designated Router Election Priority\n"
7919 "Value of the new DR Priority\n")
7920{
d62a17ae 7921 int idx_number = 3;
dedccda6 7922
bb387611 7923 return pim_process_ip_pim_drprio_cmd(vty, argv[idx_number]->arg);
dedccda6
DS
7924}
7925
7926DEFUN (interface_no_ip_pim_drprio,
7927 interface_no_ip_pim_drprio_cmd,
b181fa04 7928 "no ip pim drpriority [(1-4294967295)]",
d7fa34c1 7929 NO_STR
dedccda6
DS
7930 IP_STR
7931 PIM_STR
7932 "Revert the Designated Router Priority to default\n"
7933 "Old Value of the Priority\n")
7934{
bb387611 7935 return pim_process_no_ip_pim_drprio_cmd(vty);
dedccda6
DS
7936}
7937
6741a5bb 7938DEFPY_HIDDEN (interface_ip_igmp_query_generate,
521c5b9d
MS
7939 interface_ip_igmp_query_generate_cmd,
7940 "ip igmp generate-query-once [version (2-3)]",
7941 IP_STR
7942 IFACE_IGMP_STR
7943 "Generate igmp general query once\n"
7944 "IGMP version\n"
7945 "IGMP version number\n")
6741a5bb 7946{
5a46a3de 7947#if PIM_IPV == 4
6741a5bb 7948 VTY_DECLVAR_CONTEXT(interface, ifp);
761e4fba 7949 int igmp_version;
7950 struct pim_interface *pim_ifp = ifp->info;
6741a5bb 7951
7952 if (!ifp->info) {
7953 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
7954 ifp->name);
7955 return CMD_WARNING_CONFIG_FAILED;
7956 }
7957
761e4fba 7958 /* It takes the igmp version configured on the interface as default */
dfc26ad1 7959 igmp_version = pim_ifp->igmp_version;
761e4fba 7960
6741a5bb 7961 if (argc > 3)
7962 igmp_version = atoi(argv[4]->arg);
7963
7964 igmp_send_query_on_intf(ifp, igmp_version);
5a46a3de 7965#endif
6741a5bb 7966 return CMD_SUCCESS;
7967}
7968
70fd22bd
DS
7969DEFPY_HIDDEN (pim_test_sg_keepalive,
7970 pim_test_sg_keepalive_cmd,
7971 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7972 "Test code\n"
7973 PIM_STR
7974 VRF_CMD_HELP_STR
7975 "Reset the Keepalive Timer\n"
7976 "The Source we are resetting\n"
7977 "The Group we are resetting\n")
7978{
7979 struct pim_upstream *up;
7980 struct pim_instance *pim;
6fff2cc6 7981 pim_sgaddr sg;
70fd22bd
DS
7982
7983 sg.src = source;
7984 sg.grp = group;
7985
7986 if (!name)
7987 pim = pim_get_pim_instance(VRF_DEFAULT);
7988 else {
7989 struct vrf *vrf = vrf_lookup_by_name(name);
7990
7991 if (!vrf) {
7992 vty_out(vty, "%% Vrf specified: %s does not exist\n",
7993 name);
7994 return CMD_WARNING;
7995 }
7996
7997 pim = pim_get_pim_instance(vrf->vrf_id);
7998 }
7999
8000 if (!pim) {
8001 vty_out(vty, "%% Unable to find pim instance\n");
8002 return CMD_WARNING;
8003 }
8004
8005 up = pim_upstream_find(pim, &sg);
8006 if (!up) {
98a81d2b 8007 vty_out(vty, "%% Unable to find %pSG specified\n", &sg);
70fd22bd
DS
8008 return CMD_WARNING;
8009 }
8010
98a81d2b
DL
8011 vty_out(vty, "Setting %pSG to current keep alive time: %d\n", &sg,
8012 pim->keep_alive_time);
70fd22bd
DS
8013 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
8014
8015 return CMD_SUCCESS;
8016}
8017
17823cdd
DS
8018DEFPY (interface_ip_pim_activeactive,
8019 interface_ip_pim_activeactive_cmd,
8020 "[no$no] ip pim active-active",
8021 NO_STR
8022 IP_STR
8023 PIM_STR
8024 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
414d885a 8025{
7e01b641 8026 return pim_process_ip_pim_activeactive_cmd(vty, no);
414d885a
DS
8027}
8028
d2772e7b 8029DEFUN_HIDDEN (interface_ip_pim_ssm,
521c5b9d
MS
8030 interface_ip_pim_ssm_cmd,
8031 "ip pim ssm",
8032 IP_STR
8033 PIM_STR
8034 IFACE_PIM_STR)
981d6c7a 8035{
50d194f8 8036 int ret;
43e40fdf 8037
dab0ac29 8038 ret = pim_process_ip_pim_cmd(vty);
981d6c7a 8039
50d194f8
SP
8040 if (ret != NB_OK)
8041 return ret;
ecca97ac 8042
50d194f8
SP
8043 vty_out(vty,
8044 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
c992c9a0 8045
50d194f8 8046 return NB_OK;
981d6c7a
DS
8047}
8048
2f5e937c 8049DEFUN_HIDDEN (interface_ip_pim_sm,
521c5b9d
MS
8050 interface_ip_pim_sm_cmd,
8051 "ip pim sm",
8052 IP_STR
8053 PIM_STR
8054 IFACE_PIM_SM_STR)
2f5e937c 8055{
2b16b40f 8056 return pim_process_ip_pim_cmd(vty);
2f5e937c 8057}
8058
8059DEFUN (interface_ip_pim,
8060 interface_ip_pim_cmd,
8061 "ip pim",
8062 IP_STR
8063 PIM_STR)
8064{
a1caf7a8 8065 return pim_process_ip_pim_cmd(vty);
2f5e937c 8066}
8067
d2772e7b 8068DEFUN_HIDDEN (interface_no_ip_pim_ssm,
521c5b9d
MS
8069 interface_no_ip_pim_ssm_cmd,
8070 "no ip pim ssm",
8071 NO_STR
8072 IP_STR
8073 PIM_STR
8074 IFACE_PIM_STR)
981d6c7a 8075{
dab0ac29 8076 return pim_process_no_ip_pim_cmd(vty);
981d6c7a
DS
8077}
8078
2f5e937c 8079DEFUN_HIDDEN (interface_no_ip_pim_sm,
521c5b9d
MS
8080 interface_no_ip_pim_sm_cmd,
8081 "no ip pim sm",
8082 NO_STR
8083 IP_STR
8084 PIM_STR
8085 IFACE_PIM_SM_STR)
981d6c7a 8086{
2b16b40f 8087 return pim_process_no_ip_pim_cmd(vty);
2f5e937c 8088}
981d6c7a 8089
2f5e937c 8090DEFUN (interface_no_ip_pim,
8091 interface_no_ip_pim_cmd,
8092 "no ip pim",
8093 NO_STR
8094 IP_STR
8095 PIM_STR)
8096{
dab0ac29 8097 return pim_process_no_ip_pim_cmd(vty);
12e41d03
DL
8098}
8099
b0f525a8
QY
8100/* boundaries */
8101DEFUN(interface_ip_pim_boundary_oil,
8102 interface_ip_pim_boundary_oil_cmd,
8103 "ip multicast boundary oil WORD",
8104 IP_STR
8105 "Generic multicast configuration options\n"
8106 "Define multicast boundary\n"
8107 "Filter OIL by group using prefix list\n"
513c8462 8108 "Prefix list to filter OIL with\n")
b0f525a8 8109{
52c52d78 8110 return pim_process_ip_pim_boundary_oil_cmd(vty, argv[4]->arg);
b0f525a8
QY
8111}
8112
8113DEFUN(interface_no_ip_pim_boundary_oil,
8114 interface_no_ip_pim_boundary_oil_cmd,
8115 "no ip multicast boundary oil [WORD]",
8116 NO_STR
8117 IP_STR
8118 "Generic multicast configuration options\n"
8119 "Define multicast boundary\n"
8120 "Filter OIL by group using prefix list\n"
513c8462 8121 "Prefix list to filter OIL with\n")
b0f525a8 8122{
52c52d78 8123 return pim_process_no_ip_pim_boundary_oil_cmd(vty);
b0f525a8
QY
8124}
8125
6250610a
JAG
8126DEFUN (interface_ip_mroute,
8127 interface_ip_mroute_cmd,
e57cc5f0 8128 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
6250610a
JAG
8129 IP_STR
8130 "Add multicast route\n"
8131 "Outgoing interface name\n"
8132 "Group address\n"
8133 "Source address\n")
8134{
d62a17ae 8135 int idx_interface = 2;
8136 int idx_ipv4 = 3;
675c8fde 8137 const char *source_str;
d62a17ae 8138
675c8fde
SP
8139 if (argc == (idx_ipv4 + 1))
8140 source_str = "0.0.0.0";
8141 else
8142 source_str = argv[idx_ipv4 + 1]->arg;
d62a17ae 8143
63ee25c0 8144 return pim_process_ip_mroute_cmd(vty, argv[idx_interface]->arg,
8145 argv[idx_ipv4]->arg, source_str);
6250610a
JAG
8146}
8147
8148DEFUN (interface_no_ip_mroute,
8149 interface_no_ip_mroute_cmd,
e57cc5f0 8150 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
6250610a
JAG
8151 NO_STR
8152 IP_STR
8153 "Add multicast route\n"
8154 "Outgoing interface name\n"
8155 "Group Address\n"
8156 "Source Address\n")
8157{
63ee25c0 8158 int idx_interface = 3;
d62a17ae 8159 int idx_ipv4 = 4;
675c8fde 8160 const char *source_str;
d62a17ae 8161
675c8fde
SP
8162 if (argc == (idx_ipv4 + 1))
8163 source_str = "0.0.0.0";
8164 else
8165 source_str = argv[idx_ipv4 + 1]->arg;
d62a17ae 8166
63ee25c0 8167 return pim_process_no_ip_mroute_cmd(vty, argv[idx_interface]->arg,
8168 argv[idx_ipv4]->arg, source_str);
6250610a
JAG
8169}
8170
7960fa8f
DS
8171DEFUN (interface_ip_pim_hello,
8172 interface_ip_pim_hello_cmd,
11ca3587 8173 "ip pim hello (1-65535) [(1-65535)]",
7960fa8f
DS
8174 IP_STR
8175 PIM_STR
8176 IFACE_PIM_HELLO_STR
80d3d26b
DW
8177 IFACE_PIM_HELLO_TIME_STR
8178 IFACE_PIM_HELLO_HOLD_STR)
7960fa8f 8179{
d62a17ae 8180 int idx_time = 3;
8181 int idx_hold = 4;
7960fa8f 8182
d62a17ae 8183 if (argc == idx_hold + 1)
e6aab613 8184 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
8185 argv[idx_hold]->arg);
7960fa8f 8186
e6aab613 8187 else
8188 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
8189 NULL);
7960fa8f
DS
8190}
8191
7960fa8f
DS
8192DEFUN (interface_no_ip_pim_hello,
8193 interface_no_ip_pim_hello_cmd,
11ca3587 8194 "no ip pim hello [(1-65535) [(1-65535)]]",
7960fa8f
DS
8195 NO_STR
8196 IP_STR
8197 PIM_STR
8198 IFACE_PIM_HELLO_STR
11ca3587
CH
8199 IGNORED_IN_NO_STR
8200 IGNORED_IN_NO_STR)
7960fa8f 8201{
e6aab613 8202 return pim_process_no_ip_pim_hello_cmd(vty);
7960fa8f
DS
8203}
8204
12e41d03
DL
8205DEFUN (debug_igmp,
8206 debug_igmp_cmd,
8207 "debug igmp",
8208 DEBUG_STR
8209 DEBUG_IGMP_STR)
8210{
d62a17ae 8211 PIM_DO_DEBUG_IGMP_EVENTS;
8212 PIM_DO_DEBUG_IGMP_PACKETS;
8213 PIM_DO_DEBUG_IGMP_TRACE;
8214 return CMD_SUCCESS;
12e41d03
DL
8215}
8216
8217DEFUN (no_debug_igmp,
8218 no_debug_igmp_cmd,
8219 "no debug igmp",
8220 NO_STR
8221 DEBUG_STR
8222 DEBUG_IGMP_STR)
8223{
d62a17ae 8224 PIM_DONT_DEBUG_IGMP_EVENTS;
8225 PIM_DONT_DEBUG_IGMP_PACKETS;
8226 PIM_DONT_DEBUG_IGMP_TRACE;
8227 return CMD_SUCCESS;
12e41d03
DL
8228}
8229
12e41d03
DL
8230
8231DEFUN (debug_igmp_events,
8232 debug_igmp_events_cmd,
8233 "debug igmp events",
8234 DEBUG_STR
8235 DEBUG_IGMP_STR
8236 DEBUG_IGMP_EVENTS_STR)
8237{
d62a17ae 8238 PIM_DO_DEBUG_IGMP_EVENTS;
8239 return CMD_SUCCESS;
12e41d03
DL
8240}
8241
8242DEFUN (no_debug_igmp_events,
8243 no_debug_igmp_events_cmd,
8244 "no debug igmp events",
8245 NO_STR
8246 DEBUG_STR
8247 DEBUG_IGMP_STR
8248 DEBUG_IGMP_EVENTS_STR)
8249{
d62a17ae 8250 PIM_DONT_DEBUG_IGMP_EVENTS;
8251 return CMD_SUCCESS;
12e41d03
DL
8252}
8253
12e41d03
DL
8254
8255DEFUN (debug_igmp_packets,
8256 debug_igmp_packets_cmd,
8257 "debug igmp packets",
8258 DEBUG_STR
8259 DEBUG_IGMP_STR
8260 DEBUG_IGMP_PACKETS_STR)
8261{
d62a17ae 8262 PIM_DO_DEBUG_IGMP_PACKETS;
8263 return CMD_SUCCESS;
12e41d03
DL
8264}
8265
8266DEFUN (no_debug_igmp_packets,
8267 no_debug_igmp_packets_cmd,
8268 "no debug igmp packets",
8269 NO_STR
8270 DEBUG_STR
8271 DEBUG_IGMP_STR
8272 DEBUG_IGMP_PACKETS_STR)
8273{
d62a17ae 8274 PIM_DONT_DEBUG_IGMP_PACKETS;
8275 return CMD_SUCCESS;
12e41d03
DL
8276}
8277
12e41d03
DL
8278
8279DEFUN (debug_igmp_trace,
8280 debug_igmp_trace_cmd,
8281 "debug igmp trace",
8282 DEBUG_STR
8283 DEBUG_IGMP_STR
8284 DEBUG_IGMP_TRACE_STR)
8285{
d62a17ae 8286 PIM_DO_DEBUG_IGMP_TRACE;
8287 return CMD_SUCCESS;
12e41d03
DL
8288}
8289
8290DEFUN (no_debug_igmp_trace,
8291 no_debug_igmp_trace_cmd,
8292 "no debug igmp trace",
8293 NO_STR
8294 DEBUG_STR
8295 DEBUG_IGMP_STR
8296 DEBUG_IGMP_TRACE_STR)
8297{
d62a17ae 8298 PIM_DONT_DEBUG_IGMP_TRACE;
8299 return CMD_SUCCESS;
12e41d03
DL
8300}
8301
12e41d03
DL
8302
8303DEFUN (debug_mroute,
8304 debug_mroute_cmd,
8305 "debug mroute",
8306 DEBUG_STR
8307 DEBUG_MROUTE_STR)
8308{
d62a17ae 8309 PIM_DO_DEBUG_MROUTE;
8310 return CMD_SUCCESS;
12e41d03
DL
8311}
8312
6c7197b1
DS
8313DEFUN (debug_mroute_detail,
8314 debug_mroute_detail_cmd,
8315 "debug mroute detail",
8316 DEBUG_STR
8317 DEBUG_MROUTE_STR
8318 "detailed\n")
8319{
d62a17ae 8320 PIM_DO_DEBUG_MROUTE_DETAIL;
8321 return CMD_SUCCESS;
6c7197b1
DS
8322}
8323
12e41d03
DL
8324DEFUN (no_debug_mroute,
8325 no_debug_mroute_cmd,
8326 "no debug mroute",
8327 NO_STR
8328 DEBUG_STR
8329 DEBUG_MROUTE_STR)
8330{
d62a17ae 8331 PIM_DONT_DEBUG_MROUTE;
8332 return CMD_SUCCESS;
12e41d03
DL
8333}
8334
6c7197b1
DS
8335DEFUN (no_debug_mroute_detail,
8336 no_debug_mroute_detail_cmd,
8337 "no debug mroute detail",
8338 NO_STR
8339 DEBUG_STR
8340 DEBUG_MROUTE_STR
8341 "detailed\n")
8342{
d62a17ae 8343 PIM_DONT_DEBUG_MROUTE_DETAIL;
8344 return CMD_SUCCESS;
6c7197b1 8345}
12e41d03 8346
35a12720
MS
8347DEFUN (debug_pim_static,
8348 debug_pim_static_cmd,
8349 "debug pim static",
6250610a 8350 DEBUG_STR
35a12720 8351 DEBUG_PIM_STR
6250610a
JAG
8352 DEBUG_STATIC_STR)
8353{
d62a17ae 8354 PIM_DO_DEBUG_STATIC;
8355 return CMD_SUCCESS;
6250610a
JAG
8356}
8357
35a12720
MS
8358DEFUN (no_debug_pim_static,
8359 no_debug_pim_static_cmd,
8360 "no debug pim static",
6250610a
JAG
8361 NO_STR
8362 DEBUG_STR
35a12720 8363 DEBUG_PIM_STR
6250610a
JAG
8364 DEBUG_STATIC_STR)
8365{
d62a17ae 8366 PIM_DONT_DEBUG_STATIC;
8367 return CMD_SUCCESS;
6250610a
JAG
8368}
8369
6250610a 8370
12e41d03
DL
8371DEFUN (debug_pim,
8372 debug_pim_cmd,
8373 "debug pim",
8374 DEBUG_STR
8375 DEBUG_PIM_STR)
8376{
d62a17ae 8377 PIM_DO_DEBUG_PIM_EVENTS;
8378 PIM_DO_DEBUG_PIM_PACKETS;
8379 PIM_DO_DEBUG_PIM_TRACE;
8380 PIM_DO_DEBUG_MSDP_EVENTS;
8381 PIM_DO_DEBUG_MSDP_PACKETS;
09524ccf 8382 PIM_DO_DEBUG_BSM;
d62a17ae 8383 return CMD_SUCCESS;
12e41d03
DL
8384}
8385
8386DEFUN (no_debug_pim,
8387 no_debug_pim_cmd,
8388 "no debug pim",
8389 NO_STR
8390 DEBUG_STR
8391 DEBUG_PIM_STR)
8392{
d62a17ae 8393 PIM_DONT_DEBUG_PIM_EVENTS;
8394 PIM_DONT_DEBUG_PIM_PACKETS;
8395 PIM_DONT_DEBUG_PIM_TRACE;
8396 PIM_DONT_DEBUG_MSDP_EVENTS;
8397 PIM_DONT_DEBUG_MSDP_PACKETS;
12e41d03 8398
d62a17ae 8399 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8400 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
09524ccf 8401 PIM_DONT_DEBUG_BSM;
12e41d03 8402
d62a17ae 8403 return CMD_SUCCESS;
12e41d03
DL
8404}
8405
40f1f31b
DS
8406DEFUN (debug_pim_nht,
8407 debug_pim_nht_cmd,
8408 "debug pim nht",
8409 DEBUG_STR
8410 DEBUG_PIM_STR
8411 "Nexthop Tracking\n")
8412{
8413 PIM_DO_DEBUG_PIM_NHT;
8414 return CMD_SUCCESS;
8415}
8416
8417DEFUN (no_debug_pim_nht,
8418 no_debug_pim_nht_cmd,
8419 "no debug pim nht",
8420 NO_STR
8421 DEBUG_STR
8422 DEBUG_PIM_STR
8423 "Nexthop Tracking\n")
8424{
8425 PIM_DONT_DEBUG_PIM_NHT;
8426 return CMD_SUCCESS;
8427}
12e41d03 8428
3d225d48
DS
8429DEFUN (debug_pim_nht_rp,
8430 debug_pim_nht_rp_cmd,
8431 "debug pim nht rp",
8432 DEBUG_STR
8433 DEBUG_PIM_STR
8434 "Nexthop Tracking\n"
8435 "RP Nexthop Tracking\n")
8436{
8437 PIM_DO_DEBUG_PIM_NHT_RP;
8438 return CMD_SUCCESS;
8439}
8440
8441DEFUN (no_debug_pim_nht_rp,
8442 no_debug_pim_nht_rp_cmd,
8443 "no debug pim nht rp",
8444 NO_STR
8445 DEBUG_STR
8446 DEBUG_PIM_STR
8447 "Nexthop Tracking\n"
8448 "RP Nexthop Tracking\n")
8449{
8450 PIM_DONT_DEBUG_PIM_NHT_RP;
8451 return CMD_SUCCESS;
8452}
8453
12e41d03
DL
8454DEFUN (debug_pim_events,
8455 debug_pim_events_cmd,
8456 "debug pim events",
8457 DEBUG_STR
8458 DEBUG_PIM_STR
8459 DEBUG_PIM_EVENTS_STR)
8460{
d62a17ae 8461 PIM_DO_DEBUG_PIM_EVENTS;
8462 return CMD_SUCCESS;
12e41d03
DL
8463}
8464
8465DEFUN (no_debug_pim_events,
8466 no_debug_pim_events_cmd,
8467 "no debug pim events",
8468 NO_STR
8469 DEBUG_STR
8470 DEBUG_PIM_STR
8471 DEBUG_PIM_EVENTS_STR)
8472{
d62a17ae 8473 PIM_DONT_DEBUG_PIM_EVENTS;
8474 return CMD_SUCCESS;
12e41d03
DL
8475}
8476
12e41d03
DL
8477DEFUN (debug_pim_packets,
8478 debug_pim_packets_cmd,
a957a05b 8479 "debug pim packets [<hello|joins|register>]",
12e41d03
DL
8480 DEBUG_STR
8481 DEBUG_PIM_STR
8482 DEBUG_PIM_PACKETS_STR
8483 DEBUG_PIM_HELLO_PACKETS_STR
9add3b88
DS
8484 DEBUG_PIM_J_P_PACKETS_STR
8485 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 8486{
d62a17ae 8487 int idx = 0;
8488 if (argv_find(argv, argc, "hello", &idx)) {
8489 PIM_DO_DEBUG_PIM_HELLO;
8490 vty_out(vty, "PIM Hello debugging is on\n");
8491 } else if (argv_find(argv, argc, "joins", &idx)) {
8492 PIM_DO_DEBUG_PIM_J_P;
8493 vty_out(vty, "PIM Join/Prune debugging is on\n");
8494 } else if (argv_find(argv, argc, "register", &idx)) {
8495 PIM_DO_DEBUG_PIM_REG;
8496 vty_out(vty, "PIM Register debugging is on\n");
8497 } else {
8498 PIM_DO_DEBUG_PIM_PACKETS;
8499 vty_out(vty, "PIM Packet debugging is on \n");
8500 }
8501 return CMD_SUCCESS;
12e41d03
DL
8502}
8503
8504DEFUN (no_debug_pim_packets,
8505 no_debug_pim_packets_cmd,
a957a05b 8506 "no debug pim packets [<hello|joins|register>]",
12e41d03
DL
8507 NO_STR
8508 DEBUG_STR
8509 DEBUG_PIM_STR
8510 DEBUG_PIM_PACKETS_STR
8511 DEBUG_PIM_HELLO_PACKETS_STR
a957a05b
DS
8512 DEBUG_PIM_J_P_PACKETS_STR
8513 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 8514{
d62a17ae 8515 int idx = 0;
8516 if (argv_find(argv, argc, "hello", &idx)) {
8517 PIM_DONT_DEBUG_PIM_HELLO;
8518 vty_out(vty, "PIM Hello debugging is off \n");
8519 } else if (argv_find(argv, argc, "joins", &idx)) {
8520 PIM_DONT_DEBUG_PIM_J_P;
8521 vty_out(vty, "PIM Join/Prune debugging is off \n");
8522 } else if (argv_find(argv, argc, "register", &idx)) {
8523 PIM_DONT_DEBUG_PIM_REG;
8524 vty_out(vty, "PIM Register debugging is off\n");
8525 } else
8526 PIM_DONT_DEBUG_PIM_PACKETS;
8527
8528 return CMD_SUCCESS;
12e41d03
DL
8529}
8530
12e41d03
DL
8531
8532DEFUN (debug_pim_packetdump_send,
8533 debug_pim_packetdump_send_cmd,
8534 "debug pim packet-dump send",
8535 DEBUG_STR
8536 DEBUG_PIM_STR
8537 DEBUG_PIM_PACKETDUMP_STR
8538 DEBUG_PIM_PACKETDUMP_SEND_STR)
8539{
d62a17ae 8540 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
8541 return CMD_SUCCESS;
12e41d03
DL
8542}
8543
8544DEFUN (no_debug_pim_packetdump_send,
8545 no_debug_pim_packetdump_send_cmd,
8546 "no debug pim packet-dump send",
8547 NO_STR
8548 DEBUG_STR
8549 DEBUG_PIM_STR
8550 DEBUG_PIM_PACKETDUMP_STR
8551 DEBUG_PIM_PACKETDUMP_SEND_STR)
8552{
d62a17ae 8553 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8554 return CMD_SUCCESS;
12e41d03
DL
8555}
8556
12e41d03
DL
8557DEFUN (debug_pim_packetdump_recv,
8558 debug_pim_packetdump_recv_cmd,
8559 "debug pim packet-dump receive",
8560 DEBUG_STR
8561 DEBUG_PIM_STR
8562 DEBUG_PIM_PACKETDUMP_STR
8563 DEBUG_PIM_PACKETDUMP_RECV_STR)
8564{
d62a17ae 8565 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
8566 return CMD_SUCCESS;
12e41d03
DL
8567}
8568
8569DEFUN (no_debug_pim_packetdump_recv,
8570 no_debug_pim_packetdump_recv_cmd,
8571 "no debug pim packet-dump receive",
8572 NO_STR
8573 DEBUG_STR
8574 DEBUG_PIM_STR
8575 DEBUG_PIM_PACKETDUMP_STR
8576 DEBUG_PIM_PACKETDUMP_RECV_STR)
8577{
d62a17ae 8578 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8579 return CMD_SUCCESS;
12e41d03
DL
8580}
8581
12e41d03
DL
8582DEFUN (debug_pim_trace,
8583 debug_pim_trace_cmd,
8584 "debug pim trace",
8585 DEBUG_STR
8586 DEBUG_PIM_STR
8587 DEBUG_PIM_TRACE_STR)
8588{
d62a17ae 8589 PIM_DO_DEBUG_PIM_TRACE;
8590 return CMD_SUCCESS;
12e41d03
DL
8591}
8592
56c238c9
DS
8593DEFUN (debug_pim_trace_detail,
8594 debug_pim_trace_detail_cmd,
8595 "debug pim trace detail",
8596 DEBUG_STR
8597 DEBUG_PIM_STR
5f40dada
DS
8598 DEBUG_PIM_TRACE_STR
8599 "Detailed Information\n")
56c238c9
DS
8600{
8601 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
8602 return CMD_SUCCESS;
8603}
8604
12e41d03
DL
8605DEFUN (no_debug_pim_trace,
8606 no_debug_pim_trace_cmd,
8607 "no debug pim trace",
8608 NO_STR
8609 DEBUG_STR
8610 DEBUG_PIM_STR
8611 DEBUG_PIM_TRACE_STR)
8612{
d62a17ae 8613 PIM_DONT_DEBUG_PIM_TRACE;
8614 return CMD_SUCCESS;
12e41d03
DL
8615}
8616
56c238c9
DS
8617DEFUN (no_debug_pim_trace_detail,
8618 no_debug_pim_trace_detail_cmd,
9853a7a5 8619 "no debug pim trace detail",
56c238c9
DS
8620 NO_STR
8621 DEBUG_STR
8622 DEBUG_PIM_STR
bd4d05c5
DS
8623 DEBUG_PIM_TRACE_STR
8624 "Detailed Information\n")
56c238c9
DS
8625{
8626 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
8627 return CMD_SUCCESS;
8628}
8629
12e41d03
DL
8630DEFUN (debug_ssmpingd,
8631 debug_ssmpingd_cmd,
8632 "debug ssmpingd",
8633 DEBUG_STR
12e41d03
DL
8634 DEBUG_SSMPINGD_STR)
8635{
d62a17ae 8636 PIM_DO_DEBUG_SSMPINGD;
8637 return CMD_SUCCESS;
12e41d03
DL
8638}
8639
8640DEFUN (no_debug_ssmpingd,
8641 no_debug_ssmpingd_cmd,
8642 "no debug ssmpingd",
8643 NO_STR
8644 DEBUG_STR
12e41d03
DL
8645 DEBUG_SSMPINGD_STR)
8646{
d62a17ae 8647 PIM_DONT_DEBUG_SSMPINGD;
8648 return CMD_SUCCESS;
12e41d03
DL
8649}
8650
12e41d03
DL
8651DEFUN (debug_pim_zebra,
8652 debug_pim_zebra_cmd,
8653 "debug pim zebra",
8654 DEBUG_STR
8655 DEBUG_PIM_STR
8656 DEBUG_PIM_ZEBRA_STR)
8657{
d62a17ae 8658 PIM_DO_DEBUG_ZEBRA;
8659 return CMD_SUCCESS;
12e41d03
DL
8660}
8661
8662DEFUN (no_debug_pim_zebra,
8663 no_debug_pim_zebra_cmd,
8664 "no debug pim zebra",
8665 NO_STR
8666 DEBUG_STR
8667 DEBUG_PIM_STR
8668 DEBUG_PIM_ZEBRA_STR)
8669{
d62a17ae 8670 PIM_DONT_DEBUG_ZEBRA;
8671 return CMD_SUCCESS;
12e41d03
DL
8672}
8673
36b5b98f
SK
8674DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
8675 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8676{
8677 PIM_DO_DEBUG_MLAG;
8678 return CMD_SUCCESS;
8679}
8680
8681DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
8682 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8683{
8684 PIM_DONT_DEBUG_MLAG;
8685 return CMD_SUCCESS;
8686}
8687
4d913fa6
AK
8688DEFUN (debug_pim_vxlan,
8689 debug_pim_vxlan_cmd,
8690 "debug pim vxlan",
8691 DEBUG_STR
8692 DEBUG_PIM_STR
8693 DEBUG_PIM_VXLAN_STR)
8694{
8695 PIM_DO_DEBUG_VXLAN;
8696 return CMD_SUCCESS;
8697}
8698
8699DEFUN (no_debug_pim_vxlan,
8700 no_debug_pim_vxlan_cmd,
8701 "no debug pim vxlan",
8702 NO_STR
8703 DEBUG_STR
8704 DEBUG_PIM_STR
8705 DEBUG_PIM_VXLAN_STR)
8706{
8707 PIM_DONT_DEBUG_VXLAN;
8708 return CMD_SUCCESS;
8709}
8710
2a333e0f 8711DEFUN (debug_msdp,
8712 debug_msdp_cmd,
8713 "debug msdp",
8714 DEBUG_STR
8715 DEBUG_MSDP_STR)
8716{
d62a17ae 8717 PIM_DO_DEBUG_MSDP_EVENTS;
8718 PIM_DO_DEBUG_MSDP_PACKETS;
8719 return CMD_SUCCESS;
2a333e0f 8720}
8721
8722DEFUN (no_debug_msdp,
8723 no_debug_msdp_cmd,
8724 "no debug msdp",
8725 NO_STR
8726 DEBUG_STR
8727 DEBUG_MSDP_STR)
8728{
d62a17ae 8729 PIM_DONT_DEBUG_MSDP_EVENTS;
8730 PIM_DONT_DEBUG_MSDP_PACKETS;
8731 return CMD_SUCCESS;
2a333e0f 8732}
8733
2a333e0f 8734DEFUN (debug_msdp_events,
8735 debug_msdp_events_cmd,
8736 "debug msdp events",
8737 DEBUG_STR
8738 DEBUG_MSDP_STR
8739 DEBUG_MSDP_EVENTS_STR)
8740{
d62a17ae 8741 PIM_DO_DEBUG_MSDP_EVENTS;
8742 return CMD_SUCCESS;
2a333e0f 8743}
8744
8745DEFUN (no_debug_msdp_events,
8746 no_debug_msdp_events_cmd,
8747 "no debug msdp events",
8748 NO_STR
8749 DEBUG_STR
8750 DEBUG_MSDP_STR
8751 DEBUG_MSDP_EVENTS_STR)
8752{
d62a17ae 8753 PIM_DONT_DEBUG_MSDP_EVENTS;
8754 return CMD_SUCCESS;
2a333e0f 8755}
8756
2a333e0f 8757DEFUN (debug_msdp_packets,
8758 debug_msdp_packets_cmd,
8759 "debug msdp packets",
8760 DEBUG_STR
8761 DEBUG_MSDP_STR
8762 DEBUG_MSDP_PACKETS_STR)
8763{
d62a17ae 8764 PIM_DO_DEBUG_MSDP_PACKETS;
8765 return CMD_SUCCESS;
2a333e0f 8766}
8767
8768DEFUN (no_debug_msdp_packets,
8769 no_debug_msdp_packets_cmd,
8770 "no debug msdp packets",
8771 NO_STR
8772 DEBUG_STR
8773 DEBUG_MSDP_STR
8774 DEBUG_MSDP_PACKETS_STR)
8775{
d62a17ae 8776 PIM_DONT_DEBUG_MSDP_PACKETS;
8777 return CMD_SUCCESS;
2a333e0f 8778}
8779
4d9ad5dc
MS
8780DEFUN (debug_mtrace,
8781 debug_mtrace_cmd,
8782 "debug mtrace",
8783 DEBUG_STR
8784 DEBUG_MTRACE_STR)
8785{
8786 PIM_DO_DEBUG_MTRACE;
8787 return CMD_SUCCESS;
8788}
8789
8790DEFUN (no_debug_mtrace,
8791 no_debug_mtrace_cmd,
8792 "no debug mtrace",
8793 NO_STR
8794 DEBUG_STR
8795 DEBUG_MTRACE_STR)
8796{
8797 PIM_DONT_DEBUG_MTRACE;
8798 return CMD_SUCCESS;
8799}
8800
09524ccf 8801DEFUN (debug_bsm,
8802 debug_bsm_cmd,
8803 "debug pim bsm",
8804 DEBUG_STR
8805 DEBUG_PIM_STR
8806 DEBUG_PIM_BSM_STR)
8807{
8808 PIM_DO_DEBUG_BSM;
8809 return CMD_SUCCESS;
8810}
8811
8812DEFUN (no_debug_bsm,
8813 no_debug_bsm_cmd,
8814 "no debug pim bsm",
8815 NO_STR
8816 DEBUG_STR
8817 DEBUG_PIM_STR
8818 DEBUG_PIM_BSM_STR)
8819{
8820 PIM_DONT_DEBUG_BSM;
8821 return CMD_SUCCESS;
8822}
8823
8824
87f6dc50
DS
8825DEFUN_NOSH (show_debugging_pim,
8826 show_debugging_pim_cmd,
8827 "show debugging [pim]",
8828 SHOW_STR
8829 DEBUG_STR
8830 PIM_STR)
12e41d03 8831{
87f6dc50
DS
8832 vty_out(vty, "PIM debugging status\n");
8833
d62a17ae 8834 pim_debug_config_write(vty);
87f6dc50 8835
d62a17ae 8836 return CMD_SUCCESS;
12e41d03
DL
8837}
8838
4763cd0e 8839DEFUN (interface_pim_use_source,
8840 interface_pim_use_source_cmd,
8841 "ip pim use-source A.B.C.D",
8842 IP_STR
2f5e937c 8843 PIM_STR
4763cd0e 8844 "Configure primary IP address\n"
8845 "source ip address\n")
8846{
675c8fde
SP
8847 nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, argv[3]->arg);
8848
8849 return nb_cli_apply_changes(vty,
698f4147 8850 FRR_PIM_INTERFACE_XPATH,
521c5b9d 8851 "frr-routing:ipv4");
4763cd0e 8852}
8853
8854DEFUN (interface_no_pim_use_source,
8855 interface_no_pim_use_source_cmd,
2243bb17 8856 "no ip pim use-source [A.B.C.D]",
4763cd0e 8857 NO_STR
8858 IP_STR
2f5e937c 8859 PIM_STR
2243bb17
DS
8860 "Delete source IP address\n"
8861 "source ip address\n")
4763cd0e 8862{
675c8fde
SP
8863 nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, "0.0.0.0");
8864
8865 return nb_cli_apply_changes(vty,
698f4147 8866 FRR_PIM_INTERFACE_XPATH,
521c5b9d 8867 "frr-routing:ipv4");
4763cd0e 8868}
8869
745b8d4a 8870DEFPY (ip_pim_bfd,
ba4eb1bc 8871 ip_pim_bfd_cmd,
745b8d4a 8872 "ip pim bfd [profile BFDPROF$prof]",
ba4eb1bc
CS
8873 IP_STR
8874 PIM_STR
745b8d4a
RZ
8875 "Enables BFD support\n"
8876 "Use BFD profile\n"
8877 "Use BFD profile name\n")
ba4eb1bc 8878{
b73779d3 8879 const struct lyd_node *igmp_enable_dnode;
ba4eb1bc 8880
3bb513c3
CH
8881 igmp_enable_dnode =
8882 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 8883 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
8884 "frr-routing:ipv4");
b73779d3
SP
8885 if (!igmp_enable_dnode)
8886 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
5c90f569 8887 "true");
b73779d3
SP
8888 else {
8889 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
8890 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
5c90f569 8891 "true");
2fd8de7d 8892 }
2fd8de7d 8893
1f3e6bf5 8894 nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
745b8d4a
RZ
8895 if (prof)
8896 nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_MODIFY, prof);
8897
698f4147 8898 return nb_cli_apply_changes(vty,
8899 FRR_PIM_INTERFACE_XPATH,
8900 "frr-routing:ipv4");
745b8d4a
RZ
8901}
8902
8903DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
8904 "no ip pim bfd profile [BFDPROF]",
8905 NO_STR
8906 IP_STR
8907 PIM_STR
8908 "Enables BFD support\n"
8909 "Disable BFD profile\n"
8910 "BFD Profile name\n")
8911{
8912 nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_DESTROY, NULL);
ba4eb1bc 8913
698f4147 8914 return nb_cli_apply_changes(vty,
8915 FRR_PIM_INTERFACE_XPATH,
8916 "frr-routing:ipv4");
ba4eb1bc
CS
8917}
8918
8919DEFUN (no_ip_pim_bfd,
8920 no_ip_pim_bfd_cmd,
8921 "no ip pim bfd",
8922 NO_STR
8923 IP_STR
8924 PIM_STR
8925 "Disables BFD support\n")
8926{
b73779d3 8927 nb_cli_enqueue_change(vty, "./bfd", NB_OP_DESTROY, NULL);
ba4eb1bc 8928
698f4147 8929 return nb_cli_apply_changes(vty,
8930 FRR_PIM_INTERFACE_XPATH,
8931 "frr-routing:ipv4");
ba4eb1bc
CS
8932}
8933
16c926c8 8934DEFUN (ip_pim_bsm,
8935 ip_pim_bsm_cmd,
8936 "ip pim bsm",
8937 IP_STR
8938 PIM_STR
8939 "Enables BSM support on the interface\n")
8940{
e3eb2bab 8941 const struct lyd_node *igmp_enable_dnode;
16c926c8 8942
3bb513c3
CH
8943 igmp_enable_dnode =
8944 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 8945 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
8946 "frr-routing:ipv4");
e3eb2bab
SP
8947 if (!igmp_enable_dnode)
8948 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8949 "true");
8950 else {
8951 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
8952 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8953 "true");
16c926c8 8954 }
8955
e3eb2bab 8956 nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "true");
16c926c8 8957
698f4147 8958 return nb_cli_apply_changes(vty,
8959 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
16c926c8 8960}
8961
8962DEFUN (no_ip_pim_bsm,
8963 no_ip_pim_bsm_cmd,
8964 "no ip pim bsm",
8965 NO_STR
8966 IP_STR
8967 PIM_STR
8968 "Disables BSM support\n")
8969{
e3eb2bab 8970 nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "false");
16c926c8 8971
698f4147 8972 return nb_cli_apply_changes(vty,
8973 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
16c926c8 8974}
8975
8976DEFUN (ip_pim_ucast_bsm,
8977 ip_pim_ucast_bsm_cmd,
8978 "ip pim unicast-bsm",
8979 IP_STR
8980 PIM_STR
8981 "Accept/Send unicast BSM on the interface\n")
8982{
e3eb2bab 8983 const struct lyd_node *igmp_enable_dnode;
16c926c8 8984
3bb513c3
CH
8985 igmp_enable_dnode =
8986 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 8987 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
8988 "frr-routing:ipv4");
e3eb2bab
SP
8989 if (!igmp_enable_dnode)
8990 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8991 "true");
8992 else {
8993 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
8994 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8995 "true");
16c926c8 8996 }
8997
e3eb2bab 8998 nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "true");
16c926c8 8999
698f4147 9000 return nb_cli_apply_changes(vty,
9001 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
9002
16c926c8 9003}
9004
9005DEFUN (no_ip_pim_ucast_bsm,
9006 no_ip_pim_ucast_bsm_cmd,
9007 "no ip pim unicast-bsm",
9008 NO_STR
9009 IP_STR
9010 PIM_STR
9011 "Block send/receive unicast BSM on this interface\n")
9012{
e3eb2bab 9013 nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "false");
16c926c8 9014
698f4147 9015 return nb_cli_apply_changes(vty,
9016 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
16c926c8 9017}
9018
64dc4b2d 9019#if HAVE_BFDD > 0
11ca3587 9020DEFUN_HIDDEN (
521c5b9d
MS
9021 ip_pim_bfd_param,
9022 ip_pim_bfd_param_cmd,
11ca3587 9023 "ip pim bfd (2-255) (1-65535) (1-65535)",
521c5b9d
MS
9024 IP_STR
9025 PIM_STR
9026 "Enables BFD support\n"
9027 "Detect Multiplier\n"
9028 "Required min receive interval\n"
9029 "Desired min transmit interval\n")
64dc4b2d 9030#else
521c5b9d
MS
9031 DEFUN(
9032 ip_pim_bfd_param,
9033 ip_pim_bfd_param_cmd,
11ca3587 9034 "ip pim bfd (2-255) (1-65535) (1-65535)",
521c5b9d
MS
9035 IP_STR
9036 PIM_STR
9037 "Enables BFD support\n"
9038 "Detect Multiplier\n"
9039 "Required min receive interval\n"
9040 "Desired min transmit interval\n")
3779776a 9041#endif /* HAVE_BFDD */
ba4eb1bc 9042{
d62a17ae 9043 int idx_number = 3;
9044 int idx_number_2 = 4;
9045 int idx_number_3 = 5;
b73779d3 9046 const struct lyd_node *igmp_enable_dnode;
ba4eb1bc 9047
3bb513c3
CH
9048 igmp_enable_dnode =
9049 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 9050 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
9051 "frr-routing:ipv4");
b73779d3
SP
9052 if (!igmp_enable_dnode)
9053 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
521c5b9d 9054 "true");
b73779d3
SP
9055 else {
9056 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
9057 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
521c5b9d 9058 "true");
b73779d3 9059 }
ba4eb1bc 9060
1f3e6bf5 9061 nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
b73779d3 9062 nb_cli_enqueue_change(vty, "./bfd/min-rx-interval", NB_OP_MODIFY,
521c5b9d 9063 argv[idx_number_2]->arg);
b73779d3 9064 nb_cli_enqueue_change(vty, "./bfd/min-tx-interval", NB_OP_MODIFY,
521c5b9d 9065 argv[idx_number_3]->arg);
b73779d3 9066 nb_cli_enqueue_change(vty, "./bfd/detect_mult", NB_OP_MODIFY,
521c5b9d 9067 argv[idx_number]->arg);
b73779d3 9068
698f4147 9069 return nb_cli_apply_changes(vty,
9070 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
ba4eb1bc
CS
9071}
9072
64dc4b2d 9073#if HAVE_BFDD == 0
d62a17ae 9074ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
11ca3587
CH
9075 "no ip pim bfd (2-255) (1-65535) (1-65535)",
9076 NO_STR
9077 IP_STR
9078 PIM_STR
d62a17ae 9079 "Enables BFD support\n"
9080 "Detect Multiplier\n"
9081 "Required min receive interval\n"
9082 "Desired min transmit interval\n")
64dc4b2d 9083#endif /* !HAVE_BFDD */
d62a17ae 9084
56697b3e
RZ
9085DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
9086 "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
9087 IP_STR
9088 CFG_MSDP_STR
9089 "Configure MSDP peer\n"
9090 "Peer IP address\n"
9091 "Source address for TCP connection\n"
9092 "Local IP address\n")
2a333e0f 9093{
cf740d2e
SP
9094 const char *vrfname;
9095 char temp_xpath[XPATH_MAXLEN];
9096 char msdp_peer_source_xpath[XPATH_MAXLEN];
2a333e0f 9097
5a1a3920
RZ
9098 vrfname = pim_cli_get_vrf_name(vty);
9099 if (vrfname == NULL)
9100 return CMD_WARNING_CONFIG_FAILED;
2a333e0f 9101
cf740d2e 9102 snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
698f4147 9103 FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
56697b3e 9104 "frr-routing:ipv4");
cf740d2e 9105 snprintf(temp_xpath, sizeof(temp_xpath),
56697b3e 9106 "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
cf740d2e
SP
9107 strlcat(msdp_peer_source_xpath, temp_xpath,
9108 sizeof(msdp_peer_source_xpath));
2a333e0f 9109
cf740d2e 9110 nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
56697b3e 9111 source_str);
2a333e0f 9112
698f4147 9113 return nb_cli_apply_changes(vty,
9114 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
2a333e0f 9115}
9116
622fd3f1 9117DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
11ca3587 9118 "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
622fd3f1
RZ
9119 IP_STR
9120 CFG_MSDP_STR
9121 "MSDP timers configuration\n"
9122 "Keep alive period (in seconds)\n"
9123 "Hold time period (in seconds)\n"
9124 "Connection retry period (in seconds)\n")
9125{
9126 const char *vrfname;
9127 char xpath[XPATH_MAXLEN];
9128
9129 vrfname = pim_cli_get_vrf_name(vty);
9130 if (vrfname == NULL)
9131 return CMD_WARNING_CONFIG_FAILED;
9132
9133 snprintf(xpath, sizeof(xpath), FRR_PIM_MSDP_XPATH, "frr-pim:pimd",
9134 "pim", vrfname, "frr-routing:ipv4");
9135 nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
9136 nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
9137 if (connretry_str)
9138 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
9139 connretry_str);
9140 else
9141 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
9142 NULL);
9143
9144 nb_cli_apply_changes(vty, xpath);
9145
9146 return CMD_SUCCESS;
9147}
9148
11ca3587
CH
9149DEFPY(no_ip_msdp_timers, no_ip_msdp_timers_cmd,
9150 "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
9151 NO_STR
9152 IP_STR
9153 CFG_MSDP_STR
9154 "MSDP timers configuration\n"
9155 IGNORED_IN_NO_STR
9156 IGNORED_IN_NO_STR
9157 IGNORED_IN_NO_STR)
9158{
9159 const char *vrfname;
9160 char xpath[XPATH_MAXLEN];
9161
9162 vrfname = pim_cli_get_vrf_name(vty);
9163 if (vrfname == NULL)
9164 return CMD_WARNING_CONFIG_FAILED;
9165
9166 snprintf(xpath, sizeof(xpath), FRR_PIM_MSDP_XPATH, "frr-pim:pimd",
9167 "pim", vrfname, "frr-routing:ipv4");
9168
9169 nb_cli_enqueue_change(vty, "./hold-time", NB_OP_DESTROY, NULL);
9170 nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_DESTROY, NULL);
9171 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, NULL);
9172
9173 nb_cli_apply_changes(vty, xpath);
9174
9175 return CMD_SUCCESS;
9176}
9177
9fbd9fc4 9178DEFUN (no_ip_msdp_peer,
2a333e0f 9179 no_ip_msdp_peer_cmd,
9180 "no ip msdp peer A.B.C.D",
977d71cc 9181 NO_STR
2a333e0f 9182 IP_STR
9183 CFG_MSDP_STR
9184 "Delete MSDP peer\n"
9185 "peer ip address\n")
9186{
cf740d2e
SP
9187 const char *vrfname;
9188 char msdp_peer_xpath[XPATH_MAXLEN];
9189 char temp_xpath[XPATH_MAXLEN];
2a333e0f 9190
5a1a3920
RZ
9191 vrfname = pim_cli_get_vrf_name(vty);
9192 if (vrfname == NULL)
9193 return CMD_WARNING_CONFIG_FAILED;
977d71cc 9194
cf740d2e 9195 snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
698f4147 9196 FRR_PIM_VRF_XPATH,
cf740d2e
SP
9197 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
9198 snprintf(temp_xpath, sizeof(temp_xpath),
9199 "/msdp-peer[peer-ip='%s']",
9200 argv[4]->arg);
977d71cc 9201
cf740d2e
SP
9202 strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath));
9203
9204 nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
977d71cc 9205
cf740d2e 9206 return nb_cli_apply_changes(vty, NULL);
977d71cc 9207}
9208
e2809e61
RZ
9209DEFPY(ip_msdp_mesh_group_member,
9210 ip_msdp_mesh_group_member_cmd,
9211 "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9212 IP_STR
9213 CFG_MSDP_STR
9214 "Configure MSDP mesh-group\n"
9215 "Mesh group name\n"
9216 "Mesh group member\n"
9217 "Peer IP address\n")
977d71cc 9218{
cf740d2e 9219 const char *vrfname;
e2809e61 9220 char xpath_value[XPATH_MAXLEN];
977d71cc 9221
5a1a3920
RZ
9222 vrfname = pim_cli_get_vrf_name(vty);
9223 if (vrfname == NULL)
9224 return CMD_WARNING_CONFIG_FAILED;
977d71cc 9225
e2809e61
RZ
9226 /* Create mesh group. */
9227 snprintf(xpath_value, sizeof(xpath_value),
698f4147 9228 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
9229 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
9230 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
977d71cc 9231
e2809e61
RZ
9232 /* Create mesh group member. */
9233 strlcat(xpath_value, "/members[address='", sizeof(xpath_value));
9234 strlcat(xpath_value, maddr_str, sizeof(xpath_value));
9235 strlcat(xpath_value, "']", sizeof(xpath_value));
9236 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
977d71cc 9237
cf740d2e 9238 return nb_cli_apply_changes(vty, NULL);
977d71cc 9239}
cf740d2e 9240
e2809e61
RZ
9241DEFPY(no_ip_msdp_mesh_group_member,
9242 no_ip_msdp_mesh_group_member_cmd,
9243 "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9244 NO_STR
9245 IP_STR
9246 CFG_MSDP_STR
9247 "Delete MSDP mesh-group member\n"
9248 "Mesh group name\n"
9249 "Mesh group member\n"
9250 "Peer IP address\n")
977d71cc 9251{
cf740d2e 9252 const char *vrfname;
e2809e61
RZ
9253 char xpath_value[XPATH_MAXLEN];
9254 char xpath_member_value[XPATH_MAXLEN];
977d71cc 9255
5a1a3920
RZ
9256 vrfname = pim_cli_get_vrf_name(vty);
9257 if (vrfname == NULL)
9258 return CMD_WARNING_CONFIG_FAILED;
977d71cc 9259
e2809e61
RZ
9260 /* Get mesh group base XPath. */
9261 snprintf(xpath_value, sizeof(xpath_value),
698f4147 9262 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61 9263 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
cf740d2e 9264
e2809e61
RZ
9265 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
9266 vty_out(vty, "%% mesh-group does not exist\n");
9267 return CMD_WARNING_CONFIG_FAILED;
d62a17ae 9268 }
977d71cc 9269
e2809e61
RZ
9270 /* Remove mesh group member. */
9271 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
9272 strlcat(xpath_member_value, "/members[address='",
9273 sizeof(xpath_member_value));
9274 strlcat(xpath_member_value, maddr_str, sizeof(xpath_member_value));
9275 strlcat(xpath_member_value, "']", sizeof(xpath_member_value));
9276 if (!yang_dnode_exists(vty->candidate_config->dnode,
9277 xpath_member_value)) {
9278 vty_out(vty, "%% mesh-group member does not exist\n");
9279 return CMD_WARNING_CONFIG_FAILED;
d62a17ae 9280 }
977d71cc 9281
46877489 9282 nb_cli_enqueue_change(vty, xpath_member_value, NB_OP_DESTROY, NULL);
977d71cc 9283
e2809e61
RZ
9284 /*
9285 * If this is the last member, then we must remove the group altogether
9286 * to not break legacy CLI behaviour.
9287 */
9288 pim_cli_legacy_mesh_group_behavior(vty, gname);
9289
9290 return nb_cli_apply_changes(vty, NULL);
cf740d2e 9291}
977d71cc 9292
e2809e61
RZ
9293DEFPY(ip_msdp_mesh_group_source,
9294 ip_msdp_mesh_group_source_cmd,
9295 "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
9296 IP_STR
9297 CFG_MSDP_STR
9298 "Configure MSDP mesh-group\n"
9299 "Mesh group name\n"
9300 "Mesh group local address\n"
9301 "Source IP address for the TCP connection\n")
977d71cc 9302{
cf740d2e 9303 const char *vrfname;
e2809e61 9304 char xpath_value[XPATH_MAXLEN];
977d71cc 9305
5a1a3920
RZ
9306 vrfname = pim_cli_get_vrf_name(vty);
9307 if (vrfname == NULL)
9308 return CMD_WARNING_CONFIG_FAILED;
977d71cc 9309
e2809e61
RZ
9310 /* Create mesh group. */
9311 snprintf(xpath_value, sizeof(xpath_value),
698f4147 9312 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
9313 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
9314 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
977d71cc 9315
46877489 9316 /* Create mesh group source. */
e2809e61
RZ
9317 strlcat(xpath_value, "/source", sizeof(xpath_value));
9318 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
977d71cc 9319
cf740d2e 9320 return nb_cli_apply_changes(vty, NULL);
977d71cc 9321}
9322
e2809e61
RZ
9323DEFPY(no_ip_msdp_mesh_group_source,
9324 no_ip_msdp_mesh_group_source_cmd,
9325 "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
9326 NO_STR
9327 IP_STR
9328 CFG_MSDP_STR
9329 "Delete MSDP mesh-group source\n"
9330 "Mesh group name\n"
9331 "Mesh group source\n"
9332 "Mesh group local address\n")
977d71cc 9333{
cf740d2e 9334 const char *vrfname;
e2809e61 9335 char xpath_value[XPATH_MAXLEN];
cf740d2e 9336
5a1a3920
RZ
9337 vrfname = pim_cli_get_vrf_name(vty);
9338 if (vrfname == NULL)
9339 return CMD_WARNING_CONFIG_FAILED;
cf740d2e 9340
e2809e61
RZ
9341 /* Get mesh group base XPath. */
9342 snprintf(xpath_value, sizeof(xpath_value),
698f4147 9343 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
9344 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
9345 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
cf740d2e 9346
46877489 9347 /* Create mesh group source. */
e2809e61
RZ
9348 strlcat(xpath_value, "/source", sizeof(xpath_value));
9349 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
cf740d2e 9350
e2809e61
RZ
9351 /*
9352 * If this is the last member, then we must remove the group altogether
9353 * to not break legacy CLI behaviour.
9354 */
9355 pim_cli_legacy_mesh_group_behavior(vty, gname);
34d86eff 9356
cf740d2e 9357 return nb_cli_apply_changes(vty, NULL);
34d86eff
SP
9358}
9359
e2809e61
RZ
9360DEFPY(no_ip_msdp_mesh_group,
9361 no_ip_msdp_mesh_group_cmd,
9362 "no ip msdp mesh-group WORD$gname",
9363 NO_STR
9364 IP_STR
9365 CFG_MSDP_STR
9366 "Delete MSDP mesh-group\n"
9367 "Mesh group name")
34d86eff 9368{
cf740d2e 9369 const char *vrfname;
e2809e61 9370 char xpath_value[XPATH_MAXLEN];
34d86eff 9371
5a1a3920
RZ
9372 vrfname = pim_cli_get_vrf_name(vty);
9373 if (vrfname == NULL)
9374 return CMD_WARNING_CONFIG_FAILED;
cf740d2e 9375
e2809e61
RZ
9376 /* Get mesh group base XPath. */
9377 snprintf(xpath_value, sizeof(xpath_value),
698f4147 9378 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
9379 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
9380 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
9381 return CMD_SUCCESS;
cf740d2e 9382
e2809e61 9383 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
cf740d2e 9384 return nb_cli_apply_changes(vty, NULL);
d62a17ae 9385}
9386
e2809e61
RZ
9387static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
9388 struct json_object *json)
d62a17ae 9389{
9390 struct listnode *mbrnode;
9391 struct pim_msdp_mg_mbr *mbr;
d62a17ae 9392 char mbr_str[INET_ADDRSTRLEN];
9393 char src_str[INET_ADDRSTRLEN];
9394 char state_str[PIM_MSDP_STATE_STRLEN];
9395 enum pim_msdp_peer_state state;
d62a17ae 9396 json_object *json_mg_row = NULL;
9397 json_object *json_members = NULL;
9398 json_object *json_row = NULL;
9399
d62a17ae 9400 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
e2809e61 9401 if (json) {
d62a17ae 9402 /* currently there is only one mesh group but we should still
9403 * make
9404 * it a dict with mg-name as key */
9405 json_mg_row = json_object_new_object();
9406 json_object_string_add(json_mg_row, "name",
9407 mg->mesh_group_name);
9408 json_object_string_add(json_mg_row, "source", src_str);
9409 } else {
9410 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
9411 vty_out(vty, " Source : %s\n", src_str);
9412 vty_out(vty, " Member State\n");
9413 }
9414
9415 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
9416 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
9417 if (mbr->mp) {
9418 state = mbr->mp->state;
9419 } else {
9420 state = PIM_MSDP_DISABLED;
9421 }
9422 pim_msdp_state_dump(state, state_str, sizeof(state_str));
e2809e61 9423 if (json) {
d62a17ae 9424 json_row = json_object_new_object();
9425 json_object_string_add(json_row, "member", mbr_str);
9426 json_object_string_add(json_row, "state", state_str);
9427 if (!json_members) {
9428 json_members = json_object_new_object();
9429 json_object_object_add(json_mg_row, "members",
9430 json_members);
9431 }
9432 json_object_object_add(json_members, mbr_str, json_row);
9433 } else {
9434 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
9435 }
9436 }
9437
e2809e61 9438 if (json)
d62a17ae 9439 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
977d71cc 9440}
9441
9442DEFUN (show_ip_msdp_mesh_group,
9443 show_ip_msdp_mesh_group_cmd,
20a7e5fd 9444 "show ip msdp [vrf NAME] mesh-group [json]",
977d71cc 9445 SHOW_STR
9446 IP_STR
9447 MSDP_STR
f02d59db 9448 VRF_CMD_HELP_STR
977d71cc 9449 "MSDP mesh-group information\n"
f5da2cc2 9450 JSON_STR)
977d71cc 9451{
9f049418 9452 bool uj = use_json(argc, argv);
c68ba0d7 9453 int idx = 2;
e2809e61 9454 struct pim_msdp_mg *mg;
02a16316 9455 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
e2809e61
RZ
9456 struct pim_instance *pim = vrf->info;
9457 struct json_object *json = NULL;
02a16316
DS
9458
9459 if (!vrf)
9460 return CMD_WARNING;
9461
e2809e61
RZ
9462 /* Quick case: list is empty. */
9463 if (SLIST_EMPTY(&pim->msdp.mglist)) {
9464 if (uj)
9465 vty_out(vty, "{}\n");
9466
9467 return CMD_SUCCESS;
9468 }
9469
9470 if (uj)
9471 json = json_object_new_object();
9472
9473 SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
9474 ip_msdp_show_mesh_group(vty, mg, json);
9475
3757f964
DA
9476 if (uj)
9477 vty_json(vty, json);
d62a17ae 9478
9479 return CMD_SUCCESS;
9480}
9481
a25de56b
DS
9482DEFUN (show_ip_msdp_mesh_group_vrf_all,
9483 show_ip_msdp_mesh_group_vrf_all_cmd,
9484 "show ip msdp vrf all mesh-group [json]",
9485 SHOW_STR
9486 IP_STR
9487 MSDP_STR
9488 VRF_CMD_HELP_STR
9489 "MSDP mesh-group information\n"
f5da2cc2 9490 JSON_STR)
a25de56b 9491{
9f049418 9492 bool uj = use_json(argc, argv);
e2809e61
RZ
9493 struct json_object *json = NULL, *vrf_json = NULL;
9494 struct pim_instance *pim;
9495 struct pim_msdp_mg *mg;
a25de56b 9496 struct vrf *vrf;
a25de56b
DS
9497
9498 if (uj)
e2809e61
RZ
9499 json = json_object_new_object();
9500
a2addae8 9501 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b 9502 if (uj) {
e2809e61
RZ
9503 vrf_json = json_object_new_object();
9504 json_object_object_add(json, vrf->name, vrf_json);
a25de56b
DS
9505 } else
9506 vty_out(vty, "VRF: %s\n", vrf->name);
e2809e61
RZ
9507
9508 pim = vrf->info;
9509 SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
9510 ip_msdp_show_mesh_group(vty, mg, vrf_json);
9511 }
9512
3757f964
DA
9513 if (uj)
9514 vty_json(vty, json);
9515
a25de56b
DS
9516
9517 return CMD_SUCCESS;
9518}
9519
64c86530 9520static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
088f1098 9521 bool uj)
d62a17ae 9522{
9523 struct listnode *mpnode;
9524 struct pim_msdp_peer *mp;
9525 char peer_str[INET_ADDRSTRLEN];
9526 char local_str[INET_ADDRSTRLEN];
9527 char state_str[PIM_MSDP_STATE_STRLEN];
9528 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9529 int64_t now;
9530 json_object *json = NULL;
9531 json_object *json_row = NULL;
9532
9533
9534 if (uj) {
9535 json = json_object_new_object();
9536 } else {
9537 vty_out(vty,
9538 "Peer Local State Uptime SaCnt\n");
9539 }
9540
02a16316 9541 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 9542 if (mp->state == PIM_MSDP_ESTABLISHED) {
9543 now = pim_time_monotonic_sec();
9544 pim_time_uptime(timebuf, sizeof(timebuf),
9545 now - mp->uptime);
9546 } else {
c35b7e6b 9547 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 9548 }
9549 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9550 pim_inet4_dump("<local?>", mp->local, local_str,
9551 sizeof(local_str));
9552 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9553 if (uj) {
9554 json_row = json_object_new_object();
9555 json_object_string_add(json_row, "peer", peer_str);
9556 json_object_string_add(json_row, "local", local_str);
9557 json_object_string_add(json_row, "state", state_str);
9558 json_object_string_add(json_row, "upTime", timebuf);
9559 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9560 json_object_object_add(json, peer_str, json_row);
9561 } else {
9562 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
9563 local_str, state_str, timebuf, mp->sa_cnt);
9564 }
9565 }
9566
3757f964
DA
9567 if (uj)
9568 vty_json(vty, json);
d62a17ae 9569}
9570
64c86530 9571static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
088f1098 9572 const char *peer, bool uj)
d62a17ae 9573{
9574 struct listnode *mpnode;
9575 struct pim_msdp_peer *mp;
9576 char peer_str[INET_ADDRSTRLEN];
9577 char local_str[INET_ADDRSTRLEN];
9578 char state_str[PIM_MSDP_STATE_STRLEN];
9579 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9580 char katimer[PIM_MSDP_TIMER_STRLEN];
9581 char crtimer[PIM_MSDP_TIMER_STRLEN];
9582 char holdtimer[PIM_MSDP_TIMER_STRLEN];
9583 int64_t now;
9584 json_object *json = NULL;
9585 json_object *json_row = NULL;
9586
9587 if (uj) {
9588 json = json_object_new_object();
9589 }
9590
02a16316 9591 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 9592 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9593 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
9594 continue;
9595
9596 if (mp->state == PIM_MSDP_ESTABLISHED) {
9597 now = pim_time_monotonic_sec();
9598 pim_time_uptime(timebuf, sizeof(timebuf),
9599 now - mp->uptime);
9600 } else {
c35b7e6b 9601 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 9602 }
9603 pim_inet4_dump("<local?>", mp->local, local_str,
9604 sizeof(local_str));
9605 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9606 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
9607 mp->ka_timer);
9608 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
9609 mp->cr_timer);
9610 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
9611 mp->hold_timer);
9612
9613 if (uj) {
9614 json_row = json_object_new_object();
9615 json_object_string_add(json_row, "peer", peer_str);
9616 json_object_string_add(json_row, "local", local_str);
0ce04a08
RZ
9617 if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
9618 json_object_string_add(json_row,
9619 "meshGroupName",
9620 mp->mesh_group_name);
d62a17ae 9621 json_object_string_add(json_row, "state", state_str);
9622 json_object_string_add(json_row, "upTime", timebuf);
9623 json_object_string_add(json_row, "keepAliveTimer",
9624 katimer);
9625 json_object_string_add(json_row, "connRetryTimer",
9626 crtimer);
9627 json_object_string_add(json_row, "holdTimer",
9628 holdtimer);
9629 json_object_string_add(json_row, "lastReset",
9630 mp->last_reset);
9631 json_object_int_add(json_row, "connAttempts",
9632 mp->conn_attempts);
9633 json_object_int_add(json_row, "establishedChanges",
9634 mp->est_flaps);
9635 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9636 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
9637 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
9638 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
9639 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
9640 json_object_object_add(json, peer_str, json_row);
9641 } else {
9642 vty_out(vty, "Peer : %s\n", peer_str);
9643 vty_out(vty, " Local : %s\n", local_str);
0ce04a08
RZ
9644 if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
9645 vty_out(vty, " Mesh Group : %s\n",
9646 mp->mesh_group_name);
d62a17ae 9647 vty_out(vty, " State : %s\n", state_str);
9648 vty_out(vty, " Uptime : %s\n", timebuf);
9649
9650 vty_out(vty, " Keepalive Timer : %s\n", katimer);
9651 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
9652 vty_out(vty, " Hold Timer : %s\n", holdtimer);
9653 vty_out(vty, " Last Reset : %s\n",
9654 mp->last_reset);
9655 vty_out(vty, " Conn Attempts : %d\n",
9656 mp->conn_attempts);
9657 vty_out(vty, " Established Changes : %d\n",
9658 mp->est_flaps);
9659 vty_out(vty, " SA Count : %d\n",
9660 mp->sa_cnt);
9661 vty_out(vty, " Statistics :\n");
9662 vty_out(vty,
9663 " Sent Rcvd\n");
9664 vty_out(vty, " Keepalives : %10d %10d\n",
9665 mp->ka_tx_cnt, mp->ka_rx_cnt);
9666 vty_out(vty, " SAs : %10d %10d\n",
9667 mp->sa_tx_cnt, mp->sa_rx_cnt);
9668 vty_out(vty, "\n");
9669 }
9670 }
9671
3757f964
DA
9672 if (uj)
9673 vty_json(vty, json);
977d71cc 9674}
9675
9676DEFUN (show_ip_msdp_peer_detail,
9677 show_ip_msdp_peer_detail_cmd,
20a7e5fd 9678 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
2a333e0f 9679 SHOW_STR
9680 IP_STR
9681 MSDP_STR
f02d59db 9682 VRF_CMD_HELP_STR
2a333e0f 9683 "MSDP peer information\n"
977d71cc 9684 "Detailed output\n"
9685 "peer ip address\n"
f5da2cc2 9686 JSON_STR)
2a333e0f 9687{
9f049418 9688 bool uj = use_json(argc, argv);
c68ba0d7 9689 int idx = 2;
02a16316 9690 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 9691
07a29355
QY
9692 if (!vrf)
9693 return CMD_WARNING;
9694
9695 char *arg = NULL;
9696
9697 if (argv_find(argv, argc, "detail", &idx))
9698 arg = argv[idx]->text;
9699 else if (argv_find(argv, argc, "A.B.C.D", &idx))
9700 arg = argv[idx]->arg;
9701
9702 if (arg)
64c86530 9703 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 9704 else
64c86530 9705 ip_msdp_show_peers(vrf->info, vty, uj);
d62a17ae 9706
9707 return CMD_SUCCESS;
9708}
9709
a25de56b
DS
9710DEFUN (show_ip_msdp_peer_detail_vrf_all,
9711 show_ip_msdp_peer_detail_vrf_all_cmd,
9712 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9713 SHOW_STR
9714 IP_STR
9715 MSDP_STR
9716 VRF_CMD_HELP_STR
9717 "MSDP peer information\n"
9718 "Detailed output\n"
9719 "peer ip address\n"
f5da2cc2 9720 JSON_STR)
a25de56b
DS
9721{
9722 int idx = 2;
9f049418 9723 bool uj = use_json(argc, argv);
a25de56b
DS
9724 struct vrf *vrf;
9725 bool first = true;
9726
9727 if (uj)
9728 vty_out(vty, "{ ");
a2addae8 9729 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9730 if (uj) {
9731 if (!first)
9732 vty_out(vty, ", ");
9733 vty_out(vty, " \"%s\": ", vrf->name);
9734 first = false;
9735 } else
9736 vty_out(vty, "VRF: %s\n", vrf->name);
9737 if (argv_find(argv, argc, "detail", &idx)
9738 || argv_find(argv, argc, "A.B.C.D", &idx))
9739 ip_msdp_show_peers_detail(vrf->info, vty,
9740 argv[idx]->arg, uj);
9741 else
9742 ip_msdp_show_peers(vrf->info, vty, uj);
9743 }
9744 if (uj)
9745 vty_out(vty, "}\n");
9746
9747 return CMD_SUCCESS;
9748}
9749
088f1098 9750static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 9751{
9752 struct listnode *sanode;
9753 struct pim_msdp_sa *sa;
d62a17ae 9754 char rp_str[INET_ADDRSTRLEN];
9755 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9756 char spt_str[8];
9757 char local_str[8];
9758 int64_t now;
9759 json_object *json = NULL;
9760 json_object *json_group = NULL;
9761 json_object *json_row = NULL;
9762
9763 if (uj) {
9764 json = json_object_new_object();
9765 } else {
9766 vty_out(vty,
9767 "Source Group RP Local SPT Uptime\n");
9768 }
9769
02a16316 9770 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9771 now = pim_time_monotonic_sec();
9772 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
d62a17ae 9773 if (sa->flags & PIM_MSDP_SAF_PEER) {
9774 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9775 if (sa->up) {
c35b7e6b 9776 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 9777 } else {
c35b7e6b 9778 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 9779 }
9780 } else {
c35b7e6b
QY
9781 strlcpy(rp_str, "-", sizeof(rp_str));
9782 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 9783 }
9784 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 9785 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 9786 } else {
c35b7e6b 9787 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 9788 }
9789 if (uj) {
8e8be741
DL
9790 char src_str[PIM_ADDRSTRLEN];
9791 char grp_str[PIM_ADDRSTRLEN];
9792
9793 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
9794 &sa->sg.grp);
9795 snprintfrr(src_str, sizeof(src_str), "%pPAs",
9796 &sa->sg.src);
9797
d62a17ae 9798 json_object_object_get_ex(json, grp_str, &json_group);
9799
9800 if (!json_group) {
9801 json_group = json_object_new_object();
9802 json_object_object_add(json, grp_str,
9803 json_group);
9804 }
9805
9806 json_row = json_object_new_object();
9807 json_object_string_add(json_row, "source", src_str);
9808 json_object_string_add(json_row, "group", grp_str);
9809 json_object_string_add(json_row, "rp", rp_str);
9810 json_object_string_add(json_row, "local", local_str);
9811 json_object_string_add(json_row, "sptSetup", spt_str);
9812 json_object_string_add(json_row, "upTime", timebuf);
9813 json_object_object_add(json_group, src_str, json_row);
9814 } else {
8e8be741
DL
9815 vty_out(vty, "%-15pPAs %15pPAs %15s %5c %3c %8s\n",
9816 &sa->sg.src, &sa->sg.grp, rp_str, local_str[0],
d62a17ae 9817 spt_str[0], timebuf);
9818 }
9819 }
9820
3757f964
DA
9821 if (uj)
9822 vty_json(vty, json);
d62a17ae 9823}
9824
9825static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
9826 const char *src_str,
9827 const char *grp_str, struct vty *vty,
088f1098 9828 bool uj, json_object *json)
d62a17ae 9829{
9830 char rp_str[INET_ADDRSTRLEN];
9831 char peer_str[INET_ADDRSTRLEN];
9832 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9833 char spt_str[8];
9834 char local_str[8];
9835 char statetimer[PIM_MSDP_TIMER_STRLEN];
9836 int64_t now;
9837 json_object *json_group = NULL;
9838 json_object *json_row = NULL;
9839
9840 now = pim_time_monotonic_sec();
9841 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9842 if (sa->flags & PIM_MSDP_SAF_PEER) {
9843 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9844 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
9845 if (sa->up) {
c35b7e6b 9846 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 9847 } else {
c35b7e6b 9848 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 9849 }
9850 } else {
c35b7e6b
QY
9851 strlcpy(rp_str, "-", sizeof(rp_str));
9852 strlcpy(peer_str, "-", sizeof(peer_str));
9853 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 9854 }
9855 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 9856 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 9857 } else {
c35b7e6b 9858 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 9859 }
9860 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
9861 sa->sa_state_timer);
9862 if (uj) {
9863 json_object_object_get_ex(json, grp_str, &json_group);
9864
9865 if (!json_group) {
9866 json_group = json_object_new_object();
9867 json_object_object_add(json, grp_str, json_group);
9868 }
9869
9870 json_row = json_object_new_object();
9871 json_object_string_add(json_row, "source", src_str);
9872 json_object_string_add(json_row, "group", grp_str);
9873 json_object_string_add(json_row, "rp", rp_str);
9874 json_object_string_add(json_row, "local", local_str);
9875 json_object_string_add(json_row, "sptSetup", spt_str);
9876 json_object_string_add(json_row, "upTime", timebuf);
9877 json_object_string_add(json_row, "stateTimer", statetimer);
9878 json_object_object_add(json_group, src_str, json_row);
9879 } else {
9880 vty_out(vty, "SA : %s\n", sa->sg_str);
9881 vty_out(vty, " RP : %s\n", rp_str);
9882 vty_out(vty, " Peer : %s\n", peer_str);
9883 vty_out(vty, " Local : %s\n", local_str);
9884 vty_out(vty, " SPT Setup : %s\n", spt_str);
9885 vty_out(vty, " Uptime : %s\n", timebuf);
9886 vty_out(vty, " State Timer : %s\n", statetimer);
9887 vty_out(vty, "\n");
9888 }
9889}
9890
64c86530 9891static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
088f1098 9892 bool uj)
d62a17ae 9893{
9894 struct listnode *sanode;
9895 struct pim_msdp_sa *sa;
d62a17ae 9896 json_object *json = NULL;
9897
9898 if (uj) {
9899 json = json_object_new_object();
9900 }
9901
02a16316 9902 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8e8be741
DL
9903 char src_str[PIM_ADDRSTRLEN];
9904 char grp_str[PIM_ADDRSTRLEN];
9905
9906 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
9907 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
9908
d62a17ae 9909 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
9910 json);
9911 }
9912
3757f964
DA
9913 if (uj)
9914 vty_json(vty, json);
977d71cc 9915}
9916
9917DEFUN (show_ip_msdp_sa_detail,
9918 show_ip_msdp_sa_detail_cmd,
20a7e5fd 9919 "show ip msdp [vrf NAME] sa detail [json]",
3c72d654 9920 SHOW_STR
9921 IP_STR
9922 MSDP_STR
f02d59db 9923 VRF_CMD_HELP_STR
3c72d654 9924 "MSDP active-source information\n"
977d71cc 9925 "Detailed output\n"
f5da2cc2 9926 JSON_STR)
3c72d654 9927{
9f049418 9928 bool uj = use_json(argc, argv);
c68ba0d7 9929 int idx = 2;
02a16316
DS
9930 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9931
9932 if (!vrf)
9933 return CMD_WARNING;
9934
64c86530 9935 ip_msdp_show_sa_detail(vrf->info, vty, uj);
977d71cc 9936
d62a17ae 9937 return CMD_SUCCESS;
977d71cc 9938}
9939
a25de56b
DS
9940DEFUN (show_ip_msdp_sa_detail_vrf_all,
9941 show_ip_msdp_sa_detail_vrf_all_cmd,
9942 "show ip msdp vrf all sa detail [json]",
9943 SHOW_STR
9944 IP_STR
9945 MSDP_STR
9946 VRF_CMD_HELP_STR
9947 "MSDP active-source information\n"
9948 "Detailed output\n"
f5da2cc2 9949 JSON_STR)
a25de56b 9950{
9f049418 9951 bool uj = use_json(argc, argv);
a25de56b
DS
9952 struct vrf *vrf;
9953 bool first = true;
9954
9955 if (uj)
9956 vty_out(vty, "{ ");
a2addae8 9957 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9958 if (uj) {
9959 if (!first)
9960 vty_out(vty, ", ");
9961 vty_out(vty, " \"%s\": ", vrf->name);
9962 first = false;
9963 } else
9964 vty_out(vty, "VRF: %s\n", vrf->name);
9965 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9966 }
9967 if (uj)
9968 vty_out(vty, "}\n");
9969
9970 return CMD_SUCCESS;
9971}
9972
64c86530 9973static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
088f1098 9974 const char *addr, bool uj)
977d71cc 9975{
d62a17ae 9976 struct listnode *sanode;
9977 struct pim_msdp_sa *sa;
d62a17ae 9978 json_object *json = NULL;
977d71cc 9979
d62a17ae 9980 if (uj) {
9981 json = json_object_new_object();
9982 }
977d71cc 9983
02a16316 9984 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8e8be741
DL
9985 char src_str[PIM_ADDRSTRLEN];
9986 char grp_str[PIM_ADDRSTRLEN];
9987
9988 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
9989 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
9990
d62a17ae 9991 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
9992 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9993 uj, json);
9994 }
9995 }
977d71cc 9996
3757f964
DA
9997 if (uj)
9998 vty_json(vty, json);
977d71cc 9999}
10000
64c86530 10001static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
088f1098 10002 const char *src, const char *grp, bool uj)
977d71cc 10003{
d62a17ae 10004 struct listnode *sanode;
10005 struct pim_msdp_sa *sa;
d62a17ae 10006 json_object *json = NULL;
977d71cc 10007
d62a17ae 10008 if (uj) {
10009 json = json_object_new_object();
10010 }
977d71cc 10011
02a16316 10012 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8e8be741
DL
10013 char src_str[PIM_ADDRSTRLEN];
10014 char grp_str[PIM_ADDRSTRLEN];
10015
10016 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
10017 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
10018
d62a17ae 10019 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
10020 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
10021 uj, json);
10022 }
10023 }
977d71cc 10024
3757f964
DA
10025 if (uj)
10026 vty_json(vty, json);
977d71cc 10027}
10028
10029DEFUN (show_ip_msdp_sa_sg,
10030 show_ip_msdp_sa_sg_cmd,
20a7e5fd 10031 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
977d71cc 10032 SHOW_STR
10033 IP_STR
10034 MSDP_STR
f02d59db 10035 VRF_CMD_HELP_STR
977d71cc 10036 "MSDP active-source information\n"
10037 "source or group ip\n"
a957a05b 10038 "group ip\n"
f5da2cc2 10039 JSON_STR)
977d71cc 10040{
9f049418 10041 bool uj = use_json(argc, argv);
02a16316 10042 struct vrf *vrf;
c68ba0d7 10043 int idx = 2;
02a16316
DS
10044
10045 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10046
10047 if (!vrf)
10048 return CMD_WARNING;
10049
d62a17ae 10050 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
521c5b9d 10051 : NULL;
d62a17ae 10052 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
521c5b9d
MS
10053 ? argv[idx]->arg
10054 : NULL;
9ea49d61 10055
d62a17ae 10056 if (src_ip && grp_ip)
64c86530 10057 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
d62a17ae 10058 else if (src_ip)
64c86530 10059 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
d62a17ae 10060 else
64c86530 10061 ip_msdp_show_sa(vrf->info, vty, uj);
3c72d654 10062
d62a17ae 10063 return CMD_SUCCESS;
3c72d654 10064}
10065
47bf9e21
DS
10066DEFUN (show_ip_msdp_sa_sg_vrf_all,
10067 show_ip_msdp_sa_sg_vrf_all_cmd,
10068 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10069 SHOW_STR
10070 IP_STR
10071 MSDP_STR
10072 VRF_CMD_HELP_STR
10073 "MSDP active-source information\n"
10074 "source or group ip\n"
10075 "group ip\n"
10076 JSON_STR)
10077{
9f049418 10078 bool uj = use_json(argc, argv);
47bf9e21
DS
10079 struct vrf *vrf;
10080 bool first = true;
10081 int idx = 2;
10082
10083 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
521c5b9d 10084 : NULL;
47bf9e21 10085 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
521c5b9d
MS
10086 ? argv[idx]->arg
10087 : NULL;
47bf9e21
DS
10088
10089 if (uj)
10090 vty_out(vty, "{ ");
a2addae8 10091 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
47bf9e21
DS
10092 if (uj) {
10093 if (!first)
10094 vty_out(vty, ", ");
10095 vty_out(vty, " \"%s\": ", vrf->name);
10096 first = false;
10097 } else
10098 vty_out(vty, "VRF: %s\n", vrf->name);
10099
10100 if (src_ip && grp_ip)
10101 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
10102 else if (src_ip)
10103 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
10104 else
10105 ip_msdp_show_sa(vrf->info, vty, uj);
10106 }
10107 if (uj)
10108 vty_out(vty, "}\n");
10109
10110 return CMD_SUCCESS;
10111}
10112
f1e2901a
AK
10113struct pim_sg_cache_walk_data {
10114 struct vty *vty;
10115 json_object *json;
10116 json_object *json_group;
10117 struct in_addr addr;
10118 bool addr_match;
10119};
10120
10121static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
521c5b9d 10122 struct pim_sg_cache_walk_data *cwd)
f1e2901a
AK
10123{
10124 struct vty *vty = cwd->vty;
10125 json_object *json = cwd->json;
f1e2901a 10126 json_object *json_row;
2951a7a4 10127 bool installed = (vxlan_sg->up) ? true : false;
f1e2901a
AK
10128 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10129 const char *oif_name;
10130
10131 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10132 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10133 else
10134 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10135
032a7412
DL
10136 if (cwd->addr_match && pim_addr_cmp(vxlan_sg->sg.src, cwd->addr) &&
10137 pim_addr_cmp(vxlan_sg->sg.grp, cwd->addr)) {
f1e2901a
AK
10138 return;
10139 }
f1e2901a 10140 if (json) {
8e8be741
DL
10141 char src_str[PIM_ADDRSTRLEN];
10142 char grp_str[PIM_ADDRSTRLEN];
10143
10144 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
10145 &vxlan_sg->sg.grp);
10146 snprintfrr(src_str, sizeof(src_str), "%pPAs",
10147 &vxlan_sg->sg.src);
10148
f1e2901a
AK
10149 json_object_object_get_ex(json, grp_str, &cwd->json_group);
10150
10151 if (!cwd->json_group) {
10152 cwd->json_group = json_object_new_object();
10153 json_object_object_add(json, grp_str,
521c5b9d 10154 cwd->json_group);
f1e2901a
AK
10155 }
10156
10157 json_row = json_object_new_object();
10158 json_object_string_add(json_row, "source", src_str);
10159 json_object_string_add(json_row, "group", grp_str);
10160 json_object_string_add(json_row, "input", iif_name);
10161 json_object_string_add(json_row, "output", oif_name);
10162 if (installed)
10163 json_object_boolean_true_add(json_row, "installed");
10164 else
10165 json_object_boolean_false_add(json_row, "installed");
10166 json_object_object_add(cwd->json_group, src_str, json_row);
10167 } else {
8e8be741
DL
10168 vty_out(vty, "%-15pPAs %-15pPAs %-15s %-15s %-5s\n",
10169 &vxlan_sg->sg.src, &vxlan_sg->sg.grp, iif_name,
10170 oif_name, installed ? "I" : "");
f1e2901a
AK
10171 }
10172}
10173
1ac88792 10174static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *bucket, void *arg)
f1e2901a 10175{
1ac88792 10176 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)bucket->data,
521c5b9d 10177 (struct pim_sg_cache_walk_data *)arg);
f1e2901a
AK
10178}
10179
10180static void pim_show_vxlan_sg(struct pim_instance *pim,
521c5b9d 10181 struct vty *vty, bool uj)
f1e2901a
AK
10182{
10183 json_object *json = NULL;
10184 struct pim_sg_cache_walk_data cwd;
10185
10186 if (uj) {
10187 json = json_object_new_object();
10188 } else {
10189 vty_out(vty, "Codes: I -> installed\n");
10190 vty_out(vty,
10191 "Source Group Input Output Flags\n");
10192 }
10193
10194 memset(&cwd, 0, sizeof(cwd));
10195 cwd.vty = vty;
10196 cwd.json = json;
10197 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10198
3757f964
DA
10199 if (uj)
10200 vty_json(vty, json);
f1e2901a
AK
10201}
10202
10203static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
521c5b9d
MS
10204 struct vty *vty, char *addr_str,
10205 bool uj)
f1e2901a
AK
10206{
10207 json_object *json = NULL;
10208 struct pim_sg_cache_walk_data cwd;
10209 int result = 0;
10210
10211 memset(&cwd, 0, sizeof(cwd));
10212 result = inet_pton(AF_INET, addr_str, &cwd.addr);
10213 if (result <= 0) {
10214 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
521c5b9d 10215 errno, safe_strerror(errno));
f1e2901a
AK
10216 return;
10217 }
10218
10219 if (uj) {
10220 json = json_object_new_object();
10221 } else {
10222 vty_out(vty, "Codes: I -> installed\n");
10223 vty_out(vty,
10224 "Source Group Input Output Flags\n");
10225 }
10226
10227 cwd.vty = vty;
10228 cwd.json = json;
2951a7a4 10229 cwd.addr_match = true;
f1e2901a
AK
10230 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10231
3757f964
DA
10232 if (uj)
10233 vty_json(vty, json);
f1e2901a
AK
10234}
10235
10236static void pim_show_vxlan_sg_one(struct pim_instance *pim,
521c5b9d
MS
10237 struct vty *vty, char *src_str, char *grp_str,
10238 bool uj)
f1e2901a
AK
10239{
10240 json_object *json = NULL;
6fff2cc6 10241 pim_sgaddr sg;
f1e2901a
AK
10242 int result = 0;
10243 struct pim_vxlan_sg *vxlan_sg;
10244 const char *iif_name;
10245 bool installed;
10246 const char *oif_name;
10247
10248 result = inet_pton(AF_INET, src_str, &sg.src);
10249 if (result <= 0) {
10250 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
521c5b9d 10251 errno, safe_strerror(errno));
f1e2901a
AK
10252 return;
10253 }
10254 result = inet_pton(AF_INET, grp_str, &sg.grp);
10255 if (result <= 0) {
10256 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
521c5b9d 10257 errno, safe_strerror(errno));
f1e2901a
AK
10258 return;
10259 }
10260
f1e2901a
AK
10261 if (uj)
10262 json = json_object_new_object();
10263
10264 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
10265 if (vxlan_sg) {
2951a7a4 10266 installed = (vxlan_sg->up) ? true : false;
f1e2901a
AK
10267 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10268
10269 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10270 oif_name =
10271 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10272 else
10273 oif_name =
10274 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10275
10276 if (uj) {
10277 json_object_string_add(json, "source", src_str);
10278 json_object_string_add(json, "group", grp_str);
10279 json_object_string_add(json, "input", iif_name);
10280 json_object_string_add(json, "output", oif_name);
10281 if (installed)
10282 json_object_boolean_true_add(json, "installed");
10283 else
10284 json_object_boolean_false_add(json,
521c5b9d 10285 "installed");
f1e2901a
AK
10286 } else {
10287 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
10288 vty_out(vty, " Input : %s\n", iif_name);
10289 vty_out(vty, " Output : %s\n", oif_name);
10290 vty_out(vty, " installed : %s\n",
10291 installed?"yes":"no");
10292 }
10293 }
10294
3757f964
DA
10295 if (uj)
10296 vty_json(vty, json);
f1e2901a
AK
10297}
10298
10299DEFUN (show_ip_pim_vxlan_sg,
10300 show_ip_pim_vxlan_sg_cmd,
10301 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10302 SHOW_STR
10303 IP_STR
10304 PIM_STR
10305 VRF_CMD_HELP_STR
10306 "VxLAN BUM groups\n"
10307 "source or group ip\n"
10308 "group ip\n"
10309 JSON_STR)
10310{
10311 bool uj = use_json(argc, argv);
10312 struct vrf *vrf;
10313 int idx = 2;
10314
10315 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10316
10317 if (!vrf)
10318 return CMD_WARNING;
10319
10320 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
10321 argv[idx++]->arg:NULL;
10322 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
10323 argv[idx]->arg:NULL;
10324
10325 if (src_ip && grp_ip)
10326 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
10327 else if (src_ip)
10328 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
10329 else
10330 pim_show_vxlan_sg(vrf->info, vty, uj);
10331
10332 return CMD_SUCCESS;
10333}
10334
10335static void pim_show_vxlan_sg_work(struct pim_instance *pim,
521c5b9d 10336 struct vty *vty, bool uj)
f1e2901a
AK
10337{
10338 json_object *json = NULL;
10339 struct pim_sg_cache_walk_data cwd;
10340 struct listnode *node;
10341 struct pim_vxlan_sg *vxlan_sg;
10342
10343 if (uj) {
10344 json = json_object_new_object();
10345 } else {
10346 vty_out(vty, "Codes: I -> installed\n");
10347 vty_out(vty,
10348 "Source Group Input Flags\n");
10349 }
10350
10351 memset(&cwd, 0, sizeof(cwd));
10352 cwd.vty = vty;
10353 cwd.json = json;
10354 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
10355 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
10356
3757f964
DA
10357 if (uj)
10358 vty_json(vty, json);
f1e2901a
AK
10359}
10360
10361DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
10362 show_ip_pim_vxlan_sg_work_cmd,
10363 "show ip pim [vrf NAME] vxlan-work [json]",
10364 SHOW_STR
10365 IP_STR
10366 PIM_STR
10367 VRF_CMD_HELP_STR
10368 "VxLAN work list\n"
10369 JSON_STR)
10370{
10371 bool uj = use_json(argc, argv);
10372 struct vrf *vrf;
10373 int idx = 2;
10374
10375 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10376
10377 if (!vrf)
10378 return CMD_WARNING;
10379
10380 pim_show_vxlan_sg_work(vrf->info, vty, uj);
10381
10382 return CMD_SUCCESS;
10383}
10384
7c85225c 10385DEFUN_HIDDEN (no_ip_pim_mlag,
521c5b9d
MS
10386 no_ip_pim_mlag_cmd,
10387 "no ip pim mlag",
10388 NO_STR
10389 IP_STR
10390 PIM_STR
10391 "MLAG\n")
7c85225c 10392{
0c949724 10393 char mlag_xpath[XPATH_MAXLEN];
7c85225c 10394
698f4147 10395 snprintf(mlag_xpath, sizeof(mlag_xpath), FRR_PIM_VRF_XPATH,
0c949724
SP
10396 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10397 strlcat(mlag_xpath, "/mlag", sizeof(mlag_xpath));
7c85225c 10398
0c949724
SP
10399 nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL);
10400
10401
10402 return nb_cli_apply_changes(vty, NULL);
7c85225c
AK
10403}
10404
10405DEFUN_HIDDEN (ip_pim_mlag,
521c5b9d
MS
10406 ip_pim_mlag_cmd,
10407 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10408 IP_STR
10409 PIM_STR
10410 "MLAG\n"
10411 "peerlink sub interface\n"
10412 "MLAG role\n"
10413 "MLAG role primary\n"
10414 "MLAG role secondary\n"
10415 "peer session state\n"
10416 "peer session state up\n"
10417 "peer session state down\n"
10418 "configure PIP\n"
10419 "unique ip address\n")
7c85225c 10420{
7c85225c 10421 int idx;
0c949724
SP
10422 char mlag_peerlink_rif_xpath[XPATH_MAXLEN];
10423 char mlag_my_role_xpath[XPATH_MAXLEN];
10424 char mlag_peer_state_xpath[XPATH_MAXLEN];
10425 char mlag_reg_address_xpath[XPATH_MAXLEN];
10426
10427 snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath),
698f4147 10428 FRR_PIM_VRF_XPATH,
0c949724
SP
10429 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10430 strlcat(mlag_peerlink_rif_xpath, "/mlag/peerlink-rif",
10431 sizeof(mlag_peerlink_rif_xpath));
7c85225c
AK
10432
10433 idx = 3;
0c949724 10434 nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY,
521c5b9d 10435 argv[idx]->arg);
0c949724
SP
10436
10437 snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath),
698f4147 10438 FRR_PIM_VRF_XPATH,
0c949724
SP
10439 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10440 strlcat(mlag_my_role_xpath, "/mlag/my-role",
10441 sizeof(mlag_my_role_xpath));
7c85225c
AK
10442
10443 idx += 2;
10444 if (!strcmp(argv[idx]->arg, "primary")) {
0c949724 10445 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
521c5b9d 10446 "MLAG_ROLE_PRIMARY");
0c949724 10447
7c85225c 10448 } else if (!strcmp(argv[idx]->arg, "secondary")) {
0c949724 10449 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
521c5b9d 10450 "MLAG_ROLE_SECONDARY");
0c949724 10451
7c85225c
AK
10452 } else {
10453 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
10454 return CMD_WARNING;
10455 }
10456
0c949724 10457 snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath),
698f4147 10458 FRR_PIM_VRF_XPATH,
0c949724
SP
10459 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10460 strlcat(mlag_peer_state_xpath, "/mlag/peer-state",
10461 sizeof(mlag_peer_state_xpath));
10462
7c85225c
AK
10463 idx += 2;
10464 if (!strcmp(argv[idx]->arg, "up")) {
0c949724 10465 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
521c5b9d 10466 "true");
0c949724 10467
7c85225c 10468 } else if (strcmp(argv[idx]->arg, "down")) {
0c949724 10469 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
521c5b9d 10470 "false");
0c949724 10471
7c85225c
AK
10472 } else {
10473 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
10474 return CMD_WARNING;
10475 }
10476
0c949724 10477 snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath),
698f4147 10478 FRR_PIM_VRF_XPATH,
0c949724
SP
10479 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
10480 strlcat(mlag_reg_address_xpath, "/mlag/reg-address",
10481 sizeof(mlag_reg_address_xpath));
10482
7c85225c 10483 idx += 2;
0c949724 10484 nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY,
521c5b9d 10485 argv[idx]->arg);
7c85225c 10486
0c949724 10487 return nb_cli_apply_changes(vty, NULL);
7c85225c
AK
10488}
10489
c68ba0d7 10490void pim_cmd_init(void)
12e41d03 10491{
9da01b0b 10492 if_cmd_init(pim_interface_config_write);
d62a17ae 10493
612c2c15 10494 install_node(&debug_node);
d62a17ae 10495
70fd22bd
DS
10496 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
10497
d62a17ae 10498 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
9ecb7b77 10499 install_element(VRF_NODE, &ip_pim_rp_cmd);
d62a17ae 10500 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
9ecb7b77 10501 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
d62a17ae 10502 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
4f9f3925 10503 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
d62a17ae 10504 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
4f9f3925 10505 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
d62a17ae 10506 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
4f9f3925 10507 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
d62a17ae 10508 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
4f9f3925 10509 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
d62a17ae 10510 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
4f9f3925 10511 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
d62a17ae 10512 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
10513 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
10514 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
4f9f3925 10515 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
d62a17ae 10516 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 10517 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 10518 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
4f9f3925 10519 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
d62a17ae 10520 install_element(CONFIG_NODE,
10521 &no_ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 10522 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
f4e74bd0
DS
10523 install_element(CONFIG_NODE, &pim_register_accept_list_cmd);
10524 install_element(VRF_NODE, &pim_register_accept_list_cmd);
d62a17ae 10525 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
10526 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
10527 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
4f9f3925 10528 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
cc14df13
DS
10529 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
10530 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
d62a17ae 10531 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
4f9f3925 10532 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
cc14df13
DS
10533 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
10534 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
d62a17ae 10535 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
10536 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
10537 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
4f9f3925 10538 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
d62a17ae 10539 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
4f9f3925 10540 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
d62a17ae 10541 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
4f9f3925 10542 install_element(VRF_NODE, &ip_ssmpingd_cmd);
d62a17ae 10543 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
4f9f3925 10544 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
d62a17ae 10545 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
4f9f3925 10546 install_element(VRF_NODE, &ip_msdp_peer_cmd);
d62a17ae 10547 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
4f9f3925 10548 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
d62a17ae 10549 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
4f9f3925 10550 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
d62a17ae 10551 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
4f9f3925 10552 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
d62a17ae 10553 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
4f9f3925 10554 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
d62a17ae 10555 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
4f9f3925 10556 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
7c85225c
AK
10557 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
10558 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
339f7695 10559 install_element(CONFIG_NODE, &igmp_group_watermark_cmd);
10560 install_element(VRF_NODE, &igmp_group_watermark_cmd);
10561 install_element(CONFIG_NODE, &no_igmp_group_watermark_cmd);
10562 install_element(VRF_NODE, &no_igmp_group_watermark_cmd);
d62a17ae 10563
10564 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
10565 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
10566 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
10567 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
10568 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
10569 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
10570 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
10571 install_element(INTERFACE_NODE,
10572 &interface_no_ip_igmp_query_interval_cmd);
10573 install_element(INTERFACE_NODE,
10574 &interface_ip_igmp_query_max_response_time_cmd);
10575 install_element(INTERFACE_NODE,
10576 &interface_no_ip_igmp_query_max_response_time_cmd);
10577 install_element(INTERFACE_NODE,
10578 &interface_ip_igmp_query_max_response_time_dsec_cmd);
10579 install_element(INTERFACE_NODE,
10580 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
59115451
SP
10581 install_element(INTERFACE_NODE,
10582 &interface_ip_igmp_last_member_query_count_cmd);
10583 install_element(INTERFACE_NODE,
10584 &interface_no_ip_igmp_last_member_query_count_cmd);
10585 install_element(INTERFACE_NODE,
10586 &interface_ip_igmp_last_member_query_interval_cmd);
10587 install_element(INTERFACE_NODE,
10588 &interface_no_ip_igmp_last_member_query_interval_cmd);
414d885a 10589 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
d62a17ae 10590 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
10591 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
10592 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
10593 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
2f5e937c 10594 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
10595 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
d62a17ae 10596 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
10597 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
10598 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
10599 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
b0f525a8
QY
10600 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
10601 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
6741a5bb 10602 install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
d62a17ae 10603
10604 // Static mroutes NEB
10605 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
d62a17ae 10606 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
d62a17ae 10607
10608 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
a25de56b 10609 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
d62a17ae 10610 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
a25de56b 10611 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
d62a17ae 10612 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
a25de56b 10613 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
d62a17ae 10614 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
10615 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
10616 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
21313cbf 10617 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
d62a17ae 10618 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
10619 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
10620 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
10621 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
10622 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
10623 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
a25de56b 10624 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
d62a17ae 10625 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
a25de56b 10626 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
87b7cd5b 10627 install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
d62a17ae 10628 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
f80427e9
AK
10629 install_element(VIEW_NODE, &show_ip_pim_mlag_summary_cmd);
10630 install_element(VIEW_NODE, &show_ip_pim_mlag_up_cmd);
10631 install_element(VIEW_NODE, &show_ip_pim_mlag_up_vrf_all_cmd);
d62a17ae 10632 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
a25de56b 10633 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
d62a17ae 10634 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
a25de56b 10635 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
d62a17ae 10636 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
10637 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
a25de56b 10638 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
d62a17ae 10639 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
a25de56b 10640 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
5c9a72ef 10641 install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
d62a17ae 10642 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
10643 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
10644 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
a25de56b 10645 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
256392eb 10646 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
d62a17ae 10647 install_element(VIEW_NODE, &show_ip_multicast_cmd);
a25de56b 10648 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
8c8d7031
SP
10649 install_element(VIEW_NODE, &show_ip_multicast_count_cmd);
10650 install_element(VIEW_NODE, &show_ip_multicast_count_vrf_all_cmd);
d62a17ae 10651 install_element(VIEW_NODE, &show_ip_mroute_cmd);
b283a4ca 10652 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
d62a17ae 10653 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
5c3aac90 10654 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
468b6f44
SP
10655 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
10656 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
d62a17ae 10657 install_element(VIEW_NODE, &show_ip_rib_cmd);
10658 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
d62a17ae 10659 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
10660 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
321295c1 10661 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
0d1a4e24 10662 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
415f6350 10663 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
d62a17ae 10664
cd333cf9 10665 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
d62a17ae 10666 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
10667 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
10668 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
10669 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
10670 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
10671 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
415f6350 10672 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
e7016ceb 10673 install_element(ENABLE_NODE, &clear_ip_pim_bsr_db_cmd);
d62a17ae 10674
dd73744d
IR
10675 install_element(ENABLE_NODE, &show_debugging_pim_cmd);
10676
d62a17ae 10677 install_element(ENABLE_NODE, &debug_igmp_cmd);
10678 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
10679 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
10680 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
10681 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
10682 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
10683 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
10684 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
10685 install_element(ENABLE_NODE, &debug_mroute_cmd);
10686 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
10687 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
10688 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
10689 install_element(ENABLE_NODE, &debug_pim_static_cmd);
10690 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
d62a17ae 10691 install_element(ENABLE_NODE, &debug_pim_cmd);
10692 install_element(ENABLE_NODE, &no_debug_pim_cmd);
40f1f31b
DS
10693 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
10694 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
3d225d48
DS
10695 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
10696 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 10697 install_element(ENABLE_NODE, &debug_pim_events_cmd);
10698 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
10699 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
10700 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
10701 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
10702 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
10703 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
10704 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
10705 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
10706 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
10707 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
10708 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 10709 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
10710 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
10711 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
10712 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
36b5b98f
SK
10713 install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
10714 install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
4d913fa6
AK
10715 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
10716 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 10717 install_element(ENABLE_NODE, &debug_msdp_cmd);
10718 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
d62a17ae 10719 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
10720 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
d62a17ae 10721 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
10722 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
10723 install_element(ENABLE_NODE, &debug_mtrace_cmd);
10724 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
09524ccf 10725 install_element(ENABLE_NODE, &debug_bsm_cmd);
10726 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
d62a17ae 10727
10728 install_element(CONFIG_NODE, &debug_igmp_cmd);
10729 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
10730 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
10731 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
10732 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
10733 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
10734 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
10735 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
10736 install_element(CONFIG_NODE, &debug_mroute_cmd);
10737 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
10738 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
10739 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
10740 install_element(CONFIG_NODE, &debug_pim_static_cmd);
10741 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
d62a17ae 10742 install_element(CONFIG_NODE, &debug_pim_cmd);
10743 install_element(CONFIG_NODE, &no_debug_pim_cmd);
40f1f31b
DS
10744 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
10745 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
3d225d48
DS
10746 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
10747 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 10748 install_element(CONFIG_NODE, &debug_pim_events_cmd);
10749 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
10750 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
10751 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
5c4508cb 10752 install_element(CONFIG_NODE, &debug_pim_packetdump_send_cmd);
10753 install_element(CONFIG_NODE, &no_debug_pim_packetdump_send_cmd);
10754 install_element(CONFIG_NODE, &debug_pim_packetdump_recv_cmd);
10755 install_element(CONFIG_NODE, &no_debug_pim_packetdump_recv_cmd);
d62a17ae 10756 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
10757 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
10758 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
10759 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 10760 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
10761 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
10762 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
10763 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
f80427e9
AK
10764 install_element(CONFIG_NODE, &debug_pim_mlag_cmd);
10765 install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd);
4d913fa6
AK
10766 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
10767 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 10768 install_element(CONFIG_NODE, &debug_msdp_cmd);
10769 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
d62a17ae 10770 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
10771 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
d62a17ae 10772 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
10773 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
10774 install_element(CONFIG_NODE, &debug_mtrace_cmd);
10775 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
09524ccf 10776 install_element(CONFIG_NODE, &debug_bsm_cmd);
10777 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
02a16316 10778
622fd3f1
RZ
10779 install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
10780 install_element(VRF_NODE, &ip_msdp_timers_cmd);
11ca3587
CH
10781 install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd);
10782 install_element(VRF_NODE, &no_ip_msdp_timers_cmd);
d62a17ae 10783 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
02a16316 10784 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
d62a17ae 10785 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
1b973cb7 10786 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
d62a17ae 10787 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
02a16316 10788 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
d62a17ae 10789 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
02a16316 10790 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
34d86eff
SP
10791 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd);
10792 install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd);
d62a17ae 10793 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
a25de56b 10794 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
d62a17ae 10795 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
a25de56b 10796 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
d62a17ae 10797 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
47bf9e21 10798 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
d62a17ae 10799 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
a25de56b 10800 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
d62a17ae 10801 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
10802 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
f1e2901a
AK
10803 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
10804 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
d62a17ae 10805 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
10806 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
16c926c8 10807 /* Install BSM command */
10808 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
10809 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
10810 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
10811 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
d62a17ae 10812 /* Install BFD command */
10813 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
10814 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
745b8d4a 10815 install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd);
d62a17ae 10816 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
64dc4b2d 10817#if HAVE_BFDD == 0
d62a17ae 10818 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
64dc4b2d 10819#endif /* !HAVE_BFDD */
12e41d03 10820}