]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
Merge pull request #5767 from ton31337/fix/replace_s_addr_0_to_INADDR_ANY
[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) {
975a328e 1744 if (sg->grp.s_addr != INADDR_ANY
6de45bcc
DS
1745 && sg->grp.s_addr != ch->sg.grp.s_addr)
1746 continue;
975a328e 1747 if (sg->src.s_addr != INADDR_ANY
6de45bcc 1748 && sg->src.s_addr != ch->sg.src.s_addr)
975a328e 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
975a328e
DA
2451 if (sg->grp.s_addr != INADDR_ANY
2452 && sg->grp.s_addr != up->sg.grp.s_addr)
dff5cedb 2453 continue;
975a328e
DA
2454 if (sg->src.s_addr != INADDR_ANY
2455 && sg->src.s_addr != up->sg.src.s_addr)
dff5cedb
DS
2456 continue;
2457
d62a17ae 2458 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2459 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2460 pim_time_uptime(uptime, sizeof(uptime),
2461 now - up->state_transition);
2462 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
2463 up->t_join_timer);
2464
2465 /*
d8bed89d
SP
2466 * If the upstream is not dummy and it has a J/P timer for the
2467 * neighbor display that
d62a17ae 2468 */
d8bed89d 2469 if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
d62a17ae 2470 struct pim_neighbor *nbr;
2471
2472 nbr = pim_neighbor_find(
2473 up->rpf.source_nexthop.interface,
2474 up->rpf.rpf_addr.u.prefix4);
2475 if (nbr)
2476 pim_time_timer_to_hhmmss(join_timer,
2477 sizeof(join_timer),
2478 nbr->jp_timer);
2479 }
2480
2481 pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
2482 up->t_rs_timer);
2483 pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
2484 up->t_ka_timer);
2485 pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
2486 up->t_msdp_reg_timer);
2487
c35b7e6b 2488 pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str));
d62a17ae 2489 if (up->reg_state != PIM_REG_NOINFO) {
2490 char tmp_str[PIM_REG_STATE_STR_LEN];
2491
2492 sprintf(state_str + strlen(state_str), ",%s",
c35b7e6b
QY
2493 pim_reg_state2brief_str(up->reg_state, tmp_str,
2494 sizeof(tmp_str)));
d62a17ae 2495 }
2496
2497 if (uj) {
2498 json_object_object_get_ex(json, grp_str, &json_group);
2499
2500 if (!json_group) {
2501 json_group = json_object_new_object();
2502 json_object_object_add(json, grp_str,
2503 json_group);
2504 }
2505
2506 json_row = json_object_new_object();
2507 json_object_pim_upstream_add(json_row, up);
2508 json_object_string_add(
d8bed89d
SP
2509 json_row, "inboundInterface",
2510 up->rpf.source_nexthop.interface
2511 ? up->rpf.source_nexthop.interface->name
2512 : "Unknown");
48f41fe8
DS
2513
2514 /*
2515 * The RPF address we use is slightly different
2516 * based upon what we are looking up.
2517 * If we have a S, list that unless
2518 * we are the FHR, else we just put
2519 * the RP as the rpfAddress
2520 */
996c9314
LB
2521 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR
2522 || up->sg.src.s_addr == INADDR_ANY) {
48f41fe8
DS
2523 char rpf[PREFIX_STRLEN];
2524 struct pim_rpf *rpg;
2525
2526 rpg = RP(pim, up->sg.grp);
2527 pim_inet4_dump("<rpf?>",
996c9314
LB
2528 rpg->rpf_addr.u.prefix4, rpf,
2529 sizeof(rpf));
2530 json_object_string_add(json_row, "rpfAddress",
2531 rpf);
48f41fe8 2532 } else {
996c9314
LB
2533 json_object_string_add(json_row, "rpfAddress",
2534 src_str);
48f41fe8
DS
2535 }
2536
d62a17ae 2537 json_object_string_add(json_row, "source", src_str);
2538 json_object_string_add(json_row, "group", grp_str);
2539 json_object_string_add(json_row, "state", state_str);
2540 json_object_string_add(
2541 json_row, "joinState",
2542 pim_upstream_state2str(up->join_state));
2543 json_object_string_add(
2544 json_row, "regState",
c35b7e6b 2545 pim_reg_state2str(up->reg_state, state_str, sizeof(state_str)));
d62a17ae 2546 json_object_string_add(json_row, "upTime", uptime);
2547 json_object_string_add(json_row, "joinTimer",
2548 join_timer);
2549 json_object_string_add(json_row, "resetTimer",
2550 rs_timer);
2551 json_object_string_add(json_row, "keepaliveTimer",
2552 ka_timer);
2553 json_object_string_add(json_row, "msdpRegTimer",
2554 msdp_reg_timer);
2555 json_object_int_add(json_row, "refCount",
2556 up->ref_count);
2557 json_object_int_add(json_row, "sptBit", up->sptbit);
2558 json_object_object_add(json_group, src_str, json_row);
2559 } else {
2560 vty_out(vty,
ff415346 2561 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
d8bed89d
SP
2562 up->rpf.source_nexthop.interface
2563 ? up->rpf.source_nexthop.interface->name
2564 : "Unknown",
2565 src_str, grp_str, state_str, uptime, join_timer,
d62a17ae 2566 rs_timer, ka_timer, up->ref_count);
2567 }
2568 }
2569
2570 if (uj) {
9d303b37
DL
2571 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2572 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2573 json_object_free(json);
2574 }
12e41d03
DL
2575}
2576
5c9a72ef 2577static void pim_show_channel_helper(struct pim_instance *pim,
1a8a3da8
DS
2578 struct vty *vty,
2579 struct pim_interface *pim_ifp,
2580 struct pim_ifchannel *ch,
088f1098 2581 json_object *json, bool uj)
12e41d03 2582{
1a8a3da8
DS
2583 struct pim_upstream *up = ch->upstream;
2584 json_object *json_group = NULL;
d62a17ae 2585 char src_str[INET_ADDRSTRLEN];
2586 char grp_str[INET_ADDRSTRLEN];
d62a17ae 2587 json_object *json_row = NULL;
2588
1a8a3da8
DS
2589 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2590 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
d62a17ae 2591
1a8a3da8
DS
2592 if (uj) {
2593 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 2594
1a8a3da8
DS
2595 if (!json_group) {
2596 json_group = json_object_new_object();
996c9314 2597 json_object_object_add(json, grp_str, json_group);
1a8a3da8 2598 }
d62a17ae 2599
1a8a3da8
DS
2600 json_row = json_object_new_object();
2601 json_object_pim_upstream_add(json_row, up);
2602 json_object_string_add(json_row, "interface",
2603 ch->interface->name);
2604 json_object_string_add(json_row, "source", src_str);
2605 json_object_string_add(json_row, "group", grp_str);
d62a17ae 2606
1a8a3da8 2607 if (pim_macro_ch_lost_assert(ch))
996c9314 2608 json_object_boolean_true_add(json_row, "lostAssert");
d62a17ae 2609
1a8a3da8
DS
2610 if (pim_macro_chisin_joins(ch))
2611 json_object_boolean_true_add(json_row, "joins");
d62a17ae 2612
1a8a3da8 2613 if (pim_macro_chisin_pim_include(ch))
996c9314 2614 json_object_boolean_true_add(json_row, "pimInclude");
d62a17ae 2615
1a8a3da8 2616 if (pim_upstream_evaluate_join_desired(pim, up))
996c9314
LB
2617 json_object_boolean_true_add(json_row,
2618 "evaluateJoinDesired");
d62a17ae 2619
1a8a3da8 2620 json_object_object_add(json_group, src_str, json_row);
d62a17ae 2621
1a8a3da8 2622 } else {
ff415346 2623 vty_out(vty, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
1a8a3da8
DS
2624 ch->interface->name, src_str, grp_str,
2625 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2626 pim_macro_chisin_joins(ch) ? "yes" : "no",
2627 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
996c9314
LB
2628 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
2629 ? "yes"
2630 : "no",
2631 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2632 : "no");
1a8a3da8
DS
2633 }
2634}
d62a17ae 2635
5c9a72ef 2636static void pim_show_channel(struct pim_instance *pim, struct vty *vty,
088f1098 2637 bool uj)
1a8a3da8 2638{
1a8a3da8
DS
2639 struct pim_interface *pim_ifp;
2640 struct pim_ifchannel *ch;
2641 struct interface *ifp;
d62a17ae 2642
1a8a3da8 2643 json_object *json = NULL;
d62a17ae 2644
1a8a3da8
DS
2645 if (uj)
2646 json = json_object_new_object();
2647 else
2648 vty_out(vty,
ff415346 2649 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
1a8a3da8
DS
2650
2651 /* scan per-interface (S,G) state */
451fda4f 2652 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1a8a3da8
DS
2653 pim_ifp = ifp->info;
2654 if (!pim_ifp)
2655 continue;
2656
ad7b74c4 2657
a2addae8 2658 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1a8a3da8 2659 /* scan all interfaces */
5c9a72ef 2660 pim_show_channel_helper(pim, vty, pim_ifp, ch,
1a8a3da8 2661 json, uj);
d62a17ae 2662 }
2663 }
2664
2665 if (uj) {
9d303b37
DL
2666 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2667 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2668 json_object_free(json);
2669 }
12e41d03
DL
2670}
2671
8ff637c8
AK
2672static void pim_show_join_desired_helper(struct pim_instance *pim,
2673 struct vty *vty,
2674 struct pim_upstream *up,
2675 json_object *json, bool uj)
2676{
2677 json_object *json_group = NULL;
2678 char src_str[INET_ADDRSTRLEN];
2679 char grp_str[INET_ADDRSTRLEN];
2680 json_object *json_row = NULL;
2681
2682 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2683 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2684
2685 if (uj) {
2686 json_object_object_get_ex(json, grp_str, &json_group);
2687
2688 if (!json_group) {
2689 json_group = json_object_new_object();
2690 json_object_object_add(json, grp_str, json_group);
2691 }
2692
2693 json_row = json_object_new_object();
2694 json_object_pim_upstream_add(json_row, up);
2695 json_object_string_add(json_row, "source", src_str);
2696 json_object_string_add(json_row, "group", grp_str);
2697
2698 if (pim_upstream_evaluate_join_desired(pim, up))
2699 json_object_boolean_true_add(json_row,
2700 "evaluateJoinDesired");
2701
2702 json_object_object_add(json_group, src_str, json_row);
2703
2704 } else {
2705 vty_out(vty, "%-15s %-15s %-6s\n",
2706 src_str, grp_str,
2707 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2708 : "no");
2709 }
2710}
2711
2712static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
2713 bool uj)
2714{
8ff637c8
AK
2715 struct pim_upstream *up;
2716
2717 json_object *json = NULL;
2718
2719 if (uj)
2720 json = json_object_new_object();
2721 else
2722 vty_out(vty,
2723 "Source Group EvalJD\n");
2724
dd3364cb 2725 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
8ff637c8
AK
2726 /* scan all interfaces */
2727 pim_show_join_desired_helper(pim, vty, up,
2728 json, uj);
2729 }
2730
2731 if (uj) {
2732 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2733 json, JSON_C_TO_STRING_PRETTY));
2734 json_object_free(json);
2735 }
2736}
2737
64c86530 2738static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
088f1098 2739 bool uj)
12e41d03 2740{
d62a17ae 2741 struct pim_upstream *up;
2742 json_object *json = NULL;
2743 json_object *json_group = NULL;
2744 json_object *json_row = NULL;
2745
2746 if (uj)
2747 json = json_object_new_object();
2748 else
2749 vty_out(vty,
ff415346 2750 "Source Group RpfIface RibNextHop RpfAddress \n");
d62a17ae 2751
dd3364cb 2752 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
d62a17ae 2753 char src_str[INET_ADDRSTRLEN];
2754 char grp_str[INET_ADDRSTRLEN];
2755 char rpf_nexthop_str[PREFIX_STRLEN];
2756 char rpf_addr_str[PREFIX_STRLEN];
2757 struct pim_rpf *rpf;
2758 const char *rpf_ifname;
2759
2760 rpf = &up->rpf;
2761
2762 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2763 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2764 pim_addr_dump("<nexthop?>",
2765 &rpf->source_nexthop.mrib_nexthop_addr,
2766 rpf_nexthop_str, sizeof(rpf_nexthop_str));
2767 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2768 sizeof(rpf_addr_str));
2769
9d303b37 2770 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2771
2772 if (uj) {
2773 json_object_object_get_ex(json, grp_str, &json_group);
2774
2775 if (!json_group) {
2776 json_group = json_object_new_object();
2777 json_object_object_add(json, grp_str,
2778 json_group);
2779 }
2780
2781 json_row = json_object_new_object();
2782 json_object_pim_upstream_add(json_row, up);
2783 json_object_string_add(json_row, "source", src_str);
2784 json_object_string_add(json_row, "group", grp_str);
2785 json_object_string_add(json_row, "rpfInterface",
2786 rpf_ifname);
2787 json_object_string_add(json_row, "ribNexthop",
2788 rpf_nexthop_str);
2789 json_object_string_add(json_row, "rpfAddress",
2790 rpf_addr_str);
2791 json_object_object_add(json_group, src_str, json_row);
2792 } else {
ff415346 2793 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s\n", src_str,
d62a17ae 2794 grp_str, rpf_ifname, rpf_nexthop_str,
2795 rpf_addr_str);
2796 }
2797 }
2798
2799 if (uj) {
9d303b37
DL
2800 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2801 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2802 json_object_free(json);
2803 }
2804}
2805
da11e325
DS
2806static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
2807 time_t now, json_object *json)
d62a17ae 2808{
2809 char refresh_uptime[10];
2810
2811 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
bfc92019 2812 pim->rpf_cache_refresh_last);
d62a17ae 2813
2814 if (json) {
2815 json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
da03883e 2816 router->rpf_cache_refresh_delay_msec);
d62a17ae 2817 json_object_int_add(
2818 json, "rpfCacheRefreshTimer",
da11e325 2819 pim_time_timer_remain_msec(pim->rpf_cache_refresher));
d62a17ae 2820 json_object_int_add(json, "rpfCacheRefreshRequests",
bfc92019 2821 pim->rpf_cache_refresh_requests);
d62a17ae 2822 json_object_int_add(json, "rpfCacheRefreshEvents",
bfc92019 2823 pim->rpf_cache_refresh_events);
d62a17ae 2824 json_object_string_add(json, "rpfCacheRefreshLast",
2825 refresh_uptime);
2826 json_object_int_add(json, "nexthopLookups",
bfc92019 2827 pim->nexthop_lookups);
d62a17ae 2828 json_object_int_add(json, "nexthopLookupsAvoided",
bfc92019 2829 pim->nexthop_lookups_avoided);
d62a17ae 2830 } else {
2831 vty_out(vty,
2832 "RPF Cache Refresh Delay: %ld msecs\n"
2833 "RPF Cache Refresh Timer: %ld msecs\n"
2834 "RPF Cache Refresh Requests: %lld\n"
2835 "RPF Cache Refresh Events: %lld\n"
2836 "RPF Cache Refresh Last: %s\n"
2837 "Nexthop Lookups: %lld\n"
2838 "Nexthop Lookups Avoided: %lld\n",
da03883e 2839 router->rpf_cache_refresh_delay_msec,
da11e325 2840 pim_time_timer_remain_msec(pim->rpf_cache_refresher),
bfc92019
DS
2841 (long long)pim->rpf_cache_refresh_requests,
2842 (long long)pim->rpf_cache_refresh_events,
2843 refresh_uptime, (long long)pim->nexthop_lookups,
2844 (long long)pim->nexthop_lookups_avoided);
d62a17ae 2845 }
12e41d03
DL
2846}
2847
64c86530 2848static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2849 time_t now)
12e41d03 2850{
d62a17ae 2851 char uptime_scan_oil[10];
2852 char uptime_mroute_add[10];
2853 char uptime_mroute_del[10];
12e41d03 2854
d62a17ae 2855 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
bfc92019 2856 pim->scan_oil_last);
d62a17ae 2857 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
c68ba0d7 2858 pim->mroute_add_last);
d62a17ae 2859 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
c68ba0d7 2860 pim->mroute_del_last);
12e41d03 2861
d62a17ae 2862 vty_out(vty,
2863 "Scan OIL - Last: %s Events: %lld\n"
2864 "MFC Add - Last: %s Events: %lld\n"
2865 "MFC Del - Last: %s Events: %lld\n",
bfc92019 2866 uptime_scan_oil, (long long)pim->scan_oil_events,
c68ba0d7
DS
2867 uptime_mroute_add, (long long)pim->mroute_add_events,
2868 uptime_mroute_del, (long long)pim->mroute_del_events);
12e41d03
DL
2869}
2870
088f1098 2871static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
12e41d03 2872{
d62a17ae 2873 struct pim_upstream *up;
2874 time_t now = pim_time_monotonic_sec();
2875 json_object *json = NULL;
2876 json_object *json_group = NULL;
2877 json_object *json_row = NULL;
2878
2879 if (uj) {
2880 json = json_object_new_object();
da11e325 2881 show_rpf_refresh_stats(vty, pim, now, json);
d62a17ae 2882 } else {
da11e325 2883 show_rpf_refresh_stats(vty, pim, now, json);
d62a17ae 2884 vty_out(vty, "\n");
2885 vty_out(vty,
ff415346 2886 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
d62a17ae 2887 }
cba44481 2888
dd3364cb 2889 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
d62a17ae 2890 char src_str[INET_ADDRSTRLEN];
2891 char grp_str[INET_ADDRSTRLEN];
2892 char rpf_addr_str[PREFIX_STRLEN];
2893 char rib_nexthop_str[PREFIX_STRLEN];
2894 const char *rpf_ifname;
2895 struct pim_rpf *rpf = &up->rpf;
2896
2897 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2898 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2899 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2900 sizeof(rpf_addr_str));
2901 pim_addr_dump("<nexthop?>",
2902 &rpf->source_nexthop.mrib_nexthop_addr,
2903 rib_nexthop_str, sizeof(rib_nexthop_str));
2904
9d303b37 2905 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2906
2907 if (uj) {
2908 json_object_object_get_ex(json, grp_str, &json_group);
2909
2910 if (!json_group) {
2911 json_group = json_object_new_object();
2912 json_object_object_add(json, grp_str,
2913 json_group);
2914 }
2915
2916 json_row = json_object_new_object();
2917 json_object_string_add(json_row, "source", src_str);
2918 json_object_string_add(json_row, "group", grp_str);
2919 json_object_string_add(json_row, "rpfInterface",
2920 rpf_ifname);
2921 json_object_string_add(json_row, "rpfAddress",
2922 rpf_addr_str);
2923 json_object_string_add(json_row, "ribNexthop",
2924 rib_nexthop_str);
2925 json_object_int_add(
2926 json_row, "routeMetric",
2927 rpf->source_nexthop.mrib_route_metric);
2928 json_object_int_add(
2929 json_row, "routePreference",
2930 rpf->source_nexthop.mrib_metric_preference);
2931 json_object_object_add(json_group, src_str, json_row);
2932
2933 } else {
ff415346 2934 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
d62a17ae 2935 src_str, grp_str, rpf_ifname, rpf_addr_str,
2936 rib_nexthop_str,
2937 rpf->source_nexthop.mrib_route_metric,
2938 rpf->source_nexthop.mrib_metric_preference);
2939 }
2940 }
2941
2942 if (uj) {
9d303b37
DL
2943 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2944 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2945 json_object_free(json);
2946 }
cba44481
CS
2947}
2948
c68ba0d7
DS
2949struct pnc_cache_walk_data {
2950 struct vty *vty;
2951 struct pim_instance *pim;
2952};
2953
e3b78da8 2954static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
12e41d03 2955{
e3b78da8 2956 struct pim_nexthop_cache *pnc = bucket->data;
c68ba0d7
DS
2957 struct pnc_cache_walk_data *cwd = arg;
2958 struct vty *vty = cwd->vty;
2959 struct pim_instance *pim = cwd->pim;
d62a17ae 2960 struct nexthop *nh_node = NULL;
2961 ifindex_t first_ifindex;
2962 struct interface *ifp = NULL;
2963
d62a17ae 2964 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
2965 first_ifindex = nh_node->ifindex;
c68ba0d7 2966 ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
d62a17ae 2967
2968 vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
ff415346 2969 vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
d62a17ae 2970 vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
2971 vty_out(vty, "\n");
2972 }
2973 return CMD_SUCCESS;
2974}
2975
64c86530 2976static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
d62a17ae 2977{
c68ba0d7 2978 struct pnc_cache_walk_data cwd;
d62a17ae 2979
c68ba0d7
DS
2980 cwd.vty = vty;
2981 cwd.pim = pim;
2982 vty_out(vty, "Number of registered addresses: %lu\n",
2983 pim->rpf_hash->count);
ff415346
DS
2984 vty_out(vty, "Address Interface Nexthop\n");
2985 vty_out(vty, "---------------------------------------------\n");
12e41d03 2986
c68ba0d7 2987 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
d62a17ae 2988}
2989
0d1a4e24 2990/* Display the bsm database details */
2991static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
2992{
2993 struct listnode *bsmnode;
2994 int count = 0;
2995 int fragment = 1;
2996 struct bsm_info *bsm;
2997 json_object *json = NULL;
2998 json_object *json_group = NULL;
2999 json_object *json_row = NULL;
3000
3001 count = pim->global_scope.bsm_list->count;
3002
3003 if (uj) {
3004 json = json_object_new_object();
3005 json_object_int_add(json, "Number of the fragments", count);
3006 } else {
3007 vty_out(vty, "Scope Zone: Global\n");
3008 vty_out(vty, "Number of the fragments: %d\n", count);
3009 vty_out(vty, "\n");
3010 }
3011
3012 for (ALL_LIST_ELEMENTS_RO(pim->global_scope.bsm_list, bsmnode, bsm)) {
3013 char grp_str[INET_ADDRSTRLEN];
3014 char rp_str[INET_ADDRSTRLEN];
3015 char bsr_str[INET_ADDRSTRLEN];
3016 struct bsmmsg_grpinfo *group;
3017 struct bsmmsg_rpinfo *rpaddr;
3018 struct prefix grp;
3019 struct bsm_hdr *hdr;
3020 uint32_t offset = 0;
3021 uint8_t *buf;
3022 uint32_t len = 0;
3023 uint32_t frag_rp_cnt = 0;
3024
3025 buf = bsm->bsm;
3026 len = bsm->size;
3027
3028 /* skip pim header */
3029 buf += PIM_MSG_HEADER_LEN;
3030 len -= PIM_MSG_HEADER_LEN;
3031
3032 hdr = (struct bsm_hdr *)buf;
3033
3034 /* BSM starts with bsr header */
3035 buf += sizeof(struct bsm_hdr);
3036 len -= sizeof(struct bsm_hdr);
3037
3038 pim_inet4_dump("<BSR Address?>", hdr->bsr_addr.addr, bsr_str,
3039 sizeof(bsr_str));
3040
3041
3042 if (uj) {
3043 json_object_string_add(json, "BSR address", bsr_str);
3044 json_object_int_add(json, "BSR priority",
3045 hdr->bsr_prio);
3046 json_object_int_add(json, "Hashmask Length",
3047 hdr->hm_len);
3048 json_object_int_add(json, "Fragment Tag",
3049 ntohs(hdr->frag_tag));
3050 } else {
3051 vty_out(vty, "BSM Fragment : %d\n", fragment);
3052 vty_out(vty, "------------------\n");
3053 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3054 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3055 vty_out(vty, "%-15s %-15d %-15d %-15d\n", bsr_str,
3056 hdr->bsr_prio, hdr->hm_len,
3057 ntohs(hdr->frag_tag));
3058 }
3059
3060 vty_out(vty, "\n");
3061
3062 while (offset < len) {
3063 group = (struct bsmmsg_grpinfo *)buf;
3064
3065 if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
3066 grp.family = AF_INET;
3067
3068 grp.prefixlen = group->group.mask;
3069 grp.u.prefix4.s_addr = group->group.addr.s_addr;
3070
3071 prefix2str(&grp, grp_str, sizeof(grp_str));
3072
3073 buf += sizeof(struct bsmmsg_grpinfo);
3074 offset += sizeof(struct bsmmsg_grpinfo);
3075
3076 if (uj) {
3077 json_object_object_get_ex(json, grp_str,
3078 &json_group);
3079 if (!json_group) {
3080 json_group = json_object_new_object();
3081 json_object_int_add(json_group,
3082 "Rp Count",
3083 group->rp_count);
3084 json_object_int_add(
3085 json_group, "Fragment Rp count",
3086 group->frag_rp_count);
3087 json_object_object_add(json, grp_str,
3088 json_group);
3089 }
3090 } else {
3091 vty_out(vty, "Group : %s\n", grp_str);
3092 vty_out(vty, "-------------------\n");
3093 vty_out(vty, "Rp Count:%d\n", group->rp_count);
3094 vty_out(vty, "Fragment Rp Count : %d\n",
3095 group->frag_rp_count);
3096 }
3097
3098 frag_rp_cnt = group->frag_rp_count;
3099
3100 if (!frag_rp_cnt)
3101 continue;
3102
3103 if (!uj)
3104 vty_out(vty,
3105 "RpAddress HoldTime Priority\n");
3106
3107 while (frag_rp_cnt--) {
3108 rpaddr = (struct bsmmsg_rpinfo *)buf;
3109
3110 buf += sizeof(struct bsmmsg_rpinfo);
3111 offset += sizeof(struct bsmmsg_rpinfo);
3112
3113 pim_inet4_dump("<Rp addr?>",
3114 rpaddr->rpaddr.addr, rp_str,
3115 sizeof(rp_str));
3116
3117 if (uj) {
3118 json_row = json_object_new_object();
3119 json_object_string_add(
3120 json_row, "Rp Address", rp_str);
3121 json_object_int_add(
3122 json_row, "Rp HoldTime",
3123 ntohs(rpaddr->rp_holdtime));
3124 json_object_int_add(json_row,
3125 "Rp Priority",
3126 rpaddr->rp_pri);
3127 json_object_object_add(
3128 json_group, rp_str, json_row);
3129 } else {
3130 vty_out(vty, "%-15s %-12d %d\n", rp_str,
3131 ntohs(rpaddr->rp_holdtime),
3132 rpaddr->rp_pri);
3133 }
3134 }
3135 vty_out(vty, "\n");
3136 }
3137
3138 fragment++;
3139 }
3140
3141 if (uj) {
3142 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3143 json, JSON_C_TO_STRING_PRETTY));
3144 json_object_free(json);
3145 }
3146}
3147
321295c1 3148/*Display the group-rp mappings */
3149static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
3150 struct vty *vty, bool uj)
3151{
3152 struct bsgrp_node *bsgrp;
3153 struct listnode *rpnode;
3154 struct bsm_rpinfo *bsm_rp;
3155 struct route_node *rn;
3156 char bsr_str[INET_ADDRSTRLEN];
3157 json_object *json = NULL;
3158 json_object *json_group = NULL;
3159 json_object *json_row = NULL;
3160
3161 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY)
fbd74c7d 3162 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
321295c1 3163
3164 else
3165 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str,
3166 sizeof(bsr_str));
3167
3168 if (uj) {
3169 json = json_object_new_object();
3170 json_object_string_add(json, "BSR Address", bsr_str);
3171 } else {
3172 vty_out(vty, "BSR Address %s\n", bsr_str);
3173 }
3174
3175 for (rn = route_top(pim->global_scope.bsrp_table); rn;
3176 rn = route_next(rn)) {
3177 bsgrp = (struct bsgrp_node *)rn->info;
3178
3179 if (!bsgrp)
3180 continue;
3181
3182 char grp_str[INET_ADDRSTRLEN];
3183
3184 prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
3185
3186 if (uj) {
3187 json_object_object_get_ex(json, grp_str, &json_group);
3188 if (!json_group) {
3189 json_group = json_object_new_object();
3190 json_object_object_add(json, grp_str,
3191 json_group);
3192 }
3193 } else {
3194 vty_out(vty, "Group Address %s\n", grp_str);
3195 vty_out(vty, "--------------------------\n");
3196 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3197 "priority", "Holdtime", "Hash");
3198
3199 vty_out(vty, "(ACTIVE)\n");
3200 }
3201
3202 if (bsgrp->bsrp_list) {
3203 for (ALL_LIST_ELEMENTS_RO(bsgrp->bsrp_list, rpnode,
3204 bsm_rp)) {
3205 char rp_str[INET_ADDRSTRLEN];
3206
3207 pim_inet4_dump("<Rp Address?>",
3208 bsm_rp->rp_address, rp_str,
3209 sizeof(rp_str));
3210
3211 if (uj) {
3212 json_row = json_object_new_object();
3213 json_object_string_add(
3214 json_row, "Rp Address", rp_str);
3215 json_object_int_add(
3216 json_row, "Rp HoldTime",
3217 bsm_rp->rp_holdtime);
3218 json_object_int_add(json_row,
3219 "Rp Priority",
3220 bsm_rp->rp_prio);
3221 json_object_int_add(json_row,
3222 "Hash Val",
3223 bsm_rp->hash);
3224 json_object_object_add(
3225 json_group, rp_str, json_row);
3226
3227 } else {
3228 vty_out(vty,
3229 "%-15s %-15u %-15u %-15u\n",
3230 rp_str, bsm_rp->rp_prio,
3231 bsm_rp->rp_holdtime,
3232 bsm_rp->hash);
3233 }
3234 }
3235 if (!bsgrp->bsrp_list->count && !uj)
3236 vty_out(vty, "Active List is empty.\n");
3237 }
3238
3239 if (uj) {
3240 json_object_int_add(json_group, "Pending RP count",
3241 bsgrp->pend_rp_cnt);
3242 } else {
3243 vty_out(vty, "(PENDING)\n");
3244 vty_out(vty, "Pending RP count :%d\n",
3245 bsgrp->pend_rp_cnt);
3246 if (bsgrp->pend_rp_cnt)
3247 vty_out(vty, "%-15s %-15s %-15s %-15s\n",
3248 "Rp Address", "priority", "Holdtime",
3249 "Hash");
3250 }
3251
3252 if (bsgrp->partial_bsrp_list) {
3253 for (ALL_LIST_ELEMENTS_RO(bsgrp->partial_bsrp_list,
3254 rpnode, bsm_rp)) {
3255 char rp_str[INET_ADDRSTRLEN];
3256
3257 pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address,
3258 rp_str, sizeof(rp_str));
3259
3260 if (uj) {
3261 json_row = json_object_new_object();
3262 json_object_string_add(
3263 json_row, "Rp Address", rp_str);
3264 json_object_int_add(
3265 json_row, "Rp HoldTime",
3266 bsm_rp->rp_holdtime);
3267 json_object_int_add(json_row,
3268 "Rp Priority",
3269 bsm_rp->rp_prio);
3270 json_object_int_add(json_row,
3271 "Hash Val",
3272 bsm_rp->hash);
3273 json_object_object_add(
3274 json_group, rp_str, json_row);
3275 } else {
3276 vty_out(vty,
3277 "%-15s %-15u %-15u %-15u\n",
3278 rp_str, bsm_rp->rp_prio,
3279 bsm_rp->rp_holdtime,
3280 bsm_rp->hash);
3281 }
3282 }
3283 if (!bsgrp->partial_bsrp_list->count && !uj)
3284 vty_out(vty, "Partial List is empty\n");
3285 }
3286
3287 if (!uj)
3288 vty_out(vty, "\n");
3289 }
3290
3291 if (uj) {
3292 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3293 json, JSON_C_TO_STRING_PRETTY));
3294 json_object_free(json);
3295 }
3296}
3297
415f6350 3298/* pim statistics - just adding only bsm related now.
3299 * We can continue to add all pim related stats here.
3300 */
3301static void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
3302 const char *ifname, bool uj)
3303{
3304 json_object *json = NULL;
3305 struct interface *ifp;
3306
3307 if (uj) {
3308 json = json_object_new_object();
3309 json_object_int_add(json, "Number of Received BSMs",
3310 pim->bsm_rcvd);
3311 json_object_int_add(json, "Number of Forwared BSMs",
3312 pim->bsm_sent);
3313 json_object_int_add(json, "Number of Dropped BSMs",
3314 pim->bsm_dropped);
3315 } else {
3316 vty_out(vty, "BSM Statistics :\n");
3317 vty_out(vty, "----------------\n");
9a8a7b0e
DS
3318 vty_out(vty, "Number of Received BSMs : %" PRIu64 "\n",
3319 pim->bsm_rcvd);
3320 vty_out(vty, "Number of Forwared BSMs : %" PRIu64 "\n",
3321 pim->bsm_sent);
3322 vty_out(vty, "Number of Dropped BSMs : %" PRIu64 "\n",
415f6350 3323 pim->bsm_dropped);
3324 }
3325
3326 vty_out(vty, "\n");
3327
3328 /* scan interfaces */
3329 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3330 struct pim_interface *pim_ifp = ifp->info;
3331
3332 if (ifname && strcmp(ifname, ifp->name))
3333 continue;
3334
3335 if (!pim_ifp)
3336 continue;
3337
3338 if (!uj) {
3339 vty_out(vty, "Interface : %s\n", ifp->name);
3340 vty_out(vty, "-------------------\n");
3341 vty_out(vty,
3342 "Number of BSMs dropped due to config miss : %u\n",
3343 pim_ifp->pim_ifstat_bsm_cfg_miss);
3344 vty_out(vty, "Number of unicast BSMs dropped : %u\n",
3345 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3346 vty_out(vty,
3347 "Number of BSMs dropped due to invalid scope zone : %u\n",
3348 pim_ifp->pim_ifstat_bsm_invalid_sz);
3349 } else {
3350
3351 json_object *json_row = NULL;
3352
3353 json_row = json_object_new_object();
3354
3355 json_object_string_add(json_row, "If Name", ifp->name);
3356 json_object_int_add(
3357 json_row,
3358 "Number of BSMs dropped due to config miss",
3359 pim_ifp->pim_ifstat_bsm_cfg_miss);
3360 json_object_int_add(
3361 json_row, "Number of unicast BSMs dropped",
3362 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3363 json_object_int_add(json_row,
3364 "Number of BSMs dropped due to invalid scope zone",
3365 pim_ifp->pim_ifstat_bsm_invalid_sz);
3366 json_object_object_add(json, ifp->name, json_row);
3367 }
3368 vty_out(vty, "\n");
3369 }
3370
3371 if (uj) {
3372 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3373 json, JSON_C_TO_STRING_PRETTY));
3374 json_object_free(json);
3375 }
3376}
3377
3378static void clear_pim_statistics(struct pim_instance *pim)
3379{
3380 struct interface *ifp;
3381
3382 pim->bsm_rcvd = 0;
3383 pim->bsm_sent = 0;
3384 pim->bsm_dropped = 0;
3385
3386 /* scan interfaces */
3387 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3388 struct pim_interface *pim_ifp = ifp->info;
3389
3390 if (!pim_ifp)
3391 continue;
3392
3393 pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
3394 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
3395 pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
3396 }
3397}
3398
088f1098 3399static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 3400{
d62a17ae 3401 struct interface *ifp;
3402 time_t now;
3403 json_object *json = NULL;
3404 json_object *json_iface = NULL;
3405 json_object *json_row = NULL;
3406
3407 now = pim_time_monotonic_sec();
3408
3409 if (uj)
3410 json = json_object_new_object();
3411 else
3412 vty_out(vty,
ff415346 3413 "Interface Address Group Mode Timer Srcs V Uptime \n");
d62a17ae 3414
3415 /* scan interfaces */
451fda4f 3416 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3417 struct pim_interface *pim_ifp = ifp->info;
3418 struct listnode *sock_node;
3419 struct igmp_sock *igmp;
3420
3421 if (!pim_ifp)
3422 continue;
3423
3424 /* scan igmp sockets */
3425 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3426 igmp)) {
3427 char ifaddr_str[INET_ADDRSTRLEN];
3428 struct listnode *grpnode;
3429 struct igmp_group *grp;
3430
3431 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3432 sizeof(ifaddr_str));
3433
3434 /* scan igmp groups */
3435 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3436 grpnode, grp)) {
3437 char group_str[INET_ADDRSTRLEN];
3438 char hhmmss[10];
3439 char uptime[10];
3440
3441 pim_inet4_dump("<group?>", grp->group_addr,
3442 group_str, sizeof(group_str));
3443 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
3444 grp->t_group_timer);
3445 pim_time_uptime(uptime, sizeof(uptime),
3446 now - grp->group_creation);
3447
3448 if (uj) {
3449 json_object_object_get_ex(
3450 json, ifp->name, &json_iface);
3451
3452 if (!json_iface) {
3453 json_iface =
3454 json_object_new_object();
3455 json_object_pim_ifp_add(
3456 json_iface, ifp);
3457 json_object_object_add(
3458 json, ifp->name,
3459 json_iface);
3460 }
3461
3462 json_row = json_object_new_object();
3463 json_object_string_add(
3464 json_row, "source", ifaddr_str);
3465 json_object_string_add(
3466 json_row, "group", group_str);
3467
3468 if (grp->igmp_version == 3)
3469 json_object_string_add(
3470 json_row, "mode",
3471 grp->group_filtermode_isexcl
3472 ? "EXCLUDE"
3473 : "INCLUDE");
3474
3475 json_object_string_add(json_row,
3476 "timer", hhmmss);
3477 json_object_int_add(
3478 json_row, "sourcesCount",
3479 grp->group_source_list
3480 ? listcount(
3481 grp->group_source_list)
3482 : 0);
3483 json_object_int_add(json_row, "version",
3484 grp->igmp_version);
3485 json_object_string_add(
3486 json_row, "uptime", uptime);
3487 json_object_object_add(json_iface,
3488 group_str,
3489 json_row);
3490
3491 } else {
3492 vty_out(vty,
ff415346 3493 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
d62a17ae 3494 ifp->name, ifaddr_str,
3495 group_str,
3496 grp->igmp_version == 3
3497 ? (grp->group_filtermode_isexcl
3498 ? "EXCL"
3499 : "INCL")
3500 : "----",
3501 hhmmss,
3502 grp->group_source_list
3503 ? listcount(
3504 grp->group_source_list)
3505 : 0,
3506 grp->igmp_version, uptime);
3507 }
3508 } /* scan igmp groups */
3509 } /* scan igmp sockets */
3510 } /* scan interfaces */
3511
3512 if (uj) {
9d303b37
DL
3513 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3514 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 3515 json_object_free(json);
3516 }
12e41d03
DL
3517}
3518
64c86530
DS
3519static void igmp_show_group_retransmission(struct pim_instance *pim,
3520 struct vty *vty)
12e41d03 3521{
d62a17ae 3522 struct interface *ifp;
3523
3524 vty_out(vty,
ff415346 3525 "Interface Address Group RetTimer Counter RetSrcs\n");
d62a17ae 3526
3527 /* scan interfaces */
451fda4f 3528 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3529 struct pim_interface *pim_ifp = ifp->info;
3530 struct listnode *sock_node;
3531 struct igmp_sock *igmp;
3532
3533 if (!pim_ifp)
3534 continue;
3535
3536 /* scan igmp sockets */
3537 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3538 igmp)) {
3539 char ifaddr_str[INET_ADDRSTRLEN];
3540 struct listnode *grpnode;
3541 struct igmp_group *grp;
3542
3543 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3544 sizeof(ifaddr_str));
3545
3546 /* scan igmp groups */
3547 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3548 grpnode, grp)) {
3549 char group_str[INET_ADDRSTRLEN];
3550 char grp_retr_mmss[10];
3551 struct listnode *src_node;
3552 struct igmp_source *src;
3553 int grp_retr_sources = 0;
3554
3555 pim_inet4_dump("<group?>", grp->group_addr,
3556 group_str, sizeof(group_str));
3557 pim_time_timer_to_mmss(
3558 grp_retr_mmss, sizeof(grp_retr_mmss),
3559 grp->t_group_query_retransmit_timer);
3560
3561
3562 /* count group sources with retransmission state
3563 */
3564 for (ALL_LIST_ELEMENTS_RO(
3565 grp->group_source_list, src_node,
3566 src)) {
3567 if (src->source_query_retransmit_count
3568 > 0) {
3569 ++grp_retr_sources;
3570 }
3571 }
3572
ff415346 3573 vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
d62a17ae 3574 ifp->name, ifaddr_str, group_str,
3575 grp_retr_mmss,
3576 grp->group_specific_query_retransmit_count,
3577 grp_retr_sources);
3578
3579 } /* scan igmp groups */
3580 } /* scan igmp sockets */
3581 } /* scan interfaces */
12e41d03
DL
3582}
3583
64c86530 3584static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
12e41d03 3585{
d62a17ae 3586 struct interface *ifp;
3587 time_t now;
3588
3589 now = pim_time_monotonic_sec();
3590
3591 vty_out(vty,
ff415346 3592 "Interface Address Group Source Timer Fwd Uptime \n");
d62a17ae 3593
3594 /* scan interfaces */
451fda4f 3595 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3596 struct pim_interface *pim_ifp = ifp->info;
3597 struct listnode *sock_node;
3598 struct igmp_sock *igmp;
3599
3600 if (!pim_ifp)
3601 continue;
3602
3603 /* scan igmp sockets */
3604 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3605 igmp)) {
3606 char ifaddr_str[INET_ADDRSTRLEN];
3607 struct listnode *grpnode;
3608 struct igmp_group *grp;
3609
3610 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3611 sizeof(ifaddr_str));
3612
3613 /* scan igmp groups */
3614 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3615 grpnode, grp)) {
3616 char group_str[INET_ADDRSTRLEN];
3617 struct listnode *srcnode;
3618 struct igmp_source *src;
3619
3620 pim_inet4_dump("<group?>", grp->group_addr,
3621 group_str, sizeof(group_str));
3622
3623 /* scan group sources */
3624 for (ALL_LIST_ELEMENTS_RO(
3625 grp->group_source_list, srcnode,
3626 src)) {
3627 char source_str[INET_ADDRSTRLEN];
3628 char mmss[10];
3629 char uptime[10];
3630
3631 pim_inet4_dump(
3632 "<source?>", src->source_addr,
3633 source_str, sizeof(source_str));
3634
3635 pim_time_timer_to_mmss(
3636 mmss, sizeof(mmss),
3637 src->t_source_timer);
3638
3639 pim_time_uptime(
3640 uptime, sizeof(uptime),
3641 now - src->source_creation);
3642
3643 vty_out(vty,
ff415346 3644 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
d62a17ae 3645 ifp->name, ifaddr_str,
3646 group_str, source_str, mmss,
3647 IGMP_SOURCE_TEST_FORWARDING(
3648 src->source_flags)
3649 ? "Y"
3650 : "N",
3651 uptime);
3652
3653 } /* scan group sources */
3654 } /* scan igmp groups */
3655 } /* scan igmp sockets */
3656 } /* scan interfaces */
12e41d03
DL
3657}
3658
64c86530
DS
3659static void igmp_show_source_retransmission(struct pim_instance *pim,
3660 struct vty *vty)
12e41d03 3661{
d62a17ae 3662 struct interface *ifp;
3663
3664 vty_out(vty,
ff415346 3665 "Interface Address Group Source Counter\n");
d62a17ae 3666
3667 /* scan interfaces */
451fda4f 3668 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3669 struct pim_interface *pim_ifp = ifp->info;
3670 struct listnode *sock_node;
3671 struct igmp_sock *igmp;
3672
3673 if (!pim_ifp)
3674 continue;
3675
3676 /* scan igmp sockets */
3677 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3678 igmp)) {
3679 char ifaddr_str[INET_ADDRSTRLEN];
3680 struct listnode *grpnode;
3681 struct igmp_group *grp;
3682
3683 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3684 sizeof(ifaddr_str));
3685
3686 /* scan igmp groups */
3687 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3688 grpnode, grp)) {
3689 char group_str[INET_ADDRSTRLEN];
3690 struct listnode *srcnode;
3691 struct igmp_source *src;
3692
3693 pim_inet4_dump("<group?>", grp->group_addr,
3694 group_str, sizeof(group_str));
3695
3696 /* scan group sources */
3697 for (ALL_LIST_ELEMENTS_RO(
3698 grp->group_source_list, srcnode,
3699 src)) {
3700 char source_str[INET_ADDRSTRLEN];
3701
3702 pim_inet4_dump(
3703 "<source?>", src->source_addr,
3704 source_str, sizeof(source_str));
3705
3706 vty_out(vty,
ff415346 3707 "%-16s %-15s %-15s %-15s %7d\n",
d62a17ae 3708 ifp->name, ifaddr_str,
3709 group_str, source_str,
3710 src->source_query_retransmit_count);
3711
3712 } /* scan group sources */
3713 } /* scan igmp groups */
3714 } /* scan igmp sockets */
3715 } /* scan interfaces */
12e41d03
DL
3716}
3717
256392eb 3718static void pim_show_bsr(struct pim_instance *pim,
3719 struct vty *vty,
3720 bool uj)
3721{
3722 char uptime[10];
3723 char last_bsm_seen[10];
3724 time_t now;
3725 char bsr_state[20];
3726 char bsr_str[PREFIX_STRLEN];
3727 json_object *json = NULL;
3728
3729 vty_out(vty, "PIMv2 Bootstrap information\n");
3730
3731 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) {
fbd74c7d 3732 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
256392eb 3733 pim_time_uptime(uptime, sizeof(uptime),
3734 pim->global_scope.current_bsr_first_ts);
3735 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3736 pim->global_scope.current_bsr_last_ts);
3737 }
3738
3739 else {
3740 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr,
3741 bsr_str, sizeof(bsr_str));
3742 now = pim_time_monotonic_sec();
3743 pim_time_uptime(uptime, sizeof(uptime),
3744 (now - pim->global_scope.current_bsr_first_ts));
3745 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3746 now - pim->global_scope.current_bsr_last_ts);
3747 }
3748
3749 switch (pim->global_scope.state) {
3750 case NO_INFO:
fbd74c7d 3751 strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
256392eb 3752 break;
3753 case ACCEPT_ANY:
fbd74c7d 3754 strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
256392eb 3755 break;
3756 case ACCEPT_PREFERRED:
fbd74c7d 3757 strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
256392eb 3758 break;
3759 default:
fbd74c7d 3760 strlcpy(bsr_state, "", sizeof(bsr_state));
256392eb 3761 }
3762
3763 if (uj) {
3764 json = json_object_new_object();
3765 json_object_string_add(json, "bsr", bsr_str);
3766 json_object_int_add(json, "priority",
3767 pim->global_scope.current_bsr_prio);
3768 json_object_int_add(json, "fragment_tag",
3769 pim->global_scope.bsm_frag_tag);
3770 json_object_string_add(json, "state", bsr_state);
3771 json_object_string_add(json, "upTime", uptime);
3772 json_object_string_add(json, "last_bsm_seen", last_bsm_seen);
3773 }
3774
3775 else {
3776 vty_out(vty, "Current preferred BSR address: %s\n", bsr_str);
3777 vty_out(vty,
3778 "Priority Fragment-Tag State UpTime\n");
3779 vty_out(vty, " %-12d %-12d %-13s %7s\n",
3780 pim->global_scope.current_bsr_prio,
3781 pim->global_scope.bsm_frag_tag,
3782 bsr_state,
3783 uptime);
3784 vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
3785 }
3786
3787 if (uj) {
3788 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3789 json, JSON_C_TO_STRING_PRETTY));
3790 json_object_free(json);
3791 }
3792}
3793
c68ba0d7 3794static void clear_igmp_interfaces(struct pim_instance *pim)
12e41d03 3795{
d62a17ae 3796 struct interface *ifp;
12e41d03 3797
451fda4f 3798 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 3799 pim_if_addr_del_all_igmp(ifp);
12e41d03 3800
451fda4f 3801 FOR_ALL_INTERFACES (pim->vrf, ifp)
d62a17ae 3802 pim_if_addr_add_all(ifp);
12e41d03
DL
3803}
3804
c68ba0d7 3805static void clear_pim_interfaces(struct pim_instance *pim)
12e41d03 3806{
d62a17ae 3807 struct interface *ifp;
12e41d03 3808
451fda4f 3809 FOR_ALL_INTERFACES (pim->vrf, ifp) {
d62a17ae 3810 if (ifp->info) {
3811 pim_neighbor_delete_all(ifp, "interface cleared");
3812 }
3813 }
12e41d03
DL
3814}
3815
c68ba0d7 3816static void clear_interfaces(struct pim_instance *pim)
12e41d03 3817{
c68ba0d7
DS
3818 clear_igmp_interfaces(pim);
3819 clear_pim_interfaces(pim);
12e41d03
DL
3820}
3821
996c9314
LB
3822#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3823 pim_ifp = ifp->info; \
3824 if (!pim_ifp) { \
3825 vty_out(vty, \
21b3e44e 3826 "%% Enable PIM and/or IGMP on this interface first\n"); \
996c9314 3827 return CMD_WARNING_CONFIG_FAILED; \
21b3e44e
QY
3828 }
3829
12e41d03
DL
3830DEFUN (clear_ip_interfaces,
3831 clear_ip_interfaces_cmd,
20a7e5fd 3832 "clear ip interfaces [vrf NAME]",
12e41d03
DL
3833 CLEAR_STR
3834 IP_STR
c68ba0d7
DS
3835 "Reset interfaces\n"
3836 VRF_CMD_HELP_STR)
12e41d03 3837{
c68ba0d7
DS
3838 int idx = 2;
3839 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3840
3841 if (!vrf)
3842 return CMD_WARNING;
3843
3844 clear_interfaces(vrf->info);
12e41d03 3845
d62a17ae 3846 return CMD_SUCCESS;
12e41d03
DL
3847}
3848
3849DEFUN (clear_ip_igmp_interfaces,
3850 clear_ip_igmp_interfaces_cmd,
20a7e5fd 3851 "clear ip igmp [vrf NAME] interfaces",
12e41d03
DL
3852 CLEAR_STR
3853 IP_STR
3854 CLEAR_IP_IGMP_STR
c68ba0d7 3855 VRF_CMD_HELP_STR
12e41d03
DL
3856 "Reset IGMP interfaces\n")
3857{
c68ba0d7
DS
3858 int idx = 2;
3859 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3860
3861 if (!vrf)
3862 return CMD_WARNING;
3863
3864 clear_igmp_interfaces(vrf->info);
12e41d03 3865
d62a17ae 3866 return CMD_SUCCESS;
12e41d03
DL
3867}
3868
415f6350 3869DEFUN (clear_ip_pim_statistics,
3870 clear_ip_pim_statistics_cmd,
3871 "clear ip pim statistics [vrf NAME]",
3872 CLEAR_STR
3873 IP_STR
3874 CLEAR_IP_PIM_STR
3875 VRF_CMD_HELP_STR
3876 "Reset PIM statistics\n")
3877{
3878 int idx = 2;
3879 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3880
3881 if (!vrf)
3882 return CMD_WARNING;
3883
3884 clear_pim_statistics(vrf->info);
3885 return CMD_SUCCESS;
3886}
3887
4a5e6e74 3888static void clear_mroute(struct pim_instance *pim)
3889{
3890 struct pim_upstream *up;
3891 struct interface *ifp;
3892
3893 /* scan interfaces */
3894 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3895 struct pim_interface *pim_ifp = ifp->info;
3896 struct listnode *sock_node;
3897 struct igmp_sock *igmp;
3898 struct pim_ifchannel *ch;
3899
3900 if (!pim_ifp)
3901 continue;
3902
3903 /* deleting all ifchannels */
3904 while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
3905 ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
3906
3907 pim_ifchannel_delete(ch);
3908 }
3909
3910 /* clean up all igmp groups */
3911 /* scan igmp sockets */
3912 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3913 igmp)) {
3914
3915 struct igmp_group *grp;
3916
3917 if (igmp->igmp_group_list) {
3918 while (igmp->igmp_group_list->count) {
3919 grp = listnode_head(
3920 igmp->igmp_group_list);
3921 igmp_group_delete(grp);
3922 }
3923 }
3924
3925 }
3926 }
3927
3928 /* clean up all upstreams*/
dd3364cb
DS
3929 while ((up = rb_pim_upstream_first(&pim->upstream_head))) {
3930 pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
4a5e6e74 3931 }
3932}
3933
12e41d03
DL
3934DEFUN (clear_ip_mroute,
3935 clear_ip_mroute_cmd,
20a7e5fd 3936 "clear ip mroute [vrf NAME]",
12e41d03
DL
3937 CLEAR_STR
3938 IP_STR
c68ba0d7
DS
3939 "Reset multicast routes\n"
3940 VRF_CMD_HELP_STR)
12e41d03 3941{
c68ba0d7
DS
3942 int idx = 2;
3943 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3944
3945 if (!vrf)
3946 return CMD_WARNING;
3947
4a5e6e74 3948 clear_mroute(vrf->info);
12e41d03 3949
d62a17ae 3950 return CMD_SUCCESS;
12e41d03
DL
3951}
3952
3953DEFUN (clear_ip_pim_interfaces,
3954 clear_ip_pim_interfaces_cmd,
20a7e5fd 3955 "clear ip pim [vrf NAME] interfaces",
12e41d03
DL
3956 CLEAR_STR
3957 IP_STR
3958 CLEAR_IP_PIM_STR
c68ba0d7 3959 VRF_CMD_HELP_STR
12e41d03
DL
3960 "Reset PIM interfaces\n")
3961{
c68ba0d7
DS
3962 int idx = 2;
3963 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3964
3965 if (!vrf)
3966 return CMD_WARNING;
3967
3968 clear_pim_interfaces(vrf->info);
12e41d03 3969
d62a17ae 3970 return CMD_SUCCESS;
12e41d03
DL
3971}
3972
39438188
CS
3973DEFUN (clear_ip_pim_interface_traffic,
3974 clear_ip_pim_interface_traffic_cmd,
20a7e5fd 3975 "clear ip pim [vrf NAME] interface traffic",
39438188
CS
3976 "Reset functions\n"
3977 "IP information\n"
3978 "PIM clear commands\n"
c68ba0d7 3979 VRF_CMD_HELP_STR
39438188
CS
3980 "Reset PIM interfaces\n"
3981 "Reset Protocol Packet counters\n")
3982{
c68ba0d7
DS
3983 int idx = 2;
3984 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3985 struct interface *ifp = NULL;
3986 struct pim_interface *pim_ifp = NULL;
3987
c68ba0d7
DS
3988 if (!vrf)
3989 return CMD_WARNING;
3990
451fda4f 3991 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 3992 pim_ifp = ifp->info;
3993
3994 if (!pim_ifp)
3995 continue;
3996
3997 pim_ifp->pim_ifstat_hello_recv = 0;
3998 pim_ifp->pim_ifstat_hello_sent = 0;
3999 pim_ifp->pim_ifstat_join_recv = 0;
4000 pim_ifp->pim_ifstat_join_send = 0;
4001 pim_ifp->pim_ifstat_prune_recv = 0;
4002 pim_ifp->pim_ifstat_prune_send = 0;
4003 pim_ifp->pim_ifstat_reg_recv = 0;
4004 pim_ifp->pim_ifstat_reg_send = 0;
4005 pim_ifp->pim_ifstat_reg_stop_recv = 0;
4006 pim_ifp->pim_ifstat_reg_stop_send = 0;
4007 pim_ifp->pim_ifstat_assert_recv = 0;
4008 pim_ifp->pim_ifstat_assert_send = 0;
5164ad1e 4009 pim_ifp->pim_ifstat_bsm_rx = 0;
4010 pim_ifp->pim_ifstat_bsm_tx = 0;
d62a17ae 4011 }
39438188 4012
d62a17ae 4013 return CMD_SUCCESS;
39438188
CS
4014}
4015
12e41d03
DL
4016DEFUN (clear_ip_pim_oil,
4017 clear_ip_pim_oil_cmd,
20a7e5fd 4018 "clear ip pim [vrf NAME] oil",
12e41d03
DL
4019 CLEAR_STR
4020 IP_STR
4021 CLEAR_IP_PIM_STR
c68ba0d7 4022 VRF_CMD_HELP_STR
12e41d03
DL
4023 "Rescan PIM OIL (output interface list)\n")
4024{
c68ba0d7
DS
4025 int idx = 2;
4026 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4027
4028 if (!vrf)
4029 return CMD_WARNING;
4030
4031 pim_scan_oil(vrf->info);
12e41d03 4032
d62a17ae 4033 return CMD_SUCCESS;
12e41d03
DL
4034}
4035
4036DEFUN (show_ip_igmp_interface,
4037 show_ip_igmp_interface_cmd,
20a7e5fd 4038 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
4039 SHOW_STR
4040 IP_STR
4041 IGMP_STR
c68ba0d7 4042 VRF_CMD_HELP_STR
a268493f 4043 "IGMP interface information\n"
9b91bb50 4044 "Detailed output\n"
a268493f 4045 "interface name\n"
f5da2cc2 4046 JSON_STR)
12e41d03 4047{
c68ba0d7
DS
4048 int idx = 2;
4049 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4050 bool uj = use_json(argc, argv);
c68ba0d7
DS
4051
4052 if (!vrf)
4053 return CMD_WARNING;
72e81cf4 4054
d62a17ae 4055 if (argv_find(argv, argc, "detail", &idx)
4056 || argv_find(argv, argc, "WORD", &idx))
64c86530 4057 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 4058 else
64c86530 4059 igmp_show_interfaces(vrf->info, vty, uj);
12e41d03 4060
d62a17ae 4061 return CMD_SUCCESS;
12e41d03
DL
4062}
4063
a25de56b
DS
4064DEFUN (show_ip_igmp_interface_vrf_all,
4065 show_ip_igmp_interface_vrf_all_cmd,
4066 "show ip igmp vrf all interface [detail|WORD] [json]",
4067 SHOW_STR
4068 IP_STR
4069 IGMP_STR
4070 VRF_CMD_HELP_STR
4071 "IGMP interface information\n"
4072 "Detailed output\n"
4073 "interface name\n"
f5da2cc2 4074 JSON_STR)
a25de56b
DS
4075{
4076 int idx = 2;
9f049418 4077 bool uj = use_json(argc, argv);
a25de56b
DS
4078 struct vrf *vrf;
4079 bool first = true;
4080
4081 if (uj)
4082 vty_out(vty, "{ ");
a2addae8 4083 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4084 if (uj) {
4085 if (!first)
4086 vty_out(vty, ", ");
4087 vty_out(vty, " \"%s\": ", vrf->name);
4088 first = false;
4089 } else
4090 vty_out(vty, "VRF: %s\n", vrf->name);
4091 if (argv_find(argv, argc, "detail", &idx)
4092 || argv_find(argv, argc, "WORD", &idx))
4093 igmp_show_interfaces_single(vrf->info, vty,
4094 argv[idx]->arg, uj);
4095 else
4096 igmp_show_interfaces(vrf->info, vty, uj);
4097 }
4098 if (uj)
4099 vty_out(vty, "}\n");
4100
4101 return CMD_SUCCESS;
4102}
4103
12e41d03
DL
4104DEFUN (show_ip_igmp_join,
4105 show_ip_igmp_join_cmd,
20a7e5fd 4106 "show ip igmp [vrf NAME] join",
12e41d03
DL
4107 SHOW_STR
4108 IP_STR
4109 IGMP_STR
c68ba0d7 4110 VRF_CMD_HELP_STR
12e41d03
DL
4111 "IGMP static join information\n")
4112{
c68ba0d7
DS
4113 int idx = 2;
4114 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4115
4116 if (!vrf)
4117 return CMD_WARNING;
4118
64c86530 4119 igmp_show_interface_join(vrf->info, vty);
12e41d03 4120
d62a17ae 4121 return CMD_SUCCESS;
12e41d03
DL
4122}
4123
a25de56b
DS
4124DEFUN (show_ip_igmp_join_vrf_all,
4125 show_ip_igmp_join_vrf_all_cmd,
4126 "show ip igmp vrf all join",
4127 SHOW_STR
4128 IP_STR
4129 IGMP_STR
4130 VRF_CMD_HELP_STR
4131 "IGMP static join information\n")
4132{
9f049418 4133 bool uj = use_json(argc, argv);
a25de56b
DS
4134 struct vrf *vrf;
4135 bool first = true;
4136
4137 if (uj)
4138 vty_out(vty, "{ ");
a2addae8 4139 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4140 if (uj) {
4141 if (!first)
4142 vty_out(vty, ", ");
4143 vty_out(vty, " \"%s\": ", vrf->name);
4144 first = false;
4145 } else
4146 vty_out(vty, "VRF: %s\n", vrf->name);
4147 igmp_show_interface_join(vrf->info, vty);
4148 }
4149 if (uj)
4150 vty_out(vty, "}\n");
4151
4152 return CMD_SUCCESS;
4153}
4154
12e41d03
DL
4155DEFUN (show_ip_igmp_groups,
4156 show_ip_igmp_groups_cmd,
20a7e5fd 4157 "show ip igmp [vrf NAME] groups [json]",
12e41d03
DL
4158 SHOW_STR
4159 IP_STR
4160 IGMP_STR
c68ba0d7 4161 VRF_CMD_HELP_STR
9b91bb50 4162 IGMP_GROUP_STR
f5da2cc2 4163 JSON_STR)
12e41d03 4164{
c68ba0d7
DS
4165 int idx = 2;
4166 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4167 bool uj = use_json(argc, argv);
c68ba0d7
DS
4168
4169 if (!vrf)
4170 return CMD_WARNING;
4171
64c86530 4172 igmp_show_groups(vrf->info, vty, uj);
12e41d03 4173
d62a17ae 4174 return CMD_SUCCESS;
12e41d03
DL
4175}
4176
a25de56b
DS
4177DEFUN (show_ip_igmp_groups_vrf_all,
4178 show_ip_igmp_groups_vrf_all_cmd,
4179 "show ip igmp vrf all groups [json]",
4180 SHOW_STR
4181 IP_STR
4182 IGMP_STR
4183 VRF_CMD_HELP_STR
4184 IGMP_GROUP_STR
f5da2cc2 4185 JSON_STR)
a25de56b 4186{
9f049418 4187 bool uj = use_json(argc, argv);
a25de56b
DS
4188 struct vrf *vrf;
4189 bool first = true;
4190
4191 if (uj)
4192 vty_out(vty, "{ ");
a2addae8 4193 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4194 if (uj) {
4195 if (!first)
4196 vty_out(vty, ", ");
4197 vty_out(vty, " \"%s\": ", vrf->name);
4198 first = false;
4199 } else
4200 vty_out(vty, "VRF: %s\n", vrf->name);
4201 igmp_show_groups(vrf->info, vty, uj);
4202 }
4203 if (uj)
4204 vty_out(vty, "}\n");
4205
4206 return CMD_SUCCESS;
4207}
4208
12e41d03
DL
4209DEFUN (show_ip_igmp_groups_retransmissions,
4210 show_ip_igmp_groups_retransmissions_cmd,
20a7e5fd 4211 "show ip igmp [vrf NAME] groups retransmissions",
12e41d03
DL
4212 SHOW_STR
4213 IP_STR
4214 IGMP_STR
c68ba0d7 4215 VRF_CMD_HELP_STR
12e41d03
DL
4216 IGMP_GROUP_STR
4217 "IGMP group retransmissions\n")
4218{
c68ba0d7
DS
4219 int idx = 2;
4220 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4221
4222 if (!vrf)
4223 return CMD_WARNING;
4224
64c86530 4225 igmp_show_group_retransmission(vrf->info, vty);
12e41d03 4226
d62a17ae 4227 return CMD_SUCCESS;
12e41d03
DL
4228}
4229
12e41d03
DL
4230DEFUN (show_ip_igmp_sources,
4231 show_ip_igmp_sources_cmd,
20a7e5fd 4232 "show ip igmp [vrf NAME] sources",
12e41d03
DL
4233 SHOW_STR
4234 IP_STR
4235 IGMP_STR
c68ba0d7 4236 VRF_CMD_HELP_STR
12e41d03
DL
4237 IGMP_SOURCE_STR)
4238{
c68ba0d7
DS
4239 int idx = 2;
4240 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4241
4242 if (!vrf)
4243 return CMD_WARNING;
4244
64c86530 4245 igmp_show_sources(vrf->info, vty);
12e41d03 4246
d62a17ae 4247 return CMD_SUCCESS;
12e41d03
DL
4248}
4249
4250DEFUN (show_ip_igmp_sources_retransmissions,
4251 show_ip_igmp_sources_retransmissions_cmd,
20a7e5fd 4252 "show ip igmp [vrf NAME] sources retransmissions",
12e41d03
DL
4253 SHOW_STR
4254 IP_STR
4255 IGMP_STR
c68ba0d7 4256 VRF_CMD_HELP_STR
12e41d03
DL
4257 IGMP_SOURCE_STR
4258 "IGMP source retransmissions\n")
4259{
c68ba0d7
DS
4260 int idx = 2;
4261 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4262
4263 if (!vrf)
4264 return CMD_WARNING;
4265
64c86530 4266 igmp_show_source_retransmission(vrf->info, vty);
12e41d03 4267
d62a17ae 4268 return CMD_SUCCESS;
12e41d03
DL
4269}
4270
21313cbf
MS
4271DEFUN (show_ip_igmp_statistics,
4272 show_ip_igmp_statistics_cmd,
4273 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4274 SHOW_STR
4275 IP_STR
4276 IGMP_STR
4277 VRF_CMD_HELP_STR
4278 "IGMP statistics\n"
4279 "interface\n"
4280 "IGMP interface\n"
4281 JSON_STR)
4282{
4283 int idx = 2;
4284 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4285 bool uj = use_json(argc, argv);
21313cbf
MS
4286
4287 if (!vrf)
4288 return CMD_WARNING;
4289
4290 if (argv_find(argv, argc, "WORD", &idx))
4291 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
4292 else
4293 igmp_show_statistics(vrf->info, vty, NULL, uj);
4294
4295 return CMD_SUCCESS;
4296}
4297
12e41d03
DL
4298DEFUN (show_ip_pim_assert,
4299 show_ip_pim_assert_cmd,
20a7e5fd 4300 "show ip pim [vrf NAME] assert",
12e41d03
DL
4301 SHOW_STR
4302 IP_STR
4303 PIM_STR
c68ba0d7 4304 VRF_CMD_HELP_STR
12e41d03
DL
4305 "PIM interface assert\n")
4306{
c68ba0d7
DS
4307 int idx = 2;
4308 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4309
4310 if (!vrf)
4311 return CMD_WARNING;
4312
64c86530 4313 pim_show_assert(vrf->info, vty);
12e41d03 4314
d62a17ae 4315 return CMD_SUCCESS;
12e41d03
DL
4316}
4317
4318DEFUN (show_ip_pim_assert_internal,
4319 show_ip_pim_assert_internal_cmd,
20a7e5fd 4320 "show ip pim [vrf NAME] assert-internal",
12e41d03
DL
4321 SHOW_STR
4322 IP_STR
4323 PIM_STR
c68ba0d7 4324 VRF_CMD_HELP_STR
12e41d03
DL
4325 "PIM interface internal assert state\n")
4326{
c68ba0d7
DS
4327 int idx = 2;
4328 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4329
4330 if (!vrf)
4331 return CMD_WARNING;
4332
64c86530 4333 pim_show_assert_internal(vrf->info, vty);
12e41d03 4334
d62a17ae 4335 return CMD_SUCCESS;
12e41d03
DL
4336}
4337
4338DEFUN (show_ip_pim_assert_metric,
4339 show_ip_pim_assert_metric_cmd,
20a7e5fd 4340 "show ip pim [vrf NAME] assert-metric",
12e41d03
DL
4341 SHOW_STR
4342 IP_STR
4343 PIM_STR
c68ba0d7 4344 VRF_CMD_HELP_STR
12e41d03
DL
4345 "PIM interface assert metric\n")
4346{
c68ba0d7
DS
4347 int idx = 2;
4348 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4349
4350 if (!vrf)
4351 return CMD_WARNING;
4352
64c86530 4353 pim_show_assert_metric(vrf->info, vty);
12e41d03 4354
d62a17ae 4355 return CMD_SUCCESS;
12e41d03
DL
4356}
4357
4358DEFUN (show_ip_pim_assert_winner_metric,
4359 show_ip_pim_assert_winner_metric_cmd,
20a7e5fd 4360 "show ip pim [vrf NAME] assert-winner-metric",
12e41d03
DL
4361 SHOW_STR
4362 IP_STR
4363 PIM_STR
c68ba0d7 4364 VRF_CMD_HELP_STR
12e41d03
DL
4365 "PIM interface assert winner metric\n")
4366{
c68ba0d7
DS
4367 int idx = 2;
4368 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4369
4370 if (!vrf)
4371 return CMD_WARNING;
4372
64c86530 4373 pim_show_assert_winner_metric(vrf->info, vty);
12e41d03 4374
d62a17ae 4375 return CMD_SUCCESS;
12e41d03
DL
4376}
4377
12e41d03
DL
4378DEFUN (show_ip_pim_interface,
4379 show_ip_pim_interface_cmd,
20a7e5fd 4380 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
4381 SHOW_STR
4382 IP_STR
4383 PIM_STR
c68ba0d7 4384 VRF_CMD_HELP_STR
a268493f 4385 "PIM interface information\n"
9b91bb50 4386 "Detailed output\n"
a268493f 4387 "interface name\n"
f5da2cc2 4388 JSON_STR)
12e41d03 4389{
c68ba0d7
DS
4390 int idx = 2;
4391 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4392 bool uj = use_json(argc, argv);
c68ba0d7
DS
4393
4394 if (!vrf)
4395 return CMD_WARNING;
72e81cf4 4396
d62a17ae 4397 if (argv_find(argv, argc, "WORD", &idx)
4398 || argv_find(argv, argc, "detail", &idx))
64c86530 4399 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 4400 else
64c86530 4401 pim_show_interfaces(vrf->info, vty, uj);
12e41d03 4402
d62a17ae 4403 return CMD_SUCCESS;
12e41d03
DL
4404}
4405
a25de56b
DS
4406DEFUN (show_ip_pim_interface_vrf_all,
4407 show_ip_pim_interface_vrf_all_cmd,
4408 "show ip pim vrf all interface [detail|WORD] [json]",
4409 SHOW_STR
4410 IP_STR
4411 PIM_STR
4412 VRF_CMD_HELP_STR
4413 "PIM interface information\n"
4414 "Detailed output\n"
4415 "interface name\n"
f5da2cc2 4416 JSON_STR)
a25de56b
DS
4417{
4418 int idx = 6;
9f049418 4419 bool uj = use_json(argc, argv);
a25de56b
DS
4420 struct vrf *vrf;
4421 bool first = true;
4422
4423 if (uj)
4424 vty_out(vty, "{ ");
a2addae8 4425 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4426 if (uj) {
4427 if (!first)
4428 vty_out(vty, ", ");
4429 vty_out(vty, " \"%s\": ", vrf->name);
4430 first = false;
4431 } else
4432 vty_out(vty, "VRF: %s\n", vrf->name);
4433 if (argv_find(argv, argc, "WORD", &idx)
4434 || argv_find(argv, argc, "detail", &idx))
4435 pim_show_interfaces_single(vrf->info, vty,
4436 argv[idx]->arg, uj);
4437 else
4438 pim_show_interfaces(vrf->info, vty, uj);
4439 }
4440 if (uj)
4441 vty_out(vty, "}\n");
4442
4443 return CMD_SUCCESS;
4444}
4445
6de45bcc 4446DEFPY (show_ip_pim_join,
12e41d03 4447 show_ip_pim_join_cmd,
6de45bcc 4448 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
4449 SHOW_STR
4450 IP_STR
4451 PIM_STR
c68ba0d7 4452 VRF_CMD_HELP_STR
a957a05b 4453 "PIM interface join information\n"
6de45bcc
DS
4454 "The Source or Group\n"
4455 "The Group\n"
a957a05b 4456 JSON_STR)
12e41d03 4457{
6de45bcc
DS
4458 struct prefix_sg sg = {0};
4459 struct vrf *v;
4460 bool uj = !!json;
4461 struct pim_instance *pim;
c68ba0d7 4462
6de45bcc
DS
4463 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4464
4465 if (!v) {
4466 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 4467 return CMD_WARNING;
6de45bcc
DS
4468 }
4469 pim = pim_get_pim_instance(v->vrf_id);
4470
4471 if (!pim) {
4472 vty_out(vty, "%% Unable to find pim instance\n");
4473 return CMD_WARNING;
4474 }
4475
4476 if (s_or_g.s_addr != 0) {
4477 if (g.s_addr != 0) {
4478 sg.src = s_or_g;
4479 sg.grp = g;
4480 } else
4481 sg.grp = s_or_g;
4482 }
c68ba0d7 4483
6de45bcc 4484 pim_show_join(pim, vty, &sg, uj);
12e41d03 4485
d62a17ae 4486 return CMD_SUCCESS;
12e41d03
DL
4487}
4488
a25de56b
DS
4489DEFUN (show_ip_pim_join_vrf_all,
4490 show_ip_pim_join_vrf_all_cmd,
4491 "show ip pim vrf all join [json]",
4492 SHOW_STR
4493 IP_STR
4494 PIM_STR
4495 VRF_CMD_HELP_STR
4496 "PIM interface join information\n"
4497 JSON_STR)
4498{
6de45bcc 4499 struct prefix_sg sg = {0};
9f049418 4500 bool uj = use_json(argc, argv);
a25de56b
DS
4501 struct vrf *vrf;
4502 bool first = true;
4503
4504 if (uj)
4505 vty_out(vty, "{ ");
a2addae8 4506 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4507 if (uj) {
4508 if (!first)
4509 vty_out(vty, ", ");
4510 vty_out(vty, " \"%s\": ", vrf->name);
4511 first = false;
4512 } else
4513 vty_out(vty, "VRF: %s\n", vrf->name);
6de45bcc 4514 pim_show_join(vrf->info, vty, &sg, uj);
a25de56b
DS
4515 }
4516 if (uj)
4517 vty_out(vty, "}\n");
4518
4519 return CMD_WARNING;
4520}
4521
87b7cd5b
AK
4522static void pim_show_jp_agg_helper(struct vty *vty,
4523 struct interface *ifp,
4524 struct pim_neighbor *neigh,
4525 struct pim_upstream *up,
4526 int is_join)
4527{
4528 char src_str[INET_ADDRSTRLEN];
4529 char grp_str[INET_ADDRSTRLEN];
4530 char rpf_str[INET_ADDRSTRLEN];
4531
4532 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
4533 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
4534 /* pius->address.s_addr */
4535 pim_inet4_dump("<rpf?>", neigh->source_addr, rpf_str, sizeof(rpf_str));
4536
4537 vty_out(vty, "%-16s %-15s %-15s %-15s %5s\n",
4538 ifp->name, rpf_str, src_str,
4539 grp_str, is_join?"J":"P");
4540}
4541
4542static void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
4543{
4544 struct interface *ifp;
4545 struct pim_interface *pim_ifp;
4546 struct listnode *n_node;
4547 struct pim_neighbor *neigh;
4548 struct listnode *jag_node;
4549 struct pim_jp_agg_group *jag;
4550 struct listnode *js_node;
4551 struct pim_jp_sources *js;
4552
4553 vty_out(vty,
4554 "Interface RPF Nbr Source Group State\n");
4555
4556 FOR_ALL_INTERFACES (pim->vrf, ifp) {
4557 pim_ifp = ifp->info;
4558 if (!pim_ifp)
4559 continue;
4560
4561 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
4562 n_node, neigh)) {
4563 for (ALL_LIST_ELEMENTS_RO(neigh->upstream_jp_agg,
4564 jag_node, jag)) {
4565 for (ALL_LIST_ELEMENTS_RO(jag->sources,
4566 js_node, js)) {
4567 pim_show_jp_agg_helper(vty,
4568 ifp, neigh, js->up,
4569 js->is_join);
4570 }
4571 }
4572 }
4573 }
4574}
4575
4576DEFPY (show_ip_pim_jp_agg,
4577 show_ip_pim_jp_agg_cmd,
4578 "show ip pim [vrf NAME] jp-agg",
4579 SHOW_STR
4580 IP_STR
4581 PIM_STR
4582 VRF_CMD_HELP_STR
4583 "join prune aggregation list\n")
4584{
4585 struct vrf *v;
4586 struct pim_instance *pim;
4587
4588 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4589
4590 if (!v) {
4591 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4592 return CMD_WARNING;
4593 }
4594 pim = pim_get_pim_instance(v->vrf_id);
4595
4596 if (!pim) {
4597 vty_out(vty, "%% Unable to find pim instance\n");
4598 return CMD_WARNING;
4599 }
4600
4601 pim_show_jp_agg_list(pim, vty);
4602
4603 return CMD_SUCCESS;
4604}
4605
12e41d03
DL
4606DEFUN (show_ip_pim_local_membership,
4607 show_ip_pim_local_membership_cmd,
20a7e5fd 4608 "show ip pim [vrf NAME] local-membership [json]",
12e41d03
DL
4609 SHOW_STR
4610 IP_STR
4611 PIM_STR
c68ba0d7 4612 VRF_CMD_HELP_STR
a957a05b
DS
4613 "PIM interface local-membership\n"
4614 JSON_STR)
12e41d03 4615{
c68ba0d7
DS
4616 int idx = 2;
4617 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4618 bool uj = use_json(argc, argv);
c68ba0d7
DS
4619
4620 if (!vrf)
4621 return CMD_WARNING;
4622
64c86530 4623 pim_show_membership(vrf->info, vty, uj);
12e41d03 4624
d62a17ae 4625 return CMD_SUCCESS;
12e41d03
DL
4626}
4627
12e41d03
DL
4628DEFUN (show_ip_pim_neighbor,
4629 show_ip_pim_neighbor_cmd,
20a7e5fd 4630 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
12e41d03
DL
4631 SHOW_STR
4632 IP_STR
4633 PIM_STR
c68ba0d7 4634 VRF_CMD_HELP_STR
a268493f 4635 "PIM neighbor information\n"
9b91bb50 4636 "Detailed output\n"
a268493f 4637 "Name of interface or neighbor\n"
f5da2cc2 4638 JSON_STR)
12e41d03 4639{
c68ba0d7
DS
4640 int idx = 2;
4641 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4642 bool uj = use_json(argc, argv);
c68ba0d7
DS
4643
4644 if (!vrf)
4645 return CMD_WARNING;
72e81cf4 4646
d62a17ae 4647 if (argv_find(argv, argc, "detail", &idx)
4648 || argv_find(argv, argc, "WORD", &idx))
64c86530 4649 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 4650 else
64c86530 4651 pim_show_neighbors(vrf->info, vty, uj);
12e41d03 4652
d62a17ae 4653 return CMD_SUCCESS;
12e41d03
DL
4654}
4655
a25de56b
DS
4656DEFUN (show_ip_pim_neighbor_vrf_all,
4657 show_ip_pim_neighbor_vrf_all_cmd,
4658 "show ip pim vrf all neighbor [detail|WORD] [json]",
4659 SHOW_STR
4660 IP_STR
4661 PIM_STR
4662 VRF_CMD_HELP_STR
4663 "PIM neighbor information\n"
4664 "Detailed output\n"
4665 "Name of interface or neighbor\n"
f5da2cc2 4666 JSON_STR)
a25de56b
DS
4667{
4668 int idx = 2;
9f049418 4669 bool uj = use_json(argc, argv);
a25de56b
DS
4670 struct vrf *vrf;
4671 bool first = true;
4672
4673 if (uj)
4674 vty_out(vty, "{ ");
a2addae8 4675 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4676 if (uj) {
4677 if (!first)
4678 vty_out(vty, ", ");
4679 vty_out(vty, " \"%s\": ", vrf->name);
4680 first = false;
4681 } else
4682 vty_out(vty, "VRF: %s\n", vrf->name);
4683 if (argv_find(argv, argc, "detail", &idx)
4684 || argv_find(argv, argc, "WORD", &idx))
4685 pim_show_neighbors_single(vrf->info, vty,
4686 argv[idx]->arg, uj);
4687 else
4688 pim_show_neighbors(vrf->info, vty, uj);
4689 }
4690 if (uj)
4691 vty_out(vty, "}\n");
4692
4693 return CMD_SUCCESS;
4694}
4695
12e41d03
DL
4696DEFUN (show_ip_pim_secondary,
4697 show_ip_pim_secondary_cmd,
20a7e5fd 4698 "show ip pim [vrf NAME] secondary",
12e41d03
DL
4699 SHOW_STR
4700 IP_STR
4701 PIM_STR
c68ba0d7 4702 VRF_CMD_HELP_STR
12e41d03
DL
4703 "PIM neighbor addresses\n")
4704{
c68ba0d7
DS
4705 int idx = 2;
4706 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4707
4708 if (!vrf)
4709 return CMD_WARNING;
4710
64c86530 4711 pim_show_neighbors_secondary(vrf->info, vty);
12e41d03 4712
d62a17ae 4713 return CMD_SUCCESS;
12e41d03
DL
4714}
4715
31a21c9c
DW
4716DEFUN (show_ip_pim_state,
4717 show_ip_pim_state_cmd,
20a7e5fd 4718 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
31a21c9c
DW
4719 SHOW_STR
4720 IP_STR
4721 PIM_STR
c68ba0d7 4722 VRF_CMD_HELP_STR
31a21c9c
DW
4723 "PIM state information\n"
4724 "Unicast or Multicast address\n"
4725 "Multicast address\n"
f5da2cc2 4726 JSON_STR)
31a21c9c 4727{
d62a17ae 4728 const char *src_or_group = NULL;
4729 const char *group = NULL;
c68ba0d7
DS
4730 int idx = 2;
4731 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4732 bool uj = use_json(argc, argv);
c68ba0d7
DS
4733
4734 if (!vrf)
4735 return CMD_WARNING;
4736
d62a17ae 4737 if (uj)
4738 argc--;
31a21c9c 4739
56243c3a
DS
4740 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4741 src_or_group = argv[idx]->arg;
4742 if (idx + 1 < argc)
4743 group = argv[idx + 1]->arg;
4744 }
31a21c9c 4745
64c86530 4746 pim_show_state(vrf->info, vty, src_or_group, group, uj);
31a21c9c 4747
d62a17ae 4748 return CMD_SUCCESS;
31a21c9c
DW
4749}
4750
a25de56b
DS
4751DEFUN (show_ip_pim_state_vrf_all,
4752 show_ip_pim_state_vrf_all_cmd,
4753 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4754 SHOW_STR
4755 IP_STR
4756 PIM_STR
4757 VRF_CMD_HELP_STR
4758 "PIM state information\n"
4759 "Unicast or Multicast address\n"
4760 "Multicast address\n"
f5da2cc2 4761 JSON_STR)
a25de56b
DS
4762{
4763 const char *src_or_group = NULL;
4764 const char *group = NULL;
4765 int idx = 2;
9f049418 4766 bool uj = use_json(argc, argv);
a25de56b
DS
4767 struct vrf *vrf;
4768 bool first = true;
4769
4770 if (uj) {
4771 vty_out(vty, "{ ");
4772 argc--;
4773 }
4774
4775 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4776 src_or_group = argv[idx]->arg;
4777 if (idx + 1 < argc)
4778 group = argv[idx + 1]->arg;
4779 }
4780
a2addae8 4781 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4782 if (uj) {
4783 if (!first)
4784 vty_out(vty, ", ");
4785 vty_out(vty, " \"%s\": ", vrf->name);
4786 first = false;
4787 } else
4788 vty_out(vty, "VRF: %s\n", vrf->name);
4789 pim_show_state(vrf->info, vty, src_or_group, group, uj);
4790 }
4791 if (uj)
4792 vty_out(vty, "}\n");
4793
4794 return CMD_SUCCESS;
4795}
4796
dff5cedb 4797DEFPY (show_ip_pim_upstream,
12e41d03 4798 show_ip_pim_upstream_cmd,
dff5cedb 4799 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
12e41d03
DL
4800 SHOW_STR
4801 IP_STR
4802 PIM_STR
c68ba0d7 4803 VRF_CMD_HELP_STR
a268493f 4804 "PIM upstream information\n"
dff5cedb
DS
4805 "The Source or Group\n"
4806 "The Group\n"
f5da2cc2 4807 JSON_STR)
12e41d03 4808{
dff5cedb
DS
4809 struct prefix_sg sg = {0};
4810 struct vrf *v;
4811 bool uj = !!json;
4812 struct pim_instance *pim;
c68ba0d7 4813
dff5cedb
DS
4814 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4815
4816 if (!v) {
4817 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 4818 return CMD_WARNING;
dff5cedb
DS
4819 }
4820 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 4821
dff5cedb
DS
4822 if (!pim) {
4823 vty_out(vty, "%% Unable to find pim instance\n");
4824 return CMD_WARNING;
4825 }
4826
4827 if (s_or_g.s_addr != 0) {
4828 if (g.s_addr != 0) {
4829 sg.src = s_or_g;
4830 sg.grp = g;
4831 } else
4832 sg.grp = s_or_g;
4833 }
4834 pim_show_upstream(pim, vty, &sg, uj);
12e41d03 4835
d62a17ae 4836 return CMD_SUCCESS;
12e41d03
DL
4837}
4838
a25de56b
DS
4839DEFUN (show_ip_pim_upstream_vrf_all,
4840 show_ip_pim_upstream_vrf_all_cmd,
4841 "show ip pim vrf all upstream [json]",
4842 SHOW_STR
4843 IP_STR
4844 PIM_STR
4845 VRF_CMD_HELP_STR
4846 "PIM upstream information\n"
4847 JSON_STR)
4848{
dff5cedb 4849 struct prefix_sg sg = {0};
9f049418 4850 bool uj = use_json(argc, argv);
a25de56b
DS
4851 struct vrf *vrf;
4852 bool first = true;
4853
4854 if (uj)
4855 vty_out(vty, "{ ");
a2addae8 4856 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4857 if (uj) {
4858 if (!first)
4859 vty_out(vty, ", ");
4860 vty_out(vty, " \"%s\": ", vrf->name);
4861 first = false;
4862 } else
4863 vty_out(vty, "VRF: %s\n", vrf->name);
dff5cedb 4864 pim_show_upstream(vrf->info, vty, &sg, uj);
a25de56b
DS
4865 }
4866
4867 return CMD_SUCCESS;
4868}
4869
5c9a72ef
AK
4870DEFUN (show_ip_pim_channel,
4871 show_ip_pim_channel_cmd,
4872 "show ip pim [vrf NAME] channel [json]",
12e41d03
DL
4873 SHOW_STR
4874 IP_STR
4875 PIM_STR
c68ba0d7 4876 VRF_CMD_HELP_STR
5c9a72ef 4877 "PIM downstream channel info\n"
f5da2cc2 4878 JSON_STR)
12e41d03 4879{
c68ba0d7
DS
4880 int idx = 2;
4881 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4882 bool uj = use_json(argc, argv);
c68ba0d7
DS
4883
4884 if (!vrf)
4885 return CMD_WARNING;
4886
5c9a72ef 4887 pim_show_channel(vrf->info, vty, uj);
12e41d03 4888
d62a17ae 4889 return CMD_SUCCESS;
12e41d03
DL
4890}
4891
12e41d03
DL
4892DEFUN (show_ip_pim_upstream_join_desired,
4893 show_ip_pim_upstream_join_desired_cmd,
20a7e5fd 4894 "show ip pim [vrf NAME] upstream-join-desired [json]",
12e41d03
DL
4895 SHOW_STR
4896 IP_STR
4897 PIM_STR
c68ba0d7 4898 VRF_CMD_HELP_STR
a268493f 4899 "PIM upstream join-desired\n"
f5da2cc2 4900 JSON_STR)
12e41d03 4901{
c68ba0d7
DS
4902 int idx = 2;
4903 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4904 bool uj = use_json(argc, argv);
c68ba0d7
DS
4905
4906 if (!vrf)
4907 return CMD_WARNING;
4908
64c86530 4909 pim_show_join_desired(vrf->info, vty, uj);
12e41d03 4910
d62a17ae 4911 return CMD_SUCCESS;
12e41d03
DL
4912}
4913
4914DEFUN (show_ip_pim_upstream_rpf,
4915 show_ip_pim_upstream_rpf_cmd,
20a7e5fd 4916 "show ip pim [vrf NAME] upstream-rpf [json]",
12e41d03
DL
4917 SHOW_STR
4918 IP_STR
4919 PIM_STR
c68ba0d7 4920 VRF_CMD_HELP_STR
a268493f 4921 "PIM upstream source rpf\n"
f5da2cc2 4922 JSON_STR)
12e41d03 4923{
c68ba0d7
DS
4924 int idx = 2;
4925 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4926 bool uj = use_json(argc, argv);
c68ba0d7
DS
4927
4928 if (!vrf)
4929 return CMD_WARNING;
4930
64c86530 4931 pim_show_upstream_rpf(vrf->info, vty, uj);
12e41d03 4932
d62a17ae 4933 return CMD_SUCCESS;
12e41d03
DL
4934}
4935
00d07c6f
DS
4936DEFUN (show_ip_pim_rp,
4937 show_ip_pim_rp_cmd,
20a7e5fd 4938 "show ip pim [vrf NAME] rp-info [json]",
00d07c6f
DS
4939 SHOW_STR
4940 IP_STR
4941 PIM_STR
c68ba0d7 4942 VRF_CMD_HELP_STR
a268493f 4943 "PIM RP information\n"
f5da2cc2 4944 JSON_STR)
00d07c6f 4945{
c68ba0d7
DS
4946 int idx = 2;
4947 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 4948 bool uj = use_json(argc, argv);
c68ba0d7
DS
4949
4950 if (!vrf)
4951 return CMD_WARNING;
4952
64c86530 4953 pim_rp_show_information(vrf->info, vty, uj);
00d07c6f 4954
d62a17ae 4955 return CMD_SUCCESS;
00d07c6f
DS
4956}
4957
a25de56b
DS
4958DEFUN (show_ip_pim_rp_vrf_all,
4959 show_ip_pim_rp_vrf_all_cmd,
4960 "show ip pim vrf all rp-info [json]",
4961 SHOW_STR
4962 IP_STR
4963 PIM_STR
4964 VRF_CMD_HELP_STR
4965 "PIM RP information\n"
f5da2cc2 4966 JSON_STR)
a25de56b 4967{
9f049418 4968 bool uj = use_json(argc, argv);
a25de56b
DS
4969 struct vrf *vrf;
4970 bool first = true;
4971
4972 if (uj)
4973 vty_out(vty, "{ ");
a2addae8 4974 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
4975 if (uj) {
4976 if (!first)
4977 vty_out(vty, ", ");
4978 vty_out(vty, " \"%s\": ", vrf->name);
4979 first = false;
4980 } else
4981 vty_out(vty, "VRF: %s\n", vrf->name);
4982 pim_rp_show_information(vrf->info, vty, uj);
4983 }
4984 if (uj)
4985 vty_out(vty, "}\n");
4986
4987 return CMD_SUCCESS;
4988}
4989
12e41d03
DL
4990DEFUN (show_ip_pim_rpf,
4991 show_ip_pim_rpf_cmd,
20a7e5fd 4992 "show ip pim [vrf NAME] rpf [json]",
12e41d03
DL
4993 SHOW_STR
4994 IP_STR
4995 PIM_STR
c68ba0d7 4996 VRF_CMD_HELP_STR
a268493f 4997 "PIM cached source rpf information\n"
f5da2cc2 4998 JSON_STR)
12e41d03 4999{
c68ba0d7
DS
5000 int idx = 2;
5001 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5002 bool uj = use_json(argc, argv);
c68ba0d7
DS
5003
5004 if (!vrf)
5005 return CMD_WARNING;
5006
64c86530 5007 pim_show_rpf(vrf->info, vty, uj);
12e41d03 5008
d62a17ae 5009 return CMD_SUCCESS;
12e41d03
DL
5010}
5011
a25de56b
DS
5012DEFUN (show_ip_pim_rpf_vrf_all,
5013 show_ip_pim_rpf_vrf_all_cmd,
5014 "show ip pim vrf all rpf [json]",
5015 SHOW_STR
5016 IP_STR
5017 PIM_STR
5018 VRF_CMD_HELP_STR
5019 "PIM cached source rpf information\n"
f5da2cc2 5020 JSON_STR)
a25de56b 5021{
9f049418 5022 bool uj = use_json(argc, argv);
a25de56b
DS
5023 struct vrf *vrf;
5024 bool first = true;
5025
5026 if (uj)
5027 vty_out(vty, "{ ");
a2addae8 5028 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5029 if (uj) {
5030 if (!first)
5031 vty_out(vty, ", ");
5032 vty_out(vty, " \"%s\": ", vrf->name);
5033 first = false;
5034 } else
5035 vty_out(vty, "VRF: %s\n", vrf->name);
5036 pim_show_rpf(vrf->info, vty, uj);
5037 }
5038 if (uj)
5039 vty_out(vty, "}\n");
5040
5041 return CMD_SUCCESS;
5042}
5043
cba44481
CS
5044DEFUN (show_ip_pim_nexthop,
5045 show_ip_pim_nexthop_cmd,
20a7e5fd 5046 "show ip pim [vrf NAME] nexthop",
cba44481
CS
5047 SHOW_STR
5048 IP_STR
5049 PIM_STR
c68ba0d7 5050 VRF_CMD_HELP_STR
cba44481
CS
5051 "PIM cached nexthop rpf information\n")
5052{
c68ba0d7
DS
5053 int idx = 2;
5054 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5055
5056 if (!vrf)
5057 return CMD_WARNING;
5058
64c86530 5059 pim_show_nexthop(vrf->info, vty);
cba44481 5060
d62a17ae 5061 return CMD_SUCCESS;
cba44481
CS
5062}
5063
5064DEFUN (show_ip_pim_nexthop_lookup,
5065 show_ip_pim_nexthop_lookup_cmd,
20a7e5fd 5066 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
cba44481
CS
5067 SHOW_STR
5068 IP_STR
5069 PIM_STR
c68ba0d7 5070 VRF_CMD_HELP_STR
cba44481
CS
5071 "PIM cached nexthop rpf lookup\n"
5072 "Source/RP address\n"
5073 "Multicast Group address\n")
5074{
d62a17ae 5075 struct prefix nht_p;
5076 int result = 0;
5077 struct in_addr src_addr, grp_addr;
5078 struct in_addr vif_source;
5079 const char *addr_str, *addr_str1;
5080 struct prefix grp;
5081 struct pim_nexthop nexthop;
5082 char nexthop_addr_str[PREFIX_STRLEN];
5083 char grp_str[PREFIX_STRLEN];
c68ba0d7
DS
5084 int idx = 2;
5085 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 5086
c68ba0d7
DS
5087 if (!vrf)
5088 return CMD_WARNING;
5089
5090 argv_find(argv, argc, "A.B.C.D", &idx);
5091 addr_str = argv[idx]->arg;
d62a17ae 5092 result = inet_pton(AF_INET, addr_str, &src_addr);
5093 if (result <= 0) {
5094 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5095 errno, safe_strerror(errno));
5096 return CMD_WARNING;
5097 }
5098
5099 if (pim_is_group_224_4(src_addr)) {
5100 vty_out(vty,
5101 "Invalid argument. Expected Valid Source Address.\n");
5102 return CMD_WARNING;
5103 }
5104
c68ba0d7 5105 addr_str1 = argv[idx + 1]->arg;
d62a17ae 5106 result = inet_pton(AF_INET, addr_str1, &grp_addr);
5107 if (result <= 0) {
5108 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5109 errno, safe_strerror(errno));
5110 return CMD_WARNING;
5111 }
5112
5113 if (!pim_is_group_224_4(grp_addr)) {
5114 vty_out(vty,
5115 "Invalid argument. Expected Valid Multicast Group Address.\n");
5116 return CMD_WARNING;
5117 }
5118
c68ba0d7
DS
5119 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
5120 grp_addr))
d62a17ae 5121 return CMD_SUCCESS;
5122
d62a17ae 5123 nht_p.family = AF_INET;
5124 nht_p.prefixlen = IPV4_MAX_BITLEN;
5125 nht_p.u.prefix4 = vif_source;
5126 grp.family = AF_INET;
5127 grp.prefixlen = IPV4_MAX_BITLEN;
5128 grp.u.prefix4 = grp_addr;
5129 memset(&nexthop, 0, sizeof(nexthop));
5130
43763b11 5131 result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
9993f22c
DS
5132
5133 if (!result) {
996c9314
LB
5134 vty_out(vty,
5135 "Nexthop Lookup failed, no usable routes returned.\n");
9993f22c
DS
5136 return CMD_SUCCESS;
5137 }
d62a17ae 5138
5139 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
5140 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
5141 nexthop_addr_str, sizeof(nexthop_addr_str));
5142 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
5143 nexthop_addr_str, nexthop.interface->name);
5144
5145 return CMD_SUCCESS;
cba44481
CS
5146}
5147
39438188
CS
5148DEFUN (show_ip_pim_interface_traffic,
5149 show_ip_pim_interface_traffic_cmd,
20a7e5fd 5150 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
39438188
CS
5151 SHOW_STR
5152 IP_STR
5153 PIM_STR
c68ba0d7 5154 VRF_CMD_HELP_STR
39438188
CS
5155 "PIM interface information\n"
5156 "Protocol Packet counters\n"
17d86e50 5157 "Interface name\n"
f5da2cc2 5158 JSON_STR)
39438188 5159{
c68ba0d7
DS
5160 int idx = 2;
5161 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 5162 bool uj = use_json(argc, argv);
c68ba0d7
DS
5163
5164 if (!vrf)
5165 return CMD_WARNING;
39438188 5166
d62a17ae 5167 if (argv_find(argv, argc, "WORD", &idx))
64c86530 5168 pim_show_interface_traffic_single(vrf->info, vty,
c68ba0d7 5169 argv[idx]->arg, uj);
d62a17ae 5170 else
64c86530 5171 pim_show_interface_traffic(vrf->info, vty, uj);
39438188 5172
d62a17ae 5173 return CMD_SUCCESS;
39438188
CS
5174}
5175
0d1a4e24 5176DEFUN (show_ip_pim_bsm_db,
5177 show_ip_pim_bsm_db_cmd,
5178 "show ip pim bsm-database [vrf NAME] [json]",
5179 SHOW_STR
5180 IP_STR
5181 PIM_STR
0d1a4e24 5182 "PIM cached bsm packets information\n"
33b58e53 5183 VRF_CMD_HELP_STR
0d1a4e24 5184 JSON_STR)
5185{
5186 int idx = 2;
5187 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5188 bool uj = use_json(argc, argv);
5189
5190 if (!vrf)
5191 return CMD_WARNING;
5192
5193 pim_show_bsm_db(vrf->info, vty, uj);
5194 return CMD_SUCCESS;
5195}
321295c1 5196
5197DEFUN (show_ip_pim_bsrp,
5198 show_ip_pim_bsrp_cmd,
5199 "show ip pim bsrp-info [vrf NAME] [json]",
5200 SHOW_STR
5201 IP_STR
5202 PIM_STR
321295c1 5203 "PIM cached group-rp mappings information\n"
33b58e53 5204 VRF_CMD_HELP_STR
321295c1 5205 JSON_STR)
5206{
5207 int idx = 2;
5208 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5209 bool uj = use_json(argc, argv);
5210
5211 if (!vrf)
5212 return CMD_WARNING;
5213
5214 pim_show_group_rp_mappings_info(vrf->info, vty, uj);
5215
5216 return CMD_SUCCESS;
5217}
5218
415f6350 5219DEFUN (show_ip_pim_statistics,
5220 show_ip_pim_statistics_cmd,
33b58e53 5221 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
415f6350 5222 SHOW_STR
5223 IP_STR
5224 PIM_STR
5225 VRF_CMD_HELP_STR
5226 "PIM statistics\n"
33b58e53 5227 INTERFACE_STR
415f6350 5228 "PIM interface\n"
5229 JSON_STR)
5230{
5231 int idx = 2;
5232 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5233 bool uj = use_json(argc, argv);
5234
5235 if (!vrf)
5236 return CMD_WARNING;
5237
5238 if (argv_find(argv, argc, "WORD", &idx))
5239 pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
5240 else
5241 pim_show_statistics(vrf->info, vty, NULL, uj);
5242
5243 return CMD_SUCCESS;
5244}
5245
64c86530 5246static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
12e41d03 5247{
d62a17ae 5248 struct interface *ifp;
5249
5250 vty_out(vty, "\n");
5251
5252 vty_out(vty,
ff415346 5253 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
d62a17ae 5254
451fda4f 5255 FOR_ALL_INTERFACES (pim->vrf, ifp) {
c68ba0d7
DS
5256 struct pim_interface *pim_ifp;
5257 struct in_addr ifaddr;
5258 struct sioc_vif_req vreq;
d62a17ae 5259
c68ba0d7 5260 pim_ifp = ifp->info;
d62a17ae 5261
c68ba0d7
DS
5262 if (!pim_ifp)
5263 continue;
d62a17ae 5264
c68ba0d7
DS
5265 memset(&vreq, 0, sizeof(vreq));
5266 vreq.vifi = pim_ifp->mroute_vif_index;
d62a17ae 5267
c68ba0d7
DS
5268 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
5269 zlog_warn(
5270 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5271 (unsigned long)SIOCGETVIFCNT, ifp->name,
5272 pim_ifp->mroute_vif_index, errno,
5273 safe_strerror(errno));
5274 }
ecca97ac 5275
c68ba0d7 5276 ifaddr = pim_ifp->primary_address;
d62a17ae 5277
ff415346 5278 vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
c68ba0d7
DS
5279 ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
5280 pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
5281 (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
5282 (unsigned long)vreq.obytes);
d62a17ae 5283 }
12e41d03
DL
5284}
5285
a25de56b
DS
5286static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
5287 struct vty *vty)
12e41d03 5288{
a25de56b 5289 struct vrf *vrf = pim->vrf;
d62a17ae 5290 time_t now = pim_time_monotonic_sec();
d62a17ae 5291 char uptime[10];
afec9bba 5292 char mlag_role[80];
d62a17ae 5293
bc14b6c7
DS
5294 pim = vrf->info;
5295
afec9bba
DS
5296 vty_out(vty, "Router MLAG Role: %s\n",
5297 mlag_role2str(router->role, mlag_role, sizeof(mlag_role)));
ecca97ac
DS
5298 vty_out(vty, "Mroute socket descriptor:");
5299
c68ba0d7 5300 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
12e41d03 5301
d62a17ae 5302 pim_time_uptime(uptime, sizeof(uptime),
c68ba0d7 5303 now - pim->mroute_socket_creation);
d62a17ae 5304 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
12e41d03 5305
d62a17ae 5306 vty_out(vty, "\n");
12e41d03 5307
d62a17ae 5308 pim_zebra_zclient_update(vty);
5309 pim_zlookup_show_ip_multicast(vty);
05b0d0d0 5310
d62a17ae 5311 vty_out(vty, "\n");
5312 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
12e41d03 5313
d62a17ae 5314 vty_out(vty, "\n");
5b45753e 5315 vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
d62a17ae 5316 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
4795fff7 5317 vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
d62a17ae 5318 vty_out(vty, "PIM ECMP Rebalance: %s\n",
4795fff7 5319 pim->ecmp_rebalance_enable ? "Enable" : "Disable");
12e41d03 5320
d62a17ae 5321 vty_out(vty, "\n");
12e41d03 5322
da11e325 5323 show_rpf_refresh_stats(vty, pim, now, NULL);
12e41d03 5324
d62a17ae 5325 vty_out(vty, "\n");
12e41d03 5326
64c86530 5327 show_scan_oil_stats(pim, vty, now);
12e41d03 5328
64c86530 5329 show_multicast_interfaces(pim, vty);
a25de56b
DS
5330}
5331
5332DEFUN (show_ip_multicast,
5333 show_ip_multicast_cmd,
5334 "show ip multicast [vrf NAME]",
5335 SHOW_STR
5336 IP_STR
5337 VRF_CMD_HELP_STR
5338 "Multicast global information\n")
5339{
5340 int idx = 2;
5341 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5342
5343 if (!vrf)
5344 return CMD_WARNING;
5345
5346 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5347
5348 return CMD_SUCCESS;
5349}
5350
5351DEFUN (show_ip_multicast_vrf_all,
5352 show_ip_multicast_vrf_all_cmd,
5353 "show ip multicast vrf all",
5354 SHOW_STR
5355 IP_STR
5356 VRF_CMD_HELP_STR
5357 "Multicast global information\n")
5358{
9f049418 5359 bool uj = use_json(argc, argv);
a25de56b
DS
5360 struct vrf *vrf;
5361 bool first = true;
5362
5363 if (uj)
5364 vty_out(vty, "{ ");
a2addae8 5365 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
5366 if (uj) {
5367 if (!first)
5368 vty_out(vty, ", ");
5369 vty_out(vty, " \"%s\": ", vrf->name);
5370 first = false;
5371 } else
5372 vty_out(vty, "VRF: %s\n", vrf->name);
5373 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5374 }
5375 if (uj)
5376 vty_out(vty, "}\n");
12e41d03 5377
d62a17ae 5378 return CMD_SUCCESS;
12e41d03
DL
5379}
5380
c23c1d39
DS
5381static void show_mroute(struct pim_instance *pim, struct vty *vty,
5382 struct prefix_sg *sg, bool fill, bool uj)
12e41d03 5383{
d62a17ae 5384 struct listnode *node;
5385 struct channel_oil *c_oil;
5386 struct static_route *s_route;
5387 time_t now;
5388 json_object *json = NULL;
5389 json_object *json_group = NULL;
5390 json_object *json_source = NULL;
5391 json_object *json_oil = NULL;
5392 json_object *json_ifp_out = NULL;
a2b6e694 5393 int found_oif;
5394 int first;
d62a17ae 5395 char grp_str[INET_ADDRSTRLEN];
5396 char src_str[INET_ADDRSTRLEN];
5397 char in_ifname[INTERFACE_NAMSIZ + 1];
5398 char out_ifname[INTERFACE_NAMSIZ + 1];
5399 int oif_vif_index;
5400 struct interface *ifp_in;
5401 char proto[100];
5402
5403 if (uj) {
5404 json = json_object_new_object();
5405 } else {
5406 vty_out(vty,
ff415346 5407 "Source Group Proto Input Output TTL Uptime\n");
d62a17ae 5408 }
5409
5410 now = pim_time_monotonic_sec();
5411
5412 /* print list of PIM and IGMP routes */
7315ecda 5413 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
d62a17ae 5414 found_oif = 0;
5415 first = 1;
5416 if (!c_oil->installed && !uj)
5417 continue;
5418
c23c1d39
DS
5419 if (sg->grp.s_addr != 0 &&
5420 sg->grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr)
5421 continue;
5422 if (sg->src.s_addr != 0 &&
5423 sg->src.s_addr != c_oil->oil.mfcc_origin.s_addr)
5424 continue;
5425
d62a17ae 5426 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
5427 sizeof(grp_str));
5428 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
5429 sizeof(src_str));
7cfc7bcf 5430 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 5431
5432 if (ifp_in)
c35b7e6b 5433 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
d62a17ae 5434 else
c35b7e6b 5435 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 5436
5437 if (uj) {
5438
5439 /* Find the group, create it if it doesn't exist */
5440 json_object_object_get_ex(json, grp_str, &json_group);
5441
5442 if (!json_group) {
5443 json_group = json_object_new_object();
5444 json_object_object_add(json, grp_str,
5445 json_group);
5446 }
5447
5448 /* Find the source nested under the group, create it if
5449 * it doesn't exist */
5450 json_object_object_get_ex(json_group, src_str,
5451 &json_source);
5452
5453 if (!json_source) {
5454 json_source = json_object_new_object();
5455 json_object_object_add(json_group, src_str,
5456 json_source);
5457 }
5458
5459 /* Find the inbound interface nested under the source,
5460 * create it if it doesn't exist */
5461 json_object_int_add(json_source, "installed",
5462 c_oil->installed);
5463 json_object_int_add(json_source, "refCount",
5464 c_oil->oil_ref_count);
5465 json_object_int_add(json_source, "oilSize",
5466 c_oil->oil_size);
5467 json_object_int_add(json_source, "OilInheritedRescan",
5468 c_oil->oil_inherited_rescan);
5469 json_object_string_add(json_source, "iif", in_ifname);
5470 json_oil = NULL;
5471 }
5472
5473 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5474 ++oif_vif_index) {
5475 struct interface *ifp_out;
e7cd85bd 5476 char mroute_uptime[10];
d62a17ae 5477 int ttl;
5478
5479 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
5480 if (ttl < 1)
5481 continue;
5482
5923b739
AK
5483 /* do not display muted OIFs */
5484 if (c_oil->oif_flags[oif_vif_index]
5485 & PIM_OIF_FLAG_MUTE)
5486 continue;
5487
60eb7e6b
AK
5488 if (c_oil->oil.mfcc_parent == oif_vif_index &&
5489 !pim_mroute_allow_iif_in_oil(c_oil,
5490 oif_vif_index))
5491 continue;
5492
7cfc7bcf 5493 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 5494 pim_time_uptime(
e7cd85bd
SP
5495 mroute_uptime, sizeof(mroute_uptime),
5496 now - c_oil->mroute_creation);
d62a17ae 5497 found_oif = 1;
5498
5499 if (ifp_out)
c35b7e6b 5500 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
d62a17ae 5501 else
c35b7e6b 5502 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 5503
5504 if (uj) {
5505 json_ifp_out = json_object_new_object();
5506 json_object_string_add(json_ifp_out, "source",
5507 src_str);
5508 json_object_string_add(json_ifp_out, "group",
5509 grp_str);
5510
5511 if (c_oil->oif_flags[oif_vif_index]
5512 & PIM_OIF_FLAG_PROTO_PIM)
5513 json_object_boolean_true_add(
5514 json_ifp_out, "protocolPim");
5515
5516 if (c_oil->oif_flags[oif_vif_index]
5517 & PIM_OIF_FLAG_PROTO_IGMP)
5518 json_object_boolean_true_add(
5519 json_ifp_out, "protocolIgmp");
5520
ee31c9fd
AK
5521 if (c_oil->oif_flags[oif_vif_index]
5522 & PIM_OIF_FLAG_PROTO_VXLAN)
5523 json_object_boolean_true_add(
5524 json_ifp_out, "protocolVxlan");
5525
d62a17ae 5526 if (c_oil->oif_flags[oif_vif_index]
5527 & PIM_OIF_FLAG_PROTO_STAR)
5528 json_object_boolean_true_add(
5529 json_ifp_out,
5530 "protocolInherited");
5531
5532 json_object_string_add(json_ifp_out,
5533 "inboundInterface",
5534 in_ifname);
5535 json_object_int_add(json_ifp_out, "iVifI",
5536 c_oil->oil.mfcc_parent);
5537 json_object_string_add(json_ifp_out,
5538 "outboundInterface",
5539 out_ifname);
5540 json_object_int_add(json_ifp_out, "oVifI",
5541 oif_vif_index);
5542 json_object_int_add(json_ifp_out, "ttl", ttl);
5543 json_object_string_add(json_ifp_out, "upTime",
e7cd85bd 5544 mroute_uptime);
d62a17ae 5545 if (!json_oil) {
5546 json_oil = json_object_new_object();
5547 json_object_object_add(json_source,
5548 "oil", json_oil);
5549 }
5550 json_object_object_add(json_oil, out_ifname,
5551 json_ifp_out);
5552 } else {
5553 if (c_oil->oif_flags[oif_vif_index]
5554 & PIM_OIF_FLAG_PROTO_PIM) {
c35b7e6b 5555 strlcpy(proto, "PIM", sizeof(proto));
d62a17ae 5556 }
5557
5558 if (c_oil->oif_flags[oif_vif_index]
5559 & PIM_OIF_FLAG_PROTO_IGMP) {
c35b7e6b 5560 strlcpy(proto, "IGMP", sizeof(proto));
d62a17ae 5561 }
5562
ee31c9fd
AK
5563 if (c_oil->oif_flags[oif_vif_index]
5564 & PIM_OIF_FLAG_PROTO_VXLAN) {
c35b7e6b 5565 strlcpy(proto, "VxLAN", sizeof(proto));
ee31c9fd
AK
5566 }
5567
d62a17ae 5568 if (c_oil->oif_flags[oif_vif_index]
5569 & PIM_OIF_FLAG_PROTO_STAR) {
c35b7e6b 5570 strlcpy(proto, "STAR", sizeof(proto));
d62a17ae 5571 }
5572
5573 vty_out(vty,
ff415346 5574 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
d62a17ae 5575 src_str, grp_str, proto, in_ifname,
e7cd85bd 5576 out_ifname, ttl, mroute_uptime);
d62a17ae 5577
5578 if (first) {
5579 src_str[0] = '\0';
5580 grp_str[0] = '\0';
5581 in_ifname[0] = '\0';
5582 first = 0;
5583 }
5584 }
5585 }
5586
5587 if (!uj && !found_oif) {
ff415346 5588 vty_out(vty, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
d62a17ae 5589 src_str, grp_str, "none", in_ifname, "none", 0,
5590 "--:--:--");
5591 }
5592 }
5593
5594 /* Print list of static routes */
7cfc7bcf
DS
5595 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5596 first = 1;
5597
5598 if (!s_route->c_oil.installed)
d62a17ae 5599 continue;
5600
7cfc7bcf
DS
5601 pim_inet4_dump("<group?>", s_route->group, grp_str,
5602 sizeof(grp_str));
5603 pim_inet4_dump("<source?>", s_route->source, src_str,
5604 sizeof(src_str));
5605 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
5606 found_oif = 0;
d62a17ae 5607
7cfc7bcf 5608 if (ifp_in)
c35b7e6b 5609 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
7cfc7bcf 5610 else
c35b7e6b 5611 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
d62a17ae 5612
7cfc7bcf 5613 if (uj) {
d62a17ae 5614
7cfc7bcf
DS
5615 /* Find the group, create it if it doesn't exist */
5616 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 5617
7cfc7bcf
DS
5618 if (!json_group) {
5619 json_group = json_object_new_object();
5620 json_object_object_add(json, grp_str,
5621 json_group);
5622 }
d62a17ae 5623
7cfc7bcf
DS
5624 /* Find the source nested under the group, create it if
5625 * it doesn't exist */
5626 json_object_object_get_ex(json_group, src_str,
5627 &json_source);
d62a17ae 5628
7cfc7bcf
DS
5629 if (!json_source) {
5630 json_source = json_object_new_object();
5631 json_object_object_add(json_group, src_str,
5632 json_source);
5633 }
d62a17ae 5634
7cfc7bcf
DS
5635 json_object_string_add(json_source, "iif", in_ifname);
5636 json_oil = NULL;
5637 } else {
c35b7e6b 5638 strlcpy(proto, "STATIC", sizeof(proto));
7cfc7bcf 5639 }
d62a17ae 5640
7cfc7bcf
DS
5641 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5642 ++oif_vif_index) {
5643 struct interface *ifp_out;
5644 char oif_uptime[10];
5645 int ttl;
d62a17ae 5646
7cfc7bcf
DS
5647 ttl = s_route->oif_ttls[oif_vif_index];
5648 if (ttl < 1)
5649 continue;
5650
5651 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
996c9314
LB
5652 pim_time_uptime(
5653 oif_uptime, sizeof(oif_uptime),
5654 now
5655 - s_route->c_oil
5656 .oif_creation[oif_vif_index]);
7cfc7bcf 5657 found_oif = 1;
d62a17ae 5658
7cfc7bcf 5659 if (ifp_out)
c35b7e6b 5660 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
7cfc7bcf 5661 else
c35b7e6b 5662 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
d62a17ae 5663
7cfc7bcf
DS
5664 if (uj) {
5665 json_ifp_out = json_object_new_object();
5666 json_object_string_add(json_ifp_out, "source",
5667 src_str);
5668 json_object_string_add(json_ifp_out, "group",
5669 grp_str);
5670 json_object_boolean_true_add(json_ifp_out,
5671 "protocolStatic");
5672 json_object_string_add(json_ifp_out,
5673 "inboundInterface",
5674 in_ifname);
5675 json_object_int_add(
5676 json_ifp_out, "iVifI",
5677 s_route->c_oil.oil.mfcc_parent);
5678 json_object_string_add(json_ifp_out,
5679 "outboundInterface",
5680 out_ifname);
5681 json_object_int_add(json_ifp_out, "oVifI",
5682 oif_vif_index);
5683 json_object_int_add(json_ifp_out, "ttl", ttl);
5684 json_object_string_add(json_ifp_out, "upTime",
5685 oif_uptime);
5686 if (!json_oil) {
5687 json_oil = json_object_new_object();
5688 json_object_object_add(json_source,
5689 "oil", json_oil);
d62a17ae 5690 }
7cfc7bcf
DS
5691 json_object_object_add(json_oil, out_ifname,
5692 json_ifp_out);
5693 } else {
d62a17ae 5694 vty_out(vty,
ff415346 5695 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
d62a17ae 5696 src_str, grp_str, proto, in_ifname,
7cfc7bcf
DS
5697 out_ifname, ttl, oif_uptime,
5698 pim->vrf->name);
45b7b092 5699 if (first && !fill) {
7cfc7bcf
DS
5700 src_str[0] = '\0';
5701 grp_str[0] = '\0';
5702 in_ifname[0] = '\0';
5703 first = 0;
5704 }
d62a17ae 5705 }
5706 }
7cfc7bcf
DS
5707
5708 if (!uj && !found_oif) {
5709 vty_out(vty,
ff415346 5710 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
7cfc7bcf
DS
5711 src_str, grp_str, proto, in_ifname, "none", 0,
5712 "--:--:--", pim->vrf->name);
5713 }
d62a17ae 5714 }
5715
5716 if (uj) {
9d303b37
DL
5717 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5718 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 5719 json_object_free(json);
5720 }
12e41d03
DL
5721}
5722
c23c1d39 5723DEFPY (show_ip_mroute,
12e41d03 5724 show_ip_mroute_cmd,
c23c1d39 5725 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
12e41d03
DL
5726 SHOW_STR
5727 IP_STR
a957a05b 5728 MROUTE_STR
c3169ac7 5729 VRF_CMD_HELP_STR
c23c1d39
DS
5730 "The Source or Group\n"
5731 "The Group\n"
45b7b092 5732 "Fill in Assumed data\n"
a957a05b 5733 JSON_STR)
12e41d03 5734{
c23c1d39
DS
5735 struct prefix_sg sg = {0};
5736 struct pim_instance *pim;
5737 struct vrf *v;
c68ba0d7 5738
c23c1d39
DS
5739 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
5740
5741 if (!v) {
5742 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
c68ba0d7 5743 return CMD_WARNING;
c23c1d39
DS
5744 }
5745 pim = pim_get_pim_instance(v->vrf_id);
c68ba0d7 5746
c23c1d39
DS
5747 if (!pim) {
5748 vty_out(vty, "%% Unable to find pim instance\n");
5749 return CMD_WARNING;
5750 }
45b7b092 5751
c23c1d39
DS
5752 if (s_or_g.s_addr != 0) {
5753 if (g.s_addr != 0) {
5754 sg.src = s_or_g;
5755 sg.grp = g;
5756 } else
5757 sg.grp = s_or_g;
5758 }
5759 show_mroute(pim, vty, &sg, !!fill, !!json);
d62a17ae 5760 return CMD_SUCCESS;
12e41d03
DL
5761}
5762
b283a4ca
DS
5763DEFUN (show_ip_mroute_vrf_all,
5764 show_ip_mroute_vrf_all_cmd,
45b7b092 5765 "show ip mroute vrf all [fill] [json]",
b283a4ca
DS
5766 SHOW_STR
5767 IP_STR
5768 MROUTE_STR
5769 VRF_CMD_HELP_STR
45b7b092 5770 "Fill in Assumed data\n"
b283a4ca
DS
5771 JSON_STR)
5772{
c23c1d39 5773 struct prefix_sg sg = {0};
9f049418 5774 bool uj = use_json(argc, argv);
45b7b092 5775 int idx = 4;
b283a4ca
DS
5776 struct vrf *vrf;
5777 bool first = true;
45b7b092
DS
5778 bool fill = false;
5779
5780 if (argv_find(argv, argc, "fill", &idx))
5781 fill = true;
b283a4ca
DS
5782
5783 if (uj)
5784 vty_out(vty, "{ ");
a2addae8 5785 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
b283a4ca
DS
5786 if (uj) {
5787 if (!first)
5788 vty_out(vty, ", ");
5789 vty_out(vty, " \"%s\": ", vrf->name);
5790 first = false;
5791 } else
5792 vty_out(vty, "VRF: %s\n", vrf->name);
c23c1d39 5793 show_mroute(vrf->info, vty, &sg, fill, uj);
b283a4ca
DS
5794 }
5795 if (uj)
5cef40fc 5796 vty_out(vty, "}\n");
b283a4ca
DS
5797
5798 return CMD_SUCCESS;
5799}
5800
cd333cf9
DS
5801DEFUN (clear_ip_mroute_count,
5802 clear_ip_mroute_count_cmd,
5803 "clear ip mroute [vrf NAME] count",
5804 CLEAR_STR
5805 IP_STR
5806 MROUTE_STR
5807 VRF_CMD_HELP_STR
5808 "Route and packet count data\n")
5809{
5810 int idx = 2;
5811 struct listnode *node;
5812 struct channel_oil *c_oil;
5813 struct static_route *sr;
5814 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5815 struct pim_instance *pim;
5816
5817 if (!vrf)
5818 return CMD_WARNING;
5819
5820 pim = vrf->info;
7315ecda 5821 frr_each(rb_pim_oil, &pim->channel_oil_head, c_oil) {
cd333cf9
DS
5822 if (!c_oil->installed)
5823 continue;
5824
5825 pim_mroute_update_counters(c_oil);
5826 c_oil->cc.origpktcnt = c_oil->cc.pktcnt;
5827 c_oil->cc.origbytecnt = c_oil->cc.bytecnt;
5828 c_oil->cc.origwrong_if = c_oil->cc.wrong_if;
5829 }
5830
5831 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
5832 if (!sr->c_oil.installed)
5833 continue;
5834
5835 pim_mroute_update_counters(&sr->c_oil);
5836
5837 sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt;
5838 sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt;
5839 sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if;
5840 }
5841 return CMD_SUCCESS;
5842}
5843
64c86530 5844static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
12e41d03 5845{
d62a17ae 5846 struct listnode *node;
5847 struct channel_oil *c_oil;
cd333cf9 5848 struct static_route *sr;
12e41d03 5849
d62a17ae 5850 vty_out(vty, "\n");
12e41d03 5851
d62a17ae 5852 vty_out(vty,
5853 "Source Group LastUsed Packets Bytes WrongIf \n");
12e41d03 5854
d62a17ae 5855 /* Print PIM and IGMP route counts */
7315ecda 5856 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
d62a17ae 5857 char group_str[INET_ADDRSTRLEN];
5858 char source_str[INET_ADDRSTRLEN];
58302dc7 5859
d62a17ae 5860 if (!c_oil->installed)
5861 continue;
12e41d03 5862
d62a17ae 5863 pim_mroute_update_counters(c_oil);
12e41d03 5864
d62a17ae 5865 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
5866 sizeof(group_str));
5867 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
5868 sizeof(source_str));
6250610a 5869
d62a17ae 5870 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5871 source_str, group_str, c_oil->cc.lastused / 100,
cd333cf9
DS
5872 c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
5873 c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
5874 c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
d62a17ae 5875 }
5876
cd333cf9 5877 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
c68ba0d7
DS
5878 char group_str[INET_ADDRSTRLEN];
5879 char source_str[INET_ADDRSTRLEN];
6250610a 5880
cd333cf9 5881 if (!sr->c_oil.installed)
c68ba0d7 5882 continue;
6250610a 5883
cd333cf9 5884 pim_mroute_update_counters(&sr->c_oil);
4e0bc0f0 5885
cd333cf9 5886 pim_inet4_dump("<group?>", sr->c_oil.oil.mfcc_mcastgrp,
c68ba0d7 5887 group_str, sizeof(group_str));
cd333cf9 5888 pim_inet4_dump("<source?>", sr->c_oil.oil.mfcc_origin,
c68ba0d7 5889 source_str, sizeof(source_str));
4e0bc0f0 5890
c68ba0d7 5891 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
cd333cf9
DS
5892 source_str, group_str, sr->c_oil.cc.lastused,
5893 sr->c_oil.cc.pktcnt - sr->c_oil.cc.origpktcnt,
5894 sr->c_oil.cc.bytecnt - sr->c_oil.cc.origbytecnt,
5895 sr->c_oil.cc.wrong_if - sr->c_oil.cc.origwrong_if);
d62a17ae 5896 }
12e41d03
DL
5897}
5898
5899DEFUN (show_ip_mroute_count,
5900 show_ip_mroute_count_cmd,
20a7e5fd 5901 "show ip mroute [vrf NAME] count",
12e41d03
DL
5902 SHOW_STR
5903 IP_STR
5904 MROUTE_STR
c68ba0d7 5905 VRF_CMD_HELP_STR
12e41d03
DL
5906 "Route and packet count data\n")
5907{
c68ba0d7
DS
5908 int idx = 2;
5909 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5910
e691f179
DS
5911 if (!vrf)
5912 return CMD_WARNING;
5913
64c86530 5914 show_mroute_count(vrf->info, vty);
d62a17ae 5915 return CMD_SUCCESS;
12e41d03
DL
5916}
5917
5c3aac90
DS
5918DEFUN (show_ip_mroute_count_vrf_all,
5919 show_ip_mroute_count_vrf_all_cmd,
5920 "show ip mroute vrf all count",
5921 SHOW_STR
5922 IP_STR
5923 MROUTE_STR
5924 VRF_CMD_HELP_STR
5925 "Route and packet count data\n")
5926{
9f049418 5927 bool uj = use_json(argc, argv);
5c3aac90
DS
5928 struct vrf *vrf;
5929 bool first = true;
5930
5931 if (uj)
5932 vty_out(vty, "{ ");
a2addae8 5933 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5c3aac90
DS
5934 if (uj) {
5935 if (!first)
5936 vty_out(vty, ", ");
5937 vty_out(vty, " \"%s\": ", vrf->name);
5938 first = false;
5939 } else
5940 vty_out(vty, "VRF: %s\n", vrf->name);
5941 show_mroute_count(vrf->info, vty);
5942 }
5943 if (uj)
5944 vty_out(vty, "}\n");
5945
5946 return CMD_SUCCESS;
5947}
5948
468b6f44
SP
5949static void show_mroute_summary(struct pim_instance *pim, struct vty *vty)
5950{
5951 struct listnode *node;
5952 struct channel_oil *c_oil;
5953 struct static_route *s_route;
5954 uint32_t starg_sw_mroute_cnt = 0;
5955 uint32_t sg_sw_mroute_cnt = 0;
5956 uint32_t starg_hw_mroute_cnt = 0;
5957 uint32_t sg_hw_mroute_cnt = 0;
5958
5959 vty_out(vty, "Mroute Type Installed/Total\n");
5960
7315ecda 5961 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
468b6f44
SP
5962 if (!c_oil->installed) {
5963 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5964 starg_sw_mroute_cnt++;
5965 else
5966 sg_sw_mroute_cnt++;
5967 } else {
5968 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5969 starg_hw_mroute_cnt++;
5970 else
5971 sg_hw_mroute_cnt++;
5972 }
5973 }
5974
5975 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5976 if (!s_route->c_oil.installed) {
5977 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5978 starg_sw_mroute_cnt++;
5979 else
5980 sg_sw_mroute_cnt++;
5981 } else {
5982 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5983 starg_hw_mroute_cnt++;
5984 else
5985 sg_hw_mroute_cnt++;
5986 }
5987 }
5988
5989 vty_out(vty, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt,
5990 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
5991 vty_out(vty, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt,
5992 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
5993 vty_out(vty, "------\n");
5994 vty_out(vty, "%-20s %d/%d\n", "Total",
5995 (starg_hw_mroute_cnt + sg_hw_mroute_cnt),
5996 (starg_sw_mroute_cnt +
5997 starg_hw_mroute_cnt +
5998 sg_sw_mroute_cnt +
5999 sg_hw_mroute_cnt));
6000}
6001
6002DEFUN (show_ip_mroute_summary,
6003 show_ip_mroute_summary_cmd,
6004 "show ip mroute [vrf NAME] summary",
6005 SHOW_STR
6006 IP_STR
6007 MROUTE_STR
6008 VRF_CMD_HELP_STR
6009 "Summary of all mroutes\n")
6010{
6011 int idx = 2;
6012 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6013
6014 if (!vrf)
6015 return CMD_WARNING;
6016
6017 show_mroute_summary(vrf->info, vty);
6018 return CMD_SUCCESS;
6019}
6020
6021DEFUN (show_ip_mroute_summary_vrf_all,
6022 show_ip_mroute_summary_vrf_all_cmd,
6023 "show ip mroute vrf all summary",
6024 SHOW_STR
6025 IP_STR
6026 MROUTE_STR
6027 VRF_CMD_HELP_STR
6028 "Summary of all mroutes\n")
6029{
6030 struct vrf *vrf;
6031
6032 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
6033 vty_out(vty, "VRF: %s\n", vrf->name);
6034 show_mroute_summary(vrf->info, vty);
6035 }
6036
6037 return CMD_SUCCESS;
6038}
6039
12e41d03
DL
6040DEFUN (show_ip_rib,
6041 show_ip_rib_cmd,
20a7e5fd 6042 "show ip rib [vrf NAME] A.B.C.D",
12e41d03
DL
6043 SHOW_STR
6044 IP_STR
6045 RIB_STR
c68ba0d7 6046 VRF_CMD_HELP_STR
12e41d03
DL
6047 "Unicast address\n")
6048{
c68ba0d7
DS
6049 int idx = 2;
6050 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 6051 struct in_addr addr;
6052 const char *addr_str;
6053 struct pim_nexthop nexthop;
6054 char nexthop_addr_str[PREFIX_STRLEN];
6055 int result;
6056
c68ba0d7
DS
6057 if (!vrf)
6058 return CMD_WARNING;
6059
d62a17ae 6060 memset(&nexthop, 0, sizeof(nexthop));
c68ba0d7
DS
6061 argv_find(argv, argc, "A.B.C.D", &idx);
6062 addr_str = argv[idx]->arg;
d62a17ae 6063 result = inet_pton(AF_INET, addr_str, &addr);
6064 if (result <= 0) {
6065 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
6066 errno, safe_strerror(errno));
6067 return CMD_WARNING;
6068 }
12e41d03 6069
ade155e1 6070 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
d62a17ae 6071 vty_out(vty,
6072 "Failure querying RIB nexthop for unicast address %s\n",
6073 addr_str);
6074 return CMD_WARNING;
6075 }
12e41d03 6076
d62a17ae 6077 vty_out(vty,
6078 "Address NextHop Interface Metric Preference\n");
12e41d03 6079
d62a17ae 6080 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
6081 nexthop_addr_str, sizeof(nexthop_addr_str));
12e41d03 6082
d62a17ae 6083 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
6084 nexthop.interface ? nexthop.interface->name : "<ifname?>",
6085 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
12e41d03 6086
d62a17ae 6087 return CMD_SUCCESS;
12e41d03
DL
6088}
6089
64c86530 6090static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
12e41d03 6091{
d62a17ae 6092 struct listnode *node;
6093 struct ssmpingd_sock *ss;
6094 time_t now;
12e41d03 6095
d62a17ae 6096 vty_out(vty,
6097 "Source Socket Address Port Uptime Requests\n");
12e41d03 6098
71ad9915 6099 if (!pim->ssmpingd_list)
d62a17ae 6100 return;
12e41d03 6101
d62a17ae 6102 now = pim_time_monotonic_sec();
12e41d03 6103
71ad9915 6104 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
d62a17ae 6105 char source_str[INET_ADDRSTRLEN];
6106 char ss_uptime[10];
6107 struct sockaddr_in bind_addr;
6108 socklen_t len = sizeof(bind_addr);
6109 char bind_addr_str[INET_ADDRSTRLEN];
12e41d03 6110
d62a17ae 6111 pim_inet4_dump("<src?>", ss->source_addr, source_str,
6112 sizeof(source_str));
12e41d03 6113
d62a17ae 6114 if (pim_socket_getsockname(
6115 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
6116 vty_out(vty,
6117 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6118 source_str, ss->sock_fd);
6119 }
12e41d03 6120
d62a17ae 6121 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
6122 sizeof(bind_addr_str));
6123 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
6124 now - ss->creation);
12e41d03 6125
d62a17ae 6126 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
6127 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
6128 ss_uptime, (long long)ss->requests);
6129 }
12e41d03
DL
6130}
6131
6132DEFUN (show_ip_ssmpingd,
6133 show_ip_ssmpingd_cmd,
20a7e5fd 6134 "show ip ssmpingd [vrf NAME]",
12e41d03
DL
6135 SHOW_STR
6136 IP_STR
c68ba0d7
DS
6137 SHOW_SSMPINGD_STR
6138 VRF_CMD_HELP_STR)
12e41d03 6139{
c68ba0d7
DS
6140 int idx = 2;
6141 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6142
6143 if (!vrf)
6144 return CMD_WARNING;
6145
64c86530 6146 show_ssmpingd(vrf->info, vty);
d62a17ae 6147 return CMD_SUCCESS;
12e41d03
DL
6148}
6149
64c86530 6150static int pim_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
9ecb7b77 6151 const char *rp, const char *group,
d62a17ae 6152 const char *plist)
36d6bd7d 6153{
d62a17ae 6154 int result;
36d6bd7d 6155
d0e418b4 6156 result = pim_rp_new_config(pim, rp, group, plist);
6157
6158 if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
6159 vty_out(vty, "%% Inconsistent address and mask: %s\n",
6160 group);
6161 return CMD_WARNING_CONFIG_FAILED;
6162 }
dfe43e25 6163
d62a17ae 6164 if (result == PIM_GROUP_BAD_ADDRESS) {
6165 vty_out(vty, "%% Bad group address specified: %s\n", group);
6166 return CMD_WARNING_CONFIG_FAILED;
6167 }
dfe43e25 6168
d62a17ae 6169 if (result == PIM_RP_BAD_ADDRESS) {
6170 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
6171 return CMD_WARNING_CONFIG_FAILED;
6172 }
36d6bd7d 6173
d62a17ae 6174 if (result == PIM_RP_NO_PATH) {
6175 vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
c6e7b952 6176 return CMD_WARNING;
d62a17ae 6177 }
dfe43e25 6178
d62a17ae 6179 if (result == PIM_GROUP_OVERLAP) {
996c9314
LB
6180 vty_out(vty,
6181 "%% Group range specified cannot exact match another\n");
d62a17ae 6182 return CMD_WARNING_CONFIG_FAILED;
6183 }
dfe43e25 6184
d62a17ae 6185 if (result == PIM_GROUP_PFXLIST_OVERLAP) {
6186 vty_out(vty,
6187 "%% This group is already covered by a RP prefix-list\n");
6188 return CMD_WARNING_CONFIG_FAILED;
6189 }
36d6bd7d 6190
d62a17ae 6191 if (result == PIM_RP_PFXLIST_IN_USE) {
6192 vty_out(vty,
6193 "%% The same prefix-list cannot be applied to multiple RPs\n");
6194 return CMD_WARNING_CONFIG_FAILED;
6195 }
36d6bd7d 6196
d62a17ae 6197 return CMD_SUCCESS;
36d6bd7d
DS
6198}
6199
4f9f3925
DS
6200static int pim_cmd_spt_switchover(struct pim_instance *pim,
6201 enum pim_spt_switchover spt,
d62a17ae 6202 const char *plist)
df94f9a9 6203{
4f9f3925 6204 pim->spt.switchover = spt;
df94f9a9 6205
4f9f3925 6206 switch (pim->spt.switchover) {
d62a17ae 6207 case PIM_SPT_IMMEDIATE:
0a22ddfb 6208 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
df94f9a9 6209
4f9f3925 6210 pim_upstream_add_lhr_star_pimreg(pim);
d62a17ae 6211 break;
6212 case PIM_SPT_INFINITY:
4f9f3925 6213 pim_upstream_remove_lhr_star_pimreg(pim, plist);
df94f9a9 6214
0a22ddfb 6215 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
df94f9a9 6216
d62a17ae 6217 if (plist)
c68ba0d7 6218 pim->spt.plist =
d62a17ae 6219 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
6220 break;
6221 }
df94f9a9 6222
d62a17ae 6223 return CMD_SUCCESS;
df94f9a9
DS
6224}
6225
a7b2b1e2
DS
6226DEFUN (ip_pim_spt_switchover_infinity,
6227 ip_pim_spt_switchover_infinity_cmd,
6228 "ip pim spt-switchover infinity-and-beyond",
6229 IP_STR
6230 PIM_STR
6231 "SPT-Switchover\n"
6232 "Never switch to SPT Tree\n")
6233{
4f9f3925
DS
6234 PIM_DECLVAR_CONTEXT(vrf, pim);
6235 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, NULL);
df94f9a9 6236}
a7b2b1e2 6237
df94f9a9
DS
6238DEFUN (ip_pim_spt_switchover_infinity_plist,
6239 ip_pim_spt_switchover_infinity_plist_cmd,
6240 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6241 IP_STR
6242 PIM_STR
6243 "SPT-Switchover\n"
6244 "Never switch to SPT Tree\n"
6245 "Prefix-List to control which groups to switch\n"
6246 "Prefix-List name\n")
6247{
4f9f3925
DS
6248 PIM_DECLVAR_CONTEXT(vrf, pim);
6249 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, argv[5]->arg);
a7b2b1e2
DS
6250}
6251
6252DEFUN (no_ip_pim_spt_switchover_infinity,
6253 no_ip_pim_spt_switchover_infinity_cmd,
6254 "no ip pim spt-switchover infinity-and-beyond",
6255 NO_STR
6256 IP_STR
6257 PIM_STR
6258 "SPT_Switchover\n"
6259 "Never switch to SPT Tree\n")
6260{
4f9f3925
DS
6261 PIM_DECLVAR_CONTEXT(vrf, pim);
6262 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
df94f9a9 6263}
a7b2b1e2 6264
df94f9a9
DS
6265DEFUN (no_ip_pim_spt_switchover_infinity_plist,
6266 no_ip_pim_spt_switchover_infinity_plist_cmd,
6267 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6268 NO_STR
6269 IP_STR
6270 PIM_STR
6271 "SPT_Switchover\n"
6272 "Never switch to SPT Tree\n"
6273 "Prefix-List to control which groups to switch\n"
6274 "Prefix-List name\n")
6275{
4f9f3925
DS
6276 PIM_DECLVAR_CONTEXT(vrf, pim);
6277 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
a7b2b1e2
DS
6278}
6279
ee1a0718
DS
6280DEFUN (ip_pim_joinprune_time,
6281 ip_pim_joinprune_time_cmd,
ebe94743 6282 "ip pim join-prune-interval (60-600)",
ee1a0718
DS
6283 IP_STR
6284 "pim multicast routing\n"
6285 "Join Prune Send Interval\n"
6286 "Seconds\n")
6287{
4f9f3925 6288 PIM_DECLVAR_CONTEXT(vrf, pim);
5b45753e 6289 router->t_periodic = atoi(argv[3]->arg);
d62a17ae 6290 return CMD_SUCCESS;
ee1a0718
DS
6291}
6292
6293DEFUN (no_ip_pim_joinprune_time,
6294 no_ip_pim_joinprune_time_cmd,
ebe94743 6295 "no ip pim join-prune-interval (60-600)",
ee1a0718
DS
6296 NO_STR
6297 IP_STR
6298 "pim multicast routing\n"
6299 "Join Prune Send Interval\n"
6300 "Seconds\n")
6301{
4f9f3925 6302 PIM_DECLVAR_CONTEXT(vrf, pim);
5b45753e 6303 router->t_periodic = PIM_DEFAULT_T_PERIODIC;
d62a17ae 6304 return CMD_SUCCESS;
ee1a0718
DS
6305}
6306
191f5695
DS
6307DEFUN (ip_pim_register_suppress,
6308 ip_pim_register_suppress_cmd,
ebe94743 6309 "ip pim register-suppress-time (5-60000)",
4304f95c
DS
6310 IP_STR
6311 "pim multicast routing\n"
191f5695
DS
6312 "Register Suppress Timer\n"
6313 "Seconds\n")
4304f95c 6314{
4f9f3925 6315 PIM_DECLVAR_CONTEXT(vrf, pim);
2925dff5 6316 router->register_suppress_time = atoi(argv[3]->arg);
d62a17ae 6317 return CMD_SUCCESS;
4304f95c
DS
6318}
6319
191f5695
DS
6320DEFUN (no_ip_pim_register_suppress,
6321 no_ip_pim_register_suppress_cmd,
ebe94743 6322 "no ip pim register-suppress-time (5-60000)",
4304f95c
DS
6323 NO_STR
6324 IP_STR
6325 "pim multicast routing\n"
191f5695 6326 "Register Suppress Timer\n"
01408ede 6327 "Seconds\n")
4304f95c 6328{
4f9f3925 6329 PIM_DECLVAR_CONTEXT(vrf, pim);
2925dff5 6330 router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
d62a17ae 6331 return CMD_SUCCESS;
4304f95c
DS
6332}
6333
cc14df13
DS
6334DEFUN (ip_pim_rp_keep_alive,
6335 ip_pim_rp_keep_alive_cmd,
6336 "ip pim rp keep-alive-timer (31-60000)",
6337 IP_STR
6338 "pim multicast routing\n"
6339 "Rendevous Point\n"
6340 "Keep alive Timer\n"
6341 "Seconds\n")
6342{
6343 PIM_DECLVAR_CONTEXT(vrf, pim);
9643e2c7 6344 pim->rp_keep_alive_time = atoi(argv[4]->arg);
cc14df13
DS
6345 return CMD_SUCCESS;
6346}
6347
6348DEFUN (no_ip_pim_rp_keep_alive,
6349 no_ip_pim_rp_keep_alive_cmd,
6350 "no ip pim rp keep-alive-timer (31-60000)",
6351 NO_STR
6352 IP_STR
6353 "pim multicast routing\n"
6354 "Rendevous Point\n"
6355 "Keep alive Timer\n"
6356 "Seconds\n")
6357{
6358 PIM_DECLVAR_CONTEXT(vrf, pim);
6359 pim->rp_keep_alive_time = PIM_KEEPALIVE_PERIOD;
6360 return CMD_SUCCESS;
6361}
6362
191f5695
DS
6363DEFUN (ip_pim_keep_alive,
6364 ip_pim_keep_alive_cmd,
ebe94743 6365 "ip pim keep-alive-timer (31-60000)",
01408ede
DS
6366 IP_STR
6367 "pim multicast routing\n"
01408ede
DS
6368 "Keep alive Timer\n"
6369 "Seconds\n")
6370{
4f9f3925 6371 PIM_DECLVAR_CONTEXT(vrf, pim);
19b807ca 6372 pim->keep_alive_time = atoi(argv[3]->arg);
d62a17ae 6373 return CMD_SUCCESS;
01408ede
DS
6374}
6375
191f5695
DS
6376DEFUN (no_ip_pim_keep_alive,
6377 no_ip_pim_keep_alive_cmd,
ebe94743 6378 "no ip pim keep-alive-timer (31-60000)",
01408ede
DS
6379 NO_STR
6380 IP_STR
6381 "pim multicast routing\n"
01408ede
DS
6382 "Keep alive Timer\n"
6383 "Seconds\n")
6384{
4f9f3925 6385 PIM_DECLVAR_CONTEXT(vrf, pim);
19b807ca 6386 pim->keep_alive_time = PIM_KEEPALIVE_PERIOD;
d62a17ae 6387 return CMD_SUCCESS;
01408ede
DS
6388}
6389
8e4c9ef3
DS
6390DEFUN (ip_pim_packets,
6391 ip_pim_packets_cmd,
ebe94743 6392 "ip pim packets (1-100)",
8e4c9ef3
DS
6393 IP_STR
6394 "pim multicast routing\n"
a957a05b
DS
6395 "packets to process at one time per fd\n"
6396 "Number of packets\n")
8e4c9ef3 6397{
4f9f3925 6398 PIM_DECLVAR_CONTEXT(vrf, pim);
75373cca 6399 router->packet_process = atoi(argv[3]->arg);
d62a17ae 6400 return CMD_SUCCESS;
8e4c9ef3
DS
6401}
6402
6403DEFUN (no_ip_pim_packets,
6404 no_ip_pim_packets_cmd,
ebe94743 6405 "no ip pim packets (1-100)",
8e4c9ef3
DS
6406 NO_STR
6407 IP_STR
6408 "pim multicast routing\n"
a957a05b
DS
6409 "packets to process at one time per fd\n"
6410 "Number of packets\n")
8e4c9ef3 6411{
4f9f3925 6412 PIM_DECLVAR_CONTEXT(vrf, pim);
75373cca 6413 router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
d62a17ae 6414 return CMD_SUCCESS;
8e4c9ef3
DS
6415}
6416
71bbe73d
DS
6417DEFUN (ip_pim_v6_secondary,
6418 ip_pim_v6_secondary_cmd,
6419 "ip pim send-v6-secondary",
6420 IP_STR
6421 "pim multicast routing\n"
6422 "Send v6 secondary addresses\n")
6423{
4f9f3925 6424 PIM_DECLVAR_CONTEXT(vrf, pim);
c68ba0d7 6425 pim->send_v6_secondary = 1;
71bbe73d 6426
d62a17ae 6427 return CMD_SUCCESS;
71bbe73d
DS
6428}
6429
6430DEFUN (no_ip_pim_v6_secondary,
6431 no_ip_pim_v6_secondary_cmd,
6432 "no ip pim send-v6-secondary",
6433 NO_STR
6434 IP_STR
6435 "pim multicast routing\n"
6436 "Send v6 secondary addresses\n")
6437{
4f9f3925 6438 PIM_DECLVAR_CONTEXT(vrf, pim);
c68ba0d7 6439 pim->send_v6_secondary = 0;
71bbe73d 6440
d62a17ae 6441 return CMD_SUCCESS;
71bbe73d
DS
6442}
6443
981d6c7a
DS
6444DEFUN (ip_pim_rp,
6445 ip_pim_rp_cmd,
75a26779 6446 "ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a 6447 IP_STR
9b34069d
QY
6448 "pim multicast routing\n"
6449 "Rendevous Point\n"
a957a05b
DS
6450 "ip address of RP\n"
6451 "Group Address range to cover\n")
981d6c7a 6452{
ae4a6b57 6453 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6454 int idx_ipv4 = 3;
846ef662 6455
d62a17ae 6456 if (argc == (idx_ipv4 + 1))
64c86530 6457 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
9ecb7b77 6458 NULL);
d62a17ae 6459 else
64c86530 6460 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
d62a17ae 6461 argv[idx_ipv4 + 1]->arg, NULL);
dfe43e25
DW
6462}
6463
6464DEFUN (ip_pim_rp_prefix_list,
6465 ip_pim_rp_prefix_list_cmd,
6466 "ip pim rp A.B.C.D prefix-list WORD",
6467 IP_STR
6468 "pim multicast routing\n"
6469 "Rendevous Point\n"
6470 "ip address of RP\n"
6471 "group prefix-list filter\n"
6472 "Name of a prefix-list\n")
6473{
4f9f3925 6474 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 6475 return pim_rp_cmd_worker(pim, vty, argv[3]->arg, NULL, argv[5]->arg);
36d6bd7d 6476}
981d6c7a 6477
64c86530 6478static int pim_no_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925
DS
6479 const char *rp, const char *group,
6480 const char *plist)
36d6bd7d 6481{
d0e418b4 6482 int result = pim_rp_del_config(pim, rp, group, plist);
dfe43e25 6483
d62a17ae 6484 if (result == PIM_GROUP_BAD_ADDRESS) {
6485 vty_out(vty, "%% Bad group address specified: %s\n", group);
6486 return CMD_WARNING_CONFIG_FAILED;
6487 }
75a26779 6488
d62a17ae 6489 if (result == PIM_RP_BAD_ADDRESS) {
6490 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
6491 return CMD_WARNING_CONFIG_FAILED;
6492 }
981d6c7a 6493
d62a17ae 6494 if (result == PIM_RP_NOT_FOUND) {
6495 vty_out(vty, "%% Unable to find specified RP\n");
6496 return CMD_WARNING_CONFIG_FAILED;
6497 }
c8ae3ce8 6498
d62a17ae 6499 return CMD_SUCCESS;
981d6c7a
DS
6500}
6501
6502DEFUN (no_ip_pim_rp,
6503 no_ip_pim_rp_cmd,
75a26779 6504 "no ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a
DS
6505 NO_STR
6506 IP_STR
9b34069d
QY
6507 "pim multicast routing\n"
6508 "Rendevous Point\n"
a957a05b
DS
6509 "ip address of RP\n"
6510 "Group Address range to cover\n")
981d6c7a 6511{
4f9f3925 6512 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6513 int idx_ipv4 = 4, idx_group = 0;
72e81cf4 6514
d62a17ae 6515 if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
64c86530 6516 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
d62a17ae 6517 argv[idx_group]->arg, NULL);
6518 else
64c86530 6519 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
d62a17ae 6520 NULL);
dfe43e25
DW
6521}
6522
6523DEFUN (no_ip_pim_rp_prefix_list,
6524 no_ip_pim_rp_prefix_list_cmd,
6525 "no ip pim rp A.B.C.D prefix-list WORD",
6526 NO_STR
6527 IP_STR
6528 "pim multicast routing\n"
6529 "Rendevous Point\n"
6530 "ip address of RP\n"
6531 "group prefix-list filter\n"
6532 "Name of a prefix-list\n")
6533{
4f9f3925 6534 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 6535 return pim_no_rp_cmd_worker(pim, vty, argv[4]->arg, NULL, argv[6]->arg);
981d6c7a
DS
6536}
6537
6f439a70
DS
6538static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
6539 const char *plist)
15a5dafe 6540{
6f439a70 6541 int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
3b13a2cc 6542 int ret = CMD_WARNING_CONFIG_FAILED;
15a5dafe 6543
d62a17ae 6544 if (result == PIM_SSM_ERR_NONE)
6545 return CMD_SUCCESS;
15a5dafe 6546
d62a17ae 6547 switch (result) {
6548 case PIM_SSM_ERR_NO_VRF:
6549 vty_out(vty, "%% VRF doesn't exist\n");
6550 break;
6551 case PIM_SSM_ERR_DUP:
6552 vty_out(vty, "%% duplicate config\n");
3b13a2cc 6553 ret = CMD_WARNING;
d62a17ae 6554 break;
6555 default:
6556 vty_out(vty, "%% ssm range config failed\n");
6557 }
15a5dafe 6558
3b13a2cc 6559 return ret;
15a5dafe 6560}
6561
6562DEFUN (ip_pim_ssm_prefix_list,
6563 ip_pim_ssm_prefix_list_cmd,
6564 "ip pim ssm prefix-list WORD",
6565 IP_STR
6566 "pim multicast routing\n"
6567 "Source Specific Multicast\n"
6568 "group range prefix-list filter\n"
6569 "Name of a prefix-list\n")
6570{
4f9f3925 6571 PIM_DECLVAR_CONTEXT(vrf, pim);
9643e2c7 6572 return pim_ssm_cmd_worker(pim, vty, argv[4]->arg);
15a5dafe 6573}
6574
6575DEFUN (no_ip_pim_ssm_prefix_list,
6576 no_ip_pim_ssm_prefix_list_cmd,
6577 "no ip pim ssm prefix-list",
6578 NO_STR
6579 IP_STR
6580 "pim multicast routing\n"
6581 "Source Specific Multicast\n"
6582 "group range prefix-list filter\n")
6583{
4f9f3925
DS
6584 PIM_DECLVAR_CONTEXT(vrf, pim);
6585 return pim_ssm_cmd_worker(pim, vty, NULL);
15a5dafe 6586}
6587
6588DEFUN (no_ip_pim_ssm_prefix_list_name,
6589 no_ip_pim_ssm_prefix_list_name_cmd,
6590 "no ip pim ssm prefix-list WORD",
6591 NO_STR
6592 IP_STR
6593 "pim multicast routing\n"
6594 "Source Specific Multicast\n"
6595 "group range prefix-list filter\n"
6596 "Name of a prefix-list\n")
6597{
4f9f3925
DS
6598 PIM_DECLVAR_CONTEXT(vrf, pim);
6599 struct pim_ssm *ssm = pim->ssm_info;
15a5dafe 6600
9643e2c7 6601 if (ssm->plist_name && !strcmp(ssm->plist_name, argv[5]->arg))
4f9f3925 6602 return pim_ssm_cmd_worker(pim, vty, NULL);
15a5dafe 6603
9643e2c7 6604 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
15a5dafe 6605
d62a17ae 6606 return CMD_WARNING_CONFIG_FAILED;
15a5dafe 6607}
6608
64c86530 6609static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
088f1098 6610 struct vty *vty, bool uj)
15a5dafe 6611{
c68ba0d7 6612 struct pim_ssm *ssm = pim->ssm_info;
d62a17ae 6613 const char *range_str =
6614 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
15a5dafe 6615
d62a17ae 6616 if (uj) {
6617 json_object *json;
6618 json = json_object_new_object();
6619 json_object_string_add(json, "ssmGroups", range_str);
9d303b37
DL
6620 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6621 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 6622 json_object_free(json);
6623 } else
6624 vty_out(vty, "SSM group range : %s\n", range_str);
15a5dafe 6625}
6626
6627DEFUN (show_ip_pim_ssm_range,
6628 show_ip_pim_ssm_range_cmd,
20a7e5fd 6629 "show ip pim [vrf NAME] group-type [json]",
15a5dafe 6630 SHOW_STR
6631 IP_STR
6632 PIM_STR
c68ba0d7 6633 VRF_CMD_HELP_STR
15a5dafe 6634 "PIM group type\n"
f5da2cc2 6635 JSON_STR)
15a5dafe 6636{
c68ba0d7
DS
6637 int idx = 2;
6638 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 6639 bool uj = use_json(argc, argv);
c68ba0d7
DS
6640
6641 if (!vrf)
6642 return CMD_WARNING;
6643
64c86530 6644 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
15a5dafe 6645
d62a17ae 6646 return CMD_SUCCESS;
15a5dafe 6647}
6648
64c86530 6649static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
088f1098 6650 struct vty *vty, bool uj,
d62a17ae 6651 const char *group)
15a5dafe 6652{
d62a17ae 6653 struct in_addr group_addr;
6654 const char *type_str;
6655 int result;
15a5dafe 6656
d62a17ae 6657 result = inet_pton(AF_INET, group, &group_addr);
6658 if (result <= 0)
6659 type_str = "invalid";
6660 else {
6661 if (pim_is_group_224_4(group_addr))
c68ba0d7
DS
6662 type_str =
6663 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
d62a17ae 6664 else
6665 type_str = "not-multicast";
6666 }
15a5dafe 6667
d62a17ae 6668 if (uj) {
6669 json_object *json;
6670 json = json_object_new_object();
6671 json_object_string_add(json, "groupType", type_str);
9d303b37
DL
6672 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6673 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 6674 json_object_free(json);
6675 } else
6676 vty_out(vty, "Group type : %s\n", type_str);
15a5dafe 6677}
6678
6679DEFUN (show_ip_pim_group_type,
6680 show_ip_pim_group_type_cmd,
20a7e5fd 6681 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
15a5dafe 6682 SHOW_STR
6683 IP_STR
6684 PIM_STR
c68ba0d7 6685 VRF_CMD_HELP_STR
15a5dafe 6686 "multicast group type\n"
6687 "group address\n"
f5da2cc2 6688 JSON_STR)
15a5dafe 6689{
c68ba0d7
DS
6690 int idx = 2;
6691 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9f049418 6692 bool uj = use_json(argc, argv);
c68ba0d7
DS
6693
6694 if (!vrf)
6695 return CMD_WARNING;
6696
6697 argv_find(argv, argc, "A.B.C.D", &idx);
64c86530 6698 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
15a5dafe 6699
d62a17ae 6700 return CMD_SUCCESS;
15a5dafe 6701}
6702
256392eb 6703DEFUN (show_ip_pim_bsr,
6704 show_ip_pim_bsr_cmd,
6705 "show ip pim bsr [json]",
6706 SHOW_STR
6707 IP_STR
6708 PIM_STR
6709 "boot-strap router information\n"
6710 JSON_STR)
6711{
6712 int idx = 2;
6713 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6714 bool uj = use_json(argc, argv);
6715
6716 if (!vrf)
6717 return CMD_WARNING;
6718
6719 pim_show_bsr(vrf->info, vty, uj);
6720
6721 return CMD_SUCCESS;
6722}
6723
12e41d03
DL
6724DEFUN (ip_ssmpingd,
6725 ip_ssmpingd_cmd,
6726 "ip ssmpingd [A.B.C.D]",
6727 IP_STR
6728 CONF_SSMPINGD_STR
6729 "Source address\n")
6730{
4f9f3925 6731 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6732 int idx_ipv4 = 2;
6733 int result;
6734 struct in_addr source_addr;
6735 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03 6736
d62a17ae 6737 result = inet_pton(AF_INET, source_str, &source_addr);
6738 if (result <= 0) {
6739 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
6740 source_str, errno, safe_strerror(errno));
6741 return CMD_WARNING_CONFIG_FAILED;
6742 }
12e41d03 6743
4f9f3925 6744 result = pim_ssmpingd_start(pim, source_addr);
d62a17ae 6745 if (result) {
6746 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
6747 source_str, result);
6748 return CMD_WARNING_CONFIG_FAILED;
6749 }
12e41d03 6750
d62a17ae 6751 return CMD_SUCCESS;
12e41d03
DL
6752}
6753
6754DEFUN (no_ip_ssmpingd,
6755 no_ip_ssmpingd_cmd,
6756 "no ip ssmpingd [A.B.C.D]",
6757 NO_STR
6758 IP_STR
6759 CONF_SSMPINGD_STR
6760 "Source address\n")
6761{
4f9f3925 6762 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 6763 int idx_ipv4 = 3;
6764 int result;
6765 struct in_addr source_addr;
6766 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03 6767
d62a17ae 6768 result = inet_pton(AF_INET, source_str, &source_addr);
6769 if (result <= 0) {
6770 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
6771 source_str, errno, safe_strerror(errno));
6772 return CMD_WARNING_CONFIG_FAILED;
6773 }
12e41d03 6774
4f9f3925 6775 result = pim_ssmpingd_stop(pim, source_addr);
d62a17ae 6776 if (result) {
6777 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
6778 source_str, result);
6779 return CMD_WARNING_CONFIG_FAILED;
6780 }
12e41d03 6781
d62a17ae 6782 return CMD_SUCCESS;
12e41d03
DL
6783}
6784
cba44481
CS
6785DEFUN (ip_pim_ecmp,
6786 ip_pim_ecmp_cmd,
6787 "ip pim ecmp",
6788 IP_STR
6789 "pim multicast routing\n"
6790 "Enable PIM ECMP \n")
6791{
4f9f3925 6792 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7 6793 pim->ecmp_enable = true;
cba44481 6794
d62a17ae 6795 return CMD_SUCCESS;
cba44481
CS
6796}
6797
6798DEFUN (no_ip_pim_ecmp,
6799 no_ip_pim_ecmp_cmd,
6800 "no ip pim ecmp",
6801 NO_STR
6802 IP_STR
6803 "pim multicast routing\n"
6804 "Disable PIM ECMP \n")
6805{
4f9f3925 6806 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7 6807 pim->ecmp_enable = false;
cba44481 6808
d62a17ae 6809 return CMD_SUCCESS;
cba44481
CS
6810}
6811
6812DEFUN (ip_pim_ecmp_rebalance,
6813 ip_pim_ecmp_rebalance_cmd,
6814 "ip pim ecmp rebalance",
6815 IP_STR
6816 "pim multicast routing\n"
6817 "Enable PIM ECMP \n"
6818 "Enable PIM ECMP Rebalance\n")
6819{
4f9f3925 6820 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7
DS
6821 pim->ecmp_enable = true;
6822 pim->ecmp_rebalance_enable = true;
cba44481 6823
d62a17ae 6824 return CMD_SUCCESS;
cba44481
CS
6825}
6826
6827DEFUN (no_ip_pim_ecmp_rebalance,
6828 no_ip_pim_ecmp_rebalance_cmd,
6829 "no ip pim ecmp rebalance",
6830 NO_STR
6831 IP_STR
6832 "pim multicast routing\n"
6833 "Disable PIM ECMP \n"
6834 "Disable PIM ECMP Rebalance\n")
6835{
4f9f3925 6836 PIM_DECLVAR_CONTEXT(vrf, pim);
4795fff7 6837 pim->ecmp_rebalance_enable = false;
cba44481 6838
d62a17ae 6839 return CMD_SUCCESS;
cba44481
CS
6840}
6841
d62a17ae 6842static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
12e41d03 6843{
d62a17ae 6844 struct pim_interface *pim_ifp;
6845 uint8_t need_startup = 0;
12e41d03 6846
d62a17ae 6847 pim_ifp = ifp->info;
12e41d03 6848
d62a17ae 6849 if (!pim_ifp) {
11884868 6850 (void)pim_if_new(ifp, true, false, false, false);
d62a17ae 6851 need_startup = 1;
6852 } else {
6853 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
6854 PIM_IF_DO_IGMP(pim_ifp->options);
6855 need_startup = 1;
6856 }
6857 }
12e41d03 6858
d62a17ae 6859 /* 'ip igmp' executed multiple times, with need_startup
6860 avoid multiple if add all and membership refresh */
6861 if (need_startup) {
6862 pim_if_addr_add_all(ifp);
6863 pim_if_membership_refresh(ifp);
6864 }
12e41d03 6865
d62a17ae 6866 return CMD_SUCCESS;
12e41d03
DL
6867}
6868
21419f59
DS
6869DEFUN (interface_ip_igmp,
6870 interface_ip_igmp_cmd,
6871 "ip igmp",
6872 IP_STR
6873 IFACE_IGMP_STR)
6874{
d62a17ae 6875 VTY_DECLVAR_CONTEXT(interface, ifp);
21419f59 6876
d62a17ae 6877 return pim_cmd_igmp_start(vty, ifp);
21419f59
DS
6878}
6879
12e41d03
DL
6880DEFUN (interface_no_ip_igmp,
6881 interface_no_ip_igmp_cmd,
6882 "no ip igmp",
6883 NO_STR
6884 IP_STR
6885 IFACE_IGMP_STR)
6886{
d62a17ae 6887 VTY_DECLVAR_CONTEXT(interface, ifp);
6888 struct pim_interface *pim_ifp = ifp->info;
12e41d03 6889
d62a17ae 6890 if (!pim_ifp)
6891 return CMD_SUCCESS;
12e41d03 6892
d62a17ae 6893 PIM_IF_DONT_IGMP(pim_ifp->options);
12e41d03 6894
d62a17ae 6895 pim_if_membership_clear(ifp);
12e41d03 6896
d62a17ae 6897 pim_if_addr_del_all_igmp(ifp);
12e41d03 6898
d62a17ae 6899 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
6900 pim_if_delete(ifp);
6901 }
12e41d03 6902
d62a17ae 6903 return CMD_SUCCESS;
12e41d03
DL
6904}
6905
6906DEFUN (interface_ip_igmp_join,
6907 interface_ip_igmp_join_cmd,
771ce8ad 6908 "ip igmp join A.B.C.D [A.B.C.D]",
12e41d03
DL
6909 IP_STR
6910 IFACE_IGMP_STR
6911 "IGMP join multicast group\n"
6912 "Multicast group address\n"
6913 "Source address\n")
6914{
d62a17ae 6915 VTY_DECLVAR_CONTEXT(interface, ifp);
6916 int idx_ipv4 = 3;
6917 int idx_ipv4_2 = 4;
6918 const char *group_str;
6919 const char *source_str;
6920 struct in_addr group_addr;
6921 struct in_addr source_addr;
6922 int result;
6923
6924 /* Group address */
6925 group_str = argv[idx_ipv4]->arg;
6926 result = inet_pton(AF_INET, group_str, &group_addr);
6927 if (result <= 0) {
6928 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
6929 errno, safe_strerror(errno));
6930 return CMD_WARNING_CONFIG_FAILED;
6931 }
6932
6933 /* Source address */
771ce8ad
LM
6934 if (argc == (idx_ipv4_2 + 1)) {
6935 source_str = argv[idx_ipv4_2]->arg;
6936 result = inet_pton(AF_INET, source_str, &source_addr);
6937 if (result <= 0) {
6938 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
6939 source_str, errno, safe_strerror(errno));
6940 return CMD_WARNING_CONFIG_FAILED;
6941 }
6942 /* Reject 0.0.0.0. Reserved for any source. */
6943 if (source_addr.s_addr == INADDR_ANY) {
6944 vty_out(vty, "Bad source address %s\n", source_str);
6945 return CMD_WARNING_CONFIG_FAILED;
6946 }
6947 } else {
6948 source_addr.s_addr = INADDR_ANY;
d62a17ae 6949 }
6950
37664928
DS
6951 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp, group_addr, source_addr),
6952 "Failure joining IGMP group: $ERR");
d62a17ae 6953
6954 return CMD_SUCCESS;
12e41d03
DL
6955}
6956
6957DEFUN (interface_no_ip_igmp_join,
6958 interface_no_ip_igmp_join_cmd,
771ce8ad 6959 "no ip igmp join A.B.C.D [A.B.C.D]",
12e41d03
DL
6960 NO_STR
6961 IP_STR
6962 IFACE_IGMP_STR
6963 "IGMP join multicast group\n"
6964 "Multicast group address\n"
6965 "Source address\n")
6966{
d62a17ae 6967 VTY_DECLVAR_CONTEXT(interface, ifp);
6968 int idx_ipv4 = 4;
6969 int idx_ipv4_2 = 5;
6970 const char *group_str;
6971 const char *source_str;
6972 struct in_addr group_addr;
6973 struct in_addr source_addr;
6974 int result;
6975
6976 /* Group address */
6977 group_str = argv[idx_ipv4]->arg;
6978 result = inet_pton(AF_INET, group_str, &group_addr);
6979 if (result <= 0) {
6980 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
6981 errno, safe_strerror(errno));
6982 return CMD_WARNING_CONFIG_FAILED;
6983 }
6984
6985 /* Source address */
771ce8ad
LM
6986 if (argc == (idx_ipv4_2 + 1)) {
6987 source_str = argv[idx_ipv4_2]->arg;
6988 result = inet_pton(AF_INET, source_str, &source_addr);
6989 if (result <= 0) {
6990 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
6991 source_str, errno, safe_strerror(errno));
6992 return CMD_WARNING_CONFIG_FAILED;
6993 }
6994 /* Reject 0.0.0.0. Reserved for any source. */
6995 if (source_addr.s_addr == INADDR_ANY) {
6996 vty_out(vty, "Bad source address %s\n", source_str);
6997 return CMD_WARNING_CONFIG_FAILED;
6998 }
6999 } else {
7000 source_str = "*";
7001 source_addr.s_addr = INADDR_ANY;
d62a17ae 7002 }
7003
7004 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
7005 if (result) {
7006 vty_out(vty,
7007 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7008 group_str, source_str, ifp->name, result);
7009 return CMD_WARNING_CONFIG_FAILED;
7010 }
7011
7012 return CMD_SUCCESS;
12e41d03
DL
7013}
7014
7015/*
7016 CLI reconfiguration affects the interface level (struct pim_interface).
7017 This function propagates the reconfiguration to every active socket
7018 for that interface.
7019 */
7020static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
7021{
d62a17ae 7022 struct interface *ifp;
7023 struct pim_interface *pim_ifp;
12e41d03 7024
d62a17ae 7025 zassert(igmp);
12e41d03 7026
d62a17ae 7027 /* other querier present? */
12e41d03 7028
d62a17ae 7029 if (igmp->t_other_querier_timer)
7030 return;
12e41d03 7031
d62a17ae 7032 /* this is the querier */
12e41d03 7033
d62a17ae 7034 zassert(igmp->interface);
7035 zassert(igmp->interface->info);
12e41d03 7036
d62a17ae 7037 ifp = igmp->interface;
7038 pim_ifp = ifp->info;
12e41d03 7039
d62a17ae 7040 if (PIM_DEBUG_IGMP_TRACE) {
7041 char ifaddr_str[INET_ADDRSTRLEN];
7042 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
7043 sizeof(ifaddr_str));
7044 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7045 __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
7046 pim_ifp->igmp_default_query_interval);
7047 }
12e41d03 7048
d62a17ae 7049 /*
7050 igmp_startup_mode_on() will reset QQI:
12e41d03 7051
d62a17ae 7052 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7053 */
7054 igmp_startup_mode_on(igmp);
12e41d03
DL
7055}
7056
7057static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
7058{
d62a17ae 7059 if (igmp->t_igmp_query_timer) {
7060 /* other querier present */
7061 zassert(igmp->t_igmp_query_timer);
7062 zassert(!igmp->t_other_querier_timer);
12e41d03 7063
d62a17ae 7064 pim_igmp_general_query_off(igmp);
7065 pim_igmp_general_query_on(igmp);
12e41d03 7066
d62a17ae 7067 zassert(igmp->t_igmp_query_timer);
7068 zassert(!igmp->t_other_querier_timer);
7069 } else {
7070 /* this is the querier */
12e41d03 7071
d62a17ae 7072 zassert(!igmp->t_igmp_query_timer);
7073 zassert(igmp->t_other_querier_timer);
12e41d03 7074
d62a17ae 7075 pim_igmp_other_querier_timer_off(igmp);
7076 pim_igmp_other_querier_timer_on(igmp);
12e41d03 7077
d62a17ae 7078 zassert(!igmp->t_igmp_query_timer);
7079 zassert(igmp->t_other_querier_timer);
7080 }
12e41d03
DL
7081}
7082
7083static void change_query_interval(struct pim_interface *pim_ifp,
7084 int query_interval)
7085{
d62a17ae 7086 struct listnode *sock_node;
7087 struct igmp_sock *igmp;
12e41d03 7088
d62a17ae 7089 pim_ifp->igmp_default_query_interval = query_interval;
12e41d03 7090
d62a17ae 7091 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7092 igmp_sock_query_interval_reconfig(igmp);
7093 igmp_sock_query_reschedule(igmp);
7094 }
12e41d03
DL
7095}
7096
7097static void change_query_max_response_time(struct pim_interface *pim_ifp,
7098 int query_max_response_time_dsec)
7099{
d62a17ae 7100 struct listnode *sock_node;
7101 struct igmp_sock *igmp;
7102
7103 pim_ifp->igmp_query_max_response_time_dsec =
7104 query_max_response_time_dsec;
7105
7106 /*
7107 Below we modify socket/group/source timers in order to quickly
7108 reflect the change. Otherwise, those timers would eventually catch
7109 up.
7110 */
7111
7112 /* scan all sockets */
7113 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7114 struct listnode *grp_node;
7115 struct igmp_group *grp;
7116
7117 /* reschedule socket general query */
7118 igmp_sock_query_reschedule(igmp);
7119
7120 /* scan socket groups */
7121 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
7122 grp)) {
7123 struct listnode *src_node;
7124 struct igmp_source *src;
7125
7126 /* reset group timers for groups in EXCLUDE mode */
7127 if (grp->group_filtermode_isexcl) {
7128 igmp_group_reset_gmi(grp);
7129 }
7130
7131 /* scan group sources */
7132 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
7133 src_node, src)) {
7134
7135 /* reset source timers for sources with running
7136 * timers */
7137 if (src->t_source_timer) {
7138 igmp_source_reset_gmi(igmp, grp, src);
7139 }
7140 }
7141 }
12e41d03 7142 }
12e41d03
DL
7143}
7144
7145#define IGMP_QUERY_INTERVAL_MIN (1)
7146#define IGMP_QUERY_INTERVAL_MAX (1800)
7147
7148DEFUN (interface_ip_igmp_query_interval,
7149 interface_ip_igmp_query_interval_cmd,
9ccf14f7 7150 "ip igmp query-interval (1-1800)",
12e41d03
DL
7151 IP_STR
7152 IFACE_IGMP_STR
7153 IFACE_IGMP_QUERY_INTERVAL_STR
7154 "Query interval in seconds\n")
7155{
d62a17ae 7156 VTY_DECLVAR_CONTEXT(interface, ifp);
7157 struct pim_interface *pim_ifp = ifp->info;
7158 int query_interval;
7159 int query_interval_dsec;
7160 int ret;
7161
7162 if (!pim_ifp) {
7163 ret = pim_cmd_igmp_start(vty, ifp);
7164 if (ret != CMD_SUCCESS)
7165 return ret;
7166 pim_ifp = ifp->info;
7167 }
7168
7169 query_interval = atoi(argv[3]->arg);
7170 query_interval_dsec = 10 * query_interval;
7171
7172 /*
7173 It seems we don't need to check bounds since command.c does it
7174 already, but we verify them anyway for extra safety.
7175 */
7176 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
7177 vty_out(vty,
7178 "General query interval %d lower than minimum %d\n",
7179 query_interval, IGMP_QUERY_INTERVAL_MIN);
7180 return CMD_WARNING_CONFIG_FAILED;
7181 }
7182 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
7183 vty_out(vty,
7184 "General query interval %d higher than maximum %d\n",
7185 query_interval, IGMP_QUERY_INTERVAL_MAX);
7186 return CMD_WARNING_CONFIG_FAILED;
7187 }
7188
7189 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
7190 vty_out(vty,
7191 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7192 query_interval_dsec,
7193 pim_ifp->igmp_query_max_response_time_dsec);
7194 return CMD_WARNING_CONFIG_FAILED;
7195 }
7196
7197 change_query_interval(pim_ifp, query_interval);
7198
7199 return CMD_SUCCESS;
12e41d03
DL
7200}
7201
7202DEFUN (interface_no_ip_igmp_query_interval,
7203 interface_no_ip_igmp_query_interval_cmd,
9ccf14f7 7204 "no ip igmp query-interval",
12e41d03
DL
7205 NO_STR
7206 IP_STR
7207 IFACE_IGMP_STR
7208 IFACE_IGMP_QUERY_INTERVAL_STR)
7209{
d62a17ae 7210 VTY_DECLVAR_CONTEXT(interface, ifp);
7211 struct pim_interface *pim_ifp = ifp->info;
7212 int default_query_interval_dsec;
12e41d03 7213
d62a17ae 7214 if (!pim_ifp)
7215 return CMD_SUCCESS;
12e41d03 7216
d62a17ae 7217 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
12e41d03 7218
d62a17ae 7219 if (default_query_interval_dsec
7220 <= pim_ifp->igmp_query_max_response_time_dsec) {
7221 vty_out(vty,
7222 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7223 default_query_interval_dsec,
7224 pim_ifp->igmp_query_max_response_time_dsec);
7225 return CMD_WARNING_CONFIG_FAILED;
7226 }
12e41d03 7227
d62a17ae 7228 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
12e41d03 7229
d62a17ae 7230 return CMD_SUCCESS;
12e41d03
DL
7231}
7232
b05b72e8
DW
7233DEFUN (interface_ip_igmp_version,
7234 interface_ip_igmp_version_cmd,
72e81cf4 7235 "ip igmp version (2-3)",
b05b72e8
DW
7236 IP_STR
7237 IFACE_IGMP_STR
7238 "IGMP version\n"
7239 "IGMP version number\n")
7240{
d62a17ae 7241 VTY_DECLVAR_CONTEXT(interface, ifp);
7242 struct pim_interface *pim_ifp = ifp->info;
7243 int igmp_version, old_version = 0;
7244 int ret;
7245
7246 if (!pim_ifp) {
7247 ret = pim_cmd_igmp_start(vty, ifp);
7248 if (ret != CMD_SUCCESS)
7249 return ret;
7250 pim_ifp = ifp->info;
7251 }
7252
7253 igmp_version = atoi(argv[3]->arg);
7254 old_version = pim_ifp->igmp_version;
7255 pim_ifp->igmp_version = igmp_version;
7256
7257 // Check if IGMP is Enabled otherwise, enable on interface
7258 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7259 PIM_IF_DO_IGMP(pim_ifp->options);
7260 pim_if_addr_add_all(ifp);
7261 pim_if_membership_refresh(ifp);
3a6351a3
LB
7262 old_version = igmp_version;
7263 // avoid refreshing membership again.
d62a17ae 7264 }
7265 /* Current and new version is different refresh existing
7266 membership. Going from 3 -> 2 or 2 -> 3. */
7267 if (old_version != igmp_version)
7268 pim_if_membership_refresh(ifp);
7269
7270 return CMD_SUCCESS;
b05b72e8
DW
7271}
7272
7273DEFUN (interface_no_ip_igmp_version,
7274 interface_no_ip_igmp_version_cmd,
72e81cf4 7275 "no ip igmp version (2-3)",
b05b72e8
DW
7276 NO_STR
7277 IP_STR
7278 IFACE_IGMP_STR
7279 "IGMP version\n"
7280 "IGMP version number\n")
7281{
d62a17ae 7282 VTY_DECLVAR_CONTEXT(interface, ifp);
7283 struct pim_interface *pim_ifp = ifp->info;
b05b72e8 7284
d62a17ae 7285 if (!pim_ifp)
7286 return CMD_SUCCESS;
b05b72e8 7287
d62a17ae 7288 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
b05b72e8 7289
d62a17ae 7290 return CMD_SUCCESS;
b05b72e8
DW
7291}
7292
58344b65
DS
7293#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7294#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
12e41d03
DL
7295
7296DEFUN (interface_ip_igmp_query_max_response_time,
7297 interface_ip_igmp_query_max_response_time_cmd,
58344b65 7298 "ip igmp query-max-response-time (10-250)",
12e41d03
DL
7299 IP_STR
7300 IFACE_IGMP_STR
7301 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
58344b65 7302 "Query response value in deci-seconds\n")
12e41d03 7303{
d62a17ae 7304 VTY_DECLVAR_CONTEXT(interface, ifp);
7305 struct pim_interface *pim_ifp = ifp->info;
7306 int query_max_response_time;
7307 int ret;
12e41d03 7308
d62a17ae 7309 if (!pim_ifp) {
7310 ret = pim_cmd_igmp_start(vty, ifp);
7311 if (ret != CMD_SUCCESS)
7312 return ret;
7313 pim_ifp = ifp->info;
7314 }
12e41d03 7315
d62a17ae 7316 query_max_response_time = atoi(argv[3]->arg);
12e41d03 7317
d62a17ae 7318 if (query_max_response_time
7319 >= pim_ifp->igmp_default_query_interval * 10) {
7320 vty_out(vty,
7321 "Can't set query max response time %d sec >= general query interval %d sec\n",
7322 query_max_response_time,
7323 pim_ifp->igmp_default_query_interval);
7324 return CMD_WARNING_CONFIG_FAILED;
7325 }
12e41d03 7326
d62a17ae 7327 change_query_max_response_time(pim_ifp, query_max_response_time);
12e41d03 7328
d62a17ae 7329 return CMD_SUCCESS;
12e41d03
DL
7330}
7331
7332DEFUN (interface_no_ip_igmp_query_max_response_time,
7333 interface_no_ip_igmp_query_max_response_time_cmd,
72e81cf4 7334 "no ip igmp query-max-response-time (10-250)",
12e41d03
DL
7335 NO_STR
7336 IP_STR
7337 IFACE_IGMP_STR
a957a05b
DS
7338 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7339 "Time for response in deci-seconds\n")
12e41d03 7340{
d62a17ae 7341 VTY_DECLVAR_CONTEXT(interface, ifp);
7342 struct pim_interface *pim_ifp = ifp->info;
12e41d03 7343
d62a17ae 7344 if (!pim_ifp)
7345 return CMD_SUCCESS;
12e41d03 7346
d62a17ae 7347 change_query_max_response_time(pim_ifp,
7348 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
12e41d03 7349
d62a17ae 7350 return CMD_SUCCESS;
12e41d03
DL
7351}
7352
7353#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7354#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7355
58344b65
DS
7356DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
7357 interface_ip_igmp_query_max_response_time_dsec_cmd,
7358 "ip igmp query-max-response-time-dsec (10-250)",
7359 IP_STR
7360 IFACE_IGMP_STR
7361 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7362 "Query response value in deciseconds\n")
12e41d03 7363{
d62a17ae 7364 VTY_DECLVAR_CONTEXT(interface, ifp);
7365 struct pim_interface *pim_ifp = ifp->info;
7366 int query_max_response_time_dsec;
7367 int default_query_interval_dsec;
7368 int ret;
7369
7370 if (!pim_ifp) {
7371 ret = pim_cmd_igmp_start(vty, ifp);
7372 if (ret != CMD_SUCCESS)
7373 return ret;
7374 pim_ifp = ifp->info;
7375 }
12e41d03 7376
d62a17ae 7377 query_max_response_time_dsec = atoi(argv[4]->arg);
12e41d03 7378
d62a17ae 7379 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
12e41d03 7380
d62a17ae 7381 if (query_max_response_time_dsec >= default_query_interval_dsec) {
7382 vty_out(vty,
7383 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7384 query_max_response_time_dsec,
7385 default_query_interval_dsec);
7386 return CMD_WARNING_CONFIG_FAILED;
7387 }
12e41d03 7388
d62a17ae 7389 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
12e41d03 7390
d62a17ae 7391 return CMD_SUCCESS;
12e41d03
DL
7392}
7393
58344b65
DS
7394DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
7395 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
7396 "no ip igmp query-max-response-time-dsec",
7397 NO_STR
7398 IP_STR
7399 IFACE_IGMP_STR
7400 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
12e41d03 7401{
d62a17ae 7402 VTY_DECLVAR_CONTEXT(interface, ifp);
7403 struct pim_interface *pim_ifp = ifp->info;
12e41d03 7404
d62a17ae 7405 if (!pim_ifp)
7406 return CMD_SUCCESS;
12e41d03 7407
d62a17ae 7408 change_query_max_response_time(pim_ifp,
7409 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
12e41d03 7410
d62a17ae 7411 return CMD_SUCCESS;
12e41d03
DL
7412}
7413
59115451
SP
7414#define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7415#define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7416
7417DEFUN (interface_ip_igmp_last_member_query_count,
7418 interface_ip_igmp_last_member_query_count_cmd,
7419 "ip igmp last-member-query-count (1-7)",
7420 IP_STR
7421 IFACE_IGMP_STR
7422 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7423 "Last member query count\n")
7424{
7425 VTY_DECLVAR_CONTEXT(interface, ifp);
7426 struct pim_interface *pim_ifp = ifp->info;
7427 int last_member_query_count;
7428 int ret;
7429
7430 if (!pim_ifp) {
7431 ret = pim_cmd_igmp_start(vty, ifp);
7432 if (ret != CMD_SUCCESS)
7433 return ret;
7434 pim_ifp = ifp->info;
7435 }
7436
7437 last_member_query_count = atoi(argv[3]->arg);
7438
7439 pim_ifp->igmp_last_member_query_count = last_member_query_count;
7440
7441 return CMD_SUCCESS;
7442}
7443
7444DEFUN (interface_no_ip_igmp_last_member_query_count,
7445 interface_no_ip_igmp_last_member_query_count_cmd,
7446 "no ip igmp last-member-query-count",
7447 NO_STR
7448 IP_STR
7449 IFACE_IGMP_STR
7450 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR)
7451{
7452 VTY_DECLVAR_CONTEXT(interface, ifp);
7453 struct pim_interface *pim_ifp = ifp->info;
7454
7455 if (!pim_ifp)
7456 return CMD_SUCCESS;
7457
7458 pim_ifp->igmp_last_member_query_count =
7459 IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
7460
7461 return CMD_SUCCESS;
7462}
7463
7464#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7465#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7466
7467DEFUN (interface_ip_igmp_last_member_query_interval,
7468 interface_ip_igmp_last_member_query_interval_cmd,
7469 "ip igmp last-member-query-interval (1-255)",
7470 IP_STR
7471 IFACE_IGMP_STR
7472 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7473 "Last member query interval in deciseconds\n")
7474{
7475 VTY_DECLVAR_CONTEXT(interface, ifp);
7476 struct pim_interface *pim_ifp = ifp->info;
7477 int last_member_query_interval;
7478 int ret;
7479
7480 if (!pim_ifp) {
7481 ret = pim_cmd_igmp_start(vty, ifp);
7482 if (ret != CMD_SUCCESS)
7483 return ret;
7484 pim_ifp = ifp->info;
7485 }
7486
7487 last_member_query_interval = atoi(argv[3]->arg);
7488 pim_ifp->igmp_specific_query_max_response_time_dsec
7489 = last_member_query_interval;
7490
7491 return CMD_SUCCESS;
7492}
7493
7494DEFUN (interface_no_ip_igmp_last_member_query_interval,
7495 interface_no_ip_igmp_last_member_query_interval_cmd,
7496 "no ip igmp last-member-query-interval",
7497 NO_STR
7498 IP_STR
7499 IFACE_IGMP_STR
7500 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR)
7501{
7502 VTY_DECLVAR_CONTEXT(interface, ifp);
7503 struct pim_interface *pim_ifp = ifp->info;
7504
7505 if (!pim_ifp)
7506 return CMD_SUCCESS;
7507
7508 pim_ifp->igmp_specific_query_max_response_time_dsec =
7509 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
7510
7511 return CMD_SUCCESS;
7512}
7513
dedccda6
DS
7514DEFUN (interface_ip_pim_drprio,
7515 interface_ip_pim_drprio_cmd,
b181fa04 7516 "ip pim drpriority (1-4294967295)",
dedccda6
DS
7517 IP_STR
7518 PIM_STR
7519 "Set the Designated Router Election Priority\n"
7520 "Value of the new DR Priority\n")
7521{
d62a17ae 7522 VTY_DECLVAR_CONTEXT(interface, ifp);
7523 int idx_number = 3;
7524 struct pim_interface *pim_ifp = ifp->info;
7525 uint32_t old_dr_prio;
dedccda6 7526
d62a17ae 7527 if (!pim_ifp) {
7528 vty_out(vty, "Please enable PIM on interface, first\n");
7529 return CMD_WARNING_CONFIG_FAILED;
7530 }
dedccda6 7531
d62a17ae 7532 old_dr_prio = pim_ifp->pim_dr_priority;
dedccda6 7533
d62a17ae 7534 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
dedccda6 7535
d62a17ae 7536 if (old_dr_prio != pim_ifp->pim_dr_priority) {
3de70812
DS
7537 pim_if_dr_election(ifp);
7538 pim_hello_restart_now(ifp);
d62a17ae 7539 }
dedccda6 7540
d62a17ae 7541 return CMD_SUCCESS;
dedccda6
DS
7542}
7543
7544DEFUN (interface_no_ip_pim_drprio,
7545 interface_no_ip_pim_drprio_cmd,
b181fa04 7546 "no ip pim drpriority [(1-4294967295)]",
d7fa34c1 7547 NO_STR
dedccda6
DS
7548 IP_STR
7549 PIM_STR
7550 "Revert the Designated Router Priority to default\n"
7551 "Old Value of the Priority\n")
7552{
d62a17ae 7553 VTY_DECLVAR_CONTEXT(interface, ifp);
7554 struct pim_interface *pim_ifp = ifp->info;
dedccda6 7555
d62a17ae 7556 if (!pim_ifp) {
7557 vty_out(vty, "Pim not enabled on this interface\n");
7558 return CMD_WARNING_CONFIG_FAILED;
7559 }
dedccda6 7560
d62a17ae 7561 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
7562 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
3de70812
DS
7563 pim_if_dr_election(ifp);
7564 pim_hello_restart_now(ifp);
d62a17ae 7565 }
dedccda6 7566
d62a17ae 7567 return CMD_SUCCESS;
dedccda6
DS
7568}
7569
6741a5bb 7570DEFPY_HIDDEN (interface_ip_igmp_query_generate,
7571 interface_ip_igmp_query_generate_cmd,
7572 "ip igmp generate-query-once [version (2-3)]",
7573 IP_STR
7574 IFACE_IGMP_STR
7575 "Generate igmp general query once\n"
7576 "IGMP version\n"
7577 "IGMP version number\n")
7578{
7579 VTY_DECLVAR_CONTEXT(interface, ifp);
7580 int igmp_version = 2;
7581
7582 if (!ifp->info) {
7583 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
7584 ifp->name);
7585 return CMD_WARNING_CONFIG_FAILED;
7586 }
7587
7588 if (argc > 3)
7589 igmp_version = atoi(argv[4]->arg);
7590
7591 igmp_send_query_on_intf(ifp, igmp_version);
7592
7593 return CMD_SUCCESS;
7594}
7595
d62a17ae 7596static int pim_cmd_interface_add(struct interface *ifp)
12e41d03 7597{
d62a17ae 7598 struct pim_interface *pim_ifp = ifp->info;
12e41d03 7599
11884868 7600 if (!pim_ifp)
0f39cb4c 7601 pim_ifp = pim_if_new(ifp, false, true, false, false);
11884868 7602 else
d62a17ae 7603 PIM_IF_DO_PIM(pim_ifp->options);
12e41d03 7604
d62a17ae 7605 pim_if_addr_add_all(ifp);
7606 pim_if_membership_refresh(ifp);
0f39cb4c
DS
7607
7608 pim_if_create_pimreg(pim_ifp->pim);
d62a17ae 7609 return 1;
981d6c7a
DS
7610}
7611
70fd22bd
DS
7612DEFPY_HIDDEN (pim_test_sg_keepalive,
7613 pim_test_sg_keepalive_cmd,
7614 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7615 "Test code\n"
7616 PIM_STR
7617 VRF_CMD_HELP_STR
7618 "Reset the Keepalive Timer\n"
7619 "The Source we are resetting\n"
7620 "The Group we are resetting\n")
7621{
7622 struct pim_upstream *up;
7623 struct pim_instance *pim;
7624 struct prefix_sg sg;
7625
7626 sg.src = source;
7627 sg.grp = group;
7628
7629 if (!name)
7630 pim = pim_get_pim_instance(VRF_DEFAULT);
7631 else {
7632 struct vrf *vrf = vrf_lookup_by_name(name);
7633
7634 if (!vrf) {
7635 vty_out(vty, "%% Vrf specified: %s does not exist\n",
7636 name);
7637 return CMD_WARNING;
7638 }
7639
7640 pim = pim_get_pim_instance(vrf->vrf_id);
7641 }
7642
7643 if (!pim) {
7644 vty_out(vty, "%% Unable to find pim instance\n");
7645 return CMD_WARNING;
7646 }
7647
7648 up = pim_upstream_find(pim, &sg);
7649 if (!up) {
7650 vty_out(vty, "%% Unable to find %s specified\n",
7651 pim_str_sg_dump(&sg));
7652 return CMD_WARNING;
7653 }
7654
7655 vty_out(vty, "Setting %s to current keep alive time: %d\n",
7656 pim_str_sg_dump(&sg), pim->keep_alive_time);
7657 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
7658
7659 return CMD_SUCCESS;
7660}
7661
414d885a
DS
7662DEFPY_HIDDEN (interface_ip_pim_activeactive,
7663 interface_ip_pim_activeactive_cmd,
7664 "[no$no] ip pim active-active",
7665 NO_STR
7666 IP_STR
7667 PIM_STR
7668 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7669{
7670 VTY_DECLVAR_CONTEXT(interface, ifp);
7671 struct pim_interface *pim_ifp;
7672
7673 if (!no && !pim_cmd_interface_add(ifp)) {
7674 vty_out(vty, "Could not enable PIM SM active-active on interface\n");
7675 return CMD_WARNING_CONFIG_FAILED;
7676 }
7677
7678 pim_ifp = ifp->info;
7679 if (no)
36b5b98f 7680 pim_if_unconfigure_mlag_dualactive(pim_ifp);
414d885a 7681 else
36b5b98f 7682 pim_if_configure_mlag_dualactive(pim_ifp);
414d885a
DS
7683
7684 return CMD_SUCCESS;
7685}
7686
d2772e7b 7687DEFUN_HIDDEN (interface_ip_pim_ssm,
981d6c7a
DS
7688 interface_ip_pim_ssm_cmd,
7689 "ip pim ssm",
7690 IP_STR
7691 PIM_STR
7692 IFACE_PIM_STR)
7693{
d62a17ae 7694 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a 7695
d62a17ae 7696 if (!pim_cmd_interface_add(ifp)) {
7697 vty_out(vty, "Could not enable PIM SM on interface\n");
7698 return CMD_WARNING_CONFIG_FAILED;
7699 }
981d6c7a 7700
d62a17ae 7701 vty_out(vty,
7702 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7703 "range if needed\n");
7704 return CMD_SUCCESS;
12e41d03
DL
7705}
7706
2f5e937c 7707static int interface_ip_pim_helper(struct vty *vty)
12e41d03 7708{
43e40fdf
DS
7709 struct pim_interface *pim_ifp;
7710
d62a17ae 7711 VTY_DECLVAR_CONTEXT(interface, ifp);
2f5e937c 7712
d62a17ae 7713 if (!pim_cmd_interface_add(ifp)) {
7714 vty_out(vty, "Could not enable PIM SM on interface\n");
7715 return CMD_WARNING_CONFIG_FAILED;
7716 }
981d6c7a 7717
43e40fdf 7718 pim_ifp = ifp->info;
ecca97ac 7719
43e40fdf 7720 pim_if_create_pimreg(pim_ifp->pim);
c992c9a0 7721
d62a17ae 7722 return CMD_SUCCESS;
981d6c7a
DS
7723}
7724
2f5e937c 7725DEFUN_HIDDEN (interface_ip_pim_sm,
7726 interface_ip_pim_sm_cmd,
7727 "ip pim sm",
7728 IP_STR
7729 PIM_STR
7730 IFACE_PIM_SM_STR)
7731{
7732 return interface_ip_pim_helper(vty);
7733}
7734
7735DEFUN (interface_ip_pim,
7736 interface_ip_pim_cmd,
7737 "ip pim",
7738 IP_STR
7739 PIM_STR)
7740{
7741 return interface_ip_pim_helper(vty);
7742}
7743
d62a17ae 7744static int pim_cmd_interface_delete(struct interface *ifp)
981d6c7a 7745{
d62a17ae 7746 struct pim_interface *pim_ifp = ifp->info;
981d6c7a 7747
d62a17ae 7748 if (!pim_ifp)
7749 return 1;
12e41d03 7750
d62a17ae 7751 PIM_IF_DONT_PIM(pim_ifp->options);
12e41d03 7752
d62a17ae 7753 pim_if_membership_clear(ifp);
12e41d03 7754
d62a17ae 7755 /*
7756 pim_sock_delete() removes all neighbors from
7757 pim_ifp->pim_neighbor_list.
7758 */
7759 pim_sock_delete(ifp, "pim unconfigured on interface");
12e41d03 7760
d62a17ae 7761 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7762 pim_if_addr_del_all(ifp);
7763 pim_if_delete(ifp);
7764 }
12e41d03 7765
d62a17ae 7766 return 1;
981d6c7a
DS
7767}
7768
2f5e937c 7769static int interface_no_ip_pim_helper(struct vty *vty)
7770{
eccdcfe2
SP
7771 VTY_DECLVAR_CONTEXT(interface, ifp);
7772 if (!pim_cmd_interface_delete(ifp)) {
7773 vty_out(vty, "Unable to delete interface information\n");
7774 return CMD_WARNING_CONFIG_FAILED;
7775 }
2f5e937c 7776
eccdcfe2 7777 return CMD_SUCCESS;
2f5e937c 7778}
7779
d2772e7b 7780DEFUN_HIDDEN (interface_no_ip_pim_ssm,
981d6c7a
DS
7781 interface_no_ip_pim_ssm_cmd,
7782 "no ip pim ssm",
7783 NO_STR
7784 IP_STR
7785 PIM_STR
7786 IFACE_PIM_STR)
7787{
2f5e937c 7788 return interface_no_ip_pim_helper(vty);
981d6c7a
DS
7789}
7790
2f5e937c 7791DEFUN_HIDDEN (interface_no_ip_pim_sm,
981d6c7a
DS
7792 interface_no_ip_pim_sm_cmd,
7793 "no ip pim sm",
7794 NO_STR
7795 IP_STR
7796 PIM_STR
8371bd60 7797 IFACE_PIM_SM_STR)
981d6c7a 7798{
2f5e937c 7799 return interface_no_ip_pim_helper(vty);
7800}
981d6c7a 7801
2f5e937c 7802DEFUN (interface_no_ip_pim,
7803 interface_no_ip_pim_cmd,
7804 "no ip pim",
7805 NO_STR
7806 IP_STR
7807 PIM_STR)
7808{
7809 return interface_no_ip_pim_helper(vty);
12e41d03
DL
7810}
7811
b0f525a8
QY
7812/* boundaries */
7813DEFUN(interface_ip_pim_boundary_oil,
7814 interface_ip_pim_boundary_oil_cmd,
7815 "ip multicast boundary oil WORD",
7816 IP_STR
7817 "Generic multicast configuration options\n"
7818 "Define multicast boundary\n"
7819 "Filter OIL by group using prefix list\n"
513c8462 7820 "Prefix list to filter OIL with\n")
b0f525a8
QY
7821{
7822 VTY_DECLVAR_CONTEXT(interface, iif);
7823 struct pim_interface *pim_ifp;
7824 int idx = 0;
7825
7826 argv_find(argv, argc, "WORD", &idx);
7827
7828 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7829
7830 if (pim_ifp->boundary_oil_plist)
7831 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7832
7833 pim_ifp->boundary_oil_plist =
7834 XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
7835
7836 /* Interface will be pruned from OIL on next Join */
7837 return CMD_SUCCESS;
7838}
7839
7840DEFUN(interface_no_ip_pim_boundary_oil,
7841 interface_no_ip_pim_boundary_oil_cmd,
7842 "no ip multicast boundary oil [WORD]",
7843 NO_STR
7844 IP_STR
7845 "Generic multicast configuration options\n"
7846 "Define multicast boundary\n"
7847 "Filter OIL by group using prefix list\n"
513c8462 7848 "Prefix list to filter OIL with\n")
b0f525a8
QY
7849{
7850 VTY_DECLVAR_CONTEXT(interface, iif);
7851 struct pim_interface *pim_ifp;
be1d57fc 7852 int idx = 0;
b0f525a8
QY
7853
7854 argv_find(argv, argc, "WORD", &idx);
7855
7856 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7857
7858 if (pim_ifp->boundary_oil_plist)
7859 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7860
7861 return CMD_SUCCESS;
7862}
7863
6250610a
JAG
7864DEFUN (interface_ip_mroute,
7865 interface_ip_mroute_cmd,
e57cc5f0 7866 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
6250610a
JAG
7867 IP_STR
7868 "Add multicast route\n"
7869 "Outgoing interface name\n"
7870 "Group address\n"
7871 "Source address\n")
7872{
d62a17ae 7873 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
7874 struct pim_interface *pim_ifp;
7875 struct pim_instance *pim;
d62a17ae 7876 int idx_interface = 2;
7877 int idx_ipv4 = 3;
d62a17ae 7878 struct interface *oif;
7879 const char *oifname;
7880 const char *grp_str;
7881 struct in_addr grp_addr;
7882 const char *src_str;
7883 struct in_addr src_addr;
7884 int result;
7885
21b3e44e 7886 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
4e0bc0f0
DS
7887 pim = pim_ifp->pim;
7888
d62a17ae 7889 oifname = argv[idx_interface]->arg;
a36898e7 7890 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 7891 if (!oif) {
7892 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 7893 return CMD_WARNING;
d62a17ae 7894 }
7895
7896 grp_str = argv[idx_ipv4]->arg;
7897 result = inet_pton(AF_INET, grp_str, &grp_addr);
7898 if (result <= 0) {
7899 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7900 errno, safe_strerror(errno));
4e0bc0f0 7901 return CMD_WARNING;
d62a17ae 7902 }
7903
e57cc5f0
JAG
7904 if (argc == (idx_ipv4 + 1)) {
7905 src_addr.s_addr = INADDR_ANY;
7906 }
7907 else {
7908 src_str = argv[idx_ipv4 + 1]->arg;
7909 result = inet_pton(AF_INET, src_str, &src_addr);
7910 if (result <= 0) {
7911 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
7912 errno, safe_strerror(errno));
7913 return CMD_WARNING;
7914 }
7915 }
d62a17ae 7916
4e0bc0f0 7917 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
e57cc5f0 7918 vty_out(vty, "Failed to add static mroute\n");
4e0bc0f0 7919 return CMD_WARNING;
d62a17ae 7920 }
7921
7922 return CMD_SUCCESS;
6250610a
JAG
7923}
7924
7925DEFUN (interface_no_ip_mroute,
7926 interface_no_ip_mroute_cmd,
e57cc5f0 7927 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
6250610a
JAG
7928 NO_STR
7929 IP_STR
7930 "Add multicast route\n"
7931 "Outgoing interface name\n"
7932 "Group Address\n"
7933 "Source Address\n")
7934{
d62a17ae 7935 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
7936 struct pim_interface *pim_ifp;
7937 struct pim_instance *pim;
d62a17ae 7938 int idx_interface = 3;
7939 int idx_ipv4 = 4;
d62a17ae 7940 struct interface *oif;
7941 const char *oifname;
7942 const char *grp_str;
7943 struct in_addr grp_addr;
7944 const char *src_str;
7945 struct in_addr src_addr;
7946 int result;
7947
21b3e44e 7948 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
4e0bc0f0
DS
7949 pim = pim_ifp->pim;
7950
d62a17ae 7951 oifname = argv[idx_interface]->arg;
a36898e7 7952 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 7953 if (!oif) {
7954 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 7955 return CMD_WARNING;
d62a17ae 7956 }
7957
7958 grp_str = argv[idx_ipv4]->arg;
7959 result = inet_pton(AF_INET, grp_str, &grp_addr);
7960 if (result <= 0) {
7961 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7962 errno, safe_strerror(errno));
4e0bc0f0 7963 return CMD_WARNING;
d62a17ae 7964 }
7965
e57cc5f0
JAG
7966 if (argc == (idx_ipv4 + 1)) {
7967 src_addr.s_addr = INADDR_ANY;
7968 }
7969 else {
7970 src_str = argv[idx_ipv4 + 1]->arg;
7971 result = inet_pton(AF_INET, src_str, &src_addr);
7972 if (result <= 0) {
7973 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
7974 errno, safe_strerror(errno));
7975 return CMD_WARNING;
7976 }
7977 }
d62a17ae 7978
4e0bc0f0 7979 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
e57cc5f0 7980 vty_out(vty, "Failed to remove static mroute\n");
4e0bc0f0 7981 return CMD_WARNING;
d62a17ae 7982 }
7983
7984 return CMD_SUCCESS;
6250610a
JAG
7985}
7986
7960fa8f
DS
7987DEFUN (interface_ip_pim_hello,
7988 interface_ip_pim_hello_cmd,
80d3d26b 7989 "ip pim hello (1-180) [(1-180)]",
7960fa8f
DS
7990 IP_STR
7991 PIM_STR
7992 IFACE_PIM_HELLO_STR
80d3d26b
DW
7993 IFACE_PIM_HELLO_TIME_STR
7994 IFACE_PIM_HELLO_HOLD_STR)
7960fa8f 7995{
d62a17ae 7996 VTY_DECLVAR_CONTEXT(interface, ifp);
7997 int idx_time = 3;
7998 int idx_hold = 4;
7999 struct pim_interface *pim_ifp = ifp->info;
7960fa8f 8000
d62a17ae 8001 if (!pim_ifp) {
8002 if (!pim_cmd_interface_add(ifp)) {
8003 vty_out(vty, "Could not enable PIM SM on interface\n");
8004 return CMD_WARNING_CONFIG_FAILED;
8005 }
8006 }
7960fa8f 8007
d62a17ae 8008 pim_ifp = ifp->info;
8009 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
7960fa8f 8010
d62a17ae 8011 if (argc == idx_hold + 1)
8012 pim_ifp->pim_default_holdtime =
8013 strtol(argv[idx_hold]->arg, NULL, 10);
7960fa8f 8014
d62a17ae 8015 return CMD_SUCCESS;
7960fa8f
DS
8016}
8017
7960fa8f
DS
8018DEFUN (interface_no_ip_pim_hello,
8019 interface_no_ip_pim_hello_cmd,
b181fa04 8020 "no ip pim hello [(1-180) (1-180)]",
7960fa8f
DS
8021 NO_STR
8022 IP_STR
8023 PIM_STR
8024 IFACE_PIM_HELLO_STR
8025 IFACE_PIM_HELLO_TIME_STR
8026 IFACE_PIM_HELLO_HOLD_STR)
8027{
d62a17ae 8028 VTY_DECLVAR_CONTEXT(interface, ifp);
8029 struct pim_interface *pim_ifp = ifp->info;
7960fa8f 8030
d62a17ae 8031 if (!pim_ifp) {
8032 vty_out(vty, "Pim not enabled on this interface\n");
8033 return CMD_WARNING_CONFIG_FAILED;
8034 }
7960fa8f 8035
d62a17ae 8036 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
8037 pim_ifp->pim_default_holdtime = -1;
7960fa8f 8038
d62a17ae 8039 return CMD_SUCCESS;
7960fa8f
DS
8040}
8041
12e41d03
DL
8042DEFUN (debug_igmp,
8043 debug_igmp_cmd,
8044 "debug igmp",
8045 DEBUG_STR
8046 DEBUG_IGMP_STR)
8047{
d62a17ae 8048 PIM_DO_DEBUG_IGMP_EVENTS;
8049 PIM_DO_DEBUG_IGMP_PACKETS;
8050 PIM_DO_DEBUG_IGMP_TRACE;
8051 return CMD_SUCCESS;
12e41d03
DL
8052}
8053
8054DEFUN (no_debug_igmp,
8055 no_debug_igmp_cmd,
8056 "no debug igmp",
8057 NO_STR
8058 DEBUG_STR
8059 DEBUG_IGMP_STR)
8060{
d62a17ae 8061 PIM_DONT_DEBUG_IGMP_EVENTS;
8062 PIM_DONT_DEBUG_IGMP_PACKETS;
8063 PIM_DONT_DEBUG_IGMP_TRACE;
8064 return CMD_SUCCESS;
12e41d03
DL
8065}
8066
12e41d03
DL
8067
8068DEFUN (debug_igmp_events,
8069 debug_igmp_events_cmd,
8070 "debug igmp events",
8071 DEBUG_STR
8072 DEBUG_IGMP_STR
8073 DEBUG_IGMP_EVENTS_STR)
8074{
d62a17ae 8075 PIM_DO_DEBUG_IGMP_EVENTS;
8076 return CMD_SUCCESS;
12e41d03
DL
8077}
8078
8079DEFUN (no_debug_igmp_events,
8080 no_debug_igmp_events_cmd,
8081 "no debug igmp events",
8082 NO_STR
8083 DEBUG_STR
8084 DEBUG_IGMP_STR
8085 DEBUG_IGMP_EVENTS_STR)
8086{
d62a17ae 8087 PIM_DONT_DEBUG_IGMP_EVENTS;
8088 return CMD_SUCCESS;
12e41d03
DL
8089}
8090
12e41d03
DL
8091
8092DEFUN (debug_igmp_packets,
8093 debug_igmp_packets_cmd,
8094 "debug igmp packets",
8095 DEBUG_STR
8096 DEBUG_IGMP_STR
8097 DEBUG_IGMP_PACKETS_STR)
8098{
d62a17ae 8099 PIM_DO_DEBUG_IGMP_PACKETS;
8100 return CMD_SUCCESS;
12e41d03
DL
8101}
8102
8103DEFUN (no_debug_igmp_packets,
8104 no_debug_igmp_packets_cmd,
8105 "no debug igmp packets",
8106 NO_STR
8107 DEBUG_STR
8108 DEBUG_IGMP_STR
8109 DEBUG_IGMP_PACKETS_STR)
8110{
d62a17ae 8111 PIM_DONT_DEBUG_IGMP_PACKETS;
8112 return CMD_SUCCESS;
12e41d03
DL
8113}
8114
12e41d03
DL
8115
8116DEFUN (debug_igmp_trace,
8117 debug_igmp_trace_cmd,
8118 "debug igmp trace",
8119 DEBUG_STR
8120 DEBUG_IGMP_STR
8121 DEBUG_IGMP_TRACE_STR)
8122{
d62a17ae 8123 PIM_DO_DEBUG_IGMP_TRACE;
8124 return CMD_SUCCESS;
12e41d03
DL
8125}
8126
8127DEFUN (no_debug_igmp_trace,
8128 no_debug_igmp_trace_cmd,
8129 "no debug igmp trace",
8130 NO_STR
8131 DEBUG_STR
8132 DEBUG_IGMP_STR
8133 DEBUG_IGMP_TRACE_STR)
8134{
d62a17ae 8135 PIM_DONT_DEBUG_IGMP_TRACE;
8136 return CMD_SUCCESS;
12e41d03
DL
8137}
8138
12e41d03
DL
8139
8140DEFUN (debug_mroute,
8141 debug_mroute_cmd,
8142 "debug mroute",
8143 DEBUG_STR
8144 DEBUG_MROUTE_STR)
8145{
d62a17ae 8146 PIM_DO_DEBUG_MROUTE;
8147 return CMD_SUCCESS;
12e41d03
DL
8148}
8149
6c7197b1
DS
8150DEFUN (debug_mroute_detail,
8151 debug_mroute_detail_cmd,
8152 "debug mroute detail",
8153 DEBUG_STR
8154 DEBUG_MROUTE_STR
8155 "detailed\n")
8156{
d62a17ae 8157 PIM_DO_DEBUG_MROUTE_DETAIL;
8158 return CMD_SUCCESS;
6c7197b1
DS
8159}
8160
12e41d03
DL
8161DEFUN (no_debug_mroute,
8162 no_debug_mroute_cmd,
8163 "no debug mroute",
8164 NO_STR
8165 DEBUG_STR
8166 DEBUG_MROUTE_STR)
8167{
d62a17ae 8168 PIM_DONT_DEBUG_MROUTE;
8169 return CMD_SUCCESS;
12e41d03
DL
8170}
8171
6c7197b1
DS
8172DEFUN (no_debug_mroute_detail,
8173 no_debug_mroute_detail_cmd,
8174 "no debug mroute detail",
8175 NO_STR
8176 DEBUG_STR
8177 DEBUG_MROUTE_STR
8178 "detailed\n")
8179{
d62a17ae 8180 PIM_DONT_DEBUG_MROUTE_DETAIL;
8181 return CMD_SUCCESS;
6c7197b1 8182}
12e41d03 8183
35a12720
MS
8184DEFUN (debug_pim_static,
8185 debug_pim_static_cmd,
8186 "debug pim static",
6250610a 8187 DEBUG_STR
35a12720 8188 DEBUG_PIM_STR
6250610a
JAG
8189 DEBUG_STATIC_STR)
8190{
d62a17ae 8191 PIM_DO_DEBUG_STATIC;
8192 return CMD_SUCCESS;
6250610a
JAG
8193}
8194
35a12720
MS
8195DEFUN (no_debug_pim_static,
8196 no_debug_pim_static_cmd,
8197 "no debug pim static",
6250610a
JAG
8198 NO_STR
8199 DEBUG_STR
35a12720 8200 DEBUG_PIM_STR
6250610a
JAG
8201 DEBUG_STATIC_STR)
8202{
d62a17ae 8203 PIM_DONT_DEBUG_STATIC;
8204 return CMD_SUCCESS;
6250610a
JAG
8205}
8206
6250610a 8207
12e41d03
DL
8208DEFUN (debug_pim,
8209 debug_pim_cmd,
8210 "debug pim",
8211 DEBUG_STR
8212 DEBUG_PIM_STR)
8213{
d62a17ae 8214 PIM_DO_DEBUG_PIM_EVENTS;
8215 PIM_DO_DEBUG_PIM_PACKETS;
8216 PIM_DO_DEBUG_PIM_TRACE;
8217 PIM_DO_DEBUG_MSDP_EVENTS;
8218 PIM_DO_DEBUG_MSDP_PACKETS;
09524ccf 8219 PIM_DO_DEBUG_BSM;
d62a17ae 8220 return CMD_SUCCESS;
12e41d03
DL
8221}
8222
8223DEFUN (no_debug_pim,
8224 no_debug_pim_cmd,
8225 "no debug pim",
8226 NO_STR
8227 DEBUG_STR
8228 DEBUG_PIM_STR)
8229{
d62a17ae 8230 PIM_DONT_DEBUG_PIM_EVENTS;
8231 PIM_DONT_DEBUG_PIM_PACKETS;
8232 PIM_DONT_DEBUG_PIM_TRACE;
8233 PIM_DONT_DEBUG_MSDP_EVENTS;
8234 PIM_DONT_DEBUG_MSDP_PACKETS;
12e41d03 8235
d62a17ae 8236 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8237 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
09524ccf 8238 PIM_DONT_DEBUG_BSM;
12e41d03 8239
d62a17ae 8240 return CMD_SUCCESS;
12e41d03
DL
8241}
8242
40f1f31b
DS
8243DEFUN (debug_pim_nht,
8244 debug_pim_nht_cmd,
8245 "debug pim nht",
8246 DEBUG_STR
8247 DEBUG_PIM_STR
8248 "Nexthop Tracking\n")
8249{
8250 PIM_DO_DEBUG_PIM_NHT;
8251 return CMD_SUCCESS;
8252}
8253
8254DEFUN (no_debug_pim_nht,
8255 no_debug_pim_nht_cmd,
8256 "no debug pim nht",
8257 NO_STR
8258 DEBUG_STR
8259 DEBUG_PIM_STR
8260 "Nexthop Tracking\n")
8261{
8262 PIM_DONT_DEBUG_PIM_NHT;
8263 return CMD_SUCCESS;
8264}
12e41d03 8265
3d225d48
DS
8266DEFUN (debug_pim_nht_rp,
8267 debug_pim_nht_rp_cmd,
8268 "debug pim nht rp",
8269 DEBUG_STR
8270 DEBUG_PIM_STR
8271 "Nexthop Tracking\n"
8272 "RP Nexthop Tracking\n")
8273{
8274 PIM_DO_DEBUG_PIM_NHT_RP;
8275 return CMD_SUCCESS;
8276}
8277
8278DEFUN (no_debug_pim_nht_rp,
8279 no_debug_pim_nht_rp_cmd,
8280 "no debug pim nht rp",
8281 NO_STR
8282 DEBUG_STR
8283 DEBUG_PIM_STR
8284 "Nexthop Tracking\n"
8285 "RP Nexthop Tracking\n")
8286{
8287 PIM_DONT_DEBUG_PIM_NHT_RP;
8288 return CMD_SUCCESS;
8289}
8290
12e41d03
DL
8291DEFUN (debug_pim_events,
8292 debug_pim_events_cmd,
8293 "debug pim events",
8294 DEBUG_STR
8295 DEBUG_PIM_STR
8296 DEBUG_PIM_EVENTS_STR)
8297{
d62a17ae 8298 PIM_DO_DEBUG_PIM_EVENTS;
8299 return CMD_SUCCESS;
12e41d03
DL
8300}
8301
8302DEFUN (no_debug_pim_events,
8303 no_debug_pim_events_cmd,
8304 "no debug pim events",
8305 NO_STR
8306 DEBUG_STR
8307 DEBUG_PIM_STR
8308 DEBUG_PIM_EVENTS_STR)
8309{
d62a17ae 8310 PIM_DONT_DEBUG_PIM_EVENTS;
8311 return CMD_SUCCESS;
12e41d03
DL
8312}
8313
12e41d03
DL
8314DEFUN (debug_pim_packets,
8315 debug_pim_packets_cmd,
a957a05b 8316 "debug pim packets [<hello|joins|register>]",
12e41d03
DL
8317 DEBUG_STR
8318 DEBUG_PIM_STR
8319 DEBUG_PIM_PACKETS_STR
8320 DEBUG_PIM_HELLO_PACKETS_STR
9add3b88
DS
8321 DEBUG_PIM_J_P_PACKETS_STR
8322 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 8323{
d62a17ae 8324 int idx = 0;
8325 if (argv_find(argv, argc, "hello", &idx)) {
8326 PIM_DO_DEBUG_PIM_HELLO;
8327 vty_out(vty, "PIM Hello debugging is on\n");
8328 } else if (argv_find(argv, argc, "joins", &idx)) {
8329 PIM_DO_DEBUG_PIM_J_P;
8330 vty_out(vty, "PIM Join/Prune debugging is on\n");
8331 } else if (argv_find(argv, argc, "register", &idx)) {
8332 PIM_DO_DEBUG_PIM_REG;
8333 vty_out(vty, "PIM Register debugging is on\n");
8334 } else {
8335 PIM_DO_DEBUG_PIM_PACKETS;
8336 vty_out(vty, "PIM Packet debugging is on \n");
8337 }
8338 return CMD_SUCCESS;
12e41d03
DL
8339}
8340
8341DEFUN (no_debug_pim_packets,
8342 no_debug_pim_packets_cmd,
a957a05b 8343 "no debug pim packets [<hello|joins|register>]",
12e41d03
DL
8344 NO_STR
8345 DEBUG_STR
8346 DEBUG_PIM_STR
8347 DEBUG_PIM_PACKETS_STR
8348 DEBUG_PIM_HELLO_PACKETS_STR
a957a05b
DS
8349 DEBUG_PIM_J_P_PACKETS_STR
8350 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 8351{
d62a17ae 8352 int idx = 0;
8353 if (argv_find(argv, argc, "hello", &idx)) {
8354 PIM_DONT_DEBUG_PIM_HELLO;
8355 vty_out(vty, "PIM Hello debugging is off \n");
8356 } else if (argv_find(argv, argc, "joins", &idx)) {
8357 PIM_DONT_DEBUG_PIM_J_P;
8358 vty_out(vty, "PIM Join/Prune debugging is off \n");
8359 } else if (argv_find(argv, argc, "register", &idx)) {
8360 PIM_DONT_DEBUG_PIM_REG;
8361 vty_out(vty, "PIM Register debugging is off\n");
8362 } else
8363 PIM_DONT_DEBUG_PIM_PACKETS;
8364
8365 return CMD_SUCCESS;
12e41d03
DL
8366}
8367
12e41d03
DL
8368
8369DEFUN (debug_pim_packetdump_send,
8370 debug_pim_packetdump_send_cmd,
8371 "debug pim packet-dump send",
8372 DEBUG_STR
8373 DEBUG_PIM_STR
8374 DEBUG_PIM_PACKETDUMP_STR
8375 DEBUG_PIM_PACKETDUMP_SEND_STR)
8376{
d62a17ae 8377 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
8378 return CMD_SUCCESS;
12e41d03
DL
8379}
8380
8381DEFUN (no_debug_pim_packetdump_send,
8382 no_debug_pim_packetdump_send_cmd,
8383 "no debug pim packet-dump send",
8384 NO_STR
8385 DEBUG_STR
8386 DEBUG_PIM_STR
8387 DEBUG_PIM_PACKETDUMP_STR
8388 DEBUG_PIM_PACKETDUMP_SEND_STR)
8389{
d62a17ae 8390 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8391 return CMD_SUCCESS;
12e41d03
DL
8392}
8393
12e41d03
DL
8394DEFUN (debug_pim_packetdump_recv,
8395 debug_pim_packetdump_recv_cmd,
8396 "debug pim packet-dump receive",
8397 DEBUG_STR
8398 DEBUG_PIM_STR
8399 DEBUG_PIM_PACKETDUMP_STR
8400 DEBUG_PIM_PACKETDUMP_RECV_STR)
8401{
d62a17ae 8402 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
8403 return CMD_SUCCESS;
12e41d03
DL
8404}
8405
8406DEFUN (no_debug_pim_packetdump_recv,
8407 no_debug_pim_packetdump_recv_cmd,
8408 "no debug pim packet-dump receive",
8409 NO_STR
8410 DEBUG_STR
8411 DEBUG_PIM_STR
8412 DEBUG_PIM_PACKETDUMP_STR
8413 DEBUG_PIM_PACKETDUMP_RECV_STR)
8414{
d62a17ae 8415 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8416 return CMD_SUCCESS;
12e41d03
DL
8417}
8418
12e41d03
DL
8419DEFUN (debug_pim_trace,
8420 debug_pim_trace_cmd,
8421 "debug pim trace",
8422 DEBUG_STR
8423 DEBUG_PIM_STR
8424 DEBUG_PIM_TRACE_STR)
8425{
d62a17ae 8426 PIM_DO_DEBUG_PIM_TRACE;
8427 return CMD_SUCCESS;
12e41d03
DL
8428}
8429
56c238c9
DS
8430DEFUN (debug_pim_trace_detail,
8431 debug_pim_trace_detail_cmd,
8432 "debug pim trace detail",
8433 DEBUG_STR
8434 DEBUG_PIM_STR
5f40dada
DS
8435 DEBUG_PIM_TRACE_STR
8436 "Detailed Information\n")
56c238c9
DS
8437{
8438 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
8439 return CMD_SUCCESS;
8440}
8441
12e41d03
DL
8442DEFUN (no_debug_pim_trace,
8443 no_debug_pim_trace_cmd,
8444 "no debug pim trace",
8445 NO_STR
8446 DEBUG_STR
8447 DEBUG_PIM_STR
8448 DEBUG_PIM_TRACE_STR)
8449{
d62a17ae 8450 PIM_DONT_DEBUG_PIM_TRACE;
8451 return CMD_SUCCESS;
12e41d03
DL
8452}
8453
56c238c9
DS
8454DEFUN (no_debug_pim_trace_detail,
8455 no_debug_pim_trace_detail_cmd,
9853a7a5 8456 "no debug pim trace detail",
56c238c9
DS
8457 NO_STR
8458 DEBUG_STR
8459 DEBUG_PIM_STR
bd4d05c5
DS
8460 DEBUG_PIM_TRACE_STR
8461 "Detailed Information\n")
56c238c9
DS
8462{
8463 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
8464 return CMD_SUCCESS;
8465}
8466
12e41d03
DL
8467DEFUN (debug_ssmpingd,
8468 debug_ssmpingd_cmd,
8469 "debug ssmpingd",
8470 DEBUG_STR
12e41d03
DL
8471 DEBUG_SSMPINGD_STR)
8472{
d62a17ae 8473 PIM_DO_DEBUG_SSMPINGD;
8474 return CMD_SUCCESS;
12e41d03
DL
8475}
8476
8477DEFUN (no_debug_ssmpingd,
8478 no_debug_ssmpingd_cmd,
8479 "no debug ssmpingd",
8480 NO_STR
8481 DEBUG_STR
12e41d03
DL
8482 DEBUG_SSMPINGD_STR)
8483{
d62a17ae 8484 PIM_DONT_DEBUG_SSMPINGD;
8485 return CMD_SUCCESS;
12e41d03
DL
8486}
8487
12e41d03
DL
8488DEFUN (debug_pim_zebra,
8489 debug_pim_zebra_cmd,
8490 "debug pim zebra",
8491 DEBUG_STR
8492 DEBUG_PIM_STR
8493 DEBUG_PIM_ZEBRA_STR)
8494{
d62a17ae 8495 PIM_DO_DEBUG_ZEBRA;
8496 return CMD_SUCCESS;
12e41d03
DL
8497}
8498
8499DEFUN (no_debug_pim_zebra,
8500 no_debug_pim_zebra_cmd,
8501 "no debug pim zebra",
8502 NO_STR
8503 DEBUG_STR
8504 DEBUG_PIM_STR
8505 DEBUG_PIM_ZEBRA_STR)
8506{
d62a17ae 8507 PIM_DONT_DEBUG_ZEBRA;
8508 return CMD_SUCCESS;
12e41d03
DL
8509}
8510
36b5b98f
SK
8511DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
8512 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8513{
8514 PIM_DO_DEBUG_MLAG;
8515 return CMD_SUCCESS;
8516}
8517
8518DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
8519 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8520{
8521 PIM_DONT_DEBUG_MLAG;
8522 return CMD_SUCCESS;
8523}
8524
4d913fa6
AK
8525DEFUN (debug_pim_vxlan,
8526 debug_pim_vxlan_cmd,
8527 "debug pim vxlan",
8528 DEBUG_STR
8529 DEBUG_PIM_STR
8530 DEBUG_PIM_VXLAN_STR)
8531{
8532 PIM_DO_DEBUG_VXLAN;
8533 return CMD_SUCCESS;
8534}
8535
8536DEFUN (no_debug_pim_vxlan,
8537 no_debug_pim_vxlan_cmd,
8538 "no debug pim vxlan",
8539 NO_STR
8540 DEBUG_STR
8541 DEBUG_PIM_STR
8542 DEBUG_PIM_VXLAN_STR)
8543{
8544 PIM_DONT_DEBUG_VXLAN;
8545 return CMD_SUCCESS;
8546}
8547
2a333e0f 8548DEFUN (debug_msdp,
8549 debug_msdp_cmd,
8550 "debug msdp",
8551 DEBUG_STR
8552 DEBUG_MSDP_STR)
8553{
d62a17ae 8554 PIM_DO_DEBUG_MSDP_EVENTS;
8555 PIM_DO_DEBUG_MSDP_PACKETS;
8556 return CMD_SUCCESS;
2a333e0f 8557}
8558
8559DEFUN (no_debug_msdp,
8560 no_debug_msdp_cmd,
8561 "no debug msdp",
8562 NO_STR
8563 DEBUG_STR
8564 DEBUG_MSDP_STR)
8565{
d62a17ae 8566 PIM_DONT_DEBUG_MSDP_EVENTS;
8567 PIM_DONT_DEBUG_MSDP_PACKETS;
8568 return CMD_SUCCESS;
2a333e0f 8569}
8570
2a333e0f 8571DEFUN (debug_msdp_events,
8572 debug_msdp_events_cmd,
8573 "debug msdp events",
8574 DEBUG_STR
8575 DEBUG_MSDP_STR
8576 DEBUG_MSDP_EVENTS_STR)
8577{
d62a17ae 8578 PIM_DO_DEBUG_MSDP_EVENTS;
8579 return CMD_SUCCESS;
2a333e0f 8580}
8581
8582DEFUN (no_debug_msdp_events,
8583 no_debug_msdp_events_cmd,
8584 "no debug msdp events",
8585 NO_STR
8586 DEBUG_STR
8587 DEBUG_MSDP_STR
8588 DEBUG_MSDP_EVENTS_STR)
8589{
d62a17ae 8590 PIM_DONT_DEBUG_MSDP_EVENTS;
8591 return CMD_SUCCESS;
2a333e0f 8592}
8593
2a333e0f 8594DEFUN (debug_msdp_packets,
8595 debug_msdp_packets_cmd,
8596 "debug msdp packets",
8597 DEBUG_STR
8598 DEBUG_MSDP_STR
8599 DEBUG_MSDP_PACKETS_STR)
8600{
d62a17ae 8601 PIM_DO_DEBUG_MSDP_PACKETS;
8602 return CMD_SUCCESS;
2a333e0f 8603}
8604
8605DEFUN (no_debug_msdp_packets,
8606 no_debug_msdp_packets_cmd,
8607 "no debug msdp packets",
8608 NO_STR
8609 DEBUG_STR
8610 DEBUG_MSDP_STR
8611 DEBUG_MSDP_PACKETS_STR)
8612{
d62a17ae 8613 PIM_DONT_DEBUG_MSDP_PACKETS;
8614 return CMD_SUCCESS;
2a333e0f 8615}
8616
4d9ad5dc
MS
8617DEFUN (debug_mtrace,
8618 debug_mtrace_cmd,
8619 "debug mtrace",
8620 DEBUG_STR
8621 DEBUG_MTRACE_STR)
8622{
8623 PIM_DO_DEBUG_MTRACE;
8624 return CMD_SUCCESS;
8625}
8626
8627DEFUN (no_debug_mtrace,
8628 no_debug_mtrace_cmd,
8629 "no debug mtrace",
8630 NO_STR
8631 DEBUG_STR
8632 DEBUG_MTRACE_STR)
8633{
8634 PIM_DONT_DEBUG_MTRACE;
8635 return CMD_SUCCESS;
8636}
8637
09524ccf 8638DEFUN (debug_bsm,
8639 debug_bsm_cmd,
8640 "debug pim bsm",
8641 DEBUG_STR
8642 DEBUG_PIM_STR
8643 DEBUG_PIM_BSM_STR)
8644{
8645 PIM_DO_DEBUG_BSM;
8646 return CMD_SUCCESS;
8647}
8648
8649DEFUN (no_debug_bsm,
8650 no_debug_bsm_cmd,
8651 "no debug pim bsm",
8652 NO_STR
8653 DEBUG_STR
8654 DEBUG_PIM_STR
8655 DEBUG_PIM_BSM_STR)
8656{
8657 PIM_DONT_DEBUG_BSM;
8658 return CMD_SUCCESS;
8659}
8660
8661
87f6dc50
DS
8662DEFUN_NOSH (show_debugging_pim,
8663 show_debugging_pim_cmd,
8664 "show debugging [pim]",
8665 SHOW_STR
8666 DEBUG_STR
8667 PIM_STR)
12e41d03 8668{
87f6dc50
DS
8669 vty_out(vty, "PIM debugging status\n");
8670
d62a17ae 8671 pim_debug_config_write(vty);
87f6dc50 8672
d62a17ae 8673 return CMD_SUCCESS;
12e41d03
DL
8674}
8675
d62a17ae 8676static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
4763cd0e 8677{
d62a17ae 8678 int result;
8679 struct in_addr source_addr;
23f1c68b 8680 int ret = CMD_SUCCESS;
d62a17ae 8681 VTY_DECLVAR_CONTEXT(interface, ifp);
4763cd0e 8682
d62a17ae 8683 result = inet_pton(AF_INET, source, &source_addr);
8684 if (result <= 0) {
8685 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
8686 errno, safe_strerror(errno));
8687 return CMD_WARNING_CONFIG_FAILED;
8688 }
4763cd0e 8689
d62a17ae 8690 result = pim_update_source_set(ifp, source_addr);
8691 switch (result) {
8692 case PIM_SUCCESS:
8693 break;
8694 case PIM_IFACE_NOT_FOUND:
23f1c68b 8695 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8696 vty_out(vty, "Pim not enabled on this interface\n");
8697 break;
8698 case PIM_UPDATE_SOURCE_DUP:
23f1c68b 8699 ret = CMD_WARNING;
d62a17ae 8700 vty_out(vty, "%% Source already set to %s\n", source);
8701 break;
8702 default:
23f1c68b 8703 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8704 vty_out(vty, "%% Source set failed\n");
8705 }
4763cd0e 8706
23f1c68b 8707 return ret;
4763cd0e 8708}
8709
8710DEFUN (interface_pim_use_source,
8711 interface_pim_use_source_cmd,
8712 "ip pim use-source A.B.C.D",
8713 IP_STR
2f5e937c 8714 PIM_STR
4763cd0e 8715 "Configure primary IP address\n"
8716 "source ip address\n")
8717{
d62a17ae 8718 return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
4763cd0e 8719}
8720
8721DEFUN (interface_no_pim_use_source,
8722 interface_no_pim_use_source_cmd,
2243bb17 8723 "no ip pim use-source [A.B.C.D]",
4763cd0e 8724 NO_STR
8725 IP_STR
2f5e937c 8726 PIM_STR
2243bb17
DS
8727 "Delete source IP address\n"
8728 "source ip address\n")
4763cd0e 8729{
d62a17ae 8730 return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
4763cd0e 8731}
8732
ba4eb1bc
CS
8733DEFUN (ip_pim_bfd,
8734 ip_pim_bfd_cmd,
8735 "ip pim bfd",
8736 IP_STR
8737 PIM_STR
8738 "Enables BFD support\n")
8739{
d62a17ae 8740 VTY_DECLVAR_CONTEXT(interface, ifp);
8741 struct pim_interface *pim_ifp = ifp->info;
8742 struct bfd_info *bfd_info = NULL;
ba4eb1bc 8743
2fd8de7d
CS
8744 if (!pim_ifp) {
8745 if (!pim_cmd_interface_add(ifp)) {
8746 vty_out(vty, "Could not enable PIM SM on interface\n");
8747 return CMD_WARNING;
8748 }
8749 }
8750 pim_ifp = ifp->info;
8751
d62a17ae 8752 bfd_info = pim_ifp->bfd_info;
ba4eb1bc 8753
d62a17ae 8754 if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
8755 pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
8756 BFD_DEF_DETECT_MULT, 1);
ba4eb1bc 8757
d62a17ae 8758 return CMD_SUCCESS;
ba4eb1bc
CS
8759}
8760
8761DEFUN (no_ip_pim_bfd,
8762 no_ip_pim_bfd_cmd,
8763 "no ip pim bfd",
8764 NO_STR
8765 IP_STR
8766 PIM_STR
8767 "Disables BFD support\n")
8768{
d62a17ae 8769 VTY_DECLVAR_CONTEXT(interface, ifp);
8770 struct pim_interface *pim_ifp = ifp->info;
ba4eb1bc 8771
2fd8de7d
CS
8772 if (!pim_ifp) {
8773 vty_out(vty, "Pim not enabled on this interface\n");
8774 return CMD_WARNING;
8775 }
ba4eb1bc 8776
d62a17ae 8777 if (pim_ifp->bfd_info) {
8778 pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
8779 bfd_info_free(&(pim_ifp->bfd_info));
8780 }
ba4eb1bc 8781
d62a17ae 8782 return CMD_SUCCESS;
ba4eb1bc
CS
8783}
8784
16c926c8 8785DEFUN (ip_pim_bsm,
8786 ip_pim_bsm_cmd,
8787 "ip pim bsm",
8788 IP_STR
8789 PIM_STR
8790 "Enables BSM support on the interface\n")
8791{
8792 VTY_DECLVAR_CONTEXT(interface, ifp);
8793 struct pim_interface *pim_ifp = ifp->info;
8794
8795 if (!pim_ifp) {
8796 if (!pim_cmd_interface_add(ifp)) {
8797 vty_out(vty, "Could not enable PIM SM on interface\n");
8798 return CMD_WARNING;
8799 }
8800 }
8801
8802 pim_ifp = ifp->info;
8803 pim_ifp->bsm_enable = true;
8804
8805 return CMD_SUCCESS;
8806}
8807
8808DEFUN (no_ip_pim_bsm,
8809 no_ip_pim_bsm_cmd,
8810 "no ip pim bsm",
8811 NO_STR
8812 IP_STR
8813 PIM_STR
8814 "Disables BSM support\n")
8815{
8816 VTY_DECLVAR_CONTEXT(interface, ifp);
8817 struct pim_interface *pim_ifp = ifp->info;
8818
8819 if (!pim_ifp) {
8820 vty_out(vty, "Pim not enabled on this interface\n");
8821 return CMD_WARNING;
8822 }
8823
8824 pim_ifp->bsm_enable = false;
8825
8826 return CMD_SUCCESS;
8827}
8828
8829DEFUN (ip_pim_ucast_bsm,
8830 ip_pim_ucast_bsm_cmd,
8831 "ip pim unicast-bsm",
8832 IP_STR
8833 PIM_STR
8834 "Accept/Send unicast BSM on the interface\n")
8835{
8836 VTY_DECLVAR_CONTEXT(interface, ifp);
8837 struct pim_interface *pim_ifp = ifp->info;
8838
8839 if (!pim_ifp) {
8840 if (!pim_cmd_interface_add(ifp)) {
8841 vty_out(vty, "Could not enable PIM SM on interface\n");
8842 return CMD_WARNING;
8843 }
8844 }
8845
8846 pim_ifp = ifp->info;
8847 pim_ifp->ucast_bsm_accept = true;
8848
8849 return CMD_SUCCESS;
8850}
8851
8852DEFUN (no_ip_pim_ucast_bsm,
8853 no_ip_pim_ucast_bsm_cmd,
8854 "no ip pim unicast-bsm",
8855 NO_STR
8856 IP_STR
8857 PIM_STR
8858 "Block send/receive unicast BSM on this interface\n")
8859{
8860 VTY_DECLVAR_CONTEXT(interface, ifp);
8861 struct pim_interface *pim_ifp = ifp->info;
8862
8863 if (!pim_ifp) {
8864 vty_out(vty, "Pim not enabled on this interface\n");
8865 return CMD_WARNING;
8866 }
8867
8868 pim_ifp->ucast_bsm_accept = false;
8869
8870 return CMD_SUCCESS;
8871}
8872
64dc4b2d
RZ
8873#if HAVE_BFDD > 0
8874DEFUN_HIDDEN(
3779776a
DL
8875 ip_pim_bfd_param,
8876 ip_pim_bfd_param_cmd,
8877 "ip pim bfd (2-255) (50-60000) (50-60000)",
8878 IP_STR
8879 PIM_STR
8880 "Enables BFD support\n"
8881 "Detect Multiplier\n"
8882 "Required min receive interval\n"
8883 "Desired min transmit interval\n")
64dc4b2d
RZ
8884#else
8885DEFUN(
64dc4b2d 8886 ip_pim_bfd_param,
ba4eb1bc
CS
8887 ip_pim_bfd_param_cmd,
8888 "ip pim bfd (2-255) (50-60000) (50-60000)",
8889 IP_STR
8890 PIM_STR
8891 "Enables BFD support\n"
8892 "Detect Multiplier\n"
8893 "Required min receive interval\n"
8894 "Desired min transmit interval\n")
3779776a 8895#endif /* HAVE_BFDD */
ba4eb1bc 8896{
d62a17ae 8897 VTY_DECLVAR_CONTEXT(interface, ifp);
8898 int idx_number = 3;
8899 int idx_number_2 = 4;
8900 int idx_number_3 = 5;
d7c0a89a
QY
8901 uint32_t rx_val;
8902 uint32_t tx_val;
8903 uint8_t dm_val;
d62a17ae 8904 int ret;
2fd8de7d 8905 struct pim_interface *pim_ifp = ifp->info;
ba4eb1bc 8906
2fd8de7d
CS
8907 if (!pim_ifp) {
8908 if (!pim_cmd_interface_add(ifp)) {
8909 vty_out(vty, "Could not enable PIM SM on interface\n");
8910 return CMD_WARNING;
8911 }
8912 }
ba4eb1bc 8913
d62a17ae 8914 if ((ret = bfd_validate_param(
8915 vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
8916 argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
8917 != CMD_SUCCESS)
8918 return ret;
ba4eb1bc 8919
d62a17ae 8920 pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
ba4eb1bc 8921
d62a17ae 8922 return CMD_SUCCESS;
ba4eb1bc
CS
8923}
8924
64dc4b2d 8925#if HAVE_BFDD == 0
d62a17ae 8926ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
9d303b37 8927 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
d62a17ae 8928 "Enables BFD support\n"
8929 "Detect Multiplier\n"
8930 "Required min receive interval\n"
8931 "Desired min transmit interval\n")
64dc4b2d 8932#endif /* !HAVE_BFDD */
d62a17ae 8933
64c86530 8934static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925 8935 const char *peer, const char *local)
d62a17ae 8936{
8937 enum pim_msdp_err result;
8938 struct in_addr peer_addr;
8939 struct in_addr local_addr;
01841ed3 8940 int ret = CMD_SUCCESS;
d62a17ae 8941
8942 result = inet_pton(AF_INET, peer, &peer_addr);
8943 if (result <= 0) {
8944 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
8945 errno, safe_strerror(errno));
8946 return CMD_WARNING_CONFIG_FAILED;
8947 }
8948
8949 result = inet_pton(AF_INET, local, &local_addr);
8950 if (result <= 0) {
8951 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
8952 errno, safe_strerror(errno));
8953 return CMD_WARNING_CONFIG_FAILED;
8954 }
ba4eb1bc 8955
4f9f3925 8956 result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
d62a17ae 8957 NULL /* mp_p */);
8958 switch (result) {
8959 case PIM_MSDP_ERR_NONE:
8960 break;
8961 case PIM_MSDP_ERR_OOM:
01841ed3 8962 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8963 vty_out(vty, "%% Out of memory\n");
8964 break;
8965 case PIM_MSDP_ERR_PEER_EXISTS:
01841ed3 8966 ret = CMD_WARNING;
d62a17ae 8967 vty_out(vty, "%% Peer exists\n");
8968 break;
8969 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
01841ed3 8970 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8971 vty_out(vty, "%% Only one mesh-group allowed currently\n");
8972 break;
8973 default:
01841ed3 8974 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 8975 vty_out(vty, "%% peer add failed\n");
8976 }
8977
01841ed3 8978 return ret;
2a333e0f 8979}
8980
977d71cc 8981DEFUN_HIDDEN (ip_msdp_peer,
2a333e0f 8982 ip_msdp_peer_cmd,
8983 "ip msdp peer A.B.C.D source A.B.C.D",
8984 IP_STR
8985 CFG_MSDP_STR
8986 "Configure MSDP peer\n"
8987 "peer ip address\n"
8988 "Source address for TCP connection\n"
8989 "local ip address\n")
8990{
4f9f3925 8991 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 8992 return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg);
2a333e0f 8993}
8994
64c86530 8995static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925 8996 const char *peer)
2a333e0f 8997{
d62a17ae 8998 enum pim_msdp_err result;
8999 struct in_addr peer_addr;
2a333e0f 9000
d62a17ae 9001 result = inet_pton(AF_INET, peer, &peer_addr);
9002 if (result <= 0) {
9003 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
9004 errno, safe_strerror(errno));
9005 return CMD_WARNING_CONFIG_FAILED;
9006 }
2a333e0f 9007
4f9f3925 9008 result = pim_msdp_peer_del(pim, peer_addr);
d62a17ae 9009 switch (result) {
9010 case PIM_MSDP_ERR_NONE:
9011 break;
9012 case PIM_MSDP_ERR_NO_PEER:
9013 vty_out(vty, "%% Peer does not exist\n");
9014 break;
9015 default:
9016 vty_out(vty, "%% peer del failed\n");
9017 }
2a333e0f 9018
d62a17ae 9019 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
2a333e0f 9020}
9021
977d71cc 9022DEFUN_HIDDEN (no_ip_msdp_peer,
2a333e0f 9023 no_ip_msdp_peer_cmd,
9024 "no ip msdp peer A.B.C.D",
977d71cc 9025 NO_STR
2a333e0f 9026 IP_STR
9027 CFG_MSDP_STR
9028 "Delete MSDP peer\n"
9029 "peer ip address\n")
9030{
4f9f3925 9031 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 9032 return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg);
2a333e0f 9033}
9034
64c86530
DS
9035static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9036 struct vty *vty, const char *mg,
9037 const char *mbr)
977d71cc 9038{
d62a17ae 9039 enum pim_msdp_err result;
9040 struct in_addr mbr_ip;
01841ed3 9041 int ret = CMD_SUCCESS;
977d71cc 9042
d62a17ae 9043 result = inet_pton(AF_INET, mbr, &mbr_ip);
9044 if (result <= 0) {
9045 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9046 errno, safe_strerror(errno));
9047 return CMD_WARNING_CONFIG_FAILED;
9048 }
977d71cc 9049
02a16316 9050 result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
d62a17ae 9051 switch (result) {
9052 case PIM_MSDP_ERR_NONE:
9053 break;
9054 case PIM_MSDP_ERR_OOM:
01841ed3 9055 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 9056 vty_out(vty, "%% Out of memory\n");
9057 break;
9058 case PIM_MSDP_ERR_MG_MBR_EXISTS:
01841ed3 9059 ret = CMD_WARNING;
d62a17ae 9060 vty_out(vty, "%% mesh-group member exists\n");
9061 break;
9062 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
01841ed3 9063 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 9064 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9065 break;
9066 default:
01841ed3 9067 ret = CMD_WARNING_CONFIG_FAILED;
d62a17ae 9068 vty_out(vty, "%% member add failed\n");
9069 }
977d71cc 9070
01841ed3 9071 return ret;
977d71cc 9072}
9073
9074DEFUN (ip_msdp_mesh_group_member,
9075 ip_msdp_mesh_group_member_cmd,
9076 "ip msdp mesh-group WORD member A.B.C.D",
9077 IP_STR
9078 CFG_MSDP_STR
9079 "Configure MSDP mesh-group\n"
9080 "mesh group name\n"
9081 "mesh group member\n"
9082 "peer ip address\n")
9083{
02a16316 9084 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 9085 return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg,
d62a17ae 9086 argv[5]->arg);
977d71cc 9087}
9088
64c86530
DS
9089static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9090 struct vty *vty,
d62a17ae 9091 const char *mg,
9092 const char *mbr)
977d71cc 9093{
d62a17ae 9094 enum pim_msdp_err result;
9095 struct in_addr mbr_ip;
977d71cc 9096
d62a17ae 9097 result = inet_pton(AF_INET, mbr, &mbr_ip);
9098 if (result <= 0) {
9099 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9100 errno, safe_strerror(errno));
9101 return CMD_WARNING_CONFIG_FAILED;
9102 }
977d71cc 9103
02a16316 9104 result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
d62a17ae 9105 switch (result) {
9106 case PIM_MSDP_ERR_NONE:
9107 break;
9108 case PIM_MSDP_ERR_NO_MG:
9109 vty_out(vty, "%% mesh-group does not exist\n");
9110 break;
9111 case PIM_MSDP_ERR_NO_MG_MBR:
9112 vty_out(vty, "%% mesh-group member does not exist\n");
9113 break;
9114 default:
9115 vty_out(vty, "%% mesh-group member del failed\n");
9116 }
977d71cc 9117
d62a17ae 9118 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 9119}
9120DEFUN (no_ip_msdp_mesh_group_member,
9121 no_ip_msdp_mesh_group_member_cmd,
9122 "no ip msdp mesh-group WORD member A.B.C.D",
9123 NO_STR
9124 IP_STR
9125 CFG_MSDP_STR
9126 "Delete MSDP mesh-group member\n"
9127 "mesh group name\n"
9128 "mesh group member\n"
9129 "peer ip address\n")
9130{
02a16316 9131 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 9132 return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg,
d62a17ae 9133 argv[6]->arg);
977d71cc 9134}
9135
64c86530
DS
9136static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9137 struct vty *vty, const char *mg,
9138 const char *src)
977d71cc 9139{
d62a17ae 9140 enum pim_msdp_err result;
9141 struct in_addr src_ip;
977d71cc 9142
d62a17ae 9143 result = inet_pton(AF_INET, src, &src_ip);
9144 if (result <= 0) {
9145 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
9146 errno, safe_strerror(errno));
9147 return CMD_WARNING_CONFIG_FAILED;
9148 }
977d71cc 9149
02a16316 9150 result = pim_msdp_mg_src_add(pim, mg, src_ip);
d62a17ae 9151 switch (result) {
9152 case PIM_MSDP_ERR_NONE:
9153 break;
9154 case PIM_MSDP_ERR_OOM:
9155 vty_out(vty, "%% Out of memory\n");
9156 break;
9157 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9158 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9159 break;
9160 default:
9161 vty_out(vty, "%% source add failed\n");
9162 }
977d71cc 9163
d62a17ae 9164 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 9165}
9166
9167
9168DEFUN (ip_msdp_mesh_group_source,
9169 ip_msdp_mesh_group_source_cmd,
9170 "ip msdp mesh-group WORD source A.B.C.D",
9171 IP_STR
9172 CFG_MSDP_STR
9173 "Configure MSDP mesh-group\n"
9174 "mesh group name\n"
9175 "mesh group local address\n"
9176 "source ip address for the TCP connection\n")
9177{
02a16316 9178 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 9179 return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg,
d62a17ae 9180 argv[5]->arg);
977d71cc 9181}
9182
64c86530
DS
9183static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9184 struct vty *vty,
d62a17ae 9185 const char *mg)
977d71cc 9186{
d62a17ae 9187 enum pim_msdp_err result;
977d71cc 9188
02a16316 9189 result = pim_msdp_mg_src_del(pim, mg);
d62a17ae 9190 switch (result) {
9191 case PIM_MSDP_ERR_NONE:
9192 break;
9193 case PIM_MSDP_ERR_NO_MG:
9194 vty_out(vty, "%% mesh-group does not exist\n");
9195 break;
9196 default:
9197 vty_out(vty, "%% mesh-group source del failed\n");
9198 }
977d71cc 9199
d62a17ae 9200 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 9201}
9202
64c86530
DS
9203static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
9204 struct vty *vty, const char *mg)
977d71cc 9205{
d62a17ae 9206 enum pim_msdp_err result;
977d71cc 9207
02a16316 9208 result = pim_msdp_mg_del(pim, mg);
d62a17ae 9209 switch (result) {
9210 case PIM_MSDP_ERR_NONE:
9211 break;
9212 case PIM_MSDP_ERR_NO_MG:
9213 vty_out(vty, "%% mesh-group does not exist\n");
9214 break;
9215 default:
9216 vty_out(vty, "%% mesh-group source del failed\n");
9217 }
977d71cc 9218
d62a17ae 9219 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 9220}
9221
58344b65
DS
9222DEFUN (no_ip_msdp_mesh_group_source,
9223 no_ip_msdp_mesh_group_source_cmd,
9224 "no ip msdp mesh-group WORD source [A.B.C.D]",
977d71cc 9225 NO_STR
9226 IP_STR
9227 CFG_MSDP_STR
58344b65
DS
9228 "Delete MSDP mesh-group source\n"
9229 "mesh group name\n"
a957a05b 9230 "mesh group source\n"
58344b65 9231 "mesh group local address\n")
977d71cc 9232{
02a16316 9233 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 9234 if (argc == 7)
64c86530 9235 return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[6]->arg);
d62a17ae 9236 else
64c86530 9237 return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty,
d62a17ae 9238 argv[4]->arg);
9239}
9240
9241static void print_empty_json_obj(struct vty *vty)
9242{
9243 json_object *json;
9244 json = json_object_new_object();
9245 vty_out(vty, "%s\n",
9246 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
9247 json_object_free(json);
9248}
9249
64c86530 9250static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
088f1098 9251 bool uj)
d62a17ae 9252{
9253 struct listnode *mbrnode;
9254 struct pim_msdp_mg_mbr *mbr;
02a16316 9255 struct pim_msdp_mg *mg = pim->msdp.mg;
d62a17ae 9256 char mbr_str[INET_ADDRSTRLEN];
9257 char src_str[INET_ADDRSTRLEN];
9258 char state_str[PIM_MSDP_STATE_STRLEN];
9259 enum pim_msdp_peer_state state;
9260 json_object *json = NULL;
9261 json_object *json_mg_row = NULL;
9262 json_object *json_members = NULL;
9263 json_object *json_row = NULL;
9264
9265 if (!mg) {
9266 if (uj)
9267 print_empty_json_obj(vty);
9268 return;
9269 }
9270
9271 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
9272 if (uj) {
9273 json = json_object_new_object();
9274 /* currently there is only one mesh group but we should still
9275 * make
9276 * it a dict with mg-name as key */
9277 json_mg_row = json_object_new_object();
9278 json_object_string_add(json_mg_row, "name",
9279 mg->mesh_group_name);
9280 json_object_string_add(json_mg_row, "source", src_str);
9281 } else {
9282 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
9283 vty_out(vty, " Source : %s\n", src_str);
9284 vty_out(vty, " Member State\n");
9285 }
9286
9287 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
9288 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
9289 if (mbr->mp) {
9290 state = mbr->mp->state;
9291 } else {
9292 state = PIM_MSDP_DISABLED;
9293 }
9294 pim_msdp_state_dump(state, state_str, sizeof(state_str));
9295 if (uj) {
9296 json_row = json_object_new_object();
9297 json_object_string_add(json_row, "member", mbr_str);
9298 json_object_string_add(json_row, "state", state_str);
9299 if (!json_members) {
9300 json_members = json_object_new_object();
9301 json_object_object_add(json_mg_row, "members",
9302 json_members);
9303 }
9304 json_object_object_add(json_members, mbr_str, json_row);
9305 } else {
9306 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
9307 }
9308 }
9309
9310 if (uj) {
9311 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
9d303b37
DL
9312 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9313 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9314 json_object_free(json);
9315 }
977d71cc 9316}
9317
9318DEFUN (show_ip_msdp_mesh_group,
9319 show_ip_msdp_mesh_group_cmd,
20a7e5fd 9320 "show ip msdp [vrf NAME] mesh-group [json]",
977d71cc 9321 SHOW_STR
9322 IP_STR
9323 MSDP_STR
f02d59db 9324 VRF_CMD_HELP_STR
977d71cc 9325 "MSDP mesh-group information\n"
f5da2cc2 9326 JSON_STR)
977d71cc 9327{
9f049418 9328 bool uj = use_json(argc, argv);
c68ba0d7 9329 int idx = 2;
02a16316
DS
9330 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9331
9332 if (!vrf)
9333 return CMD_WARNING;
9334
64c86530 9335 ip_msdp_show_mesh_group(vrf->info, vty, uj);
d62a17ae 9336
9337 return CMD_SUCCESS;
9338}
9339
a25de56b
DS
9340DEFUN (show_ip_msdp_mesh_group_vrf_all,
9341 show_ip_msdp_mesh_group_vrf_all_cmd,
9342 "show ip msdp vrf all mesh-group [json]",
9343 SHOW_STR
9344 IP_STR
9345 MSDP_STR
9346 VRF_CMD_HELP_STR
9347 "MSDP mesh-group information\n"
f5da2cc2 9348 JSON_STR)
a25de56b 9349{
9f049418 9350 bool uj = use_json(argc, argv);
a25de56b
DS
9351 struct vrf *vrf;
9352 bool first = true;
9353
9354 if (uj)
9355 vty_out(vty, "{ ");
a2addae8 9356 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9357 if (uj) {
9358 if (!first)
9359 vty_out(vty, ", ");
9360 vty_out(vty, " \"%s\": ", vrf->name);
9361 first = false;
9362 } else
9363 vty_out(vty, "VRF: %s\n", vrf->name);
9364 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9365 }
9366 if (uj)
9367 vty_out(vty, "}\n");
9368
9369 return CMD_SUCCESS;
9370}
9371
64c86530 9372static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
088f1098 9373 bool uj)
d62a17ae 9374{
9375 struct listnode *mpnode;
9376 struct pim_msdp_peer *mp;
9377 char peer_str[INET_ADDRSTRLEN];
9378 char local_str[INET_ADDRSTRLEN];
9379 char state_str[PIM_MSDP_STATE_STRLEN];
9380 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9381 int64_t now;
9382 json_object *json = NULL;
9383 json_object *json_row = NULL;
9384
9385
9386 if (uj) {
9387 json = json_object_new_object();
9388 } else {
9389 vty_out(vty,
9390 "Peer Local State Uptime SaCnt\n");
9391 }
9392
02a16316 9393 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 9394 if (mp->state == PIM_MSDP_ESTABLISHED) {
9395 now = pim_time_monotonic_sec();
9396 pim_time_uptime(timebuf, sizeof(timebuf),
9397 now - mp->uptime);
9398 } else {
c35b7e6b 9399 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 9400 }
9401 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9402 pim_inet4_dump("<local?>", mp->local, local_str,
9403 sizeof(local_str));
9404 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9405 if (uj) {
9406 json_row = json_object_new_object();
9407 json_object_string_add(json_row, "peer", peer_str);
9408 json_object_string_add(json_row, "local", local_str);
9409 json_object_string_add(json_row, "state", state_str);
9410 json_object_string_add(json_row, "upTime", timebuf);
9411 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9412 json_object_object_add(json, peer_str, json_row);
9413 } else {
9414 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
9415 local_str, state_str, timebuf, mp->sa_cnt);
9416 }
9417 }
9418
9419 if (uj) {
9d303b37
DL
9420 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9421 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9422 json_object_free(json);
9423 }
9424}
9425
64c86530 9426static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
088f1098 9427 const char *peer, bool uj)
d62a17ae 9428{
9429 struct listnode *mpnode;
9430 struct pim_msdp_peer *mp;
9431 char peer_str[INET_ADDRSTRLEN];
9432 char local_str[INET_ADDRSTRLEN];
9433 char state_str[PIM_MSDP_STATE_STRLEN];
9434 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9435 char katimer[PIM_MSDP_TIMER_STRLEN];
9436 char crtimer[PIM_MSDP_TIMER_STRLEN];
9437 char holdtimer[PIM_MSDP_TIMER_STRLEN];
9438 int64_t now;
9439 json_object *json = NULL;
9440 json_object *json_row = NULL;
9441
9442 if (uj) {
9443 json = json_object_new_object();
9444 }
9445
02a16316 9446 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 9447 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9448 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
9449 continue;
9450
9451 if (mp->state == PIM_MSDP_ESTABLISHED) {
9452 now = pim_time_monotonic_sec();
9453 pim_time_uptime(timebuf, sizeof(timebuf),
9454 now - mp->uptime);
9455 } else {
c35b7e6b 9456 strlcpy(timebuf, "-", sizeof(timebuf));
d62a17ae 9457 }
9458 pim_inet4_dump("<local?>", mp->local, local_str,
9459 sizeof(local_str));
9460 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9461 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
9462 mp->ka_timer);
9463 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
9464 mp->cr_timer);
9465 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
9466 mp->hold_timer);
9467
9468 if (uj) {
9469 json_row = json_object_new_object();
9470 json_object_string_add(json_row, "peer", peer_str);
9471 json_object_string_add(json_row, "local", local_str);
9472 json_object_string_add(json_row, "meshGroupName",
9473 mp->mesh_group_name);
9474 json_object_string_add(json_row, "state", state_str);
9475 json_object_string_add(json_row, "upTime", timebuf);
9476 json_object_string_add(json_row, "keepAliveTimer",
9477 katimer);
9478 json_object_string_add(json_row, "connRetryTimer",
9479 crtimer);
9480 json_object_string_add(json_row, "holdTimer",
9481 holdtimer);
9482 json_object_string_add(json_row, "lastReset",
9483 mp->last_reset);
9484 json_object_int_add(json_row, "connAttempts",
9485 mp->conn_attempts);
9486 json_object_int_add(json_row, "establishedChanges",
9487 mp->est_flaps);
9488 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9489 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
9490 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
9491 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
9492 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
9493 json_object_object_add(json, peer_str, json_row);
9494 } else {
9495 vty_out(vty, "Peer : %s\n", peer_str);
9496 vty_out(vty, " Local : %s\n", local_str);
9497 vty_out(vty, " Mesh Group : %s\n",
9498 mp->mesh_group_name);
9499 vty_out(vty, " State : %s\n", state_str);
9500 vty_out(vty, " Uptime : %s\n", timebuf);
9501
9502 vty_out(vty, " Keepalive Timer : %s\n", katimer);
9503 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
9504 vty_out(vty, " Hold Timer : %s\n", holdtimer);
9505 vty_out(vty, " Last Reset : %s\n",
9506 mp->last_reset);
9507 vty_out(vty, " Conn Attempts : %d\n",
9508 mp->conn_attempts);
9509 vty_out(vty, " Established Changes : %d\n",
9510 mp->est_flaps);
9511 vty_out(vty, " SA Count : %d\n",
9512 mp->sa_cnt);
9513 vty_out(vty, " Statistics :\n");
9514 vty_out(vty,
9515 " Sent Rcvd\n");
9516 vty_out(vty, " Keepalives : %10d %10d\n",
9517 mp->ka_tx_cnt, mp->ka_rx_cnt);
9518 vty_out(vty, " SAs : %10d %10d\n",
9519 mp->sa_tx_cnt, mp->sa_rx_cnt);
9520 vty_out(vty, "\n");
9521 }
9522 }
9523
9524 if (uj) {
9d303b37
DL
9525 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9526 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9527 json_object_free(json);
9528 }
977d71cc 9529}
9530
9531DEFUN (show_ip_msdp_peer_detail,
9532 show_ip_msdp_peer_detail_cmd,
20a7e5fd 9533 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
2a333e0f 9534 SHOW_STR
9535 IP_STR
9536 MSDP_STR
f02d59db 9537 VRF_CMD_HELP_STR
2a333e0f 9538 "MSDP peer information\n"
977d71cc 9539 "Detailed output\n"
9540 "peer ip address\n"
f5da2cc2 9541 JSON_STR)
2a333e0f 9542{
9f049418 9543 bool uj = use_json(argc, argv);
c68ba0d7 9544 int idx = 2;
02a16316 9545 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 9546
07a29355
QY
9547 if (!vrf)
9548 return CMD_WARNING;
9549
9550 char *arg = NULL;
9551
9552 if (argv_find(argv, argc, "detail", &idx))
9553 arg = argv[idx]->text;
9554 else if (argv_find(argv, argc, "A.B.C.D", &idx))
9555 arg = argv[idx]->arg;
9556
9557 if (arg)
64c86530 9558 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 9559 else
64c86530 9560 ip_msdp_show_peers(vrf->info, vty, uj);
d62a17ae 9561
9562 return CMD_SUCCESS;
9563}
9564
a25de56b
DS
9565DEFUN (show_ip_msdp_peer_detail_vrf_all,
9566 show_ip_msdp_peer_detail_vrf_all_cmd,
9567 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9568 SHOW_STR
9569 IP_STR
9570 MSDP_STR
9571 VRF_CMD_HELP_STR
9572 "MSDP peer information\n"
9573 "Detailed output\n"
9574 "peer ip address\n"
f5da2cc2 9575 JSON_STR)
a25de56b
DS
9576{
9577 int idx = 2;
9f049418 9578 bool uj = use_json(argc, argv);
a25de56b
DS
9579 struct vrf *vrf;
9580 bool first = true;
9581
9582 if (uj)
9583 vty_out(vty, "{ ");
a2addae8 9584 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9585 if (uj) {
9586 if (!first)
9587 vty_out(vty, ", ");
9588 vty_out(vty, " \"%s\": ", vrf->name);
9589 first = false;
9590 } else
9591 vty_out(vty, "VRF: %s\n", vrf->name);
9592 if (argv_find(argv, argc, "detail", &idx)
9593 || argv_find(argv, argc, "A.B.C.D", &idx))
9594 ip_msdp_show_peers_detail(vrf->info, vty,
9595 argv[idx]->arg, uj);
9596 else
9597 ip_msdp_show_peers(vrf->info, vty, uj);
9598 }
9599 if (uj)
9600 vty_out(vty, "}\n");
9601
9602 return CMD_SUCCESS;
9603}
9604
088f1098 9605static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
d62a17ae 9606{
9607 struct listnode *sanode;
9608 struct pim_msdp_sa *sa;
9609 char src_str[INET_ADDRSTRLEN];
9610 char grp_str[INET_ADDRSTRLEN];
9611 char rp_str[INET_ADDRSTRLEN];
9612 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9613 char spt_str[8];
9614 char local_str[8];
9615 int64_t now;
9616 json_object *json = NULL;
9617 json_object *json_group = NULL;
9618 json_object *json_row = NULL;
9619
9620 if (uj) {
9621 json = json_object_new_object();
9622 } else {
9623 vty_out(vty,
9624 "Source Group RP Local SPT Uptime\n");
9625 }
9626
02a16316 9627 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9628 now = pim_time_monotonic_sec();
9629 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9630 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9631 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9632 if (sa->flags & PIM_MSDP_SAF_PEER) {
9633 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9634 if (sa->up) {
c35b7e6b 9635 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 9636 } else {
c35b7e6b 9637 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 9638 }
9639 } else {
c35b7e6b
QY
9640 strlcpy(rp_str, "-", sizeof(rp_str));
9641 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 9642 }
9643 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 9644 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 9645 } else {
c35b7e6b 9646 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 9647 }
9648 if (uj) {
9649 json_object_object_get_ex(json, grp_str, &json_group);
9650
9651 if (!json_group) {
9652 json_group = json_object_new_object();
9653 json_object_object_add(json, grp_str,
9654 json_group);
9655 }
9656
9657 json_row = json_object_new_object();
9658 json_object_string_add(json_row, "source", src_str);
9659 json_object_string_add(json_row, "group", grp_str);
9660 json_object_string_add(json_row, "rp", rp_str);
9661 json_object_string_add(json_row, "local", local_str);
9662 json_object_string_add(json_row, "sptSetup", spt_str);
9663 json_object_string_add(json_row, "upTime", timebuf);
9664 json_object_object_add(json_group, src_str, json_row);
9665 } else {
9666 vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
9667 src_str, grp_str, rp_str, local_str[0],
9668 spt_str[0], timebuf);
9669 }
9670 }
9671
d62a17ae 9672 if (uj) {
9d303b37
DL
9673 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9674 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9675 json_object_free(json);
9676 }
9677}
9678
9679static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
9680 const char *src_str,
9681 const char *grp_str, struct vty *vty,
088f1098 9682 bool uj, json_object *json)
d62a17ae 9683{
9684 char rp_str[INET_ADDRSTRLEN];
9685 char peer_str[INET_ADDRSTRLEN];
9686 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9687 char spt_str[8];
9688 char local_str[8];
9689 char statetimer[PIM_MSDP_TIMER_STRLEN];
9690 int64_t now;
9691 json_object *json_group = NULL;
9692 json_object *json_row = NULL;
9693
9694 now = pim_time_monotonic_sec();
9695 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9696 if (sa->flags & PIM_MSDP_SAF_PEER) {
9697 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9698 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
9699 if (sa->up) {
c35b7e6b 9700 strlcpy(spt_str, "yes", sizeof(spt_str));
d62a17ae 9701 } else {
c35b7e6b 9702 strlcpy(spt_str, "no", sizeof(spt_str));
d62a17ae 9703 }
9704 } else {
c35b7e6b
QY
9705 strlcpy(rp_str, "-", sizeof(rp_str));
9706 strlcpy(peer_str, "-", sizeof(peer_str));
9707 strlcpy(spt_str, "-", sizeof(spt_str));
d62a17ae 9708 }
9709 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
c35b7e6b 9710 strlcpy(local_str, "yes", sizeof(local_str));
d62a17ae 9711 } else {
c35b7e6b 9712 strlcpy(local_str, "no", sizeof(local_str));
d62a17ae 9713 }
9714 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
9715 sa->sa_state_timer);
9716 if (uj) {
9717 json_object_object_get_ex(json, grp_str, &json_group);
9718
9719 if (!json_group) {
9720 json_group = json_object_new_object();
9721 json_object_object_add(json, grp_str, json_group);
9722 }
9723
9724 json_row = json_object_new_object();
9725 json_object_string_add(json_row, "source", src_str);
9726 json_object_string_add(json_row, "group", grp_str);
9727 json_object_string_add(json_row, "rp", rp_str);
9728 json_object_string_add(json_row, "local", local_str);
9729 json_object_string_add(json_row, "sptSetup", spt_str);
9730 json_object_string_add(json_row, "upTime", timebuf);
9731 json_object_string_add(json_row, "stateTimer", statetimer);
9732 json_object_object_add(json_group, src_str, json_row);
9733 } else {
9734 vty_out(vty, "SA : %s\n", sa->sg_str);
9735 vty_out(vty, " RP : %s\n", rp_str);
9736 vty_out(vty, " Peer : %s\n", peer_str);
9737 vty_out(vty, " Local : %s\n", local_str);
9738 vty_out(vty, " SPT Setup : %s\n", spt_str);
9739 vty_out(vty, " Uptime : %s\n", timebuf);
9740 vty_out(vty, " State Timer : %s\n", statetimer);
9741 vty_out(vty, "\n");
9742 }
9743}
9744
64c86530 9745static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
088f1098 9746 bool uj)
d62a17ae 9747{
9748 struct listnode *sanode;
9749 struct pim_msdp_sa *sa;
9750 char src_str[INET_ADDRSTRLEN];
9751 char grp_str[INET_ADDRSTRLEN];
9752 json_object *json = NULL;
9753
9754 if (uj) {
9755 json = json_object_new_object();
9756 }
9757
02a16316 9758 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9759 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9760 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9761 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
9762 json);
9763 }
9764
9765 if (uj) {
9d303b37
DL
9766 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9767 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9768 json_object_free(json);
9769 }
977d71cc 9770}
9771
9772DEFUN (show_ip_msdp_sa_detail,
9773 show_ip_msdp_sa_detail_cmd,
20a7e5fd 9774 "show ip msdp [vrf NAME] sa detail [json]",
3c72d654 9775 SHOW_STR
9776 IP_STR
9777 MSDP_STR
f02d59db 9778 VRF_CMD_HELP_STR
3c72d654 9779 "MSDP active-source information\n"
977d71cc 9780 "Detailed output\n"
f5da2cc2 9781 JSON_STR)
3c72d654 9782{
9f049418 9783 bool uj = use_json(argc, argv);
c68ba0d7 9784 int idx = 2;
02a16316
DS
9785 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9786
9787 if (!vrf)
9788 return CMD_WARNING;
9789
64c86530 9790 ip_msdp_show_sa_detail(vrf->info, vty, uj);
977d71cc 9791
d62a17ae 9792 return CMD_SUCCESS;
977d71cc 9793}
9794
a25de56b
DS
9795DEFUN (show_ip_msdp_sa_detail_vrf_all,
9796 show_ip_msdp_sa_detail_vrf_all_cmd,
9797 "show ip msdp vrf all sa detail [json]",
9798 SHOW_STR
9799 IP_STR
9800 MSDP_STR
9801 VRF_CMD_HELP_STR
9802 "MSDP active-source information\n"
9803 "Detailed output\n"
f5da2cc2 9804 JSON_STR)
a25de56b 9805{
9f049418 9806 bool uj = use_json(argc, argv);
a25de56b
DS
9807 struct vrf *vrf;
9808 bool first = true;
9809
9810 if (uj)
9811 vty_out(vty, "{ ");
a2addae8 9812 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
a25de56b
DS
9813 if (uj) {
9814 if (!first)
9815 vty_out(vty, ", ");
9816 vty_out(vty, " \"%s\": ", vrf->name);
9817 first = false;
9818 } else
9819 vty_out(vty, "VRF: %s\n", vrf->name);
9820 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9821 }
9822 if (uj)
9823 vty_out(vty, "}\n");
9824
9825 return CMD_SUCCESS;
9826}
9827
64c86530 9828static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
088f1098 9829 const char *addr, bool uj)
977d71cc 9830{
d62a17ae 9831 struct listnode *sanode;
9832 struct pim_msdp_sa *sa;
9833 char src_str[INET_ADDRSTRLEN];
9834 char grp_str[INET_ADDRSTRLEN];
9835 json_object *json = NULL;
977d71cc 9836
d62a17ae 9837 if (uj) {
9838 json = json_object_new_object();
9839 }
977d71cc 9840
02a16316 9841 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9842 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9843 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9844 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
9845 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9846 uj, json);
9847 }
9848 }
977d71cc 9849
d62a17ae 9850 if (uj) {
9d303b37
DL
9851 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9852 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9853 json_object_free(json);
9854 }
977d71cc 9855}
9856
64c86530 9857static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
088f1098 9858 const char *src, const char *grp, bool uj)
977d71cc 9859{
d62a17ae 9860 struct listnode *sanode;
9861 struct pim_msdp_sa *sa;
9862 char src_str[INET_ADDRSTRLEN];
9863 char grp_str[INET_ADDRSTRLEN];
9864 json_object *json = NULL;
977d71cc 9865
d62a17ae 9866 if (uj) {
9867 json = json_object_new_object();
9868 }
977d71cc 9869
02a16316 9870 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 9871 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9872 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9873 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
9874 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9875 uj, json);
9876 }
9877 }
977d71cc 9878
d62a17ae 9879 if (uj) {
9d303b37
DL
9880 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9881 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 9882 json_object_free(json);
9883 }
977d71cc 9884}
9885
9886DEFUN (show_ip_msdp_sa_sg,
9887 show_ip_msdp_sa_sg_cmd,
20a7e5fd 9888 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
977d71cc 9889 SHOW_STR
9890 IP_STR
9891 MSDP_STR
f02d59db 9892 VRF_CMD_HELP_STR
977d71cc 9893 "MSDP active-source information\n"
9894 "source or group ip\n"
a957a05b 9895 "group ip\n"
f5da2cc2 9896 JSON_STR)
977d71cc 9897{
9f049418 9898 bool uj = use_json(argc, argv);
02a16316 9899 struct vrf *vrf;
c68ba0d7 9900 int idx = 2;
02a16316
DS
9901
9902 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9903
9904 if (!vrf)
9905 return CMD_WARNING;
9906
d62a17ae 9907 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
9908 : NULL;
9909 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
9910 ? argv[idx]->arg
9911 : NULL;
9ea49d61 9912
d62a17ae 9913 if (src_ip && grp_ip)
64c86530 9914 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
d62a17ae 9915 else if (src_ip)
64c86530 9916 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
d62a17ae 9917 else
64c86530 9918 ip_msdp_show_sa(vrf->info, vty, uj);
3c72d654 9919
d62a17ae 9920 return CMD_SUCCESS;
3c72d654 9921}
9922
47bf9e21
DS
9923DEFUN (show_ip_msdp_sa_sg_vrf_all,
9924 show_ip_msdp_sa_sg_vrf_all_cmd,
9925 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
9926 SHOW_STR
9927 IP_STR
9928 MSDP_STR
9929 VRF_CMD_HELP_STR
9930 "MSDP active-source information\n"
9931 "source or group ip\n"
9932 "group ip\n"
9933 JSON_STR)
9934{
9f049418 9935 bool uj = use_json(argc, argv);
47bf9e21
DS
9936 struct vrf *vrf;
9937 bool first = true;
9938 int idx = 2;
9939
9940 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
996c9314 9941 : NULL;
47bf9e21 9942 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
996c9314
LB
9943 ? argv[idx]->arg
9944 : NULL;
47bf9e21
DS
9945
9946 if (uj)
9947 vty_out(vty, "{ ");
a2addae8 9948 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
47bf9e21
DS
9949 if (uj) {
9950 if (!first)
9951 vty_out(vty, ", ");
9952 vty_out(vty, " \"%s\": ", vrf->name);
9953 first = false;
9954 } else
9955 vty_out(vty, "VRF: %s\n", vrf->name);
9956
9957 if (src_ip && grp_ip)
9958 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
9959 else if (src_ip)
9960 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
9961 else
9962 ip_msdp_show_sa(vrf->info, vty, uj);
9963 }
9964 if (uj)
9965 vty_out(vty, "}\n");
9966
9967 return CMD_SUCCESS;
9968}
9969
f1e2901a
AK
9970struct pim_sg_cache_walk_data {
9971 struct vty *vty;
9972 json_object *json;
9973 json_object *json_group;
9974 struct in_addr addr;
9975 bool addr_match;
9976};
9977
9978static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
9979 struct pim_sg_cache_walk_data *cwd)
9980{
9981 struct vty *vty = cwd->vty;
9982 json_object *json = cwd->json;
9983 char src_str[INET_ADDRSTRLEN];
9984 char grp_str[INET_ADDRSTRLEN];
9985 json_object *json_row;
2951a7a4 9986 bool installed = (vxlan_sg->up) ? true : false;
f1e2901a
AK
9987 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
9988 const char *oif_name;
9989
9990 if (pim_vxlan_is_orig_mroute(vxlan_sg))
9991 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
9992 else
9993 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
9994
9995 if (cwd->addr_match && (vxlan_sg->sg.src.s_addr != cwd->addr.s_addr) &&
9996 (vxlan_sg->sg.grp.s_addr != cwd->addr.s_addr)) {
9997 return;
9998 }
9999 pim_inet4_dump("<src?>", vxlan_sg->sg.src, src_str, sizeof(src_str));
10000 pim_inet4_dump("<grp?>", vxlan_sg->sg.grp, grp_str, sizeof(grp_str));
10001 if (json) {
10002 json_object_object_get_ex(json, grp_str, &cwd->json_group);
10003
10004 if (!cwd->json_group) {
10005 cwd->json_group = json_object_new_object();
10006 json_object_object_add(json, grp_str,
10007 cwd->json_group);
10008 }
10009
10010 json_row = json_object_new_object();
10011 json_object_string_add(json_row, "source", src_str);
10012 json_object_string_add(json_row, "group", grp_str);
10013 json_object_string_add(json_row, "input", iif_name);
10014 json_object_string_add(json_row, "output", oif_name);
10015 if (installed)
10016 json_object_boolean_true_add(json_row, "installed");
10017 else
10018 json_object_boolean_false_add(json_row, "installed");
10019 json_object_object_add(cwd->json_group, src_str, json_row);
10020 } else {
10021 vty_out(vty, "%-15s %-15s %-15s %-15s %-5s\n",
10022 src_str, grp_str, iif_name, oif_name,
10023 installed?"I":"");
10024 }
10025}
10026
10027static void pim_show_vxlan_sg_hash_entry(struct hash_backet *backet, void *arg)
10028{
10029 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)backet->data,
10030 (struct pim_sg_cache_walk_data *)arg);
10031}
10032
10033static void pim_show_vxlan_sg(struct pim_instance *pim,
10034 struct vty *vty, bool uj)
10035{
10036 json_object *json = NULL;
10037 struct pim_sg_cache_walk_data cwd;
10038
10039 if (uj) {
10040 json = json_object_new_object();
10041 } else {
10042 vty_out(vty, "Codes: I -> installed\n");
10043 vty_out(vty,
10044 "Source Group Input Output Flags\n");
10045 }
10046
10047 memset(&cwd, 0, sizeof(cwd));
10048 cwd.vty = vty;
10049 cwd.json = json;
10050 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10051
10052 if (uj) {
10053 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10054 json, JSON_C_TO_STRING_PRETTY));
10055 json_object_free(json);
10056 }
10057}
10058
10059static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
10060 struct vty *vty, char *addr_str, bool uj)
10061{
10062 json_object *json = NULL;
10063 struct pim_sg_cache_walk_data cwd;
10064 int result = 0;
10065
10066 memset(&cwd, 0, sizeof(cwd));
10067 result = inet_pton(AF_INET, addr_str, &cwd.addr);
10068 if (result <= 0) {
10069 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
10070 errno, safe_strerror(errno));
10071 return;
10072 }
10073
10074 if (uj) {
10075 json = json_object_new_object();
10076 } else {
10077 vty_out(vty, "Codes: I -> installed\n");
10078 vty_out(vty,
10079 "Source Group Input Output Flags\n");
10080 }
10081
10082 cwd.vty = vty;
10083 cwd.json = json;
2951a7a4 10084 cwd.addr_match = true;
f1e2901a
AK
10085 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10086
10087 if (uj) {
10088 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10089 json, JSON_C_TO_STRING_PRETTY));
10090 json_object_free(json);
10091 }
10092}
10093
10094static void pim_show_vxlan_sg_one(struct pim_instance *pim,
10095 struct vty *vty, char *src_str, char *grp_str, bool uj)
10096{
10097 json_object *json = NULL;
10098 struct prefix_sg sg;
10099 int result = 0;
10100 struct pim_vxlan_sg *vxlan_sg;
10101 const char *iif_name;
10102 bool installed;
10103 const char *oif_name;
10104
10105 result = inet_pton(AF_INET, src_str, &sg.src);
10106 if (result <= 0) {
10107 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
10108 errno, safe_strerror(errno));
10109 return;
10110 }
10111 result = inet_pton(AF_INET, grp_str, &sg.grp);
10112 if (result <= 0) {
10113 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
10114 errno, safe_strerror(errno));
10115 return;
10116 }
10117
10118 sg.family = AF_INET;
10119 sg.prefixlen = IPV4_MAX_BITLEN;
10120 if (uj)
10121 json = json_object_new_object();
10122
10123 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
10124 if (vxlan_sg) {
2951a7a4 10125 installed = (vxlan_sg->up) ? true : false;
f1e2901a
AK
10126 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10127
10128 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10129 oif_name =
10130 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10131 else
10132 oif_name =
10133 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10134
10135 if (uj) {
10136 json_object_string_add(json, "source", src_str);
10137 json_object_string_add(json, "group", grp_str);
10138 json_object_string_add(json, "input", iif_name);
10139 json_object_string_add(json, "output", oif_name);
10140 if (installed)
10141 json_object_boolean_true_add(json, "installed");
10142 else
10143 json_object_boolean_false_add(json,
10144 "installed");
10145 } else {
10146 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
10147 vty_out(vty, " Input : %s\n", iif_name);
10148 vty_out(vty, " Output : %s\n", oif_name);
10149 vty_out(vty, " installed : %s\n",
10150 installed?"yes":"no");
10151 }
10152 }
10153
10154 if (uj) {
10155 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10156 json, JSON_C_TO_STRING_PRETTY));
10157 json_object_free(json);
10158 }
10159}
10160
10161DEFUN (show_ip_pim_vxlan_sg,
10162 show_ip_pim_vxlan_sg_cmd,
10163 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10164 SHOW_STR
10165 IP_STR
10166 PIM_STR
10167 VRF_CMD_HELP_STR
10168 "VxLAN BUM groups\n"
10169 "source or group ip\n"
10170 "group ip\n"
10171 JSON_STR)
10172{
10173 bool uj = use_json(argc, argv);
10174 struct vrf *vrf;
10175 int idx = 2;
10176
10177 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10178
10179 if (!vrf)
10180 return CMD_WARNING;
10181
10182 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
10183 argv[idx++]->arg:NULL;
10184 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
10185 argv[idx]->arg:NULL;
10186
10187 if (src_ip && grp_ip)
10188 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
10189 else if (src_ip)
10190 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
10191 else
10192 pim_show_vxlan_sg(vrf->info, vty, uj);
10193
10194 return CMD_SUCCESS;
10195}
10196
10197static void pim_show_vxlan_sg_work(struct pim_instance *pim,
10198 struct vty *vty, bool uj)
10199{
10200 json_object *json = NULL;
10201 struct pim_sg_cache_walk_data cwd;
10202 struct listnode *node;
10203 struct pim_vxlan_sg *vxlan_sg;
10204
10205 if (uj) {
10206 json = json_object_new_object();
10207 } else {
10208 vty_out(vty, "Codes: I -> installed\n");
10209 vty_out(vty,
10210 "Source Group Input Flags\n");
10211 }
10212
10213 memset(&cwd, 0, sizeof(cwd));
10214 cwd.vty = vty;
10215 cwd.json = json;
10216 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
10217 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
10218
10219 if (uj) {
10220 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10221 json, JSON_C_TO_STRING_PRETTY));
10222 json_object_free(json);
10223 }
10224}
10225
10226DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
10227 show_ip_pim_vxlan_sg_work_cmd,
10228 "show ip pim [vrf NAME] vxlan-work [json]",
10229 SHOW_STR
10230 IP_STR
10231 PIM_STR
10232 VRF_CMD_HELP_STR
10233 "VxLAN work list\n"
10234 JSON_STR)
10235{
10236 bool uj = use_json(argc, argv);
10237 struct vrf *vrf;
10238 int idx = 2;
10239
10240 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10241
10242 if (!vrf)
10243 return CMD_WARNING;
10244
10245 pim_show_vxlan_sg_work(vrf->info, vty, uj);
10246
10247 return CMD_SUCCESS;
10248}
10249
7c85225c
AK
10250DEFUN_HIDDEN (no_ip_pim_mlag,
10251 no_ip_pim_mlag_cmd,
10252 "no ip pim mlag",
10253 NO_STR
10254 IP_STR
10255 PIM_STR
10256 "MLAG\n")
10257{
10258 struct in_addr addr;
10259
10260 addr.s_addr = 0;
2951a7a4
QY
10261 pim_vxlan_mlag_update(true/*mlag_enable*/,
10262 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY,
7c85225c
AK
10263 NULL/*peerlink*/, &addr);
10264
10265 return CMD_SUCCESS;
10266}
10267
10268DEFUN_HIDDEN (ip_pim_mlag,
10269 ip_pim_mlag_cmd,
10270 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10271 IP_STR
10272 PIM_STR
10273 "MLAG\n"
10274 "peerlink sub interface\n"
10275 "MLAG role\n"
10276 "MLAG role primary\n"
10277 "MLAG role secondary\n"
10278 "peer session state\n"
10279 "peer session state up\n"
10280 "peer session state down\n"
10281 "configure PIP\n"
10282 "unique ip address\n")
10283{
10284 struct interface *ifp;
10285 const char *peerlink;
10286 uint32_t role;
10287 int idx;
10288 bool peer_state;
10289 int result;
10290 struct in_addr reg_addr;
10291
10292 idx = 3;
10293 peerlink = argv[idx]->arg;
a36898e7 10294 ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
7c85225c
AK
10295 if (!ifp) {
10296 vty_out(vty, "No such interface name %s\n", peerlink);
10297 return CMD_WARNING;
10298 }
10299
10300 idx += 2;
10301 if (!strcmp(argv[idx]->arg, "primary")) {
10302 role = PIM_VXLAN_MLAG_ROLE_PRIMARY;
10303 } else if (!strcmp(argv[idx]->arg, "secondary")) {
10304 role = PIM_VXLAN_MLAG_ROLE_SECONDARY;
10305 } else {
10306 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
10307 return CMD_WARNING;
10308 }
10309
10310 idx += 2;
10311 if (!strcmp(argv[idx]->arg, "up")) {
2951a7a4 10312 peer_state = true;
7c85225c 10313 } else if (strcmp(argv[idx]->arg, "down")) {
2951a7a4 10314 peer_state = false;
7c85225c
AK
10315 } else {
10316 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
10317 return CMD_WARNING;
10318 }
10319
10320 idx += 2;
10321 result = inet_pton(AF_INET, argv[idx]->arg, &reg_addr);
10322 if (result <= 0) {
10323 vty_out(vty, "%% Bad reg address %s: errno=%d: %s\n",
10324 argv[idx]->arg,
10325 errno, safe_strerror(errno));
10326 return CMD_WARNING_CONFIG_FAILED;
10327 }
2951a7a4 10328 pim_vxlan_mlag_update(true, peer_state, role, ifp, &reg_addr);
7c85225c
AK
10329
10330 return CMD_SUCCESS;
10331}
10332
c68ba0d7 10333void pim_cmd_init(void)
12e41d03 10334{
d62a17ae 10335 install_node(&interface_node,
10336 pim_interface_config_write); /* INTERFACE_NODE */
10337 if_cmd_init();
10338
10339 install_node(&debug_node, pim_debug_config_write);
10340
70fd22bd
DS
10341 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
10342
d62a17ae 10343 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
9ecb7b77 10344 install_element(VRF_NODE, &ip_pim_rp_cmd);
d62a17ae 10345 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
9ecb7b77 10346 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
d62a17ae 10347 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
4f9f3925 10348 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
d62a17ae 10349 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
4f9f3925 10350 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
d62a17ae 10351 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
4f9f3925 10352 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
d62a17ae 10353 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
4f9f3925 10354 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
d62a17ae 10355 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
4f9f3925 10356 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
d62a17ae 10357 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
4f9f3925 10358 install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
d62a17ae 10359 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
4f9f3925 10360 install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
d62a17ae 10361 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
4f9f3925 10362 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
d62a17ae 10363 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 10364 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 10365 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
4f9f3925 10366 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
d62a17ae 10367 install_element(CONFIG_NODE,
10368 &no_ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 10369 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 10370 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
4f9f3925 10371 install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
d62a17ae 10372 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
4f9f3925 10373 install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
d62a17ae 10374 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
4f9f3925 10375 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
cc14df13
DS
10376 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
10377 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
d62a17ae 10378 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
4f9f3925 10379 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
cc14df13
DS
10380 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
10381 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
d62a17ae 10382 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
4f9f3925 10383 install_element(VRF_NODE, &ip_pim_packets_cmd);
d62a17ae 10384 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
4f9f3925 10385 install_element(VRF_NODE, &no_ip_pim_packets_cmd);
d62a17ae 10386 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
4f9f3925 10387 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
d62a17ae 10388 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
4f9f3925 10389 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
d62a17ae 10390 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
4f9f3925 10391 install_element(VRF_NODE, &ip_ssmpingd_cmd);
d62a17ae 10392 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
4f9f3925 10393 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
d62a17ae 10394 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
4f9f3925 10395 install_element(VRF_NODE, &ip_msdp_peer_cmd);
d62a17ae 10396 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
4f9f3925 10397 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
d62a17ae 10398 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
4f9f3925 10399 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
d62a17ae 10400 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
4f9f3925 10401 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
d62a17ae 10402 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
4f9f3925 10403 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
d62a17ae 10404 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
4f9f3925 10405 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
7c85225c
AK
10406 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
10407 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
d62a17ae 10408
10409 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
10410 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
10411 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
10412 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
10413 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
10414 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
10415 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
10416 install_element(INTERFACE_NODE,
10417 &interface_no_ip_igmp_query_interval_cmd);
10418 install_element(INTERFACE_NODE,
10419 &interface_ip_igmp_query_max_response_time_cmd);
10420 install_element(INTERFACE_NODE,
10421 &interface_no_ip_igmp_query_max_response_time_cmd);
10422 install_element(INTERFACE_NODE,
10423 &interface_ip_igmp_query_max_response_time_dsec_cmd);
10424 install_element(INTERFACE_NODE,
10425 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
59115451
SP
10426 install_element(INTERFACE_NODE,
10427 &interface_ip_igmp_last_member_query_count_cmd);
10428 install_element(INTERFACE_NODE,
10429 &interface_no_ip_igmp_last_member_query_count_cmd);
10430 install_element(INTERFACE_NODE,
10431 &interface_ip_igmp_last_member_query_interval_cmd);
10432 install_element(INTERFACE_NODE,
10433 &interface_no_ip_igmp_last_member_query_interval_cmd);
414d885a 10434 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
d62a17ae 10435 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
10436 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
10437 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
10438 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
2f5e937c 10439 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
10440 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
d62a17ae 10441 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
10442 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
10443 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
10444 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
b0f525a8
QY
10445 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
10446 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
6741a5bb 10447 install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
d62a17ae 10448
10449 // Static mroutes NEB
10450 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
d62a17ae 10451 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
d62a17ae 10452
10453 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
a25de56b 10454 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
d62a17ae 10455 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
a25de56b 10456 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
d62a17ae 10457 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
a25de56b 10458 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
d62a17ae 10459 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
10460 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
10461 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
21313cbf 10462 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
d62a17ae 10463 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
10464 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
10465 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
10466 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
10467 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
10468 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
a25de56b 10469 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
d62a17ae 10470 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
a25de56b 10471 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
87b7cd5b 10472 install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
d62a17ae 10473 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
10474 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
a25de56b 10475 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
d62a17ae 10476 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
a25de56b 10477 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
d62a17ae 10478 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
10479 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
a25de56b 10480 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
d62a17ae 10481 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
a25de56b 10482 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
5c9a72ef 10483 install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
d62a17ae 10484 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
10485 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
10486 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
a25de56b 10487 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
256392eb 10488 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
d62a17ae 10489 install_element(VIEW_NODE, &show_ip_multicast_cmd);
a25de56b 10490 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
d62a17ae 10491 install_element(VIEW_NODE, &show_ip_mroute_cmd);
b283a4ca 10492 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
d62a17ae 10493 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
5c3aac90 10494 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
468b6f44
SP
10495 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
10496 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
d62a17ae 10497 install_element(VIEW_NODE, &show_ip_rib_cmd);
10498 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
10499 install_element(VIEW_NODE, &show_debugging_pim_cmd);
10500 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
10501 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
321295c1 10502 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
0d1a4e24 10503 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
415f6350 10504 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
d62a17ae 10505
cd333cf9 10506 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
d62a17ae 10507 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
10508 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
10509 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
10510 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
10511 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
10512 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
415f6350 10513 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
d62a17ae 10514
10515 install_element(ENABLE_NODE, &debug_igmp_cmd);
10516 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
10517 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
10518 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
10519 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
10520 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
10521 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
10522 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
10523 install_element(ENABLE_NODE, &debug_mroute_cmd);
10524 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
10525 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
10526 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
10527 install_element(ENABLE_NODE, &debug_pim_static_cmd);
10528 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
d62a17ae 10529 install_element(ENABLE_NODE, &debug_pim_cmd);
10530 install_element(ENABLE_NODE, &no_debug_pim_cmd);
40f1f31b
DS
10531 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
10532 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
3d225d48
DS
10533 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
10534 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 10535 install_element(ENABLE_NODE, &debug_pim_events_cmd);
10536 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
10537 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
10538 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
10539 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
10540 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
10541 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
10542 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
10543 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
10544 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
10545 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
10546 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 10547 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
10548 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
10549 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
10550 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
36b5b98f
SK
10551 install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
10552 install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
4d913fa6
AK
10553 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
10554 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 10555 install_element(ENABLE_NODE, &debug_msdp_cmd);
10556 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
d62a17ae 10557 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
10558 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
d62a17ae 10559 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
10560 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
10561 install_element(ENABLE_NODE, &debug_mtrace_cmd);
10562 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
09524ccf 10563 install_element(ENABLE_NODE, &debug_bsm_cmd);
10564 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
d62a17ae 10565
10566 install_element(CONFIG_NODE, &debug_igmp_cmd);
10567 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
10568 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
10569 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
10570 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
10571 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
10572 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
10573 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
10574 install_element(CONFIG_NODE, &debug_mroute_cmd);
10575 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
10576 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
10577 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
35a12720
MS
10578 install_element(CONFIG_NODE, &debug_pim_static_cmd);
10579 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
d62a17ae 10580 install_element(CONFIG_NODE, &debug_pim_cmd);
10581 install_element(CONFIG_NODE, &no_debug_pim_cmd);
40f1f31b
DS
10582 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
10583 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
3d225d48
DS
10584 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
10585 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
d62a17ae 10586 install_element(CONFIG_NODE, &debug_pim_events_cmd);
10587 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
10588 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
10589 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
10590 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
10591 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
10592 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
10593 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 10594 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
10595 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
10596 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
10597 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
4d913fa6
AK
10598 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
10599 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
d62a17ae 10600 install_element(CONFIG_NODE, &debug_msdp_cmd);
10601 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
d62a17ae 10602 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
10603 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
d62a17ae 10604 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
10605 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
4d9ad5dc
MS
10606 install_element(CONFIG_NODE, &debug_mtrace_cmd);
10607 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
09524ccf 10608 install_element(CONFIG_NODE, &debug_bsm_cmd);
10609 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
02a16316 10610
d62a17ae 10611 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
02a16316 10612 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
d62a17ae 10613 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
1b973cb7 10614 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
d62a17ae 10615 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
02a16316 10616 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
d62a17ae 10617 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
02a16316 10618 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
d62a17ae 10619 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
a25de56b 10620 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
d62a17ae 10621 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
a25de56b 10622 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
d62a17ae 10623 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
47bf9e21 10624 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
d62a17ae 10625 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
a25de56b 10626 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
d62a17ae 10627 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
10628 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
f1e2901a
AK
10629 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
10630 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
d62a17ae 10631 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
10632 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
16c926c8 10633 /* Install BSM command */
10634 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
10635 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
10636 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
10637 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
d62a17ae 10638 /* Install BFD command */
10639 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
10640 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
10641 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
64dc4b2d 10642#if HAVE_BFDD == 0
d62a17ae 10643 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
64dc4b2d 10644#endif /* !HAVE_BFDD */
12e41d03 10645}