]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
pim6d: Implementing "show ipv6 pim rpf" CLI
[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);
7d0bc729
DA
1658 json_object_int_add(json_row, "pruneRx",
1659 pim_ifp->pim_ifstat_prune_recv);
1660 json_object_int_add(json_row, "pruneTx",
1661 pim_ifp->pim_ifstat_prune_send);
d62a17ae 1662 json_object_int_add(json_row, "registerRx",
1663 pim_ifp->pim_ifstat_reg_recv);
1664 json_object_int_add(json_row, "registerTx",
1665 pim_ifp->pim_ifstat_reg_recv);
1666 json_object_int_add(json_row, "registerStopRx",
1667 pim_ifp->pim_ifstat_reg_stop_recv);
1668 json_object_int_add(json_row, "registerStopTx",
1669 pim_ifp->pim_ifstat_reg_stop_send);
1670 json_object_int_add(json_row, "assertRx",
1671 pim_ifp->pim_ifstat_assert_recv);
1672 json_object_int_add(json_row, "assertTx",
1673 pim_ifp->pim_ifstat_assert_send);
4616b2e9 1674 json_object_int_add(json_row, "bsmRx",
1675 pim_ifp->pim_ifstat_bsm_rx);
1676 json_object_int_add(json_row, "bsmTx",
1677 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1678
1679 json_object_object_add(json, ifp->name, json_row);
1680 } else {
1681 vty_out(vty,
9a8a7b0e 1682 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64 "/%-7" PRIu64 "\n",
d62a17ae 1683 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1684 pim_ifp->pim_ifstat_hello_sent,
1685 pim_ifp->pim_ifstat_join_recv,
1686 pim_ifp->pim_ifstat_join_send,
1687 pim_ifp->pim_ifstat_prune_recv,
1688 pim_ifp->pim_ifstat_prune_send,
1689 pim_ifp->pim_ifstat_reg_recv,
1690 pim_ifp->pim_ifstat_reg_send,
1691 pim_ifp->pim_ifstat_reg_stop_recv,
1692 pim_ifp->pim_ifstat_reg_stop_send,
1693 pim_ifp->pim_ifstat_assert_recv,
4616b2e9 1694 pim_ifp->pim_ifstat_assert_send,
1695 pim_ifp->pim_ifstat_bsm_rx,
1696 pim_ifp->pim_ifstat_bsm_tx);
d62a17ae 1697 }
1698 }
3757f964
DA
1699 if (uj)
1700 vty_json(vty, json);
1701 else if (!found_ifname)
1702 vty_out(vty, "%% No such interface\n");
39438188
CS
1703}
1704
996c9314
LB
1705static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
1706 struct pim_ifchannel *ch, json_object *json,
088f1098 1707 time_t now, bool uj)
1a8a3da8 1708{
1a8a3da8
DS
1709 json_object *json_iface = NULL;
1710 json_object *json_row = NULL;
1711 json_object *json_grp = NULL;
1712 struct in_addr ifaddr;
1713 char uptime[10];
1714 char expire[10];
1715 char prune[10];
ee2bbf7c 1716 char buf[PREFIX_STRLEN];
1a8a3da8
DS
1717
1718 ifaddr = pim_ifp->primary_address;
1719
996c9314 1720 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
1a8a3da8
DS
1721 pim_time_timer_to_mmss(expire, sizeof(expire),
1722 ch->t_ifjoin_expiry_timer);
1723 pim_time_timer_to_mmss(prune, sizeof(prune),
1724 ch->t_ifjoin_prune_pending_timer);
1725
1726 if (uj) {
8e8be741
DL
1727 char ch_grp_str[PIM_ADDRSTRLEN];
1728 char ch_src_str[PIM_ADDRSTRLEN];
1729
1730 snprintfrr(ch_grp_str, sizeof(ch_grp_str), "%pPAs",
1731 &ch->sg.grp);
1732 snprintfrr(ch_src_str, sizeof(ch_src_str), "%pPAs",
1733 &ch->sg.src);
1734
1a8a3da8
DS
1735 json_object_object_get_ex(json, ch->interface->name,
1736 &json_iface);
1737
1738 if (!json_iface) {
1739 json_iface = json_object_new_object();
996c9314
LB
1740 json_object_pim_ifp_add(json_iface, ch->interface);
1741 json_object_object_add(json, ch->interface->name,
1742 json_iface);
1a8a3da8
DS
1743 }
1744
1745 json_row = json_object_new_object();
1746 json_object_string_add(json_row, "source", ch_src_str);
1747 json_object_string_add(json_row, "group", ch_grp_str);
1748 json_object_string_add(json_row, "upTime", uptime);
1749 json_object_string_add(json_row, "expire", expire);
1750 json_object_string_add(json_row, "prune", prune);
1751 json_object_string_add(
1752 json_row, "channelJoinName",
996c9314 1753 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
77a2f8e5
DA
1754 if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) {
1755#if CONFDATE > 20230131
1756CPP_NOTICE("Remove JSON object commands with keys starting with capital")
1757#endif
1a8a3da8 1758 json_object_int_add(json_row, "SGRpt", 1);
77a2f8e5
DA
1759 json_object_int_add(json_row, "sgRpt", 1);
1760 }
9443810e
SP
1761 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch->flags))
1762 json_object_int_add(json_row, "protocolPim", 1);
1763 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch->flags))
1764 json_object_int_add(json_row, "protocolIgmp", 1);
996c9314 1765 json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
1a8a3da8
DS
1766 if (!json_grp) {
1767 json_grp = json_object_new_object();
996c9314 1768 json_object_object_add(json_grp, ch_src_str, json_row);
1a8a3da8
DS
1769 json_object_object_add(json_iface, ch_grp_str,
1770 json_grp);
1771 } else
996c9314 1772 json_object_object_add(json_grp, ch_src_str, json_row);
1a8a3da8 1773 } else {
8e8be741 1774 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-10s %8s %-6s %5s\n",
ee2bbf7c
MS
1775 ch->interface->name,
1776 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
8e8be741 1777 &ch->sg.src, &ch->sg.grp,
996c9314 1778 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
1a8a3da8
DS
1779 uptime, expire, prune);
1780 }
1781}
1782
6de45bcc 1783static void pim_show_join(struct pim_instance *pim, struct vty *vty,
6fff2cc6 1784 pim_sgaddr *sg, bool uj)
12e41d03 1785{
d62a17ae 1786 struct pim_interface *pim_ifp;
d62a17ae 1787 struct pim_ifchannel *ch;
1a8a3da8 1788 struct interface *ifp;
d62a17ae 1789 time_t now;
1790 json_object *json = NULL;
d62a17ae 1791
1792 now = pim_time_monotonic_sec();
1793
1794 if (uj)
1795 json = json_object_new_object();
1796 else
1797 vty_out(vty,
ff415346 1798 "Interface Address Source Group State Uptime Expire Prune\n");
d62a17ae 1799
451fda4f 1800 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8 1801 pim_ifp = ifp->info;
d62a17ae 1802 if (!pim_ifp)
1803 continue;
1804
a2addae8 1805 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
62f59b58 1806 if (!pim_sgaddr_match(ch->sg, *sg))
975a328e 1807 continue;
a2addae8 1808 pim_show_join_helper(vty, pim_ifp, ch, json, now, uj);
1a8a3da8
DS
1809 } /* scan interface channels */
1810 }
d62a17ae 1811
3757f964
DA
1812 if (uj)
1813 vty_json(vty, json);
d62a17ae 1814}
1815
64c86530 1816static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
088f1098 1817 const char *neighbor, bool uj)
d62a17ae 1818{
d62a17ae 1819 struct listnode *neighnode;
1820 struct interface *ifp;
1821 struct pim_interface *pim_ifp;
1822 struct pim_neighbor *neigh;
1823 time_t now;
1824 int found_neighbor = 0;
1825 int option_address_list;
1826 int option_dr_priority;
1827 int option_generation_id;
1828 int option_holdtime;
1829 int option_lan_prune_delay;
1830 int option_t_bit;
1831 char uptime[10];
1832 char expire[10];
1833 char neigh_src_str[INET_ADDRSTRLEN];
1834
1835 json_object *json = NULL;
1836 json_object *json_ifp = NULL;
1837 json_object *json_row = NULL;
1838
1839 now = pim_time_monotonic_sec();
1840
1841 if (uj)
1842 json = json_object_new_object();
1843
451fda4f 1844 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 1845 pim_ifp = ifp->info;
1846
1847 if (!pim_ifp)
1848 continue;
1849
1850 if (pim_ifp->pim_sock_fd < 0)
1851 continue;
1852
1853 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
1854 neigh)) {
1855 pim_inet4_dump("<src?>", neigh->source_addr,
1856 neigh_src_str, sizeof(neigh_src_str));
1857
1858 /*
1859 * The user can specify either the interface name or the
1860 * PIM neighbor IP.
1861 * If this pim_ifp matches neither then skip.
1862 */
1863 if (strcmp(neighbor, "detail")
1864 && strcmp(neighbor, ifp->name)
1865 && strcmp(neighbor, neigh_src_str))
1866 continue;
1867
1868 found_neighbor = 1;
1869 pim_time_uptime(uptime, sizeof(uptime),
1870 now - neigh->creation);
1871 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1872 neigh->t_expire_timer);
1873
1874 option_address_list = 0;
1875 option_dr_priority = 0;
1876 option_generation_id = 0;
1877 option_holdtime = 0;
1878 option_lan_prune_delay = 0;
1879 option_t_bit = 0;
1880
1881 if (PIM_OPTION_IS_SET(neigh->hello_options,
1882 PIM_OPTION_MASK_ADDRESS_LIST))
1883 option_address_list = 1;
1884
1885 if (PIM_OPTION_IS_SET(neigh->hello_options,
1886 PIM_OPTION_MASK_DR_PRIORITY))
1887 option_dr_priority = 1;
1888
1889 if (PIM_OPTION_IS_SET(neigh->hello_options,
1890 PIM_OPTION_MASK_GENERATION_ID))
1891 option_generation_id = 1;
1892
1893 if (PIM_OPTION_IS_SET(neigh->hello_options,
1894 PIM_OPTION_MASK_HOLDTIME))
1895 option_holdtime = 1;
1896
1897 if (PIM_OPTION_IS_SET(neigh->hello_options,
1898 PIM_OPTION_MASK_LAN_PRUNE_DELAY))
1899 option_lan_prune_delay = 1;
1900
1901 if (PIM_OPTION_IS_SET(
1902 neigh->hello_options,
1903 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
1904 option_t_bit = 1;
1905
1906 if (uj) {
1907
1908 /* Does this ifp live in json? If not create
1909 * it. */
1910 json_object_object_get_ex(json, ifp->name,
1911 &json_ifp);
1912
1913 if (!json_ifp) {
1914 json_ifp = json_object_new_object();
1915 json_object_pim_ifp_add(json_ifp, ifp);
1916 json_object_object_add(json, ifp->name,
1917 json_ifp);
1918 }
1919
1920 json_row = json_object_new_object();
1921 json_object_string_add(json_row, "interface",
1922 ifp->name);
1923 json_object_string_add(json_row, "address",
1924 neigh_src_str);
1925 json_object_string_add(json_row, "upTime",
1926 uptime);
1927 json_object_string_add(json_row, "holdtime",
1928 expire);
1929 json_object_int_add(json_row, "drPriority",
1930 neigh->dr_priority);
1931 json_object_int_add(json_row, "generationId",
1932 neigh->generation_id);
1933
1934 if (option_address_list)
1935 json_object_boolean_true_add(
1936 json_row,
1937 "helloOptionAddressList");
1938
1939 if (option_dr_priority)
1940 json_object_boolean_true_add(
1941 json_row,
1942 "helloOptionDrPriority");
1943
1944 if (option_generation_id)
1945 json_object_boolean_true_add(
1946 json_row,
1947 "helloOptionGenerationId");
1948
1949 if (option_holdtime)
1950 json_object_boolean_true_add(
1951 json_row,
1952 "helloOptionHoldtime");
1953
1954 if (option_lan_prune_delay)
1955 json_object_boolean_true_add(
1956 json_row,
1957 "helloOptionLanPruneDelay");
1958
1959 if (option_t_bit)
1960 json_object_boolean_true_add(
1961 json_row, "helloOptionTBit");
1962
1963 json_object_object_add(json_ifp, neigh_src_str,
1964 json_row);
1965
1966 } else {
1967 vty_out(vty, "Interface : %s\n", ifp->name);
1968 vty_out(vty, "Neighbor : %s\n", neigh_src_str);
1969 vty_out(vty,
1970 " Uptime : %s\n",
1971 uptime);
1972 vty_out(vty,
1973 " Holdtime : %s\n",
1974 expire);
1975 vty_out(vty,
1976 " DR Priority : %d\n",
1977 neigh->dr_priority);
1978 vty_out(vty,
1979 " Generation ID : %08x\n",
1980 neigh->generation_id);
1981 vty_out(vty,
1982 " Override Interval (msec) : %d\n",
1983 neigh->override_interval_msec);
1984 vty_out(vty,
1985 " Propagation Delay (msec) : %d\n",
1986 neigh->propagation_delay_msec);
1987 vty_out(vty,
1988 " Hello Option - Address List : %s\n",
1989 option_address_list ? "yes" : "no");
1990 vty_out(vty,
1991 " Hello Option - DR Priority : %s\n",
1992 option_dr_priority ? "yes" : "no");
1993 vty_out(vty,
1994 " Hello Option - Generation ID : %s\n",
1995 option_generation_id ? "yes" : "no");
1996 vty_out(vty,
1997 " Hello Option - Holdtime : %s\n",
1998 option_holdtime ? "yes" : "no");
1999 vty_out(vty,
2000 " Hello Option - LAN Prune Delay : %s\n",
2001 option_lan_prune_delay ? "yes" : "no");
2002 vty_out(vty,
2003 " Hello Option - T-bit : %s\n",
2004 option_t_bit ? "yes" : "no");
1f3e6bf5
RZ
2005 bfd_sess_show(vty, json_ifp,
2006 neigh->bfd_session);
d62a17ae 2007 vty_out(vty, "\n");
2008 }
2009 }
2010 }
2011
3757f964
DA
2012 if (uj)
2013 vty_json(vty, json);
2014 else if (!found_neighbor)
2015 vty_out(vty, "%% No such interface or neighbor\n");
d62a17ae 2016}
2017
64c86530 2018static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
088f1098 2019 bool uj)
12e41d03 2020{
d62a17ae 2021 struct listnode *neighnode;
2022 struct interface *ifp;
2023 struct pim_interface *pim_ifp;
2024 struct pim_neighbor *neigh;
2025 time_t now;
2026 char uptime[10];
2027 char expire[10];
2028 char neigh_src_str[INET_ADDRSTRLEN];
2029 json_object *json = NULL;
2030 json_object *json_ifp_rows = NULL;
2031 json_object *json_row = NULL;
2032
2033 now = pim_time_monotonic_sec();
2034
2035 if (uj) {
2036 json = json_object_new_object();
2037 } else {
2038 vty_out(vty,
ff415346 2039 "Interface Neighbor Uptime Holdtime DR Pri\n");
d62a17ae 2040 }
2041
451fda4f 2042 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2043 pim_ifp = ifp->info;
2044
2045 if (!pim_ifp)
2046 continue;
2047
2048 if (pim_ifp->pim_sock_fd < 0)
2049 continue;
2050
2051 if (uj)
2052 json_ifp_rows = json_object_new_object();
2053
2054 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2055 neigh)) {
2056 pim_inet4_dump("<src?>", neigh->source_addr,
2057 neigh_src_str, sizeof(neigh_src_str));
2058 pim_time_uptime(uptime, sizeof(uptime),
2059 now - neigh->creation);
2060 pim_time_timer_to_hhmmss(expire, sizeof(expire),
2061 neigh->t_expire_timer);
2062
2063 if (uj) {
2064 json_row = json_object_new_object();
2065 json_object_string_add(json_row, "interface",
2066 ifp->name);
2067 json_object_string_add(json_row, "neighbor",
2068 neigh_src_str);
2069 json_object_string_add(json_row, "upTime",
2070 uptime);
2071 json_object_string_add(json_row, "holdTime",
2072 expire);
2073 json_object_int_add(json_row, "holdTimeMax",
2074 neigh->holdtime);
2075 json_object_int_add(json_row, "drPriority",
2076 neigh->dr_priority);
2077 json_object_object_add(json_ifp_rows,
2078 neigh_src_str, json_row);
2079
2080 } else {
ff415346 2081 vty_out(vty, "%-16s %15s %8s %8s %6d\n",
d62a17ae 2082 ifp->name, neigh_src_str, uptime,
2083 expire, neigh->dr_priority);
2084 }
2085 }
2086
2087 if (uj) {
2088 json_object_object_add(json, ifp->name, json_ifp_rows);
2089 json_ifp_rows = NULL;
2090 }
2091 }
2092
3757f964
DA
2093 if (uj)
2094 vty_json(vty, json);
12e41d03
DL
2095}
2096
45e26aa0 2097static void pim_show_channel_helper(struct pim_instance *pim, struct vty *vty,
521c5b9d 2098 struct pim_interface *pim_ifp,
45e26aa0
A
2099 struct pim_ifchannel *ch, json_object *json,
2100 bool uj)
12e41d03 2101{
1a8a3da8
DS
2102 struct pim_upstream *up = ch->upstream;
2103 json_object *json_group = NULL;
d62a17ae 2104 json_object *json_row = NULL;
2105
1a8a3da8 2106 if (uj) {
8e8be741
DL
2107 char grp_str[PIM_ADDRSTRLEN];
2108 char src_str[PIM_ADDRSTRLEN];
2109
2110 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
2111 snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
2112
1a8a3da8 2113 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 2114
1a8a3da8
DS
2115 if (!json_group) {
2116 json_group = json_object_new_object();
996c9314 2117 json_object_object_add(json, grp_str, json_group);
1a8a3da8 2118 }
d62a17ae 2119
1a8a3da8
DS
2120 json_row = json_object_new_object();
2121 json_object_pim_upstream_add(json_row, up);
2122 json_object_string_add(json_row, "interface",
2123 ch->interface->name);
2124 json_object_string_add(json_row, "source", src_str);
2125 json_object_string_add(json_row, "group", grp_str);
d62a17ae 2126
1a8a3da8 2127 if (pim_macro_ch_lost_assert(ch))
996c9314 2128 json_object_boolean_true_add(json_row, "lostAssert");
d62a17ae 2129
1a8a3da8
DS
2130 if (pim_macro_chisin_joins(ch))
2131 json_object_boolean_true_add(json_row, "joins");
d62a17ae 2132
1a8a3da8 2133 if (pim_macro_chisin_pim_include(ch))
996c9314 2134 json_object_boolean_true_add(json_row, "pimInclude");
d62a17ae 2135
1a8a3da8 2136 if (pim_upstream_evaluate_join_desired(pim, up))
996c9314
LB
2137 json_object_boolean_true_add(json_row,
2138 "evaluateJoinDesired");
d62a17ae 2139
1a8a3da8 2140 json_object_object_add(json_group, src_str, json_row);
d62a17ae 2141
1a8a3da8 2142 } else {
8e8be741
DL
2143 vty_out(vty, "%-16s %-15pPAs %-15pPAs %-10s %-5s %-10s %-11s %-6s\n",
2144 ch->interface->name, &up->sg.src, &up->sg.grp,
1a8a3da8
DS
2145 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2146 pim_macro_chisin_joins(ch) ? "yes" : "no",
2147 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
996c9314 2148 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
521c5b9d
MS
2149 ? "yes"
2150 : "no",
996c9314 2151 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
521c5b9d 2152 : "no");
1a8a3da8
DS
2153 }
2154}
d62a17ae 2155
5c9a72ef 2156static void pim_show_channel(struct pim_instance *pim, struct vty *vty,
521c5b9d 2157 bool uj)
1a8a3da8 2158{
1a8a3da8
DS
2159 struct pim_interface *pim_ifp;
2160 struct pim_ifchannel *ch;
2161 struct interface *ifp;
d62a17ae 2162
1a8a3da8 2163 json_object *json = NULL;
d62a17ae 2164
1a8a3da8
DS
2165 if (uj)
2166 json = json_object_new_object();
2167 else
2168 vty_out(vty,
ff415346 2169 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
1a8a3da8
DS
2170
2171 /* scan per-interface (S,G) state */
451fda4f 2172 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8
DS
2173 pim_ifp = ifp->info;
2174 if (!pim_ifp)
2175 continue;
2176
ad7b74c4 2177
a2addae8 2178 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8 2179 /* scan all interfaces */
5c9a72ef 2180 pim_show_channel_helper(pim, vty, pim_ifp, ch,
521c5b9d 2181 json, uj);
d62a17ae 2182 }
2183 }
2184
3757f964
DA
2185 if (uj)
2186 vty_json(vty, json);
12e41d03
DL
2187}
2188
64c86530 2189static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2190 time_t now)
12e41d03 2191{
d62a17ae 2192 char uptime_scan_oil[10];
2193 char uptime_mroute_add[10];
2194 char uptime_mroute_del[10];
12e41d03 2195
d62a17ae 2196 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
bfc92019 2197 pim->scan_oil_last);
d62a17ae 2198 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
c68ba0d7 2199 pim->mroute_add_last);
d62a17ae 2200 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
c68ba0d7 2201 pim->mroute_del_last);
12e41d03 2202
d62a17ae 2203 vty_out(vty,
2204 "Scan OIL - Last: %s Events: %lld\n"
2205 "MFC Add - Last: %s Events: %lld\n"
2206 "MFC Del - Last: %s Events: %lld\n",
bfc92019 2207 uptime_scan_oil, (long long)pim->scan_oil_events,
c68ba0d7
DS
2208 uptime_mroute_add, (long long)pim->mroute_add_events,
2209 uptime_mroute_del, (long long)pim->mroute_del_events);
12e41d03
DL
2210}
2211
c68ba0d7
DS
2212struct pnc_cache_walk_data {
2213 struct vty *vty;
2214 struct pim_instance *pim;
2215};
2216
e3b78da8 2217static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
12e41d03 2218{
e3b78da8 2219 struct pim_nexthop_cache *pnc = bucket->data;
c68ba0d7
DS
2220 struct pnc_cache_walk_data *cwd = arg;
2221 struct vty *vty = cwd->vty;
2222 struct pim_instance *pim = cwd->pim;
d62a17ae 2223 struct nexthop *nh_node = NULL;
2224 ifindex_t first_ifindex;
2225 struct interface *ifp = NULL;
ee2bbf7c 2226 char buf[PREFIX_STRLEN];
d62a17ae 2227
d62a17ae 2228 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
2229 first_ifindex = nh_node->ifindex;
d3cc1e45 2230 ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
d62a17ae 2231
ee2bbf7c
MS
2232 vty_out(vty, "%-15s ", inet_ntop(AF_INET,
2233 &pnc->rpf.rpf_addr.u.prefix4,
2234 buf, sizeof(buf)));
ff415346 2235 vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
ee2bbf7c 2236 vty_out(vty, "%pI4 ", &nh_node->gate.ipv4);
d62a17ae 2237 vty_out(vty, "\n");
2238 }
2239 return CMD_SUCCESS;
2240}
2241
64c86530 2242static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
d62a17ae 2243{
c68ba0d7 2244 struct pnc_cache_walk_data cwd;
d62a17ae 2245
c68ba0d7
DS
2246 cwd.vty = vty;
2247 cwd.pim = pim;
2248 vty_out(vty, "Number of registered addresses: %lu\n",
2249 pim->rpf_hash->count);
ff415346
DS
2250 vty_out(vty, "Address Interface Nexthop\n");
2251 vty_out(vty, "---------------------------------------------\n");
12e41d03 2252
c68ba0d7 2253 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
d62a17ae 2254}
2255
0d1a4e24 2256/* Display the bsm database details */
2257static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
2258{
0d1a4e24 2259 int count = 0;
2260 int fragment = 1;
d4a4525c 2261 struct bsm_frag *bsfrag;
0d1a4e24 2262 json_object *json = NULL;
2263 json_object *json_group = NULL;
2264 json_object *json_row = NULL;
2265
d4a4525c 2266 count = bsm_frags_count(pim->global_scope.bsm_frags);
0d1a4e24 2267
2268 if (uj) {
2269 json = json_object_new_object();
2270 json_object_int_add(json, "Number of the fragments", count);
2271 } else {
2272 vty_out(vty, "Scope Zone: Global\n");
2273 vty_out(vty, "Number of the fragments: %d\n", count);
2274 vty_out(vty, "\n");
2275 }
2276
d4a4525c 2277 frr_each (bsm_frags, pim->global_scope.bsm_frags, bsfrag) {
93a5bc80 2278 char grp_str[PREFIX_STRLEN];
0d1a4e24 2279 char rp_str[INET_ADDRSTRLEN];
2280 char bsr_str[INET_ADDRSTRLEN];
2281 struct bsmmsg_grpinfo *group;
2282 struct bsmmsg_rpinfo *rpaddr;
2283 struct prefix grp;
2284 struct bsm_hdr *hdr;
2285 uint32_t offset = 0;
2286 uint8_t *buf;
2287 uint32_t len = 0;
2288 uint32_t frag_rp_cnt = 0;
2289
d4a4525c
DL
2290 buf = bsfrag->data;
2291 len = bsfrag->size;
0d1a4e24 2292
2293 /* skip pim header */
2294 buf += PIM_MSG_HEADER_LEN;
2295 len -= PIM_MSG_HEADER_LEN;
2296
2297 hdr = (struct bsm_hdr *)buf;
2298
2299 /* BSM starts with bsr header */
2300 buf += sizeof(struct bsm_hdr);
2301 len -= sizeof(struct bsm_hdr);
2302
2303 pim_inet4_dump("<BSR Address?>", hdr->bsr_addr.addr, bsr_str,
2304 sizeof(bsr_str));
2305
2306
2307 if (uj) {
2308 json_object_string_add(json, "BSR address", bsr_str);
2309 json_object_int_add(json, "BSR priority",
2310 hdr->bsr_prio);
2311 json_object_int_add(json, "Hashmask Length",
2312 hdr->hm_len);
2313 json_object_int_add(json, "Fragment Tag",
2314 ntohs(hdr->frag_tag));
2315 } else {
2316 vty_out(vty, "BSM Fragment : %d\n", fragment);
2317 vty_out(vty, "------------------\n");
2318 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
2319 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
2320 vty_out(vty, "%-15s %-15d %-15d %-15d\n", bsr_str,
2321 hdr->bsr_prio, hdr->hm_len,
2322 ntohs(hdr->frag_tag));
2323 }
2324
2325 vty_out(vty, "\n");
2326
2327 while (offset < len) {
2328 group = (struct bsmmsg_grpinfo *)buf;
2329
2330 if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
2331 grp.family = AF_INET;
2332
2333 grp.prefixlen = group->group.mask;
2334 grp.u.prefix4.s_addr = group->group.addr.s_addr;
2335
2336 prefix2str(&grp, grp_str, sizeof(grp_str));
2337
2338 buf += sizeof(struct bsmmsg_grpinfo);
2339 offset += sizeof(struct bsmmsg_grpinfo);
2340
2341 if (uj) {
2342 json_object_object_get_ex(json, grp_str,
2343 &json_group);
2344 if (!json_group) {
2345 json_group = json_object_new_object();
2346 json_object_int_add(json_group,
2347 "Rp Count",
2348 group->rp_count);
2349 json_object_int_add(
2350 json_group, "Fragment Rp count",
2351 group->frag_rp_count);
2352 json_object_object_add(json, grp_str,
2353 json_group);
2354 }
2355 } else {
2356 vty_out(vty, "Group : %s\n", grp_str);
2357 vty_out(vty, "-------------------\n");
2358 vty_out(vty, "Rp Count:%d\n", group->rp_count);
2359 vty_out(vty, "Fragment Rp Count : %d\n",
2360 group->frag_rp_count);
2361 }
2362
2363 frag_rp_cnt = group->frag_rp_count;
2364
2365 if (!frag_rp_cnt)
2366 continue;
2367
2368 if (!uj)
2369 vty_out(vty,
2370 "RpAddress HoldTime Priority\n");
2371
2372 while (frag_rp_cnt--) {
2373 rpaddr = (struct bsmmsg_rpinfo *)buf;
2374
2375 buf += sizeof(struct bsmmsg_rpinfo);
2376 offset += sizeof(struct bsmmsg_rpinfo);
2377
2378 pim_inet4_dump("<Rp addr?>",
2379 rpaddr->rpaddr.addr, rp_str,
2380 sizeof(rp_str));
2381
2382 if (uj) {
2383 json_row = json_object_new_object();
2384 json_object_string_add(
2385 json_row, "Rp Address", rp_str);
2386 json_object_int_add(
2387 json_row, "Rp HoldTime",
2388 ntohs(rpaddr->rp_holdtime));
2389 json_object_int_add(json_row,
2390 "Rp Priority",
2391 rpaddr->rp_pri);
2392 json_object_object_add(
2393 json_group, rp_str, json_row);
2394 } else {
2395 vty_out(vty, "%-15s %-12d %d\n", rp_str,
2396 ntohs(rpaddr->rp_holdtime),
2397 rpaddr->rp_pri);
2398 }
2399 }
2400 vty_out(vty, "\n");
2401 }
2402
2403 fragment++;
2404 }
2405
3757f964
DA
2406 if (uj)
2407 vty_json(vty, json);
0d1a4e24 2408}
2409
321295c1 2410/*Display the group-rp mappings */
2411static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
2412 struct vty *vty, bool uj)
2413{
2414 struct bsgrp_node *bsgrp;
321295c1 2415 struct bsm_rpinfo *bsm_rp;
2416 struct route_node *rn;
2417 char bsr_str[INET_ADDRSTRLEN];
2418 json_object *json = NULL;
2419 json_object *json_group = NULL;
2420 json_object *json_row = NULL;
2421
2422 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY)
fbd74c7d 2423 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
321295c1 2424
2425 else
2426 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str,
2427 sizeof(bsr_str));
2428
2429 if (uj) {
2430 json = json_object_new_object();
2431 json_object_string_add(json, "BSR Address", bsr_str);
2432 } else {
2433 vty_out(vty, "BSR Address %s\n", bsr_str);
2434 }
2435
2436 for (rn = route_top(pim->global_scope.bsrp_table); rn;
2437 rn = route_next(rn)) {
2438 bsgrp = (struct bsgrp_node *)rn->info;
2439
2440 if (!bsgrp)
2441 continue;
2442
93a5bc80 2443 char grp_str[PREFIX_STRLEN];
321295c1 2444
2445 prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
2446
2447 if (uj) {
2448 json_object_object_get_ex(json, grp_str, &json_group);
2449 if (!json_group) {
2450 json_group = json_object_new_object();
2451 json_object_object_add(json, grp_str,
2452 json_group);
2453 }
2454 } else {
2dbe669b 2455 vty_out(vty, "Group Address %pFX\n", &bsgrp->group);
321295c1 2456 vty_out(vty, "--------------------------\n");
2457 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
2458 "priority", "Holdtime", "Hash");
2459
2460 vty_out(vty, "(ACTIVE)\n");
2461 }
2462
fdab2940
DL
2463 frr_each (bsm_rpinfos, bsgrp->bsrp_list, bsm_rp) {
2464 char rp_str[INET_ADDRSTRLEN];
321295c1 2465
fdab2940
DL
2466 pim_inet4_dump("<Rp Address?>", bsm_rp->rp_address,
2467 rp_str, sizeof(rp_str));
321295c1 2468
fdab2940
DL
2469 if (uj) {
2470 json_row = json_object_new_object();
2471 json_object_string_add(json_row, "Rp Address",
2472 rp_str);
2473 json_object_int_add(json_row, "Rp HoldTime",
2474 bsm_rp->rp_holdtime);
2475 json_object_int_add(json_row, "Rp Priority",
2476 bsm_rp->rp_prio);
2477 json_object_int_add(json_row, "Hash Val",
2478 bsm_rp->hash);
2479 json_object_object_add(json_group, rp_str,
2480 json_row);
321295c1 2481
fdab2940
DL
2482 } else {
2483 vty_out(vty, "%-15s %-15u %-15u %-15u\n",
2484 rp_str, bsm_rp->rp_prio,
2485 bsm_rp->rp_holdtime, bsm_rp->hash);
321295c1 2486 }
321295c1 2487 }
fdab2940
DL
2488 if (!bsm_rpinfos_count(bsgrp->bsrp_list) && !uj)
2489 vty_out(vty, "Active List is empty.\n");
321295c1 2490
2491 if (uj) {
2492 json_object_int_add(json_group, "Pending RP count",
2493 bsgrp->pend_rp_cnt);
2494 } else {
2495 vty_out(vty, "(PENDING)\n");
2496 vty_out(vty, "Pending RP count :%d\n",
2497 bsgrp->pend_rp_cnt);
2498 if (bsgrp->pend_rp_cnt)
2499 vty_out(vty, "%-15s %-15s %-15s %-15s\n",
2500 "Rp Address", "priority", "Holdtime",
2501 "Hash");
2502 }
2503
fdab2940
DL
2504 frr_each (bsm_rpinfos, bsgrp->partial_bsrp_list, bsm_rp) {
2505 char rp_str[INET_ADDRSTRLEN];
321295c1 2506
fdab2940
DL
2507 pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address, rp_str,
2508 sizeof(rp_str));
321295c1 2509
fdab2940
DL
2510 if (uj) {
2511 json_row = json_object_new_object();
2512 json_object_string_add(json_row, "Rp Address",
2513 rp_str);
2514 json_object_int_add(json_row, "Rp HoldTime",
2515 bsm_rp->rp_holdtime);
2516 json_object_int_add(json_row, "Rp Priority",
2517 bsm_rp->rp_prio);
2518 json_object_int_add(json_row, "Hash Val",
2519 bsm_rp->hash);
2520 json_object_object_add(json_group, rp_str,
2521 json_row);
2522 } else {
2523 vty_out(vty, "%-15s %-15u %-15u %-15u\n",
2524 rp_str, bsm_rp->rp_prio,
2525 bsm_rp->rp_holdtime, bsm_rp->hash);
321295c1 2526 }
321295c1 2527 }
fdab2940
DL
2528 if (!bsm_rpinfos_count(bsgrp->partial_bsrp_list) && !uj)
2529 vty_out(vty, "Partial List is empty\n");
321295c1 2530
2531 if (!uj)
2532 vty_out(vty, "\n");
2533 }
2534
3757f964
DA
2535 if (uj)
2536 vty_json(vty, json);
321295c1 2537}
2538
415f6350 2539static void clear_pim_statistics(struct pim_instance *pim)
2540{
2541 struct interface *ifp;
2542
2543 pim->bsm_rcvd = 0;
2544 pim->bsm_sent = 0;
2545 pim->bsm_dropped = 0;
2546
2547 /* scan interfaces */
2548 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2549 struct pim_interface *pim_ifp = ifp->info;
2550
2551 if (!pim_ifp)
2552 continue;
2553
2554 pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
2555 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
2556 pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
2557 }
2558}
2559
088f1098 2560static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 2561{
d62a17ae 2562 struct interface *ifp;
2563 time_t now;
2564 json_object *json = NULL;
2565 json_object *json_iface = NULL;
4d360968 2566 json_object *json_group = NULL;
2567 json_object *json_groups = NULL;
d62a17ae 2568
2569 now = pim_time_monotonic_sec();
2570
339f7695 2571 if (uj) {
d62a17ae 2572 json = json_object_new_object();
339f7695 2573 json_object_int_add(json, "totalGroups", pim->igmp_group_count);
2574 json_object_int_add(json, "watermarkLimit",
2575 pim->igmp_watermark_limit);
2576 } else {
2577 vty_out(vty, "Total IGMP groups: %u\n", pim->igmp_group_count);
2578 vty_out(vty, "Watermark warn limit(%s): %u\n",
2579 pim->igmp_watermark_limit ? "Set" : "Not Set",
2580 pim->igmp_watermark_limit);
d62a17ae 2581 vty_out(vty,
dda4d23c 2582 "Interface Group Mode Timer Srcs V Uptime \n");
339f7695 2583 }
d62a17ae 2584
2585 /* scan interfaces */
451fda4f 2586 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2587 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 2588 struct listnode *grpnode;
a16db099 2589 struct gm_group *grp;
d62a17ae 2590
2591 if (!pim_ifp)
2592 continue;
2593
dda4d23c 2594 /* scan igmp groups */
18adcff1 2595 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 2596 grp)) {
dda4d23c
DL
2597 char group_str[INET_ADDRSTRLEN];
2598 char hhmmss[10];
2599 char uptime[10];
d62a17ae 2600
a1a4295a
DL
2601 pim_inet4_dump("<group?>", grp->group_addr, group_str,
2602 sizeof(group_str));
dda4d23c
DL
2603 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
2604 grp->t_group_timer);
2605 pim_time_uptime(uptime, sizeof(uptime),
2606 now - grp->group_creation);
d62a17ae 2607
dda4d23c 2608 if (uj) {
a1a4295a
DL
2609 json_object_object_get_ex(json, ifp->name,
2610 &json_iface);
d62a17ae 2611
dda4d23c 2612 if (!json_iface) {
a1a4295a
DL
2613 json_iface = json_object_new_object();
2614 json_object_pim_ifp_add(json_iface,
2615 ifp);
2616 json_object_object_add(json, ifp->name,
2617 json_iface);
2618 json_groups = json_object_new_array();
2619 json_object_object_add(json_iface,
2620 "groups",
2621 json_groups);
d62a17ae 2622 }
dda4d23c
DL
2623
2624 json_group = json_object_new_object();
a1a4295a 2625 json_object_string_add(json_group, "group",
dda4d23c
DL
2626 group_str);
2627
2628 if (grp->igmp_version == 3)
2629 json_object_string_add(
2630 json_group, "mode",
2631 grp->group_filtermode_isexcl
a1a4295a
DL
2632 ? "EXCLUDE"
2633 : "INCLUDE");
dda4d23c 2634
a1a4295a
DL
2635 json_object_string_add(json_group, "timer",
2636 hhmmss);
dda4d23c
DL
2637 json_object_int_add(
2638 json_group, "sourcesCount",
a1a4295a 2639 grp->group_source_list ? listcount(
dda4d23c 2640 grp->group_source_list)
a1a4295a
DL
2641 : 0);
2642 json_object_int_add(json_group, "version",
2643 grp->igmp_version);
2644 json_object_string_add(json_group, "uptime",
2645 uptime);
2646 json_object_array_add(json_groups, json_group);
dda4d23c 2647 } else {
a1a4295a 2648 vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n",
dda4d23c
DL
2649 ifp->name, group_str,
2650 grp->igmp_version == 3
a1a4295a
DL
2651 ? (grp->group_filtermode_isexcl
2652 ? "EXCL"
2653 : "INCL")
2654 : "----",
dda4d23c 2655 hhmmss,
a1a4295a 2656 grp->group_source_list ? listcount(
dda4d23c 2657 grp->group_source_list)
a1a4295a 2658 : 0,
dda4d23c
DL
2659 grp->igmp_version, uptime);
2660 }
2661 } /* scan igmp groups */
2662 } /* scan interfaces */
d62a17ae 2663
3757f964
DA
2664 if (uj)
2665 vty_json(vty, json);
12e41d03
DL
2666}
2667
64c86530
DS
2668static void igmp_show_group_retransmission(struct pim_instance *pim,
2669 struct vty *vty)
12e41d03 2670{
d62a17ae 2671 struct interface *ifp;
2672
2673 vty_out(vty,
dda4d23c 2674 "Interface Group RetTimer Counter RetSrcs\n");
d62a17ae 2675
2676 /* scan interfaces */
451fda4f 2677 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2678 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 2679 struct listnode *grpnode;
a16db099 2680 struct gm_group *grp;
d62a17ae 2681
2682 if (!pim_ifp)
2683 continue;
2684
dda4d23c 2685 /* scan igmp groups */
18adcff1 2686 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 2687 grp)) {
dda4d23c
DL
2688 char group_str[INET_ADDRSTRLEN];
2689 char grp_retr_mmss[10];
2690 struct listnode *src_node;
51700107 2691 struct gm_source *src;
dda4d23c 2692 int grp_retr_sources = 0;
d62a17ae 2693
a1a4295a
DL
2694 pim_inet4_dump("<group?>", grp->group_addr, group_str,
2695 sizeof(group_str));
dda4d23c
DL
2696 pim_time_timer_to_mmss(
2697 grp_retr_mmss, sizeof(grp_retr_mmss),
2698 grp->t_group_query_retransmit_timer);
d62a17ae 2699
dda4d23c
DL
2700
2701 /* count group sources with retransmission state
2702 */
a1a4295a
DL
2703 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
2704 src_node, src)) {
2705 if (src->source_query_retransmit_count > 0) {
dda4d23c 2706 ++grp_retr_sources;
d62a17ae 2707 }
dda4d23c 2708 }
d62a17ae 2709
a1a4295a
DL
2710 vty_out(vty, "%-16s %-15s %-8s %7d %7d\n", ifp->name,
2711 group_str, grp_retr_mmss,
dda4d23c
DL
2712 grp->group_specific_query_retransmit_count,
2713 grp_retr_sources);
d62a17ae 2714
dda4d23c
DL
2715 } /* scan igmp groups */
2716 } /* scan interfaces */
12e41d03
DL
2717}
2718
4527b70a
SG
2719static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
2720 bool uj)
12e41d03 2721{
d62a17ae 2722 struct interface *ifp;
2723 time_t now;
4527b70a
SG
2724 json_object *json = NULL;
2725 json_object *json_iface = NULL;
2726 json_object *json_group = NULL;
2727 json_object *json_source = NULL;
2728 json_object *json_sources = NULL;
d62a17ae 2729
2730 now = pim_time_monotonic_sec();
2731
4527b70a
SG
2732 if (uj)
2733 json = json_object_new_object();
2734 else
2735 vty_out(vty,
2736 "Interface Address Group Source Timer Fwd Uptime \n");
d62a17ae 2737
2738 /* scan interfaces */
451fda4f 2739 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2740 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 2741 struct listnode *grpnode;
a16db099 2742 struct gm_group *grp;
d62a17ae 2743
2744 if (!pim_ifp)
2745 continue;
2746
dda4d23c 2747 /* scan igmp groups */
18adcff1 2748 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 2749 grp)) {
dda4d23c
DL
2750 char group_str[INET_ADDRSTRLEN];
2751 struct listnode *srcnode;
51700107 2752 struct gm_source *src;
dda4d23c 2753
a1a4295a
DL
2754 pim_inet4_dump("<group?>", grp->group_addr, group_str,
2755 sizeof(group_str));
dda4d23c
DL
2756
2757 /* scan group sources */
a1a4295a
DL
2758 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
2759 srcnode, src)) {
dda4d23c
DL
2760 char source_str[INET_ADDRSTRLEN];
2761 char mmss[10];
2762 char uptime[10];
d62a17ae 2763
a1a4295a
DL
2764 pim_inet4_dump("<source?>", src->source_addr,
2765 source_str, sizeof(source_str));
d62a17ae 2766
a1a4295a
DL
2767 pim_time_timer_to_mmss(mmss, sizeof(mmss),
2768 src->t_source_timer);
d62a17ae 2769
a1a4295a
DL
2770 pim_time_uptime(uptime, sizeof(uptime),
2771 now - src->source_creation);
d62a17ae 2772
4527b70a
SG
2773 if (uj) {
2774 json_object_object_get_ex(
2775 json, ifp->name, &json_iface);
2776 if (!json_iface) {
2777 json_iface =
2778 json_object_new_object();
2779 json_object_string_add(
2780 json_iface, "name",
2781 ifp->name);
2782 json_object_object_add(
2783 json, ifp->name,
2784 json_iface);
2785 }
2786 json_object_object_get_ex(json_iface,
2787 group_str,
2788 &json_group);
2789
2790 if (!json_group) {
2791 json_group =
2792 json_object_new_object();
2793 json_object_string_add(
2794 json_group, "group",
2795 group_str);
2796 json_object_object_add(
2797 json_iface, group_str,
2798 json_group);
2799 json_sources =
2800 json_object_new_array();
2801 json_object_object_add(
2802 json_group, "sources",
2803 json_sources);
2804 }
2805 json_source = json_object_new_object();
2806 json_object_string_add(json_source,
2807 "source",
2808 source_str);
2809 json_object_string_add(json_source,
2810 "timer", mmss);
2811 json_object_boolean_add(
2812 json_source, "forwarded",
2813 IGMP_SOURCE_TEST_FORWARDING(
2814 src->source_flags));
2815 json_object_string_add(
2816 json_source, "uptime", uptime);
2817 json_object_array_add(json_sources,
2818 json_source);
2819
2820 } else {
2821 vty_out(vty,
2822 "%-16s %-15s %-15s %5s %3s %8s\n",
2823 ifp->name, group_str,
2824 source_str, mmss,
2825 IGMP_SOURCE_TEST_FORWARDING(
2826 src->source_flags)
2827 ? "Y"
2828 : "N",
2829 uptime);
2830 }
d62a17ae 2831
dda4d23c 2832 } /* scan group sources */
18adcff1 2833 } /* scan igmp groups */
dda4d23c 2834 } /* scan interfaces */
4527b70a
SG
2835 if (uj)
2836 vty_json(vty, json);
12e41d03
DL
2837}
2838
64c86530
DS
2839static void igmp_show_source_retransmission(struct pim_instance *pim,
2840 struct vty *vty)
12e41d03 2841{
d62a17ae 2842 struct interface *ifp;
2843
2844 vty_out(vty,
dda4d23c 2845 "Interface Group Source Counter\n");
d62a17ae 2846
2847 /* scan interfaces */
451fda4f 2848 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2849 struct pim_interface *pim_ifp = ifp->info;
dda4d23c 2850 struct listnode *grpnode;
a16db099 2851 struct gm_group *grp;
d62a17ae 2852
2853 if (!pim_ifp)
2854 continue;
2855
dda4d23c 2856 /* scan igmp groups */
18adcff1 2857 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
29e58225 2858 grp)) {
dda4d23c
DL
2859 char group_str[INET_ADDRSTRLEN];
2860 struct listnode *srcnode;
51700107 2861 struct gm_source *src;
d62a17ae 2862
a1a4295a
DL
2863 pim_inet4_dump("<group?>", grp->group_addr, group_str,
2864 sizeof(group_str));
d62a17ae 2865
dda4d23c 2866 /* scan group sources */
a1a4295a
DL
2867 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
2868 srcnode, src)) {
dda4d23c 2869 char source_str[INET_ADDRSTRLEN];
d62a17ae 2870
a1a4295a
DL
2871 pim_inet4_dump("<source?>", src->source_addr,
2872 source_str, sizeof(source_str));
d62a17ae 2873
a1a4295a 2874 vty_out(vty, "%-16s %-15s %-15s %7d\n",
dda4d23c
DL
2875 ifp->name, group_str, source_str,
2876 src->source_query_retransmit_count);
d62a17ae 2877
dda4d23c 2878 } /* scan group sources */
18adcff1 2879 } /* scan igmp groups */
dda4d23c 2880 } /* scan interfaces */
12e41d03
DL
2881}
2882
256392eb 2883static void pim_show_bsr(struct pim_instance *pim,
2884 struct vty *vty,
2885 bool uj)
2886{
2887 char uptime[10];
2888 char last_bsm_seen[10];
2889 time_t now;
2890 char bsr_state[20];
2891 char bsr_str[PREFIX_STRLEN];
2892 json_object *json = NULL;
2893
256392eb 2894 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) {
fbd74c7d 2895 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
256392eb 2896 pim_time_uptime(uptime, sizeof(uptime),
2897 pim->global_scope.current_bsr_first_ts);
2898 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
2899 pim->global_scope.current_bsr_last_ts);
2900 }
2901
2902 else {
2903 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr,
2904 bsr_str, sizeof(bsr_str));
2905 now = pim_time_monotonic_sec();
2906 pim_time_uptime(uptime, sizeof(uptime),
2907 (now - pim->global_scope.current_bsr_first_ts));
2908 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
2909 now - pim->global_scope.current_bsr_last_ts);
2910 }
2911
2912 switch (pim->global_scope.state) {
2913 case NO_INFO:
fbd74c7d 2914 strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
256392eb 2915 break;
2916 case ACCEPT_ANY:
fbd74c7d 2917 strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
256392eb 2918 break;
2919 case ACCEPT_PREFERRED:
fbd74c7d 2920 strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
256392eb 2921 break;
2922 default:
fbd74c7d 2923 strlcpy(bsr_state, "", sizeof(bsr_state));
256392eb 2924 }
2925
2926 if (uj) {
2927 json = json_object_new_object();
2928 json_object_string_add(json, "bsr", bsr_str);
2929 json_object_int_add(json, "priority",
2930 pim->global_scope.current_bsr_prio);
a5f610e4 2931 json_object_int_add(json, "fragmentTag",
256392eb 2932 pim->global_scope.bsm_frag_tag);
2933 json_object_string_add(json, "state", bsr_state);
2934 json_object_string_add(json, "upTime", uptime);
a5f610e4 2935 json_object_string_add(json, "lastBsmSeen", last_bsm_seen);
256392eb 2936 }
2937
2938 else {
36afe486 2939 vty_out(vty, "PIMv2 Bootstrap information\n");
256392eb 2940 vty_out(vty, "Current preferred BSR address: %s\n", bsr_str);
2941 vty_out(vty,
2942 "Priority Fragment-Tag State UpTime\n");
2943 vty_out(vty, " %-12d %-12d %-13s %7s\n",
2944 pim->global_scope.current_bsr_prio,
2945 pim->global_scope.bsm_frag_tag,
2946 bsr_state,
2947 uptime);
2948 vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
2949 }
2950
3757f964
DA
2951 if (uj)
2952 vty_json(vty, json);
256392eb 2953}
2954
c68ba0d7 2955static void clear_igmp_interfaces(struct pim_instance *pim)
12e41d03 2956{
d62a17ae 2957 struct interface *ifp;
12e41d03 2958
451fda4f 2959 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 2960 pim_if_addr_del_all_igmp(ifp);
12e41d03 2961
451fda4f 2962 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 2963 pim_if_addr_add_all(ifp);
12e41d03
DL
2964}
2965
c68ba0d7 2966static void clear_pim_interfaces(struct pim_instance *pim)
12e41d03 2967{
d62a17ae 2968 struct interface *ifp;
12e41d03 2969
451fda4f 2970 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 2971 if (ifp->info) {
2972 pim_neighbor_delete_all(ifp, "interface cleared");
2973 }
2974 }
12e41d03
DL
2975}
2976
c68ba0d7 2977static void clear_interfaces(struct pim_instance *pim)
12e41d03 2978{
c68ba0d7
DS
2979 clear_igmp_interfaces(pim);
2980 clear_pim_interfaces(pim);
12e41d03
DL
2981}
2982
521c5b9d
MS
2983#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
2984 pim_ifp = ifp->info; \
2985 if (!pim_ifp) { \
2986 vty_out(vty, \
21b3e44e 2987 "%% Enable PIM and/or IGMP on this interface first\n"); \
521c5b9d 2988 return CMD_WARNING_CONFIG_FAILED; \
21b3e44e
QY
2989 }
2990
e2809e61
RZ
2991/**
2992 * Compatibility function to keep the legacy mesh group CLI behavior:
2993 * Delete group when there are no more configurations in it.
2994 *
2995 * NOTE:
2996 * Don't forget to call `nb_cli_apply_changes` after this.
2997 */
2998static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
2999 const char *gname)
3000{
3001 const char *vrfname;
3002 char xpath_value[XPATH_MAXLEN];
3003 char xpath_member_value[XPATH_MAXLEN];
3004 const struct lyd_node *member_dnode;
3005
3006 vrfname = pim_cli_get_vrf_name(vty);
3007 if (vrfname == NULL)
3008 return;
3009
3010 /* Get mesh group base XPath. */
3011 snprintf(xpath_value, sizeof(xpath_value),
698f4147 3012 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
3013 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
3014 /* Group must exists, otherwise just quit. */
3015 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
3016 return;
3017
3018 /* Group members check: */
3019 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
3020 strlcat(xpath_member_value, "/members", sizeof(xpath_member_value));
3021 if (yang_dnode_exists(vty->candidate_config->dnode,
3022 xpath_member_value)) {
3023 member_dnode = yang_dnode_get(vty->candidate_config->dnode,
3024 xpath_member_value);
46877489 3025 if (!member_dnode || !yang_is_last_list_dnode(member_dnode))
e2809e61
RZ
3026 return;
3027 }
3028
3029 /* Source address check: */
3030 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
3031 strlcat(xpath_member_value, "/source", sizeof(xpath_member_value));
3032 if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value))
3033 return;
3034
3035 /* No configurations found: delete it. */
3036 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
3037}
3038
12e41d03
DL
3039DEFUN (clear_ip_interfaces,
3040 clear_ip_interfaces_cmd,
20a7e5fd 3041 "clear ip interfaces [vrf NAME]",
12e41d03
DL
3042 CLEAR_STR
3043 IP_STR
c68ba0d7
DS
3044 "Reset interfaces\n"
3045 VRF_CMD_HELP_STR)
12e41d03 3046{
c68ba0d7
DS
3047 int idx = 2;
3048 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3049
3050 if (!vrf)
3051 return CMD_WARNING;
3052
3053 clear_interfaces(vrf->info);
12e41d03 3054
d62a17ae 3055 return CMD_SUCCESS;
12e41d03
DL
3056}
3057
3058DEFUN (clear_ip_igmp_interfaces,
3059 clear_ip_igmp_interfaces_cmd,
20a7e5fd 3060 "clear ip igmp [vrf NAME] interfaces",
12e41d03
DL
3061 CLEAR_STR
3062 IP_STR
3063 CLEAR_IP_IGMP_STR
c68ba0d7 3064 VRF_CMD_HELP_STR
12e41d03
DL
3065 "Reset IGMP interfaces\n")
3066{
c68ba0d7
DS
3067 int idx = 2;
3068 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3069
3070 if (!vrf)
3071 return CMD_WARNING;
3072
3073 clear_igmp_interfaces(vrf->info);
12e41d03 3074
d62a17ae 3075 return CMD_SUCCESS;
12e41d03
DL
3076}
3077
415f6350 3078DEFUN (clear_ip_pim_statistics,
3079 clear_ip_pim_statistics_cmd,
3080 "clear ip pim statistics [vrf NAME]",
3081 CLEAR_STR
3082 IP_STR
3083 CLEAR_IP_PIM_STR
3084 VRF_CMD_HELP_STR
3085 "Reset PIM statistics\n")
3086{
3087 int idx = 2;
3088 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3089
3090 if (!vrf)
3091 return CMD_WARNING;
3092
3093 clear_pim_statistics(vrf->info);
3094 return CMD_SUCCESS;
3095}
3096
4a5e6e74 3097static void clear_mroute(struct pim_instance *pim)
3098{
3099 struct pim_upstream *up;
3100 struct interface *ifp;
3101
3102 /* scan interfaces */
3103 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3104 struct pim_interface *pim_ifp = ifp->info;
4a5e6e74 3105 struct pim_ifchannel *ch;
3106
3107 if (!pim_ifp)
3108 continue;
3109
3110 /* deleting all ifchannels */
3111 while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
3112 ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
3113
3114 pim_ifchannel_delete(ch);
3115 }
3116
5a46a3de 3117#if PIM_IPV == 4
4a5e6e74 3118 /* clean up all igmp groups */
5a46a3de 3119 struct gm_group *grp;
4a5e6e74 3120
18adcff1
SG
3121 if (pim_ifp->gm_group_list) {
3122 while (pim_ifp->gm_group_list->count) {
3123 grp = listnode_head(pim_ifp->gm_group_list);
dda4d23c 3124 igmp_group_delete(grp);
4a5e6e74 3125 }
4a5e6e74 3126 }
5a46a3de 3127#endif
4a5e6e74 3128 }
3129
3130 /* clean up all upstreams*/
521c5b9d 3131 while ((up = rb_pim_upstream_first(&pim->upstream_head)))
5e81f5dd 3132 pim_upstream_del(pim, up, __func__);
521c5b9d 3133
4a5e6e74 3134}
3135
12e41d03
DL
3136DEFUN (clear_ip_mroute,
3137 clear_ip_mroute_cmd,
20a7e5fd 3138 "clear ip mroute [vrf NAME]",
12e41d03
DL
3139 CLEAR_STR
3140 IP_STR
c68ba0d7
DS
3141 "Reset multicast routes\n"
3142 VRF_CMD_HELP_STR)
12e41d03 3143{
c68ba0d7
DS
3144 int idx = 2;
3145 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3146
3147 if (!vrf)
3148 return CMD_WARNING;
3149
4a5e6e74 3150 clear_mroute(vrf->info);
12e41d03 3151
d62a17ae 3152 return CMD_SUCCESS;
12e41d03
DL
3153}
3154
3155DEFUN (clear_ip_pim_interfaces,
3156 clear_ip_pim_interfaces_cmd,
20a7e5fd 3157 "clear ip pim [vrf NAME] interfaces",
12e41d03
DL
3158 CLEAR_STR
3159 IP_STR
3160 CLEAR_IP_PIM_STR
c68ba0d7 3161 VRF_CMD_HELP_STR
12e41d03
DL
3162 "Reset PIM interfaces\n")
3163{
c68ba0d7
DS
3164 int idx = 2;
3165 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3166
3167 if (!vrf)
3168 return CMD_WARNING;
3169
3170 clear_pim_interfaces(vrf->info);
12e41d03 3171
d62a17ae 3172 return CMD_SUCCESS;
12e41d03
DL
3173}
3174
39438188
CS
3175DEFUN (clear_ip_pim_interface_traffic,
3176 clear_ip_pim_interface_traffic_cmd,
20a7e5fd 3177 "clear ip pim [vrf NAME] interface traffic",
39438188
CS
3178 "Reset functions\n"
3179 "IP information\n"
3180 "PIM clear commands\n"
c68ba0d7 3181 VRF_CMD_HELP_STR
39438188
CS
3182 "Reset PIM interfaces\n"
3183 "Reset Protocol Packet counters\n")
3184{
c68ba0d7
DS
3185 int idx = 2;
3186 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3187 struct interface *ifp = NULL;
3188 struct pim_interface *pim_ifp = NULL;
3189
c68ba0d7
DS
3190 if (!vrf)
3191 return CMD_WARNING;
3192
451fda4f 3193 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 3194 pim_ifp = ifp->info;
3195
3196 if (!pim_ifp)
3197 continue;
3198
3199 pim_ifp->pim_ifstat_hello_recv = 0;
3200 pim_ifp->pim_ifstat_hello_sent = 0;
3201 pim_ifp->pim_ifstat_join_recv = 0;
3202 pim_ifp->pim_ifstat_join_send = 0;
3203 pim_ifp->pim_ifstat_prune_recv = 0;
3204 pim_ifp->pim_ifstat_prune_send = 0;
3205 pim_ifp->pim_ifstat_reg_recv = 0;
3206 pim_ifp->pim_ifstat_reg_send = 0;
3207 pim_ifp->pim_ifstat_reg_stop_recv = 0;
3208 pim_ifp->pim_ifstat_reg_stop_send = 0;
3209 pim_ifp->pim_ifstat_assert_recv = 0;
3210 pim_ifp->pim_ifstat_assert_send = 0;
5164ad1e 3211 pim_ifp->pim_ifstat_bsm_rx = 0;
3212 pim_ifp->pim_ifstat_bsm_tx = 0;
f2058cb4
DA
3213 pim_ifp->igmp_ifstat_joins_sent = 0;
3214 pim_ifp->igmp_ifstat_joins_failed = 0;
3e5d8665 3215 pim_ifp->igmp_peak_group_count = 0;
d62a17ae 3216 }
39438188 3217
d62a17ae 3218 return CMD_SUCCESS;
39438188
CS
3219}
3220
12e41d03
DL
3221DEFUN (clear_ip_pim_oil,
3222 clear_ip_pim_oil_cmd,
20a7e5fd 3223 "clear ip pim [vrf NAME] oil",
12e41d03
DL
3224 CLEAR_STR
3225 IP_STR
3226 CLEAR_IP_PIM_STR
c68ba0d7 3227 VRF_CMD_HELP_STR
12e41d03
DL
3228 "Rescan PIM OIL (output interface list)\n")
3229{
c68ba0d7
DS
3230 int idx = 2;
3231 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3232
3233 if (!vrf)
3234 return CMD_WARNING;
3235
3236 pim_scan_oil(vrf->info);
12e41d03 3237
d62a17ae 3238 return CMD_SUCCESS;
12e41d03
DL
3239}
3240
e7016ceb 3241DEFUN (clear_ip_pim_bsr_db,
3242 clear_ip_pim_bsr_db_cmd,
3243 "clear ip pim [vrf NAME] bsr-data",
3244 CLEAR_STR
3245 IP_STR
3246 CLEAR_IP_PIM_STR
3247 VRF_CMD_HELP_STR
3248 "Reset pim bsr data\n")
3249{
3250 int idx = 2;
3251 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3252
3253 if (!vrf)
3254 return CMD_WARNING;
3255
b09bd804 3256 pim_bsm_clear(vrf->info);
e7016ceb 3257
3258 return CMD_SUCCESS;
3259}
3260
12e41d03
DL
3261DEFUN (show_ip_igmp_interface,
3262 show_ip_igmp_interface_cmd,
20a7e5fd 3263 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
3264 SHOW_STR
3265 IP_STR
3266 IGMP_STR
c68ba0d7 3267 VRF_CMD_HELP_STR
a268493f 3268 "IGMP interface information\n"
9b91bb50 3269 "Detailed output\n"
a268493f 3270 "interface name\n"
f5da2cc2 3271 JSON_STR)
12e41d03 3272{
c68ba0d7
DS
3273 int idx = 2;
3274 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 3275 bool uj = use_json(argc, argv);
c68ba0d7
DS
3276
3277 if (!vrf)
3278 return CMD_WARNING;
72e81cf4 3279
d62a17ae 3280 if (argv_find(argv, argc, "detail", &idx)
3281 || argv_find(argv, argc, "WORD", &idx))
64c86530 3282 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 3283 else
64c86530 3284 igmp_show_interfaces(vrf->info, vty, uj);
12e41d03 3285
d62a17ae 3286 return CMD_SUCCESS;
12e41d03
DL
3287}
3288
a25de56b
DS
3289DEFUN (show_ip_igmp_interface_vrf_all,
3290 show_ip_igmp_interface_vrf_all_cmd,
3291 "show ip igmp vrf all interface [detail|WORD] [json]",
3292 SHOW_STR
3293 IP_STR
3294 IGMP_STR
3295 VRF_CMD_HELP_STR
3296 "IGMP interface information\n"
3297 "Detailed output\n"
3298 "interface name\n"
f5da2cc2 3299 JSON_STR)
a25de56b
DS
3300{
3301 int idx = 2;
9f049418 3302 bool uj = use_json(argc, argv);
a25de56b
DS
3303 struct vrf *vrf;
3304 bool first = true;
3305
3306 if (uj)
3307 vty_out(vty, "{ ");
a2addae8 3308 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
3309 if (uj) {
3310 if (!first)
3311 vty_out(vty, ", ");
3312 vty_out(vty, " \"%s\": ", vrf->name);
3313 first = false;
3314 } else
3315 vty_out(vty, "VRF: %s\n", vrf->name);
3316 if (argv_find(argv, argc, "detail", &idx)
3317 || argv_find(argv, argc, "WORD", &idx))
3318 igmp_show_interfaces_single(vrf->info, vty,
3319 argv[idx]->arg, uj);
3320 else
3321 igmp_show_interfaces(vrf->info, vty, uj);
3322 }
3323 if (uj)
3324 vty_out(vty, "}\n");
3325
3326 return CMD_SUCCESS;
3327}
3328
12e41d03
DL
3329DEFUN (show_ip_igmp_join,
3330 show_ip_igmp_join_cmd,
85c82866 3331 "show ip igmp [vrf NAME] join [json]",
12e41d03
DL
3332 SHOW_STR
3333 IP_STR
3334 IGMP_STR
c68ba0d7 3335 VRF_CMD_HELP_STR
85c82866 3336 "IGMP static join information\n"
3337 JSON_STR)
12e41d03 3338{
c68ba0d7
DS
3339 int idx = 2;
3340 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
85c82866 3341 bool uj = use_json(argc, argv);
c68ba0d7
DS
3342
3343 if (!vrf)
3344 return CMD_WARNING;
3345
85c82866 3346 igmp_show_interface_join(vrf->info, vty, uj);
12e41d03 3347
d62a17ae 3348 return CMD_SUCCESS;
12e41d03
DL
3349}
3350
a25de56b
DS
3351DEFUN (show_ip_igmp_join_vrf_all,
3352 show_ip_igmp_join_vrf_all_cmd,
85c82866 3353 "show ip igmp vrf all join [json]",
a25de56b
DS
3354 SHOW_STR
3355 IP_STR
3356 IGMP_STR
3357 VRF_CMD_HELP_STR
85c82866 3358 "IGMP static join information\n"
3359 JSON_STR)
a25de56b 3360{
9f049418 3361 bool uj = use_json(argc, argv);
a25de56b
DS
3362 struct vrf *vrf;
3363 bool first = true;
3364
3365 if (uj)
3366 vty_out(vty, "{ ");
a2addae8 3367 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
3368 if (uj) {
3369 if (!first)
3370 vty_out(vty, ", ");
3371 vty_out(vty, " \"%s\": ", vrf->name);
3372 first = false;
3373 } else
3374 vty_out(vty, "VRF: %s\n", vrf->name);
85c82866 3375 igmp_show_interface_join(vrf->info, vty, uj);
a25de56b
DS
3376 }
3377 if (uj)
3378 vty_out(vty, "}\n");
3379
3380 return CMD_SUCCESS;
3381}
3382
12e41d03
DL
3383DEFUN (show_ip_igmp_groups,
3384 show_ip_igmp_groups_cmd,
20a7e5fd 3385 "show ip igmp [vrf NAME] groups [json]",
12e41d03
DL
3386 SHOW_STR
3387 IP_STR
3388 IGMP_STR
c68ba0d7 3389 VRF_CMD_HELP_STR
9b91bb50 3390 IGMP_GROUP_STR
f5da2cc2 3391 JSON_STR)
12e41d03 3392{
c68ba0d7
DS
3393 int idx = 2;
3394 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 3395 bool uj = use_json(argc, argv);
c68ba0d7
DS
3396
3397 if (!vrf)
3398 return CMD_WARNING;
3399
64c86530 3400 igmp_show_groups(vrf->info, vty, uj);
12e41d03 3401
d62a17ae 3402 return CMD_SUCCESS;
12e41d03
DL
3403}
3404
a25de56b
DS
3405DEFUN (show_ip_igmp_groups_vrf_all,
3406 show_ip_igmp_groups_vrf_all_cmd,
3407 "show ip igmp vrf all groups [json]",
3408 SHOW_STR
3409 IP_STR
3410 IGMP_STR
3411 VRF_CMD_HELP_STR
3412 IGMP_GROUP_STR
f5da2cc2 3413 JSON_STR)
a25de56b 3414{
9f049418 3415 bool uj = use_json(argc, argv);
a25de56b
DS
3416 struct vrf *vrf;
3417 bool first = true;
3418
3419 if (uj)
3420 vty_out(vty, "{ ");
a2addae8 3421 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
3422 if (uj) {
3423 if (!first)
3424 vty_out(vty, ", ");
3425 vty_out(vty, " \"%s\": ", vrf->name);
3426 first = false;
3427 } else
3428 vty_out(vty, "VRF: %s\n", vrf->name);
3429 igmp_show_groups(vrf->info, vty, uj);
3430 }
3431 if (uj)
3432 vty_out(vty, "}\n");
3433
3434 return CMD_SUCCESS;
3435}
3436
12e41d03
DL
3437DEFUN (show_ip_igmp_groups_retransmissions,
3438 show_ip_igmp_groups_retransmissions_cmd,
20a7e5fd 3439 "show ip igmp [vrf NAME] groups retransmissions",
12e41d03
DL
3440 SHOW_STR
3441 IP_STR
3442 IGMP_STR
c68ba0d7 3443 VRF_CMD_HELP_STR
12e41d03
DL
3444 IGMP_GROUP_STR
3445 "IGMP group retransmissions\n")
3446{
c68ba0d7
DS
3447 int idx = 2;
3448 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3449
3450 if (!vrf)
3451 return CMD_WARNING;
3452
64c86530 3453 igmp_show_group_retransmission(vrf->info, vty);
12e41d03 3454
d62a17ae 3455 return CMD_SUCCESS;
12e41d03
DL
3456}
3457
12e41d03
DL
3458DEFUN (show_ip_igmp_sources,
3459 show_ip_igmp_sources_cmd,
4527b70a 3460 "show ip igmp [vrf NAME] sources [json]",
12e41d03
DL
3461 SHOW_STR
3462 IP_STR
3463 IGMP_STR
c68ba0d7 3464 VRF_CMD_HELP_STR
4527b70a
SG
3465 IGMP_SOURCE_STR
3466 JSON_STR)
12e41d03 3467{
c68ba0d7
DS
3468 int idx = 2;
3469 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3470
3471 if (!vrf)
3472 return CMD_WARNING;
3473
4527b70a 3474 igmp_show_sources(vrf->info, vty, use_json(argc, argv));
12e41d03 3475
d62a17ae 3476 return CMD_SUCCESS;
12e41d03
DL
3477}
3478
3479DEFUN (show_ip_igmp_sources_retransmissions,
3480 show_ip_igmp_sources_retransmissions_cmd,
20a7e5fd 3481 "show ip igmp [vrf NAME] sources retransmissions",
12e41d03
DL
3482 SHOW_STR
3483 IP_STR
3484 IGMP_STR
c68ba0d7 3485 VRF_CMD_HELP_STR
12e41d03
DL
3486 IGMP_SOURCE_STR
3487 "IGMP source retransmissions\n")
3488{
c68ba0d7
DS
3489 int idx = 2;
3490 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3491
3492 if (!vrf)
3493 return CMD_WARNING;
3494
64c86530 3495 igmp_show_source_retransmission(vrf->info, vty);
12e41d03 3496
d62a17ae 3497 return CMD_SUCCESS;
12e41d03
DL
3498}
3499
21313cbf
MS
3500DEFUN (show_ip_igmp_statistics,
3501 show_ip_igmp_statistics_cmd,
3502 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3503 SHOW_STR
3504 IP_STR
3505 IGMP_STR
3506 VRF_CMD_HELP_STR
3507 "IGMP statistics\n"
3508 "interface\n"
3509 "IGMP interface\n"
3510 JSON_STR)
3511{
3512 int idx = 2;
3513 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 3514 bool uj = use_json(argc, argv);
21313cbf
MS
3515
3516 if (!vrf)
3517 return CMD_WARNING;
3518
3519 if (argv_find(argv, argc, "WORD", &idx))
3520 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
3521 else
3522 igmp_show_statistics(vrf->info, vty, NULL, uj);
3523
3524 return CMD_SUCCESS;
3525}
3526
17823cdd
DS
3527DEFUN (show_ip_pim_mlag_summary,
3528 show_ip_pim_mlag_summary_cmd,
3529 "show ip pim mlag summary [json]",
3530 SHOW_STR
3531 IP_STR
3532 PIM_STR
3533 "MLAG\n"
3534 "status and stats\n"
3535 JSON_STR)
3536{
3537 bool uj = use_json(argc, argv);
3538 char role_buf[MLAG_ROLE_STRSIZE];
3539 char addr_buf[INET_ADDRSTRLEN];
3540
3541 if (uj) {
3542 json_object *json = NULL;
3543 json_object *json_stat = NULL;
3544
3545 json = json_object_new_object();
3546 if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
3547 json_object_boolean_true_add(json, "mlagConnUp");
3548 if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
3549 json_object_boolean_true_add(json, "mlagPeerConnUp");
3550 if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
3551 json_object_boolean_true_add(json, "mlagPeerZebraUp");
3552 json_object_string_add(json, "mlagRole",
521c5b9d
MS
3553 mlag_role2str(router->mlag_role,
3554 role_buf, sizeof(role_buf)));
17823cdd 3555 inet_ntop(AF_INET, &router->local_vtep_ip,
521c5b9d 3556 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
3557 json_object_string_add(json, "localVtepIp", addr_buf);
3558 inet_ntop(AF_INET, &router->anycast_vtep_ip,
521c5b9d 3559 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
3560 json_object_string_add(json, "anycastVtepIp", addr_buf);
3561 json_object_string_add(json, "peerlinkRif",
521c5b9d 3562 router->peerlink_rif);
17823cdd
DS
3563
3564 json_stat = json_object_new_object();
3565 json_object_int_add(json_stat, "mlagConnFlaps",
521c5b9d 3566 router->mlag_stats.mlagd_session_downs);
17823cdd 3567 json_object_int_add(json_stat, "mlagPeerConnFlaps",
521c5b9d 3568 router->mlag_stats.peer_session_downs);
17823cdd 3569 json_object_int_add(json_stat, "mlagPeerZebraFlaps",
521c5b9d 3570 router->mlag_stats.peer_zebra_downs);
17823cdd 3571 json_object_int_add(json_stat, "mrouteAddRx",
521c5b9d 3572 router->mlag_stats.msg.mroute_add_rx);
17823cdd 3573 json_object_int_add(json_stat, "mrouteAddTx",
521c5b9d 3574 router->mlag_stats.msg.mroute_add_tx);
17823cdd 3575 json_object_int_add(json_stat, "mrouteDelRx",
521c5b9d 3576 router->mlag_stats.msg.mroute_del_rx);
17823cdd 3577 json_object_int_add(json_stat, "mrouteDelTx",
521c5b9d 3578 router->mlag_stats.msg.mroute_del_tx);
17823cdd 3579 json_object_int_add(json_stat, "mlagStatusUpdates",
521c5b9d 3580 router->mlag_stats.msg.mlag_status_updates);
17823cdd 3581 json_object_int_add(json_stat, "peerZebraStatusUpdates",
521c5b9d 3582 router->mlag_stats.msg.peer_zebra_status_updates);
17823cdd 3583 json_object_int_add(json_stat, "pimStatusUpdates",
521c5b9d 3584 router->mlag_stats.msg.pim_status_updates);
17823cdd 3585 json_object_int_add(json_stat, "vxlanUpdates",
521c5b9d 3586 router->mlag_stats.msg.vxlan_updates);
17823cdd
DS
3587 json_object_object_add(json, "connStats", json_stat);
3588
3757f964 3589 vty_json(vty, json);
17823cdd
DS
3590 return CMD_SUCCESS;
3591 }
3592
3593 vty_out(vty, "MLAG daemon connection: %s\n",
3594 (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
521c5b9d 3595 ? "up" : "down");
17823cdd
DS
3596 vty_out(vty, "MLAG peer state: %s\n",
3597 (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
521c5b9d 3598 ? "up" : "down");
17823cdd
DS
3599 vty_out(vty, "Zebra peer state: %s\n",
3600 (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
521c5b9d 3601 ? "up" : "down");
17823cdd
DS
3602 vty_out(vty, "MLAG role: %s\n",
3603 mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
3604 inet_ntop(AF_INET, &router->local_vtep_ip,
521c5b9d 3605 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
3606 vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
3607 inet_ntop(AF_INET, &router->anycast_vtep_ip,
521c5b9d 3608 addr_buf, INET_ADDRSTRLEN);
17823cdd
DS
3609 vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
3610 vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
3611 vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
521c5b9d
MS
3612 router->mlag_stats.mlagd_session_downs,
3613 router->mlag_stats.peer_session_downs,
3614 router->mlag_stats.peer_zebra_downs);
17823cdd
DS
3615 vty_out(vty, "Message Statistics:\n");
3616 vty_out(vty, " mroute adds: rx: %d, tx: %d\n",
521c5b9d
MS
3617 router->mlag_stats.msg.mroute_add_rx,
3618 router->mlag_stats.msg.mroute_add_tx);
17823cdd 3619 vty_out(vty, " mroute dels: rx: %d, tx: %d\n",
521c5b9d
MS
3620 router->mlag_stats.msg.mroute_del_rx,
3621 router->mlag_stats.msg.mroute_del_tx);
17823cdd 3622 vty_out(vty, " peer zebra status updates: %d\n",
521c5b9d 3623 router->mlag_stats.msg.peer_zebra_status_updates);
17823cdd 3624 vty_out(vty, " PIM status updates: %d\n",
521c5b9d 3625 router->mlag_stats.msg.pim_status_updates);
17823cdd 3626 vty_out(vty, " VxLAN updates: %d\n",
521c5b9d 3627 router->mlag_stats.msg.vxlan_updates);
17823cdd
DS
3628
3629 return CMD_SUCCESS;
3630}
3631
12e41d03
DL
3632DEFUN (show_ip_pim_assert,
3633 show_ip_pim_assert_cmd,
20a7e5fd 3634 "show ip pim [vrf NAME] assert",
12e41d03
DL
3635 SHOW_STR
3636 IP_STR
3637 PIM_STR
c68ba0d7 3638 VRF_CMD_HELP_STR
12e41d03
DL
3639 "PIM interface assert\n")
3640{
c68ba0d7
DS
3641 int idx = 2;
3642 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3643
3644 if (!vrf)
3645 return CMD_WARNING;
3646
64c86530 3647 pim_show_assert(vrf->info, vty);
12e41d03 3648
d62a17ae 3649 return CMD_SUCCESS;
12e41d03
DL
3650}
3651
3652DEFUN (show_ip_pim_assert_internal,
3653 show_ip_pim_assert_internal_cmd,
20a7e5fd 3654 "show ip pim [vrf NAME] assert-internal",
12e41d03
DL
3655 SHOW_STR
3656 IP_STR
3657 PIM_STR
c68ba0d7 3658 VRF_CMD_HELP_STR
12e41d03
DL
3659 "PIM interface internal assert state\n")
3660{
c68ba0d7
DS
3661 int idx = 2;
3662 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3663
3664 if (!vrf)
3665 return CMD_WARNING;
3666
64c86530 3667 pim_show_assert_internal(vrf->info, vty);
12e41d03 3668
d62a17ae 3669 return CMD_SUCCESS;
12e41d03
DL
3670}
3671
3672DEFUN (show_ip_pim_assert_metric,
3673 show_ip_pim_assert_metric_cmd,
20a7e5fd 3674 "show ip pim [vrf NAME] assert-metric",
12e41d03
DL
3675 SHOW_STR
3676 IP_STR
3677 PIM_STR
c68ba0d7 3678 VRF_CMD_HELP_STR
12e41d03
DL
3679 "PIM interface assert metric\n")
3680{
c68ba0d7
DS
3681 int idx = 2;
3682 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3683
3684 if (!vrf)
3685 return CMD_WARNING;
3686
64c86530 3687 pim_show_assert_metric(vrf->info, vty);
12e41d03 3688
d62a17ae 3689 return CMD_SUCCESS;
12e41d03
DL
3690}
3691
3692DEFUN (show_ip_pim_assert_winner_metric,
3693 show_ip_pim_assert_winner_metric_cmd,
20a7e5fd 3694 "show ip pim [vrf NAME] assert-winner-metric",
12e41d03
DL
3695 SHOW_STR
3696 IP_STR
3697 PIM_STR
c68ba0d7 3698 VRF_CMD_HELP_STR
12e41d03
DL
3699 "PIM interface assert winner metric\n")
3700{
c68ba0d7
DS
3701 int idx = 2;
3702 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3703
3704 if (!vrf)
3705 return CMD_WARNING;
3706
64c86530 3707 pim_show_assert_winner_metric(vrf->info, vty);
12e41d03 3708
d62a17ae 3709 return CMD_SUCCESS;
12e41d03
DL
3710}
3711
12e41d03
DL
3712DEFUN (show_ip_pim_interface,
3713 show_ip_pim_interface_cmd,
17823cdd 3714 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
3715 SHOW_STR
3716 IP_STR
3717 PIM_STR
17823cdd 3718 "MLAG\n"
c68ba0d7 3719 VRF_CMD_HELP_STR
a268493f 3720 "PIM interface information\n"
9b91bb50 3721 "Detailed output\n"
a268493f 3722 "interface name\n"
f5da2cc2 3723 JSON_STR)
12e41d03 3724{
c68ba0d7
DS
3725 int idx = 2;
3726 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 3727 bool uj = use_json(argc, argv);
17823cdd 3728 bool mlag = false;
c68ba0d7
DS
3729
3730 if (!vrf)
3731 return CMD_WARNING;
72e81cf4 3732
17823cdd
DS
3733 if (argv_find(argv, argc, "mlag", &idx))
3734 mlag = true;
3735
d62a17ae 3736 if (argv_find(argv, argc, "WORD", &idx)
3737 || argv_find(argv, argc, "detail", &idx))
17823cdd
DS
3738 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, mlag,
3739 uj);
d62a17ae 3740 else
17823cdd 3741 pim_show_interfaces(vrf->info, vty, mlag, uj);
12e41d03 3742
d62a17ae 3743 return CMD_SUCCESS;
12e41d03
DL
3744}
3745
a25de56b
DS
3746DEFUN (show_ip_pim_interface_vrf_all,
3747 show_ip_pim_interface_vrf_all_cmd,
17823cdd 3748 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
a25de56b
DS
3749 SHOW_STR
3750 IP_STR
3751 PIM_STR
17823cdd 3752 "MLAG\n"
a25de56b
DS
3753 VRF_CMD_HELP_STR
3754 "PIM interface information\n"
3755 "Detailed output\n"
3756 "interface name\n"
f5da2cc2 3757 JSON_STR)
a25de56b 3758{
17823cdd 3759 int idx = 2;
9f049418 3760 bool uj = use_json(argc, argv);
a25de56b
DS
3761 struct vrf *vrf;
3762 bool first = true;
17823cdd 3763 bool mlag = false;
a25de56b 3764
17823cdd
DS
3765 if (argv_find(argv, argc, "mlag", &idx))
3766 mlag = true;
3767
3768 idx = 6;
a25de56b
DS
3769 if (uj)
3770 vty_out(vty, "{ ");
a2addae8 3771 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
3772 if (uj) {
3773 if (!first)
3774 vty_out(vty, ", ");
3775 vty_out(vty, " \"%s\": ", vrf->name);
3776 first = false;
3777 } else
3778 vty_out(vty, "VRF: %s\n", vrf->name);
3779 if (argv_find(argv, argc, "WORD", &idx)
3780 || argv_find(argv, argc, "detail", &idx))
3781 pim_show_interfaces_single(vrf->info, vty,
17823cdd 3782 argv[idx]->arg, mlag, uj);
a25de56b 3783 else
17823cdd 3784 pim_show_interfaces(vrf->info, vty, mlag, uj);
a25de56b
DS
3785 }
3786 if (uj)
3787 vty_out(vty, "}\n");
3788
3789 return CMD_SUCCESS;
3790}
3791
6de45bcc 3792DEFPY (show_ip_pim_join,
12e41d03 3793 show_ip_pim_join_cmd,
6de45bcc 3794 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
3795 SHOW_STR
3796 IP_STR
3797 PIM_STR
c68ba0d7 3798 VRF_CMD_HELP_STR
a957a05b 3799 "PIM interface join information\n"
6de45bcc
DS
3800 "The Source or Group\n"
3801 "The Group\n"
a957a05b 3802 JSON_STR)
12e41d03 3803{
6fff2cc6 3804 pim_sgaddr sg = {0};
6de45bcc
DS
3805 struct vrf *v;
3806 bool uj = !!json;
3807 struct pim_instance *pim;
c68ba0d7 3808
6de45bcc
DS
3809 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
3810
3811 if (!v) {
3812 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 3813 return CMD_WARNING;
6de45bcc
DS
3814 }
3815 pim = pim_get_pim_instance(v->vrf_id);
3816
3817 if (!pim) {
3818 vty_out(vty, "%% Unable to find pim instance\n");
3819 return CMD_WARNING;
3820 }
3821
3a6290bd
DA
3822 if (s_or_g.s_addr != INADDR_ANY) {
3823 if (g.s_addr != INADDR_ANY) {
6de45bcc
DS
3824 sg.src = s_or_g;
3825 sg.grp = g;
3826 } else
3827 sg.grp = s_or_g;
3828 }
c68ba0d7 3829
6de45bcc 3830 pim_show_join(pim, vty, &sg, uj);
12e41d03 3831
d62a17ae 3832 return CMD_SUCCESS;
12e41d03
DL
3833}
3834
a25de56b
DS
3835DEFUN (show_ip_pim_join_vrf_all,
3836 show_ip_pim_join_vrf_all_cmd,
3837 "show ip pim vrf all join [json]",
3838 SHOW_STR
3839 IP_STR
3840 PIM_STR
3841 VRF_CMD_HELP_STR
3842 "PIM interface join information\n"
3843 JSON_STR)
3844{
6fff2cc6 3845 pim_sgaddr sg = {0};
9f049418 3846 bool uj = use_json(argc, argv);
a25de56b
DS
3847 struct vrf *vrf;
3848 bool first = true;
3849
3850 if (uj)
3851 vty_out(vty, "{ ");
a2addae8 3852 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
3853 if (uj) {
3854 if (!first)
3855 vty_out(vty, ", ");
3856 vty_out(vty, " \"%s\": ", vrf->name);
3857 first = false;
3858 } else
3859 vty_out(vty, "VRF: %s\n", vrf->name);
6de45bcc 3860 pim_show_join(vrf->info, vty, &sg, uj);
a25de56b
DS
3861 }
3862 if (uj)
3863 vty_out(vty, "}\n");
3864
3865 return CMD_WARNING;
3866}
3867
87b7cd5b 3868static void pim_show_jp_agg_helper(struct vty *vty,
521c5b9d
MS
3869 struct interface *ifp,
3870 struct pim_neighbor *neigh,
3871 struct pim_upstream *up,
3872 int is_join)
87b7cd5b 3873{
87b7cd5b
AK
3874 char rpf_str[INET_ADDRSTRLEN];
3875
521c5b9d 3876 /* pius->address.s_addr */
87b7cd5b
AK
3877 pim_inet4_dump("<rpf?>", neigh->source_addr, rpf_str, sizeof(rpf_str));
3878
8e8be741
DL
3879 vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %5s\n", ifp->name, rpf_str,
3880 &up->sg.src, &up->sg.grp, is_join ? "J" : "P");
87b7cd5b
AK
3881}
3882
3883static void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
3884{
3885 struct interface *ifp;
3886 struct pim_interface *pim_ifp;
3887 struct listnode *n_node;
3888 struct pim_neighbor *neigh;
3889 struct listnode *jag_node;
3890 struct pim_jp_agg_group *jag;
3891 struct listnode *js_node;
3892 struct pim_jp_sources *js;
3893
3894 vty_out(vty,
521c5b9d 3895 "Interface RPF Nbr Source Group State\n");
87b7cd5b
AK
3896
3897 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3898 pim_ifp = ifp->info;
3899 if (!pim_ifp)
3900 continue;
3901
3902 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
521c5b9d 3903 n_node, neigh)) {
87b7cd5b 3904 for (ALL_LIST_ELEMENTS_RO(neigh->upstream_jp_agg,
521c5b9d 3905 jag_node, jag)) {
87b7cd5b 3906 for (ALL_LIST_ELEMENTS_RO(jag->sources,
521c5b9d 3907 js_node, js)) {
87b7cd5b 3908 pim_show_jp_agg_helper(vty,
521c5b9d
MS
3909 ifp, neigh, js->up,
3910 js->is_join);
87b7cd5b
AK
3911 }
3912 }
3913 }
3914 }
3915}
3916
3917DEFPY (show_ip_pim_jp_agg,
3918 show_ip_pim_jp_agg_cmd,
3919 "show ip pim [vrf NAME] jp-agg",
3920 SHOW_STR
3921 IP_STR
3922 PIM_STR
3923 VRF_CMD_HELP_STR
3924 "join prune aggregation list\n")
3925{
3926 struct vrf *v;
3927 struct pim_instance *pim;
3928
3929 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
3930
3931 if (!v) {
3932 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
3933 return CMD_WARNING;
3934 }
3935 pim = pim_get_pim_instance(v->vrf_id);
3936
3937 if (!pim) {
3938 vty_out(vty, "%% Unable to find pim instance\n");
3939 return CMD_WARNING;
3940 }
3941
3942 pim_show_jp_agg_list(pim, vty);
3943
3944 return CMD_SUCCESS;
3945}
3946
12e41d03
DL
3947DEFUN (show_ip_pim_local_membership,
3948 show_ip_pim_local_membership_cmd,
20a7e5fd 3949 "show ip pim [vrf NAME] local-membership [json]",
12e41d03
DL
3950 SHOW_STR
3951 IP_STR
3952 PIM_STR
c68ba0d7 3953 VRF_CMD_HELP_STR
a957a05b
DS
3954 "PIM interface local-membership\n"
3955 JSON_STR)
12e41d03 3956{
c68ba0d7
DS
3957 int idx = 2;
3958 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 3959 bool uj = use_json(argc, argv);
c68ba0d7
DS
3960
3961 if (!vrf)
3962 return CMD_WARNING;
3963
64c86530 3964 pim_show_membership(vrf->info, vty, uj);
12e41d03 3965
d62a17ae 3966 return CMD_SUCCESS;
12e41d03
DL
3967}
3968
f80427e9 3969static void pim_show_mlag_up_entry_detail(struct vrf *vrf,
521c5b9d
MS
3970 struct vty *vty,
3971 struct pim_upstream *up,
3972 char *src_str, char *grp_str,
3973 json_object *json)
f80427e9
AK
3974{
3975 if (json) {
3976 json_object *json_row = NULL;
3977 json_object *own_list = NULL;
3978 json_object *json_group = NULL;
3979
3980
3981 json_object_object_get_ex(json, grp_str, &json_group);
3982 if (!json_group) {
3983 json_group = json_object_new_object();
3984 json_object_object_add(json, grp_str,
521c5b9d 3985 json_group);
f80427e9
AK
3986 }
3987
3988 json_row = json_object_new_object();
3989 json_object_string_add(json_row, "source", src_str);
3990 json_object_string_add(json_row, "group", grp_str);
3991
3992 own_list = json_object_new_array();
3993 if (pim_up_mlag_is_local(up))
3994 json_object_array_add(own_list,
521c5b9d 3995 json_object_new_string("local"));
f80427e9
AK
3996 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
3997 json_object_array_add(own_list,
521c5b9d 3998 json_object_new_string("peer"));
f80427e9
AK
3999 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
4000 json_object_array_add(
4001 own_list, json_object_new_string("Interface"));
4002 json_object_object_add(json_row, "owners", own_list);
4003
4004 json_object_int_add(json_row, "localCost",
521c5b9d 4005 pim_up_mlag_local_cost(up));
f80427e9 4006 json_object_int_add(json_row, "peerCost",
521c5b9d 4007 pim_up_mlag_peer_cost(up));
f80427e9
AK
4008 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
4009 json_object_boolean_false_add(json_row, "df");
4010 else
4011 json_object_boolean_true_add(json_row, "df");
4012 json_object_object_add(json_group, src_str, json_row);
4013 } else {
4014 char own_str[6];
4015
4016 own_str[0] = '\0';
4017 if (pim_up_mlag_is_local(up))
6c1b7a8c 4018 strlcat(own_str, "L", sizeof(own_str));
f80427e9 4019 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
6c1b7a8c 4020 strlcat(own_str, "P", sizeof(own_str));
f80427e9 4021 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
6c1b7a8c 4022 strlcat(own_str, "I", sizeof(own_str));
f80427e9
AK
4023 /* XXX - fixup, print paragraph output */
4024 vty_out(vty,
521c5b9d
MS
4025 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4026 src_str, grp_str, own_str,
4027 pim_up_mlag_local_cost(up),
4028 pim_up_mlag_peer_cost(up),
4029 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
4030 ? "n" : "y");
f80427e9
AK
4031 }
4032}
4033
4034static void pim_show_mlag_up_detail(struct vrf *vrf,
521c5b9d
MS
4035 struct vty *vty, const char *src_or_group,
4036 const char *group, bool uj)
f80427e9 4037{
8e8be741
DL
4038 char src_str[PIM_ADDRSTRLEN];
4039 char grp_str[PIM_ADDRSTRLEN];
f80427e9
AK
4040 struct pim_upstream *up;
4041 struct pim_instance *pim = vrf->info;
4042 json_object *json = NULL;
4043
4044 if (uj)
4045 json = json_object_new_object();
4046 else
4047 vty_out(vty,
4048 "Source Group Owner Local-cost Peer-cost DF\n");
4049
4050 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
4051 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
4052 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
4053 && !pim_up_mlag_is_local(up))
4054 continue;
4055
8e8be741
DL
4056 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
4057 snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
4058
f80427e9
AK
4059 /* XXX: strcmps are clearly inefficient. we should do uint comps
4060 * here instead.
4061 */
4062 if (group) {
4063 if (strcmp(src_str, src_or_group) ||
6c1b7a8c 4064 strcmp(grp_str, group))
f80427e9
AK
4065 continue;
4066 } else {
4067 if (strcmp(src_str, src_or_group) &&
6c1b7a8c 4068 strcmp(grp_str, src_or_group))
f80427e9
AK
4069 continue;
4070 }
4071 pim_show_mlag_up_entry_detail(vrf, vty, up,
6c1b7a8c 4072 src_str, grp_str, json);
f80427e9
AK
4073 }
4074
3757f964
DA
4075 if (uj)
4076 vty_json(vty, json);
f80427e9
AK
4077}
4078
4079static void pim_show_mlag_up_vrf(struct vrf *vrf, struct vty *vty, bool uj)
4080{
4081 json_object *json = NULL;
4082 json_object *json_row;
4083 struct pim_upstream *up;
f80427e9
AK
4084 struct pim_instance *pim = vrf->info;
4085 json_object *json_group = NULL;
4086
4087 if (uj) {
4088 json = json_object_new_object();
4089 } else {
4090 vty_out(vty,
4091 "Source Group Owner Local-cost Peer-cost DF\n");
4092 }
4093
4094 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
4095 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
4096 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
4097 && !pim_up_mlag_is_local(up))
4098 continue;
f80427e9 4099 if (uj) {
8e8be741
DL
4100 char src_str[PIM_ADDRSTRLEN];
4101 char grp_str[PIM_ADDRSTRLEN];
f80427e9
AK
4102 json_object *own_list = NULL;
4103
8e8be741
DL
4104 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
4105 &up->sg.grp);
4106 snprintfrr(src_str, sizeof(src_str), "%pPAs",
4107 &up->sg.src);
4108
f80427e9
AK
4109 json_object_object_get_ex(json, grp_str, &json_group);
4110 if (!json_group) {
4111 json_group = json_object_new_object();
4112 json_object_object_add(json, grp_str,
521c5b9d 4113 json_group);
f80427e9
AK
4114 }
4115
4116 json_row = json_object_new_object();
4117 json_object_string_add(json_row, "vrf", vrf->name);
4118 json_object_string_add(json_row, "source", src_str);
4119 json_object_string_add(json_row, "group", grp_str);
4120
4121 own_list = json_object_new_array();
4122 if (pim_up_mlag_is_local(up)) {
4123
4124 json_object_array_add(own_list,
521c5b9d
MS
4125 json_object_new_string(
4126 "local"));
f80427e9
AK
4127 }
4128 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)) {
4129 json_object_array_add(own_list,
521c5b9d
MS
4130 json_object_new_string(
4131 "peer"));
f80427e9
AK
4132 }
4133 json_object_object_add(json_row, "owners", own_list);
4134
4135 json_object_int_add(json_row, "localCost",
521c5b9d 4136 pim_up_mlag_local_cost(up));
f80427e9 4137 json_object_int_add(json_row, "peerCost",
521c5b9d 4138 pim_up_mlag_peer_cost(up));
f80427e9
AK
4139 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
4140 json_object_boolean_false_add(json_row, "df");
4141 else
4142 json_object_boolean_true_add(json_row, "df");
4143 json_object_object_add(json_group, src_str, json_row);
4144 } else {
4145 char own_str[6];
4146
4147 own_str[0] = '\0';
4148 if (pim_up_mlag_is_local(up))
6c1b7a8c 4149 strlcat(own_str, "L", sizeof(own_str));
f80427e9 4150 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
6c1b7a8c 4151 strlcat(own_str, "P", sizeof(own_str));
f80427e9 4152 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
6c1b7a8c 4153 strlcat(own_str, "I", sizeof(own_str));
f80427e9 4154 vty_out(vty,
8e8be741
DL
4155 "%-15pPAs %-15pPAs %-6s %-11u %-10u %2s\n",
4156 &up->sg.src, &up->sg.grp, own_str,
f80427e9
AK
4157 pim_up_mlag_local_cost(up),
4158 pim_up_mlag_peer_cost(up),
4159 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
521c5b9d 4160 ? "n" : "y");
f80427e9
AK
4161 }
4162 }
3757f964
DA
4163 if (uj)
4164 vty_json(vty, json);
f80427e9
AK
4165}
4166
4167static void pim_show_mlag_help_string(struct vty *vty, bool uj)
4168{
4169 if (!uj) {
4170 vty_out(vty, "Owner codes:\n");
4171 vty_out(vty,
3efd0893 4172 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
f80427e9
AK
4173 }
4174}
4175
4176
4177DEFUN(show_ip_pim_mlag_up, show_ip_pim_mlag_up_cmd,
4178 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4179 SHOW_STR
4180 IP_STR
4181 PIM_STR
4182 VRF_CMD_HELP_STR
4183 "MLAG\n"
4184 "upstream\n"
4185 "Unicast or Multicast address\n"
4186 "Multicast address\n" JSON_STR)
4187{
4188 const char *src_or_group = NULL;
4189 const char *group = NULL;
4190 int idx = 2;
4191 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4192 bool uj = use_json(argc, argv);
4193
4194 if (!vrf || !vrf->info) {
4195 vty_out(vty, "%s: VRF or Info missing\n", __func__);
4196 return CMD_WARNING;
4197 }
4198
4199 if (uj)
4200 argc--;
4201
4202 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4203 src_or_group = argv[idx]->arg;
4204 if (idx + 1 < argc)
4205 group = argv[idx + 1]->arg;
4206 }
4207
4208 pim_show_mlag_help_string(vty, uj);
4209
6c1b7a8c 4210 if (src_or_group)
f80427e9
AK
4211 pim_show_mlag_up_detail(vrf, vty, src_or_group, group, uj);
4212 else
4213 pim_show_mlag_up_vrf(vrf, vty, uj);
4214
4215 return CMD_SUCCESS;
4216}
4217
4218
4219DEFUN(show_ip_pim_mlag_up_vrf_all, show_ip_pim_mlag_up_vrf_all_cmd,
4220 "show ip pim vrf all mlag upstream [json]",
4221 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
4222 "MLAG\n"
4223 "upstream\n" JSON_STR)
4224{
4225 struct vrf *vrf;
4226 bool uj = use_json(argc, argv);
4227
4228 pim_show_mlag_help_string(vty, uj);
4229 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4230 pim_show_mlag_up_vrf(vrf, vty, uj);
4231 }
4232
4233 return CMD_SUCCESS;
4234}
4235
12e41d03
DL
4236DEFUN (show_ip_pim_neighbor,
4237 show_ip_pim_neighbor_cmd,
20a7e5fd 4238 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
12e41d03
DL
4239 SHOW_STR
4240 IP_STR
4241 PIM_STR
c68ba0d7 4242 VRF_CMD_HELP_STR
a268493f 4243 "PIM neighbor information\n"
9b91bb50 4244 "Detailed output\n"
a268493f 4245 "Name of interface or neighbor\n"
f5da2cc2 4246 JSON_STR)
12e41d03 4247{
c68ba0d7
DS
4248 int idx = 2;
4249 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4250 bool uj = use_json(argc, argv);
c68ba0d7
DS
4251
4252 if (!vrf)
4253 return CMD_WARNING;
72e81cf4 4254
d62a17ae 4255 if (argv_find(argv, argc, "detail", &idx)
4256 || argv_find(argv, argc, "WORD", &idx))
64c86530 4257 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 4258 else
64c86530 4259 pim_show_neighbors(vrf->info, vty, uj);
12e41d03 4260
d62a17ae 4261 return CMD_SUCCESS;
12e41d03
DL
4262}
4263
a25de56b
DS
4264DEFUN (show_ip_pim_neighbor_vrf_all,
4265 show_ip_pim_neighbor_vrf_all_cmd,
4266 "show ip pim vrf all neighbor [detail|WORD] [json]",
4267 SHOW_STR
4268 IP_STR
4269 PIM_STR
4270 VRF_CMD_HELP_STR
4271 "PIM neighbor information\n"
4272 "Detailed output\n"
4273 "Name of interface or neighbor\n"
f5da2cc2 4274 JSON_STR)
a25de56b
DS
4275{
4276 int idx = 2;
9f049418 4277 bool uj = use_json(argc, argv);
a25de56b
DS
4278 struct vrf *vrf;
4279 bool first = true;
4280
4281 if (uj)
4282 vty_out(vty, "{ ");
a2addae8 4283 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4284 if (uj) {
4285 if (!first)
4286 vty_out(vty, ", ");
4287 vty_out(vty, " \"%s\": ", vrf->name);
4288 first = false;
4289 } else
4290 vty_out(vty, "VRF: %s\n", vrf->name);
4291 if (argv_find(argv, argc, "detail", &idx)
4292 || argv_find(argv, argc, "WORD", &idx))
4293 pim_show_neighbors_single(vrf->info, vty,
4294 argv[idx]->arg, uj);
4295 else
4296 pim_show_neighbors(vrf->info, vty, uj);
4297 }
4298 if (uj)
4299 vty_out(vty, "}\n");
4300
4301 return CMD_SUCCESS;
4302}
4303
12e41d03
DL
4304DEFUN (show_ip_pim_secondary,
4305 show_ip_pim_secondary_cmd,
20a7e5fd 4306 "show ip pim [vrf NAME] secondary",
12e41d03
DL
4307 SHOW_STR
4308 IP_STR
4309 PIM_STR
c68ba0d7 4310 VRF_CMD_HELP_STR
12e41d03
DL
4311 "PIM neighbor addresses\n")
4312{
c68ba0d7
DS
4313 int idx = 2;
4314 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4315
4316 if (!vrf)
4317 return CMD_WARNING;
4318
64c86530 4319 pim_show_neighbors_secondary(vrf->info, vty);
12e41d03 4320
d62a17ae 4321 return CMD_SUCCESS;
12e41d03
DL
4322}
4323
31a21c9c
DW
4324DEFUN (show_ip_pim_state,
4325 show_ip_pim_state_cmd,
20a7e5fd 4326 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
31a21c9c
DW
4327 SHOW_STR
4328 IP_STR
4329 PIM_STR
c68ba0d7 4330 VRF_CMD_HELP_STR
31a21c9c
DW
4331 "PIM state information\n"
4332 "Unicast or Multicast address\n"
4333 "Multicast address\n"
f5da2cc2 4334 JSON_STR)
31a21c9c 4335{
d62a17ae 4336 const char *src_or_group = NULL;
4337 const char *group = NULL;
c68ba0d7
DS
4338 int idx = 2;
4339 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4340 bool uj = use_json(argc, argv);
c68ba0d7
DS
4341
4342 if (!vrf)
4343 return CMD_WARNING;
4344
d62a17ae 4345 if (uj)
4346 argc--;
31a21c9c 4347
56243c3a
DS
4348 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4349 src_or_group = argv[idx]->arg;
4350 if (idx + 1 < argc)
4351 group = argv[idx + 1]->arg;
4352 }
31a21c9c 4353
64c86530 4354 pim_show_state(vrf->info, vty, src_or_group, group, uj);
31a21c9c 4355
d62a17ae 4356 return CMD_SUCCESS;
31a21c9c
DW
4357}
4358
a25de56b
DS
4359DEFUN (show_ip_pim_state_vrf_all,
4360 show_ip_pim_state_vrf_all_cmd,
4361 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4362 SHOW_STR
4363 IP_STR
4364 PIM_STR
4365 VRF_CMD_HELP_STR
4366 "PIM state information\n"
4367 "Unicast or Multicast address\n"
4368 "Multicast address\n"
f5da2cc2 4369 JSON_STR)
a25de56b
DS
4370{
4371 const char *src_or_group = NULL;
4372 const char *group = NULL;
4373 int idx = 2;
9f049418 4374 bool uj = use_json(argc, argv);
a25de56b
DS
4375 struct vrf *vrf;
4376 bool first = true;
4377
4378 if (uj) {
4379 vty_out(vty, "{ ");
4380 argc--;
4381 }
4382
4383 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4384 src_or_group = argv[idx]->arg;
4385 if (idx + 1 < argc)
4386 group = argv[idx + 1]->arg;
4387 }
4388
a2addae8 4389 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4390 if (uj) {
4391 if (!first)
4392 vty_out(vty, ", ");
4393 vty_out(vty, " \"%s\": ", vrf->name);
4394 first = false;
4395 } else
4396 vty_out(vty, "VRF: %s\n", vrf->name);
4397 pim_show_state(vrf->info, vty, src_or_group, group, uj);
4398 }
4399 if (uj)
4400 vty_out(vty, "}\n");
4401
4402 return CMD_SUCCESS;
4403}
4404
dff5cedb 4405DEFPY (show_ip_pim_upstream,
12e41d03 4406 show_ip_pim_upstream_cmd,
dff5cedb 4407 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
4408 SHOW_STR
4409 IP_STR
4410 PIM_STR
c68ba0d7 4411 VRF_CMD_HELP_STR
a268493f 4412 "PIM upstream information\n"
dff5cedb
DS
4413 "The Source or Group\n"
4414 "The Group\n"
f5da2cc2 4415 JSON_STR)
12e41d03 4416{
6fff2cc6 4417 pim_sgaddr sg = {0};
dff5cedb
DS
4418 struct vrf *v;
4419 bool uj = !!json;
4420 struct pim_instance *pim;
c68ba0d7 4421
dff5cedb
DS
4422 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4423
4424 if (!v) {
4425 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 4426 return CMD_WARNING;
dff5cedb
DS
4427 }
4428 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 4429
dff5cedb
DS
4430 if (!pim) {
4431 vty_out(vty, "%% Unable to find pim instance\n");
4432 return CMD_WARNING;
4433 }
4434
3a6290bd
DA
4435 if (s_or_g.s_addr != INADDR_ANY) {
4436 if (g.s_addr != INADDR_ANY) {
dff5cedb
DS
4437 sg.src = s_or_g;
4438 sg.grp = g;
4439 } else
4440 sg.grp = s_or_g;
4441 }
4442 pim_show_upstream(pim, vty, &sg, uj);
12e41d03 4443
d62a17ae 4444 return CMD_SUCCESS;
12e41d03
DL
4445}
4446
a25de56b
DS
4447DEFUN (show_ip_pim_upstream_vrf_all,
4448 show_ip_pim_upstream_vrf_all_cmd,
4449 "show ip pim vrf all upstream [json]",
4450 SHOW_STR
4451 IP_STR
4452 PIM_STR
4453 VRF_CMD_HELP_STR
4454 "PIM upstream information\n"
4455 JSON_STR)
4456{
6fff2cc6 4457 pim_sgaddr sg = {0};
9f049418 4458 bool uj = use_json(argc, argv);
a25de56b
DS
4459 struct vrf *vrf;
4460 bool first = true;
4461
4462 if (uj)
4463 vty_out(vty, "{ ");
a2addae8 4464 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4465 if (uj) {
4466 if (!first)
4467 vty_out(vty, ", ");
4468 vty_out(vty, " \"%s\": ", vrf->name);
4469 first = false;
4470 } else
4471 vty_out(vty, "VRF: %s\n", vrf->name);
dff5cedb 4472 pim_show_upstream(vrf->info, vty, &sg, uj);
a25de56b
DS
4473 }
4474
4475 return CMD_SUCCESS;
4476}
4477
5c9a72ef
AK
4478DEFUN (show_ip_pim_channel,
4479 show_ip_pim_channel_cmd,
4480 "show ip pim [vrf NAME] channel [json]",
12e41d03
DL
4481 SHOW_STR
4482 IP_STR
4483 PIM_STR
c68ba0d7 4484 VRF_CMD_HELP_STR
5c9a72ef 4485 "PIM downstream channel info\n"
f5da2cc2 4486 JSON_STR)
12e41d03 4487{
c68ba0d7
DS
4488 int idx = 2;
4489 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4490 bool uj = use_json(argc, argv);
c68ba0d7
DS
4491
4492 if (!vrf)
4493 return CMD_WARNING;
4494
5c9a72ef 4495 pim_show_channel(vrf->info, vty, uj);
12e41d03 4496
d62a17ae 4497 return CMD_SUCCESS;
12e41d03
DL
4498}
4499
12e41d03
DL
4500DEFUN (show_ip_pim_upstream_join_desired,
4501 show_ip_pim_upstream_join_desired_cmd,
20a7e5fd 4502 "show ip pim [vrf NAME] upstream-join-desired [json]",
12e41d03
DL
4503 SHOW_STR
4504 IP_STR
4505 PIM_STR
c68ba0d7 4506 VRF_CMD_HELP_STR
a268493f 4507 "PIM upstream join-desired\n"
f5da2cc2 4508 JSON_STR)
12e41d03 4509{
c68ba0d7
DS
4510 int idx = 2;
4511 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4512 bool uj = use_json(argc, argv);
c68ba0d7
DS
4513
4514 if (!vrf)
4515 return CMD_WARNING;
4516
64c86530 4517 pim_show_join_desired(vrf->info, vty, uj);
12e41d03 4518
d62a17ae 4519 return CMD_SUCCESS;
12e41d03
DL
4520}
4521
4522DEFUN (show_ip_pim_upstream_rpf,
4523 show_ip_pim_upstream_rpf_cmd,
20a7e5fd 4524 "show ip pim [vrf NAME] upstream-rpf [json]",
12e41d03
DL
4525 SHOW_STR
4526 IP_STR
4527 PIM_STR
c68ba0d7 4528 VRF_CMD_HELP_STR
a268493f 4529 "PIM upstream source rpf\n"
f5da2cc2 4530 JSON_STR)
12e41d03 4531{
c68ba0d7
DS
4532 int idx = 2;
4533 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4534 bool uj = use_json(argc, argv);
c68ba0d7
DS
4535
4536 if (!vrf)
4537 return CMD_WARNING;
4538
64c86530 4539 pim_show_upstream_rpf(vrf->info, vty, uj);
12e41d03 4540
d62a17ae 4541 return CMD_SUCCESS;
12e41d03
DL
4542}
4543
0095f482 4544DEFPY (show_ip_pim_rp,
00d07c6f 4545 show_ip_pim_rp_cmd,
0095f482 4546 "show ip pim [vrf NAME] rp-info [A.B.C.D/M$group] [json$json]",
00d07c6f
DS
4547 SHOW_STR
4548 IP_STR
4549 PIM_STR
c68ba0d7 4550 VRF_CMD_HELP_STR
a268493f 4551 "PIM RP information\n"
8c0a7680 4552 "Multicast Group range\n"
f5da2cc2 4553 JSON_STR)
00d07c6f 4554{
0095f482
A
4555 struct pim_instance *pim;
4556 struct vrf *v;
4557 json_object *json_parent = NULL;
8c0a7680 4558 struct prefix *range = NULL;
c68ba0d7 4559
0095f482
A
4560 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4561
4562 if (!v)
c68ba0d7
DS
4563 return CMD_WARNING;
4564
0095f482
A
4565 pim = pim_get_pim_instance(v->vrf_id);
4566
4567 if (!pim) {
4568 vty_out(vty, "%% Unable to find pim instance\n");
4569 return CMD_WARNING;
4570 }
4571
4572 if (group_str) {
8c0a7680 4573 range = prefix_new();
0095f482 4574 prefix_copy(range, group);
8c0a7680
DA
4575 apply_mask(range);
4576 }
4577
0095f482
A
4578 if (json)
4579 json_parent = json_object_new_object();
4580
4581 pim_rp_show_information(pim, range, vty, json_parent);
4582
4583 if (json)
4584 vty_json(vty, json_parent);
4585
4586 prefix_free(&range);
00d07c6f 4587
d62a17ae 4588 return CMD_SUCCESS;
00d07c6f
DS
4589}
4590
0095f482 4591DEFPY (show_ip_pim_rp_vrf_all,
a25de56b 4592 show_ip_pim_rp_vrf_all_cmd,
0095f482 4593 "show ip pim vrf all rp-info [A.B.C.D/M$group] [json$json]",
a25de56b
DS
4594 SHOW_STR
4595 IP_STR
4596 PIM_STR
4597 VRF_CMD_HELP_STR
4598 "PIM RP information\n"
8c0a7680 4599 "Multicast Group range\n"
f5da2cc2 4600 JSON_STR)
a25de56b 4601{
a25de56b 4602 struct vrf *vrf;
0095f482
A
4603 json_object *json_parent = NULL;
4604 json_object *json_vrf = NULL;
8c0a7680
DA
4605 struct prefix *range = NULL;
4606
0095f482 4607 if (group_str) {
8c0a7680 4608 range = prefix_new();
0095f482 4609 prefix_copy(range, group);
8c0a7680
DA
4610 apply_mask(range);
4611 }
a25de56b 4612
0095f482
A
4613 if (json)
4614 json_parent = json_object_new_object();
4615
a2addae8 4616 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
0095f482 4617 if (!json)
a25de56b 4618 vty_out(vty, "VRF: %s\n", vrf->name);
0095f482
A
4619 else
4620 json_vrf = json_object_new_object();
4621 pim_rp_show_information(vrf->info, range, vty, json_vrf);
4622 if (json)
4623 json_object_object_add(json_parent, vrf->name,
4624 json_vrf);
a25de56b 4625 }
0095f482
A
4626 if (json)
4627 vty_json(vty, json_parent);
4628
4629 prefix_free(&range);
a25de56b
DS
4630
4631 return CMD_SUCCESS;
4632}
4633
1aa8de46 4634DEFPY (show_ip_pim_rpf,
12e41d03 4635 show_ip_pim_rpf_cmd,
1aa8de46 4636 "show ip pim [vrf NAME] rpf [json$json]",
12e41d03
DL
4637 SHOW_STR
4638 IP_STR
4639 PIM_STR
c68ba0d7 4640 VRF_CMD_HELP_STR
a268493f 4641 "PIM cached source rpf information\n"
f5da2cc2 4642 JSON_STR)
12e41d03 4643{
1aa8de46
A
4644 struct pim_instance *pim;
4645 struct vrf *v;
4646 json_object *json_parent = NULL;
c68ba0d7 4647
1aa8de46
A
4648 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4649
4650 if (!v)
4651 return CMD_WARNING;
4652
4653 pim = pim_get_pim_instance(v->vrf_id);
4654
4655 if (!pim) {
4656 vty_out(vty, "%% Unable to find pim instance\n");
c68ba0d7 4657 return CMD_WARNING;
1aa8de46
A
4658 }
4659
4660 if (json)
4661 json_parent = json_object_new_object();
4662
4663 pim_show_rpf(pim, vty, json_parent);
c68ba0d7 4664
1aa8de46
A
4665 if (json)
4666 vty_json(vty, json_parent);
12e41d03 4667
d62a17ae 4668 return CMD_SUCCESS;
12e41d03
DL
4669}
4670
1aa8de46 4671DEFPY (show_ip_pim_rpf_vrf_all,
a25de56b 4672 show_ip_pim_rpf_vrf_all_cmd,
1aa8de46 4673 "show ip pim vrf all rpf [json$json]",
a25de56b
DS
4674 SHOW_STR
4675 IP_STR
4676 PIM_STR
4677 VRF_CMD_HELP_STR
4678 "PIM cached source rpf information\n"
f5da2cc2 4679 JSON_STR)
a25de56b 4680{
a25de56b 4681 struct vrf *vrf;
1aa8de46
A
4682 json_object *json_parent = NULL;
4683 json_object *json_vrf = NULL;
4684
4685 if (json)
4686 json_parent = json_object_new_object();
a25de56b 4687
a2addae8 4688 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1aa8de46 4689 if (!json)
a25de56b 4690 vty_out(vty, "VRF: %s\n", vrf->name);
1aa8de46
A
4691 else
4692 json_vrf = json_object_new_object();
4693 pim_show_rpf(vrf->info, vty, json_vrf);
4694 if (json)
4695 json_object_object_add(json_parent, vrf->name,
4696 json_vrf);
a25de56b 4697 }
1aa8de46
A
4698 if (json)
4699 vty_json(vty, json_parent);
a25de56b
DS
4700
4701 return CMD_SUCCESS;
4702}
4703
cba44481
CS
4704DEFUN (show_ip_pim_nexthop,
4705 show_ip_pim_nexthop_cmd,
20a7e5fd 4706 "show ip pim [vrf NAME] nexthop",
cba44481
CS
4707 SHOW_STR
4708 IP_STR
4709 PIM_STR
c68ba0d7 4710 VRF_CMD_HELP_STR
cba44481
CS
4711 "PIM cached nexthop rpf information\n")
4712{
c68ba0d7
DS
4713 int idx = 2;
4714 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4715
4716 if (!vrf)
4717 return CMD_WARNING;
4718
64c86530 4719 pim_show_nexthop(vrf->info, vty);
cba44481 4720
d62a17ae 4721 return CMD_SUCCESS;
cba44481
CS
4722}
4723
4724DEFUN (show_ip_pim_nexthop_lookup,
4725 show_ip_pim_nexthop_lookup_cmd,
20a7e5fd 4726 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
cba44481
CS
4727 SHOW_STR
4728 IP_STR
4729 PIM_STR
c68ba0d7 4730 VRF_CMD_HELP_STR
cba44481
CS
4731 "PIM cached nexthop rpf lookup\n"
4732 "Source/RP address\n"
4733 "Multicast Group address\n")
4734{
d62a17ae 4735 struct prefix nht_p;
4736 int result = 0;
4737 struct in_addr src_addr, grp_addr;
4738 struct in_addr vif_source;
4739 const char *addr_str, *addr_str1;
4740 struct prefix grp;
4741 struct pim_nexthop nexthop;
4742 char nexthop_addr_str[PREFIX_STRLEN];
4743 char grp_str[PREFIX_STRLEN];
c68ba0d7
DS
4744 int idx = 2;
4745 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 4746
c68ba0d7
DS
4747 if (!vrf)
4748 return CMD_WARNING;
4749
4750 argv_find(argv, argc, "A.B.C.D", &idx);
4751 addr_str = argv[idx]->arg;
d62a17ae 4752 result = inet_pton(AF_INET, addr_str, &src_addr);
4753 if (result <= 0) {
4754 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
4755 errno, safe_strerror(errno));
4756 return CMD_WARNING;
4757 }
4758
4759 if (pim_is_group_224_4(src_addr)) {
4760 vty_out(vty,
4761 "Invalid argument. Expected Valid Source Address.\n");
4762 return CMD_WARNING;
4763 }
4764
c68ba0d7 4765 addr_str1 = argv[idx + 1]->arg;
d62a17ae 4766 result = inet_pton(AF_INET, addr_str1, &grp_addr);
4767 if (result <= 0) {
4768 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
4769 errno, safe_strerror(errno));
4770 return CMD_WARNING;
4771 }
4772
4773 if (!pim_is_group_224_4(grp_addr)) {
4774 vty_out(vty,
4775 "Invalid argument. Expected Valid Multicast Group Address.\n");
4776 return CMD_WARNING;
4777 }
4778
c68ba0d7
DS
4779 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
4780 grp_addr))
d62a17ae 4781 return CMD_SUCCESS;
4782
d62a17ae 4783 nht_p.family = AF_INET;
4784 nht_p.prefixlen = IPV4_MAX_BITLEN;
4785 nht_p.u.prefix4 = vif_source;
4786 grp.family = AF_INET;
4787 grp.prefixlen = IPV4_MAX_BITLEN;
4788 grp.u.prefix4 = grp_addr;
4789 memset(&nexthop, 0, sizeof(nexthop));
4790
43763b11 4791 result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
9993f22c
DS
4792
4793 if (!result) {
996c9314
LB
4794 vty_out(vty,
4795 "Nexthop Lookup failed, no usable routes returned.\n");
9993f22c
DS
4796 return CMD_SUCCESS;
4797 }
d62a17ae 4798
4799 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
4800 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
4801 nexthop_addr_str, sizeof(nexthop_addr_str));
4802 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
4803 nexthop_addr_str, nexthop.interface->name);
4804
4805 return CMD_SUCCESS;
cba44481
CS
4806}
4807
39438188
CS
4808DEFUN (show_ip_pim_interface_traffic,
4809 show_ip_pim_interface_traffic_cmd,
20a7e5fd 4810 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
39438188
CS
4811 SHOW_STR
4812 IP_STR
4813 PIM_STR
c68ba0d7 4814 VRF_CMD_HELP_STR
39438188
CS
4815 "PIM interface information\n"
4816 "Protocol Packet counters\n"
17d86e50 4817 "Interface name\n"
f5da2cc2 4818 JSON_STR)
39438188 4819{
c68ba0d7
DS
4820 int idx = 2;
4821 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4822 bool uj = use_json(argc, argv);
c68ba0d7
DS
4823
4824 if (!vrf)
4825 return CMD_WARNING;
39438188 4826
d62a17ae 4827 if (argv_find(argv, argc, "WORD", &idx))
64c86530 4828 pim_show_interface_traffic_single(vrf->info, vty,
c68ba0d7 4829 argv[idx]->arg, uj);
d62a17ae 4830 else
64c86530 4831 pim_show_interface_traffic(vrf->info, vty, uj);
39438188 4832
d62a17ae 4833 return CMD_SUCCESS;
39438188
CS
4834}
4835
0d1a4e24 4836DEFUN (show_ip_pim_bsm_db,
4837 show_ip_pim_bsm_db_cmd,
4838 "show ip pim bsm-database [vrf NAME] [json]",
4839 SHOW_STR
4840 IP_STR
4841 PIM_STR
0d1a4e24 4842 "PIM cached bsm packets information\n"
33b58e53 4843 VRF_CMD_HELP_STR
0d1a4e24 4844 JSON_STR)
4845{
4846 int idx = 2;
4847 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4848 bool uj = use_json(argc, argv);
4849
4850 if (!vrf)
4851 return CMD_WARNING;
4852
4853 pim_show_bsm_db(vrf->info, vty, uj);
4854 return CMD_SUCCESS;
4855}
321295c1 4856
4857DEFUN (show_ip_pim_bsrp,
4858 show_ip_pim_bsrp_cmd,
4859 "show ip pim bsrp-info [vrf NAME] [json]",
4860 SHOW_STR
4861 IP_STR
4862 PIM_STR
321295c1 4863 "PIM cached group-rp mappings information\n"
33b58e53 4864 VRF_CMD_HELP_STR
321295c1 4865 JSON_STR)
4866{
4867 int idx = 2;
4868 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4869 bool uj = use_json(argc, argv);
4870
4871 if (!vrf)
4872 return CMD_WARNING;
4873
4874 pim_show_group_rp_mappings_info(vrf->info, vty, uj);
4875
4876 return CMD_SUCCESS;
4877}
4878
415f6350 4879DEFUN (show_ip_pim_statistics,
4880 show_ip_pim_statistics_cmd,
33b58e53 4881 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
415f6350 4882 SHOW_STR
4883 IP_STR
4884 PIM_STR
4885 VRF_CMD_HELP_STR
4886 "PIM statistics\n"
33b58e53 4887 INTERFACE_STR
415f6350 4888 "PIM interface\n"
4889 JSON_STR)
4890{
4891 int idx = 2;
4892 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4893 bool uj = use_json(argc, argv);
4894
4895 if (!vrf)
4896 return CMD_WARNING;
4897
4898 if (argv_find(argv, argc, "WORD", &idx))
4899 pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
4900 else
4901 pim_show_statistics(vrf->info, vty, NULL, uj);
4902
4903 return CMD_SUCCESS;
4904}
4905
8c8d7031
SP
4906static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
4907 bool uj)
12e41d03 4908{
d62a17ae 4909 struct interface *ifp;
ee2bbf7c 4910 char buf[PREFIX_STRLEN];
8c8d7031
SP
4911 json_object *json = NULL;
4912 json_object *json_row = NULL;
d62a17ae 4913
4914 vty_out(vty, "\n");
4915
8c8d7031
SP
4916 if (uj)
4917 json = json_object_new_object();
4918 else
4919 vty_out(vty,
4920 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
d62a17ae 4921
451fda4f 4922 FOR_ALL_INTERFACES (pim->vrf, ifp) {
c68ba0d7
DS
4923 struct pim_interface *pim_ifp;
4924 struct in_addr ifaddr;
4925 struct sioc_vif_req vreq;
d62a17ae 4926
c68ba0d7 4927 pim_ifp = ifp->info;
d62a17ae 4928
c68ba0d7
DS
4929 if (!pim_ifp)
4930 continue;
d62a17ae 4931
c68ba0d7
DS
4932 memset(&vreq, 0, sizeof(vreq));
4933 vreq.vifi = pim_ifp->mroute_vif_index;
d62a17ae 4934
c68ba0d7
DS
4935 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
4936 zlog_warn(
4937 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4938 (unsigned long)SIOCGETVIFCNT, ifp->name,
4939 pim_ifp->mroute_vif_index, errno,
4940 safe_strerror(errno));
4941 }
ecca97ac 4942
c68ba0d7 4943 ifaddr = pim_ifp->primary_address;
8c8d7031
SP
4944 if (uj) {
4945 json_row = json_object_new_object();
4946 json_object_string_add(json_row, "name", ifp->name);
4947 json_object_string_add(json_row, "state",
4948 if_is_up(ifp) ? "up" : "down");
b0d5264e
DA
4949 json_object_string_addf(json_row, "address", "%pI4",
4950 &pim_ifp->primary_address);
8c8d7031
SP
4951 json_object_int_add(json_row, "ifIndex", ifp->ifindex);
4952 json_object_int_add(json_row, "vif",
4953 pim_ifp->mroute_vif_index);
4954 json_object_int_add(json_row, "pktsIn",
4955 (unsigned long)vreq.icount);
4956 json_object_int_add(json_row, "pktsOut",
4957 (unsigned long)vreq.ocount);
4958 json_object_int_add(json_row, "bytesIn",
4959 (unsigned long)vreq.ibytes);
4960 json_object_int_add(json_row, "bytesOut",
4961 (unsigned long)vreq.obytes);
4962 json_object_object_add(json, ifp->name, json_row);
4963 } else {
4964 vty_out(vty,
4965 "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
ee2bbf7c
MS
4966 ifp->name,
4967 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
4968 ifp->ifindex, pim_ifp->mroute_vif_index,
8c8d7031
SP
4969 (unsigned long)vreq.icount,
4970 (unsigned long)vreq.ocount,
4971 (unsigned long)vreq.ibytes,
4972 (unsigned long)vreq.obytes);
4973 }
4974 }
d62a17ae 4975
3757f964
DA
4976 if (uj)
4977 vty_json(vty, json);
12e41d03
DL
4978}
4979
a25de56b
DS
4980static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
4981 struct vty *vty)
12e41d03 4982{
a25de56b 4983 struct vrf *vrf = pim->vrf;
d62a17ae 4984 time_t now = pim_time_monotonic_sec();
d62a17ae 4985 char uptime[10];
afec9bba 4986 char mlag_role[80];
d62a17ae 4987
bc14b6c7
DS
4988 pim = vrf->info;
4989
afec9bba 4990 vty_out(vty, "Router MLAG Role: %s\n",
05ca004b 4991 mlag_role2str(router->mlag_role, mlag_role, sizeof(mlag_role)));
ecca97ac
DS
4992 vty_out(vty, "Mroute socket descriptor:");
4993
c68ba0d7 4994 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
12e41d03 4995
d62a17ae 4996 pim_time_uptime(uptime, sizeof(uptime),
c68ba0d7 4997 now - pim->mroute_socket_creation);
d62a17ae 4998 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
12e41d03 4999
d62a17ae 5000 vty_out(vty, "\n");
12e41d03 5001
d62a17ae 5002 pim_zebra_zclient_update(vty);
5003 pim_zlookup_show_ip_multicast(vty);
05b0d0d0 5004
d62a17ae 5005 vty_out(vty, "\n");
5006 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
12e41d03 5007
d62a17ae 5008 vty_out(vty, "\n");
5b45753e 5009 vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
d62a17ae 5010 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
4795fff7 5011 vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
d62a17ae 5012 vty_out(vty, "PIM ECMP Rebalance: %s\n",
4795fff7 5013 pim->ecmp_rebalance_enable ? "Enable" : "Disable");
12e41d03 5014
d62a17ae 5015 vty_out(vty, "\n");
12e41d03 5016
1aa8de46 5017 pim_show_rpf_refresh_stats(vty, pim, now, NULL);
12e41d03 5018
d62a17ae 5019 vty_out(vty, "\n");
12e41d03 5020
64c86530 5021 show_scan_oil_stats(pim, vty, now);
12e41d03 5022
8c8d7031 5023 show_multicast_interfaces(pim, vty, false);
a25de56b
DS
5024}
5025
5026DEFUN (show_ip_multicast,
5027 show_ip_multicast_cmd,
5028 "show ip multicast [vrf NAME]",
5029 SHOW_STR
5030 IP_STR
5031 VRF_CMD_HELP_STR
5032 "Multicast global information\n")
5033{
5034 int idx = 2;
5035 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5036
5037 if (!vrf)
5038 return CMD_WARNING;
5039
5040 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5041
5042 return CMD_SUCCESS;
5043}
5044
5045DEFUN (show_ip_multicast_vrf_all,
5046 show_ip_multicast_vrf_all_cmd,
5047 "show ip multicast vrf all",
5048 SHOW_STR
5049 IP_STR
5050 VRF_CMD_HELP_STR
5051 "Multicast global information\n")
5052{
9f049418 5053 bool uj = use_json(argc, argv);
a25de56b
DS
5054 struct vrf *vrf;
5055 bool first = true;
5056
5057 if (uj)
5058 vty_out(vty, "{ ");
a2addae8 5059 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5060 if (uj) {
5061 if (!first)
5062 vty_out(vty, ", ");
5063 vty_out(vty, " \"%s\": ", vrf->name);
5064 first = false;
5065 } else
5066 vty_out(vty, "VRF: %s\n", vrf->name);
5067 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5068 }
5069 if (uj)
5070 vty_out(vty, "}\n");
12e41d03 5071
d62a17ae 5072 return CMD_SUCCESS;
12e41d03
DL
5073}
5074
8c8d7031
SP
5075DEFUN(show_ip_multicast_count,
5076 show_ip_multicast_count_cmd,
5077 "show ip multicast count [vrf NAME] [json]",
5078 SHOW_STR IP_STR
5079 "Multicast global information\n"
5080 "Data packet count\n"
5081 VRF_CMD_HELP_STR JSON_STR)
5082{
5083 int idx = 3;
5084 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5085 bool uj = use_json(argc, argv);
5086
5087 if (!vrf)
5088 return CMD_WARNING;
5089
5090 show_multicast_interfaces(vrf->info, vty, uj);
5091
5092 return CMD_SUCCESS;
5093}
5094
5095DEFUN(show_ip_multicast_count_vrf_all,
5096 show_ip_multicast_count_vrf_all_cmd,
5097 "show ip multicast count vrf all [json]",
5098 SHOW_STR IP_STR
5099 "Multicast global information\n"
5100 "Data packet count\n"
5101 VRF_CMD_HELP_STR JSON_STR)
5102{
5103 bool uj = use_json(argc, argv);
5104 struct vrf *vrf;
5105 bool first = true;
5106
5107 if (uj)
5108 vty_out(vty, "{ ");
5109
5110 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5111 if (uj) {
5112 if (!first)
5113 vty_out(vty, ", ");
5114
5115 vty_out(vty, " \"%s\": ", vrf->name);
5116 first = false;
5117 } else
5118 vty_out(vty, "VRF: %s\n", vrf->name);
5119
5120 show_multicast_interfaces(vrf->info, vty, uj);
5121 }
5122
5123 if (uj)
5124 vty_out(vty, "}\n");
5125
5126 return CMD_SUCCESS;
5127}
5128
c23c1d39 5129static void show_mroute(struct pim_instance *pim, struct vty *vty,
6fff2cc6 5130 pim_sgaddr *sg, bool fill, bool uj)
12e41d03 5131{
d62a17ae 5132 struct listnode *node;
5133 struct channel_oil *c_oil;
5134 struct static_route *s_route;
5135 time_t now;
5136 json_object *json = NULL;
5137 json_object *json_group = NULL;
5138 json_object *json_source = NULL;
5139 json_object *json_oil = NULL;
5140 json_object *json_ifp_out = NULL;
a2b6e694 5141 int found_oif;
5142 int first;
d62a17ae 5143 char grp_str[INET_ADDRSTRLEN];
5144 char src_str[INET_ADDRSTRLEN];
5145 char in_ifname[INTERFACE_NAMSIZ + 1];
5146 char out_ifname[INTERFACE_NAMSIZ + 1];
5147 int oif_vif_index;
5148 struct interface *ifp_in;
5149 char proto[100];
6a424619 5150 char state_str[PIM_REG_STATE_STR_LEN];
dfd12d02 5151 char mroute_uptime[10];
d62a17ae 5152
5153 if (uj) {
5154 json = json_object_new_object();
5155 } else {
6a424619 5156 vty_out(vty, "IP Multicast Routing Table\n");
5d06e8a6 5157 vty_out(vty, "Flags: S - Sparse, C - Connected, P - Pruned\n");
d62a17ae 5158 vty_out(vty,
e9376c88 5159 " R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n");
6a424619 5160 vty_out(vty,
cd72ad01 5161 "\nSource Group Flags Proto Input Output TTL Uptime\n");
d62a17ae 5162 }
5163
5164 now = pim_time_monotonic_sec();
5165
5166 /* print list of PIM and IGMP routes */
7315ecda 5167 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
d62a17ae 5168 found_oif = 0;
5169 first = 1;
91c0fb47 5170 if (!c_oil->installed)
d62a17ae 5171 continue;
5172
032a7412
DL
5173 if (!pim_addr_is_any(sg->grp) &&
5174 pim_addr_cmp(sg->grp, c_oil->oil.mfcc_mcastgrp))
c23c1d39 5175 continue;
032a7412
DL
5176 if (!pim_addr_is_any(sg->src) &&
5177 pim_addr_cmp(sg->src, c_oil->oil.mfcc_origin))
c23c1d39
DS
5178 continue;
5179
d62a17ae 5180 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
5181 sizeof(grp_str));
5182 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
5183 sizeof(src_str));
6a424619
SP
5184
5185 strlcpy(state_str, "S", sizeof(state_str));
5186 /* When a non DR receives a igmp join, it creates a (*,G)
5187 * channel_oil without any upstream creation */
5188 if (c_oil->up) {
5189 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil->up->flags))
5190 strlcat(state_str, "C", sizeof(state_str));
5191 if (pim_upstream_is_sg_rpt(c_oil->up))
5192 strlcat(state_str, "R", sizeof(state_str));
5193 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil->up->flags))
5194 strlcat(state_str, "F", sizeof(state_str));
5195 if (c_oil->up->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
5196 strlcat(state_str, "T", sizeof(state_str));
5197 }
5198 if (pim_channel_oil_empty(c_oil))
5199 strlcat(state_str, "P", sizeof(state_str));
5200
7cfc7bcf 5201 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 5202
5203 if (ifp_in)
c35b7e6b 5204 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
d62a17ae 5205 else
c35b7e6b 5206 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 5207
dfd12d02
SP
5208
5209 pim_time_uptime(mroute_uptime, sizeof(mroute_uptime),
5210 now - c_oil->mroute_creation);
5211
d62a17ae 5212 if (uj) {
5213
5214 /* Find the group, create it if it doesn't exist */
5215 json_object_object_get_ex(json, grp_str, &json_group);
5216
5217 if (!json_group) {
5218 json_group = json_object_new_object();
5219 json_object_object_add(json, grp_str,
5220 json_group);
5221 }
5222
5223 /* Find the source nested under the group, create it if
6a424619
SP
5224 * it doesn't exist
5225 */
d62a17ae 5226 json_object_object_get_ex(json_group, src_str,
5227 &json_source);
5228
5229 if (!json_source) {
5230 json_source = json_object_new_object();
5231 json_object_object_add(json_group, src_str,
5232 json_source);
5233 }
5234
5235 /* Find the inbound interface nested under the source,
5236 * create it if it doesn't exist */
f37cbaea 5237 json_object_string_add(json_source, "source",
5238 src_str);
5239 json_object_string_add(json_source, "group",
5240 grp_str);
d62a17ae 5241 json_object_int_add(json_source, "installed",
5242 c_oil->installed);
5243 json_object_int_add(json_source, "refCount",
5244 c_oil->oil_ref_count);
5245 json_object_int_add(json_source, "oilSize",
5246 c_oil->oil_size);
5247 json_object_int_add(json_source, "OilInheritedRescan",
5248 c_oil->oil_inherited_rescan);
77a2f8e5
DA
5249 json_object_int_add(json_source, "oilInheritedRescan",
5250 c_oil->oil_inherited_rescan);
d62a17ae 5251 json_object_string_add(json_source, "iif", in_ifname);
dfd12d02
SP
5252 json_object_string_add(json_source, "upTime",
5253 mroute_uptime);
d62a17ae 5254 json_oil = NULL;
5255 }
5256
5257 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5258 ++oif_vif_index) {
5259 struct interface *ifp_out;
d62a17ae 5260 int ttl;
5261
5262 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
5263 if (ttl < 1)
5264 continue;
5265
5923b739
AK
5266 /* do not display muted OIFs */
5267 if (c_oil->oif_flags[oif_vif_index]
521c5b9d 5268 & PIM_OIF_FLAG_MUTE)
5923b739
AK
5269 continue;
5270
60eb7e6b 5271 if (c_oil->oil.mfcc_parent == oif_vif_index &&
521c5b9d
MS
5272 !pim_mroute_allow_iif_in_oil(c_oil,
5273 oif_vif_index))
60eb7e6b
AK
5274 continue;
5275
7cfc7bcf 5276 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 5277 found_oif = 1;
5278
5279 if (ifp_out)
c35b7e6b 5280 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
d62a17ae 5281 else
c35b7e6b 5282 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 5283
5284 if (uj) {
5285 json_ifp_out = json_object_new_object();
5286 json_object_string_add(json_ifp_out, "source",
5287 src_str);
5288 json_object_string_add(json_ifp_out, "group",
5289 grp_str);
5290
5291 if (c_oil->oif_flags[oif_vif_index]
5292 & PIM_OIF_FLAG_PROTO_PIM)
5293 json_object_boolean_true_add(
5294 json_ifp_out, "protocolPim");
5295
5296 if (c_oil->oif_flags[oif_vif_index]
5297 & PIM_OIF_FLAG_PROTO_IGMP)
5298 json_object_boolean_true_add(
5299 json_ifp_out, "protocolIgmp");
5300
ee31c9fd
AK
5301 if (c_oil->oif_flags[oif_vif_index]
5302 & PIM_OIF_FLAG_PROTO_VXLAN)
5303 json_object_boolean_true_add(
5304 json_ifp_out, "protocolVxlan");
5305
d62a17ae 5306 if (c_oil->oif_flags[oif_vif_index]
5307 & PIM_OIF_FLAG_PROTO_STAR)
5308 json_object_boolean_true_add(
5309 json_ifp_out,
5310 "protocolInherited");
5311
5312 json_object_string_add(json_ifp_out,
5313 "inboundInterface",
5314 in_ifname);
5315 json_object_int_add(json_ifp_out, "iVifI",
5316 c_oil->oil.mfcc_parent);
5317 json_object_string_add(json_ifp_out,
5318 "outboundInterface",
5319 out_ifname);
5320 json_object_int_add(json_ifp_out, "oVifI",
5321 oif_vif_index);
5322 json_object_int_add(json_ifp_out, "ttl", ttl);
5323 json_object_string_add(json_ifp_out, "upTime",
e7cd85bd 5324 mroute_uptime);
922e7544 5325 json_object_string_add(json_source, "flags",
5326 state_str);
d62a17ae 5327 if (!json_oil) {
5328 json_oil = json_object_new_object();
5329 json_object_object_add(json_source,
5330 "oil", json_oil);
5331 }
5332 json_object_object_add(json_oil, out_ifname,
5333 json_ifp_out);
5334 } else {
f8ca1bb9 5335 proto[0] = '\0';
d62a17ae 5336 if (c_oil->oif_flags[oif_vif_index]
5337 & PIM_OIF_FLAG_PROTO_PIM) {
c35b7e6b 5338 strlcpy(proto, "PIM", sizeof(proto));
d62a17ae 5339 }
5340
5341 if (c_oil->oif_flags[oif_vif_index]
5342 & PIM_OIF_FLAG_PROTO_IGMP) {
c35b7e6b 5343 strlcpy(proto, "IGMP", sizeof(proto));
d62a17ae 5344 }
5345
ee31c9fd
AK
5346 if (c_oil->oif_flags[oif_vif_index]
5347 & PIM_OIF_FLAG_PROTO_VXLAN) {
c35b7e6b 5348 strlcpy(proto, "VxLAN", sizeof(proto));
ee31c9fd
AK
5349 }
5350
d62a17ae 5351 if (c_oil->oif_flags[oif_vif_index]
5352 & PIM_OIF_FLAG_PROTO_STAR) {
c35b7e6b 5353 strlcpy(proto, "STAR", sizeof(proto));
d62a17ae 5354 }
5355
5356 vty_out(vty,
cd72ad01 5357 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6a424619
SP
5358 src_str, grp_str, state_str, proto,
5359 in_ifname, out_ifname, ttl,
5360 mroute_uptime);
d62a17ae 5361
5362 if (first) {
5363 src_str[0] = '\0';
5364 grp_str[0] = '\0';
5365 in_ifname[0] = '\0';
6a424619 5366 state_str[0] = '\0';
dfd12d02 5367 mroute_uptime[0] = '\0';
d62a17ae 5368 first = 0;
5369 }
5370 }
5371 }
5372
5373 if (!uj && !found_oif) {
6a424619 5374 vty_out(vty,
530b12cf 5375 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6a424619
SP
5376 src_str, grp_str, state_str, "none", in_ifname,
5377 "none", 0, "--:--:--");
d62a17ae 5378 }
5379 }
5380
5381 /* Print list of static routes */
7cfc7bcf
DS
5382 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5383 first = 1;
5384
5385 if (!s_route->c_oil.installed)
d62a17ae 5386 continue;
5387
7cfc7bcf
DS
5388 pim_inet4_dump("<group?>", s_route->group, grp_str,
5389 sizeof(grp_str));
5390 pim_inet4_dump("<source?>", s_route->source, src_str,
5391 sizeof(src_str));
5392 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
5393 found_oif = 0;
d62a17ae 5394
7cfc7bcf 5395 if (ifp_in)
c35b7e6b 5396 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
7cfc7bcf 5397 else
c35b7e6b 5398 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 5399
7cfc7bcf 5400 if (uj) {
d62a17ae 5401
7cfc7bcf
DS
5402 /* Find the group, create it if it doesn't exist */
5403 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 5404
7cfc7bcf
DS
5405 if (!json_group) {
5406 json_group = json_object_new_object();
5407 json_object_object_add(json, grp_str,
5408 json_group);
5409 }
d62a17ae 5410
7cfc7bcf
DS
5411 /* Find the source nested under the group, create it if
5412 * it doesn't exist */
5413 json_object_object_get_ex(json_group, src_str,
5414 &json_source);
d62a17ae 5415
7cfc7bcf
DS
5416 if (!json_source) {
5417 json_source = json_object_new_object();
5418 json_object_object_add(json_group, src_str,
5419 json_source);
5420 }
d62a17ae 5421
7cfc7bcf
DS
5422 json_object_string_add(json_source, "iif", in_ifname);
5423 json_oil = NULL;
5424 } else {
c35b7e6b 5425 strlcpy(proto, "STATIC", sizeof(proto));
7cfc7bcf 5426 }
d62a17ae 5427
7cfc7bcf
DS
5428 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5429 ++oif_vif_index) {
5430 struct interface *ifp_out;
5431 char oif_uptime[10];
5432 int ttl;
d62a17ae 5433
7cfc7bcf
DS
5434 ttl = s_route->oif_ttls[oif_vif_index];
5435 if (ttl < 1)
5436 continue;
5437
5438 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
996c9314
LB
5439 pim_time_uptime(
5440 oif_uptime, sizeof(oif_uptime),
5441 now
521c5b9d
MS
5442 - s_route->c_oil
5443 .oif_creation[oif_vif_index]);
7cfc7bcf 5444 found_oif = 1;
d62a17ae 5445
7cfc7bcf 5446 if (ifp_out)
c35b7e6b 5447 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
7cfc7bcf 5448 else
c35b7e6b 5449 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 5450
7cfc7bcf
DS
5451 if (uj) {
5452 json_ifp_out = json_object_new_object();
5453 json_object_string_add(json_ifp_out, "source",
5454 src_str);
5455 json_object_string_add(json_ifp_out, "group",
5456 grp_str);
5457 json_object_boolean_true_add(json_ifp_out,
5458 "protocolStatic");
5459 json_object_string_add(json_ifp_out,
5460 "inboundInterface",
5461 in_ifname);
5462 json_object_int_add(
5463 json_ifp_out, "iVifI",
5464 s_route->c_oil.oil.mfcc_parent);
5465 json_object_string_add(json_ifp_out,
5466 "outboundInterface",
5467 out_ifname);
5468 json_object_int_add(json_ifp_out, "oVifI",
5469 oif_vif_index);
5470 json_object_int_add(json_ifp_out, "ttl", ttl);
5471 json_object_string_add(json_ifp_out, "upTime",
5472 oif_uptime);
5473 if (!json_oil) {
5474 json_oil = json_object_new_object();
5475 json_object_object_add(json_source,
5476 "oil", json_oil);
d62a17ae 5477 }
7cfc7bcf
DS
5478 json_object_object_add(json_oil, out_ifname,
5479 json_ifp_out);
5480 } else {
d62a17ae 5481 vty_out(vty,
530b12cf
JAG
5482 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
5483 src_str, grp_str, "-", proto, in_ifname,
5484 out_ifname, ttl, oif_uptime);
45b7b092 5485 if (first && !fill) {
7cfc7bcf
DS
5486 src_str[0] = '\0';
5487 grp_str[0] = '\0';
5488 in_ifname[0] = '\0';
5489 first = 0;
5490 }
d62a17ae 5491 }
5492 }
7cfc7bcf
DS
5493
5494 if (!uj && !found_oif) {
5495 vty_out(vty,
530b12cf
JAG
5496 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
5497 src_str, grp_str, "-", proto, in_ifname, "none",
5498 0, "--:--:--");
7cfc7bcf 5499 }
d62a17ae 5500 }
5501
3757f964
DA
5502 if (uj)
5503 vty_json(vty, json);
12e41d03
DL
5504}
5505
c23c1d39 5506DEFPY (show_ip_mroute,
12e41d03 5507 show_ip_mroute_cmd,
c23c1d39 5508 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
12e41d03
DL
5509 SHOW_STR
5510 IP_STR
a957a05b 5511 MROUTE_STR
c3169ac7 5512 VRF_CMD_HELP_STR
c23c1d39
DS
5513 "The Source or Group\n"
5514 "The Group\n"
45b7b092 5515 "Fill in Assumed data\n"
a957a05b 5516 JSON_STR)
12e41d03 5517{
6fff2cc6 5518 pim_sgaddr sg = {0};
c23c1d39
DS
5519 struct pim_instance *pim;
5520 struct vrf *v;
c68ba0d7 5521
c23c1d39
DS
5522 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
5523
5524 if (!v) {
5525 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 5526 return CMD_WARNING;
c23c1d39
DS
5527 }
5528 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 5529
c23c1d39
DS
5530 if (!pim) {
5531 vty_out(vty, "%% Unable to find pim instance\n");
5532 return CMD_WARNING;
5533 }
45b7b092 5534
3a6290bd
DA
5535 if (s_or_g.s_addr != INADDR_ANY) {
5536 if (g.s_addr != INADDR_ANY) {
c23c1d39
DS
5537 sg.src = s_or_g;
5538 sg.grp = g;
5539 } else
5540 sg.grp = s_or_g;
5541 }
5542 show_mroute(pim, vty, &sg, !!fill, !!json);
d62a17ae 5543 return CMD_SUCCESS;
12e41d03
DL
5544}
5545
b283a4ca
DS
5546DEFUN (show_ip_mroute_vrf_all,
5547 show_ip_mroute_vrf_all_cmd,
45b7b092 5548 "show ip mroute vrf all [fill] [json]",
b283a4ca
DS
5549 SHOW_STR
5550 IP_STR
5551 MROUTE_STR
5552 VRF_CMD_HELP_STR
45b7b092 5553 "Fill in Assumed data\n"
b283a4ca
DS
5554 JSON_STR)
5555{
6fff2cc6 5556 pim_sgaddr sg = {0};
9f049418 5557 bool uj = use_json(argc, argv);
45b7b092 5558 int idx = 4;
b283a4ca
DS
5559 struct vrf *vrf;
5560 bool first = true;
45b7b092
DS
5561 bool fill = false;
5562
5563 if (argv_find(argv, argc, "fill", &idx))
5564 fill = true;
b283a4ca
DS
5565
5566 if (uj)
5567 vty_out(vty, "{ ");
a2addae8 5568 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b283a4ca
DS
5569 if (uj) {
5570 if (!first)
5571 vty_out(vty, ", ");
5572 vty_out(vty, " \"%s\": ", vrf->name);
5573 first = false;
5574 } else
5575 vty_out(vty, "VRF: %s\n", vrf->name);
c23c1d39 5576 show_mroute(vrf->info, vty, &sg, fill, uj);
b283a4ca
DS
5577 }
5578 if (uj)
5cef40fc 5579 vty_out(vty, "}\n");
b283a4ca
DS
5580
5581 return CMD_SUCCESS;
5582}
5583
cd333cf9
DS
5584DEFUN (clear_ip_mroute_count,
5585 clear_ip_mroute_count_cmd,
5586 "clear ip mroute [vrf NAME] count",
5587 CLEAR_STR
5588 IP_STR
5589 MROUTE_STR
5590 VRF_CMD_HELP_STR
5591 "Route and packet count data\n")
5592{
5593 int idx = 2;
5594 struct listnode *node;
5595 struct channel_oil *c_oil;
5596 struct static_route *sr;
5597 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5598 struct pim_instance *pim;
5599
5600 if (!vrf)
5601 return CMD_WARNING;
5602
5603 pim = vrf->info;
7315ecda 5604 frr_each(rb_pim_oil, &pim->channel_oil_head, c_oil) {
cd333cf9
DS
5605 if (!c_oil->installed)
5606 continue;
5607
5608 pim_mroute_update_counters(c_oil);
5609 c_oil->cc.origpktcnt = c_oil->cc.pktcnt;
5610 c_oil->cc.origbytecnt = c_oil->cc.bytecnt;
5611 c_oil->cc.origwrong_if = c_oil->cc.wrong_if;
5612 }
5613
5614 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
5615 if (!sr->c_oil.installed)
5616 continue;
5617
5618 pim_mroute_update_counters(&sr->c_oil);
5619
5620 sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt;
5621 sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt;
5622 sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if;
5623 }
5624 return CMD_SUCCESS;
5625}
5626
922e7544 5627static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil,
5628 json_object *json,
5629 struct vty *vty)
12e41d03 5630{
922e7544 5631 char group_str[INET_ADDRSTRLEN];
5632 char source_str[INET_ADDRSTRLEN];
5633 json_object *json_group = NULL;
5634 json_object *json_source = NULL;
12e41d03 5635
922e7544 5636 if (!c_oil->installed)
5637 return;
12e41d03 5638
922e7544 5639 pim_mroute_update_counters(c_oil);
12e41d03 5640
922e7544 5641 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
5642 sizeof(group_str));
5643 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
5644 sizeof(source_str));
58302dc7 5645
922e7544 5646 if (json) {
5647 json_object_object_get_ex(json, group_str, &json_group);
12e41d03 5648
922e7544 5649 if (!json_group) {
5650 json_group = json_object_new_object();
5651 json_object_object_add(json, group_str, json_group);
5652 }
12e41d03 5653
922e7544 5654 json_source = json_object_new_object();
5655 json_object_object_add(json_group, source_str, json_source);
5656 json_object_int_add(json_source, "lastUsed",
5657 c_oil->cc.lastused / 100);
5658 json_object_int_add(json_source, "packets", c_oil->cc.pktcnt);
5659 json_object_int_add(json_source, "bytes", c_oil->cc.bytecnt);
5660 json_object_int_add(json_source, "wrongIf", c_oil->cc.wrong_if);
6250610a 5661
922e7544 5662 } else {
d62a17ae 5663 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5664 source_str, group_str, c_oil->cc.lastused / 100,
cd333cf9
DS
5665 c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
5666 c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
5667 c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
d62a17ae 5668 }
922e7544 5669}
d62a17ae 5670
922e7544 5671static void show_mroute_count(struct pim_instance *pim, struct vty *vty,
5672 bool uj)
5673{
5674 struct listnode *node;
5675 struct channel_oil *c_oil;
5676 struct static_route *sr;
5677 json_object *json = NULL;
6250610a 5678
922e7544 5679 if (uj)
5680 json = json_object_new_object();
5681 else {
5682 vty_out(vty, "\n");
6250610a 5683
922e7544 5684 vty_out(vty,
5685 "Source Group LastUsed Packets Bytes WrongIf \n");
5686 }
4e0bc0f0 5687
922e7544 5688 /* Print PIM and IGMP route counts */
5689 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil)
5690 show_mroute_count_per_channel_oil(c_oil, json, vty);
4e0bc0f0 5691
922e7544 5692 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr))
5693 show_mroute_count_per_channel_oil(&sr->c_oil, json, vty);
5694
3757f964
DA
5695 if (uj)
5696 vty_json(vty, json);
12e41d03
DL
5697}
5698
5699DEFUN (show_ip_mroute_count,
5700 show_ip_mroute_count_cmd,
922e7544 5701 "show ip mroute [vrf NAME] count [json]",
12e41d03
DL
5702 SHOW_STR
5703 IP_STR
5704 MROUTE_STR
c68ba0d7 5705 VRF_CMD_HELP_STR
922e7544 5706 "Route and packet count data\n"
5707 JSON_STR)
12e41d03 5708{
c68ba0d7 5709 int idx = 2;
922e7544 5710 bool uj = use_json(argc, argv);
c68ba0d7
DS
5711 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5712
e691f179
DS
5713 if (!vrf)
5714 return CMD_WARNING;
5715
922e7544 5716 show_mroute_count(vrf->info, vty, uj);
d62a17ae 5717 return CMD_SUCCESS;
12e41d03
DL
5718}
5719
5c3aac90
DS
5720DEFUN (show_ip_mroute_count_vrf_all,
5721 show_ip_mroute_count_vrf_all_cmd,
922e7544 5722 "show ip mroute vrf all count [json]",
5c3aac90
DS
5723 SHOW_STR
5724 IP_STR
5725 MROUTE_STR
5726 VRF_CMD_HELP_STR
922e7544 5727 "Route and packet count data\n"
5728 JSON_STR)
5c3aac90 5729{
9f049418 5730 bool uj = use_json(argc, argv);
5c3aac90
DS
5731 struct vrf *vrf;
5732 bool first = true;
5733
5734 if (uj)
5735 vty_out(vty, "{ ");
a2addae8 5736 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5c3aac90
DS
5737 if (uj) {
5738 if (!first)
5739 vty_out(vty, ", ");
5740 vty_out(vty, " \"%s\": ", vrf->name);
5741 first = false;
5742 } else
5743 vty_out(vty, "VRF: %s\n", vrf->name);
922e7544 5744 show_mroute_count(vrf->info, vty, uj);
5c3aac90
DS
5745 }
5746 if (uj)
5747 vty_out(vty, "}\n");
5748
5749 return CMD_SUCCESS;
5750}
5751
922e7544 5752static void show_mroute_summary(struct pim_instance *pim, struct vty *vty,
5753 json_object *json)
468b6f44
SP
5754{
5755 struct listnode *node;
5756 struct channel_oil *c_oil;
5757 struct static_route *s_route;
5758 uint32_t starg_sw_mroute_cnt = 0;
5759 uint32_t sg_sw_mroute_cnt = 0;
5760 uint32_t starg_hw_mroute_cnt = 0;
5761 uint32_t sg_hw_mroute_cnt = 0;
922e7544 5762 json_object *json_starg = NULL;
5763 json_object *json_sg = NULL;
468b6f44 5764
922e7544 5765 if (!json)
5766 vty_out(vty, "Mroute Type Installed/Total\n");
468b6f44 5767
7315ecda 5768 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
468b6f44
SP
5769 if (!c_oil->installed) {
5770 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5771 starg_sw_mroute_cnt++;
5772 else
5773 sg_sw_mroute_cnt++;
5774 } else {
5775 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5776 starg_hw_mroute_cnt++;
5777 else
5778 sg_hw_mroute_cnt++;
5779 }
5780 }
5781
5782 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5783 if (!s_route->c_oil.installed) {
5784 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5785 starg_sw_mroute_cnt++;
5786 else
5787 sg_sw_mroute_cnt++;
5788 } else {
5789 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5790 starg_hw_mroute_cnt++;
5791 else
5792 sg_hw_mroute_cnt++;
5793 }
5794 }
5795
922e7544 5796 if (!json) {
5797 vty_out(vty, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt,
5798 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
5799 vty_out(vty, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt,
5800 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
5801 vty_out(vty, "------\n");
5802 vty_out(vty, "%-20s %u/%u\n", "Total",
5803 (starg_hw_mroute_cnt + sg_hw_mroute_cnt),
5804 (starg_sw_mroute_cnt + starg_hw_mroute_cnt
5805 + sg_sw_mroute_cnt + sg_hw_mroute_cnt));
5806 } else {
5807 /* (*,G) route details */
5808 json_starg = json_object_new_object();
5809 json_object_object_add(json, "wildcardGroup", json_starg);
5810
5811 json_object_int_add(json_starg, "installed",
5812 starg_hw_mroute_cnt);
5813 json_object_int_add(json_starg, "total",
5814 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
5815
5816 /* (S, G) route details */
5817 json_sg = json_object_new_object();
5818 json_object_object_add(json, "sourceGroup", json_sg);
5819
5820 json_object_int_add(json_sg, "installed", sg_hw_mroute_cnt);
5821 json_object_int_add(json_sg, "total",
5822 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
5823
5824 json_object_int_add(json, "totalNumOfInstalledMroutes",
5825 starg_hw_mroute_cnt + sg_hw_mroute_cnt);
5826 json_object_int_add(json, "totalNumOfMroutes",
5827 starg_sw_mroute_cnt + starg_hw_mroute_cnt
521c5b9d
MS
5828 + sg_sw_mroute_cnt
5829 + sg_hw_mroute_cnt);
922e7544 5830 }
468b6f44
SP
5831}
5832
5833DEFUN (show_ip_mroute_summary,
5834 show_ip_mroute_summary_cmd,
922e7544 5835 "show ip mroute [vrf NAME] summary [json]",
468b6f44
SP
5836 SHOW_STR
5837 IP_STR
5838 MROUTE_STR
5839 VRF_CMD_HELP_STR
922e7544 5840 "Summary of all mroutes\n"
5841 JSON_STR)
468b6f44
SP
5842{
5843 int idx = 2;
922e7544 5844 bool uj = use_json(argc, argv);
468b6f44 5845 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
922e7544 5846 json_object *json = NULL;
5847
5848 if (uj)
5849 json = json_object_new_object();
468b6f44
SP
5850
5851 if (!vrf)
5852 return CMD_WARNING;
5853
922e7544 5854 show_mroute_summary(vrf->info, vty, json);
5855
3757f964
DA
5856 if (uj)
5857 vty_json(vty, json);
468b6f44
SP
5858 return CMD_SUCCESS;
5859}
5860
5861DEFUN (show_ip_mroute_summary_vrf_all,
5862 show_ip_mroute_summary_vrf_all_cmd,
922e7544 5863 "show ip mroute vrf all summary [json]",
468b6f44
SP
5864 SHOW_STR
5865 IP_STR
5866 MROUTE_STR
5867 VRF_CMD_HELP_STR
922e7544 5868 "Summary of all mroutes\n"
5869 JSON_STR)
468b6f44
SP
5870{
5871 struct vrf *vrf;
922e7544 5872 bool uj = use_json(argc, argv);
5873 json_object *json = NULL;
5874 json_object *json_vrf = NULL;
5875
5876 if (uj)
5877 json = json_object_new_object();
468b6f44
SP
5878
5879 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
922e7544 5880 if (uj)
5881 json_vrf = json_object_new_object();
5882 else
5883 vty_out(vty, "VRF: %s\n", vrf->name);
5884
5885 show_mroute_summary(vrf->info, vty, json_vrf);
5886
5887 if (uj)
5888 json_object_object_add(json, vrf->name, json_vrf);
5889 }
5890
3757f964
DA
5891 if (uj)
5892 vty_json(vty, json);
468b6f44
SP
5893
5894 return CMD_SUCCESS;
5895}
5896
12e41d03
DL
5897DEFUN (show_ip_rib,
5898 show_ip_rib_cmd,
20a7e5fd 5899 "show ip rib [vrf NAME] A.B.C.D",
12e41d03
DL
5900 SHOW_STR
5901 IP_STR
5902 RIB_STR
c68ba0d7 5903 VRF_CMD_HELP_STR
12e41d03
DL
5904 "Unicast address\n")
5905{
c68ba0d7
DS
5906 int idx = 2;
5907 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 5908 struct in_addr addr;
5909 const char *addr_str;
5910 struct pim_nexthop nexthop;
5911 char nexthop_addr_str[PREFIX_STRLEN];
5912 int result;
5913
c68ba0d7
DS
5914 if (!vrf)
5915 return CMD_WARNING;
5916
d62a17ae 5917 memset(&nexthop, 0, sizeof(nexthop));
c68ba0d7
DS
5918 argv_find(argv, argc, "A.B.C.D", &idx);
5919 addr_str = argv[idx]->arg;
d62a17ae 5920 result = inet_pton(AF_INET, addr_str, &addr);
5921 if (result <= 0) {
5922 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5923 errno, safe_strerror(errno));
5924 return CMD_WARNING;
5925 }
12e41d03 5926
ade155e1 5927 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
d62a17ae 5928 vty_out(vty,
5929 "Failure querying RIB nexthop for unicast address %s\n",
5930 addr_str);
5931 return CMD_WARNING;
5932 }
12e41d03 5933
d62a17ae 5934 vty_out(vty,
5935 "Address NextHop Interface Metric Preference\n");
12e41d03 5936
d62a17ae 5937 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
5938 nexthop_addr_str, sizeof(nexthop_addr_str));
12e41d03 5939
d62a17ae 5940 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
5941 nexthop.interface ? nexthop.interface->name : "<ifname?>",
5942 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
12e41d03 5943
d62a17ae 5944 return CMD_SUCCESS;
12e41d03
DL
5945}
5946
64c86530 5947static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
12e41d03 5948{
d62a17ae 5949 struct listnode *node;
5950 struct ssmpingd_sock *ss;
5951 time_t now;
12e41d03 5952
d62a17ae 5953 vty_out(vty,
5954 "Source Socket Address Port Uptime Requests\n");
12e41d03 5955
71ad9915 5956 if (!pim->ssmpingd_list)
d62a17ae 5957 return;
12e41d03 5958
d62a17ae 5959 now = pim_time_monotonic_sec();
12e41d03 5960
71ad9915 5961 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
d62a17ae 5962 char source_str[INET_ADDRSTRLEN];
5963 char ss_uptime[10];
5964 struct sockaddr_in bind_addr;
5965 socklen_t len = sizeof(bind_addr);
5966 char bind_addr_str[INET_ADDRSTRLEN];
12e41d03 5967
d62a17ae 5968 pim_inet4_dump("<src?>", ss->source_addr, source_str,
5969 sizeof(source_str));
12e41d03 5970
d62a17ae 5971 if (pim_socket_getsockname(
5972 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
5973 vty_out(vty,
5974 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5975 source_str, ss->sock_fd);
5976 }
12e41d03 5977
d62a17ae 5978 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
5979 sizeof(bind_addr_str));
5980 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
5981 now - ss->creation);
12e41d03 5982
d62a17ae 5983 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
5984 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
5985 ss_uptime, (long long)ss->requests);
5986 }
12e41d03
DL
5987}
5988
5989DEFUN (show_ip_ssmpingd,
5990 show_ip_ssmpingd_cmd,
20a7e5fd 5991 "show ip ssmpingd [vrf NAME]",
12e41d03
DL
5992 SHOW_STR
5993 IP_STR
c68ba0d7
DS
5994 SHOW_SSMPINGD_STR
5995 VRF_CMD_HELP_STR)
12e41d03 5996{
c68ba0d7
DS
5997 int idx = 2;
5998 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5999
6000 if (!vrf)
6001 return CMD_WARNING;
6002
64c86530 6003 show_ssmpingd(vrf->info, vty);
d62a17ae 6004 return CMD_SUCCESS;
12e41d03
DL
6005}
6006
a7b2b1e2
DS
6007DEFUN (ip_pim_spt_switchover_infinity,
6008 ip_pim_spt_switchover_infinity_cmd,
6009 "ip pim spt-switchover infinity-and-beyond",
6010 IP_STR
6011 PIM_STR
6012 "SPT-Switchover\n"
6013 "Never switch to SPT Tree\n")
6014{
fb991ce9 6015 return pim_process_spt_switchover_infinity_cmd(vty);
df94f9a9 6016}
a7b2b1e2 6017
fb991ce9 6018DEFPY (ip_pim_spt_switchover_infinity_plist,
df94f9a9 6019 ip_pim_spt_switchover_infinity_plist_cmd,
fb991ce9 6020 "ip pim spt-switchover infinity-and-beyond prefix-list WORD$plist",
df94f9a9
DS
6021 IP_STR
6022 PIM_STR
6023 "SPT-Switchover\n"
6024 "Never switch to SPT Tree\n"
6025 "Prefix-List to control which groups to switch\n"
6026 "Prefix-List name\n")
6027{
fb991ce9 6028 return pim_process_spt_switchover_prefixlist_cmd(vty, plist);
a7b2b1e2
DS
6029}
6030
6031DEFUN (no_ip_pim_spt_switchover_infinity,
6032 no_ip_pim_spt_switchover_infinity_cmd,
6033 "no ip pim spt-switchover infinity-and-beyond",
6034 NO_STR
6035 IP_STR
6036 PIM_STR
6037 "SPT_Switchover\n"
6038 "Never switch to SPT Tree\n")
6039{
fb991ce9 6040 return pim_process_no_spt_switchover_cmd(vty);
df94f9a9 6041}
a7b2b1e2 6042
df94f9a9
DS
6043DEFUN (no_ip_pim_spt_switchover_infinity_plist,
6044 no_ip_pim_spt_switchover_infinity_plist_cmd,
6045 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6046 NO_STR
6047 IP_STR
6048 PIM_STR
6049 "SPT_Switchover\n"
6050 "Never switch to SPT Tree\n"
6051 "Prefix-List to control which groups to switch\n"
6052 "Prefix-List name\n")
6053{
fb991ce9 6054 return pim_process_no_spt_switchover_cmd(vty);
a7b2b1e2
DS
6055}
6056
f4e74bd0
DS
6057DEFPY (pim_register_accept_list,
6058 pim_register_accept_list_cmd,
6059 "[no] ip pim register-accept-list WORD$word",
6060 NO_STR
6061 IP_STR
6062 PIM_STR
6063 "Only accept registers from a specific source prefix list\n"
6064 "Prefix-List name\n")
6065{
0c949724
SP
6066 const char *vrfname;
6067 char reg_alist_xpath[XPATH_MAXLEN];
6068
5a1a3920
RZ
6069 vrfname = pim_cli_get_vrf_name(vty);
6070 if (vrfname == NULL)
6071 return CMD_WARNING_CONFIG_FAILED;
0c949724
SP
6072
6073 snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
698f4147 6074 FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
0c949724
SP
6075 "frr-routing:ipv4");
6076 strlcat(reg_alist_xpath, "/register-accept-list",
6077 sizeof(reg_alist_xpath));
f4e74bd0
DS
6078
6079 if (no)
0c949724 6080 nb_cli_enqueue_change(vty, reg_alist_xpath,
521c5b9d 6081 NB_OP_DESTROY, NULL);
0c949724
SP
6082 else
6083 nb_cli_enqueue_change(vty, reg_alist_xpath,
521c5b9d 6084 NB_OP_MODIFY, word);
0c949724
SP
6085
6086 return nb_cli_apply_changes(vty, NULL);
f4e74bd0
DS
6087}
6088
c73113ea 6089DEFPY (ip_pim_joinprune_time,
ee1a0718 6090 ip_pim_joinprune_time_cmd,
c73113ea 6091 "ip pim join-prune-interval (1-65535)$jpi",
ee1a0718
DS
6092 IP_STR
6093 "pim multicast routing\n"
6094 "Join Prune Send Interval\n"
6095 "Seconds\n")
6096{
c73113ea 6097 return pim_process_join_prune_cmd(vty, jpi_str);
ee1a0718
DS
6098}
6099
6100DEFUN (no_ip_pim_joinprune_time,
6101 no_ip_pim_joinprune_time_cmd,
11ca3587 6102 "no ip pim join-prune-interval [(1-65535)]",
ee1a0718
DS
6103 NO_STR
6104 IP_STR
6105 "pim multicast routing\n"
6106 "Join Prune Send Interval\n"
11ca3587 6107 IGNORED_IN_NO_STR)
ee1a0718 6108{
c73113ea 6109 return pim_process_no_join_prune_cmd(vty);
ee1a0718
DS
6110}
6111
18ca7de5 6112DEFPY (ip_pim_register_suppress,
191f5695 6113 ip_pim_register_suppress_cmd,
18ca7de5 6114 "ip pim register-suppress-time (1-65535)$rst",
4304f95c
DS
6115 IP_STR
6116 "pim multicast routing\n"
191f5695
DS
6117 "Register Suppress Timer\n"
6118 "Seconds\n")
4304f95c 6119{
18ca7de5 6120 return pim_process_register_suppress_cmd(vty, rst_str);
4304f95c
DS
6121}
6122
191f5695
DS
6123DEFUN (no_ip_pim_register_suppress,
6124 no_ip_pim_register_suppress_cmd,
11ca3587 6125 "no ip pim register-suppress-time [(1-65535)]",
4304f95c
DS
6126 NO_STR
6127 IP_STR
6128 "pim multicast routing\n"
191f5695 6129 "Register Suppress Timer\n"
11ca3587 6130 IGNORED_IN_NO_STR)
4304f95c 6131{
18ca7de5 6132 return pim_process_no_register_suppress_cmd(vty);
4304f95c
DS
6133}
6134
2322b991 6135DEFPY (ip_pim_rp_keep_alive,
cc14df13 6136 ip_pim_rp_keep_alive_cmd,
2322b991 6137 "ip pim rp keep-alive-timer (1-65535)$kat",
cc14df13
DS
6138 IP_STR
6139 "pim multicast routing\n"
6140 "Rendevous Point\n"
6141 "Keep alive Timer\n"
6142 "Seconds\n")
6143{
2322b991 6144 return pim_process_rp_kat_cmd(vty, kat_str);
cc14df13
DS
6145}
6146
6147DEFUN (no_ip_pim_rp_keep_alive,
6148 no_ip_pim_rp_keep_alive_cmd,
11ca3587 6149 "no ip pim rp keep-alive-timer [(1-65535)]",
cc14df13
DS
6150 NO_STR
6151 IP_STR
6152 "pim multicast routing\n"
6153 "Rendevous Point\n"
6154 "Keep alive Timer\n"
11ca3587 6155 IGNORED_IN_NO_STR)
cc14df13 6156{
2322b991 6157 return pim_process_no_rp_kat_cmd(vty);
cc14df13
DS
6158}
6159
28e32366 6160DEFPY (ip_pim_keep_alive,
191f5695 6161 ip_pim_keep_alive_cmd,
28e32366 6162 "ip pim keep-alive-timer (1-65535)$kat",
01408ede
DS
6163 IP_STR
6164 "pim multicast routing\n"
01408ede
DS
6165 "Keep alive Timer\n"
6166 "Seconds\n")
6167{
28e32366 6168 return pim_process_keepalivetimer_cmd(vty, kat_str);
01408ede
DS
6169}
6170
191f5695
DS
6171DEFUN (no_ip_pim_keep_alive,
6172 no_ip_pim_keep_alive_cmd,
11ca3587 6173 "no ip pim keep-alive-timer [(1-65535)]",
01408ede
DS
6174 NO_STR
6175 IP_STR
6176 "pim multicast routing\n"
01408ede 6177 "Keep alive Timer\n"
11ca3587 6178 IGNORED_IN_NO_STR)
01408ede 6179{
28e32366 6180 return pim_process_no_keepalivetimer_cmd(vty);
01408ede
DS
6181}
6182
0da72f1f 6183DEFPY (ip_pim_packets,
8e4c9ef3 6184 ip_pim_packets_cmd,
11ca3587 6185 "ip pim packets (1-255)",
8e4c9ef3
DS
6186 IP_STR
6187 "pim multicast routing\n"
a957a05b
DS
6188 "packets to process at one time per fd\n"
6189 "Number of packets\n")
8e4c9ef3 6190{
0da72f1f 6191 return pim_process_pim_packet_cmd(vty, packets_str);
8e4c9ef3
DS
6192}
6193
6194DEFUN (no_ip_pim_packets,
6195 no_ip_pim_packets_cmd,
11ca3587 6196 "no ip pim packets [(1-255)]",
8e4c9ef3
DS
6197 NO_STR
6198 IP_STR
6199 "pim multicast routing\n"
a957a05b 6200 "packets to process at one time per fd\n"
11ca3587 6201 IGNORED_IN_NO_STR)
8e4c9ef3 6202{
0da72f1f 6203 return pim_process_no_pim_packet_cmd(vty);
8e4c9ef3
DS
6204}
6205
339f7695 6206DEFPY (igmp_group_watermark,
6207 igmp_group_watermark_cmd,
11ca3587 6208 "ip igmp watermark-warn (1-65535)$limit",
339f7695 6209 IP_STR
6210 IGMP_STR
6211 "Configure group limit for watermark warning\n"
6212 "Group count to generate watermark warning\n")
6213{
6214 PIM_DECLVAR_CONTEXT(vrf, pim);
6215 pim->igmp_watermark_limit = limit;
6216
6217 return CMD_SUCCESS;
6218}
6219
6220DEFPY (no_igmp_group_watermark,
6221 no_igmp_group_watermark_cmd,
11ca3587 6222 "no ip igmp watermark-warn [(1-65535)$limit]",
339f7695 6223 NO_STR
6224 IP_STR
6225 IGMP_STR
6226 "Unconfigure group limit for watermark warning\n"
11ca3587 6227 IGNORED_IN_NO_STR)
339f7695 6228{
6229 PIM_DECLVAR_CONTEXT(vrf, pim);
6230 pim->igmp_watermark_limit = 0;
6231
6232 return CMD_SUCCESS;
6233}
6234
71bbe73d
DS
6235DEFUN (ip_pim_v6_secondary,
6236 ip_pim_v6_secondary_cmd,
6237 "ip pim send-v6-secondary",
6238 IP_STR
6239 "pim multicast routing\n"
6240 "Send v6 secondary addresses\n")
6241{
db9cca95
SP
6242 const char *vrfname;
6243 char send_v6_secondary_xpath[XPATH_MAXLEN];
71bbe73d 6244
5a1a3920
RZ
6245 vrfname = pim_cli_get_vrf_name(vty);
6246 if (vrfname == NULL)
6247 return CMD_WARNING_CONFIG_FAILED;
db9cca95
SP
6248
6249 snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
698f4147 6250 FRR_PIM_VRF_XPATH,
db9cca95
SP
6251 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
6252 strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
6253 sizeof(send_v6_secondary_xpath));
6254
6255 nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
521c5b9d 6256 "true");
db9cca95
SP
6257
6258 return nb_cli_apply_changes(vty, NULL);
71bbe73d
DS
6259}
6260
6261DEFUN (no_ip_pim_v6_secondary,
6262 no_ip_pim_v6_secondary_cmd,
6263 "no ip pim send-v6-secondary",
6264 NO_STR
6265 IP_STR
6266 "pim multicast routing\n"
6267 "Send v6 secondary addresses\n")
6268{
db9cca95
SP
6269 const char *vrfname;
6270 char send_v6_secondary_xpath[XPATH_MAXLEN];
71bbe73d 6271
5a1a3920
RZ
6272 vrfname = pim_cli_get_vrf_name(vty);
6273 if (vrfname == NULL)
6274 return CMD_WARNING_CONFIG_FAILED;
db9cca95
SP
6275
6276 snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
698f4147 6277 FRR_PIM_VRF_XPATH,
db9cca95
SP
6278 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
6279 strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
6280 sizeof(send_v6_secondary_xpath));
6281
6282 nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
521c5b9d 6283 "false");
db9cca95
SP
6284
6285 return nb_cli_apply_changes(vty, NULL);
71bbe73d
DS
6286}
6287
13ddf7cf 6288DEFPY (ip_pim_rp,
981d6c7a 6289 ip_pim_rp_cmd,
13ddf7cf 6290 "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
981d6c7a 6291 IP_STR
9b34069d
QY
6292 "pim multicast routing\n"
6293 "Rendevous Point\n"
a957a05b
DS
6294 "ip address of RP\n"
6295 "Group Address range to cover\n")
981d6c7a 6296{
13ddf7cf 6297 const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
7003f636 6298
13ddf7cf 6299 return pim_process_rp_cmd(vty, rp_str, group_str);
dfe43e25
DW
6300}
6301
f39f3497 6302DEFPY (ip_pim_rp_prefix_list,
dfe43e25 6303 ip_pim_rp_prefix_list_cmd,
f39f3497 6304 "ip pim rp A.B.C.D$rp prefix-list WORD$plist",
dfe43e25
DW
6305 IP_STR
6306 "pim multicast routing\n"
f39f3497 6307 "Rendezvous Point\n"
dfe43e25
DW
6308 "ip address of RP\n"
6309 "group prefix-list filter\n"
6310 "Name of a prefix-list\n")
6311{
f39f3497 6312 return pim_process_rp_plist_cmd(vty, rp_str, plist);
981d6c7a
DS
6313}
6314
13ddf7cf 6315DEFPY (no_ip_pim_rp,
981d6c7a 6316 no_ip_pim_rp_cmd,
13ddf7cf 6317 "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
981d6c7a
DS
6318 NO_STR
6319 IP_STR
9b34069d
QY
6320 "pim multicast routing\n"
6321 "Rendevous Point\n"
a957a05b
DS
6322 "ip address of RP\n"
6323 "Group Address range to cover\n")
981d6c7a 6324{
13ddf7cf 6325 const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
7003f636 6326
13ddf7cf 6327 return pim_process_no_rp_cmd(vty, rp_str, group_str);
dfe43e25
DW
6328}
6329
f39f3497 6330DEFPY (no_ip_pim_rp_prefix_list,
dfe43e25 6331 no_ip_pim_rp_prefix_list_cmd,
f39f3497 6332 "no ip pim rp A.B.C.D$rp prefix-list WORD$plist",
dfe43e25
DW
6333 NO_STR
6334 IP_STR
6335 "pim multicast routing\n"
f39f3497 6336 "Rendezvous Point\n"
dfe43e25
DW
6337 "ip address of RP\n"
6338 "group prefix-list filter\n"
6339 "Name of a prefix-list\n")
6340{
f39f3497 6341 return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
15a5dafe 6342}
6343
6344DEFUN (ip_pim_ssm_prefix_list,
6345 ip_pim_ssm_prefix_list_cmd,
6346 "ip pim ssm prefix-list WORD",
6347 IP_STR
6348 "pim multicast routing\n"
6349 "Source Specific Multicast\n"
6350 "group range prefix-list filter\n"
6351 "Name of a prefix-list\n")
6352{
f206085e
SP
6353 const char *vrfname;
6354 char ssm_plist_xpath[XPATH_MAXLEN];
6355
5a1a3920
RZ
6356 vrfname = pim_cli_get_vrf_name(vty);
6357 if (vrfname == NULL)
6358 return CMD_WARNING_CONFIG_FAILED;
f206085e 6359
698f4147 6360 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_VRF_XPATH,
f206085e
SP
6361 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
6362 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
6363
6364 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg);
6365
6366 return nb_cli_apply_changes(vty, NULL);
15a5dafe 6367}
6368
6369DEFUN (no_ip_pim_ssm_prefix_list,
6370 no_ip_pim_ssm_prefix_list_cmd,
6371 "no ip pim ssm prefix-list",
6372 NO_STR
6373 IP_STR
6374 "pim multicast routing\n"
6375 "Source Specific Multicast\n"
6376 "group range prefix-list filter\n")
6377{
f206085e
SP
6378 const char *vrfname;
6379 char ssm_plist_xpath[XPATH_MAXLEN];
6380
5a1a3920
RZ
6381 vrfname = pim_cli_get_vrf_name(vty);
6382 if (vrfname == NULL)
6383 return CMD_WARNING_CONFIG_FAILED;
f206085e
SP
6384
6385 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
698f4147 6386 FRR_PIM_VRF_XPATH,
f206085e
SP
6387 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
6388 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
6389
6390 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
6391
6392 return nb_cli_apply_changes(vty, NULL);
15a5dafe 6393}
6394
6395DEFUN (no_ip_pim_ssm_prefix_list_name,
6396 no_ip_pim_ssm_prefix_list_name_cmd,
6397 "no ip pim ssm prefix-list WORD",
6398 NO_STR
6399 IP_STR
6400 "pim multicast routing\n"
6401 "Source Specific Multicast\n"
6402 "group range prefix-list filter\n"
6403 "Name of a prefix-list\n")
6404{
f206085e
SP
6405 const char *vrfname;
6406 const struct lyd_node *ssm_plist_dnode;
6407 char ssm_plist_xpath[XPATH_MAXLEN];
6408 const char *ssm_plist_name;
15a5dafe 6409
5a1a3920
RZ
6410 vrfname = pim_cli_get_vrf_name(vty);
6411 if (vrfname == NULL)
6412 return CMD_WARNING_CONFIG_FAILED;
f206085e
SP
6413
6414 snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
698f4147 6415 FRR_PIM_VRF_XPATH,
f206085e
SP
6416 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
6417 strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
6418 ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
521c5b9d 6419 ssm_plist_xpath);
f206085e
SP
6420
6421 if (!ssm_plist_dnode) {
6422 vty_out(vty,
6423 "%% pim ssm prefix-list %s doesn't exist\n",
6424 argv[5]->arg);
6425 return CMD_WARNING_CONFIG_FAILED;
6426 }
6427
6428 ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
6429
6430 if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) {
6431 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY,
521c5b9d 6432 NULL);
f206085e
SP
6433
6434 return nb_cli_apply_changes(vty, NULL);
6435 }
15a5dafe 6436
9643e2c7 6437 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
15a5dafe 6438
d62a17ae 6439 return CMD_WARNING_CONFIG_FAILED;
15a5dafe 6440}
6441
64c86530 6442static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
088f1098 6443 struct vty *vty, bool uj)
15a5dafe 6444{
c68ba0d7 6445 struct pim_ssm *ssm = pim->ssm_info;
d62a17ae 6446 const char *range_str =
6447 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
15a5dafe 6448
d62a17ae 6449 if (uj) {
6450 json_object *json;
6451 json = json_object_new_object();
6452 json_object_string_add(json, "ssmGroups", range_str);
3757f964 6453 vty_json(vty, json);
d62a17ae 6454 } else
6455 vty_out(vty, "SSM group range : %s\n", range_str);
15a5dafe 6456}
6457
6458DEFUN (show_ip_pim_ssm_range,
6459 show_ip_pim_ssm_range_cmd,
20a7e5fd 6460 "show ip pim [vrf NAME] group-type [json]",
15a5dafe 6461 SHOW_STR
6462 IP_STR
6463 PIM_STR
c68ba0d7 6464 VRF_CMD_HELP_STR
15a5dafe 6465 "PIM group type\n"
f5da2cc2 6466 JSON_STR)
15a5dafe 6467{
c68ba0d7
DS
6468 int idx = 2;
6469 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 6470 bool uj = use_json(argc, argv);
c68ba0d7
DS
6471
6472 if (!vrf)
6473 return CMD_WARNING;
6474
64c86530 6475 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
15a5dafe 6476
d62a17ae 6477 return CMD_SUCCESS;
15a5dafe 6478}
6479
64c86530 6480static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
088f1098 6481 struct vty *vty, bool uj,
d62a17ae 6482 const char *group)
15a5dafe 6483{
d62a17ae 6484 struct in_addr group_addr;
6485 const char *type_str;
6486 int result;
15a5dafe 6487
d62a17ae 6488 result = inet_pton(AF_INET, group, &group_addr);
6489 if (result <= 0)
6490 type_str = "invalid";
6491 else {
6492 if (pim_is_group_224_4(group_addr))
c68ba0d7
DS
6493 type_str =
6494 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
d62a17ae 6495 else
6496 type_str = "not-multicast";
6497 }
15a5dafe 6498
d62a17ae 6499 if (uj) {
6500 json_object *json;
6501 json = json_object_new_object();
6502 json_object_string_add(json, "groupType", type_str);
3757f964 6503 vty_json(vty, json);
d62a17ae 6504 } else
6505 vty_out(vty, "Group type : %s\n", type_str);
15a5dafe 6506}
6507
6508DEFUN (show_ip_pim_group_type,
6509 show_ip_pim_group_type_cmd,
20a7e5fd 6510 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
15a5dafe 6511 SHOW_STR
6512 IP_STR
6513 PIM_STR
c68ba0d7 6514 VRF_CMD_HELP_STR
15a5dafe 6515 "multicast group type\n"
6516 "group address\n"
f5da2cc2 6517 JSON_STR)
15a5dafe 6518{
c68ba0d7
DS
6519 int idx = 2;
6520 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 6521 bool uj = use_json(argc, argv);
c68ba0d7
DS
6522
6523 if (!vrf)
6524 return CMD_WARNING;
6525
6526 argv_find(argv, argc, "A.B.C.D", &idx);
64c86530 6527 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
15a5dafe 6528
d62a17ae 6529 return CMD_SUCCESS;
15a5dafe 6530}
6531
256392eb 6532DEFUN (show_ip_pim_bsr,
6533 show_ip_pim_bsr_cmd,
6534 "show ip pim bsr [json]",
6535 SHOW_STR
6536 IP_STR
6537 PIM_STR
6538 "boot-strap router information\n"
6539 JSON_STR)
6540{
6541 int idx = 2;
6542 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6543 bool uj = use_json(argc, argv);
6544
6545 if (!vrf)
6546 return CMD_WARNING;
6547
6548 pim_show_bsr(vrf->info, vty, uj);
6549
6550 return CMD_SUCCESS;
6551}
6552
12e41d03
DL
6553DEFUN (ip_ssmpingd,
6554 ip_ssmpingd_cmd,
6555 "ip ssmpingd [A.B.C.D]",
6556 IP_STR
6557 CONF_SSMPINGD_STR
6558 "Source address\n")
6559{
d62a17ae 6560 int idx_ipv4 = 2;
d62a17ae 6561 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
f206085e
SP
6562 const char *vrfname;
6563 char ssmpingd_ip_xpath[XPATH_MAXLEN];
12e41d03 6564
5a1a3920
RZ
6565 vrfname = pim_cli_get_vrf_name(vty);
6566 if (vrfname == NULL)
6567 return CMD_WARNING_CONFIG_FAILED;
12e41d03 6568
f206085e 6569 snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
698f4147 6570 FRR_PIM_VRF_XPATH,
f206085e
SP
6571 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
6572 strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
6573 sizeof(ssmpingd_ip_xpath));
12e41d03 6574
f206085e 6575 nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_CREATE,
521c5b9d 6576 source_str);
12e41d03 6577
f206085e 6578 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
6579}
6580
6581DEFUN (no_ip_ssmpingd,
6582 no_ip_ssmpingd_cmd,
6583 "no ip ssmpingd [A.B.C.D]",
6584 NO_STR
6585 IP_STR
6586 CONF_SSMPINGD_STR
6587 "Source address\n")
6588{
f206085e 6589 const char *vrfname;
d62a17ae 6590 int idx_ipv4 = 3;
d62a17ae 6591 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
f206085e 6592 char ssmpingd_ip_xpath[XPATH_MAXLEN];
12e41d03 6593
5a1a3920
RZ
6594 vrfname = pim_cli_get_vrf_name(vty);
6595 if (vrfname == NULL)
6596 return CMD_WARNING_CONFIG_FAILED;
12e41d03 6597
f206085e 6598 snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
698f4147 6599 FRR_PIM_VRF_XPATH,
f206085e
SP
6600 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
6601 strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
6602 sizeof(ssmpingd_ip_xpath));
12e41d03 6603
f206085e 6604 nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_DESTROY,
521c5b9d 6605 source_str);
f206085e
SP
6606
6607 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
6608}
6609
cba44481
CS
6610DEFUN (ip_pim_ecmp,
6611 ip_pim_ecmp_cmd,
6612 "ip pim ecmp",
6613 IP_STR
6614 "pim multicast routing\n"
6615 "Enable PIM ECMP \n")
6616{
49c6b2aa
SP
6617 const char *vrfname;
6618 char ecmp_xpath[XPATH_MAXLEN];
cba44481 6619
5a1a3920
RZ
6620 vrfname = pim_cli_get_vrf_name(vty);
6621 if (vrfname == NULL)
6622 return CMD_WARNING_CONFIG_FAILED;
49c6b2aa 6623
698f4147 6624 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
6625 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
6626 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
6627
6628 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
6629 return nb_cli_apply_changes(vty, NULL);
cba44481
CS
6630}
6631
6632DEFUN (no_ip_pim_ecmp,
6633 no_ip_pim_ecmp_cmd,
6634 "no ip pim ecmp",
6635 NO_STR
6636 IP_STR
6637 "pim multicast routing\n"
6638 "Disable PIM ECMP \n")
6639{
49c6b2aa
SP
6640 const char *vrfname;
6641 char ecmp_xpath[XPATH_MAXLEN];
cba44481 6642
5a1a3920
RZ
6643 vrfname = pim_cli_get_vrf_name(vty);
6644 if (vrfname == NULL)
6645 return CMD_WARNING_CONFIG_FAILED;
49c6b2aa 6646
698f4147 6647 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
6648 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
6649 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
6650
6651 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false");
6652
6653 return nb_cli_apply_changes(vty, NULL);
cba44481
CS
6654}
6655
6656DEFUN (ip_pim_ecmp_rebalance,
6657 ip_pim_ecmp_rebalance_cmd,
6658 "ip pim ecmp rebalance",
6659 IP_STR
6660 "pim multicast routing\n"
6661 "Enable PIM ECMP \n"
6662 "Enable PIM ECMP Rebalance\n")
6663{
49c6b2aa
SP
6664 const char *vrfname;
6665 char ecmp_xpath[XPATH_MAXLEN];
6666 char ecmp_rebalance_xpath[XPATH_MAXLEN];
cba44481 6667
5a1a3920
RZ
6668 vrfname = pim_cli_get_vrf_name(vty);
6669 if (vrfname == NULL)
6670 return CMD_WARNING_CONFIG_FAILED;
49c6b2aa 6671
698f4147 6672 snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
6673 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
6674 strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
6675 snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
698f4147 6676 FRR_PIM_VRF_XPATH,
6677 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
6678 strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
6679 sizeof(ecmp_rebalance_xpath));
6680
6681 nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
6682 nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true");
6683
6684 return nb_cli_apply_changes(vty, NULL);
cba44481
CS
6685}
6686
6687DEFUN (no_ip_pim_ecmp_rebalance,
6688 no_ip_pim_ecmp_rebalance_cmd,
6689 "no ip pim ecmp rebalance",
6690 NO_STR
6691 IP_STR
6692 "pim multicast routing\n"
6693 "Disable PIM ECMP \n"
6694 "Disable PIM ECMP Rebalance\n")
6695{
49c6b2aa
SP
6696 const char *vrfname;
6697 char ecmp_rebalance_xpath[XPATH_MAXLEN];
cba44481 6698
5a1a3920
RZ
6699 vrfname = pim_cli_get_vrf_name(vty);
6700 if (vrfname == NULL)
6701 return CMD_WARNING_CONFIG_FAILED;
12e41d03 6702
49c6b2aa 6703 snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
698f4147 6704 FRR_PIM_VRF_XPATH,
6705 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
49c6b2aa
SP
6706 strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
6707 sizeof(ecmp_rebalance_xpath));
12e41d03 6708
49c6b2aa
SP
6709 nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false");
6710
6711 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
6712}
6713
21419f59
DS
6714DEFUN (interface_ip_igmp,
6715 interface_ip_igmp_cmd,
6716 "ip igmp",
6717 IP_STR
6718 IFACE_IGMP_STR)
6719{
3051f443 6720 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
21419f59 6721
3051f443 6722 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6723 "frr-routing:ipv4");
21419f59
DS
6724}
6725
12e41d03
DL
6726DEFUN (interface_no_ip_igmp,
6727 interface_no_ip_igmp_cmd,
6728 "no ip igmp",
6729 NO_STR
6730 IP_STR
6731 IFACE_IGMP_STR)
6732{
b0475d5a 6733 const struct lyd_node *pim_enable_dnode;
d7073b21 6734 char pim_if_xpath[XPATH_MAXLEN];
12e41d03 6735
d7073b21
QY
6736 int printed =
6737 snprintf(pim_if_xpath, sizeof(pim_if_xpath),
6738 "%s/frr-pim:pim/address-family[address-family='%s']",
6739 VTY_CURR_XPATH, "frr-routing:ipv4");
6740
6741 if (printed >= (int)(sizeof(pim_if_xpath))) {
6742 vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
6743 XPATH_MAXLEN);
6744 return CMD_WARNING_CONFIG_FAILED;
6745 }
12e41d03 6746
3bb513c3 6747 pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
698f4147 6748 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
6749 "frr-routing:ipv4");
b0475d5a
SP
6750 if (!pim_enable_dnode) {
6751 nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY, NULL);
6752 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6753 } else {
6754 if (!yang_dnode_get_bool(pim_enable_dnode, ".")) {
6755 nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY,
5c90f569 6756 NULL);
b0475d5a
SP
6757 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6758 } else
3051f443 6759 nb_cli_enqueue_change(vty, "./enable",
5c90f569 6760 NB_OP_MODIFY, "false");
d62a17ae 6761 }
12e41d03 6762
3051f443 6763 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6764 "frr-routing:ipv4");
12e41d03
DL
6765}
6766
6767DEFUN (interface_ip_igmp_join,
6768 interface_ip_igmp_join_cmd,
771ce8ad 6769 "ip igmp join A.B.C.D [A.B.C.D]",
12e41d03
DL
6770 IP_STR
6771 IFACE_IGMP_STR
6772 "IGMP join multicast group\n"
6773 "Multicast group address\n"
6774 "Source address\n")
6775{
b0475d5a
SP
6776 int idx_group = 3;
6777 int idx_source = 4;
d62a17ae 6778 const char *source_str;
b0475d5a 6779 char xpath[XPATH_MAXLEN];
d62a17ae 6780
b0475d5a
SP
6781 if (argc == 5) {
6782 source_str = argv[idx_source]->arg;
d62a17ae 6783
b0475d5a
SP
6784 if (strcmp(source_str, "0.0.0.0") == 0) {
6785 vty_out(vty, "Bad source address %s\n",
521c5b9d 6786 argv[idx_source]->arg);
771ce8ad
LM
6787 return CMD_WARNING_CONFIG_FAILED;
6788 }
b0475d5a
SP
6789 } else
6790 source_str = "0.0.0.0";
d62a17ae 6791
3051f443 6792 snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
521c5b9d 6793 "frr-routing:ipv4", argv[idx_group]->arg, source_str);
d62a17ae 6794
b0475d5a
SP
6795 nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
6796
6797 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
6798}
6799
6800DEFUN (interface_no_ip_igmp_join,
6801 interface_no_ip_igmp_join_cmd,
771ce8ad 6802 "no ip igmp join A.B.C.D [A.B.C.D]",
12e41d03
DL
6803 NO_STR
6804 IP_STR
6805 IFACE_IGMP_STR
6806 "IGMP join multicast group\n"
6807 "Multicast group address\n"
6808 "Source address\n")
6809{
b0475d5a
SP
6810 int idx_group = 4;
6811 int idx_source = 5;
d62a17ae 6812 const char *source_str;
b0475d5a 6813 char xpath[XPATH_MAXLEN];
d62a17ae 6814
b0475d5a
SP
6815 if (argc == 6) {
6816 source_str = argv[idx_source]->arg;
d62a17ae 6817
b0475d5a
SP
6818 if (strcmp(source_str, "0.0.0.0") == 0) {
6819 vty_out(vty, "Bad source address %s\n",
521c5b9d 6820 argv[idx_source]->arg);
771ce8ad
LM
6821 return CMD_WARNING_CONFIG_FAILED;
6822 }
b0475d5a
SP
6823 } else
6824 source_str = "0.0.0.0";
d62a17ae 6825
3051f443 6826 snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
521c5b9d 6827 "frr-routing:ipv4", argv[idx_group]->arg, source_str);
d62a17ae 6828
b0475d5a 6829 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
d62a17ae 6830
b0475d5a 6831 return nb_cli_apply_changes(vty, NULL);
12e41d03
DL
6832}
6833
12e41d03
DL
6834DEFUN (interface_ip_igmp_query_interval,
6835 interface_ip_igmp_query_interval_cmd,
11ca3587 6836 "ip igmp query-interval (1-65535)",
12e41d03
DL
6837 IP_STR
6838 IFACE_IGMP_STR
6839 IFACE_IGMP_QUERY_INTERVAL_STR
6840 "Query interval in seconds\n")
6841{
b0475d5a 6842 const struct lyd_node *pim_enable_dnode;
d62a17ae 6843
3bb513c3
CH
6844 pim_enable_dnode =
6845 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 6846 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
6847 "frr-routing:ipv4");
b0475d5a 6848 if (!pim_enable_dnode) {
698f4147 6849 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 6850 "true");
b0475d5a
SP
6851 } else {
6852 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 6853 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 6854 NB_OP_MODIFY, "true");
d62a17ae 6855 }
6856
b0475d5a 6857 nb_cli_enqueue_change(vty, "./query-interval", NB_OP_MODIFY,
521c5b9d 6858 argv[3]->arg);
d62a17ae 6859
3051f443 6860 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6861 "frr-routing:ipv4");
12e41d03
DL
6862}
6863
6864DEFUN (interface_no_ip_igmp_query_interval,
6865 interface_no_ip_igmp_query_interval_cmd,
11ca3587 6866 "no ip igmp query-interval [(1-65535)]",
12e41d03
DL
6867 NO_STR
6868 IP_STR
6869 IFACE_IGMP_STR
11ca3587
CH
6870 IFACE_IGMP_QUERY_INTERVAL_STR
6871 IGNORED_IN_NO_STR)
12e41d03 6872{
11ca3587 6873 nb_cli_enqueue_change(vty, "./query-interval", NB_OP_DESTROY, NULL);
12e41d03 6874
3051f443 6875 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6876 "frr-routing:ipv4");
12e41d03
DL
6877}
6878
b05b72e8
DW
6879DEFUN (interface_ip_igmp_version,
6880 interface_ip_igmp_version_cmd,
72e81cf4 6881 "ip igmp version (2-3)",
b05b72e8
DW
6882 IP_STR
6883 IFACE_IGMP_STR
6884 "IGMP version\n"
6885 "IGMP version number\n")
6886{
3051f443 6887 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 6888 "true");
3051f443 6889 nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_MODIFY,
6890 argv[3]->arg);
d62a17ae 6891
3051f443 6892 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6893 "frr-routing:ipv4");
b05b72e8
DW
6894}
6895
6896DEFUN (interface_no_ip_igmp_version,
6897 interface_no_ip_igmp_version_cmd,
72e81cf4 6898 "no ip igmp version (2-3)",
b05b72e8
DW
6899 NO_STR
6900 IP_STR
6901 IFACE_IGMP_STR
6902 "IGMP version\n"
6903 "IGMP version number\n")
6904{
3051f443 6905 nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_DESTROY, NULL);
b05b72e8 6906
3051f443 6907 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6908 "frr-routing:ipv4");
b05b72e8
DW
6909}
6910
12e41d03
DL
6911DEFUN (interface_ip_igmp_query_max_response_time,
6912 interface_ip_igmp_query_max_response_time_cmd,
11ca3587 6913 "ip igmp query-max-response-time (1-65535)",
12e41d03
DL
6914 IP_STR
6915 IFACE_IGMP_STR
6916 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
58344b65 6917 "Query response value in deci-seconds\n")
12e41d03 6918{
b0475d5a 6919 const struct lyd_node *pim_enable_dnode;
12e41d03 6920
3bb513c3
CH
6921 pim_enable_dnode =
6922 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 6923 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
6924 "frr-routing:ipv4");
12e41d03 6925
b0475d5a 6926 if (!pim_enable_dnode) {
3051f443 6927 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 6928 "true");
b0475d5a
SP
6929 } else {
6930 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 6931 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 6932 NB_OP_MODIFY, "true");
d62a17ae 6933 }
12e41d03 6934
b0475d5a 6935 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
521c5b9d 6936 argv[3]->arg);
12e41d03 6937
3051f443 6938 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6939 "frr-routing:ipv4");
12e41d03
DL
6940}
6941
6942DEFUN (interface_no_ip_igmp_query_max_response_time,
6943 interface_no_ip_igmp_query_max_response_time_cmd,
11ca3587 6944 "no ip igmp query-max-response-time [(1-65535)]",
12e41d03
DL
6945 NO_STR
6946 IP_STR
6947 IFACE_IGMP_STR
a957a05b 6948 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
11ca3587 6949 IGNORED_IN_NO_STR)
12e41d03 6950{
11ca3587
CH
6951 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
6952 NULL);
3051f443 6953 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6954 "frr-routing:ipv4");
12e41d03
DL
6955}
6956
58344b65
DS
6957DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
6958 interface_ip_igmp_query_max_response_time_dsec_cmd,
11ca3587 6959 "ip igmp query-max-response-time-dsec (1-65535)",
58344b65
DS
6960 IP_STR
6961 IFACE_IGMP_STR
6962 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6963 "Query response value in deciseconds\n")
12e41d03 6964{
b0475d5a 6965 const struct lyd_node *pim_enable_dnode;
d62a17ae 6966
3bb513c3
CH
6967 pim_enable_dnode =
6968 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 6969 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
6970 "frr-routing:ipv4");
b0475d5a 6971 if (!pim_enable_dnode) {
3051f443 6972 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 6973 "true");
b0475d5a
SP
6974 } else {
6975 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 6976 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 6977 NB_OP_MODIFY, "true");
d62a17ae 6978 }
12e41d03 6979
b0475d5a 6980 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
521c5b9d 6981 argv[3]->arg);
12e41d03 6982
3051f443 6983 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
6984 "frr-routing:ipv4");
12e41d03
DL
6985}
6986
58344b65
DS
6987DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
6988 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
11ca3587 6989 "no ip igmp query-max-response-time-dsec [(1-65535)]",
58344b65
DS
6990 NO_STR
6991 IP_STR
6992 IFACE_IGMP_STR
11ca3587
CH
6993 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6994 IGNORED_IN_NO_STR)
12e41d03 6995{
11ca3587
CH
6996 nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
6997 NULL);
12e41d03 6998
3051f443 6999 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7000 "frr-routing:ipv4");
12e41d03
DL
7001}
7002
59115451
SP
7003DEFUN (interface_ip_igmp_last_member_query_count,
7004 interface_ip_igmp_last_member_query_count_cmd,
11ca3587 7005 "ip igmp last-member-query-count (1-255)",
59115451
SP
7006 IP_STR
7007 IFACE_IGMP_STR
7008 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7009 "Last member query count\n")
7010{
b0475d5a 7011 const struct lyd_node *pim_enable_dnode;
59115451 7012
3bb513c3
CH
7013 pim_enable_dnode =
7014 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7015 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7016 "frr-routing:ipv4");
b0475d5a 7017 if (!pim_enable_dnode) {
3051f443 7018 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7019 "true");
b0475d5a
SP
7020 } else {
7021 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 7022 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 7023 NB_OP_MODIFY, "true");
59115451
SP
7024 }
7025
b0475d5a 7026 nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_MODIFY,
521c5b9d 7027 argv[3]->arg);
59115451 7028
3051f443 7029 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7030 "frr-routing:ipv4");
59115451
SP
7031}
7032
7033DEFUN (interface_no_ip_igmp_last_member_query_count,
7034 interface_no_ip_igmp_last_member_query_count_cmd,
11ca3587 7035 "no ip igmp last-member-query-count [(1-255)]",
59115451
SP
7036 NO_STR
7037 IP_STR
7038 IFACE_IGMP_STR
bb9ff200 7039 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
11ca3587 7040 IGNORED_IN_NO_STR)
59115451 7041{
11ca3587
CH
7042 nb_cli_enqueue_change(vty, "./robustness-variable", NB_OP_DESTROY,
7043 NULL);
59115451 7044
3051f443 7045 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7046 "frr-routing:ipv4");
59115451
SP
7047}
7048
59115451
SP
7049DEFUN (interface_ip_igmp_last_member_query_interval,
7050 interface_ip_igmp_last_member_query_interval_cmd,
11ca3587 7051 "ip igmp last-member-query-interval (1-65535)",
59115451
SP
7052 IP_STR
7053 IFACE_IGMP_STR
7054 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7055 "Last member query interval in deciseconds\n")
7056{
b0475d5a 7057 const struct lyd_node *pim_enable_dnode;
59115451 7058
3bb513c3
CH
7059 pim_enable_dnode =
7060 yang_dnode_getf(vty->candidate_config->dnode,
698f4147 7061 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
7062 "frr-routing:ipv4");
b0475d5a 7063 if (!pim_enable_dnode) {
3051f443 7064 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
521c5b9d 7065 "true");
b0475d5a
SP
7066 } else {
7067 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3051f443 7068 nb_cli_enqueue_change(vty, "./enable",
521c5b9d 7069 NB_OP_MODIFY, "true");
59115451
SP
7070 }
7071
b0475d5a 7072 nb_cli_enqueue_change(vty, "./last-member-query-interval", NB_OP_MODIFY,
521c5b9d 7073 argv[3]->arg);
59115451 7074
3051f443 7075 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7076 "frr-routing:ipv4");
59115451
SP
7077}
7078
7079DEFUN (interface_no_ip_igmp_last_member_query_interval,
7080 interface_no_ip_igmp_last_member_query_interval_cmd,
11ca3587 7081 "no ip igmp last-member-query-interval [(1-65535)]",
59115451
SP
7082 NO_STR
7083 IP_STR
7084 IFACE_IGMP_STR
bb9ff200 7085 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
11ca3587 7086 IGNORED_IN_NO_STR)
59115451 7087{
11ca3587
CH
7088 nb_cli_enqueue_change(vty, "./last-member-query-interval",
7089 NB_OP_DESTROY, NULL);
59115451 7090
3051f443 7091 return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
7092 "frr-routing:ipv4");
59115451
SP
7093}
7094
dedccda6
DS
7095DEFUN (interface_ip_pim_drprio,
7096 interface_ip_pim_drprio_cmd,
b181fa04 7097 "ip pim drpriority (1-4294967295)",
dedccda6
DS
7098 IP_STR
7099 PIM_STR
7100 "Set the Designated Router Election Priority\n"
7101 "Value of the new DR Priority\n")
7102{
d62a17ae 7103 int idx_number = 3;
dedccda6 7104
bb387611 7105 return pim_process_ip_pim_drprio_cmd(vty, argv[idx_number]->arg);
dedccda6
DS
7106}
7107
7108DEFUN (interface_no_ip_pim_drprio,
7109 interface_no_ip_pim_drprio_cmd,
b181fa04 7110 "no ip pim drpriority [(1-4294967295)]",
d7fa34c1 7111 NO_STR
dedccda6
DS
7112 IP_STR
7113 PIM_STR
7114 "Revert the Designated Router Priority to default\n"
7115 "Old Value of the Priority\n")
7116{
bb387611 7117 return pim_process_no_ip_pim_drprio_cmd(vty);
dedccda6
DS
7118}
7119
6741a5bb 7120DEFPY_HIDDEN (interface_ip_igmp_query_generate,
521c5b9d
MS
7121 interface_ip_igmp_query_generate_cmd,
7122 "ip igmp generate-query-once [version (2-3)]",
7123 IP_STR
7124 IFACE_IGMP_STR
7125 "Generate igmp general query once\n"
7126 "IGMP version\n"
7127 "IGMP version number\n")
6741a5bb 7128{
5a46a3de 7129#if PIM_IPV == 4
6741a5bb 7130 VTY_DECLVAR_CONTEXT(interface, ifp);
761e4fba 7131 int igmp_version;
7132 struct pim_interface *pim_ifp = ifp->info;
6741a5bb 7133
7134 if (!ifp->info) {
7135 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
7136 ifp->name);
7137 return CMD_WARNING_CONFIG_FAILED;
7138 }
7139
761e4fba 7140 /* It takes the igmp version configured on the interface as default */
dfc26ad1 7141 igmp_version = pim_ifp->igmp_version;
761e4fba 7142
6741a5bb 7143 if (argc > 3)
7144 igmp_version = atoi(argv[4]->arg);
7145
7146 igmp_send_query_on_intf(ifp, igmp_version);
5a46a3de 7147#endif
6741a5bb 7148 return CMD_SUCCESS;
7149}
7150
70fd22bd
DS
7151DEFPY_HIDDEN (pim_test_sg_keepalive,
7152 pim_test_sg_keepalive_cmd,
7153 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7154 "Test code\n"
7155 PIM_STR
7156 VRF_CMD_HELP_STR
7157 "Reset the Keepalive Timer\n"
7158 "The Source we are resetting\n"
7159 "The Group we are resetting\n")
7160{
7161 struct pim_upstream *up;
7162 struct pim_instance *pim;
6fff2cc6 7163 pim_sgaddr sg;
70fd22bd
DS
7164
7165 sg.src = source;
7166 sg.grp = group;
7167
7168 if (!name)
7169 pim = pim_get_pim_instance(VRF_DEFAULT);
7170 else {
7171 struct vrf *vrf = vrf_lookup_by_name(name);
7172
7173 if (!vrf) {
7174 vty_out(vty, "%% Vrf specified: %s does not exist\n",
7175 name);
7176 return CMD_WARNING;
7177 }
7178
7179 pim = pim_get_pim_instance(vrf->vrf_id);
7180 }
7181
7182 if (!pim) {
7183 vty_out(vty, "%% Unable to find pim instance\n");
7184 return CMD_WARNING;
7185 }
7186
7187 up = pim_upstream_find(pim, &sg);
7188 if (!up) {
98a81d2b 7189 vty_out(vty, "%% Unable to find %pSG specified\n", &sg);
70fd22bd
DS
7190 return CMD_WARNING;
7191 }
7192
98a81d2b
DL
7193 vty_out(vty, "Setting %pSG to current keep alive time: %d\n", &sg,
7194 pim->keep_alive_time);
70fd22bd
DS
7195 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
7196
7197 return CMD_SUCCESS;
7198}
7199
17823cdd
DS
7200DEFPY (interface_ip_pim_activeactive,
7201 interface_ip_pim_activeactive_cmd,
7202 "[no$no] ip pim active-active",
7203 NO_STR
7204 IP_STR
7205 PIM_STR
7206 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
414d885a 7207{
7e01b641 7208 return pim_process_ip_pim_activeactive_cmd(vty, no);
414d885a
DS
7209}
7210
d2772e7b 7211DEFUN_HIDDEN (interface_ip_pim_ssm,
521c5b9d
MS
7212 interface_ip_pim_ssm_cmd,
7213 "ip pim ssm",
7214 IP_STR
7215 PIM_STR
7216 IFACE_PIM_STR)
981d6c7a 7217{
50d194f8 7218 int ret;
43e40fdf 7219
dab0ac29 7220 ret = pim_process_ip_pim_cmd(vty);
981d6c7a 7221
50d194f8
SP
7222 if (ret != NB_OK)
7223 return ret;
ecca97ac 7224
50d194f8
SP
7225 vty_out(vty,
7226 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
c992c9a0 7227
50d194f8 7228 return NB_OK;
981d6c7a
DS
7229}
7230
2f5e937c 7231DEFUN_HIDDEN (interface_ip_pim_sm,
521c5b9d
MS
7232 interface_ip_pim_sm_cmd,
7233 "ip pim sm",
7234 IP_STR
7235 PIM_STR
7236 IFACE_PIM_SM_STR)
2f5e937c 7237{
2b16b40f 7238 return pim_process_ip_pim_cmd(vty);
2f5e937c 7239}
7240
7241DEFUN (interface_ip_pim,
7242 interface_ip_pim_cmd,
7243 "ip pim",
7244 IP_STR
7245 PIM_STR)
7246{
a1caf7a8 7247 return pim_process_ip_pim_cmd(vty);
2f5e937c 7248}
7249
d2772e7b 7250DEFUN_HIDDEN (interface_no_ip_pim_ssm,
521c5b9d
MS
7251 interface_no_ip_pim_ssm_cmd,
7252 "no ip pim ssm",
7253 NO_STR
7254 IP_STR
7255 PIM_STR
7256 IFACE_PIM_STR)
981d6c7a 7257{
dab0ac29 7258 return pim_process_no_ip_pim_cmd(vty);
981d6c7a
DS
7259}
7260
2f5e937c 7261DEFUN_HIDDEN (interface_no_ip_pim_sm,
521c5b9d
MS
7262 interface_no_ip_pim_sm_cmd,
7263 "no ip pim sm",
7264 NO_STR
7265 IP_STR
7266 PIM_STR
7267 IFACE_PIM_SM_STR)
981d6c7a 7268{
2b16b40f 7269 return pim_process_no_ip_pim_cmd(vty);
2f5e937c 7270}
981d6c7a 7271
2f5e937c 7272DEFUN (interface_no_ip_pim,
7273 interface_no_ip_pim_cmd,
7274 "no ip pim",
7275 NO_STR
7276 IP_STR
7277 PIM_STR)
7278{
dab0ac29 7279 return pim_process_no_ip_pim_cmd(vty);
12e41d03
DL
7280}
7281
b0f525a8
QY
7282/* boundaries */
7283DEFUN(interface_ip_pim_boundary_oil,
7284 interface_ip_pim_boundary_oil_cmd,
7285 "ip multicast boundary oil WORD",
7286 IP_STR
7287 "Generic multicast configuration options\n"
7288 "Define multicast boundary\n"
7289 "Filter OIL by group using prefix list\n"
513c8462 7290 "Prefix list to filter OIL with\n")
b0f525a8 7291{
52c52d78 7292 return pim_process_ip_pim_boundary_oil_cmd(vty, argv[4]->arg);
b0f525a8
QY
7293}
7294
7295DEFUN(interface_no_ip_pim_boundary_oil,
7296 interface_no_ip_pim_boundary_oil_cmd,
7297 "no ip multicast boundary oil [WORD]",
7298 NO_STR
7299 IP_STR
7300 "Generic multicast configuration options\n"
7301 "Define multicast boundary\n"
7302 "Filter OIL by group using prefix list\n"
513c8462 7303 "Prefix list to filter OIL with\n")
b0f525a8 7304{
52c52d78 7305 return pim_process_no_ip_pim_boundary_oil_cmd(vty);
b0f525a8
QY
7306}
7307
6250610a
JAG
7308DEFUN (interface_ip_mroute,
7309 interface_ip_mroute_cmd,
e57cc5f0 7310 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
6250610a
JAG
7311 IP_STR
7312 "Add multicast route\n"
7313 "Outgoing interface name\n"
7314 "Group address\n"
7315 "Source address\n")
7316{
d62a17ae 7317 int idx_interface = 2;
7318 int idx_ipv4 = 3;
675c8fde 7319 const char *source_str;
d62a17ae 7320
675c8fde
SP
7321 if (argc == (idx_ipv4 + 1))
7322 source_str = "0.0.0.0";
7323 else
7324 source_str = argv[idx_ipv4 + 1]->arg;
d62a17ae 7325
63ee25c0 7326 return pim_process_ip_mroute_cmd(vty, argv[idx_interface]->arg,
7327 argv[idx_ipv4]->arg, source_str);
6250610a
JAG
7328}
7329
7330DEFUN (interface_no_ip_mroute,
7331 interface_no_ip_mroute_cmd,
e57cc5f0 7332 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
6250610a
JAG
7333 NO_STR
7334 IP_STR
7335 "Add multicast route\n"
7336 "Outgoing interface name\n"
7337 "Group Address\n"
7338 "Source Address\n")
7339{
63ee25c0 7340 int idx_interface = 3;
d62a17ae 7341 int idx_ipv4 = 4;
675c8fde 7342 const char *source_str;
d62a17ae 7343
675c8fde
SP
7344 if (argc == (idx_ipv4 + 1))
7345 source_str = "0.0.0.0";
7346 else
7347 source_str = argv[idx_ipv4 + 1]->arg;
d62a17ae 7348
63ee25c0 7349 return pim_process_no_ip_mroute_cmd(vty, argv[idx_interface]->arg,
7350 argv[idx_ipv4]->arg, source_str);
6250610a
JAG
7351}
7352
7960fa8f
DS
7353DEFUN (interface_ip_pim_hello,
7354 interface_ip_pim_hello_cmd,
11ca3587 7355 "ip pim hello (1-65535) [(1-65535)]",
7960fa8f
DS
7356 IP_STR
7357 PIM_STR
7358 IFACE_PIM_HELLO_STR
80d3d26b
DW
7359 IFACE_PIM_HELLO_TIME_STR
7360 IFACE_PIM_HELLO_HOLD_STR)
7960fa8f 7361{
d62a17ae 7362 int idx_time = 3;
7363 int idx_hold = 4;
7960fa8f 7364
d62a17ae 7365 if (argc == idx_hold + 1)
e6aab613 7366 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
7367 argv[idx_hold]->arg);
7960fa8f 7368
e6aab613 7369 else
7370 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
7371 NULL);
7960fa8f
DS
7372}
7373
7960fa8f
DS
7374DEFUN (interface_no_ip_pim_hello,
7375 interface_no_ip_pim_hello_cmd,
11ca3587 7376 "no ip pim hello [(1-65535) [(1-65535)]]",
7960fa8f
DS
7377 NO_STR
7378 IP_STR
7379 PIM_STR
7380 IFACE_PIM_HELLO_STR
11ca3587
CH
7381 IGNORED_IN_NO_STR
7382 IGNORED_IN_NO_STR)
7960fa8f 7383{
e6aab613 7384 return pim_process_no_ip_pim_hello_cmd(vty);
7960fa8f
DS
7385}
7386
12e41d03
DL
7387DEFUN (debug_igmp,
7388 debug_igmp_cmd,
7389 "debug igmp",
7390 DEBUG_STR
7391 DEBUG_IGMP_STR)
7392{
d62a17ae 7393 PIM_DO_DEBUG_IGMP_EVENTS;
7394 PIM_DO_DEBUG_IGMP_PACKETS;
7395 PIM_DO_DEBUG_IGMP_TRACE;
7396 return CMD_SUCCESS;
12e41d03
DL
7397}
7398
7399DEFUN (no_debug_igmp,
7400 no_debug_igmp_cmd,
7401 "no debug igmp",
7402 NO_STR
7403 DEBUG_STR
7404 DEBUG_IGMP_STR)
7405{
d62a17ae 7406 PIM_DONT_DEBUG_IGMP_EVENTS;
7407 PIM_DONT_DEBUG_IGMP_PACKETS;
7408 PIM_DONT_DEBUG_IGMP_TRACE;
7409 return CMD_SUCCESS;
12e41d03
DL
7410}
7411
12e41d03
DL
7412
7413DEFUN (debug_igmp_events,
7414 debug_igmp_events_cmd,
7415 "debug igmp events",
7416 DEBUG_STR
7417 DEBUG_IGMP_STR
7418 DEBUG_IGMP_EVENTS_STR)
7419{
d62a17ae 7420 PIM_DO_DEBUG_IGMP_EVENTS;
7421 return CMD_SUCCESS;
12e41d03
DL
7422}
7423
7424DEFUN (no_debug_igmp_events,
7425 no_debug_igmp_events_cmd,
7426 "no debug igmp events",
7427 NO_STR
7428 DEBUG_STR
7429 DEBUG_IGMP_STR
7430 DEBUG_IGMP_EVENTS_STR)
7431{
d62a17ae 7432 PIM_DONT_DEBUG_IGMP_EVENTS;
7433 return CMD_SUCCESS;
12e41d03
DL
7434}
7435
12e41d03
DL
7436
7437DEFUN (debug_igmp_packets,
7438 debug_igmp_packets_cmd,
7439 "debug igmp packets",
7440 DEBUG_STR
7441 DEBUG_IGMP_STR
7442 DEBUG_IGMP_PACKETS_STR)
7443{
d62a17ae 7444 PIM_DO_DEBUG_IGMP_PACKETS;
7445 return CMD_SUCCESS;
12e41d03
DL
7446}
7447
7448DEFUN (no_debug_igmp_packets,
7449 no_debug_igmp_packets_cmd,
7450 "no debug igmp packets",
7451 NO_STR
7452 DEBUG_STR
7453 DEBUG_IGMP_STR
7454 DEBUG_IGMP_PACKETS_STR)
7455{
d62a17ae 7456 PIM_DONT_DEBUG_IGMP_PACKETS;
7457 return CMD_SUCCESS;
12e41d03
DL
7458}
7459
12e41d03
DL
7460
7461DEFUN (debug_igmp_trace,
7462 debug_igmp_trace_cmd,
7463 "debug igmp trace",
7464 DEBUG_STR
7465 DEBUG_IGMP_STR
7466 DEBUG_IGMP_TRACE_STR)
7467{
d62a17ae 7468 PIM_DO_DEBUG_IGMP_TRACE;
7469 return CMD_SUCCESS;
12e41d03
DL
7470}
7471
7472DEFUN (no_debug_igmp_trace,
7473 no_debug_igmp_trace_cmd,
7474 "no debug igmp trace",
7475 NO_STR
7476 DEBUG_STR
7477 DEBUG_IGMP_STR
7478 DEBUG_IGMP_TRACE_STR)
7479{
d62a17ae 7480 PIM_DONT_DEBUG_IGMP_TRACE;
7481 return CMD_SUCCESS;
12e41d03
DL
7482}
7483
12e41d03
DL
7484
7485DEFUN (debug_mroute,
7486 debug_mroute_cmd,
7487 "debug mroute",
7488 DEBUG_STR
7489 DEBUG_MROUTE_STR)
7490{
d62a17ae 7491 PIM_DO_DEBUG_MROUTE;
7492 return CMD_SUCCESS;
12e41d03
DL
7493}
7494
6c7197b1
DS
7495DEFUN (debug_mroute_detail,
7496 debug_mroute_detail_cmd,
7497 "debug mroute detail",
7498 DEBUG_STR
7499 DEBUG_MROUTE_STR
7500 "detailed\n")
7501{
d62a17ae 7502 PIM_DO_DEBUG_MROUTE_DETAIL;
7503 return CMD_SUCCESS;
6c7197b1
DS
7504}
7505
12e41d03
DL
7506DEFUN (no_debug_mroute,
7507 no_debug_mroute_cmd,
7508 "no debug mroute",
7509 NO_STR
7510 DEBUG_STR
7511 DEBUG_MROUTE_STR)
7512{
d62a17ae 7513 PIM_DONT_DEBUG_MROUTE;
7514 return CMD_SUCCESS;
12e41d03
DL
7515}
7516
6c7197b1
DS
7517DEFUN (no_debug_mroute_detail,
7518 no_debug_mroute_detail_cmd,
7519 "no debug mroute detail",
7520 NO_STR
7521 DEBUG_STR
7522 DEBUG_MROUTE_STR
7523 "detailed\n")
7524{
d62a17ae 7525 PIM_DONT_DEBUG_MROUTE_DETAIL;
7526 return CMD_SUCCESS;
6c7197b1 7527}
12e41d03 7528
35a12720
MS
7529DEFUN (debug_pim_static,
7530 debug_pim_static_cmd,
7531 "debug pim static",
6250610a 7532 DEBUG_STR
35a12720 7533 DEBUG_PIM_STR
6250610a
JAG
7534 DEBUG_STATIC_STR)
7535{
d62a17ae 7536 PIM_DO_DEBUG_STATIC;
7537 return CMD_SUCCESS;
6250610a
JAG
7538}
7539
35a12720
MS
7540DEFUN (no_debug_pim_static,
7541 no_debug_pim_static_cmd,
7542 "no debug pim static",
6250610a
JAG
7543 NO_STR
7544 DEBUG_STR
35a12720 7545 DEBUG_PIM_STR
6250610a
JAG
7546 DEBUG_STATIC_STR)
7547{
d62a17ae 7548 PIM_DONT_DEBUG_STATIC;
7549 return CMD_SUCCESS;
6250610a
JAG
7550}
7551
6250610a 7552
12e41d03
DL
7553DEFUN (debug_pim,
7554 debug_pim_cmd,
7555 "debug pim",
7556 DEBUG_STR
7557 DEBUG_PIM_STR)
7558{
d62a17ae 7559 PIM_DO_DEBUG_PIM_EVENTS;
7560 PIM_DO_DEBUG_PIM_PACKETS;
7561 PIM_DO_DEBUG_PIM_TRACE;
7562 PIM_DO_DEBUG_MSDP_EVENTS;
7563 PIM_DO_DEBUG_MSDP_PACKETS;
09524ccf 7564 PIM_DO_DEBUG_BSM;
dedcdb89 7565 PIM_DO_DEBUG_VXLAN;
d62a17ae 7566 return CMD_SUCCESS;
12e41d03
DL
7567}
7568
7569DEFUN (no_debug_pim,
7570 no_debug_pim_cmd,
7571 "no debug pim",
7572 NO_STR
7573 DEBUG_STR
7574 DEBUG_PIM_STR)
7575{
d62a17ae 7576 PIM_DONT_DEBUG_PIM_EVENTS;
7577 PIM_DONT_DEBUG_PIM_PACKETS;
7578 PIM_DONT_DEBUG_PIM_TRACE;
7579 PIM_DONT_DEBUG_MSDP_EVENTS;
7580 PIM_DONT_DEBUG_MSDP_PACKETS;
12e41d03 7581
d62a17ae 7582 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
7583 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
09524ccf 7584 PIM_DONT_DEBUG_BSM;
dedcdb89 7585 PIM_DONT_DEBUG_VXLAN;
12e41d03 7586
d62a17ae 7587 return CMD_SUCCESS;
12e41d03
DL
7588}
7589
40f1f31b
DS
7590DEFUN (debug_pim_nht,
7591 debug_pim_nht_cmd,
7592 "debug pim nht",
7593 DEBUG_STR
7594 DEBUG_PIM_STR
7595 "Nexthop Tracking\n")
7596{
7597 PIM_DO_DEBUG_PIM_NHT;
7598 return CMD_SUCCESS;
7599}
7600
7601DEFUN (no_debug_pim_nht,
7602 no_debug_pim_nht_cmd,
7603 "no debug pim nht",
7604 NO_STR
7605 DEBUG_STR
7606 DEBUG_PIM_STR
7607 "Nexthop Tracking\n")
7608{
7609 PIM_DONT_DEBUG_PIM_NHT;
7610 return CMD_SUCCESS;
7611}
12e41d03 7612
6d733f0d
SG
7613DEFUN (debug_pim_nht_det,
7614 debug_pim_nht_det_cmd,
7615 "debug pim nht detail",
7616 DEBUG_STR
7617 DEBUG_PIM_STR
7618 "Nexthop Tracking\n"
7619 "Detailed Information\n")
7620{
7621 PIM_DO_DEBUG_PIM_NHT_DETAIL;
7622 return CMD_SUCCESS;
7623}
7624
7625DEFUN (no_debug_pim_nht_det,
7626 no_debug_pim_nht_det_cmd,
7627 "no debug pim nht detail",
7628 NO_STR
7629 DEBUG_STR
7630 DEBUG_PIM_STR
7631 "Nexthop Tracking\n"
7632 "Detailed Information\n")
7633{
7634 PIM_DONT_DEBUG_PIM_NHT_DETAIL;
7635 return CMD_SUCCESS;
7636}
7637
3d225d48
DS
7638DEFUN (debug_pim_nht_rp,
7639 debug_pim_nht_rp_cmd,
7640 "debug pim nht rp",
7641 DEBUG_STR
7642 DEBUG_PIM_STR
7643 "Nexthop Tracking\n"
7644 "RP Nexthop Tracking\n")
7645{
7646 PIM_DO_DEBUG_PIM_NHT_RP;
7647 return CMD_SUCCESS;
7648}
7649
7650DEFUN (no_debug_pim_nht_rp,
7651 no_debug_pim_nht_rp_cmd,
7652 "no debug pim nht rp",
7653 NO_STR
7654 DEBUG_STR
7655 DEBUG_PIM_STR
7656 "Nexthop Tracking\n"
7657 "RP Nexthop Tracking\n")
7658{
7659 PIM_DONT_DEBUG_PIM_NHT_RP;
7660 return CMD_SUCCESS;
7661}
7662
12e41d03
DL
7663DEFUN (debug_pim_events,
7664 debug_pim_events_cmd,
7665 "debug pim events",
7666 DEBUG_STR
7667 DEBUG_PIM_STR
7668 DEBUG_PIM_EVENTS_STR)
7669{
d62a17ae 7670 PIM_DO_DEBUG_PIM_EVENTS;
7671 return CMD_SUCCESS;
12e41d03
DL
7672}
7673
7674DEFUN (no_debug_pim_events,
7675 no_debug_pim_events_cmd,
7676 "no debug pim events",
7677 NO_STR
7678 DEBUG_STR
7679 DEBUG_PIM_STR
7680 DEBUG_PIM_EVENTS_STR)
7681{
d62a17ae 7682 PIM_DONT_DEBUG_PIM_EVENTS;
7683 return CMD_SUCCESS;
12e41d03
DL
7684}
7685
12e41d03
DL
7686DEFUN (debug_pim_packets,
7687 debug_pim_packets_cmd,
a957a05b 7688 "debug pim packets [<hello|joins|register>]",
12e41d03
DL
7689 DEBUG_STR
7690 DEBUG_PIM_STR
7691 DEBUG_PIM_PACKETS_STR
7692 DEBUG_PIM_HELLO_PACKETS_STR
9add3b88
DS
7693 DEBUG_PIM_J_P_PACKETS_STR
7694 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 7695{
d62a17ae 7696 int idx = 0;
7697 if (argv_find(argv, argc, "hello", &idx)) {
7698 PIM_DO_DEBUG_PIM_HELLO;
7699 vty_out(vty, "PIM Hello debugging is on\n");
7700 } else if (argv_find(argv, argc, "joins", &idx)) {
7701 PIM_DO_DEBUG_PIM_J_P;
7702 vty_out(vty, "PIM Join/Prune debugging is on\n");
7703 } else if (argv_find(argv, argc, "register", &idx)) {
7704 PIM_DO_DEBUG_PIM_REG;
7705 vty_out(vty, "PIM Register debugging is on\n");
7706 } else {
7707 PIM_DO_DEBUG_PIM_PACKETS;
7708 vty_out(vty, "PIM Packet debugging is on \n");
7709 }
7710 return CMD_SUCCESS;
12e41d03
DL
7711}
7712
7713DEFUN (no_debug_pim_packets,
7714 no_debug_pim_packets_cmd,
a957a05b 7715 "no debug pim packets [<hello|joins|register>]",
12e41d03
DL
7716 NO_STR
7717 DEBUG_STR
7718 DEBUG_PIM_STR
7719 DEBUG_PIM_PACKETS_STR
7720 DEBUG_PIM_HELLO_PACKETS_STR
a957a05b
DS
7721 DEBUG_PIM_J_P_PACKETS_STR
7722 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 7723{
d62a17ae 7724 int idx = 0;
7725 if (argv_find(argv, argc, "hello", &idx)) {
7726 PIM_DONT_DEBUG_PIM_HELLO;
7727 vty_out(vty, "PIM Hello debugging is off \n");
7728 } else if (argv_find(argv, argc, "joins", &idx)) {
7729 PIM_DONT_DEBUG_PIM_J_P;
7730 vty_out(vty, "PIM Join/Prune debugging is off \n");
7731 } else if (argv_find(argv, argc, "register", &idx)) {
7732 PIM_DONT_DEBUG_PIM_REG;
7733 vty_out(vty, "PIM Register debugging is off\n");
7734 } else
7735 PIM_DONT_DEBUG_PIM_PACKETS;
7736
7737 return CMD_SUCCESS;
12e41d03
DL
7738}
7739
12e41d03
DL
7740
7741DEFUN (debug_pim_packetdump_send,
7742 debug_pim_packetdump_send_cmd,
7743 "debug pim packet-dump send",
7744 DEBUG_STR
7745 DEBUG_PIM_STR
7746 DEBUG_PIM_PACKETDUMP_STR
7747 DEBUG_PIM_PACKETDUMP_SEND_STR)
7748{
d62a17ae 7749 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
7750 return CMD_SUCCESS;
12e41d03
DL
7751}
7752
7753DEFUN (no_debug_pim_packetdump_send,
7754 no_debug_pim_packetdump_send_cmd,
7755 "no debug pim packet-dump send",
7756 NO_STR
7757 DEBUG_STR
7758 DEBUG_PIM_STR
7759 DEBUG_PIM_PACKETDUMP_STR
7760 DEBUG_PIM_PACKETDUMP_SEND_STR)
7761{
d62a17ae 7762 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
7763 return CMD_SUCCESS;
12e41d03
DL
7764}
7765
12e41d03
DL
7766DEFUN (debug_pim_packetdump_recv,
7767 debug_pim_packetdump_recv_cmd,
7768 "debug pim packet-dump receive",
7769 DEBUG_STR
7770 DEBUG_PIM_STR
7771 DEBUG_PIM_PACKETDUMP_STR
7772 DEBUG_PIM_PACKETDUMP_RECV_STR)
7773{
d62a17ae 7774 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
7775 return CMD_SUCCESS;
12e41d03
DL
7776}
7777
7778DEFUN (no_debug_pim_packetdump_recv,
7779 no_debug_pim_packetdump_recv_cmd,
7780 "no debug pim packet-dump receive",
7781 NO_STR
7782 DEBUG_STR
7783 DEBUG_PIM_STR
7784 DEBUG_PIM_PACKETDUMP_STR
7785 DEBUG_PIM_PACKETDUMP_RECV_STR)
7786{
d62a17ae 7787 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
7788 return CMD_SUCCESS;
12e41d03
DL
7789}
7790
12e41d03
DL
7791DEFUN (debug_pim_trace,
7792 debug_pim_trace_cmd,
7793 "debug pim trace",
7794 DEBUG_STR
7795 DEBUG_PIM_STR
7796 DEBUG_PIM_TRACE_STR)
7797{
d62a17ae 7798 PIM_DO_DEBUG_PIM_TRACE;
7799 return CMD_SUCCESS;
12e41d03
DL
7800}
7801
56c238c9
DS
7802DEFUN (debug_pim_trace_detail,
7803 debug_pim_trace_detail_cmd,
7804 "debug pim trace detail",
7805 DEBUG_STR
7806 DEBUG_PIM_STR
5f40dada
DS
7807 DEBUG_PIM_TRACE_STR
7808 "Detailed Information\n")
56c238c9
DS
7809{
7810 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
7811 return CMD_SUCCESS;
7812}
7813
12e41d03
DL
7814DEFUN (no_debug_pim_trace,
7815 no_debug_pim_trace_cmd,
7816 "no debug pim trace",
7817 NO_STR
7818 DEBUG_STR
7819 DEBUG_PIM_STR
7820 DEBUG_PIM_TRACE_STR)
7821{
d62a17ae 7822 PIM_DONT_DEBUG_PIM_TRACE;
7823 return CMD_SUCCESS;
12e41d03
DL
7824}
7825
56c238c9
DS
7826DEFUN (no_debug_pim_trace_detail,
7827 no_debug_pim_trace_detail_cmd,
9853a7a5 7828 "no debug pim trace detail",
56c238c9
DS
7829 NO_STR
7830 DEBUG_STR
7831 DEBUG_PIM_STR
bd4d05c5
DS
7832 DEBUG_PIM_TRACE_STR
7833 "Detailed Information\n")
56c238c9
DS
7834{
7835 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
7836 return CMD_SUCCESS;
7837}
7838
12e41d03
DL
7839DEFUN (debug_ssmpingd,
7840 debug_ssmpingd_cmd,
7841 "debug ssmpingd",
7842 DEBUG_STR
12e41d03
DL
7843 DEBUG_SSMPINGD_STR)
7844{
d62a17ae 7845 PIM_DO_DEBUG_SSMPINGD;
7846 return CMD_SUCCESS;
12e41d03
DL
7847}
7848
7849DEFUN (no_debug_ssmpingd,
7850 no_debug_ssmpingd_cmd,
7851 "no debug ssmpingd",
7852 NO_STR
7853 DEBUG_STR
12e41d03
DL
7854 DEBUG_SSMPINGD_STR)
7855{
d62a17ae 7856 PIM_DONT_DEBUG_SSMPINGD;
7857 return CMD_SUCCESS;
12e41d03
DL
7858}
7859
12e41d03
DL
7860DEFUN (debug_pim_zebra,
7861 debug_pim_zebra_cmd,
7862 "debug pim zebra",
7863 DEBUG_STR
7864 DEBUG_PIM_STR
7865 DEBUG_PIM_ZEBRA_STR)
7866{
d62a17ae 7867 PIM_DO_DEBUG_ZEBRA;
7868 return CMD_SUCCESS;
12e41d03
DL
7869}
7870
7871DEFUN (no_debug_pim_zebra,
7872 no_debug_pim_zebra_cmd,
7873 "no debug pim zebra",
7874 NO_STR
7875 DEBUG_STR
7876 DEBUG_PIM_STR
7877 DEBUG_PIM_ZEBRA_STR)
7878{
d62a17ae 7879 PIM_DONT_DEBUG_ZEBRA;
7880 return CMD_SUCCESS;
12e41d03
DL
7881}
7882
36b5b98f
SK
7883DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
7884 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
7885{
7886 PIM_DO_DEBUG_MLAG;
7887 return CMD_SUCCESS;
7888}
7889
7890DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
7891 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
7892{
7893 PIM_DONT_DEBUG_MLAG;
7894 return CMD_SUCCESS;
7895}
7896
4d913fa6
AK
7897DEFUN (debug_pim_vxlan,
7898 debug_pim_vxlan_cmd,
7899 "debug pim vxlan",
7900 DEBUG_STR
7901 DEBUG_PIM_STR
7902 DEBUG_PIM_VXLAN_STR)
7903{
7904 PIM_DO_DEBUG_VXLAN;
7905 return CMD_SUCCESS;
7906}
7907
7908DEFUN (no_debug_pim_vxlan,
7909 no_debug_pim_vxlan_cmd,
7910 "no debug pim vxlan",
7911 NO_STR
7912 DEBUG_STR
7913 DEBUG_PIM_STR
7914 DEBUG_PIM_VXLAN_STR)
7915{
7916 PIM_DONT_DEBUG_VXLAN;
7917 return CMD_SUCCESS;
7918}
7919
2a333e0f 7920DEFUN (debug_msdp,
7921 debug_msdp_cmd,
7922 "debug msdp",
7923 DEBUG_STR
7924 DEBUG_MSDP_STR)
7925{
d62a17ae 7926 PIM_DO_DEBUG_MSDP_EVENTS;
7927 PIM_DO_DEBUG_MSDP_PACKETS;
7928 return CMD_SUCCESS;
2a333e0f 7929}
7930
7931DEFUN (no_debug_msdp,
7932 no_debug_msdp_cmd,
7933 "no debug msdp",
7934 NO_STR
7935 DEBUG_STR
7936 DEBUG_MSDP_STR)
7937{
d62a17ae 7938 PIM_DONT_DEBUG_MSDP_EVENTS;
7939 PIM_DONT_DEBUG_MSDP_PACKETS;
7940 return CMD_SUCCESS;
2a333e0f 7941}
7942
2a333e0f 7943DEFUN (debug_msdp_events,
7944 debug_msdp_events_cmd,
7945 "debug msdp events",
7946 DEBUG_STR
7947 DEBUG_MSDP_STR
7948 DEBUG_MSDP_EVENTS_STR)
7949{
d62a17ae 7950 PIM_DO_DEBUG_MSDP_EVENTS;
7951 return CMD_SUCCESS;
2a333e0f 7952}
7953
7954DEFUN (no_debug_msdp_events,
7955 no_debug_msdp_events_cmd,
7956 "no debug msdp events",
7957 NO_STR
7958 DEBUG_STR
7959 DEBUG_MSDP_STR
7960 DEBUG_MSDP_EVENTS_STR)
7961{
d62a17ae 7962 PIM_DONT_DEBUG_MSDP_EVENTS;
7963 return CMD_SUCCESS;
2a333e0f 7964}
7965
2a333e0f 7966DEFUN (debug_msdp_packets,
7967 debug_msdp_packets_cmd,
7968 "debug msdp packets",
7969 DEBUG_STR
7970 DEBUG_MSDP_STR
7971 DEBUG_MSDP_PACKETS_STR)
7972{
d62a17ae 7973 PIM_DO_DEBUG_MSDP_PACKETS;
7974 return CMD_SUCCESS;
2a333e0f 7975}
7976
7977DEFUN (no_debug_msdp_packets,
7978 no_debug_msdp_packets_cmd,
7979 "no debug msdp packets",
7980 NO_STR
7981 DEBUG_STR
7982 DEBUG_MSDP_STR
7983 DEBUG_MSDP_PACKETS_STR)
7984{
d62a17ae 7985 PIM_DONT_DEBUG_MSDP_PACKETS;
7986 return CMD_SUCCESS;
2a333e0f 7987}
7988
4d9ad5dc
MS
7989DEFUN (debug_mtrace,
7990 debug_mtrace_cmd,
7991 "debug mtrace",
7992 DEBUG_STR
7993 DEBUG_MTRACE_STR)
7994{
7995 PIM_DO_DEBUG_MTRACE;
7996 return CMD_SUCCESS;
7997}
7998
7999DEFUN (no_debug_mtrace,
8000 no_debug_mtrace_cmd,
8001 "no debug mtrace",
8002 NO_STR
8003 DEBUG_STR
8004 DEBUG_MTRACE_STR)
8005{
8006 PIM_DONT_DEBUG_MTRACE;
8007 return CMD_SUCCESS;
8008}
8009
09524ccf 8010DEFUN (debug_bsm,
8011 debug_bsm_cmd,
8012 "debug pim bsm",
8013 DEBUG_STR
8014 DEBUG_PIM_STR
8015 DEBUG_PIM_BSM_STR)
8016{
8017 PIM_DO_DEBUG_BSM;
8018 return CMD_SUCCESS;
8019}
8020
8021DEFUN (no_debug_bsm,
8022 no_debug_bsm_cmd,
8023 "no debug pim bsm",
8024 NO_STR
8025 DEBUG_STR
8026 DEBUG_PIM_STR
8027 DEBUG_PIM_BSM_STR)
8028{
8029 PIM_DONT_DEBUG_BSM;
8030 return CMD_SUCCESS;
8031}
8032
8033
87f6dc50
DS
8034DEFUN_NOSH (show_debugging_pim,
8035 show_debugging_pim_cmd,
8036 "show debugging [pim]",
8037 SHOW_STR
8038 DEBUG_STR
8039 PIM_STR)
12e41d03 8040{
87f6dc50
DS
8041 vty_out(vty, "PIM debugging status\n");
8042
d62a17ae 8043 pim_debug_config_write(vty);
87f6dc50 8044
d62a17ae 8045 return CMD_SUCCESS;
12e41d03
DL
8046}
8047
4763cd0e 8048DEFUN (interface_pim_use_source,
8049 interface_pim_use_source_cmd,
8050 "ip pim use-source A.B.C.D",
8051 IP_STR
2f5e937c 8052 PIM_STR
4763cd0e 8053 "Configure primary IP address\n"
8054 "source ip address\n")
8055{
675c8fde
SP
8056 nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, argv[3]->arg);
8057
8058 return nb_cli_apply_changes(vty,
698f4147 8059 FRR_PIM_INTERFACE_XPATH,
521c5b9d 8060 "frr-routing:ipv4");
4763cd0e 8061}
8062
8063DEFUN (interface_no_pim_use_source,
8064 interface_no_pim_use_source_cmd,
2243bb17 8065 "no ip pim use-source [A.B.C.D]",
4763cd0e 8066 NO_STR
8067 IP_STR
2f5e937c 8068 PIM_STR
2243bb17
DS
8069 "Delete source IP address\n"
8070 "source ip address\n")
4763cd0e 8071{
675c8fde
SP
8072 nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, "0.0.0.0");
8073
8074 return nb_cli_apply_changes(vty,
698f4147 8075 FRR_PIM_INTERFACE_XPATH,
521c5b9d 8076 "frr-routing:ipv4");
4763cd0e 8077}
8078
745b8d4a 8079DEFPY (ip_pim_bfd,
ba4eb1bc 8080 ip_pim_bfd_cmd,
745b8d4a 8081 "ip pim bfd [profile BFDPROF$prof]",
ba4eb1bc
CS
8082 IP_STR
8083 PIM_STR
745b8d4a
RZ
8084 "Enables BFD support\n"
8085 "Use BFD profile\n"
8086 "Use BFD profile name\n")
ba4eb1bc 8087{
b73779d3 8088 const struct lyd_node *igmp_enable_dnode;
ba4eb1bc 8089
3bb513c3
CH
8090 igmp_enable_dnode =
8091 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 8092 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
8093 "frr-routing:ipv4");
b73779d3
SP
8094 if (!igmp_enable_dnode)
8095 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
5c90f569 8096 "true");
b73779d3
SP
8097 else {
8098 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
8099 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
5c90f569 8100 "true");
2fd8de7d 8101 }
2fd8de7d 8102
1f3e6bf5 8103 nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
745b8d4a
RZ
8104 if (prof)
8105 nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_MODIFY, prof);
8106
698f4147 8107 return nb_cli_apply_changes(vty,
8108 FRR_PIM_INTERFACE_XPATH,
8109 "frr-routing:ipv4");
745b8d4a
RZ
8110}
8111
8112DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
8113 "no ip pim bfd profile [BFDPROF]",
8114 NO_STR
8115 IP_STR
8116 PIM_STR
8117 "Enables BFD support\n"
8118 "Disable BFD profile\n"
8119 "BFD Profile name\n")
8120{
8121 nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_DESTROY, NULL);
ba4eb1bc 8122
698f4147 8123 return nb_cli_apply_changes(vty,
8124 FRR_PIM_INTERFACE_XPATH,
8125 "frr-routing:ipv4");
ba4eb1bc
CS
8126}
8127
8128DEFUN (no_ip_pim_bfd,
8129 no_ip_pim_bfd_cmd,
8130 "no ip pim bfd",
8131 NO_STR
8132 IP_STR
8133 PIM_STR
8134 "Disables BFD support\n")
8135{
b73779d3 8136 nb_cli_enqueue_change(vty, "./bfd", NB_OP_DESTROY, NULL);
ba4eb1bc 8137
698f4147 8138 return nb_cli_apply_changes(vty,
8139 FRR_PIM_INTERFACE_XPATH,
8140 "frr-routing:ipv4");
ba4eb1bc
CS
8141}
8142
16c926c8 8143DEFUN (ip_pim_bsm,
8144 ip_pim_bsm_cmd,
8145 "ip pim bsm",
8146 IP_STR
8147 PIM_STR
8148 "Enables BSM support on the interface\n")
8149{
e3eb2bab 8150 const struct lyd_node *igmp_enable_dnode;
16c926c8 8151
3bb513c3
CH
8152 igmp_enable_dnode =
8153 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 8154 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
8155 "frr-routing:ipv4");
e3eb2bab
SP
8156 if (!igmp_enable_dnode)
8157 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8158 "true");
8159 else {
8160 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
8161 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8162 "true");
16c926c8 8163 }
8164
e3eb2bab 8165 nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "true");
16c926c8 8166
698f4147 8167 return nb_cli_apply_changes(vty,
8168 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
16c926c8 8169}
8170
8171DEFUN (no_ip_pim_bsm,
8172 no_ip_pim_bsm_cmd,
8173 "no ip pim bsm",
8174 NO_STR
8175 IP_STR
8176 PIM_STR
8177 "Disables BSM support\n")
8178{
e3eb2bab 8179 nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "false");
16c926c8 8180
698f4147 8181 return nb_cli_apply_changes(vty,
8182 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
16c926c8 8183}
8184
8185DEFUN (ip_pim_ucast_bsm,
8186 ip_pim_ucast_bsm_cmd,
8187 "ip pim unicast-bsm",
8188 IP_STR
8189 PIM_STR
8190 "Accept/Send unicast BSM on the interface\n")
8191{
e3eb2bab 8192 const struct lyd_node *igmp_enable_dnode;
16c926c8 8193
3bb513c3
CH
8194 igmp_enable_dnode =
8195 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 8196 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
8197 "frr-routing:ipv4");
e3eb2bab
SP
8198 if (!igmp_enable_dnode)
8199 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8200 "true");
8201 else {
8202 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
8203 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
8204 "true");
16c926c8 8205 }
8206
e3eb2bab 8207 nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "true");
16c926c8 8208
698f4147 8209 return nb_cli_apply_changes(vty,
8210 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
8211
16c926c8 8212}
8213
8214DEFUN (no_ip_pim_ucast_bsm,
8215 no_ip_pim_ucast_bsm_cmd,
8216 "no ip pim unicast-bsm",
8217 NO_STR
8218 IP_STR
8219 PIM_STR
8220 "Block send/receive unicast BSM on this interface\n")
8221{
e3eb2bab 8222 nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "false");
16c926c8 8223
698f4147 8224 return nb_cli_apply_changes(vty,
8225 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
16c926c8 8226}
8227
64dc4b2d 8228#if HAVE_BFDD > 0
11ca3587 8229DEFUN_HIDDEN (
521c5b9d
MS
8230 ip_pim_bfd_param,
8231 ip_pim_bfd_param_cmd,
11ca3587 8232 "ip pim bfd (2-255) (1-65535) (1-65535)",
521c5b9d
MS
8233 IP_STR
8234 PIM_STR
8235 "Enables BFD support\n"
8236 "Detect Multiplier\n"
8237 "Required min receive interval\n"
8238 "Desired min transmit interval\n")
64dc4b2d 8239#else
521c5b9d
MS
8240 DEFUN(
8241 ip_pim_bfd_param,
8242 ip_pim_bfd_param_cmd,
11ca3587 8243 "ip pim bfd (2-255) (1-65535) (1-65535)",
521c5b9d
MS
8244 IP_STR
8245 PIM_STR
8246 "Enables BFD support\n"
8247 "Detect Multiplier\n"
8248 "Required min receive interval\n"
8249 "Desired min transmit interval\n")
3779776a 8250#endif /* HAVE_BFDD */
ba4eb1bc 8251{
d62a17ae 8252 int idx_number = 3;
8253 int idx_number_2 = 4;
8254 int idx_number_3 = 5;
b73779d3 8255 const struct lyd_node *igmp_enable_dnode;
ba4eb1bc 8256
3bb513c3
CH
8257 igmp_enable_dnode =
8258 yang_dnode_getf(vty->candidate_config->dnode,
3051f443 8259 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
8260 "frr-routing:ipv4");
b73779d3
SP
8261 if (!igmp_enable_dnode)
8262 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
521c5b9d 8263 "true");
b73779d3
SP
8264 else {
8265 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
8266 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
521c5b9d 8267 "true");
b73779d3 8268 }
ba4eb1bc 8269
1f3e6bf5 8270 nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
b73779d3 8271 nb_cli_enqueue_change(vty, "./bfd/min-rx-interval", NB_OP_MODIFY,
521c5b9d 8272 argv[idx_number_2]->arg);
b73779d3 8273 nb_cli_enqueue_change(vty, "./bfd/min-tx-interval", NB_OP_MODIFY,
521c5b9d 8274 argv[idx_number_3]->arg);
b73779d3 8275 nb_cli_enqueue_change(vty, "./bfd/detect_mult", NB_OP_MODIFY,
521c5b9d 8276 argv[idx_number]->arg);
b73779d3 8277
698f4147 8278 return nb_cli_apply_changes(vty,
8279 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
ba4eb1bc
CS
8280}
8281
64dc4b2d 8282#if HAVE_BFDD == 0
d62a17ae 8283ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
11ca3587
CH
8284 "no ip pim bfd (2-255) (1-65535) (1-65535)",
8285 NO_STR
8286 IP_STR
8287 PIM_STR
d62a17ae 8288 "Enables BFD support\n"
8289 "Detect Multiplier\n"
8290 "Required min receive interval\n"
8291 "Desired min transmit interval\n")
64dc4b2d 8292#endif /* !HAVE_BFDD */
d62a17ae 8293
56697b3e
RZ
8294DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
8295 "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
8296 IP_STR
8297 CFG_MSDP_STR
8298 "Configure MSDP peer\n"
8299 "Peer IP address\n"
8300 "Source address for TCP connection\n"
8301 "Local IP address\n")
2a333e0f 8302{
cf740d2e
SP
8303 const char *vrfname;
8304 char temp_xpath[XPATH_MAXLEN];
8305 char msdp_peer_source_xpath[XPATH_MAXLEN];
2a333e0f 8306
5a1a3920
RZ
8307 vrfname = pim_cli_get_vrf_name(vty);
8308 if (vrfname == NULL)
8309 return CMD_WARNING_CONFIG_FAILED;
2a333e0f 8310
cf740d2e 8311 snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
698f4147 8312 FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
56697b3e 8313 "frr-routing:ipv4");
cf740d2e 8314 snprintf(temp_xpath, sizeof(temp_xpath),
56697b3e 8315 "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
cf740d2e
SP
8316 strlcat(msdp_peer_source_xpath, temp_xpath,
8317 sizeof(msdp_peer_source_xpath));
2a333e0f 8318
cf740d2e 8319 nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
56697b3e 8320 source_str);
2a333e0f 8321
698f4147 8322 return nb_cli_apply_changes(vty,
8323 FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
2a333e0f 8324}
8325
622fd3f1 8326DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
11ca3587 8327 "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
622fd3f1
RZ
8328 IP_STR
8329 CFG_MSDP_STR
8330 "MSDP timers configuration\n"
8331 "Keep alive period (in seconds)\n"
8332 "Hold time period (in seconds)\n"
8333 "Connection retry period (in seconds)\n")
8334{
8335 const char *vrfname;
8336 char xpath[XPATH_MAXLEN];
8337
8338 vrfname = pim_cli_get_vrf_name(vty);
8339 if (vrfname == NULL)
8340 return CMD_WARNING_CONFIG_FAILED;
8341
8342 snprintf(xpath, sizeof(xpath), FRR_PIM_MSDP_XPATH, "frr-pim:pimd",
8343 "pim", vrfname, "frr-routing:ipv4");
8344 nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
8345 nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
8346 if (connretry_str)
8347 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
8348 connretry_str);
8349 else
8350 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
8351 NULL);
8352
8353 nb_cli_apply_changes(vty, xpath);
8354
8355 return CMD_SUCCESS;
8356}
8357
11ca3587
CH
8358DEFPY(no_ip_msdp_timers, no_ip_msdp_timers_cmd,
8359 "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
8360 NO_STR
8361 IP_STR
8362 CFG_MSDP_STR
8363 "MSDP timers configuration\n"
8364 IGNORED_IN_NO_STR
8365 IGNORED_IN_NO_STR
8366 IGNORED_IN_NO_STR)
8367{
8368 const char *vrfname;
8369 char xpath[XPATH_MAXLEN];
8370
8371 vrfname = pim_cli_get_vrf_name(vty);
8372 if (vrfname == NULL)
8373 return CMD_WARNING_CONFIG_FAILED;
8374
8375 snprintf(xpath, sizeof(xpath), FRR_PIM_MSDP_XPATH, "frr-pim:pimd",
8376 "pim", vrfname, "frr-routing:ipv4");
8377
8378 nb_cli_enqueue_change(vty, "./hold-time", NB_OP_DESTROY, NULL);
8379 nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_DESTROY, NULL);
8380 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, NULL);
8381
8382 nb_cli_apply_changes(vty, xpath);
8383
8384 return CMD_SUCCESS;
8385}
8386
9fbd9fc4 8387DEFUN (no_ip_msdp_peer,
2a333e0f 8388 no_ip_msdp_peer_cmd,
8389 "no ip msdp peer A.B.C.D",
977d71cc 8390 NO_STR
2a333e0f 8391 IP_STR
8392 CFG_MSDP_STR
8393 "Delete MSDP peer\n"
8394 "peer ip address\n")
8395{
cf740d2e
SP
8396 const char *vrfname;
8397 char msdp_peer_xpath[XPATH_MAXLEN];
8398 char temp_xpath[XPATH_MAXLEN];
2a333e0f 8399
5a1a3920
RZ
8400 vrfname = pim_cli_get_vrf_name(vty);
8401 if (vrfname == NULL)
8402 return CMD_WARNING_CONFIG_FAILED;
977d71cc 8403
cf740d2e 8404 snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
698f4147 8405 FRR_PIM_VRF_XPATH,
cf740d2e
SP
8406 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
8407 snprintf(temp_xpath, sizeof(temp_xpath),
8408 "/msdp-peer[peer-ip='%s']",
8409 argv[4]->arg);
977d71cc 8410
cf740d2e
SP
8411 strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath));
8412
8413 nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
977d71cc 8414
cf740d2e 8415 return nb_cli_apply_changes(vty, NULL);
977d71cc 8416}
8417
e2809e61
RZ
8418DEFPY(ip_msdp_mesh_group_member,
8419 ip_msdp_mesh_group_member_cmd,
8420 "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
8421 IP_STR
8422 CFG_MSDP_STR
8423 "Configure MSDP mesh-group\n"
8424 "Mesh group name\n"
8425 "Mesh group member\n"
8426 "Peer IP address\n")
977d71cc 8427{
cf740d2e 8428 const char *vrfname;
e2809e61 8429 char xpath_value[XPATH_MAXLEN];
977d71cc 8430
5a1a3920
RZ
8431 vrfname = pim_cli_get_vrf_name(vty);
8432 if (vrfname == NULL)
8433 return CMD_WARNING_CONFIG_FAILED;
977d71cc 8434
e2809e61
RZ
8435 /* Create mesh group. */
8436 snprintf(xpath_value, sizeof(xpath_value),
698f4147 8437 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
8438 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
8439 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
977d71cc 8440
e2809e61
RZ
8441 /* Create mesh group member. */
8442 strlcat(xpath_value, "/members[address='", sizeof(xpath_value));
8443 strlcat(xpath_value, maddr_str, sizeof(xpath_value));
8444 strlcat(xpath_value, "']", sizeof(xpath_value));
8445 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
977d71cc 8446
cf740d2e 8447 return nb_cli_apply_changes(vty, NULL);
977d71cc 8448}
cf740d2e 8449
e2809e61
RZ
8450DEFPY(no_ip_msdp_mesh_group_member,
8451 no_ip_msdp_mesh_group_member_cmd,
8452 "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
8453 NO_STR
8454 IP_STR
8455 CFG_MSDP_STR
8456 "Delete MSDP mesh-group member\n"
8457 "Mesh group name\n"
8458 "Mesh group member\n"
8459 "Peer IP address\n")
977d71cc 8460{
cf740d2e 8461 const char *vrfname;
e2809e61
RZ
8462 char xpath_value[XPATH_MAXLEN];
8463 char xpath_member_value[XPATH_MAXLEN];
977d71cc 8464
5a1a3920
RZ
8465 vrfname = pim_cli_get_vrf_name(vty);
8466 if (vrfname == NULL)
8467 return CMD_WARNING_CONFIG_FAILED;
977d71cc 8468
e2809e61
RZ
8469 /* Get mesh group base XPath. */
8470 snprintf(xpath_value, sizeof(xpath_value),
698f4147 8471 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61 8472 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
cf740d2e 8473
e2809e61
RZ
8474 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
8475 vty_out(vty, "%% mesh-group does not exist\n");
8476 return CMD_WARNING_CONFIG_FAILED;
d62a17ae 8477 }
977d71cc 8478
e2809e61
RZ
8479 /* Remove mesh group member. */
8480 strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
8481 strlcat(xpath_member_value, "/members[address='",
8482 sizeof(xpath_member_value));
8483 strlcat(xpath_member_value, maddr_str, sizeof(xpath_member_value));
8484 strlcat(xpath_member_value, "']", sizeof(xpath_member_value));
8485 if (!yang_dnode_exists(vty->candidate_config->dnode,
8486 xpath_member_value)) {
8487 vty_out(vty, "%% mesh-group member does not exist\n");
8488 return CMD_WARNING_CONFIG_FAILED;
d62a17ae 8489 }
977d71cc 8490
46877489 8491 nb_cli_enqueue_change(vty, xpath_member_value, NB_OP_DESTROY, NULL);
977d71cc 8492
e2809e61
RZ
8493 /*
8494 * If this is the last member, then we must remove the group altogether
8495 * to not break legacy CLI behaviour.
8496 */
8497 pim_cli_legacy_mesh_group_behavior(vty, gname);
8498
8499 return nb_cli_apply_changes(vty, NULL);
cf740d2e 8500}
977d71cc 8501
e2809e61
RZ
8502DEFPY(ip_msdp_mesh_group_source,
8503 ip_msdp_mesh_group_source_cmd,
8504 "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
8505 IP_STR
8506 CFG_MSDP_STR
8507 "Configure MSDP mesh-group\n"
8508 "Mesh group name\n"
8509 "Mesh group local address\n"
8510 "Source IP address for the TCP connection\n")
977d71cc 8511{
cf740d2e 8512 const char *vrfname;
e2809e61 8513 char xpath_value[XPATH_MAXLEN];
977d71cc 8514
5a1a3920
RZ
8515 vrfname = pim_cli_get_vrf_name(vty);
8516 if (vrfname == NULL)
8517 return CMD_WARNING_CONFIG_FAILED;
977d71cc 8518
e2809e61
RZ
8519 /* Create mesh group. */
8520 snprintf(xpath_value, sizeof(xpath_value),
698f4147 8521 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
8522 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
8523 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
977d71cc 8524
46877489 8525 /* Create mesh group source. */
e2809e61
RZ
8526 strlcat(xpath_value, "/source", sizeof(xpath_value));
8527 nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
977d71cc 8528
cf740d2e 8529 return nb_cli_apply_changes(vty, NULL);
977d71cc 8530}
8531
e2809e61
RZ
8532DEFPY(no_ip_msdp_mesh_group_source,
8533 no_ip_msdp_mesh_group_source_cmd,
8534 "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
8535 NO_STR
8536 IP_STR
8537 CFG_MSDP_STR
8538 "Delete MSDP mesh-group source\n"
8539 "Mesh group name\n"
8540 "Mesh group source\n"
8541 "Mesh group local address\n")
977d71cc 8542{
cf740d2e 8543 const char *vrfname;
e2809e61 8544 char xpath_value[XPATH_MAXLEN];
cf740d2e 8545
5a1a3920
RZ
8546 vrfname = pim_cli_get_vrf_name(vty);
8547 if (vrfname == NULL)
8548 return CMD_WARNING_CONFIG_FAILED;
cf740d2e 8549
e2809e61
RZ
8550 /* Get mesh group base XPath. */
8551 snprintf(xpath_value, sizeof(xpath_value),
698f4147 8552 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
8553 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
8554 nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
cf740d2e 8555
46877489 8556 /* Create mesh group source. */
e2809e61
RZ
8557 strlcat(xpath_value, "/source", sizeof(xpath_value));
8558 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
cf740d2e 8559
e2809e61
RZ
8560 /*
8561 * If this is the last member, then we must remove the group altogether
8562 * to not break legacy CLI behaviour.
8563 */
8564 pim_cli_legacy_mesh_group_behavior(vty, gname);
34d86eff 8565
cf740d2e 8566 return nb_cli_apply_changes(vty, NULL);
34d86eff
SP
8567}
8568
e2809e61
RZ
8569DEFPY(no_ip_msdp_mesh_group,
8570 no_ip_msdp_mesh_group_cmd,
8571 "no ip msdp mesh-group WORD$gname",
8572 NO_STR
8573 IP_STR
8574 CFG_MSDP_STR
8575 "Delete MSDP mesh-group\n"
8576 "Mesh group name")
34d86eff 8577{
cf740d2e 8578 const char *vrfname;
e2809e61 8579 char xpath_value[XPATH_MAXLEN];
34d86eff 8580
5a1a3920
RZ
8581 vrfname = pim_cli_get_vrf_name(vty);
8582 if (vrfname == NULL)
8583 return CMD_WARNING_CONFIG_FAILED;
cf740d2e 8584
e2809e61
RZ
8585 /* Get mesh group base XPath. */
8586 snprintf(xpath_value, sizeof(xpath_value),
698f4147 8587 FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
e2809e61
RZ
8588 "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
8589 if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
8590 return CMD_SUCCESS;
cf740d2e 8591
e2809e61 8592 nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
cf740d2e 8593 return nb_cli_apply_changes(vty, NULL);
d62a17ae 8594}
8595
e2809e61
RZ
8596static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
8597 struct json_object *json)
d62a17ae 8598{
8599 struct listnode *mbrnode;
8600 struct pim_msdp_mg_mbr *mbr;
d62a17ae 8601 char mbr_str[INET_ADDRSTRLEN];
8602 char src_str[INET_ADDRSTRLEN];
8603 char state_str[PIM_MSDP_STATE_STRLEN];
8604 enum pim_msdp_peer_state state;
d62a17ae 8605 json_object *json_mg_row = NULL;
8606 json_object *json_members = NULL;
8607 json_object *json_row = NULL;
8608
d62a17ae 8609 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
e2809e61 8610 if (json) {
d62a17ae 8611 /* currently there is only one mesh group but we should still
8612 * make
8613 * it a dict with mg-name as key */
8614 json_mg_row = json_object_new_object();
8615 json_object_string_add(json_mg_row, "name",
8616 mg->mesh_group_name);
8617 json_object_string_add(json_mg_row, "source", src_str);
8618 } else {
8619 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
8620 vty_out(vty, " Source : %s\n", src_str);
8621 vty_out(vty, " Member State\n");
8622 }
8623
8624 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
8625 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
8626 if (mbr->mp) {
8627 state = mbr->mp->state;
8628 } else {
8629 state = PIM_MSDP_DISABLED;
8630 }
8631 pim_msdp_state_dump(state, state_str, sizeof(state_str));
e2809e61 8632 if (json) {
d62a17ae 8633 json_row = json_object_new_object();
8634 json_object_string_add(json_row, "member", mbr_str);
8635 json_object_string_add(json_row, "state", state_str);
8636 if (!json_members) {
8637 json_members = json_object_new_object();
8638 json_object_object_add(json_mg_row, "members",
8639 json_members);
8640 }
8641 json_object_object_add(json_members, mbr_str, json_row);
8642 } else {
8643 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
8644 }
8645 }
8646
e2809e61 8647 if (json)
d62a17ae 8648 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
977d71cc 8649}
8650
8651DEFUN (show_ip_msdp_mesh_group,
8652 show_ip_msdp_mesh_group_cmd,
20a7e5fd 8653 "show ip msdp [vrf NAME] mesh-group [json]",
977d71cc 8654 SHOW_STR
8655 IP_STR
8656 MSDP_STR
f02d59db 8657 VRF_CMD_HELP_STR
977d71cc 8658 "MSDP mesh-group information\n"
f5da2cc2 8659 JSON_STR)
977d71cc 8660{
9f049418 8661 bool uj = use_json(argc, argv);
c68ba0d7 8662 int idx = 2;
e2809e61 8663 struct pim_msdp_mg *mg;
02a16316 8664 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
e2809e61
RZ
8665 struct pim_instance *pim = vrf->info;
8666 struct json_object *json = NULL;
02a16316
DS
8667
8668 if (!vrf)
8669 return CMD_WARNING;
8670
e2809e61
RZ
8671 /* Quick case: list is empty. */
8672 if (SLIST_EMPTY(&pim->msdp.mglist)) {
8673 if (uj)
8674 vty_out(vty, "{}\n");
8675
8676 return CMD_SUCCESS;
8677 }
8678
8679 if (uj)
8680 json = json_object_new_object();
8681
8682 SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
8683 ip_msdp_show_mesh_group(vty, mg, json);
8684
3757f964
DA
8685 if (uj)
8686 vty_json(vty, json);
d62a17ae 8687
8688 return CMD_SUCCESS;
8689}
8690
a25de56b
DS
8691DEFUN (show_ip_msdp_mesh_group_vrf_all,
8692 show_ip_msdp_mesh_group_vrf_all_cmd,
8693 "show ip msdp vrf all mesh-group [json]",
8694 SHOW_STR
8695 IP_STR
8696 MSDP_STR
8697 VRF_CMD_HELP_STR
8698 "MSDP mesh-group information\n"
f5da2cc2 8699 JSON_STR)
a25de56b 8700{
9f049418 8701 bool uj = use_json(argc, argv);
e2809e61
RZ
8702 struct json_object *json = NULL, *vrf_json = NULL;
8703 struct pim_instance *pim;
8704 struct pim_msdp_mg *mg;
a25de56b 8705 struct vrf *vrf;
a25de56b
DS
8706
8707 if (uj)
e2809e61
RZ
8708 json = json_object_new_object();
8709
a2addae8 8710 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b 8711 if (uj) {
e2809e61
RZ
8712 vrf_json = json_object_new_object();
8713 json_object_object_add(json, vrf->name, vrf_json);
a25de56b
DS
8714 } else
8715 vty_out(vty, "VRF: %s\n", vrf->name);
e2809e61
RZ
8716
8717 pim = vrf->info;
8718 SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
8719 ip_msdp_show_mesh_group(vty, mg, vrf_json);
8720 }
8721
3757f964
DA
8722 if (uj)
8723 vty_json(vty, json);
8724
a25de56b
DS
8725
8726 return CMD_SUCCESS;
8727}
8728
64c86530 8729static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
088f1098 8730 bool uj)
d62a17ae 8731{
8732 struct listnode *mpnode;
8733 struct pim_msdp_peer *mp;
8734 char peer_str[INET_ADDRSTRLEN];
8735 char local_str[INET_ADDRSTRLEN];
8736 char state_str[PIM_MSDP_STATE_STRLEN];
8737 char timebuf[PIM_MSDP_UPTIME_STRLEN];
8738 int64_t now;
8739 json_object *json = NULL;
8740 json_object *json_row = NULL;
8741
8742
8743 if (uj) {
8744 json = json_object_new_object();
8745 } else {
8746 vty_out(vty,
8747 "Peer Local State Uptime SaCnt\n");
8748 }
8749
02a16316 8750 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 8751 if (mp->state == PIM_MSDP_ESTABLISHED) {
8752 now = pim_time_monotonic_sec();
8753 pim_time_uptime(timebuf, sizeof(timebuf),
8754 now - mp->uptime);
8755 } else {
c35b7e6b 8756 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 8757 }
8758 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
8759 pim_inet4_dump("<local?>", mp->local, local_str,
8760 sizeof(local_str));
8761 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
8762 if (uj) {
8763 json_row = json_object_new_object();
8764 json_object_string_add(json_row, "peer", peer_str);
8765 json_object_string_add(json_row, "local", local_str);
8766 json_object_string_add(json_row, "state", state_str);
8767 json_object_string_add(json_row, "upTime", timebuf);
8768 json_object_int_add(json_row, "saCount", mp->sa_cnt);
8769 json_object_object_add(json, peer_str, json_row);
8770 } else {
8771 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
8772 local_str, state_str, timebuf, mp->sa_cnt);
8773 }
8774 }
8775
3757f964
DA
8776 if (uj)
8777 vty_json(vty, json);
d62a17ae 8778}
8779
64c86530 8780static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
088f1098 8781 const char *peer, bool uj)
d62a17ae 8782{
8783 struct listnode *mpnode;
8784 struct pim_msdp_peer *mp;
8785 char peer_str[INET_ADDRSTRLEN];
8786 char local_str[INET_ADDRSTRLEN];
8787 char state_str[PIM_MSDP_STATE_STRLEN];
8788 char timebuf[PIM_MSDP_UPTIME_STRLEN];
8789 char katimer[PIM_MSDP_TIMER_STRLEN];
8790 char crtimer[PIM_MSDP_TIMER_STRLEN];
8791 char holdtimer[PIM_MSDP_TIMER_STRLEN];
8792 int64_t now;
8793 json_object *json = NULL;
8794 json_object *json_row = NULL;
8795
8796 if (uj) {
8797 json = json_object_new_object();
8798 }
8799
02a16316 8800 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 8801 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
8802 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
8803 continue;
8804
8805 if (mp->state == PIM_MSDP_ESTABLISHED) {
8806 now = pim_time_monotonic_sec();
8807 pim_time_uptime(timebuf, sizeof(timebuf),
8808 now - mp->uptime);
8809 } else {
c35b7e6b 8810 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 8811 }
8812 pim_inet4_dump("<local?>", mp->local, local_str,
8813 sizeof(local_str));
8814 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
8815 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
8816 mp->ka_timer);
8817 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
8818 mp->cr_timer);
8819 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
8820 mp->hold_timer);
8821
8822 if (uj) {
8823 json_row = json_object_new_object();
8824 json_object_string_add(json_row, "peer", peer_str);
8825 json_object_string_add(json_row, "local", local_str);
0ce04a08
RZ
8826 if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
8827 json_object_string_add(json_row,
8828 "meshGroupName",
8829 mp->mesh_group_name);
d62a17ae 8830 json_object_string_add(json_row, "state", state_str);
8831 json_object_string_add(json_row, "upTime", timebuf);
8832 json_object_string_add(json_row, "keepAliveTimer",
8833 katimer);
8834 json_object_string_add(json_row, "connRetryTimer",
8835 crtimer);
8836 json_object_string_add(json_row, "holdTimer",
8837 holdtimer);
8838 json_object_string_add(json_row, "lastReset",
8839 mp->last_reset);
8840 json_object_int_add(json_row, "connAttempts",
8841 mp->conn_attempts);
8842 json_object_int_add(json_row, "establishedChanges",
8843 mp->est_flaps);
8844 json_object_int_add(json_row, "saCount", mp->sa_cnt);
8845 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
8846 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
8847 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
8848 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
8849 json_object_object_add(json, peer_str, json_row);
8850 } else {
8851 vty_out(vty, "Peer : %s\n", peer_str);
8852 vty_out(vty, " Local : %s\n", local_str);
0ce04a08
RZ
8853 if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
8854 vty_out(vty, " Mesh Group : %s\n",
8855 mp->mesh_group_name);
d62a17ae 8856 vty_out(vty, " State : %s\n", state_str);
8857 vty_out(vty, " Uptime : %s\n", timebuf);
8858
8859 vty_out(vty, " Keepalive Timer : %s\n", katimer);
8860 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
8861 vty_out(vty, " Hold Timer : %s\n", holdtimer);
8862 vty_out(vty, " Last Reset : %s\n",
8863 mp->last_reset);
8864 vty_out(vty, " Conn Attempts : %d\n",
8865 mp->conn_attempts);
8866 vty_out(vty, " Established Changes : %d\n",
8867 mp->est_flaps);
8868 vty_out(vty, " SA Count : %d\n",
8869 mp->sa_cnt);
8870 vty_out(vty, " Statistics :\n");
8871 vty_out(vty,
8872 " Sent Rcvd\n");
8873 vty_out(vty, " Keepalives : %10d %10d\n",
8874 mp->ka_tx_cnt, mp->ka_rx_cnt);
8875 vty_out(vty, " SAs : %10d %10d\n",
8876 mp->sa_tx_cnt, mp->sa_rx_cnt);
8877 vty_out(vty, "\n");
8878 }
8879 }
8880
3757f964
DA
8881 if (uj)
8882 vty_json(vty, json);
977d71cc 8883}
8884
8885DEFUN (show_ip_msdp_peer_detail,
8886 show_ip_msdp_peer_detail_cmd,
20a7e5fd 8887 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
2a333e0f 8888 SHOW_STR
8889 IP_STR
8890 MSDP_STR
f02d59db 8891 VRF_CMD_HELP_STR
2a333e0f 8892 "MSDP peer information\n"
977d71cc 8893 "Detailed output\n"
8894 "peer ip address\n"
f5da2cc2 8895 JSON_STR)
2a333e0f 8896{
9f049418 8897 bool uj = use_json(argc, argv);
c68ba0d7 8898 int idx = 2;
02a16316 8899 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 8900
07a29355
QY
8901 if (!vrf)
8902 return CMD_WARNING;
8903
8904 char *arg = NULL;
8905
8906 if (argv_find(argv, argc, "detail", &idx))
8907 arg = argv[idx]->text;
8908 else if (argv_find(argv, argc, "A.B.C.D", &idx))
8909 arg = argv[idx]->arg;
8910
8911 if (arg)
64c86530 8912 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 8913 else
64c86530 8914 ip_msdp_show_peers(vrf->info, vty, uj);
d62a17ae 8915
8916 return CMD_SUCCESS;
8917}
8918
a25de56b
DS
8919DEFUN (show_ip_msdp_peer_detail_vrf_all,
8920 show_ip_msdp_peer_detail_vrf_all_cmd,
8921 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8922 SHOW_STR
8923 IP_STR
8924 MSDP_STR
8925 VRF_CMD_HELP_STR
8926 "MSDP peer information\n"
8927 "Detailed output\n"
8928 "peer ip address\n"
f5da2cc2 8929 JSON_STR)
a25de56b
DS
8930{
8931 int idx = 2;
9f049418 8932 bool uj = use_json(argc, argv);
a25de56b
DS
8933 struct vrf *vrf;
8934 bool first = true;
8935
8936 if (uj)
8937 vty_out(vty, "{ ");
a2addae8 8938 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
8939 if (uj) {
8940 if (!first)
8941 vty_out(vty, ", ");
8942 vty_out(vty, " \"%s\": ", vrf->name);
8943 first = false;
8944 } else
8945 vty_out(vty, "VRF: %s\n", vrf->name);
8946 if (argv_find(argv, argc, "detail", &idx)
8947 || argv_find(argv, argc, "A.B.C.D", &idx))
8948 ip_msdp_show_peers_detail(vrf->info, vty,
8949 argv[idx]->arg, uj);
8950 else
8951 ip_msdp_show_peers(vrf->info, vty, uj);
8952 }
8953 if (uj)
8954 vty_out(vty, "}\n");
8955
8956 return CMD_SUCCESS;
8957}
8958
088f1098 8959static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 8960{
8961 struct listnode *sanode;
8962 struct pim_msdp_sa *sa;
d62a17ae 8963 char rp_str[INET_ADDRSTRLEN];
8964 char timebuf[PIM_MSDP_UPTIME_STRLEN];
8965 char spt_str[8];
8966 char local_str[8];
8967 int64_t now;
8968 json_object *json = NULL;
8969 json_object *json_group = NULL;
8970 json_object *json_row = NULL;
8971
8972 if (uj) {
8973 json = json_object_new_object();
8974 } else {
8975 vty_out(vty,
8976 "Source Group RP Local SPT Uptime\n");
8977 }
8978
02a16316 8979 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 8980 now = pim_time_monotonic_sec();
8981 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
d62a17ae 8982 if (sa->flags & PIM_MSDP_SAF_PEER) {
8983 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
8984 if (sa->up) {
c35b7e6b 8985 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 8986 } else {
c35b7e6b 8987 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 8988 }
8989 } else {
c35b7e6b
QY
8990 strlcpy(rp_str, "-", sizeof(rp_str));
8991 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 8992 }
8993 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 8994 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 8995 } else {
c35b7e6b 8996 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 8997 }
8998 if (uj) {
8e8be741
DL
8999 char src_str[PIM_ADDRSTRLEN];
9000 char grp_str[PIM_ADDRSTRLEN];
9001
9002 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
9003 &sa->sg.grp);
9004 snprintfrr(src_str, sizeof(src_str), "%pPAs",
9005 &sa->sg.src);
9006
d62a17ae 9007 json_object_object_get_ex(json, grp_str, &json_group);
9008
9009 if (!json_group) {
9010 json_group = json_object_new_object();
9011 json_object_object_add(json, grp_str,
9012 json_group);
9013 }
9014
9015 json_row = json_object_new_object();
9016 json_object_string_add(json_row, "source", src_str);
9017 json_object_string_add(json_row, "group", grp_str);
9018 json_object_string_add(json_row, "rp", rp_str);
9019 json_object_string_add(json_row, "local", local_str);
9020 json_object_string_add(json_row, "sptSetup", spt_str);
9021 json_object_string_add(json_row, "upTime", timebuf);
9022 json_object_object_add(json_group, src_str, json_row);
9023 } else {
8e8be741
DL
9024 vty_out(vty, "%-15pPAs %15pPAs %15s %5c %3c %8s\n",
9025 &sa->sg.src, &sa->sg.grp, rp_str, local_str[0],
d62a17ae 9026 spt_str[0], timebuf);
9027 }
9028 }
9029
3757f964
DA
9030 if (uj)
9031 vty_json(vty, json);
d62a17ae 9032}
9033
9034static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
9035 const char *src_str,
9036 const char *grp_str, struct vty *vty,
088f1098 9037 bool uj, json_object *json)
d62a17ae 9038{
9039 char rp_str[INET_ADDRSTRLEN];
9040 char peer_str[INET_ADDRSTRLEN];
9041 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9042 char spt_str[8];
9043 char local_str[8];
9044 char statetimer[PIM_MSDP_TIMER_STRLEN];
9045 int64_t now;
9046 json_object *json_group = NULL;
9047 json_object *json_row = NULL;
9048
9049 now = pim_time_monotonic_sec();
9050 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9051 if (sa->flags & PIM_MSDP_SAF_PEER) {
9052 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9053 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
9054 if (sa->up) {
c35b7e6b 9055 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 9056 } else {
c35b7e6b 9057 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 9058 }
9059 } else {
c35b7e6b
QY
9060 strlcpy(rp_str, "-", sizeof(rp_str));
9061 strlcpy(peer_str, "-", sizeof(peer_str));
9062 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 9063 }
9064 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 9065 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 9066 } else {
c35b7e6b 9067 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 9068 }
9069 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
9070 sa->sa_state_timer);
9071 if (uj) {
9072 json_object_object_get_ex(json, grp_str, &json_group);
9073
9074 if (!json_group) {
9075 json_group = json_object_new_object();
9076 json_object_object_add(json, grp_str, json_group);
9077 }
9078
9079 json_row = json_object_new_object();
9080 json_object_string_add(json_row, "source", src_str);
9081 json_object_string_add(json_row, "group", grp_str);
9082 json_object_string_add(json_row, "rp", rp_str);
9083 json_object_string_add(json_row, "local", local_str);
9084 json_object_string_add(json_row, "sptSetup", spt_str);
9085 json_object_string_add(json_row, "upTime", timebuf);
9086 json_object_string_add(json_row, "stateTimer", statetimer);
9087 json_object_object_add(json_group, src_str, json_row);
9088 } else {
9089 vty_out(vty, "SA : %s\n", sa->sg_str);
9090 vty_out(vty, " RP : %s\n", rp_str);
9091 vty_out(vty, " Peer : %s\n", peer_str);
9092 vty_out(vty, " Local : %s\n", local_str);
9093 vty_out(vty, " SPT Setup : %s\n", spt_str);
9094 vty_out(vty, " Uptime : %s\n", timebuf);
9095 vty_out(vty, " State Timer : %s\n", statetimer);
9096 vty_out(vty, "\n");
9097 }
9098}
9099
64c86530 9100static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
088f1098 9101 bool uj)
d62a17ae 9102{
9103 struct listnode *sanode;
9104 struct pim_msdp_sa *sa;
d62a17ae 9105 json_object *json = NULL;
9106
9107 if (uj) {
9108 json = json_object_new_object();
9109 }
9110
02a16316 9111 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8e8be741
DL
9112 char src_str[PIM_ADDRSTRLEN];
9113 char grp_str[PIM_ADDRSTRLEN];
9114
9115 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
9116 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
9117
d62a17ae 9118 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
9119 json);
9120 }
9121
3757f964
DA
9122 if (uj)
9123 vty_json(vty, json);
977d71cc 9124}
9125
9126DEFUN (show_ip_msdp_sa_detail,
9127 show_ip_msdp_sa_detail_cmd,
20a7e5fd 9128 "show ip msdp [vrf NAME] sa detail [json]",
3c72d654 9129 SHOW_STR
9130 IP_STR
9131 MSDP_STR
f02d59db 9132 VRF_CMD_HELP_STR
3c72d654 9133 "MSDP active-source information\n"
977d71cc 9134 "Detailed output\n"
f5da2cc2 9135 JSON_STR)
3c72d654 9136{
9f049418 9137 bool uj = use_json(argc, argv);
c68ba0d7 9138 int idx = 2;
02a16316
DS
9139 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9140
9141 if (!vrf)
9142 return CMD_WARNING;
9143
64c86530 9144 ip_msdp_show_sa_detail(vrf->info, vty, uj);
977d71cc 9145
d62a17ae 9146 return CMD_SUCCESS;
977d71cc 9147}
9148
a25de56b
DS
9149DEFUN (show_ip_msdp_sa_detail_vrf_all,
9150 show_ip_msdp_sa_detail_vrf_all_cmd,
9151 "show ip msdp vrf all sa detail [json]",
9152 SHOW_STR
9153 IP_STR
9154 MSDP_STR
9155 VRF_CMD_HELP_STR
9156 "MSDP active-source information\n"
9157 "Detailed output\n"
f5da2cc2 9158 JSON_STR)
a25de56b 9159{
9f049418 9160 bool uj = use_json(argc, argv);
a25de56b
DS
9161 struct vrf *vrf;
9162 bool first = true;
9163
9164 if (uj)
9165 vty_out(vty, "{ ");
a2addae8 9166 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9167 if (uj) {
9168 if (!first)
9169 vty_out(vty, ", ");
9170 vty_out(vty, " \"%s\": ", vrf->name);
9171 first = false;
9172 } else
9173 vty_out(vty, "VRF: %s\n", vrf->name);
9174 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9175 }
9176 if (uj)
9177 vty_out(vty, "}\n");
9178
9179 return CMD_SUCCESS;
9180}
9181
64c86530 9182static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
088f1098 9183 const char *addr, bool uj)
977d71cc 9184{
d62a17ae 9185 struct listnode *sanode;
9186 struct pim_msdp_sa *sa;
d62a17ae 9187 json_object *json = NULL;
977d71cc 9188
d62a17ae 9189 if (uj) {
9190 json = json_object_new_object();
9191 }
977d71cc 9192
02a16316 9193 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8e8be741
DL
9194 char src_str[PIM_ADDRSTRLEN];
9195 char grp_str[PIM_ADDRSTRLEN];
9196
9197 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
9198 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
9199
d62a17ae 9200 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
9201 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9202 uj, json);
9203 }
9204 }
977d71cc 9205
3757f964
DA
9206 if (uj)
9207 vty_json(vty, json);
977d71cc 9208}
9209
64c86530 9210static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
088f1098 9211 const char *src, const char *grp, bool uj)
977d71cc 9212{
d62a17ae 9213 struct listnode *sanode;
9214 struct pim_msdp_sa *sa;
d62a17ae 9215 json_object *json = NULL;
977d71cc 9216
d62a17ae 9217 if (uj) {
9218 json = json_object_new_object();
9219 }
977d71cc 9220
02a16316 9221 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8e8be741
DL
9222 char src_str[PIM_ADDRSTRLEN];
9223 char grp_str[PIM_ADDRSTRLEN];
9224
9225 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
9226 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
9227
d62a17ae 9228 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
9229 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9230 uj, json);
9231 }
9232 }
977d71cc 9233
3757f964
DA
9234 if (uj)
9235 vty_json(vty, json);
977d71cc 9236}
9237
9238DEFUN (show_ip_msdp_sa_sg,
9239 show_ip_msdp_sa_sg_cmd,
20a7e5fd 9240 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
977d71cc 9241 SHOW_STR
9242 IP_STR
9243 MSDP_STR
f02d59db 9244 VRF_CMD_HELP_STR
977d71cc 9245 "MSDP active-source information\n"
9246 "source or group ip\n"
a957a05b 9247 "group ip\n"
f5da2cc2 9248 JSON_STR)
977d71cc 9249{
9f049418 9250 bool uj = use_json(argc, argv);
02a16316 9251 struct vrf *vrf;
c68ba0d7 9252 int idx = 2;
02a16316
DS
9253
9254 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9255
9256 if (!vrf)
9257 return CMD_WARNING;
9258
d62a17ae 9259 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
521c5b9d 9260 : NULL;
d62a17ae 9261 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
521c5b9d
MS
9262 ? argv[idx]->arg
9263 : NULL;
9ea49d61 9264
d62a17ae 9265 if (src_ip && grp_ip)
64c86530 9266 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
d62a17ae 9267 else if (src_ip)
64c86530 9268 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
d62a17ae 9269 else
64c86530 9270 ip_msdp_show_sa(vrf->info, vty, uj);
3c72d654 9271
d62a17ae 9272 return CMD_SUCCESS;
3c72d654 9273}
9274
47bf9e21
DS
9275DEFUN (show_ip_msdp_sa_sg_vrf_all,
9276 show_ip_msdp_sa_sg_vrf_all_cmd,
9277 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9278 SHOW_STR
9279 IP_STR
9280 MSDP_STR
9281 VRF_CMD_HELP_STR
9282 "MSDP active-source information\n"
9283 "source or group ip\n"
9284 "group ip\n"
9285 JSON_STR)
9286{
9f049418 9287 bool uj = use_json(argc, argv);
47bf9e21
DS
9288 struct vrf *vrf;
9289 bool first = true;
9290 int idx = 2;
9291
9292 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
521c5b9d 9293 : NULL;
47bf9e21 9294 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
521c5b9d
MS
9295 ? argv[idx]->arg
9296 : NULL;
47bf9e21
DS
9297
9298 if (uj)
9299 vty_out(vty, "{ ");
a2addae8 9300 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
47bf9e21
DS
9301 if (uj) {
9302 if (!first)
9303 vty_out(vty, ", ");
9304 vty_out(vty, " \"%s\": ", vrf->name);
9305 first = false;
9306 } else
9307 vty_out(vty, "VRF: %s\n", vrf->name);
9308
9309 if (src_ip && grp_ip)
9310 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
9311 else if (src_ip)
9312 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
9313 else
9314 ip_msdp_show_sa(vrf->info, vty, uj);
9315 }
9316 if (uj)
9317 vty_out(vty, "}\n");
9318
9319 return CMD_SUCCESS;
9320}
9321
f1e2901a
AK
9322struct pim_sg_cache_walk_data {
9323 struct vty *vty;
9324 json_object *json;
9325 json_object *json_group;
9326 struct in_addr addr;
9327 bool addr_match;
9328};
9329
9330static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
521c5b9d 9331 struct pim_sg_cache_walk_data *cwd)
f1e2901a
AK
9332{
9333 struct vty *vty = cwd->vty;
9334 json_object *json = cwd->json;
f1e2901a 9335 json_object *json_row;
2951a7a4 9336 bool installed = (vxlan_sg->up) ? true : false;
f1e2901a
AK
9337 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
9338 const char *oif_name;
9339
9340 if (pim_vxlan_is_orig_mroute(vxlan_sg))
9341 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
9342 else
9343 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
9344
032a7412
DL
9345 if (cwd->addr_match && pim_addr_cmp(vxlan_sg->sg.src, cwd->addr) &&
9346 pim_addr_cmp(vxlan_sg->sg.grp, cwd->addr)) {
f1e2901a
AK
9347 return;
9348 }
f1e2901a 9349 if (json) {
8e8be741
DL
9350 char src_str[PIM_ADDRSTRLEN];
9351 char grp_str[PIM_ADDRSTRLEN];
9352
9353 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
9354 &vxlan_sg->sg.grp);
9355 snprintfrr(src_str, sizeof(src_str), "%pPAs",
9356 &vxlan_sg->sg.src);
9357
f1e2901a
AK
9358 json_object_object_get_ex(json, grp_str, &cwd->json_group);
9359
9360 if (!cwd->json_group) {
9361 cwd->json_group = json_object_new_object();
9362 json_object_object_add(json, grp_str,
521c5b9d 9363 cwd->json_group);
f1e2901a
AK
9364 }
9365
9366 json_row = json_object_new_object();
9367 json_object_string_add(json_row, "source", src_str);
9368 json_object_string_add(json_row, "group", grp_str);
9369 json_object_string_add(json_row, "input", iif_name);
9370 json_object_string_add(json_row, "output", oif_name);
9371 if (installed)
9372 json_object_boolean_true_add(json_row, "installed");
9373 else
9374 json_object_boolean_false_add(json_row, "installed");
9375 json_object_object_add(cwd->json_group, src_str, json_row);
9376 } else {
8e8be741
DL
9377 vty_out(vty, "%-15pPAs %-15pPAs %-15s %-15s %-5s\n",
9378 &vxlan_sg->sg.src, &vxlan_sg->sg.grp, iif_name,
9379 oif_name, installed ? "I" : "");
f1e2901a
AK
9380 }
9381}
9382
1ac88792 9383static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *bucket, void *arg)
f1e2901a 9384{
1ac88792 9385 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)bucket->data,
521c5b9d 9386 (struct pim_sg_cache_walk_data *)arg);
f1e2901a
AK
9387}
9388
9389static void pim_show_vxlan_sg(struct pim_instance *pim,
521c5b9d 9390 struct vty *vty, bool uj)
f1e2901a
AK
9391{
9392 json_object *json = NULL;
9393 struct pim_sg_cache_walk_data cwd;
9394
9395 if (uj) {
9396 json = json_object_new_object();
9397 } else {
9398 vty_out(vty, "Codes: I -> installed\n");
9399 vty_out(vty,
9400 "Source Group Input Output Flags\n");
9401 }
9402
9403 memset(&cwd, 0, sizeof(cwd));
9404 cwd.vty = vty;
9405 cwd.json = json;
9406 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
9407
3757f964
DA
9408 if (uj)
9409 vty_json(vty, json);
f1e2901a
AK
9410}
9411
9412static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
521c5b9d
MS
9413 struct vty *vty, char *addr_str,
9414 bool uj)
f1e2901a
AK
9415{
9416 json_object *json = NULL;
9417 struct pim_sg_cache_walk_data cwd;
9418 int result = 0;
9419
9420 memset(&cwd, 0, sizeof(cwd));
9421 result = inet_pton(AF_INET, addr_str, &cwd.addr);
9422 if (result <= 0) {
9423 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
521c5b9d 9424 errno, safe_strerror(errno));
f1e2901a
AK
9425 return;
9426 }
9427
9428 if (uj) {
9429 json = json_object_new_object();
9430 } else {
9431 vty_out(vty, "Codes: I -> installed\n");
9432 vty_out(vty,
9433 "Source Group Input Output Flags\n");
9434 }
9435
9436 cwd.vty = vty;
9437 cwd.json = json;
2951a7a4 9438 cwd.addr_match = true;
f1e2901a
AK
9439 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
9440
3757f964
DA
9441 if (uj)
9442 vty_json(vty, json);
f1e2901a
AK
9443}
9444
9445static void pim_show_vxlan_sg_one(struct pim_instance *pim,
521c5b9d
MS
9446 struct vty *vty, char *src_str, char *grp_str,
9447 bool uj)
f1e2901a
AK
9448{
9449 json_object *json = NULL;
6fff2cc6 9450 pim_sgaddr sg;
f1e2901a
AK
9451 int result = 0;
9452 struct pim_vxlan_sg *vxlan_sg;
9453 const char *iif_name;
9454 bool installed;
9455 const char *oif_name;
9456
9457 result = inet_pton(AF_INET, src_str, &sg.src);
9458 if (result <= 0) {
9459 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
521c5b9d 9460 errno, safe_strerror(errno));
f1e2901a
AK
9461 return;
9462 }
9463 result = inet_pton(AF_INET, grp_str, &sg.grp);
9464 if (result <= 0) {
9465 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
521c5b9d 9466 errno, safe_strerror(errno));
f1e2901a
AK
9467 return;
9468 }
9469
f1e2901a
AK
9470 if (uj)
9471 json = json_object_new_object();
9472
9473 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
9474 if (vxlan_sg) {
2951a7a4 9475 installed = (vxlan_sg->up) ? true : false;
f1e2901a
AK
9476 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
9477
9478 if (pim_vxlan_is_orig_mroute(vxlan_sg))
9479 oif_name =
9480 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
9481 else
9482 oif_name =
9483 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
9484
9485 if (uj) {
9486 json_object_string_add(json, "source", src_str);
9487 json_object_string_add(json, "group", grp_str);
9488 json_object_string_add(json, "input", iif_name);
9489 json_object_string_add(json, "output", oif_name);
9490 if (installed)
9491 json_object_boolean_true_add(json, "installed");
9492 else
9493 json_object_boolean_false_add(json,
521c5b9d 9494 "installed");
f1e2901a
AK
9495 } else {
9496 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
9497 vty_out(vty, " Input : %s\n", iif_name);
9498 vty_out(vty, " Output : %s\n", oif_name);
9499 vty_out(vty, " installed : %s\n",
9500 installed?"yes":"no");
9501 }
9502 }
9503
3757f964
DA
9504 if (uj)
9505 vty_json(vty, json);
f1e2901a
AK
9506}
9507
9508DEFUN (show_ip_pim_vxlan_sg,
9509 show_ip_pim_vxlan_sg_cmd,
9510 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
9511 SHOW_STR
9512 IP_STR
9513 PIM_STR
9514 VRF_CMD_HELP_STR
9515 "VxLAN BUM groups\n"
9516 "source or group ip\n"
9517 "group ip\n"
9518 JSON_STR)
9519{
9520 bool uj = use_json(argc, argv);
9521 struct vrf *vrf;
9522 int idx = 2;
9523
9524 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9525
9526 if (!vrf)
9527 return CMD_WARNING;
9528
9529 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
9530 argv[idx++]->arg:NULL;
9531 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
9532 argv[idx]->arg:NULL;
9533
9534 if (src_ip && grp_ip)
9535 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
9536 else if (src_ip)
9537 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
9538 else
9539 pim_show_vxlan_sg(vrf->info, vty, uj);
9540
9541 return CMD_SUCCESS;
9542}
9543
9544static void pim_show_vxlan_sg_work(struct pim_instance *pim,
521c5b9d 9545 struct vty *vty, bool uj)
f1e2901a
AK
9546{
9547 json_object *json = NULL;
9548 struct pim_sg_cache_walk_data cwd;
9549 struct listnode *node;
9550 struct pim_vxlan_sg *vxlan_sg;
9551
9552 if (uj) {
9553 json = json_object_new_object();
9554 } else {
9555 vty_out(vty, "Codes: I -> installed\n");
9556 vty_out(vty,
9557 "Source Group Input Flags\n");
9558 }
9559
9560 memset(&cwd, 0, sizeof(cwd));
9561 cwd.vty = vty;
9562 cwd.json = json;
9563 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
9564 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
9565
3757f964
DA
9566 if (uj)
9567 vty_json(vty, json);
f1e2901a
AK
9568}
9569
9570DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
9571 show_ip_pim_vxlan_sg_work_cmd,
9572 "show ip pim [vrf NAME] vxlan-work [json]",
9573 SHOW_STR
9574 IP_STR
9575 PIM_STR
9576 VRF_CMD_HELP_STR
9577 "VxLAN work list\n"
9578 JSON_STR)
9579{
9580 bool uj = use_json(argc, argv);
9581 struct vrf *vrf;
9582 int idx = 2;
9583
9584 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9585
9586 if (!vrf)
9587 return CMD_WARNING;
9588
9589 pim_show_vxlan_sg_work(vrf->info, vty, uj);
9590
9591 return CMD_SUCCESS;
9592}
9593
7c85225c 9594DEFUN_HIDDEN (no_ip_pim_mlag,
521c5b9d
MS
9595 no_ip_pim_mlag_cmd,
9596 "no ip pim mlag",
9597 NO_STR
9598 IP_STR
9599 PIM_STR
9600 "MLAG\n")
7c85225c 9601{
0c949724 9602 char mlag_xpath[XPATH_MAXLEN];
7c85225c 9603
698f4147 9604 snprintf(mlag_xpath, sizeof(mlag_xpath), FRR_PIM_VRF_XPATH,
0c949724
SP
9605 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
9606 strlcat(mlag_xpath, "/mlag", sizeof(mlag_xpath));
7c85225c 9607
0c949724
SP
9608 nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL);
9609
9610
9611 return nb_cli_apply_changes(vty, NULL);
7c85225c
AK
9612}
9613
9614DEFUN_HIDDEN (ip_pim_mlag,
521c5b9d
MS
9615 ip_pim_mlag_cmd,
9616 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
9617 IP_STR
9618 PIM_STR
9619 "MLAG\n"
9620 "peerlink sub interface\n"
9621 "MLAG role\n"
9622 "MLAG role primary\n"
9623 "MLAG role secondary\n"
9624 "peer session state\n"
9625 "peer session state up\n"
9626 "peer session state down\n"
9627 "configure PIP\n"
9628 "unique ip address\n")
7c85225c 9629{
7c85225c 9630 int idx;
0c949724
SP
9631 char mlag_peerlink_rif_xpath[XPATH_MAXLEN];
9632 char mlag_my_role_xpath[XPATH_MAXLEN];
9633 char mlag_peer_state_xpath[XPATH_MAXLEN];
9634 char mlag_reg_address_xpath[XPATH_MAXLEN];
9635
9636 snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath),
698f4147 9637 FRR_PIM_VRF_XPATH,
0c949724
SP
9638 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
9639 strlcat(mlag_peerlink_rif_xpath, "/mlag/peerlink-rif",
9640 sizeof(mlag_peerlink_rif_xpath));
7c85225c
AK
9641
9642 idx = 3;
0c949724 9643 nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY,
521c5b9d 9644 argv[idx]->arg);
0c949724
SP
9645
9646 snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath),
698f4147 9647 FRR_PIM_VRF_XPATH,
0c949724
SP
9648 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
9649 strlcat(mlag_my_role_xpath, "/mlag/my-role",
9650 sizeof(mlag_my_role_xpath));
7c85225c
AK
9651
9652 idx += 2;
9653 if (!strcmp(argv[idx]->arg, "primary")) {
0c949724 9654 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
521c5b9d 9655 "MLAG_ROLE_PRIMARY");
0c949724 9656
7c85225c 9657 } else if (!strcmp(argv[idx]->arg, "secondary")) {
0c949724 9658 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
521c5b9d 9659 "MLAG_ROLE_SECONDARY");
0c949724 9660
7c85225c
AK
9661 } else {
9662 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
9663 return CMD_WARNING;
9664 }
9665
0c949724 9666 snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath),
698f4147 9667 FRR_PIM_VRF_XPATH,
0c949724
SP
9668 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
9669 strlcat(mlag_peer_state_xpath, "/mlag/peer-state",
9670 sizeof(mlag_peer_state_xpath));
9671
7c85225c
AK
9672 idx += 2;
9673 if (!strcmp(argv[idx]->arg, "up")) {
0c949724 9674 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
521c5b9d 9675 "true");
0c949724 9676
7c85225c 9677 } else if (strcmp(argv[idx]->arg, "down")) {
0c949724 9678 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
521c5b9d 9679 "false");
0c949724 9680
7c85225c
AK
9681 } else {
9682 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
9683 return CMD_WARNING;
9684 }
9685
0c949724 9686 snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath),
698f4147 9687 FRR_PIM_VRF_XPATH,
0c949724
SP
9688 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
9689 strlcat(mlag_reg_address_xpath, "/mlag/reg-address",
9690 sizeof(mlag_reg_address_xpath));
9691
7c85225c 9692 idx += 2;
0c949724 9693 nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY,
521c5b9d 9694 argv[idx]->arg);
7c85225c 9695
0c949724 9696 return nb_cli_apply_changes(vty, NULL);
7c85225c
AK
9697}
9698
c68ba0d7 9699void pim_cmd_init(void)
12e41d03 9700{
9da01b0b 9701 if_cmd_init(pim_interface_config_write);
d62a17ae 9702
612c2c15 9703 install_node(&debug_node);
d62a17ae 9704
70fd22bd
DS
9705 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
9706
d62a17ae 9707 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
9ecb7b77 9708 install_element(VRF_NODE, &ip_pim_rp_cmd);
d62a17ae 9709 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
9ecb7b77 9710 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
d62a17ae 9711 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
4f9f3925 9712 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
d62a17ae 9713 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
4f9f3925 9714 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
d62a17ae 9715 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
4f9f3925 9716 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
d62a17ae 9717 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
4f9f3925 9718 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
d62a17ae 9719 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
4f9f3925 9720 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
d62a17ae 9721 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
9722 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
9723 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
4f9f3925 9724 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
d62a17ae 9725 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 9726 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 9727 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
4f9f3925 9728 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
d62a17ae 9729 install_element(CONFIG_NODE,
9730 &no_ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 9731 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
f4e74bd0
DS
9732 install_element(CONFIG_NODE, &pim_register_accept_list_cmd);
9733 install_element(VRF_NODE, &pim_register_accept_list_cmd);
d62a17ae 9734 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
9735 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
9736 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
4f9f3925 9737 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
cc14df13
DS
9738 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
9739 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
d62a17ae 9740 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
4f9f3925 9741 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
cc14df13
DS
9742 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
9743 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
d62a17ae 9744 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
9745 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
9746 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
4f9f3925 9747 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
d62a17ae 9748 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
4f9f3925 9749 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
d62a17ae 9750 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
4f9f3925 9751 install_element(VRF_NODE, &ip_ssmpingd_cmd);
d62a17ae 9752 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
4f9f3925 9753 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
d62a17ae 9754 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
4f9f3925 9755 install_element(VRF_NODE, &ip_msdp_peer_cmd);
d62a17ae 9756 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
4f9f3925 9757 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
d62a17ae 9758 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
4f9f3925 9759 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
d62a17ae 9760 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
4f9f3925 9761 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
d62a17ae 9762 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
4f9f3925 9763 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
d62a17ae 9764 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
4f9f3925 9765 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
7c85225c
AK
9766 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
9767 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
339f7695 9768 install_element(CONFIG_NODE, &igmp_group_watermark_cmd);
9769 install_element(VRF_NODE, &igmp_group_watermark_cmd);
9770 install_element(CONFIG_NODE, &no_igmp_group_watermark_cmd);
9771 install_element(VRF_NODE, &no_igmp_group_watermark_cmd);
d62a17ae 9772
9773 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
9774 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
9775 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
9776 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
9777 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
9778 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
9779 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
9780 install_element(INTERFACE_NODE,
9781 &interface_no_ip_igmp_query_interval_cmd);
9782 install_element(INTERFACE_NODE,
9783 &interface_ip_igmp_query_max_response_time_cmd);
9784 install_element(INTERFACE_NODE,
9785 &interface_no_ip_igmp_query_max_response_time_cmd);
9786 install_element(INTERFACE_NODE,
9787 &interface_ip_igmp_query_max_response_time_dsec_cmd);
9788 install_element(INTERFACE_NODE,
9789 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
59115451
SP
9790 install_element(INTERFACE_NODE,
9791 &interface_ip_igmp_last_member_query_count_cmd);
9792 install_element(INTERFACE_NODE,
9793 &interface_no_ip_igmp_last_member_query_count_cmd);
9794 install_element(INTERFACE_NODE,
9795 &interface_ip_igmp_last_member_query_interval_cmd);
9796 install_element(INTERFACE_NODE,
9797 &interface_no_ip_igmp_last_member_query_interval_cmd);
414d885a 9798 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
d62a17ae 9799 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
9800 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
9801 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
9802 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
2f5e937c 9803 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
9804 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
d62a17ae 9805 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
9806 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
9807 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
9808 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
b0f525a8
QY
9809 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
9810 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
6741a5bb 9811 install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
d62a17ae 9812
9813 // Static mroutes NEB
9814 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
d62a17ae 9815 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
d62a17ae 9816
9817 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
a25de56b 9818 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
d62a17ae 9819 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
a25de56b 9820 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
d62a17ae 9821 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
a25de56b 9822 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
d62a17ae 9823 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
9824 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
9825 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
21313cbf 9826 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
d62a17ae 9827 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
9828 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
9829 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
9830 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
9831 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
9832 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
a25de56b 9833 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
d62a17ae 9834 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
a25de56b 9835 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
87b7cd5b 9836 install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
d62a17ae 9837 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
f80427e9
AK
9838 install_element(VIEW_NODE, &show_ip_pim_mlag_summary_cmd);
9839 install_element(VIEW_NODE, &show_ip_pim_mlag_up_cmd);
9840 install_element(VIEW_NODE, &show_ip_pim_mlag_up_vrf_all_cmd);
d62a17ae 9841 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
a25de56b 9842 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
d62a17ae 9843 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
a25de56b 9844 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
d62a17ae 9845 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
9846 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
a25de56b 9847 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
d62a17ae 9848 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
a25de56b 9849 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
5c9a72ef 9850 install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
d62a17ae 9851 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
9852 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
9853 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
a25de56b 9854 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
256392eb 9855 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
d62a17ae 9856 install_element(VIEW_NODE, &show_ip_multicast_cmd);
a25de56b 9857 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
8c8d7031
SP
9858 install_element(VIEW_NODE, &show_ip_multicast_count_cmd);
9859 install_element(VIEW_NODE, &show_ip_multicast_count_vrf_all_cmd);
d62a17ae 9860 install_element(VIEW_NODE, &show_ip_mroute_cmd);
b283a4ca 9861 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
d62a17ae 9862 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
5c3aac90 9863 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
468b6f44
SP
9864 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
9865 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
d62a17ae 9866 install_element(VIEW_NODE, &show_ip_rib_cmd);
9867 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
d62a17ae 9868 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
9869 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
321295c1 9870 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
0d1a4e24 9871 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
415f6350 9872 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
d62a17ae 9873
cd333cf9 9874 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
d62a17ae 9875 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
9876 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
9877 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
9878 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
9879 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
9880 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
415f6350 9881 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
e7016ceb 9882 install_element(ENABLE_NODE, &clear_ip_pim_bsr_db_cmd);
d62a17ae 9883
dd73744d
IR
9884 install_element(ENABLE_NODE, &show_debugging_pim_cmd);
9885
d62a17ae 9886 install_element(ENABLE_NODE, &debug_igmp_cmd);
9887 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
9888 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
9889 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
9890 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
9891 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
9892 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
9893 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
9894 install_element(ENABLE_NODE, &debug_mroute_cmd);
9895 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
9896 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
9897 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
9898 install_element(ENABLE_NODE, &debug_pim_static_cmd);
9899 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
d62a17ae 9900 install_element(ENABLE_NODE, &debug_pim_cmd);
9901 install_element(ENABLE_NODE, &no_debug_pim_cmd);
40f1f31b
DS
9902 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
9903 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
6d733f0d
SG
9904 install_element(ENABLE_NODE, &debug_pim_nht_det_cmd);
9905 install_element(ENABLE_NODE, &no_debug_pim_nht_det_cmd);
3d225d48
DS
9906 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
9907 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 9908 install_element(ENABLE_NODE, &debug_pim_events_cmd);
9909 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
9910 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
9911 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
9912 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
9913 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
9914 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
9915 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
9916 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
9917 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
9918 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
9919 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 9920 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
9921 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
9922 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
9923 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
36b5b98f
SK
9924 install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
9925 install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
4d913fa6
AK
9926 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
9927 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 9928 install_element(ENABLE_NODE, &debug_msdp_cmd);
9929 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
d62a17ae 9930 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
9931 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
d62a17ae 9932 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
9933 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
9934 install_element(ENABLE_NODE, &debug_mtrace_cmd);
9935 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
09524ccf 9936 install_element(ENABLE_NODE, &debug_bsm_cmd);
9937 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
d62a17ae 9938
9939 install_element(CONFIG_NODE, &debug_igmp_cmd);
9940 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
9941 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
9942 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
9943 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
9944 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
9945 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
9946 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
9947 install_element(CONFIG_NODE, &debug_mroute_cmd);
9948 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
9949 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
9950 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
9951 install_element(CONFIG_NODE, &debug_pim_static_cmd);
9952 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
d62a17ae 9953 install_element(CONFIG_NODE, &debug_pim_cmd);
9954 install_element(CONFIG_NODE, &no_debug_pim_cmd);
40f1f31b
DS
9955 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
9956 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
6d733f0d
SG
9957 install_element(CONFIG_NODE, &debug_pim_nht_det_cmd);
9958 install_element(CONFIG_NODE, &no_debug_pim_nht_det_cmd);
3d225d48
DS
9959 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
9960 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 9961 install_element(CONFIG_NODE, &debug_pim_events_cmd);
9962 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
9963 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
9964 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
5c4508cb 9965 install_element(CONFIG_NODE, &debug_pim_packetdump_send_cmd);
9966 install_element(CONFIG_NODE, &no_debug_pim_packetdump_send_cmd);
9967 install_element(CONFIG_NODE, &debug_pim_packetdump_recv_cmd);
9968 install_element(CONFIG_NODE, &no_debug_pim_packetdump_recv_cmd);
d62a17ae 9969 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
9970 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
9971 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
9972 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 9973 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
9974 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
9975 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
9976 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
f80427e9
AK
9977 install_element(CONFIG_NODE, &debug_pim_mlag_cmd);
9978 install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd);
4d913fa6
AK
9979 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
9980 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 9981 install_element(CONFIG_NODE, &debug_msdp_cmd);
9982 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
d62a17ae 9983 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
9984 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
d62a17ae 9985 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
9986 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
9987 install_element(CONFIG_NODE, &debug_mtrace_cmd);
9988 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
09524ccf 9989 install_element(CONFIG_NODE, &debug_bsm_cmd);
9990 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
02a16316 9991
622fd3f1
RZ
9992 install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
9993 install_element(VRF_NODE, &ip_msdp_timers_cmd);
11ca3587
CH
9994 install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd);
9995 install_element(VRF_NODE, &no_ip_msdp_timers_cmd);
d62a17ae 9996 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
02a16316 9997 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
d62a17ae 9998 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
1b973cb7 9999 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
d62a17ae 10000 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
02a16316 10001 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
d62a17ae 10002 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
02a16316 10003 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
34d86eff
SP
10004 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd);
10005 install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd);
d62a17ae 10006 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
a25de56b 10007 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
d62a17ae 10008 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
a25de56b 10009 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
d62a17ae 10010 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
47bf9e21 10011 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
d62a17ae 10012 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
a25de56b 10013 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
d62a17ae 10014 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
10015 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
f1e2901a
AK
10016 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
10017 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
d62a17ae 10018 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
10019 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
16c926c8 10020 /* Install BSM command */
10021 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
10022 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
10023 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
10024 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
d62a17ae 10025 /* Install BFD command */
10026 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
10027 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
745b8d4a 10028 install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd);
d62a17ae 10029 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
64dc4b2d 10030#if HAVE_BFDD == 0
d62a17ae 10031 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
64dc4b2d 10032#endif /* !HAVE_BFDD */
12e41d03 10033}