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