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