]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
pimd: Ensure that we properly shutdown threads on start failure
[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"
12e41d03
DL
31
32#include "pimd.h"
9867746a 33#include "pim_mroute.h"
12e41d03
DL
34#include "pim_cmd.h"
35#include "pim_iface.h"
36#include "pim_vty.h"
37#include "pim_mroute.h"
38#include "pim_str.h"
39#include "pim_igmp.h"
40#include "pim_igmpv3.h"
41#include "pim_sock.h"
42#include "pim_time.h"
43#include "pim_util.h"
44#include "pim_oil.h"
45#include "pim_neighbor.h"
46#include "pim_pim.h"
47#include "pim_ifchannel.h"
48#include "pim_hello.h"
49#include "pim_msg.h"
50#include "pim_upstream.h"
51#include "pim_rpf.h"
52#include "pim_macro.h"
53#include "pim_ssmpingd.h"
54#include "pim_zebra.h"
6250610a 55#include "pim_static.h"
a920d6e7 56#include "pim_rp.h"
05b0d0d0 57#include "pim_zlookup.h"
2a333e0f 58#include "pim_msdp.h"
15a5dafe 59#include "pim_ssm.h"
cba44481 60#include "pim_nht.h"
ba4eb1bc
CS
61#include "pim_bfd.h"
62#include "bfd.h"
12e41d03
DL
63
64static struct cmd_node pim_global_node = {
d62a17ae 65 PIM_NODE, "", 1 /* vtysh ? yes */
12e41d03
DL
66};
67
68static struct cmd_node interface_node = {
d62a17ae 69 INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
12e41d03
DL
70};
71
d62a17ae 72static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
eb7a976a 73
02a16316
DS
74static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
75 const int argc, int *idx)
76{
77 struct vrf *vrf;
78
79 if (argv_find(argv, argc, "NAME", idx))
80 vrf = vrf_lookup_by_name(argv[*idx]->arg);
81 else
82 vrf = vrf_lookup_by_id(VRF_DEFAULT);
83
84 if (!vrf)
85 vty_out(vty, "Specified VRF: %s does not exist\n",
86 argv[*idx]->arg);
87
88 return vrf;
89}
90
12e41d03
DL
91static void pim_if_membership_clear(struct interface *ifp)
92{
d62a17ae 93 struct pim_interface *pim_ifp;
12e41d03 94
d62a17ae 95 pim_ifp = ifp->info;
96 zassert(pim_ifp);
12e41d03 97
d62a17ae 98 if (PIM_IF_TEST_PIM(pim_ifp->options)
99 && PIM_IF_TEST_IGMP(pim_ifp->options)) {
100 return;
101 }
12e41d03 102
d62a17ae 103 pim_ifchannel_membership_clear(ifp);
12e41d03
DL
104}
105
106/*
107 When PIM is disabled on interface, IGMPv3 local membership
108 information is not injected into PIM interface state.
109
110 The function pim_if_membership_refresh() fetches all IGMPv3 local
111 membership information into PIM. It is intented to be called
112 whenever PIM is enabled on the interface in order to collect missed
113 local membership information.
114 */
115static void pim_if_membership_refresh(struct interface *ifp)
116{
d62a17ae 117 struct pim_interface *pim_ifp;
118 struct listnode *sock_node;
119 struct igmp_sock *igmp;
12e41d03 120
d62a17ae 121 pim_ifp = ifp->info;
122 zassert(pim_ifp);
12e41d03 123
d62a17ae 124 if (!PIM_IF_TEST_PIM(pim_ifp->options))
125 return;
126 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
127 return;
12e41d03 128
d62a17ae 129 /*
130 First clear off membership from all PIM (S,G) entries on the
131 interface
132 */
12e41d03 133
d62a17ae 134 pim_ifchannel_membership_clear(ifp);
12e41d03 135
d62a17ae 136 /*
137 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
138 the interface
139 */
12e41d03 140
d62a17ae 141 /* scan igmp sockets */
142 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
143 struct listnode *grpnode;
144 struct igmp_group *grp;
12e41d03 145
d62a17ae 146 /* scan igmp groups */
147 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
148 grp)) {
149 struct listnode *srcnode;
150 struct igmp_source *src;
69283639 151
d62a17ae 152 /* scan group sources */
153 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
154 srcnode, src)) {
155
156 if (IGMP_SOURCE_TEST_FORWARDING(
157 src->source_flags)) {
158 struct prefix_sg sg;
159
160 memset(&sg, 0,
161 sizeof(struct prefix_sg));
162 sg.src = src->source_addr;
163 sg.grp = grp->group_addr;
164 pim_ifchannel_local_membership_add(ifp,
165 &sg);
166 }
12e41d03 167
d62a17ae 168 } /* scan group sources */
169 } /* scan igmp groups */
170 } /* scan igmp sockets */
12e41d03 171
d62a17ae 172 /*
173 Finally delete every PIM (S,G) entry lacking all state info
174 */
12e41d03 175
d62a17ae 176 pim_ifchannel_delete_on_noinfo(ifp);
12e41d03
DL
177}
178
64c86530 179static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
12e41d03 180{
d62a17ae 181 struct pim_interface *pim_ifp;
182 struct pim_ifchannel *ch;
183 struct listnode *ch_node;
184 struct in_addr ifaddr;
185 time_t now;
186
187 now = pim_time_monotonic_sec();
188
189 vty_out(vty,
190 "Interface Address Source Group State Winner Uptime Timer\n");
191
f88df3a6 192 for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
d62a17ae 193 char ch_src_str[INET_ADDRSTRLEN];
194 char ch_grp_str[INET_ADDRSTRLEN];
195 char winner_str[INET_ADDRSTRLEN];
196 char uptime[10];
197 char timer[10];
198
199 pim_ifp = ch->interface->info;
200
201 if (!pim_ifp)
202 continue;
203
204 ifaddr = pim_ifp->primary_address;
205
206 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
207 sizeof(ch_src_str));
208 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
209 sizeof(ch_grp_str));
210 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
211 sizeof(winner_str));
212
213 pim_time_uptime(uptime, sizeof(uptime),
214 now - ch->ifassert_creation);
215 pim_time_timer_to_mmss(timer, sizeof(timer),
216 ch->t_ifassert_timer);
217
218 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
219 ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
220 ch_grp_str,
221 pim_ifchannel_ifassert_name(ch->ifassert_state),
222 winner_str, uptime, timer);
223 } /* scan interface channels */
12e41d03
DL
224}
225
64c86530 226static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
12e41d03 227{
d62a17ae 228 struct pim_interface *pim_ifp;
229 struct listnode *ch_node;
230 struct pim_ifchannel *ch;
231 struct in_addr ifaddr;
232
233 vty_out(vty,
234 "CA: CouldAssert\n"
235 "ECA: Evaluate CouldAssert\n"
236 "ATD: AssertTrackingDesired\n"
237 "eATD: Evaluate AssertTrackingDesired\n\n");
238
239 vty_out(vty,
240 "Interface Address Source Group CA eCA ATD eATD\n");
241
f88df3a6 242 for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
d62a17ae 243 pim_ifp = ch->interface->info;
244
245 if (!pim_ifp)
246 continue;
247
248 ifaddr = pim_ifp->primary_address;
249
250 char ch_src_str[INET_ADDRSTRLEN];
251 char ch_grp_str[INET_ADDRSTRLEN];
252
253 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
254 sizeof(ch_src_str));
255 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
256 sizeof(ch_grp_str));
257 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
258 ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
259 ch_grp_str,
260 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
261 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
262 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags)
263 ? "yes"
264 : "no",
265 pim_macro_assert_tracking_desired_eval(ch) ? "yes"
266 : "no");
267 } /* scan interface channels */
12e41d03
DL
268}
269
64c86530 270static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
12e41d03 271{
d62a17ae 272 struct pim_interface *pim_ifp;
273 struct listnode *ch_node;
274 struct pim_ifchannel *ch;
275 struct in_addr ifaddr;
ea4a71fc 276
d62a17ae 277 vty_out(vty,
278 "Interface Address Source Group RPT Pref Metric Address \n");
12e41d03 279
f88df3a6 280 for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
d62a17ae 281 pim_ifp = ch->interface->info;
12e41d03 282
d62a17ae 283 if (!pim_ifp)
284 continue;
12e41d03 285
d62a17ae 286 ifaddr = pim_ifp->primary_address;
12e41d03 287
d62a17ae 288 char ch_src_str[INET_ADDRSTRLEN];
289 char ch_grp_str[INET_ADDRSTRLEN];
290 char addr_str[INET_ADDRSTRLEN];
291 struct pim_assert_metric am;
ea4a71fc 292
d62a17ae 293 am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
294 pim_ifp->primary_address);
ea4a71fc 295
d62a17ae 296 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
297 sizeof(ch_src_str));
298 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
299 sizeof(ch_grp_str));
300 pim_inet4_dump("<addr?>", am.ip_address, addr_str,
301 sizeof(addr_str));
ea4a71fc 302
d62a17ae 303 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
304 ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
305 ch_grp_str, am.rpt_bit_flag ? "yes" : "no",
306 am.metric_preference, am.route_metric, addr_str);
307 } /* scan interface channels */
12e41d03
DL
308}
309
64c86530
DS
310static void pim_show_assert_winner_metric(struct pim_instance *pim,
311 struct vty *vty)
12e41d03 312{
d62a17ae 313 struct pim_interface *pim_ifp;
314 struct listnode *ch_node;
315 struct pim_ifchannel *ch;
316 struct in_addr ifaddr;
317
318 vty_out(vty,
319 "Interface Address Source Group RPT Pref Metric Address \n");
320
f88df3a6 321 for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
d62a17ae 322 pim_ifp = ch->interface->info;
12e41d03 323
d62a17ae 324 if (!pim_ifp)
325 continue;
12e41d03 326
d62a17ae 327 ifaddr = pim_ifp->primary_address;
12e41d03 328
d62a17ae 329 char ch_src_str[INET_ADDRSTRLEN];
330 char ch_grp_str[INET_ADDRSTRLEN];
331 char addr_str[INET_ADDRSTRLEN];
332 struct pim_assert_metric *am;
333 char pref_str[5];
334 char metr_str[7];
12e41d03 335
d62a17ae 336 am = &ch->ifassert_winner_metric;
12e41d03 337
d62a17ae 338 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
339 sizeof(ch_src_str));
340 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
341 sizeof(ch_grp_str));
342 pim_inet4_dump("<addr?>", am->ip_address, addr_str,
343 sizeof(addr_str));
ea4a71fc 344
d62a17ae 345 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
346 snprintf(pref_str, sizeof(pref_str), "INFI");
347 else
348 snprintf(pref_str, sizeof(pref_str), "%4u",
349 am->metric_preference);
ea4a71fc 350
d62a17ae 351 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
352 snprintf(metr_str, sizeof(metr_str), "INFI");
353 else
354 snprintf(metr_str, sizeof(metr_str), "%6u",
355 am->route_metric);
ea4a71fc 356
d62a17ae 357 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
358 ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
359 ch_grp_str, am->rpt_bit_flag ? "yes" : "no", pref_str,
360 metr_str, addr_str);
361 } /* scan interface channels */
12e41d03
DL
362}
363
d62a17ae 364static void json_object_pim_ifp_add(struct json_object *json,
365 struct interface *ifp)
e775c0a4 366{
d62a17ae 367 struct pim_interface *pim_ifp;
e775c0a4 368
d62a17ae 369 pim_ifp = ifp->info;
370 json_object_string_add(json, "name", ifp->name);
371 json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
372 json_object_string_add(json, "address",
373 inet_ntoa(pim_ifp->primary_address));
374 json_object_int_add(json, "index", ifp->ifindex);
e775c0a4 375
d62a17ae 376 if (if_is_multicast(ifp))
377 json_object_boolean_true_add(json, "flagMulticast");
e775c0a4 378
d62a17ae 379 if (if_is_broadcast(ifp))
380 json_object_boolean_true_add(json, "flagBroadcast");
e775c0a4 381
d62a17ae 382 if (ifp->flags & IFF_ALLMULTI)
383 json_object_boolean_true_add(json, "flagAllMulticast");
e775c0a4 384
d62a17ae 385 if (ifp->flags & IFF_PROMISC)
386 json_object_boolean_true_add(json, "flagPromiscuous");
e775c0a4 387
d62a17ae 388 if (PIM_IF_IS_DELETED(ifp))
389 json_object_boolean_true_add(json, "flagDeleted");
e775c0a4 390
d62a17ae 391 if (pim_if_lan_delay_enabled(ifp))
392 json_object_boolean_true_add(json, "lanDelayEnabled");
e775c0a4
DW
393}
394
64c86530 395static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
f88df3a6 396 u_char uj)
12e41d03 397{
d62a17ae 398 struct pim_interface *pim_ifp;
399 struct listnode *ch_node;
400 struct pim_ifchannel *ch;
401 enum json_type type;
402 json_object *json = NULL;
403 json_object *json_iface = NULL;
404 json_object *json_row = NULL;
405 json_object *json_tmp = NULL;
406
407 json = json_object_new_object();
408
f88df3a6 409 for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
d62a17ae 410
411 pim_ifp = ch->interface->info;
412
413 if (!pim_ifp)
414 continue;
415
416 char ch_src_str[INET_ADDRSTRLEN];
417 char ch_grp_str[INET_ADDRSTRLEN];
418
419 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
420 sizeof(ch_src_str));
421 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
422 sizeof(ch_grp_str));
423
424 json_object_object_get_ex(json, ch->interface->name,
425 &json_iface);
426
427 if (!json_iface) {
428 json_iface = json_object_new_object();
429 json_object_pim_ifp_add(json_iface, ch->interface);
430 json_object_object_add(json, ch->interface->name,
431 json_iface);
432 }
433
434 json_row = json_object_new_object();
435 json_object_string_add(json_row, "source", ch_src_str);
436 json_object_string_add(json_row, "group", ch_grp_str);
437 json_object_string_add(
438 json_row, "localMembership",
439 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
440 ? "NOINFO"
441 : "INCLUDE");
442 json_object_object_add(json_iface, ch_grp_str, json_row);
443 } /* scan interface channels */
444
445 if (uj) {
9d303b37
DL
446 vty_out(vty, "%s\n", json_object_to_json_string_ext(
447 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 448 } else {
449 vty_out(vty,
450 "Interface Address Source Group Membership\n");
451
452 /*
453 * Example of the json data we are traversing
454 *
455 * {
456 * "swp3":{
457 * "name":"swp3",
458 * "state":"up",
459 * "address":"10.1.20.1",
460 * "index":5,
461 * "flagMulticast":true,
462 * "flagBroadcast":true,
463 * "lanDelayEnabled":true,
464 * "226.10.10.10":{
465 * "source":"*",
466 * "group":"226.10.10.10",
467 * "localMembership":"INCLUDE"
468 * }
469 * }
470 * }
471 */
472
473 /* foreach interface */
474 json_object_object_foreach(json, key, val)
475 {
476
477 /* Find all of the keys where the val is an object. In
478 * the example
479 * above the only one is 226.10.10.10
480 */
481 json_object_object_foreach(val, if_field_key,
482 if_field_val)
483 {
484 type = json_object_get_type(if_field_val);
485
486 if (type == json_type_object) {
487 vty_out(vty, "%-9s ", key);
488
489 json_object_object_get_ex(
490 val, "address", &json_tmp);
491 vty_out(vty, "%-15s ",
492 json_object_get_string(
493 json_tmp));
494
495 json_object_object_get_ex(if_field_val,
496 "source",
497 &json_tmp);
498 vty_out(vty, "%-15s ",
499 json_object_get_string(
500 json_tmp));
501
502 /* Group */
503 vty_out(vty, "%-15s ", if_field_key);
504
505 json_object_object_get_ex(
506 if_field_val, "localMembership",
507 &json_tmp);
508 vty_out(vty, "%-10s\n",
509 json_object_get_string(
510 json_tmp));
511 }
512 }
513 }
514 }
515
516 json_object_free(json);
517}
518
519static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp,
520 int mloop)
521{
522 vty_out(vty, "Flags\n");
523 vty_out(vty, "-----\n");
524 vty_out(vty, "All Multicast : %s\n",
525 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
526 vty_out(vty, "Broadcast : %s\n",
527 if_is_broadcast(ifp) ? "yes" : "no");
528 vty_out(vty, "Deleted : %s\n",
529 PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
530 vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
531 vty_out(vty, "Multicast : %s\n",
532 if_is_multicast(ifp) ? "yes" : "no");
533 vty_out(vty, "Multicast Loop : %d\n", mloop);
534 vty_out(vty, "Promiscuous : %s\n",
535 (ifp->flags & IFF_PROMISC) ? "yes" : "no");
536 vty_out(vty, "\n");
537 vty_out(vty, "\n");
a268493f
DW
538}
539
64c86530 540static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
c68ba0d7 541 u_char uj)
12e41d03 542{
d62a17ae 543 struct listnode *node;
544 struct interface *ifp;
545 time_t now;
546 json_object *json = NULL;
547 json_object *json_row = NULL;
548
549 now = pim_time_monotonic_sec();
550
551 if (uj)
552 json = json_object_new_object();
553 else
554 vty_out(vty,
555 "Interface State Address V Querier Query Timer Uptime\n");
556
c68ba0d7 557 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 558 struct pim_interface *pim_ifp;
559 struct listnode *sock_node;
560 struct igmp_sock *igmp;
561
562 pim_ifp = ifp->info;
563
564 if (!pim_ifp)
565 continue;
566
567 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
568 igmp)) {
569 char uptime[10];
570 char query_hhmmss[10];
571
572 pim_time_uptime(uptime, sizeof(uptime),
573 now - igmp->sock_creation);
574 pim_time_timer_to_hhmmss(query_hhmmss,
575 sizeof(query_hhmmss),
576 igmp->t_igmp_query_timer);
577
578 if (uj) {
579 json_row = json_object_new_object();
580 json_object_pim_ifp_add(json_row, ifp);
581 json_object_string_add(json_row, "upTime",
582 uptime);
583 json_object_int_add(json_row, "version",
584 pim_ifp->igmp_version);
585
586 if (igmp->t_igmp_query_timer) {
587 json_object_boolean_true_add(json_row,
588 "querier");
589 json_object_string_add(json_row,
590 "queryTimer",
591 query_hhmmss);
592 }
593
594 json_object_object_add(json, ifp->name,
595 json_row);
596
597 } else {
598 vty_out(vty,
599 "%-9s %5s %15s %d %7s %11s %8s\n",
600 ifp->name,
601 if_is_up(ifp) ? "up" : "down",
602 inet_ntoa(igmp->ifaddr),
603 pim_ifp->igmp_version,
604 igmp->t_igmp_query_timer ? "local"
605 : "other",
606 query_hhmmss, uptime);
607 }
608 }
609 }
610
611 if (uj) {
9d303b37
DL
612 vty_out(vty, "%s\n", json_object_to_json_string_ext(
613 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 614 json_object_free(json);
615 }
616}
617
64c86530
DS
618static void igmp_show_interfaces_single(struct pim_instance *pim,
619 struct vty *vty, const char *ifname,
620 u_char uj)
d62a17ae 621{
622 struct igmp_sock *igmp;
623 struct interface *ifp;
624 struct listnode *node;
625 struct listnode *sock_node;
626 struct pim_interface *pim_ifp;
627 char uptime[10];
628 char query_hhmmss[10];
629 char other_hhmmss[10];
630 int found_ifname = 0;
631 int sqi;
96ceedc7 632 int mloop = 0;
d62a17ae 633 long gmi_msec; /* Group Membership Interval */
634 long lmqt_msec;
635 long ohpi_msec;
636 long oqpi_msec; /* Other Querier Present Interval */
637 long qri_msec;
638 time_t now;
639
640 json_object *json = NULL;
641 json_object *json_row = NULL;
642
643 if (uj)
644 json = json_object_new_object();
645
646 now = pim_time_monotonic_sec();
647
c68ba0d7 648 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 649 pim_ifp = ifp->info;
650
651 if (!pim_ifp)
652 continue;
653
654 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
655 continue;
656
657 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
658 igmp)) {
659 found_ifname = 1;
660 pim_time_uptime(uptime, sizeof(uptime),
661 now - igmp->sock_creation);
662 pim_time_timer_to_hhmmss(query_hhmmss,
663 sizeof(query_hhmmss),
664 igmp->t_igmp_query_timer);
665 pim_time_timer_to_hhmmss(other_hhmmss,
666 sizeof(other_hhmmss),
667 igmp->t_other_querier_timer);
668
669 gmi_msec = PIM_IGMP_GMI_MSEC(
670 igmp->querier_robustness_variable,
671 igmp->querier_query_interval,
672 pim_ifp->igmp_query_max_response_time_dsec);
673
674 sqi = PIM_IGMP_SQI(
675 pim_ifp->igmp_default_query_interval);
676
677 oqpi_msec = PIM_IGMP_OQPI_MSEC(
678 igmp->querier_robustness_variable,
679 igmp->querier_query_interval,
680 pim_ifp->igmp_query_max_response_time_dsec);
681
682 lmqt_msec = PIM_IGMP_LMQT_MSEC(
683 pim_ifp->igmp_query_max_response_time_dsec,
684 igmp->querier_robustness_variable);
685
686 ohpi_msec =
687 PIM_IGMP_OHPI_DSEC(
688 igmp->querier_robustness_variable,
689 igmp->querier_query_interval,
690 pim_ifp->igmp_query_max_response_time_dsec)
691 * 100;
692
693 qri_msec = pim_ifp->igmp_query_max_response_time_dsec
694 * 100;
96ceedc7
CS
695 if (pim_ifp->pim_sock_fd >= 0)
696 mloop = pim_socket_mcastloop_get(
697 pim_ifp->pim_sock_fd);
698 else
699 mloop = 0;
d62a17ae 700
701 if (uj) {
702 json_row = json_object_new_object();
703 json_object_pim_ifp_add(json_row, ifp);
704 json_object_string_add(json_row, "upTime",
705 uptime);
706 json_object_string_add(json_row, "querier",
707 igmp->t_igmp_query_timer
708 ? "local"
709 : "other");
710 json_object_int_add(json_row, "queryStartCount",
711 igmp->startup_query_count);
712 json_object_string_add(json_row,
713 "queryQueryTimer",
714 query_hhmmss);
715 json_object_string_add(json_row,
716 "queryOtherTimer",
717 other_hhmmss);
718 json_object_int_add(json_row, "version",
719 pim_ifp->igmp_version);
720 json_object_int_add(
721 json_row,
722 "timerGroupMembershipIntervalMsec",
723 gmi_msec);
724 json_object_int_add(json_row,
725 "timerLastMemberQueryMsec",
726 lmqt_msec);
727 json_object_int_add(
728 json_row,
729 "timerOlderHostPresentIntervalMsec",
730 ohpi_msec);
731 json_object_int_add(
732 json_row,
733 "timerOtherQuerierPresentIntervalMsec",
734 oqpi_msec);
735 json_object_int_add(
736 json_row, "timerQueryInterval",
737 igmp->querier_query_interval);
738 json_object_int_add(
739 json_row,
740 "timerQueryResponseIntervalMsec",
741 qri_msec);
742 json_object_int_add(
743 json_row, "timerRobustnessVariable",
744 igmp->querier_robustness_variable);
745 json_object_int_add(json_row,
746 "timerStartupQueryInterval",
747 sqi);
748
749 json_object_object_add(json, ifp->name,
750 json_row);
751
752 } else {
753 vty_out(vty, "Interface : %s\n", ifp->name);
754 vty_out(vty, "State : %s\n",
755 if_is_up(ifp) ? "up" : "down");
756 vty_out(vty, "Address : %s\n",
757 inet_ntoa(pim_ifp->primary_address));
758 vty_out(vty, "Uptime : %s\n", uptime);
759 vty_out(vty, "Version : %d\n",
760 pim_ifp->igmp_version);
761 vty_out(vty, "\n");
762 vty_out(vty, "\n");
763
764 vty_out(vty, "Querier\n");
765 vty_out(vty, "-------\n");
766 vty_out(vty, "Querier : %s\n",
767 igmp->t_igmp_query_timer ? "local"
768 : "other");
769 vty_out(vty, "Start Count : %d\n",
770 igmp->startup_query_count);
771 vty_out(vty, "Query Timer : %s\n",
772 query_hhmmss);
773 vty_out(vty, "Other Timer : %s\n",
774 other_hhmmss);
775 vty_out(vty, "\n");
776 vty_out(vty, "\n");
777
778 vty_out(vty, "Timers\n");
779 vty_out(vty, "------\n");
780 vty_out(vty,
781 "Group Membership Interval : %lis\n",
782 gmi_msec / 1000);
783 vty_out(vty,
784 "Last Member Query Time : %lis\n",
785 lmqt_msec / 1000);
786 vty_out(vty,
787 "Older Host Present Interval : %lis\n",
788 ohpi_msec / 1000);
789 vty_out(vty,
790 "Other Querier Present Interval : %lis\n",
791 oqpi_msec / 1000);
792 vty_out(vty,
793 "Query Interval : %ds\n",
794 igmp->querier_query_interval);
795 vty_out(vty,
796 "Query Response Interval : %lis\n",
797 qri_msec / 1000);
798 vty_out(vty,
799 "Robustness Variable : %d\n",
800 igmp->querier_robustness_variable);
801 vty_out(vty,
802 "Startup Query Interval : %ds\n",
803 sqi);
804 vty_out(vty, "\n");
805 vty_out(vty, "\n");
806
807 pim_print_ifp_flags(vty, ifp, mloop);
808 }
809 }
810 }
811
812 if (uj) {
9d303b37
DL
813 vty_out(vty, "%s\n", json_object_to_json_string_ext(
814 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 815 json_object_free(json);
816 } else {
817 if (!found_ifname)
818 vty_out(vty, "%% No such interface\n");
819 }
12e41d03
DL
820}
821
64c86530 822static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
12e41d03 823{
d62a17ae 824 struct listnode *node;
825 struct interface *ifp;
826 time_t now;
827
828 now = pim_time_monotonic_sec();
829
830 vty_out(vty,
831 "Interface Address Source Group Socket Uptime \n");
832
c68ba0d7 833 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 834 struct pim_interface *pim_ifp;
835 struct listnode *join_node;
836 struct igmp_join *ij;
837 struct in_addr pri_addr;
838 char pri_addr_str[INET_ADDRSTRLEN];
839
840 pim_ifp = ifp->info;
841
842 if (!pim_ifp)
843 continue;
844
845 if (!pim_ifp->igmp_join_list)
846 continue;
847
848 pri_addr = pim_find_primary_addr(ifp);
849 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
850 sizeof(pri_addr_str));
851
852 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node,
853 ij)) {
854 char group_str[INET_ADDRSTRLEN];
855 char source_str[INET_ADDRSTRLEN];
856 char uptime[10];
857
858 pim_time_uptime(uptime, sizeof(uptime),
859 now - ij->sock_creation);
860 pim_inet4_dump("<grp?>", ij->group_addr, group_str,
861 sizeof(group_str));
862 pim_inet4_dump("<src?>", ij->source_addr, source_str,
863 sizeof(source_str));
864
865 vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s\n",
866 ifp->name, pri_addr_str, source_str, group_str,
867 ij->sock_fd, uptime);
868 } /* for (pim_ifp->igmp_join_list) */
869
870 } /* for (iflist) */
871}
872
64c86530
DS
873static void pim_show_interfaces_single(struct pim_instance *pim,
874 struct vty *vty, const char *ifname,
875 u_char uj)
d62a17ae 876{
877 struct in_addr ifaddr;
878 struct interface *ifp;
879 struct listnode *neighnode;
880 struct listnode *node;
881 struct listnode *upnode;
882 struct pim_interface *pim_ifp;
883 struct pim_neighbor *neigh;
884 struct pim_upstream *up;
885 time_t now;
886 char dr_str[INET_ADDRSTRLEN];
887 char dr_uptime[10];
888 char expire[10];
889 char grp_str[INET_ADDRSTRLEN];
890 char hello_period[10];
891 char hello_timer[10];
892 char neigh_src_str[INET_ADDRSTRLEN];
893 char src_str[INET_ADDRSTRLEN];
894 char stat_uptime[10];
895 char uptime[10];
96ceedc7 896 int mloop = 0;
d62a17ae 897 int found_ifname = 0;
898 int print_header;
899 json_object *json = NULL;
900 json_object *json_row = NULL;
901 json_object *json_pim_neighbor = NULL;
902 json_object *json_pim_neighbors = NULL;
903 json_object *json_group = NULL;
904 json_object *json_group_source = NULL;
905 json_object *json_fhr_sources = NULL;
906 struct pim_secondary_addr *sec_addr;
907 struct listnode *sec_node;
908
909 now = pim_time_monotonic_sec();
910
911 if (uj)
912 json = json_object_new_object();
913
c68ba0d7 914 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 915 pim_ifp = ifp->info;
916
917 if (!pim_ifp)
918 continue;
919
d62a17ae 920 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
921 continue;
922
923 found_ifname = 1;
924 ifaddr = pim_ifp->primary_address;
925 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
926 sizeof(dr_str));
927 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
928 pim_ifp->pim_dr_election_last);
929 pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
930 pim_ifp->t_pim_hello_timer);
931 pim_time_mmss(hello_period, sizeof(hello_period),
932 pim_ifp->pim_hello_period);
933 pim_time_uptime(stat_uptime, sizeof(stat_uptime),
934 now - pim_ifp->pim_ifstat_start);
96ceedc7
CS
935 if (pim_ifp->pim_sock_fd >= 0)
936 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
937 else
938 mloop = 0;
d62a17ae 939
940 if (uj) {
941 char pbuf[PREFIX2STR_BUFFER];
942 json_row = json_object_new_object();
943 json_object_pim_ifp_add(json_row, ifp);
944
945 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
946 json_object_string_add(
947 json_row, "useSource",
948 inet_ntoa(pim_ifp->update_source));
949 }
950 if (pim_ifp->sec_addr_list) {
951 json_object *sec_list = NULL;
952
953 sec_list = json_object_new_array();
954 for (ALL_LIST_ELEMENTS_RO(
955 pim_ifp->sec_addr_list, sec_node,
956 sec_addr)) {
957 json_object_array_add(
958 sec_list,
959 json_object_new_string(
960 prefix2str(
961 &sec_addr->addr,
962 pbuf,
963 sizeof(pbuf))));
964 }
965 json_object_object_add(json_row,
966 "secondaryAddressList",
967 sec_list);
968 }
969
970 // PIM neighbors
971 if (pim_ifp->pim_neighbor_list->count) {
972 json_pim_neighbors = json_object_new_object();
973
974 for (ALL_LIST_ELEMENTS_RO(
975 pim_ifp->pim_neighbor_list,
976 neighnode, neigh)) {
977 json_pim_neighbor =
978 json_object_new_object();
979 pim_inet4_dump("<src?>",
980 neigh->source_addr,
981 neigh_src_str,
982 sizeof(neigh_src_str));
983 pim_time_uptime(uptime, sizeof(uptime),
984 now - neigh->creation);
985 pim_time_timer_to_hhmmss(
986 expire, sizeof(expire),
987 neigh->t_expire_timer);
988
989 json_object_string_add(
990 json_pim_neighbor, "address",
991 neigh_src_str);
992 json_object_string_add(
993 json_pim_neighbor, "upTime",
994 uptime);
995 json_object_string_add(
996 json_pim_neighbor, "holdtime",
997 expire);
998
999 json_object_object_add(
1000 json_pim_neighbors,
1001 neigh_src_str,
1002 json_pim_neighbor);
1003 }
1004
1005 json_object_object_add(json_row, "neighbors",
1006 json_pim_neighbors);
1007 }
1008
1009 json_object_string_add(json_row, "drAddress", dr_str);
1010 json_object_int_add(json_row, "drPriority",
1011 pim_ifp->pim_dr_priority);
1012 json_object_string_add(json_row, "drUptime", dr_uptime);
1013 json_object_int_add(json_row, "drElections",
1014 pim_ifp->pim_dr_election_count);
1015 json_object_int_add(json_row, "drChanges",
1016 pim_ifp->pim_dr_election_changes);
1017
1018 // FHR
c68ba0d7 1019 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
d62a17ae 1020 up)) {
1021 if (ifp == up->rpf.source_nexthop.interface) {
1022 if (up->flags
1023 & PIM_UPSTREAM_FLAG_MASK_FHR) {
1024 if (!json_fhr_sources) {
1025 json_fhr_sources =
1026 json_object_new_object();
1027 }
1028
1029 pim_inet4_dump("<src?>",
1030 up->sg.src,
1031 src_str,
1032 sizeof(src_str));
1033 pim_inet4_dump("<grp?>",
1034 up->sg.grp,
1035 grp_str,
1036 sizeof(grp_str));
1037 pim_time_uptime(
1038 uptime, sizeof(uptime),
1039 now - up->state_transition);
1040
1041 /* Does this group live in
1042 * json_fhr_sources? If not
1043 * create it. */
1044 json_object_object_get_ex(
1045 json_fhr_sources,
1046 grp_str, &json_group);
1047
1048 if (!json_group) {
1049 json_group =
1050 json_object_new_object();
1051 json_object_object_add(
1052 json_fhr_sources,
1053 grp_str,
1054 json_group);
1055 }
1056
1057 json_group_source =
1058 json_object_new_object();
1059 json_object_string_add(
1060 json_group_source,
1061 "source", src_str);
1062 json_object_string_add(
1063 json_group_source,
1064 "group", grp_str);
1065 json_object_string_add(
1066 json_group_source,
1067 "upTime", uptime);
1068 json_object_object_add(
1069 json_group, src_str,
1070 json_group_source);
1071 }
1072 }
1073 }
1074
1075 if (json_fhr_sources) {
1076 json_object_object_add(json_row,
1077 "firstHopRouter",
1078 json_fhr_sources);
1079 }
1080
1081 json_object_int_add(json_row, "helloPeriod",
1082 pim_ifp->pim_hello_period);
1083 json_object_string_add(json_row, "helloTimer",
1084 hello_timer);
1085 json_object_string_add(json_row, "helloStatStart",
1086 stat_uptime);
1087 json_object_int_add(json_row, "helloReceived",
1088 pim_ifp->pim_ifstat_hello_recv);
1089 json_object_int_add(json_row, "helloReceivedFailed",
1090 pim_ifp->pim_ifstat_hello_recvfail);
1091 json_object_int_add(json_row, "helloSend",
1092 pim_ifp->pim_ifstat_hello_sent);
1093 json_object_int_add(json_row, "hellosendFailed",
1094 pim_ifp->pim_ifstat_hello_sendfail);
1095 json_object_int_add(json_row, "helloGenerationId",
1096 pim_ifp->pim_generation_id);
1097 json_object_int_add(json_row, "flagMulticastLoop",
1098 mloop);
1099
1100 json_object_int_add(
1101 json_row, "effectivePropagationDelay",
1102 pim_if_effective_propagation_delay_msec(ifp));
1103 json_object_int_add(
1104 json_row, "effectiveOverrideInterval",
1105 pim_if_effective_override_interval_msec(ifp));
1106 json_object_int_add(
1107 json_row, "joinPruneOverrideInterval",
1108 pim_if_jp_override_interval_msec(ifp));
1109
1110 json_object_int_add(
1111 json_row, "propagationDelay",
1112 pim_ifp->pim_propagation_delay_msec);
1113 json_object_int_add(
1114 json_row, "propagationDelayHighest",
1115 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1116 json_object_int_add(
1117 json_row, "overrideInterval",
1118 pim_ifp->pim_override_interval_msec);
1119 json_object_int_add(
1120 json_row, "overrideIntervalHighest",
1121 pim_ifp->pim_neighbors_highest_override_interval_msec);
1122 json_object_object_add(json, ifp->name, json_row);
1123
1124 } else {
1125 vty_out(vty, "Interface : %s\n", ifp->name);
1126 vty_out(vty, "State : %s\n",
1127 if_is_up(ifp) ? "up" : "down");
1128 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
1129 vty_out(vty, "Use Source : %s\n",
1130 inet_ntoa(pim_ifp->update_source));
1131 }
1132 if (pim_ifp->sec_addr_list) {
1133 char pbuf[PREFIX2STR_BUFFER];
1134 vty_out(vty, "Address : %s (primary)\n",
1135 inet_ntoa(ifaddr));
1136 for (ALL_LIST_ELEMENTS_RO(
1137 pim_ifp->sec_addr_list, sec_node,
1138 sec_addr)) {
1139 vty_out(vty, " %s\n",
1140 prefix2str(&sec_addr->addr,
1141 pbuf, sizeof(pbuf)));
1142 }
1143 } else {
1144 vty_out(vty, "Address : %s\n",
1145 inet_ntoa(ifaddr));
1146 }
1147 vty_out(vty, "\n");
1148
1149 // PIM neighbors
1150 print_header = 1;
1151
1152 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
1153 neighnode, neigh)) {
1154
1155 if (print_header) {
1156 vty_out(vty, "PIM Neighbors\n");
1157 vty_out(vty, "-------------\n");
1158 print_header = 0;
1159 }
1160
1161 pim_inet4_dump("<src?>", neigh->source_addr,
1162 neigh_src_str,
1163 sizeof(neigh_src_str));
1164 pim_time_uptime(uptime, sizeof(uptime),
1165 now - neigh->creation);
1166 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1167 neigh->t_expire_timer);
1168 vty_out(vty,
1169 "%-15s : up for %s, holdtime expires in %s\n",
1170 neigh_src_str, uptime, expire);
1171 }
1172
1173 if (!print_header) {
1174 vty_out(vty, "\n");
1175 vty_out(vty, "\n");
1176 }
1177
1178 vty_out(vty, "Designated Router\n");
1179 vty_out(vty, "-----------------\n");
1180 vty_out(vty, "Address : %s\n", dr_str);
1181 vty_out(vty, "Priority : %d\n",
1182 pim_ifp->pim_dr_priority);
1183 vty_out(vty, "Uptime : %s\n", dr_uptime);
1184 vty_out(vty, "Elections : %d\n",
1185 pim_ifp->pim_dr_election_count);
1186 vty_out(vty, "Changes : %d\n",
1187 pim_ifp->pim_dr_election_changes);
1188 vty_out(vty, "\n");
1189 vty_out(vty, "\n");
1190
1191 // FHR
1192 print_header = 1;
c68ba0d7 1193 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
d62a17ae 1194 up)) {
0708beb1
DS
1195 if (strcmp(ifp->name, up->rpf.source_nexthop
1196 .interface->name)
d62a17ae 1197 == 0) {
1198 if (up->flags
1199 & PIM_UPSTREAM_FLAG_MASK_FHR) {
1200
1201 if (print_header) {
1202 vty_out(vty,
1203 "FHR - First Hop Router\n");
1204 vty_out(vty,
1205 "----------------------\n");
1206 print_header = 0;
1207 }
1208
1209 pim_inet4_dump("<src?>",
1210 up->sg.src,
1211 src_str,
1212 sizeof(src_str));
1213 pim_inet4_dump("<grp?>",
1214 up->sg.grp,
1215 grp_str,
1216 sizeof(grp_str));
1217 pim_time_uptime(
1218 uptime, sizeof(uptime),
1219 now - up->state_transition);
1220 vty_out(vty,
1221 "%s : %s is a source, uptime is %s\n",
1222 grp_str, src_str,
1223 uptime);
1224 }
1225 }
1226 }
1227
1228 if (!print_header) {
1229 vty_out(vty, "\n");
1230 vty_out(vty, "\n");
1231 }
1232
1233 vty_out(vty, "Hellos\n");
1234 vty_out(vty, "------\n");
1235 vty_out(vty, "Period : %d\n",
1236 pim_ifp->pim_hello_period);
1237 vty_out(vty, "Timer : %s\n", hello_timer);
1238 vty_out(vty, "StatStart : %s\n", stat_uptime);
1239 vty_out(vty, "Receive : %d\n",
1240 pim_ifp->pim_ifstat_hello_recv);
1241 vty_out(vty, "Receive Failed : %d\n",
1242 pim_ifp->pim_ifstat_hello_recvfail);
1243 vty_out(vty, "Send : %d\n",
1244 pim_ifp->pim_ifstat_hello_sent);
1245 vty_out(vty, "Send Failed : %d\n",
1246 pim_ifp->pim_ifstat_hello_sendfail);
1247 vty_out(vty, "Generation ID : %08x\n",
1248 pim_ifp->pim_generation_id);
1249 vty_out(vty, "\n");
1250 vty_out(vty, "\n");
1251
1252 pim_print_ifp_flags(vty, ifp, mloop);
1253
1254 vty_out(vty, "Join Prune Interval\n");
1255 vty_out(vty, "-------------------\n");
1256 vty_out(vty, "LAN Delay : %s\n",
1257 pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
1258 vty_out(vty, "Effective Propagation Delay : %d msec\n",
1259 pim_if_effective_propagation_delay_msec(ifp));
1260 vty_out(vty, "Effective Override Interval : %d msec\n",
1261 pim_if_effective_override_interval_msec(ifp));
1262 vty_out(vty, "Join Prune Override Interval : %d msec\n",
1263 pim_if_jp_override_interval_msec(ifp));
1264 vty_out(vty, "\n");
1265 vty_out(vty, "\n");
1266
1267 vty_out(vty, "LAN Prune Delay\n");
1268 vty_out(vty, "---------------\n");
1269 vty_out(vty, "Propagation Delay : %d msec\n",
1270 pim_ifp->pim_propagation_delay_msec);
1271 vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
1272 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1273 vty_out(vty, "Override Interval : %d msec\n",
1274 pim_ifp->pim_override_interval_msec);
1275 vty_out(vty, "Override Interval (Highest) : %d msec\n",
1276 pim_ifp->pim_neighbors_highest_override_interval_msec);
1277 vty_out(vty, "\n");
1278 vty_out(vty, "\n");
1279 }
1280 }
1281
1282 if (uj) {
9d303b37
DL
1283 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1284 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1285 json_object_free(json);
1286 } else {
1287 if (!found_ifname)
1288 vty_out(vty, "%% No such interface\n");
1289 }
12e41d03
DL
1290}
1291
64c86530 1292static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
c68ba0d7 1293 u_char uj)
12e41d03 1294{
d62a17ae 1295 struct interface *ifp;
1296 struct listnode *node;
1297 struct listnode *upnode;
1298 struct pim_interface *pim_ifp;
1299 struct pim_upstream *up;
1300 int fhr = 0;
1301 int pim_nbrs = 0;
1302 int pim_ifchannels = 0;
1303 json_object *json = NULL;
1304 json_object *json_row = NULL;
1305 json_object *json_tmp;
1306
1307 json = json_object_new_object();
1308
c68ba0d7 1309 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 1310 pim_ifp = ifp->info;
1311
1312 if (!pim_ifp)
1313 continue;
1314
d62a17ae 1315 pim_nbrs = pim_ifp->pim_neighbor_list->count;
1316 pim_ifchannels = pim_ifp->pim_ifchannel_list->count;
1317 fhr = 0;
1318
c68ba0d7 1319 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up))
d62a17ae 1320 if (ifp == up->rpf.source_nexthop.interface)
1321 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
1322 fhr++;
1323
1324 json_row = json_object_new_object();
1325 json_object_pim_ifp_add(json_row, ifp);
1326 json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
1327 json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
1328 json_object_int_add(json_row, "firstHopRouter", fhr);
1329 json_object_string_add(json_row, "pimDesignatedRouter",
1330 inet_ntoa(pim_ifp->pim_dr_addr));
1331
1332 if (pim_ifp->pim_dr_addr.s_addr
1333 == pim_ifp->primary_address.s_addr)
1334 json_object_boolean_true_add(
1335 json_row, "pimDesignatedRouterLocal");
1336
1337 json_object_object_add(json, ifp->name, json_row);
1338 }
1339
1340 if (uj) {
9d303b37
DL
1341 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1342 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1343 } else {
1344 vty_out(vty,
1345 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1346
1347 json_object_object_foreach(json, key, val)
1348 {
1349 vty_out(vty, "%-9s ", key);
1350
1351 json_object_object_get_ex(val, "state", &json_tmp);
1352 vty_out(vty, "%5s ", json_object_get_string(json_tmp));
1353
1354 json_object_object_get_ex(val, "address", &json_tmp);
1355 vty_out(vty, "%15s ",
1356 json_object_get_string(json_tmp));
1357
1358 json_object_object_get_ex(val, "pimNeighbors",
1359 &json_tmp);
1360 vty_out(vty, "%8d ", json_object_get_int(json_tmp));
1361
1362 if (json_object_object_get_ex(
1363 val, "pimDesignatedRouterLocal",
1364 &json_tmp)) {
1365 vty_out(vty, "%15s ", "local");
1366 } else {
1367 json_object_object_get_ex(
1368 val, "pimDesignatedRouter", &json_tmp);
1369 vty_out(vty, "%15s ",
1370 json_object_get_string(json_tmp));
1371 }
1372
1373 json_object_object_get_ex(val, "firstHopRouter",
1374 &json_tmp);
1375 vty_out(vty, "%3d ", json_object_get_int(json_tmp));
1376
1377 json_object_object_get_ex(val, "pimIfChannels",
1378 &json_tmp);
1379 vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
1380 }
1381 }
1382
1383 json_object_free(json);
1384}
1385
64c86530
DS
1386static void pim_show_interface_traffic(struct pim_instance *pim,
1387 struct vty *vty, u_char uj)
d62a17ae 1388{
1389 struct interface *ifp = NULL;
1390 struct pim_interface *pim_ifp = NULL;
1391 struct listnode *node = NULL;
1392 json_object *json = NULL;
1393 json_object *json_row = NULL;
1394
1395 if (uj)
1396 json = json_object_new_object();
1397 else {
1398 vty_out(vty, "\n");
1399 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1400 "Interface", " HELLO", " JOIN", " PRUNE",
1401 " REGISTER", " REGISTER-STOP", " ASSERT");
1402 vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1403 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1404 " Rx/Tx", " Rx/Tx");
1405 vty_out(vty,
1406 "---------------------------------------------------------------------------------------------------------------\n");
1407 }
1408
c68ba0d7 1409 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 1410 pim_ifp = ifp->info;
1411
1412 if (!pim_ifp)
1413 continue;
1414
1415 if (pim_ifp->pim_sock_fd < 0)
1416 continue;
1417 if (uj) {
1418 json_row = json_object_new_object();
1419 json_object_pim_ifp_add(json_row, ifp);
1420 json_object_int_add(json_row, "helloRx",
1421 pim_ifp->pim_ifstat_hello_recv);
1422 json_object_int_add(json_row, "helloTx",
1423 pim_ifp->pim_ifstat_hello_sent);
1424 json_object_int_add(json_row, "joinRx",
1425 pim_ifp->pim_ifstat_join_recv);
1426 json_object_int_add(json_row, "joinTx",
1427 pim_ifp->pim_ifstat_join_send);
1428 json_object_int_add(json_row, "registerRx",
1429 pim_ifp->pim_ifstat_reg_recv);
1430 json_object_int_add(json_row, "registerTx",
1431 pim_ifp->pim_ifstat_reg_recv);
1432 json_object_int_add(json_row, "registerStopRx",
1433 pim_ifp->pim_ifstat_reg_stop_recv);
1434 json_object_int_add(json_row, "registerStopTx",
1435 pim_ifp->pim_ifstat_reg_stop_send);
1436 json_object_int_add(json_row, "assertRx",
1437 pim_ifp->pim_ifstat_assert_recv);
1438 json_object_int_add(json_row, "assertTx",
1439 pim_ifp->pim_ifstat_assert_send);
1440
1441 json_object_object_add(json, ifp->name, json_row);
1442 } else {
1443 vty_out(vty,
1444 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1445 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1446 pim_ifp->pim_ifstat_hello_sent,
1447 pim_ifp->pim_ifstat_join_recv,
1448 pim_ifp->pim_ifstat_join_send,
1449 pim_ifp->pim_ifstat_prune_recv,
1450 pim_ifp->pim_ifstat_prune_send,
1451 pim_ifp->pim_ifstat_reg_recv,
1452 pim_ifp->pim_ifstat_reg_send,
1453 pim_ifp->pim_ifstat_reg_stop_recv,
1454 pim_ifp->pim_ifstat_reg_stop_send,
1455 pim_ifp->pim_ifstat_assert_recv,
1456 pim_ifp->pim_ifstat_assert_send);
1457 }
1458 }
1459 if (uj) {
9d303b37
DL
1460 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1461 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1462 json_object_free(json);
1463 }
1464}
1465
64c86530
DS
1466static void pim_show_interface_traffic_single(struct pim_instance *pim,
1467 struct vty *vty,
d62a17ae 1468 const char *ifname, u_char uj)
1469{
1470 struct interface *ifp = NULL;
1471 struct pim_interface *pim_ifp = NULL;
1472 struct listnode *node = NULL;
1473 json_object *json = NULL;
1474 json_object *json_row = NULL;
1475 uint8_t found_ifname = 0;
1476
1477 if (uj)
1478 json = json_object_new_object();
1479 else {
1480 vty_out(vty, "\n");
1481 vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1482 "Interface", " HELLO", " JOIN", " PRUNE",
1483 " REGISTER", " REGISTER-STOP", " ASSERT");
1484 vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1485 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1486 " Rx/Tx", " Rx/Tx");
1487 vty_out(vty,
1488 "---------------------------------------------------------------------------------------------------------------\n");
1489 }
1490
c68ba0d7 1491 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 1492 if (strcmp(ifname, ifp->name))
1493 continue;
1494
1495 pim_ifp = ifp->info;
1496
1497 if (!pim_ifp)
1498 continue;
1499
1500 if (pim_ifp->pim_sock_fd < 0)
1501 continue;
1502
1503 found_ifname = 1;
1504 if (uj) {
1505 json_row = json_object_new_object();
1506 json_object_pim_ifp_add(json_row, ifp);
1507 json_object_int_add(json_row, "helloRx",
1508 pim_ifp->pim_ifstat_hello_recv);
1509 json_object_int_add(json_row, "helloTx",
1510 pim_ifp->pim_ifstat_hello_sent);
1511 json_object_int_add(json_row, "joinRx",
1512 pim_ifp->pim_ifstat_join_recv);
1513 json_object_int_add(json_row, "joinTx",
1514 pim_ifp->pim_ifstat_join_send);
1515 json_object_int_add(json_row, "registerRx",
1516 pim_ifp->pim_ifstat_reg_recv);
1517 json_object_int_add(json_row, "registerTx",
1518 pim_ifp->pim_ifstat_reg_recv);
1519 json_object_int_add(json_row, "registerStopRx",
1520 pim_ifp->pim_ifstat_reg_stop_recv);
1521 json_object_int_add(json_row, "registerStopTx",
1522 pim_ifp->pim_ifstat_reg_stop_send);
1523 json_object_int_add(json_row, "assertRx",
1524 pim_ifp->pim_ifstat_assert_recv);
1525 json_object_int_add(json_row, "assertTx",
1526 pim_ifp->pim_ifstat_assert_send);
1527
1528 json_object_object_add(json, ifp->name, json_row);
1529 } else {
1530 vty_out(vty,
1531 "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1532 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1533 pim_ifp->pim_ifstat_hello_sent,
1534 pim_ifp->pim_ifstat_join_recv,
1535 pim_ifp->pim_ifstat_join_send,
1536 pim_ifp->pim_ifstat_prune_recv,
1537 pim_ifp->pim_ifstat_prune_send,
1538 pim_ifp->pim_ifstat_reg_recv,
1539 pim_ifp->pim_ifstat_reg_send,
1540 pim_ifp->pim_ifstat_reg_stop_recv,
1541 pim_ifp->pim_ifstat_reg_stop_send,
1542 pim_ifp->pim_ifstat_assert_recv,
1543 pim_ifp->pim_ifstat_assert_send);
1544 }
1545 }
1546 if (uj) {
9d303b37
DL
1547 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1548 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1549 json_object_free(json);
1550 } else {
1551 if (!found_ifname)
1552 vty_out(vty, "%% No such interface\n");
1553 }
39438188
CS
1554}
1555
64c86530 1556static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj)
12e41d03 1557{
d62a17ae 1558 struct pim_interface *pim_ifp;
1559 struct in_addr ifaddr;
1560 struct listnode *ch_node;
1561 struct pim_ifchannel *ch;
1562 time_t now;
1563 json_object *json = NULL;
1564 json_object *json_iface = NULL;
1565 json_object *json_row = NULL;
1566 json_object *json_grp = NULL;
1567
1568 now = pim_time_monotonic_sec();
1569
1570 if (uj)
1571 json = json_object_new_object();
1572 else
1573 vty_out(vty,
1574 "Interface Address Source Group State Uptime Expire Prune\n");
1575
f88df3a6 1576 for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
d62a17ae 1577
1578 pim_ifp = ch->interface->info;
1579
1580 if (!pim_ifp)
1581 continue;
1582
1583 ifaddr = pim_ifp->primary_address;
1584
1585 char ch_src_str[INET_ADDRSTRLEN];
1586 char ch_grp_str[INET_ADDRSTRLEN];
1587 char uptime[10];
1588 char expire[10];
1589 char prune[10];
1590
1591 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
1592 sizeof(ch_src_str));
1593 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
1594 sizeof(ch_grp_str));
1595
1596 pim_time_uptime_begin(uptime, sizeof(uptime), now,
1597 ch->ifjoin_creation);
1598 pim_time_timer_to_mmss(expire, sizeof(expire),
1599 ch->t_ifjoin_expiry_timer);
1600 pim_time_timer_to_mmss(prune, sizeof(prune),
1601 ch->t_ifjoin_prune_pending_timer);
1602
1603 if (uj) {
1604 json_object_object_get_ex(json, ch->interface->name,
1605 &json_iface);
1606
1607 if (!json_iface) {
1608 json_iface = json_object_new_object();
1609 json_object_pim_ifp_add(json_iface,
1610 ch->interface);
1611 json_object_object_add(
1612 json, ch->interface->name, json_iface);
1613 }
1614
1615 json_row = json_object_new_object();
1616 json_object_string_add(json_row, "source", ch_src_str);
1617 json_object_string_add(json_row, "group", ch_grp_str);
1618 json_object_string_add(json_row, "upTime", uptime);
1619 json_object_string_add(json_row, "expire", expire);
1620 json_object_string_add(json_row, "prune", prune);
1621 json_object_string_add(
1622 json_row, "channelJoinName",
1623 pim_ifchannel_ifjoin_name(ch->ifjoin_state,
1624 ch->flags));
1625 if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
1626 json_object_int_add(json_row, "SGRpt", 1);
1627
1628 json_object_object_get_ex(json_iface, ch_grp_str,
1629 &json_grp);
1630 if (!json_grp) {
1631 json_grp = json_object_new_object();
1632 json_object_object_add(json_grp, ch_src_str,
1633 json_row);
1634 json_object_object_add(json_iface, ch_grp_str,
1635 json_grp);
1636 } else
1637 json_object_object_add(json_grp, ch_src_str,
1638 json_row);
1639 } else {
1640 vty_out(vty,
1641 "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s\n",
1642 ch->interface->name, inet_ntoa(ifaddr),
1643 ch_src_str, ch_grp_str,
1644 pim_ifchannel_ifjoin_name(ch->ifjoin_state,
1645 ch->flags),
1646 uptime, expire, prune);
1647 }
1648 } /* scan interface channels */
1649
1650 if (uj) {
9d303b37
DL
1651 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1652 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1653 json_object_free(json);
1654 }
1655}
1656
64c86530 1657static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
c68ba0d7 1658 const char *neighbor, u_char uj)
d62a17ae 1659{
1660 struct listnode *node;
1661 struct listnode *neighnode;
1662 struct interface *ifp;
1663 struct pim_interface *pim_ifp;
1664 struct pim_neighbor *neigh;
1665 time_t now;
1666 int found_neighbor = 0;
1667 int option_address_list;
1668 int option_dr_priority;
1669 int option_generation_id;
1670 int option_holdtime;
1671 int option_lan_prune_delay;
1672 int option_t_bit;
1673 char uptime[10];
1674 char expire[10];
1675 char neigh_src_str[INET_ADDRSTRLEN];
1676
1677 json_object *json = NULL;
1678 json_object *json_ifp = NULL;
1679 json_object *json_row = NULL;
1680
1681 now = pim_time_monotonic_sec();
1682
1683 if (uj)
1684 json = json_object_new_object();
1685
c68ba0d7 1686 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 1687 pim_ifp = ifp->info;
1688
1689 if (!pim_ifp)
1690 continue;
1691
1692 if (pim_ifp->pim_sock_fd < 0)
1693 continue;
1694
1695 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
1696 neigh)) {
1697 pim_inet4_dump("<src?>", neigh->source_addr,
1698 neigh_src_str, sizeof(neigh_src_str));
1699
1700 /*
1701 * The user can specify either the interface name or the
1702 * PIM neighbor IP.
1703 * If this pim_ifp matches neither then skip.
1704 */
1705 if (strcmp(neighbor, "detail")
1706 && strcmp(neighbor, ifp->name)
1707 && strcmp(neighbor, neigh_src_str))
1708 continue;
1709
1710 found_neighbor = 1;
1711 pim_time_uptime(uptime, sizeof(uptime),
1712 now - neigh->creation);
1713 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1714 neigh->t_expire_timer);
1715
1716 option_address_list = 0;
1717 option_dr_priority = 0;
1718 option_generation_id = 0;
1719 option_holdtime = 0;
1720 option_lan_prune_delay = 0;
1721 option_t_bit = 0;
1722
1723 if (PIM_OPTION_IS_SET(neigh->hello_options,
1724 PIM_OPTION_MASK_ADDRESS_LIST))
1725 option_address_list = 1;
1726
1727 if (PIM_OPTION_IS_SET(neigh->hello_options,
1728 PIM_OPTION_MASK_DR_PRIORITY))
1729 option_dr_priority = 1;
1730
1731 if (PIM_OPTION_IS_SET(neigh->hello_options,
1732 PIM_OPTION_MASK_GENERATION_ID))
1733 option_generation_id = 1;
1734
1735 if (PIM_OPTION_IS_SET(neigh->hello_options,
1736 PIM_OPTION_MASK_HOLDTIME))
1737 option_holdtime = 1;
1738
1739 if (PIM_OPTION_IS_SET(neigh->hello_options,
1740 PIM_OPTION_MASK_LAN_PRUNE_DELAY))
1741 option_lan_prune_delay = 1;
1742
1743 if (PIM_OPTION_IS_SET(
1744 neigh->hello_options,
1745 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
1746 option_t_bit = 1;
1747
1748 if (uj) {
1749
1750 /* Does this ifp live in json? If not create
1751 * it. */
1752 json_object_object_get_ex(json, ifp->name,
1753 &json_ifp);
1754
1755 if (!json_ifp) {
1756 json_ifp = json_object_new_object();
1757 json_object_pim_ifp_add(json_ifp, ifp);
1758 json_object_object_add(json, ifp->name,
1759 json_ifp);
1760 }
1761
1762 json_row = json_object_new_object();
1763 json_object_string_add(json_row, "interface",
1764 ifp->name);
1765 json_object_string_add(json_row, "address",
1766 neigh_src_str);
1767 json_object_string_add(json_row, "upTime",
1768 uptime);
1769 json_object_string_add(json_row, "holdtime",
1770 expire);
1771 json_object_int_add(json_row, "drPriority",
1772 neigh->dr_priority);
1773 json_object_int_add(json_row, "generationId",
1774 neigh->generation_id);
1775
1776 if (option_address_list)
1777 json_object_boolean_true_add(
1778 json_row,
1779 "helloOptionAddressList");
1780
1781 if (option_dr_priority)
1782 json_object_boolean_true_add(
1783 json_row,
1784 "helloOptionDrPriority");
1785
1786 if (option_generation_id)
1787 json_object_boolean_true_add(
1788 json_row,
1789 "helloOptionGenerationId");
1790
1791 if (option_holdtime)
1792 json_object_boolean_true_add(
1793 json_row,
1794 "helloOptionHoldtime");
1795
1796 if (option_lan_prune_delay)
1797 json_object_boolean_true_add(
1798 json_row,
1799 "helloOptionLanPruneDelay");
1800
1801 if (option_t_bit)
1802 json_object_boolean_true_add(
1803 json_row, "helloOptionTBit");
1804
1805 json_object_object_add(json_ifp, neigh_src_str,
1806 json_row);
1807
1808 } else {
1809 vty_out(vty, "Interface : %s\n", ifp->name);
1810 vty_out(vty, "Neighbor : %s\n", neigh_src_str);
1811 vty_out(vty,
1812 " Uptime : %s\n",
1813 uptime);
1814 vty_out(vty,
1815 " Holdtime : %s\n",
1816 expire);
1817 vty_out(vty,
1818 " DR Priority : %d\n",
1819 neigh->dr_priority);
1820 vty_out(vty,
1821 " Generation ID : %08x\n",
1822 neigh->generation_id);
1823 vty_out(vty,
1824 " Override Interval (msec) : %d\n",
1825 neigh->override_interval_msec);
1826 vty_out(vty,
1827 " Propagation Delay (msec) : %d\n",
1828 neigh->propagation_delay_msec);
1829 vty_out(vty,
1830 " Hello Option - Address List : %s\n",
1831 option_address_list ? "yes" : "no");
1832 vty_out(vty,
1833 " Hello Option - DR Priority : %s\n",
1834 option_dr_priority ? "yes" : "no");
1835 vty_out(vty,
1836 " Hello Option - Generation ID : %s\n",
1837 option_generation_id ? "yes" : "no");
1838 vty_out(vty,
1839 " Hello Option - Holdtime : %s\n",
1840 option_holdtime ? "yes" : "no");
1841 vty_out(vty,
1842 " Hello Option - LAN Prune Delay : %s\n",
1843 option_lan_prune_delay ? "yes" : "no");
1844 vty_out(vty,
1845 " Hello Option - T-bit : %s\n",
1846 option_t_bit ? "yes" : "no");
1847 pim_bfd_show_info(vty, neigh->bfd_info,
1848 json_ifp, uj, 0);
1849 vty_out(vty, "\n");
1850 }
1851 }
1852 }
1853
1854 if (uj) {
9d303b37
DL
1855 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1856 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 1857 json_object_free(json);
1858 } else {
1859 {
1860 if (!found_neighbor)
1861 vty_out(vty,
1862 "%% No such interface or neighbor\n");
1863 }
1864 }
1865}
1866
64c86530 1867static void pim_show_state(struct pim_instance *pim, struct vty *vty,
7cfc7bcf
DS
1868 const char *src_or_group, const char *group,
1869 u_char uj)
d62a17ae 1870{
1871 struct channel_oil *c_oil;
1872 struct listnode *node;
1873 json_object *json = NULL;
1874 json_object *json_group = NULL;
1875 json_object *json_ifp_in = NULL;
1876 json_object *json_ifp_out = NULL;
1877 json_object *json_source = NULL;
1878 time_t now;
1879 int first_oif;
1880 now = pim_time_monotonic_sec();
1881
1882 if (uj) {
1883 json = json_object_new_object();
1884 } else {
1885 vty_out(vty,
1886 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1887 vty_out(vty,
1888 "\nInstalled Source Group IIF OIL\n");
1889 }
1890
c68ba0d7 1891 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 1892 char grp_str[INET_ADDRSTRLEN];
1893 char src_str[INET_ADDRSTRLEN];
1894 char in_ifname[INTERFACE_NAMSIZ + 1];
1895 char out_ifname[INTERFACE_NAMSIZ + 1];
1896 int oif_vif_index;
1897 struct interface *ifp_in;
1898 first_oif = 1;
1899
1900 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
1901 sizeof(grp_str));
1902 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
1903 sizeof(src_str));
7cfc7bcf 1904 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 1905
1906 if (ifp_in)
1907 strcpy(in_ifname, ifp_in->name);
1908 else
1909 strcpy(in_ifname, "<iif?>");
1910
1911 if (src_or_group) {
1912 if (strcmp(src_or_group, src_str)
1913 && strcmp(src_or_group, grp_str))
1914 continue;
1915
1916 if (group && strcmp(group, grp_str))
1917 continue;
1918 }
1919
1920 if (uj) {
1921
1922 /* Find the group, create it if it doesn't exist */
1923 json_object_object_get_ex(json, grp_str, &json_group);
1924
1925 if (!json_group) {
1926 json_group = json_object_new_object();
1927 json_object_object_add(json, grp_str,
1928 json_group);
1929 }
1930
1931 /* Find the source nested under the group, create it if
1932 * it doesn't exist */
1933 json_object_object_get_ex(json_group, src_str,
1934 &json_source);
1935
1936 if (!json_source) {
1937 json_source = json_object_new_object();
1938 json_object_object_add(json_group, src_str,
1939 json_source);
1940 }
1941
1942 /* Find the inbound interface nested under the source,
1943 * create it if it doesn't exist */
1944 json_object_object_get_ex(json_source, in_ifname,
1945 &json_ifp_in);
1946
1947 if (!json_ifp_in) {
1948 json_ifp_in = json_object_new_object();
1949 json_object_object_add(json_source, in_ifname,
1950 json_ifp_in);
1951 json_object_int_add(json_source, "Installed",
1952 c_oil->installed);
1953 json_object_int_add(json_source, "RefCount",
1954 c_oil->oil_ref_count);
1955 json_object_int_add(json_source, "OilListSize",
1956 c_oil->oil_size);
1957 json_object_int_add(
1958 json_source, "OilRescan",
1959 c_oil->oil_inherited_rescan);
1960 json_object_int_add(json_source, "LastUsed",
1961 c_oil->cc.lastused);
1962 json_object_int_add(json_source, "PacketCount",
1963 c_oil->cc.pktcnt);
1964 json_object_int_add(json_source, "ByteCount",
1965 c_oil->cc.bytecnt);
1966 json_object_int_add(json_source,
1967 "WrongInterface",
1968 c_oil->cc.wrong_if);
1969 }
1970 } else {
1971 vty_out(vty, "%-9d %-15s %-15s %-7s ",
1972 c_oil->installed, src_str, grp_str,
1973 ifp_in->name);
1974 }
1975
1976 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
1977 ++oif_vif_index) {
1978 struct interface *ifp_out;
1979 char oif_uptime[10];
1980 int ttl;
1981
1982 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
1983 if (ttl < 1)
1984 continue;
1985
7cfc7bcf 1986 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 1987 pim_time_uptime(
1988 oif_uptime, sizeof(oif_uptime),
1989 now - c_oil->oif_creation[oif_vif_index]);
1990
1991 if (ifp_out)
1992 strcpy(out_ifname, ifp_out->name);
1993 else
1994 strcpy(out_ifname, "<oif?>");
1995
1996 if (uj) {
1997 json_ifp_out = json_object_new_object();
1998 json_object_string_add(json_ifp_out, "source",
1999 src_str);
2000 json_object_string_add(json_ifp_out, "group",
2001 grp_str);
2002 json_object_string_add(json_ifp_out,
2003 "inboundInterface",
2004 in_ifname);
2005 json_object_string_add(json_ifp_out,
2006 "outboundInterface",
2007 out_ifname);
2008 json_object_int_add(json_ifp_out, "installed",
2009 c_oil->installed);
2010
2011 json_object_object_add(json_ifp_in, out_ifname,
2012 json_ifp_out);
2013 } else {
2014 if (first_oif) {
2015 first_oif = 0;
2016 vty_out(vty, "%s(%c%c%c%c)", out_ifname,
2017 (c_oil->oif_flags[oif_vif_index]
2018 & PIM_OIF_FLAG_PROTO_IGMP)
2019 ? 'I'
2020 : ' ',
2021 (c_oil->oif_flags[oif_vif_index]
2022 & PIM_OIF_FLAG_PROTO_PIM)
2023 ? 'J'
2024 : ' ',
2025 (c_oil->oif_flags[oif_vif_index]
2026 & PIM_OIF_FLAG_PROTO_SOURCE)
2027 ? 'S'
2028 : ' ',
2029 (c_oil->oif_flags[oif_vif_index]
2030 & PIM_OIF_FLAG_PROTO_STAR)
2031 ? '*'
2032 : ' ');
2033 } else
2034 vty_out(vty, ", %s(%c%c%c%c)",
2035 out_ifname,
2036 (c_oil->oif_flags[oif_vif_index]
2037 & PIM_OIF_FLAG_PROTO_IGMP)
2038 ? 'I'
2039 : ' ',
2040 (c_oil->oif_flags[oif_vif_index]
2041 & PIM_OIF_FLAG_PROTO_PIM)
2042 ? 'J'
2043 : ' ',
2044 (c_oil->oif_flags[oif_vif_index]
2045 & PIM_OIF_FLAG_PROTO_SOURCE)
2046 ? 'S'
2047 : ' ',
2048 (c_oil->oif_flags[oif_vif_index]
2049 & PIM_OIF_FLAG_PROTO_STAR)
2050 ? '*'
2051 : ' ');
2052 }
2053 }
2054
2055 if (!uj)
2056 vty_out(vty, "\n");
2057 }
2058
2059
2060 if (uj) {
9d303b37
DL
2061 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2062 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2063 json_object_free(json);
2064 } else {
2065 vty_out(vty, "\n");
2066 }
31a21c9c
DW
2067}
2068
64c86530 2069static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2070 u_char uj)
12e41d03 2071{
d62a17ae 2072 struct listnode *node;
2073 struct listnode *neighnode;
2074 struct interface *ifp;
2075 struct pim_interface *pim_ifp;
2076 struct pim_neighbor *neigh;
2077 time_t now;
2078 char uptime[10];
2079 char expire[10];
2080 char neigh_src_str[INET_ADDRSTRLEN];
2081 json_object *json = NULL;
2082 json_object *json_ifp_rows = NULL;
2083 json_object *json_row = NULL;
2084
2085 now = pim_time_monotonic_sec();
2086
2087 if (uj) {
2088 json = json_object_new_object();
2089 } else {
2090 vty_out(vty,
2091 "Interface Neighbor Uptime Holdtime DR Pri\n");
2092 }
2093
c68ba0d7 2094 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 2095 pim_ifp = ifp->info;
2096
2097 if (!pim_ifp)
2098 continue;
2099
2100 if (pim_ifp->pim_sock_fd < 0)
2101 continue;
2102
2103 if (uj)
2104 json_ifp_rows = json_object_new_object();
2105
2106 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2107 neigh)) {
2108 pim_inet4_dump("<src?>", neigh->source_addr,
2109 neigh_src_str, sizeof(neigh_src_str));
2110 pim_time_uptime(uptime, sizeof(uptime),
2111 now - neigh->creation);
2112 pim_time_timer_to_hhmmss(expire, sizeof(expire),
2113 neigh->t_expire_timer);
2114
2115 if (uj) {
2116 json_row = json_object_new_object();
2117 json_object_string_add(json_row, "interface",
2118 ifp->name);
2119 json_object_string_add(json_row, "neighbor",
2120 neigh_src_str);
2121 json_object_string_add(json_row, "upTime",
2122 uptime);
2123 json_object_string_add(json_row, "holdTime",
2124 expire);
2125 json_object_int_add(json_row, "holdTimeMax",
2126 neigh->holdtime);
2127 json_object_int_add(json_row, "drPriority",
2128 neigh->dr_priority);
2129 json_object_object_add(json_ifp_rows,
2130 neigh_src_str, json_row);
2131
2132 } else {
2133 vty_out(vty, "%-9s %15s %8s %8s %6d\n",
2134 ifp->name, neigh_src_str, uptime,
2135 expire, neigh->dr_priority);
2136 }
2137 }
2138
2139 if (uj) {
2140 json_object_object_add(json, ifp->name, json_ifp_rows);
2141 json_ifp_rows = NULL;
2142 }
2143 }
2144
2145 if (uj) {
9d303b37
DL
2146 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2147 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2148 json_object_free(json);
2149 }
12e41d03
DL
2150}
2151
64c86530
DS
2152static void pim_show_neighbors_secondary(struct pim_instance *pim,
2153 struct vty *vty)
12e41d03 2154{
d62a17ae 2155 struct listnode *node;
2156 struct interface *ifp;
12e41d03 2157
d62a17ae 2158 vty_out(vty,
2159 "Interface Address Neighbor Secondary \n");
12e41d03 2160
c68ba0d7 2161 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
d62a17ae 2162 struct pim_interface *pim_ifp;
2163 struct in_addr ifaddr;
2164 struct listnode *neighnode;
2165 struct pim_neighbor *neigh;
12e41d03 2166
d62a17ae 2167 pim_ifp = ifp->info;
12e41d03 2168
d62a17ae 2169 if (!pim_ifp)
2170 continue;
12e41d03 2171
d62a17ae 2172 if (pim_ifp->pim_sock_fd < 0)
2173 continue;
12e41d03 2174
d62a17ae 2175 ifaddr = pim_ifp->primary_address;
12e41d03 2176
d62a17ae 2177 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2178 neigh)) {
2179 char neigh_src_str[INET_ADDRSTRLEN];
2180 struct listnode *prefix_node;
2181 struct prefix *p;
12e41d03 2182
d62a17ae 2183 if (!neigh->prefix_list)
2184 continue;
12e41d03 2185
d62a17ae 2186 pim_inet4_dump("<src?>", neigh->source_addr,
2187 neigh_src_str, sizeof(neigh_src_str));
12e41d03 2188
d62a17ae 2189 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
2190 prefix_node, p)) {
2191 char neigh_sec_str[PREFIX2STR_BUFFER];
12e41d03 2192
d62a17ae 2193 prefix2str(p, neigh_sec_str,
2194 sizeof(neigh_sec_str));
2195
2196 vty_out(vty, "%-9s %-15s %-15s %-15s\n",
2197 ifp->name, inet_ntoa(ifaddr),
2198 neigh_src_str, neigh_sec_str);
2199 }
2200 }
2201 }
12e41d03
DL
2202}
2203
d62a17ae 2204static void json_object_pim_upstream_add(json_object *json,
2205 struct pim_upstream *up)
9bf3c633 2206{
d62a17ae 2207 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
2208 json_object_boolean_true_add(json, "drJoinDesired");
9bf3c633 2209
d62a17ae 2210 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
2211 json_object_boolean_true_add(json, "drJoinDesiredUpdated");
9bf3c633 2212
d62a17ae 2213 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
2214 json_object_boolean_true_add(json, "firstHopRouter");
9bf3c633 2215
d62a17ae 2216 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
2217 json_object_boolean_true_add(json, "sourceIgmp");
9bf3c633 2218
d62a17ae 2219 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
2220 json_object_boolean_true_add(json, "sourcePim");
7667c556 2221
d62a17ae 2222 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
2223 json_object_boolean_true_add(json, "sourceStream");
9bf3c633 2224
d62a17ae 2225 /* XXX: need to print ths flag in the plain text display as well */
2226 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
2227 json_object_boolean_true_add(json, "sourceMsdp");
755210ab 2228}
2229
2230static const char *
d62a17ae 2231pim_upstream_state2brief_str(enum pim_upstream_state join_state,
2232 char *state_str)
2233{
2234 switch (join_state) {
2235 case PIM_UPSTREAM_NOTJOINED:
2236 strcpy(state_str, "NotJ");
2237 break;
2238 case PIM_UPSTREAM_JOINED:
2239 strcpy(state_str, "J");
2240 break;
2241 default:
2242 strcpy(state_str, "Unk");
2243 }
2244 return state_str;
2245}
2246
2247static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
2248 char *state_str)
2249{
2250 switch (reg_state) {
2251 case PIM_REG_NOINFO:
2252 strcpy(state_str, "RegNI");
2253 break;
2254 case PIM_REG_JOIN:
2255 strcpy(state_str, "RegJ");
2256 break;
2257 case PIM_REG_JOIN_PENDING:
2258 case PIM_REG_PRUNE:
2259 strcpy(state_str, "RegP");
2260 break;
2261 default:
2262 strcpy(state_str, "Unk");
2263 }
2264 return state_str;
755210ab 2265}
2266
64c86530 2267static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
c3169ac7 2268 u_char uj)
12e41d03 2269{
d62a17ae 2270 struct listnode *upnode;
2271 struct pim_upstream *up;
2272 time_t now;
2273 json_object *json = NULL;
2274 json_object *json_group = NULL;
2275 json_object *json_row = NULL;
2276
2277 now = pim_time_monotonic_sec();
2278
2279 if (uj)
2280 json = json_object_new_object();
2281 else
2282 vty_out(vty,
2283 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2284
c3169ac7 2285 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
d62a17ae 2286 char src_str[INET_ADDRSTRLEN];
2287 char grp_str[INET_ADDRSTRLEN];
2288 char uptime[10];
2289 char join_timer[10];
2290 char rs_timer[10];
2291 char ka_timer[10];
2292 char msdp_reg_timer[10];
2293 char state_str[PIM_REG_STATE_STR_LEN];
2294
2295 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2296 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2297 pim_time_uptime(uptime, sizeof(uptime),
2298 now - up->state_transition);
2299 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
2300 up->t_join_timer);
2301
2302 /*
2303 * If we have a J/P timer for the neighbor display that
2304 */
2305 if (!up->t_join_timer) {
2306 struct pim_neighbor *nbr;
2307
2308 nbr = pim_neighbor_find(
2309 up->rpf.source_nexthop.interface,
2310 up->rpf.rpf_addr.u.prefix4);
2311 if (nbr)
2312 pim_time_timer_to_hhmmss(join_timer,
2313 sizeof(join_timer),
2314 nbr->jp_timer);
2315 }
2316
2317 pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
2318 up->t_rs_timer);
2319 pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
2320 up->t_ka_timer);
2321 pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
2322 up->t_msdp_reg_timer);
2323
2324 pim_upstream_state2brief_str(up->join_state, state_str);
2325 if (up->reg_state != PIM_REG_NOINFO) {
2326 char tmp_str[PIM_REG_STATE_STR_LEN];
2327
2328 sprintf(state_str + strlen(state_str), ",%s",
2329 pim_reg_state2brief_str(up->reg_state,
2330 tmp_str));
2331 }
2332
2333 if (uj) {
2334 json_object_object_get_ex(json, grp_str, &json_group);
2335
2336 if (!json_group) {
2337 json_group = json_object_new_object();
2338 json_object_object_add(json, grp_str,
2339 json_group);
2340 }
2341
2342 json_row = json_object_new_object();
2343 json_object_pim_upstream_add(json_row, up);
2344 json_object_string_add(
2345 json_row, "inboundInterface",
2346 up->rpf.source_nexthop.interface->name);
2347 json_object_string_add(json_row, "source", src_str);
2348 json_object_string_add(json_row, "group", grp_str);
2349 json_object_string_add(json_row, "state", state_str);
2350 json_object_string_add(
2351 json_row, "joinState",
2352 pim_upstream_state2str(up->join_state));
2353 json_object_string_add(
2354 json_row, "regState",
2355 pim_reg_state2str(up->reg_state, state_str));
2356 json_object_string_add(json_row, "upTime", uptime);
2357 json_object_string_add(json_row, "joinTimer",
2358 join_timer);
2359 json_object_string_add(json_row, "resetTimer",
2360 rs_timer);
2361 json_object_string_add(json_row, "keepaliveTimer",
2362 ka_timer);
2363 json_object_string_add(json_row, "msdpRegTimer",
2364 msdp_reg_timer);
2365 json_object_int_add(json_row, "refCount",
2366 up->ref_count);
2367 json_object_int_add(json_row, "sptBit", up->sptbit);
2368 json_object_object_add(json_group, src_str, json_row);
2369 } else {
2370 vty_out(vty,
2371 "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2372 up->rpf.source_nexthop.interface->name, src_str,
2373 grp_str, state_str, uptime, join_timer,
2374 rs_timer, ka_timer, up->ref_count);
2375 }
2376 }
2377
2378 if (uj) {
9d303b37
DL
2379 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2380 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2381 json_object_free(json);
2382 }
12e41d03
DL
2383}
2384
64c86530 2385static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
f88df3a6 2386 u_char uj)
12e41d03 2387{
d62a17ae 2388 struct listnode *chnode;
2389 struct pim_interface *pim_ifp;
2390 struct pim_ifchannel *ch;
2391 char src_str[INET_ADDRSTRLEN];
2392 char grp_str[INET_ADDRSTRLEN];
2393 json_object *json = NULL;
2394 json_object *json_group = NULL;
2395 json_object *json_row = NULL;
2396
2397 if (uj)
2398 json = json_object_new_object();
2399 else
2400 vty_out(vty,
2401 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2402
2403 /* scan per-interface (S,G) state */
f88df3a6 2404 for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, chnode, ch)) {
d62a17ae 2405 /* scan all interfaces */
2406 pim_ifp = ch->interface->info;
2407 if (!pim_ifp)
2408 continue;
2409
2410 struct pim_upstream *up = ch->upstream;
2411
2412 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2413 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2414
2415 if (uj) {
2416 json_object_object_get_ex(json, grp_str, &json_group);
2417
2418 if (!json_group) {
2419 json_group = json_object_new_object();
2420 json_object_object_add(json, grp_str,
2421 json_group);
2422 }
2423
2424 json_row = json_object_new_object();
2425 json_object_pim_upstream_add(json_row, up);
2426 json_object_string_add(json_row, "interface",
2427 ch->interface->name);
2428 json_object_string_add(json_row, "source", src_str);
2429 json_object_string_add(json_row, "group", grp_str);
2430
2431 if (pim_macro_ch_lost_assert(ch))
2432 json_object_boolean_true_add(json_row,
2433 "lostAssert");
2434
2435 if (pim_macro_chisin_joins(ch))
2436 json_object_boolean_true_add(json_row, "joins");
2437
2438 if (pim_macro_chisin_pim_include(ch))
2439 json_object_boolean_true_add(json_row,
2440 "pimInclude");
2441
c3169ac7 2442 if (pim_upstream_evaluate_join_desired(pim, up))
d62a17ae 2443 json_object_boolean_true_add(
2444 json_row, "evaluateJoinDesired");
2445
2446 json_object_object_add(json_group, src_str, json_row);
2447
2448 } else {
2449 vty_out(vty,
2450 "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2451 ch->interface->name, src_str, grp_str,
2452 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2453 pim_macro_chisin_joins(ch) ? "yes" : "no",
2454 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
2455 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
2456 up->flags)
2457 ? "yes"
2458 : "no",
c3169ac7 2459 pim_upstream_evaluate_join_desired(pim, up)
9b29ea95
DS
2460 ? "yes"
2461 : "no");
d62a17ae 2462 }
2463 }
2464
2465 if (uj) {
9d303b37
DL
2466 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2467 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2468 json_object_free(json);
2469 }
12e41d03
DL
2470}
2471
64c86530 2472static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2473 u_char uj)
12e41d03 2474{
d62a17ae 2475 struct listnode *upnode;
2476 struct pim_upstream *up;
2477 json_object *json = NULL;
2478 json_object *json_group = NULL;
2479 json_object *json_row = NULL;
2480
2481 if (uj)
2482 json = json_object_new_object();
2483 else
2484 vty_out(vty,
2485 "Source Group RpfIface RibNextHop RpfAddress \n");
2486
c68ba0d7 2487 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
d62a17ae 2488 char src_str[INET_ADDRSTRLEN];
2489 char grp_str[INET_ADDRSTRLEN];
2490 char rpf_nexthop_str[PREFIX_STRLEN];
2491 char rpf_addr_str[PREFIX_STRLEN];
2492 struct pim_rpf *rpf;
2493 const char *rpf_ifname;
2494
2495 rpf = &up->rpf;
2496
2497 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2498 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2499 pim_addr_dump("<nexthop?>",
2500 &rpf->source_nexthop.mrib_nexthop_addr,
2501 rpf_nexthop_str, sizeof(rpf_nexthop_str));
2502 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2503 sizeof(rpf_addr_str));
2504
9d303b37 2505 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2506
2507 if (uj) {
2508 json_object_object_get_ex(json, grp_str, &json_group);
2509
2510 if (!json_group) {
2511 json_group = json_object_new_object();
2512 json_object_object_add(json, grp_str,
2513 json_group);
2514 }
2515
2516 json_row = json_object_new_object();
2517 json_object_pim_upstream_add(json_row, up);
2518 json_object_string_add(json_row, "source", src_str);
2519 json_object_string_add(json_row, "group", grp_str);
2520 json_object_string_add(json_row, "rpfInterface",
2521 rpf_ifname);
2522 json_object_string_add(json_row, "ribNexthop",
2523 rpf_nexthop_str);
2524 json_object_string_add(json_row, "rpfAddress",
2525 rpf_addr_str);
2526 json_object_object_add(json_group, src_str, json_row);
2527 } else {
2528 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s\n", src_str,
2529 grp_str, rpf_ifname, rpf_nexthop_str,
2530 rpf_addr_str);
2531 }
2532 }
2533
2534 if (uj) {
9d303b37
DL
2535 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2536 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2537 json_object_free(json);
2538 }
2539}
2540
2541static void show_rpf_refresh_stats(struct vty *vty, time_t now,
2542 json_object *json)
2543{
2544 char refresh_uptime[10];
2545
2546 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
2547 qpim_rpf_cache_refresh_last);
2548
2549 if (json) {
2550 json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
2551 qpim_rpf_cache_refresh_delay_msec);
2552 json_object_int_add(
2553 json, "rpfCacheRefreshTimer",
2554 pim_time_timer_remain_msec(qpim_rpf_cache_refresher));
2555 json_object_int_add(json, "rpfCacheRefreshRequests",
2556 qpim_rpf_cache_refresh_requests);
2557 json_object_int_add(json, "rpfCacheRefreshEvents",
2558 qpim_rpf_cache_refresh_events);
2559 json_object_string_add(json, "rpfCacheRefreshLast",
2560 refresh_uptime);
2561 json_object_int_add(json, "nexthopLookups",
2562 qpim_nexthop_lookups);
2563 json_object_int_add(json, "nexthopLookupsAvoided",
2564 nexthop_lookups_avoided);
2565 } else {
2566 vty_out(vty,
2567 "RPF Cache Refresh Delay: %ld msecs\n"
2568 "RPF Cache Refresh Timer: %ld msecs\n"
2569 "RPF Cache Refresh Requests: %lld\n"
2570 "RPF Cache Refresh Events: %lld\n"
2571 "RPF Cache Refresh Last: %s\n"
2572 "Nexthop Lookups: %lld\n"
2573 "Nexthop Lookups Avoided: %lld\n",
2574 qpim_rpf_cache_refresh_delay_msec,
2575 pim_time_timer_remain_msec(qpim_rpf_cache_refresher),
2576 (long long)qpim_rpf_cache_refresh_requests,
2577 (long long)qpim_rpf_cache_refresh_events,
2578 refresh_uptime, (long long)qpim_nexthop_lookups,
2579 (long long)nexthop_lookups_avoided);
2580 }
12e41d03
DL
2581}
2582
64c86530 2583static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2584 time_t now)
12e41d03 2585{
d62a17ae 2586 char uptime_scan_oil[10];
2587 char uptime_mroute_add[10];
2588 char uptime_mroute_del[10];
12e41d03 2589
d62a17ae 2590 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
2591 qpim_scan_oil_last);
2592 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
c68ba0d7 2593 pim->mroute_add_last);
d62a17ae 2594 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
c68ba0d7 2595 pim->mroute_del_last);
12e41d03 2596
d62a17ae 2597 vty_out(vty,
2598 "Scan OIL - Last: %s Events: %lld\n"
2599 "MFC Add - Last: %s Events: %lld\n"
2600 "MFC Del - Last: %s Events: %lld\n",
2601 uptime_scan_oil, (long long)qpim_scan_oil_events,
c68ba0d7
DS
2602 uptime_mroute_add, (long long)pim->mroute_add_events,
2603 uptime_mroute_del, (long long)pim->mroute_del_events);
12e41d03
DL
2604}
2605
64c86530 2606static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, u_char uj)
12e41d03 2607{
d62a17ae 2608 struct listnode *up_node;
2609 struct pim_upstream *up;
2610 time_t now = pim_time_monotonic_sec();
2611 json_object *json = NULL;
2612 json_object *json_group = NULL;
2613 json_object *json_row = NULL;
2614
2615 if (uj) {
2616 json = json_object_new_object();
2617 show_rpf_refresh_stats(vty, now, json);
2618 } else {
2619 show_rpf_refresh_stats(vty, now, json);
2620 vty_out(vty, "\n");
2621 vty_out(vty,
2622 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2623 }
cba44481 2624
c68ba0d7 2625 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
d62a17ae 2626 char src_str[INET_ADDRSTRLEN];
2627 char grp_str[INET_ADDRSTRLEN];
2628 char rpf_addr_str[PREFIX_STRLEN];
2629 char rib_nexthop_str[PREFIX_STRLEN];
2630 const char *rpf_ifname;
2631 struct pim_rpf *rpf = &up->rpf;
2632
2633 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2634 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2635 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2636 sizeof(rpf_addr_str));
2637 pim_addr_dump("<nexthop?>",
2638 &rpf->source_nexthop.mrib_nexthop_addr,
2639 rib_nexthop_str, sizeof(rib_nexthop_str));
2640
9d303b37 2641 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
d62a17ae 2642
2643 if (uj) {
2644 json_object_object_get_ex(json, grp_str, &json_group);
2645
2646 if (!json_group) {
2647 json_group = json_object_new_object();
2648 json_object_object_add(json, grp_str,
2649 json_group);
2650 }
2651
2652 json_row = json_object_new_object();
2653 json_object_string_add(json_row, "source", src_str);
2654 json_object_string_add(json_row, "group", grp_str);
2655 json_object_string_add(json_row, "rpfInterface",
2656 rpf_ifname);
2657 json_object_string_add(json_row, "rpfAddress",
2658 rpf_addr_str);
2659 json_object_string_add(json_row, "ribNexthop",
2660 rib_nexthop_str);
2661 json_object_int_add(
2662 json_row, "routeMetric",
2663 rpf->source_nexthop.mrib_route_metric);
2664 json_object_int_add(
2665 json_row, "routePreference",
2666 rpf->source_nexthop.mrib_metric_preference);
2667 json_object_object_add(json_group, src_str, json_row);
2668
2669 } else {
2670 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
2671 src_str, grp_str, rpf_ifname, rpf_addr_str,
2672 rib_nexthop_str,
2673 rpf->source_nexthop.mrib_route_metric,
2674 rpf->source_nexthop.mrib_metric_preference);
2675 }
2676 }
2677
2678 if (uj) {
9d303b37
DL
2679 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2680 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2681 json_object_free(json);
2682 }
cba44481
CS
2683}
2684
c68ba0d7
DS
2685struct pnc_cache_walk_data {
2686 struct vty *vty;
2687 struct pim_instance *pim;
2688};
2689
d62a17ae 2690static int pim_print_pnc_cache_walkcb(struct hash_backet *backet, void *arg)
12e41d03 2691{
d62a17ae 2692 struct pim_nexthop_cache *pnc = backet->data;
c68ba0d7
DS
2693 struct pnc_cache_walk_data *cwd = arg;
2694 struct vty *vty = cwd->vty;
2695 struct pim_instance *pim = cwd->pim;
d62a17ae 2696 struct nexthop *nh_node = NULL;
2697 ifindex_t first_ifindex;
2698 struct interface *ifp = NULL;
2699
2700 if (!pnc)
2701 return CMD_SUCCESS;
2702
2703 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
2704 first_ifindex = nh_node->ifindex;
c68ba0d7 2705 ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
d62a17ae 2706
2707 vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
2708 vty_out(vty, "%-14s ", ifp ? ifp->name : "NULL");
2709 vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
2710 vty_out(vty, "\n");
2711 }
2712 return CMD_SUCCESS;
2713}
2714
64c86530 2715static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
d62a17ae 2716{
c68ba0d7 2717 struct pnc_cache_walk_data cwd;
d62a17ae 2718
c68ba0d7
DS
2719 cwd.vty = vty;
2720 cwd.pim = pim;
2721 vty_out(vty, "Number of registered addresses: %lu\n",
2722 pim->rpf_hash->count);
d62a17ae 2723 vty_out(vty, "Address Interface Nexthop\n");
2724 vty_out(vty, "-------------------------------------------\n");
12e41d03 2725
c68ba0d7 2726 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
d62a17ae 2727}
2728
64c86530 2729static void igmp_show_groups(struct pim_instance *pim, struct vty *vty,
c68ba0d7 2730 u_char uj)
d62a17ae 2731{
2732 struct listnode *ifnode;
2733 struct interface *ifp;
2734 time_t now;
2735 json_object *json = NULL;
2736 json_object *json_iface = NULL;
2737 json_object *json_row = NULL;
2738
2739 now = pim_time_monotonic_sec();
2740
2741 if (uj)
2742 json = json_object_new_object();
2743 else
2744 vty_out(vty,
2745 "Interface Address Group Mode Timer Srcs V Uptime \n");
2746
2747 /* scan interfaces */
c68ba0d7 2748 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
d62a17ae 2749 struct pim_interface *pim_ifp = ifp->info;
2750 struct listnode *sock_node;
2751 struct igmp_sock *igmp;
2752
2753 if (!pim_ifp)
2754 continue;
2755
2756 /* scan igmp sockets */
2757 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
2758 igmp)) {
2759 char ifaddr_str[INET_ADDRSTRLEN];
2760 struct listnode *grpnode;
2761 struct igmp_group *grp;
2762
2763 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
2764 sizeof(ifaddr_str));
2765
2766 /* scan igmp groups */
2767 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
2768 grpnode, grp)) {
2769 char group_str[INET_ADDRSTRLEN];
2770 char hhmmss[10];
2771 char uptime[10];
2772
2773 pim_inet4_dump("<group?>", grp->group_addr,
2774 group_str, sizeof(group_str));
2775 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
2776 grp->t_group_timer);
2777 pim_time_uptime(uptime, sizeof(uptime),
2778 now - grp->group_creation);
2779
2780 if (uj) {
2781 json_object_object_get_ex(
2782 json, ifp->name, &json_iface);
2783
2784 if (!json_iface) {
2785 json_iface =
2786 json_object_new_object();
2787 json_object_pim_ifp_add(
2788 json_iface, ifp);
2789 json_object_object_add(
2790 json, ifp->name,
2791 json_iface);
2792 }
2793
2794 json_row = json_object_new_object();
2795 json_object_string_add(
2796 json_row, "source", ifaddr_str);
2797 json_object_string_add(
2798 json_row, "group", group_str);
2799
2800 if (grp->igmp_version == 3)
2801 json_object_string_add(
2802 json_row, "mode",
2803 grp->group_filtermode_isexcl
2804 ? "EXCLUDE"
2805 : "INCLUDE");
2806
2807 json_object_string_add(json_row,
2808 "timer", hhmmss);
2809 json_object_int_add(
2810 json_row, "sourcesCount",
2811 grp->group_source_list
2812 ? listcount(
2813 grp->group_source_list)
2814 : 0);
2815 json_object_int_add(json_row, "version",
2816 grp->igmp_version);
2817 json_object_string_add(
2818 json_row, "uptime", uptime);
2819 json_object_object_add(json_iface,
2820 group_str,
2821 json_row);
2822
2823 } else {
2824 vty_out(vty,
2825 "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
2826 ifp->name, ifaddr_str,
2827 group_str,
2828 grp->igmp_version == 3
2829 ? (grp->group_filtermode_isexcl
2830 ? "EXCL"
2831 : "INCL")
2832 : "----",
2833 hhmmss,
2834 grp->group_source_list
2835 ? listcount(
2836 grp->group_source_list)
2837 : 0,
2838 grp->igmp_version, uptime);
2839 }
2840 } /* scan igmp groups */
2841 } /* scan igmp sockets */
2842 } /* scan interfaces */
2843
2844 if (uj) {
9d303b37
DL
2845 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2846 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 2847 json_object_free(json);
2848 }
12e41d03
DL
2849}
2850
64c86530
DS
2851static void igmp_show_group_retransmission(struct pim_instance *pim,
2852 struct vty *vty)
12e41d03 2853{
d62a17ae 2854 struct listnode *ifnode;
2855 struct interface *ifp;
2856
2857 vty_out(vty,
2858 "Interface Address Group RetTimer Counter RetSrcs\n");
2859
2860 /* scan interfaces */
c68ba0d7 2861 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
d62a17ae 2862 struct pim_interface *pim_ifp = ifp->info;
2863 struct listnode *sock_node;
2864 struct igmp_sock *igmp;
2865
2866 if (!pim_ifp)
2867 continue;
2868
2869 /* scan igmp sockets */
2870 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
2871 igmp)) {
2872 char ifaddr_str[INET_ADDRSTRLEN];
2873 struct listnode *grpnode;
2874 struct igmp_group *grp;
2875
2876 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
2877 sizeof(ifaddr_str));
2878
2879 /* scan igmp groups */
2880 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
2881 grpnode, grp)) {
2882 char group_str[INET_ADDRSTRLEN];
2883 char grp_retr_mmss[10];
2884 struct listnode *src_node;
2885 struct igmp_source *src;
2886 int grp_retr_sources = 0;
2887
2888 pim_inet4_dump("<group?>", grp->group_addr,
2889 group_str, sizeof(group_str));
2890 pim_time_timer_to_mmss(
2891 grp_retr_mmss, sizeof(grp_retr_mmss),
2892 grp->t_group_query_retransmit_timer);
2893
2894
2895 /* count group sources with retransmission state
2896 */
2897 for (ALL_LIST_ELEMENTS_RO(
2898 grp->group_source_list, src_node,
2899 src)) {
2900 if (src->source_query_retransmit_count
2901 > 0) {
2902 ++grp_retr_sources;
2903 }
2904 }
2905
2906 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d\n",
2907 ifp->name, ifaddr_str, group_str,
2908 grp_retr_mmss,
2909 grp->group_specific_query_retransmit_count,
2910 grp_retr_sources);
2911
2912 } /* scan igmp groups */
2913 } /* scan igmp sockets */
2914 } /* scan interfaces */
12e41d03
DL
2915}
2916
64c86530 2917static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
12e41d03 2918{
d62a17ae 2919 struct listnode *ifnode;
2920 struct interface *ifp;
2921 time_t now;
2922
2923 now = pim_time_monotonic_sec();
2924
2925 vty_out(vty,
2926 "Interface Address Group Source Timer Fwd Uptime \n");
2927
2928 /* scan interfaces */
c68ba0d7 2929 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
d62a17ae 2930 struct pim_interface *pim_ifp = ifp->info;
2931 struct listnode *sock_node;
2932 struct igmp_sock *igmp;
2933
2934 if (!pim_ifp)
2935 continue;
2936
2937 /* scan igmp sockets */
2938 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
2939 igmp)) {
2940 char ifaddr_str[INET_ADDRSTRLEN];
2941 struct listnode *grpnode;
2942 struct igmp_group *grp;
2943
2944 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
2945 sizeof(ifaddr_str));
2946
2947 /* scan igmp groups */
2948 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
2949 grpnode, grp)) {
2950 char group_str[INET_ADDRSTRLEN];
2951 struct listnode *srcnode;
2952 struct igmp_source *src;
2953
2954 pim_inet4_dump("<group?>", grp->group_addr,
2955 group_str, sizeof(group_str));
2956
2957 /* scan group sources */
2958 for (ALL_LIST_ELEMENTS_RO(
2959 grp->group_source_list, srcnode,
2960 src)) {
2961 char source_str[INET_ADDRSTRLEN];
2962 char mmss[10];
2963 char uptime[10];
2964
2965 pim_inet4_dump(
2966 "<source?>", src->source_addr,
2967 source_str, sizeof(source_str));
2968
2969 pim_time_timer_to_mmss(
2970 mmss, sizeof(mmss),
2971 src->t_source_timer);
2972
2973 pim_time_uptime(
2974 uptime, sizeof(uptime),
2975 now - src->source_creation);
2976
2977 vty_out(vty,
2978 "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
2979 ifp->name, ifaddr_str,
2980 group_str, source_str, mmss,
2981 IGMP_SOURCE_TEST_FORWARDING(
2982 src->source_flags)
2983 ? "Y"
2984 : "N",
2985 uptime);
2986
2987 } /* scan group sources */
2988 } /* scan igmp groups */
2989 } /* scan igmp sockets */
2990 } /* scan interfaces */
12e41d03
DL
2991}
2992
64c86530
DS
2993static void igmp_show_source_retransmission(struct pim_instance *pim,
2994 struct vty *vty)
12e41d03 2995{
d62a17ae 2996 struct listnode *ifnode;
2997 struct interface *ifp;
2998
2999 vty_out(vty,
3000 "Interface Address Group Source Counter\n");
3001
3002 /* scan interfaces */
c68ba0d7 3003 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
d62a17ae 3004 struct pim_interface *pim_ifp = ifp->info;
3005 struct listnode *sock_node;
3006 struct igmp_sock *igmp;
3007
3008 if (!pim_ifp)
3009 continue;
3010
3011 /* scan igmp sockets */
3012 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3013 igmp)) {
3014 char ifaddr_str[INET_ADDRSTRLEN];
3015 struct listnode *grpnode;
3016 struct igmp_group *grp;
3017
3018 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3019 sizeof(ifaddr_str));
3020
3021 /* scan igmp groups */
3022 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3023 grpnode, grp)) {
3024 char group_str[INET_ADDRSTRLEN];
3025 struct listnode *srcnode;
3026 struct igmp_source *src;
3027
3028 pim_inet4_dump("<group?>", grp->group_addr,
3029 group_str, sizeof(group_str));
3030
3031 /* scan group sources */
3032 for (ALL_LIST_ELEMENTS_RO(
3033 grp->group_source_list, srcnode,
3034 src)) {
3035 char source_str[INET_ADDRSTRLEN];
3036
3037 pim_inet4_dump(
3038 "<source?>", src->source_addr,
3039 source_str, sizeof(source_str));
3040
3041 vty_out(vty,
3042 "%-9s %-15s %-15s %-15s %7d\n",
3043 ifp->name, ifaddr_str,
3044 group_str, source_str,
3045 src->source_query_retransmit_count);
3046
3047 } /* scan group sources */
3048 } /* scan igmp groups */
3049 } /* scan igmp sockets */
3050 } /* scan interfaces */
12e41d03
DL
3051}
3052
c68ba0d7 3053static void clear_igmp_interfaces(struct pim_instance *pim)
12e41d03 3054{
d62a17ae 3055 struct listnode *ifnode;
3056 struct listnode *ifnextnode;
3057 struct interface *ifp;
12e41d03 3058
c68ba0d7 3059 for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode,
d62a17ae 3060 ifp)) {
3061 pim_if_addr_del_all_igmp(ifp);
3062 }
12e41d03 3063
c68ba0d7 3064 for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode,
d62a17ae 3065 ifp)) {
3066 pim_if_addr_add_all(ifp);
3067 }
12e41d03
DL
3068}
3069
c68ba0d7 3070static void clear_pim_interfaces(struct pim_instance *pim)
12e41d03 3071{
d62a17ae 3072 struct listnode *ifnode;
3073 struct listnode *ifnextnode;
3074 struct interface *ifp;
12e41d03 3075
c68ba0d7 3076 for (ALL_LIST_ELEMENTS(vrf_iflist(pim->vrf_id), ifnode, ifnextnode,
d62a17ae 3077 ifp)) {
3078 if (ifp->info) {
3079 pim_neighbor_delete_all(ifp, "interface cleared");
3080 }
3081 }
12e41d03
DL
3082}
3083
c68ba0d7 3084static void clear_interfaces(struct pim_instance *pim)
12e41d03 3085{
c68ba0d7
DS
3086 clear_igmp_interfaces(pim);
3087 clear_pim_interfaces(pim);
12e41d03
DL
3088}
3089
12e41d03
DL
3090DEFUN (clear_ip_interfaces,
3091 clear_ip_interfaces_cmd,
20a7e5fd 3092 "clear ip interfaces [vrf NAME]",
12e41d03
DL
3093 CLEAR_STR
3094 IP_STR
c68ba0d7
DS
3095 "Reset interfaces\n"
3096 VRF_CMD_HELP_STR)
12e41d03 3097{
c68ba0d7
DS
3098 int idx = 2;
3099 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3100
3101 if (!vrf)
3102 return CMD_WARNING;
3103
3104 clear_interfaces(vrf->info);
12e41d03 3105
d62a17ae 3106 return CMD_SUCCESS;
12e41d03
DL
3107}
3108
3109DEFUN (clear_ip_igmp_interfaces,
3110 clear_ip_igmp_interfaces_cmd,
20a7e5fd 3111 "clear ip igmp [vrf NAME] interfaces",
12e41d03
DL
3112 CLEAR_STR
3113 IP_STR
3114 CLEAR_IP_IGMP_STR
c68ba0d7 3115 VRF_CMD_HELP_STR
12e41d03
DL
3116 "Reset IGMP interfaces\n")
3117{
c68ba0d7
DS
3118 int idx = 2;
3119 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3120
3121 if (!vrf)
3122 return CMD_WARNING;
3123
3124 clear_igmp_interfaces(vrf->info);
12e41d03 3125
d62a17ae 3126 return CMD_SUCCESS;
12e41d03
DL
3127}
3128
c68ba0d7 3129static void mroute_add_all(struct pim_instance *pim)
12e41d03 3130{
d62a17ae 3131 struct listnode *node;
3132 struct channel_oil *c_oil;
3133
c68ba0d7 3134 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 3135 if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
3136 /* just log warning */
3137 char source_str[INET_ADDRSTRLEN];
3138 char group_str[INET_ADDRSTRLEN];
3139 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
3140 source_str, sizeof(source_str));
3141 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
3142 group_str, sizeof(group_str));
3143 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3144 __FILE__, __PRETTY_FUNCTION__, source_str,
3145 group_str);
3146 }
3147 }
12e41d03
DL
3148}
3149
c68ba0d7 3150static void mroute_del_all(struct pim_instance *pim)
12e41d03 3151{
d62a17ae 3152 struct listnode *node;
3153 struct channel_oil *c_oil;
3154
c68ba0d7 3155 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 3156 if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
3157 /* just log warning */
3158 char source_str[INET_ADDRSTRLEN];
3159 char group_str[INET_ADDRSTRLEN];
3160 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
3161 source_str, sizeof(source_str));
3162 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
3163 group_str, sizeof(group_str));
3164 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3165 __FILE__, __PRETTY_FUNCTION__, source_str,
3166 group_str);
3167 }
3168 }
12e41d03
DL
3169}
3170
3171DEFUN (clear_ip_mroute,
3172 clear_ip_mroute_cmd,
20a7e5fd 3173 "clear ip mroute [vrf NAME]",
12e41d03
DL
3174 CLEAR_STR
3175 IP_STR
c68ba0d7
DS
3176 "Reset multicast routes\n"
3177 VRF_CMD_HELP_STR)
12e41d03 3178{
c68ba0d7
DS
3179 int idx = 2;
3180 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3181
3182 if (!vrf)
3183 return CMD_WARNING;
3184
3185 mroute_del_all(vrf->info);
3186 mroute_add_all(vrf->info);
12e41d03 3187
d62a17ae 3188 return CMD_SUCCESS;
12e41d03
DL
3189}
3190
3191DEFUN (clear_ip_pim_interfaces,
3192 clear_ip_pim_interfaces_cmd,
20a7e5fd 3193 "clear ip pim [vrf NAME] interfaces",
12e41d03
DL
3194 CLEAR_STR
3195 IP_STR
3196 CLEAR_IP_PIM_STR
c68ba0d7 3197 VRF_CMD_HELP_STR
12e41d03
DL
3198 "Reset PIM interfaces\n")
3199{
c68ba0d7
DS
3200 int idx = 2;
3201 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3202
3203 if (!vrf)
3204 return CMD_WARNING;
3205
3206 clear_pim_interfaces(vrf->info);
12e41d03 3207
d62a17ae 3208 return CMD_SUCCESS;
12e41d03
DL
3209}
3210
39438188
CS
3211DEFUN (clear_ip_pim_interface_traffic,
3212 clear_ip_pim_interface_traffic_cmd,
20a7e5fd 3213 "clear ip pim [vrf NAME] interface traffic",
39438188
CS
3214 "Reset functions\n"
3215 "IP information\n"
3216 "PIM clear commands\n"
c68ba0d7 3217 VRF_CMD_HELP_STR
39438188
CS
3218 "Reset PIM interfaces\n"
3219 "Reset Protocol Packet counters\n")
3220{
c68ba0d7
DS
3221 int idx = 2;
3222 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3223 struct listnode *ifnode = NULL;
3224 struct listnode *ifnextnode = NULL;
3225 struct interface *ifp = NULL;
3226 struct pim_interface *pim_ifp = NULL;
3227
c68ba0d7
DS
3228 if (!vrf)
3229 return CMD_WARNING;
3230
3231 for (ALL_LIST_ELEMENTS(vrf_iflist(vrf->vrf_id), ifnode, ifnextnode,
d62a17ae 3232 ifp)) {
3233 pim_ifp = ifp->info;
3234
3235 if (!pim_ifp)
3236 continue;
3237
3238 pim_ifp->pim_ifstat_hello_recv = 0;
3239 pim_ifp->pim_ifstat_hello_sent = 0;
3240 pim_ifp->pim_ifstat_join_recv = 0;
3241 pim_ifp->pim_ifstat_join_send = 0;
3242 pim_ifp->pim_ifstat_prune_recv = 0;
3243 pim_ifp->pim_ifstat_prune_send = 0;
3244 pim_ifp->pim_ifstat_reg_recv = 0;
3245 pim_ifp->pim_ifstat_reg_send = 0;
3246 pim_ifp->pim_ifstat_reg_stop_recv = 0;
3247 pim_ifp->pim_ifstat_reg_stop_send = 0;
3248 pim_ifp->pim_ifstat_assert_recv = 0;
3249 pim_ifp->pim_ifstat_assert_send = 0;
3250 }
39438188 3251
d62a17ae 3252 return CMD_SUCCESS;
39438188
CS
3253}
3254
12e41d03
DL
3255DEFUN (clear_ip_pim_oil,
3256 clear_ip_pim_oil_cmd,
20a7e5fd 3257 "clear ip pim [vrf NAME] oil",
12e41d03
DL
3258 CLEAR_STR
3259 IP_STR
3260 CLEAR_IP_PIM_STR
c68ba0d7 3261 VRF_CMD_HELP_STR
12e41d03
DL
3262 "Rescan PIM OIL (output interface list)\n")
3263{
c68ba0d7
DS
3264 int idx = 2;
3265 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3266
3267 if (!vrf)
3268 return CMD_WARNING;
3269
3270 pim_scan_oil(vrf->info);
12e41d03 3271
d62a17ae 3272 return CMD_SUCCESS;
12e41d03
DL
3273}
3274
3275DEFUN (show_ip_igmp_interface,
3276 show_ip_igmp_interface_cmd,
20a7e5fd 3277 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
3278 SHOW_STR
3279 IP_STR
3280 IGMP_STR
c68ba0d7 3281 VRF_CMD_HELP_STR
a268493f 3282 "IGMP interface information\n"
9b91bb50 3283 "Detailed output\n"
a268493f
DW
3284 "interface name\n"
3285 "JavaScript Object Notation\n")
12e41d03 3286{
c68ba0d7
DS
3287 int idx = 2;
3288 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3289 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3290
3291 if (!vrf)
3292 return CMD_WARNING;
72e81cf4 3293
d62a17ae 3294 if (argv_find(argv, argc, "detail", &idx)
3295 || argv_find(argv, argc, "WORD", &idx))
64c86530 3296 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 3297 else
64c86530 3298 igmp_show_interfaces(vrf->info, vty, uj);
12e41d03 3299
d62a17ae 3300 return CMD_SUCCESS;
12e41d03
DL
3301}
3302
3303DEFUN (show_ip_igmp_join,
3304 show_ip_igmp_join_cmd,
20a7e5fd 3305 "show ip igmp [vrf NAME] join",
12e41d03
DL
3306 SHOW_STR
3307 IP_STR
3308 IGMP_STR
c68ba0d7 3309 VRF_CMD_HELP_STR
12e41d03
DL
3310 "IGMP static join information\n")
3311{
c68ba0d7
DS
3312 int idx = 2;
3313 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3314
3315 if (!vrf)
3316 return CMD_WARNING;
3317
64c86530 3318 igmp_show_interface_join(vrf->info, vty);
12e41d03 3319
d62a17ae 3320 return CMD_SUCCESS;
12e41d03
DL
3321}
3322
3323DEFUN (show_ip_igmp_groups,
3324 show_ip_igmp_groups_cmd,
20a7e5fd 3325 "show ip igmp [vrf NAME] groups [json]",
12e41d03
DL
3326 SHOW_STR
3327 IP_STR
3328 IGMP_STR
c68ba0d7 3329 VRF_CMD_HELP_STR
9b91bb50
DW
3330 IGMP_GROUP_STR
3331 "JavaScript Object Notation\n")
12e41d03 3332{
c68ba0d7
DS
3333 int idx = 2;
3334 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3335 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3336
3337 if (!vrf)
3338 return CMD_WARNING;
3339
64c86530 3340 igmp_show_groups(vrf->info, vty, uj);
12e41d03 3341
d62a17ae 3342 return CMD_SUCCESS;
12e41d03
DL
3343}
3344
3345DEFUN (show_ip_igmp_groups_retransmissions,
3346 show_ip_igmp_groups_retransmissions_cmd,
20a7e5fd 3347 "show ip igmp [vrf NAME] groups retransmissions",
12e41d03
DL
3348 SHOW_STR
3349 IP_STR
3350 IGMP_STR
c68ba0d7 3351 VRF_CMD_HELP_STR
12e41d03
DL
3352 IGMP_GROUP_STR
3353 "IGMP group retransmissions\n")
3354{
c68ba0d7
DS
3355 int idx = 2;
3356 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3357
3358 if (!vrf)
3359 return CMD_WARNING;
3360
64c86530 3361 igmp_show_group_retransmission(vrf->info, vty);
12e41d03 3362
d62a17ae 3363 return CMD_SUCCESS;
12e41d03
DL
3364}
3365
12e41d03
DL
3366DEFUN (show_ip_igmp_sources,
3367 show_ip_igmp_sources_cmd,
20a7e5fd 3368 "show ip igmp [vrf NAME] sources",
12e41d03
DL
3369 SHOW_STR
3370 IP_STR
3371 IGMP_STR
c68ba0d7 3372 VRF_CMD_HELP_STR
12e41d03
DL
3373 IGMP_SOURCE_STR)
3374{
c68ba0d7
DS
3375 int idx = 2;
3376 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3377
3378 if (!vrf)
3379 return CMD_WARNING;
3380
64c86530 3381 igmp_show_sources(vrf->info, vty);
12e41d03 3382
d62a17ae 3383 return CMD_SUCCESS;
12e41d03
DL
3384}
3385
3386DEFUN (show_ip_igmp_sources_retransmissions,
3387 show_ip_igmp_sources_retransmissions_cmd,
20a7e5fd 3388 "show ip igmp [vrf NAME] sources retransmissions",
12e41d03
DL
3389 SHOW_STR
3390 IP_STR
3391 IGMP_STR
c68ba0d7 3392 VRF_CMD_HELP_STR
12e41d03
DL
3393 IGMP_SOURCE_STR
3394 "IGMP source retransmissions\n")
3395{
c68ba0d7
DS
3396 int idx = 2;
3397 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3398
3399 if (!vrf)
3400 return CMD_WARNING;
3401
64c86530 3402 igmp_show_source_retransmission(vrf->info, vty);
12e41d03 3403
d62a17ae 3404 return CMD_SUCCESS;
12e41d03
DL
3405}
3406
12e41d03
DL
3407DEFUN (show_ip_pim_assert,
3408 show_ip_pim_assert_cmd,
20a7e5fd 3409 "show ip pim [vrf NAME] assert",
12e41d03
DL
3410 SHOW_STR
3411 IP_STR
3412 PIM_STR
c68ba0d7 3413 VRF_CMD_HELP_STR
12e41d03
DL
3414 "PIM interface assert\n")
3415{
c68ba0d7
DS
3416 int idx = 2;
3417 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3418
3419 if (!vrf)
3420 return CMD_WARNING;
3421
64c86530 3422 pim_show_assert(vrf->info, vty);
12e41d03 3423
d62a17ae 3424 return CMD_SUCCESS;
12e41d03
DL
3425}
3426
3427DEFUN (show_ip_pim_assert_internal,
3428 show_ip_pim_assert_internal_cmd,
20a7e5fd 3429 "show ip pim [vrf NAME] assert-internal",
12e41d03
DL
3430 SHOW_STR
3431 IP_STR
3432 PIM_STR
c68ba0d7 3433 VRF_CMD_HELP_STR
12e41d03
DL
3434 "PIM interface internal assert state\n")
3435{
c68ba0d7
DS
3436 int idx = 2;
3437 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3438
3439 if (!vrf)
3440 return CMD_WARNING;
3441
64c86530 3442 pim_show_assert_internal(vrf->info, vty);
12e41d03 3443
d62a17ae 3444 return CMD_SUCCESS;
12e41d03
DL
3445}
3446
3447DEFUN (show_ip_pim_assert_metric,
3448 show_ip_pim_assert_metric_cmd,
20a7e5fd 3449 "show ip pim [vrf NAME] assert-metric",
12e41d03
DL
3450 SHOW_STR
3451 IP_STR
3452 PIM_STR
c68ba0d7 3453 VRF_CMD_HELP_STR
12e41d03
DL
3454 "PIM interface assert metric\n")
3455{
c68ba0d7
DS
3456 int idx = 2;
3457 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3458
3459 if (!vrf)
3460 return CMD_WARNING;
3461
64c86530 3462 pim_show_assert_metric(vrf->info, vty);
12e41d03 3463
d62a17ae 3464 return CMD_SUCCESS;
12e41d03
DL
3465}
3466
3467DEFUN (show_ip_pim_assert_winner_metric,
3468 show_ip_pim_assert_winner_metric_cmd,
20a7e5fd 3469 "show ip pim [vrf NAME] assert-winner-metric",
12e41d03
DL
3470 SHOW_STR
3471 IP_STR
3472 PIM_STR
c68ba0d7 3473 VRF_CMD_HELP_STR
12e41d03
DL
3474 "PIM interface assert winner metric\n")
3475{
c68ba0d7
DS
3476 int idx = 2;
3477 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3478
3479 if (!vrf)
3480 return CMD_WARNING;
3481
64c86530 3482 pim_show_assert_winner_metric(vrf->info, vty);
12e41d03 3483
d62a17ae 3484 return CMD_SUCCESS;
12e41d03
DL
3485}
3486
12e41d03
DL
3487DEFUN (show_ip_pim_interface,
3488 show_ip_pim_interface_cmd,
20a7e5fd 3489 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
12e41d03
DL
3490 SHOW_STR
3491 IP_STR
3492 PIM_STR
c68ba0d7 3493 VRF_CMD_HELP_STR
a268493f 3494 "PIM interface information\n"
9b91bb50 3495 "Detailed output\n"
a268493f
DW
3496 "interface name\n"
3497 "JavaScript Object Notation\n")
12e41d03 3498{
c68ba0d7
DS
3499 int idx = 2;
3500 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3501 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3502
3503 if (!vrf)
3504 return CMD_WARNING;
72e81cf4 3505
d62a17ae 3506 if (argv_find(argv, argc, "WORD", &idx)
3507 || argv_find(argv, argc, "detail", &idx))
64c86530 3508 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
72e81cf4 3509
d62a17ae 3510 else
64c86530 3511 pim_show_interfaces(vrf->info, vty, uj);
12e41d03 3512
d62a17ae 3513 return CMD_SUCCESS;
12e41d03
DL
3514}
3515
3516DEFUN (show_ip_pim_join,
3517 show_ip_pim_join_cmd,
20a7e5fd 3518 "show ip pim [vrf NAME] join [json]",
12e41d03
DL
3519 SHOW_STR
3520 IP_STR
3521 PIM_STR
c68ba0d7 3522 VRF_CMD_HELP_STR
a957a05b
DS
3523 "PIM interface join information\n"
3524 JSON_STR)
12e41d03 3525{
c68ba0d7
DS
3526 int idx = 2;
3527 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3528 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3529
3530 if (!vrf)
3531 return CMD_WARNING;
3532
64c86530 3533 pim_show_join(vrf->info, vty, uj);
12e41d03 3534
d62a17ae 3535 return CMD_SUCCESS;
12e41d03
DL
3536}
3537
12e41d03
DL
3538DEFUN (show_ip_pim_local_membership,
3539 show_ip_pim_local_membership_cmd,
20a7e5fd 3540 "show ip pim [vrf NAME] local-membership [json]",
12e41d03
DL
3541 SHOW_STR
3542 IP_STR
3543 PIM_STR
c68ba0d7 3544 VRF_CMD_HELP_STR
a957a05b
DS
3545 "PIM interface local-membership\n"
3546 JSON_STR)
12e41d03 3547{
c68ba0d7
DS
3548 int idx = 2;
3549 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3550 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3551
3552 if (!vrf)
3553 return CMD_WARNING;
3554
64c86530 3555 pim_show_membership(vrf->info, vty, uj);
12e41d03 3556
d62a17ae 3557 return CMD_SUCCESS;
12e41d03
DL
3558}
3559
12e41d03
DL
3560DEFUN (show_ip_pim_neighbor,
3561 show_ip_pim_neighbor_cmd,
20a7e5fd 3562 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
12e41d03
DL
3563 SHOW_STR
3564 IP_STR
3565 PIM_STR
c68ba0d7 3566 VRF_CMD_HELP_STR
a268493f 3567 "PIM neighbor information\n"
9b91bb50 3568 "Detailed output\n"
a268493f
DW
3569 "Name of interface or neighbor\n"
3570 "JavaScript Object Notation\n")
12e41d03 3571{
c68ba0d7
DS
3572 int idx = 2;
3573 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3574 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3575
3576 if (!vrf)
3577 return CMD_WARNING;
72e81cf4 3578
d62a17ae 3579 if (argv_find(argv, argc, "detail", &idx)
3580 || argv_find(argv, argc, "WORD", &idx))
64c86530 3581 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 3582 else
64c86530 3583 pim_show_neighbors(vrf->info, vty, uj);
12e41d03 3584
d62a17ae 3585 return CMD_SUCCESS;
12e41d03
DL
3586}
3587
3588DEFUN (show_ip_pim_secondary,
3589 show_ip_pim_secondary_cmd,
20a7e5fd 3590 "show ip pim [vrf NAME] secondary",
12e41d03
DL
3591 SHOW_STR
3592 IP_STR
3593 PIM_STR
c68ba0d7 3594 VRF_CMD_HELP_STR
12e41d03
DL
3595 "PIM neighbor addresses\n")
3596{
c68ba0d7
DS
3597 int idx = 2;
3598 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3599
3600 if (!vrf)
3601 return CMD_WARNING;
3602
64c86530 3603 pim_show_neighbors_secondary(vrf->info, vty);
12e41d03 3604
d62a17ae 3605 return CMD_SUCCESS;
12e41d03
DL
3606}
3607
31a21c9c
DW
3608DEFUN (show_ip_pim_state,
3609 show_ip_pim_state_cmd,
20a7e5fd 3610 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
31a21c9c
DW
3611 SHOW_STR
3612 IP_STR
3613 PIM_STR
c68ba0d7 3614 VRF_CMD_HELP_STR
31a21c9c
DW
3615 "PIM state information\n"
3616 "Unicast or Multicast address\n"
3617 "Multicast address\n"
3618 "JavaScript Object Notation\n")
3619{
d62a17ae 3620 const char *src_or_group = NULL;
3621 const char *group = NULL;
c68ba0d7
DS
3622 int idx = 2;
3623 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3624 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3625
3626 if (!vrf)
3627 return CMD_WARNING;
3628
d62a17ae 3629 if (uj)
3630 argc--;
31a21c9c 3631
56243c3a
DS
3632 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
3633 src_or_group = argv[idx]->arg;
3634 if (idx + 1 < argc)
3635 group = argv[idx + 1]->arg;
3636 }
31a21c9c 3637
64c86530 3638 pim_show_state(vrf->info, vty, src_or_group, group, uj);
31a21c9c 3639
d62a17ae 3640 return CMD_SUCCESS;
31a21c9c
DW
3641}
3642
12e41d03
DL
3643DEFUN (show_ip_pim_upstream,
3644 show_ip_pim_upstream_cmd,
20a7e5fd 3645 "show ip pim [vrf NAME] upstream [json]",
12e41d03
DL
3646 SHOW_STR
3647 IP_STR
3648 PIM_STR
c68ba0d7 3649 VRF_CMD_HELP_STR
a268493f
DW
3650 "PIM upstream information\n"
3651 "JavaScript Object Notation\n")
12e41d03 3652{
c3169ac7
DS
3653 int idx = 2;
3654 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3655 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3656
3657 if (!vrf)
3658 return CMD_WARNING;
3659
64c86530 3660 pim_show_upstream(vrf->info, vty, uj);
12e41d03 3661
d62a17ae 3662 return CMD_SUCCESS;
12e41d03
DL
3663}
3664
3665DEFUN (show_ip_pim_upstream_join_desired,
3666 show_ip_pim_upstream_join_desired_cmd,
20a7e5fd 3667 "show ip pim [vrf NAME] upstream-join-desired [json]",
12e41d03
DL
3668 SHOW_STR
3669 IP_STR
3670 PIM_STR
c68ba0d7 3671 VRF_CMD_HELP_STR
a268493f
DW
3672 "PIM upstream join-desired\n"
3673 "JavaScript Object Notation\n")
12e41d03 3674{
c68ba0d7
DS
3675 int idx = 2;
3676 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3677 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3678
3679 if (!vrf)
3680 return CMD_WARNING;
3681
64c86530 3682 pim_show_join_desired(vrf->info, vty, uj);
12e41d03 3683
d62a17ae 3684 return CMD_SUCCESS;
12e41d03
DL
3685}
3686
3687DEFUN (show_ip_pim_upstream_rpf,
3688 show_ip_pim_upstream_rpf_cmd,
20a7e5fd 3689 "show ip pim [vrf NAME] upstream-rpf [json]",
12e41d03
DL
3690 SHOW_STR
3691 IP_STR
3692 PIM_STR
c68ba0d7 3693 VRF_CMD_HELP_STR
a268493f
DW
3694 "PIM upstream source rpf\n"
3695 "JavaScript Object Notation\n")
12e41d03 3696{
c68ba0d7
DS
3697 int idx = 2;
3698 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3699 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3700
3701 if (!vrf)
3702 return CMD_WARNING;
3703
64c86530 3704 pim_show_upstream_rpf(vrf->info, vty, uj);
12e41d03 3705
d62a17ae 3706 return CMD_SUCCESS;
12e41d03
DL
3707}
3708
00d07c6f
DS
3709DEFUN (show_ip_pim_rp,
3710 show_ip_pim_rp_cmd,
20a7e5fd 3711 "show ip pim [vrf NAME] rp-info [json]",
00d07c6f
DS
3712 SHOW_STR
3713 IP_STR
3714 PIM_STR
c68ba0d7 3715 VRF_CMD_HELP_STR
a268493f
DW
3716 "PIM RP information\n"
3717 "JavaScript Object Notation\n")
00d07c6f 3718{
c68ba0d7
DS
3719 int idx = 2;
3720 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3721 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3722
3723 if (!vrf)
3724 return CMD_WARNING;
3725
64c86530 3726 pim_rp_show_information(vrf->info, vty, uj);
00d07c6f 3727
d62a17ae 3728 return CMD_SUCCESS;
00d07c6f
DS
3729}
3730
12e41d03
DL
3731DEFUN (show_ip_pim_rpf,
3732 show_ip_pim_rpf_cmd,
20a7e5fd 3733 "show ip pim [vrf NAME] rpf [json]",
12e41d03
DL
3734 SHOW_STR
3735 IP_STR
3736 PIM_STR
c68ba0d7 3737 VRF_CMD_HELP_STR
a268493f
DW
3738 "PIM cached source rpf information\n"
3739 "JavaScript Object Notation\n")
12e41d03 3740{
c68ba0d7
DS
3741 int idx = 2;
3742 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3743 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3744
3745 if (!vrf)
3746 return CMD_WARNING;
3747
64c86530 3748 pim_show_rpf(vrf->info, vty, uj);
12e41d03 3749
d62a17ae 3750 return CMD_SUCCESS;
12e41d03
DL
3751}
3752
cba44481
CS
3753DEFUN (show_ip_pim_nexthop,
3754 show_ip_pim_nexthop_cmd,
20a7e5fd 3755 "show ip pim [vrf NAME] nexthop",
cba44481
CS
3756 SHOW_STR
3757 IP_STR
3758 PIM_STR
c68ba0d7 3759 VRF_CMD_HELP_STR
cba44481
CS
3760 "PIM cached nexthop rpf information\n")
3761{
c68ba0d7
DS
3762 int idx = 2;
3763 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3764
3765 if (!vrf)
3766 return CMD_WARNING;
3767
64c86530 3768 pim_show_nexthop(vrf->info, vty);
cba44481 3769
d62a17ae 3770 return CMD_SUCCESS;
cba44481
CS
3771}
3772
3773DEFUN (show_ip_pim_nexthop_lookup,
3774 show_ip_pim_nexthop_lookup_cmd,
20a7e5fd 3775 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
cba44481
CS
3776 SHOW_STR
3777 IP_STR
3778 PIM_STR
c68ba0d7 3779 VRF_CMD_HELP_STR
cba44481
CS
3780 "PIM cached nexthop rpf lookup\n"
3781 "Source/RP address\n"
3782 "Multicast Group address\n")
3783{
d62a17ae 3784 struct pim_nexthop_cache pnc;
3785 struct prefix nht_p;
3786 int result = 0;
3787 struct in_addr src_addr, grp_addr;
3788 struct in_addr vif_source;
3789 const char *addr_str, *addr_str1;
3790 struct prefix grp;
3791 struct pim_nexthop nexthop;
3792 char nexthop_addr_str[PREFIX_STRLEN];
3793 char grp_str[PREFIX_STRLEN];
c68ba0d7
DS
3794 int idx = 2;
3795 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3796
c68ba0d7
DS
3797 if (!vrf)
3798 return CMD_WARNING;
3799
3800 argv_find(argv, argc, "A.B.C.D", &idx);
3801 addr_str = argv[idx]->arg;
d62a17ae 3802 result = inet_pton(AF_INET, addr_str, &src_addr);
3803 if (result <= 0) {
3804 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
3805 errno, safe_strerror(errno));
3806 return CMD_WARNING;
3807 }
3808
3809 if (pim_is_group_224_4(src_addr)) {
3810 vty_out(vty,
3811 "Invalid argument. Expected Valid Source Address.\n");
3812 return CMD_WARNING;
3813 }
3814
c68ba0d7 3815 addr_str1 = argv[idx + 1]->arg;
d62a17ae 3816 result = inet_pton(AF_INET, addr_str1, &grp_addr);
3817 if (result <= 0) {
3818 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
3819 errno, safe_strerror(errno));
3820 return CMD_WARNING;
3821 }
3822
3823 if (!pim_is_group_224_4(grp_addr)) {
3824 vty_out(vty,
3825 "Invalid argument. Expected Valid Multicast Group Address.\n");
3826 return CMD_WARNING;
3827 }
3828
c68ba0d7
DS
3829 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
3830 grp_addr))
d62a17ae 3831 return CMD_SUCCESS;
3832
3833 memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
3834 nht_p.family = AF_INET;
3835 nht_p.prefixlen = IPV4_MAX_BITLEN;
3836 nht_p.u.prefix4 = vif_source;
3837 grp.family = AF_INET;
3838 grp.prefixlen = IPV4_MAX_BITLEN;
3839 grp.u.prefix4 = grp_addr;
3840 memset(&nexthop, 0, sizeof(nexthop));
3841
c68ba0d7
DS
3842 if (pim_find_or_track_nexthop(vrf->info, &nht_p, NULL, NULL, &pnc))
3843 pim_ecmp_nexthop_search(vrf->info, &pnc, &nexthop, &nht_p, &grp,
3844 0);
cb9c7c50 3845 else
c68ba0d7 3846 pim_ecmp_nexthop_lookup(vrf->info, &nexthop, vif_source, &nht_p,
25b787a2 3847 &grp, 0);
d62a17ae 3848
3849 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
3850 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
3851 nexthop_addr_str, sizeof(nexthop_addr_str));
3852 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
3853 nexthop_addr_str, nexthop.interface->name);
3854
3855 return CMD_SUCCESS;
cba44481
CS
3856}
3857
39438188
CS
3858DEFUN (show_ip_pim_interface_traffic,
3859 show_ip_pim_interface_traffic_cmd,
20a7e5fd 3860 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
39438188
CS
3861 SHOW_STR
3862 IP_STR
3863 PIM_STR
c68ba0d7 3864 VRF_CMD_HELP_STR
39438188
CS
3865 "PIM interface information\n"
3866 "Protocol Packet counters\n"
17d86e50 3867 "Interface name\n"
39438188
CS
3868 "JavaScript Object Notation\n")
3869{
c68ba0d7
DS
3870 int idx = 2;
3871 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 3872 u_char uj = use_json(argc, argv);
c68ba0d7
DS
3873
3874 if (!vrf)
3875 return CMD_WARNING;
39438188 3876
d62a17ae 3877 if (argv_find(argv, argc, "WORD", &idx))
64c86530 3878 pim_show_interface_traffic_single(vrf->info, vty,
c68ba0d7 3879 argv[idx]->arg, uj);
d62a17ae 3880 else
64c86530 3881 pim_show_interface_traffic(vrf->info, vty, uj);
39438188 3882
d62a17ae 3883 return CMD_SUCCESS;
39438188
CS
3884}
3885
64c86530 3886static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
12e41d03 3887{
d62a17ae 3888 struct listnode *node;
3889 struct interface *ifp;
3890
3891 vty_out(vty, "\n");
3892
3893 vty_out(vty,
c68ba0d7 3894 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
d62a17ae 3895
c68ba0d7
DS
3896 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
3897 struct pim_interface *pim_ifp;
3898 struct in_addr ifaddr;
3899 struct sioc_vif_req vreq;
d62a17ae 3900
c68ba0d7 3901 pim_ifp = ifp->info;
d62a17ae 3902
c68ba0d7
DS
3903 if (!pim_ifp)
3904 continue;
d62a17ae 3905
c68ba0d7
DS
3906 memset(&vreq, 0, sizeof(vreq));
3907 vreq.vifi = pim_ifp->mroute_vif_index;
d62a17ae 3908
c68ba0d7
DS
3909 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
3910 zlog_warn(
3911 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
3912 (unsigned long)SIOCGETVIFCNT, ifp->name,
3913 pim_ifp->mroute_vif_index, errno,
3914 safe_strerror(errno));
3915 }
ecca97ac 3916
c68ba0d7 3917 ifaddr = pim_ifp->primary_address;
d62a17ae 3918
c68ba0d7
DS
3919 vty_out(vty, "%-12s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
3920 ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
3921 pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
3922 (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
3923 (unsigned long)vreq.obytes);
d62a17ae 3924 }
12e41d03
DL
3925}
3926
3927DEFUN (show_ip_multicast,
3928 show_ip_multicast_cmd,
20a7e5fd 3929 "show ip multicast [vrf NAME]",
12e41d03
DL
3930 SHOW_STR
3931 IP_STR
c68ba0d7 3932 VRF_CMD_HELP_STR
12e41d03
DL
3933 "Multicast global information\n")
3934{
c68ba0d7
DS
3935 int idx = 2;
3936 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
bc14b6c7 3937 struct pim_instance *pim;
d62a17ae 3938 time_t now = pim_time_monotonic_sec();
d62a17ae 3939 char uptime[10];
3940
bc14b6c7
DS
3941 if (!vrf)
3942 return CMD_WARNING;
3943 pim = vrf->info;
3944
ecca97ac
DS
3945 vty_out(vty, "Mroute socket descriptor:");
3946
c68ba0d7 3947 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
12e41d03 3948
d62a17ae 3949 pim_time_uptime(uptime, sizeof(uptime),
c68ba0d7 3950 now - pim->mroute_socket_creation);
d62a17ae 3951 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
12e41d03 3952
d62a17ae 3953 vty_out(vty, "\n");
12e41d03 3954
d62a17ae 3955 pim_zebra_zclient_update(vty);
3956 pim_zlookup_show_ip_multicast(vty);
05b0d0d0 3957
d62a17ae 3958 vty_out(vty, "\n");
3959 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
12e41d03 3960
d62a17ae 3961 vty_out(vty, "\n");
3962 vty_out(vty, "Upstream Join Timer: %d secs\n", qpim_t_periodic);
3963 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
3964 vty_out(vty, "PIM ECMP: %s\n", qpim_ecmp_enable ? "Enable" : "Disable");
3965 vty_out(vty, "PIM ECMP Rebalance: %s\n",
3966 qpim_ecmp_rebalance_enable ? "Enable" : "Disable");
12e41d03 3967
d62a17ae 3968 vty_out(vty, "\n");
12e41d03 3969
d62a17ae 3970 show_rpf_refresh_stats(vty, now, NULL);
12e41d03 3971
d62a17ae 3972 vty_out(vty, "\n");
12e41d03 3973
64c86530 3974 show_scan_oil_stats(pim, vty, now);
12e41d03 3975
64c86530 3976 show_multicast_interfaces(pim, vty);
12e41d03 3977
d62a17ae 3978 return CMD_SUCCESS;
12e41d03
DL
3979}
3980
64c86530 3981static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
12e41d03 3982{
d62a17ae 3983 struct listnode *node;
3984 struct channel_oil *c_oil;
3985 struct static_route *s_route;
3986 time_t now;
3987 json_object *json = NULL;
3988 json_object *json_group = NULL;
3989 json_object *json_source = NULL;
3990 json_object *json_oil = NULL;
3991 json_object *json_ifp_out = NULL;
3992 int found_oif = 0;
3993 int first = 1;
3994 char grp_str[INET_ADDRSTRLEN];
3995 char src_str[INET_ADDRSTRLEN];
3996 char in_ifname[INTERFACE_NAMSIZ + 1];
3997 char out_ifname[INTERFACE_NAMSIZ + 1];
3998 int oif_vif_index;
3999 struct interface *ifp_in;
4000 char proto[100];
4001
4002 if (uj) {
4003 json = json_object_new_object();
4004 } else {
4005 vty_out(vty,
4006 "Source Group Proto Input Output TTL Uptime\n");
4007 }
4008
4009 now = pim_time_monotonic_sec();
4010
4011 /* print list of PIM and IGMP routes */
c68ba0d7 4012 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 4013 found_oif = 0;
4014 first = 1;
4015 if (!c_oil->installed && !uj)
4016 continue;
4017
4018 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
4019 sizeof(grp_str));
4020 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
4021 sizeof(src_str));
7cfc7bcf 4022 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
d62a17ae 4023
4024 if (ifp_in)
4025 strcpy(in_ifname, ifp_in->name);
4026 else
4027 strcpy(in_ifname, "<iif?>");
4028
4029 if (uj) {
4030
4031 /* Find the group, create it if it doesn't exist */
4032 json_object_object_get_ex(json, grp_str, &json_group);
4033
4034 if (!json_group) {
4035 json_group = json_object_new_object();
4036 json_object_object_add(json, grp_str,
4037 json_group);
4038 }
4039
4040 /* Find the source nested under the group, create it if
4041 * it doesn't exist */
4042 json_object_object_get_ex(json_group, src_str,
4043 &json_source);
4044
4045 if (!json_source) {
4046 json_source = json_object_new_object();
4047 json_object_object_add(json_group, src_str,
4048 json_source);
4049 }
4050
4051 /* Find the inbound interface nested under the source,
4052 * create it if it doesn't exist */
4053 json_object_int_add(json_source, "installed",
4054 c_oil->installed);
4055 json_object_int_add(json_source, "refCount",
4056 c_oil->oil_ref_count);
4057 json_object_int_add(json_source, "oilSize",
4058 c_oil->oil_size);
4059 json_object_int_add(json_source, "OilInheritedRescan",
4060 c_oil->oil_inherited_rescan);
4061 json_object_string_add(json_source, "iif", in_ifname);
4062 json_oil = NULL;
4063 }
4064
4065 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
4066 ++oif_vif_index) {
4067 struct interface *ifp_out;
4068 char oif_uptime[10];
4069 int ttl;
4070
4071 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
4072 if (ttl < 1)
4073 continue;
4074
7cfc7bcf 4075 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
d62a17ae 4076 pim_time_uptime(
4077 oif_uptime, sizeof(oif_uptime),
4078 now - c_oil->oif_creation[oif_vif_index]);
4079 found_oif = 1;
4080
4081 if (ifp_out)
4082 strcpy(out_ifname, ifp_out->name);
4083 else
4084 strcpy(out_ifname, "<oif?>");
4085
4086 if (uj) {
4087 json_ifp_out = json_object_new_object();
4088 json_object_string_add(json_ifp_out, "source",
4089 src_str);
4090 json_object_string_add(json_ifp_out, "group",
4091 grp_str);
4092
4093 if (c_oil->oif_flags[oif_vif_index]
4094 & PIM_OIF_FLAG_PROTO_PIM)
4095 json_object_boolean_true_add(
4096 json_ifp_out, "protocolPim");
4097
4098 if (c_oil->oif_flags[oif_vif_index]
4099 & PIM_OIF_FLAG_PROTO_IGMP)
4100 json_object_boolean_true_add(
4101 json_ifp_out, "protocolIgmp");
4102
4103 if (c_oil->oif_flags[oif_vif_index]
4104 & PIM_OIF_FLAG_PROTO_SOURCE)
4105 json_object_boolean_true_add(
4106 json_ifp_out, "protocolSource");
4107
4108 if (c_oil->oif_flags[oif_vif_index]
4109 & PIM_OIF_FLAG_PROTO_STAR)
4110 json_object_boolean_true_add(
4111 json_ifp_out,
4112 "protocolInherited");
4113
4114 json_object_string_add(json_ifp_out,
4115 "inboundInterface",
4116 in_ifname);
4117 json_object_int_add(json_ifp_out, "iVifI",
4118 c_oil->oil.mfcc_parent);
4119 json_object_string_add(json_ifp_out,
4120 "outboundInterface",
4121 out_ifname);
4122 json_object_int_add(json_ifp_out, "oVifI",
4123 oif_vif_index);
4124 json_object_int_add(json_ifp_out, "ttl", ttl);
4125 json_object_string_add(json_ifp_out, "upTime",
4126 oif_uptime);
4127 if (!json_oil) {
4128 json_oil = json_object_new_object();
4129 json_object_object_add(json_source,
4130 "oil", json_oil);
4131 }
4132 json_object_object_add(json_oil, out_ifname,
4133 json_ifp_out);
4134 } else {
4135 if (c_oil->oif_flags[oif_vif_index]
4136 & PIM_OIF_FLAG_PROTO_PIM) {
4137 strcpy(proto, "PIM");
4138 }
4139
4140 if (c_oil->oif_flags[oif_vif_index]
4141 & PIM_OIF_FLAG_PROTO_IGMP) {
4142 strcpy(proto, "IGMP");
4143 }
4144
4145 if (c_oil->oif_flags[oif_vif_index]
4146 & PIM_OIF_FLAG_PROTO_SOURCE) {
4147 strcpy(proto, "SRC");
4148 }
4149
4150 if (c_oil->oif_flags[oif_vif_index]
4151 & PIM_OIF_FLAG_PROTO_STAR) {
4152 strcpy(proto, "STAR");
4153 }
4154
4155 vty_out(vty,
4156 "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4157 src_str, grp_str, proto, in_ifname,
4158 out_ifname, ttl, oif_uptime);
4159
4160 if (first) {
4161 src_str[0] = '\0';
4162 grp_str[0] = '\0';
4163 in_ifname[0] = '\0';
4164 first = 0;
4165 }
4166 }
4167 }
4168
4169 if (!uj && !found_oif) {
4170 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
4171 src_str, grp_str, "none", in_ifname, "none", 0,
4172 "--:--:--");
4173 }
4174 }
4175
4176 /* Print list of static routes */
7cfc7bcf
DS
4177 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
4178 first = 1;
4179
4180 if (!s_route->c_oil.installed)
d62a17ae 4181 continue;
4182
7cfc7bcf
DS
4183 pim_inet4_dump("<group?>", s_route->group, grp_str,
4184 sizeof(grp_str));
4185 pim_inet4_dump("<source?>", s_route->source, src_str,
4186 sizeof(src_str));
4187 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
4188 found_oif = 0;
d62a17ae 4189
7cfc7bcf
DS
4190 if (ifp_in)
4191 strcpy(in_ifname, ifp_in->name);
4192 else
4193 strcpy(in_ifname, "<iif?>");
d62a17ae 4194
7cfc7bcf 4195 if (uj) {
d62a17ae 4196
7cfc7bcf
DS
4197 /* Find the group, create it if it doesn't exist */
4198 json_object_object_get_ex(json, grp_str, &json_group);
d62a17ae 4199
7cfc7bcf
DS
4200 if (!json_group) {
4201 json_group = json_object_new_object();
4202 json_object_object_add(json, grp_str,
4203 json_group);
4204 }
d62a17ae 4205
7cfc7bcf
DS
4206 /* Find the source nested under the group, create it if
4207 * it doesn't exist */
4208 json_object_object_get_ex(json_group, src_str,
4209 &json_source);
d62a17ae 4210
7cfc7bcf
DS
4211 if (!json_source) {
4212 json_source = json_object_new_object();
4213 json_object_object_add(json_group, src_str,
4214 json_source);
4215 }
d62a17ae 4216
7cfc7bcf
DS
4217 json_object_string_add(json_source, "iif", in_ifname);
4218 json_oil = NULL;
4219 } else {
4220 strcpy(proto, "STATIC");
4221 }
d62a17ae 4222
7cfc7bcf
DS
4223 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
4224 ++oif_vif_index) {
4225 struct interface *ifp_out;
4226 char oif_uptime[10];
4227 int ttl;
d62a17ae 4228
7cfc7bcf
DS
4229 ttl = s_route->oif_ttls[oif_vif_index];
4230 if (ttl < 1)
4231 continue;
4232
4233 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
4234 pim_time_uptime(
4235 oif_uptime, sizeof(oif_uptime),
4236 now
4237 - s_route->c_oil
4238 .oif_creation[oif_vif_index]);
4239 found_oif = 1;
d62a17ae 4240
7cfc7bcf
DS
4241 if (ifp_out)
4242 strcpy(out_ifname, ifp_out->name);
4243 else
4244 strcpy(out_ifname, "<oif?>");
d62a17ae 4245
7cfc7bcf
DS
4246 if (uj) {
4247 json_ifp_out = json_object_new_object();
4248 json_object_string_add(json_ifp_out, "source",
4249 src_str);
4250 json_object_string_add(json_ifp_out, "group",
4251 grp_str);
4252 json_object_boolean_true_add(json_ifp_out,
4253 "protocolStatic");
4254 json_object_string_add(json_ifp_out,
4255 "inboundInterface",
4256 in_ifname);
4257 json_object_int_add(
4258 json_ifp_out, "iVifI",
4259 s_route->c_oil.oil.mfcc_parent);
4260 json_object_string_add(json_ifp_out,
4261 "outboundInterface",
4262 out_ifname);
4263 json_object_int_add(json_ifp_out, "oVifI",
4264 oif_vif_index);
4265 json_object_int_add(json_ifp_out, "ttl", ttl);
4266 json_object_string_add(json_ifp_out, "upTime",
4267 oif_uptime);
4268 if (!json_oil) {
4269 json_oil = json_object_new_object();
4270 json_object_object_add(json_source,
4271 "oil", json_oil);
d62a17ae 4272 }
7cfc7bcf
DS
4273 json_object_object_add(json_oil, out_ifname,
4274 json_ifp_out);
4275 } else {
d62a17ae 4276 vty_out(vty,
4e0bc0f0 4277 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
d62a17ae 4278 src_str, grp_str, proto, in_ifname,
7cfc7bcf
DS
4279 out_ifname, ttl, oif_uptime,
4280 pim->vrf->name);
4281 if (first) {
4282 src_str[0] = '\0';
4283 grp_str[0] = '\0';
4284 in_ifname[0] = '\0';
4285 first = 0;
4286 }
d62a17ae 4287 }
4288 }
7cfc7bcf
DS
4289
4290 if (!uj && !found_oif) {
4291 vty_out(vty,
4292 "%-15s %-15s %-6s %-10s %-10s %-3d %8s %s\n",
4293 src_str, grp_str, proto, in_ifname, "none", 0,
4294 "--:--:--", pim->vrf->name);
4295 }
d62a17ae 4296 }
4297
4298 if (uj) {
9d303b37
DL
4299 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4300 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 4301 json_object_free(json);
4302 }
12e41d03
DL
4303}
4304
4305DEFUN (show_ip_mroute,
4306 show_ip_mroute_cmd,
20a7e5fd 4307 "show ip mroute [vrf NAME] [json]",
12e41d03
DL
4308 SHOW_STR
4309 IP_STR
a957a05b 4310 MROUTE_STR
c3169ac7 4311 VRF_CMD_HELP_STR
a957a05b 4312 JSON_STR)
12e41d03 4313{
d62a17ae 4314 u_char uj = use_json(argc, argv);
c3169ac7
DS
4315 int idx = 2;
4316 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
c68ba0d7
DS
4317
4318 if (!vrf)
4319 return CMD_WARNING;
4320
64c86530 4321 show_mroute(vrf->info, vty, uj);
d62a17ae 4322 return CMD_SUCCESS;
12e41d03
DL
4323}
4324
b283a4ca
DS
4325DEFUN (show_ip_mroute_vrf_all,
4326 show_ip_mroute_vrf_all_cmd,
4327 "show ip mroute vrf all [json]",
4328 SHOW_STR
4329 IP_STR
4330 MROUTE_STR
4331 VRF_CMD_HELP_STR
4332 JSON_STR)
4333{
4334 u_char uj = use_json(argc, argv);
4335 struct vrf *vrf;
4336 bool first = true;
4337
4338 if (uj)
4339 vty_out(vty, "{ ");
4340 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name)
4341 {
4342 if (uj) {
4343 if (!first)
4344 vty_out(vty, ", ");
4345 vty_out(vty, " \"%s\": ", vrf->name);
4346 first = false;
4347 } else
4348 vty_out(vty, "VRF: %s\n", vrf->name);
64c86530 4349 show_mroute(vrf->info, vty, uj);
b283a4ca
DS
4350 }
4351 if (uj)
4352 vty_out(vty, "}");
4353
4354 return CMD_SUCCESS;
4355}
4356
64c86530 4357static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
12e41d03 4358{
d62a17ae 4359 struct listnode *node;
4360 struct channel_oil *c_oil;
4361 struct static_route *s_route;
12e41d03 4362
d62a17ae 4363 vty_out(vty, "\n");
12e41d03 4364
d62a17ae 4365 vty_out(vty,
4366 "Source Group LastUsed Packets Bytes WrongIf \n");
12e41d03 4367
d62a17ae 4368 /* Print PIM and IGMP route counts */
c68ba0d7 4369 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
d62a17ae 4370 char group_str[INET_ADDRSTRLEN];
4371 char source_str[INET_ADDRSTRLEN];
58302dc7 4372
d62a17ae 4373 if (!c_oil->installed)
4374 continue;
12e41d03 4375
d62a17ae 4376 pim_mroute_update_counters(c_oil);
12e41d03 4377
d62a17ae 4378 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
4379 sizeof(group_str));
4380 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
4381 sizeof(source_str));
6250610a 4382
d62a17ae 4383 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4384 source_str, group_str, c_oil->cc.lastused / 100,
4385 c_oil->cc.pktcnt, c_oil->cc.bytecnt,
4386 c_oil->cc.wrong_if);
4387 }
4388
c68ba0d7
DS
4389 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
4390 char group_str[INET_ADDRSTRLEN];
4391 char source_str[INET_ADDRSTRLEN];
6250610a 4392
c68ba0d7
DS
4393 if (!s_route->c_oil.installed)
4394 continue;
6250610a 4395
c68ba0d7 4396 pim_mroute_update_counters(&s_route->c_oil);
4e0bc0f0 4397
c68ba0d7
DS
4398 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp,
4399 group_str, sizeof(group_str));
4400 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin,
4401 source_str, sizeof(source_str));
4e0bc0f0 4402
c68ba0d7
DS
4403 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4404 source_str, group_str, s_route->c_oil.cc.lastused,
4405 s_route->c_oil.cc.pktcnt, s_route->c_oil.cc.bytecnt,
4406 s_route->c_oil.cc.wrong_if);
d62a17ae 4407 }
12e41d03
DL
4408}
4409
4410DEFUN (show_ip_mroute_count,
4411 show_ip_mroute_count_cmd,
20a7e5fd 4412 "show ip mroute [vrf NAME] count",
12e41d03
DL
4413 SHOW_STR
4414 IP_STR
4415 MROUTE_STR
c68ba0d7 4416 VRF_CMD_HELP_STR
12e41d03
DL
4417 "Route and packet count data\n")
4418{
c68ba0d7
DS
4419 int idx = 2;
4420 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4421
64c86530 4422 show_mroute_count(vrf->info, vty);
d62a17ae 4423 return CMD_SUCCESS;
12e41d03
DL
4424}
4425
4426DEFUN (show_ip_rib,
4427 show_ip_rib_cmd,
20a7e5fd 4428 "show ip rib [vrf NAME] A.B.C.D",
12e41d03
DL
4429 SHOW_STR
4430 IP_STR
4431 RIB_STR
c68ba0d7 4432 VRF_CMD_HELP_STR
12e41d03
DL
4433 "Unicast address\n")
4434{
c68ba0d7
DS
4435 int idx = 2;
4436 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 4437 struct in_addr addr;
4438 const char *addr_str;
4439 struct pim_nexthop nexthop;
4440 char nexthop_addr_str[PREFIX_STRLEN];
4441 int result;
4442
c68ba0d7
DS
4443 if (!vrf)
4444 return CMD_WARNING;
4445
d62a17ae 4446 memset(&nexthop, 0, sizeof(nexthop));
c68ba0d7
DS
4447 argv_find(argv, argc, "A.B.C.D", &idx);
4448 addr_str = argv[idx]->arg;
d62a17ae 4449 result = inet_pton(AF_INET, addr_str, &addr);
4450 if (result <= 0) {
4451 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
4452 errno, safe_strerror(errno));
4453 return CMD_WARNING;
4454 }
12e41d03 4455
c68ba0d7 4456 if (pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
d62a17ae 4457 vty_out(vty,
4458 "Failure querying RIB nexthop for unicast address %s\n",
4459 addr_str);
4460 return CMD_WARNING;
4461 }
12e41d03 4462
d62a17ae 4463 vty_out(vty,
4464 "Address NextHop Interface Metric Preference\n");
12e41d03 4465
d62a17ae 4466 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
4467 nexthop_addr_str, sizeof(nexthop_addr_str));
12e41d03 4468
d62a17ae 4469 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
4470 nexthop.interface ? nexthop.interface->name : "<ifname?>",
4471 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
12e41d03 4472
d62a17ae 4473 return CMD_SUCCESS;
12e41d03
DL
4474}
4475
64c86530 4476static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
12e41d03 4477{
d62a17ae 4478 struct listnode *node;
4479 struct ssmpingd_sock *ss;
4480 time_t now;
12e41d03 4481
d62a17ae 4482 vty_out(vty,
4483 "Source Socket Address Port Uptime Requests\n");
12e41d03 4484
71ad9915 4485 if (!pim->ssmpingd_list)
d62a17ae 4486 return;
12e41d03 4487
d62a17ae 4488 now = pim_time_monotonic_sec();
12e41d03 4489
71ad9915 4490 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
d62a17ae 4491 char source_str[INET_ADDRSTRLEN];
4492 char ss_uptime[10];
4493 struct sockaddr_in bind_addr;
4494 socklen_t len = sizeof(bind_addr);
4495 char bind_addr_str[INET_ADDRSTRLEN];
12e41d03 4496
d62a17ae 4497 pim_inet4_dump("<src?>", ss->source_addr, source_str,
4498 sizeof(source_str));
12e41d03 4499
d62a17ae 4500 if (pim_socket_getsockname(
4501 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
4502 vty_out(vty,
4503 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
4504 source_str, ss->sock_fd);
4505 }
12e41d03 4506
d62a17ae 4507 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
4508 sizeof(bind_addr_str));
4509 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
4510 now - ss->creation);
12e41d03 4511
d62a17ae 4512 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
4513 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
4514 ss_uptime, (long long)ss->requests);
4515 }
12e41d03
DL
4516}
4517
4518DEFUN (show_ip_ssmpingd,
4519 show_ip_ssmpingd_cmd,
20a7e5fd 4520 "show ip ssmpingd [vrf NAME]",
12e41d03
DL
4521 SHOW_STR
4522 IP_STR
c68ba0d7
DS
4523 SHOW_SSMPINGD_STR
4524 VRF_CMD_HELP_STR)
12e41d03 4525{
c68ba0d7
DS
4526 int idx = 2;
4527 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4528
4529 if (!vrf)
4530 return CMD_WARNING;
4531
64c86530 4532 show_ssmpingd(vrf->info, vty);
d62a17ae 4533 return CMD_SUCCESS;
12e41d03
DL
4534}
4535
64c86530 4536static int pim_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
9ecb7b77 4537 const char *rp, const char *group,
d62a17ae 4538 const char *plist)
36d6bd7d 4539{
d62a17ae 4540 int result;
36d6bd7d 4541
9ecb7b77 4542 result = pim_rp_new(pim, rp, group, plist);
dfe43e25 4543
d62a17ae 4544 if (result == PIM_MALLOC_FAIL) {
4545 vty_out(vty, "%% Out of memory\n");
4546 return CMD_WARNING_CONFIG_FAILED;
4547 }
dfe43e25 4548
d62a17ae 4549 if (result == PIM_GROUP_BAD_ADDRESS) {
4550 vty_out(vty, "%% Bad group address specified: %s\n", group);
4551 return CMD_WARNING_CONFIG_FAILED;
4552 }
dfe43e25 4553
d62a17ae 4554 if (result == PIM_RP_BAD_ADDRESS) {
4555 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
4556 return CMD_WARNING_CONFIG_FAILED;
4557 }
36d6bd7d 4558
d62a17ae 4559 if (result == PIM_RP_NO_PATH) {
4560 vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
4561 return CMD_WARNING_CONFIG_FAILED;
4562 }
dfe43e25 4563
d62a17ae 4564 if (result == PIM_GROUP_OVERLAP) {
4565 vty_out(vty, "%% Group range specified cannot overlap\n");
4566 return CMD_WARNING_CONFIG_FAILED;
4567 }
dfe43e25 4568
d62a17ae 4569 if (result == PIM_GROUP_PFXLIST_OVERLAP) {
4570 vty_out(vty,
4571 "%% This group is already covered by a RP prefix-list\n");
4572 return CMD_WARNING_CONFIG_FAILED;
4573 }
36d6bd7d 4574
d62a17ae 4575 if (result == PIM_RP_PFXLIST_IN_USE) {
4576 vty_out(vty,
4577 "%% The same prefix-list cannot be applied to multiple RPs\n");
4578 return CMD_WARNING_CONFIG_FAILED;
4579 }
36d6bd7d 4580
d62a17ae 4581 return CMD_SUCCESS;
36d6bd7d
DS
4582}
4583
4f9f3925
DS
4584static int pim_cmd_spt_switchover(struct pim_instance *pim,
4585 enum pim_spt_switchover spt,
d62a17ae 4586 const char *plist)
df94f9a9 4587{
4f9f3925 4588 pim->spt.switchover = spt;
df94f9a9 4589
4f9f3925 4590 switch (pim->spt.switchover) {
d62a17ae 4591 case PIM_SPT_IMMEDIATE:
4f9f3925
DS
4592 if (pim->spt.plist)
4593 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
df94f9a9 4594
4f9f3925 4595 pim_upstream_add_lhr_star_pimreg(pim);
d62a17ae 4596 break;
4597 case PIM_SPT_INFINITY:
4f9f3925 4598 pim_upstream_remove_lhr_star_pimreg(pim, plist);
df94f9a9 4599
4f9f3925
DS
4600 if (pim->spt.plist)
4601 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
df94f9a9 4602
d62a17ae 4603 if (plist)
c68ba0d7 4604 pim->spt.plist =
d62a17ae 4605 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
4606 break;
4607 }
df94f9a9 4608
d62a17ae 4609 return CMD_SUCCESS;
df94f9a9
DS
4610}
4611
a7b2b1e2
DS
4612DEFUN (ip_pim_spt_switchover_infinity,
4613 ip_pim_spt_switchover_infinity_cmd,
4614 "ip pim spt-switchover infinity-and-beyond",
4615 IP_STR
4616 PIM_STR
4617 "SPT-Switchover\n"
4618 "Never switch to SPT Tree\n")
4619{
4f9f3925
DS
4620 PIM_DECLVAR_CONTEXT(vrf, pim);
4621 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, NULL);
df94f9a9 4622}
a7b2b1e2 4623
df94f9a9
DS
4624DEFUN (ip_pim_spt_switchover_infinity_plist,
4625 ip_pim_spt_switchover_infinity_plist_cmd,
4626 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4627 IP_STR
4628 PIM_STR
4629 "SPT-Switchover\n"
4630 "Never switch to SPT Tree\n"
4631 "Prefix-List to control which groups to switch\n"
4632 "Prefix-List name\n")
4633{
4f9f3925
DS
4634 PIM_DECLVAR_CONTEXT(vrf, pim);
4635 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, argv[5]->arg);
a7b2b1e2
DS
4636}
4637
4638DEFUN (no_ip_pim_spt_switchover_infinity,
4639 no_ip_pim_spt_switchover_infinity_cmd,
4640 "no ip pim spt-switchover infinity-and-beyond",
4641 NO_STR
4642 IP_STR
4643 PIM_STR
4644 "SPT_Switchover\n"
4645 "Never switch to SPT Tree\n")
4646{
4f9f3925
DS
4647 PIM_DECLVAR_CONTEXT(vrf, pim);
4648 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
df94f9a9 4649}
a7b2b1e2 4650
df94f9a9
DS
4651DEFUN (no_ip_pim_spt_switchover_infinity_plist,
4652 no_ip_pim_spt_switchover_infinity_plist_cmd,
4653 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
4654 NO_STR
4655 IP_STR
4656 PIM_STR
4657 "SPT_Switchover\n"
4658 "Never switch to SPT Tree\n"
4659 "Prefix-List to control which groups to switch\n"
4660 "Prefix-List name\n")
4661{
4f9f3925
DS
4662 PIM_DECLVAR_CONTEXT(vrf, pim);
4663 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
a7b2b1e2
DS
4664}
4665
ee1a0718
DS
4666DEFUN (ip_pim_joinprune_time,
4667 ip_pim_joinprune_time_cmd,
ebe94743 4668 "ip pim join-prune-interval (60-600)",
ee1a0718
DS
4669 IP_STR
4670 "pim multicast routing\n"
4671 "Join Prune Send Interval\n"
4672 "Seconds\n")
4673{
4f9f3925 4674 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4675 qpim_t_periodic = atoi(argv[3]->arg);
4676 return CMD_SUCCESS;
ee1a0718
DS
4677}
4678
4679DEFUN (no_ip_pim_joinprune_time,
4680 no_ip_pim_joinprune_time_cmd,
ebe94743 4681 "no ip pim join-prune-interval (60-600)",
ee1a0718
DS
4682 NO_STR
4683 IP_STR
4684 "pim multicast routing\n"
4685 "Join Prune Send Interval\n"
4686 "Seconds\n")
4687{
4f9f3925 4688 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4689 qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
4690 return CMD_SUCCESS;
ee1a0718
DS
4691}
4692
191f5695
DS
4693DEFUN (ip_pim_register_suppress,
4694 ip_pim_register_suppress_cmd,
ebe94743 4695 "ip pim register-suppress-time (5-60000)",
4304f95c
DS
4696 IP_STR
4697 "pim multicast routing\n"
191f5695
DS
4698 "Register Suppress Timer\n"
4699 "Seconds\n")
4304f95c 4700{
4f9f3925 4701 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4702 qpim_register_suppress_time = atoi(argv[3]->arg);
4703 return CMD_SUCCESS;
4304f95c
DS
4704}
4705
191f5695
DS
4706DEFUN (no_ip_pim_register_suppress,
4707 no_ip_pim_register_suppress_cmd,
ebe94743 4708 "no ip pim register-suppress-time (5-60000)",
4304f95c
DS
4709 NO_STR
4710 IP_STR
4711 "pim multicast routing\n"
191f5695 4712 "Register Suppress Timer\n"
01408ede 4713 "Seconds\n")
4304f95c 4714{
4f9f3925 4715 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4716 qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
4717 return CMD_SUCCESS;
4304f95c
DS
4718}
4719
191f5695
DS
4720DEFUN (ip_pim_keep_alive,
4721 ip_pim_keep_alive_cmd,
ebe94743 4722 "ip pim keep-alive-timer (31-60000)",
01408ede
DS
4723 IP_STR
4724 "pim multicast routing\n"
01408ede
DS
4725 "Keep alive Timer\n"
4726 "Seconds\n")
4727{
4f9f3925 4728 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4729 qpim_keep_alive_time = atoi(argv[3]->arg);
4730 return CMD_SUCCESS;
01408ede
DS
4731}
4732
191f5695
DS
4733DEFUN (no_ip_pim_keep_alive,
4734 no_ip_pim_keep_alive_cmd,
ebe94743 4735 "no ip pim keep-alive-timer (31-60000)",
01408ede
DS
4736 NO_STR
4737 IP_STR
4738 "pim multicast routing\n"
01408ede
DS
4739 "Keep alive Timer\n"
4740 "Seconds\n")
4741{
4f9f3925 4742 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4743 qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
4744 return CMD_SUCCESS;
01408ede
DS
4745}
4746
8e4c9ef3
DS
4747DEFUN (ip_pim_packets,
4748 ip_pim_packets_cmd,
ebe94743 4749 "ip pim packets (1-100)",
8e4c9ef3
DS
4750 IP_STR
4751 "pim multicast routing\n"
a957a05b
DS
4752 "packets to process at one time per fd\n"
4753 "Number of packets\n")
8e4c9ef3 4754{
4f9f3925 4755 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4756 qpim_packet_process = atoi(argv[3]->arg);
4757 return CMD_SUCCESS;
8e4c9ef3
DS
4758}
4759
4760DEFUN (no_ip_pim_packets,
4761 no_ip_pim_packets_cmd,
ebe94743 4762 "no ip pim packets (1-100)",
8e4c9ef3
DS
4763 NO_STR
4764 IP_STR
4765 "pim multicast routing\n"
a957a05b
DS
4766 "packets to process at one time per fd\n"
4767 "Number of packets\n")
8e4c9ef3 4768{
4f9f3925 4769 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4770 qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
4771 return CMD_SUCCESS;
8e4c9ef3
DS
4772}
4773
71bbe73d
DS
4774DEFUN (ip_pim_v6_secondary,
4775 ip_pim_v6_secondary_cmd,
4776 "ip pim send-v6-secondary",
4777 IP_STR
4778 "pim multicast routing\n"
4779 "Send v6 secondary addresses\n")
4780{
4f9f3925 4781 PIM_DECLVAR_CONTEXT(vrf, pim);
c68ba0d7 4782 pim->send_v6_secondary = 1;
71bbe73d 4783
d62a17ae 4784 return CMD_SUCCESS;
71bbe73d
DS
4785}
4786
4787DEFUN (no_ip_pim_v6_secondary,
4788 no_ip_pim_v6_secondary_cmd,
4789 "no ip pim send-v6-secondary",
4790 NO_STR
4791 IP_STR
4792 "pim multicast routing\n"
4793 "Send v6 secondary addresses\n")
4794{
4f9f3925 4795 PIM_DECLVAR_CONTEXT(vrf, pim);
c68ba0d7 4796 pim->send_v6_secondary = 0;
71bbe73d 4797
d62a17ae 4798 return CMD_SUCCESS;
71bbe73d
DS
4799}
4800
981d6c7a
DS
4801DEFUN (ip_pim_rp,
4802 ip_pim_rp_cmd,
75a26779 4803 "ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a 4804 IP_STR
9b34069d
QY
4805 "pim multicast routing\n"
4806 "Rendevous Point\n"
a957a05b
DS
4807 "ip address of RP\n"
4808 "Group Address range to cover\n")
981d6c7a 4809{
ae4a6b57 4810 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4811 int idx_ipv4 = 3;
846ef662 4812
d62a17ae 4813 if (argc == (idx_ipv4 + 1))
64c86530 4814 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
9ecb7b77 4815 NULL);
d62a17ae 4816 else
64c86530 4817 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
d62a17ae 4818 argv[idx_ipv4 + 1]->arg, NULL);
dfe43e25
DW
4819}
4820
4821DEFUN (ip_pim_rp_prefix_list,
4822 ip_pim_rp_prefix_list_cmd,
4823 "ip pim rp A.B.C.D prefix-list WORD",
4824 IP_STR
4825 "pim multicast routing\n"
4826 "Rendevous Point\n"
4827 "ip address of RP\n"
4828 "group prefix-list filter\n"
4829 "Name of a prefix-list\n")
4830{
4f9f3925 4831 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 4832 return pim_rp_cmd_worker(pim, vty, argv[3]->arg, NULL, argv[5]->arg);
36d6bd7d 4833}
981d6c7a 4834
64c86530 4835static int pim_no_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925
DS
4836 const char *rp, const char *group,
4837 const char *plist)
36d6bd7d 4838{
4f9f3925 4839 int result = pim_rp_del(pim, rp, group, plist);
dfe43e25 4840
d62a17ae 4841 if (result == PIM_GROUP_BAD_ADDRESS) {
4842 vty_out(vty, "%% Bad group address specified: %s\n", group);
4843 return CMD_WARNING_CONFIG_FAILED;
4844 }
75a26779 4845
d62a17ae 4846 if (result == PIM_RP_BAD_ADDRESS) {
4847 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
4848 return CMD_WARNING_CONFIG_FAILED;
4849 }
981d6c7a 4850
d62a17ae 4851 if (result == PIM_RP_NOT_FOUND) {
4852 vty_out(vty, "%% Unable to find specified RP\n");
4853 return CMD_WARNING_CONFIG_FAILED;
4854 }
c8ae3ce8 4855
d62a17ae 4856 return CMD_SUCCESS;
981d6c7a
DS
4857}
4858
4859DEFUN (no_ip_pim_rp,
4860 no_ip_pim_rp_cmd,
75a26779 4861 "no ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a
DS
4862 NO_STR
4863 IP_STR
9b34069d
QY
4864 "pim multicast routing\n"
4865 "Rendevous Point\n"
a957a05b
DS
4866 "ip address of RP\n"
4867 "Group Address range to cover\n")
981d6c7a 4868{
4f9f3925 4869 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 4870 int idx_ipv4 = 4, idx_group = 0;
72e81cf4 4871
d62a17ae 4872 if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
64c86530 4873 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
d62a17ae 4874 argv[idx_group]->arg, NULL);
4875 else
64c86530 4876 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
d62a17ae 4877 NULL);
dfe43e25
DW
4878}
4879
4880DEFUN (no_ip_pim_rp_prefix_list,
4881 no_ip_pim_rp_prefix_list_cmd,
4882 "no ip pim rp A.B.C.D prefix-list WORD",
4883 NO_STR
4884 IP_STR
4885 "pim multicast routing\n"
4886 "Rendevous Point\n"
4887 "ip address of RP\n"
4888 "group prefix-list filter\n"
4889 "Name of a prefix-list\n")
4890{
4f9f3925 4891 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 4892 return pim_no_rp_cmd_worker(pim, vty, argv[4]->arg, NULL, argv[6]->arg);
981d6c7a
DS
4893}
4894
6f439a70
DS
4895static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
4896 const char *plist)
15a5dafe 4897{
6f439a70 4898 int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
15a5dafe 4899
d62a17ae 4900 if (result == PIM_SSM_ERR_NONE)
4901 return CMD_SUCCESS;
15a5dafe 4902
d62a17ae 4903 switch (result) {
4904 case PIM_SSM_ERR_NO_VRF:
4905 vty_out(vty, "%% VRF doesn't exist\n");
4906 break;
4907 case PIM_SSM_ERR_DUP:
4908 vty_out(vty, "%% duplicate config\n");
4909 break;
4910 default:
4911 vty_out(vty, "%% ssm range config failed\n");
4912 }
15a5dafe 4913
d62a17ae 4914 return CMD_WARNING_CONFIG_FAILED;
15a5dafe 4915}
4916
4917DEFUN (ip_pim_ssm_prefix_list,
4918 ip_pim_ssm_prefix_list_cmd,
4919 "ip pim ssm prefix-list WORD",
4920 IP_STR
4921 "pim multicast routing\n"
4922 "Source Specific Multicast\n"
4923 "group range prefix-list filter\n"
4924 "Name of a prefix-list\n")
4925{
4f9f3925
DS
4926 PIM_DECLVAR_CONTEXT(vrf, pim);
4927 return pim_ssm_cmd_worker(pim, vty, argv[0]->arg);
15a5dafe 4928}
4929
4930DEFUN (no_ip_pim_ssm_prefix_list,
4931 no_ip_pim_ssm_prefix_list_cmd,
4932 "no ip pim ssm prefix-list",
4933 NO_STR
4934 IP_STR
4935 "pim multicast routing\n"
4936 "Source Specific Multicast\n"
4937 "group range prefix-list filter\n")
4938{
4f9f3925
DS
4939 PIM_DECLVAR_CONTEXT(vrf, pim);
4940 return pim_ssm_cmd_worker(pim, vty, NULL);
15a5dafe 4941}
4942
4943DEFUN (no_ip_pim_ssm_prefix_list_name,
4944 no_ip_pim_ssm_prefix_list_name_cmd,
4945 "no ip pim ssm prefix-list WORD",
4946 NO_STR
4947 IP_STR
4948 "pim multicast routing\n"
4949 "Source Specific Multicast\n"
4950 "group range prefix-list filter\n"
4951 "Name of a prefix-list\n")
4952{
4f9f3925
DS
4953 PIM_DECLVAR_CONTEXT(vrf, pim);
4954 struct pim_ssm *ssm = pim->ssm_info;
15a5dafe 4955
d62a17ae 4956 if (ssm->plist_name && !strcmp(ssm->plist_name, argv[0]->arg))
4f9f3925 4957 return pim_ssm_cmd_worker(pim, vty, NULL);
15a5dafe 4958
d62a17ae 4959 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[0]->arg);
15a5dafe 4960
d62a17ae 4961 return CMD_WARNING_CONFIG_FAILED;
15a5dafe 4962}
4963
64c86530
DS
4964static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
4965 struct vty *vty, u_char uj)
15a5dafe 4966{
c68ba0d7 4967 struct pim_ssm *ssm = pim->ssm_info;
d62a17ae 4968 const char *range_str =
4969 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
15a5dafe 4970
d62a17ae 4971 if (uj) {
4972 json_object *json;
4973 json = json_object_new_object();
4974 json_object_string_add(json, "ssmGroups", range_str);
9d303b37
DL
4975 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4976 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 4977 json_object_free(json);
4978 } else
4979 vty_out(vty, "SSM group range : %s\n", range_str);
15a5dafe 4980}
4981
4982DEFUN (show_ip_pim_ssm_range,
4983 show_ip_pim_ssm_range_cmd,
20a7e5fd 4984 "show ip pim [vrf NAME] group-type [json]",
15a5dafe 4985 SHOW_STR
4986 IP_STR
4987 PIM_STR
c68ba0d7 4988 VRF_CMD_HELP_STR
15a5dafe 4989 "PIM group type\n"
4990 "JavaScript Object Notation\n")
4991{
c68ba0d7
DS
4992 int idx = 2;
4993 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 4994 u_char uj = use_json(argc, argv);
c68ba0d7
DS
4995
4996 if (!vrf)
4997 return CMD_WARNING;
4998
64c86530 4999 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
15a5dafe 5000
d62a17ae 5001 return CMD_SUCCESS;
15a5dafe 5002}
5003
64c86530
DS
5004static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
5005 struct vty *vty, u_char uj,
d62a17ae 5006 const char *group)
15a5dafe 5007{
d62a17ae 5008 struct in_addr group_addr;
5009 const char *type_str;
5010 int result;
15a5dafe 5011
d62a17ae 5012 result = inet_pton(AF_INET, group, &group_addr);
5013 if (result <= 0)
5014 type_str = "invalid";
5015 else {
5016 if (pim_is_group_224_4(group_addr))
c68ba0d7
DS
5017 type_str =
5018 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
d62a17ae 5019 else
5020 type_str = "not-multicast";
5021 }
15a5dafe 5022
d62a17ae 5023 if (uj) {
5024 json_object *json;
5025 json = json_object_new_object();
5026 json_object_string_add(json, "groupType", type_str);
9d303b37
DL
5027 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5028 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 5029 json_object_free(json);
5030 } else
5031 vty_out(vty, "Group type : %s\n", type_str);
15a5dafe 5032}
5033
5034DEFUN (show_ip_pim_group_type,
5035 show_ip_pim_group_type_cmd,
20a7e5fd 5036 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
15a5dafe 5037 SHOW_STR
5038 IP_STR
5039 PIM_STR
c68ba0d7 5040 VRF_CMD_HELP_STR
15a5dafe 5041 "multicast group type\n"
5042 "group address\n"
5043 "JavaScript Object Notation\n")
5044{
c68ba0d7
DS
5045 int idx = 2;
5046 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 5047 u_char uj = use_json(argc, argv);
c68ba0d7
DS
5048
5049 if (!vrf)
5050 return CMD_WARNING;
5051
5052 argv_find(argv, argc, "A.B.C.D", &idx);
64c86530 5053 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
15a5dafe 5054
d62a17ae 5055 return CMD_SUCCESS;
15a5dafe 5056}
5057
b8d16be2
DS
5058DEFUN_HIDDEN (ip_multicast_routing,
5059 ip_multicast_routing_cmd,
5060 "ip multicast-routing",
5061 IP_STR
5062 "Enable IP multicast forwarding\n")
12e41d03 5063{
d62a17ae 5064 return CMD_SUCCESS;
12e41d03
DL
5065}
5066
b8d16be2
DS
5067DEFUN_HIDDEN (no_ip_multicast_routing,
5068 no_ip_multicast_routing_cmd,
5069 "no ip multicast-routing",
5070 NO_STR
5071 IP_STR
b8d16be2 5072 "Enable IP multicast forwarding\n")
12e41d03 5073{
d62a17ae 5074 vty_out(vty,
5075 "Command is Disabled and will be removed in a future version\n");
5076 return CMD_SUCCESS;
12e41d03
DL
5077}
5078
5079DEFUN (ip_ssmpingd,
5080 ip_ssmpingd_cmd,
5081 "ip ssmpingd [A.B.C.D]",
5082 IP_STR
5083 CONF_SSMPINGD_STR
5084 "Source address\n")
5085{
4f9f3925 5086 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 5087 int idx_ipv4 = 2;
5088 int result;
5089 struct in_addr source_addr;
5090 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03 5091
d62a17ae 5092 result = inet_pton(AF_INET, source_str, &source_addr);
5093 if (result <= 0) {
5094 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
5095 source_str, errno, safe_strerror(errno));
5096 return CMD_WARNING_CONFIG_FAILED;
5097 }
12e41d03 5098
4f9f3925 5099 result = pim_ssmpingd_start(pim, source_addr);
d62a17ae 5100 if (result) {
5101 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
5102 source_str, result);
5103 return CMD_WARNING_CONFIG_FAILED;
5104 }
12e41d03 5105
d62a17ae 5106 return CMD_SUCCESS;
12e41d03
DL
5107}
5108
5109DEFUN (no_ip_ssmpingd,
5110 no_ip_ssmpingd_cmd,
5111 "no ip ssmpingd [A.B.C.D]",
5112 NO_STR
5113 IP_STR
5114 CONF_SSMPINGD_STR
5115 "Source address\n")
5116{
4f9f3925 5117 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 5118 int idx_ipv4 = 3;
5119 int result;
5120 struct in_addr source_addr;
5121 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03 5122
d62a17ae 5123 result = inet_pton(AF_INET, source_str, &source_addr);
5124 if (result <= 0) {
5125 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
5126 source_str, errno, safe_strerror(errno));
5127 return CMD_WARNING_CONFIG_FAILED;
5128 }
12e41d03 5129
4f9f3925 5130 result = pim_ssmpingd_stop(pim, source_addr);
d62a17ae 5131 if (result) {
5132 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
5133 source_str, result);
5134 return CMD_WARNING_CONFIG_FAILED;
5135 }
12e41d03 5136
d62a17ae 5137 return CMD_SUCCESS;
12e41d03
DL
5138}
5139
cba44481
CS
5140DEFUN (ip_pim_ecmp,
5141 ip_pim_ecmp_cmd,
5142 "ip pim ecmp",
5143 IP_STR
5144 "pim multicast routing\n"
5145 "Enable PIM ECMP \n")
5146{
4f9f3925 5147 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 5148 qpim_ecmp_enable = 1;
cba44481 5149
d62a17ae 5150 return CMD_SUCCESS;
cba44481
CS
5151}
5152
5153DEFUN (no_ip_pim_ecmp,
5154 no_ip_pim_ecmp_cmd,
5155 "no ip pim ecmp",
5156 NO_STR
5157 IP_STR
5158 "pim multicast routing\n"
5159 "Disable PIM ECMP \n")
5160{
4f9f3925 5161 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 5162 qpim_ecmp_enable = 0;
cba44481 5163
d62a17ae 5164 return CMD_SUCCESS;
cba44481
CS
5165}
5166
5167DEFUN (ip_pim_ecmp_rebalance,
5168 ip_pim_ecmp_rebalance_cmd,
5169 "ip pim ecmp rebalance",
5170 IP_STR
5171 "pim multicast routing\n"
5172 "Enable PIM ECMP \n"
5173 "Enable PIM ECMP Rebalance\n")
5174{
4f9f3925 5175 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 5176 qpim_ecmp_enable = 1;
5177 qpim_ecmp_rebalance_enable = 1;
cba44481 5178
d62a17ae 5179 return CMD_SUCCESS;
cba44481
CS
5180}
5181
5182DEFUN (no_ip_pim_ecmp_rebalance,
5183 no_ip_pim_ecmp_rebalance_cmd,
5184 "no ip pim ecmp rebalance",
5185 NO_STR
5186 IP_STR
5187 "pim multicast routing\n"
5188 "Disable PIM ECMP \n"
5189 "Disable PIM ECMP Rebalance\n")
5190{
4f9f3925 5191 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 5192 qpim_ecmp_rebalance_enable = 0;
cba44481 5193
d62a17ae 5194 return CMD_SUCCESS;
cba44481
CS
5195}
5196
d62a17ae 5197static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
12e41d03 5198{
d62a17ae 5199 struct pim_interface *pim_ifp;
5200 uint8_t need_startup = 0;
12e41d03 5201
d62a17ae 5202 pim_ifp = ifp->info;
12e41d03 5203
d62a17ae 5204 if (!pim_ifp) {
5205 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
5206 if (!pim_ifp) {
5207 vty_out(vty, "Could not enable IGMP on interface %s\n",
5208 ifp->name);
5209 return CMD_WARNING_CONFIG_FAILED;
5210 }
5211 need_startup = 1;
5212 } else {
5213 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
5214 PIM_IF_DO_IGMP(pim_ifp->options);
5215 need_startup = 1;
5216 }
5217 }
12e41d03 5218
d62a17ae 5219 /* 'ip igmp' executed multiple times, with need_startup
5220 avoid multiple if add all and membership refresh */
5221 if (need_startup) {
5222 pim_if_addr_add_all(ifp);
5223 pim_if_membership_refresh(ifp);
5224 }
12e41d03 5225
d62a17ae 5226 return CMD_SUCCESS;
12e41d03
DL
5227}
5228
21419f59
DS
5229DEFUN (interface_ip_igmp,
5230 interface_ip_igmp_cmd,
5231 "ip igmp",
5232 IP_STR
5233 IFACE_IGMP_STR)
5234{
d62a17ae 5235 VTY_DECLVAR_CONTEXT(interface, ifp);
21419f59 5236
d62a17ae 5237 return pim_cmd_igmp_start(vty, ifp);
21419f59
DS
5238}
5239
12e41d03
DL
5240DEFUN (interface_no_ip_igmp,
5241 interface_no_ip_igmp_cmd,
5242 "no ip igmp",
5243 NO_STR
5244 IP_STR
5245 IFACE_IGMP_STR)
5246{
d62a17ae 5247 VTY_DECLVAR_CONTEXT(interface, ifp);
5248 struct pim_interface *pim_ifp = ifp->info;
12e41d03 5249
d62a17ae 5250 if (!pim_ifp)
5251 return CMD_SUCCESS;
12e41d03 5252
d62a17ae 5253 PIM_IF_DONT_IGMP(pim_ifp->options);
12e41d03 5254
d62a17ae 5255 pim_if_membership_clear(ifp);
12e41d03 5256
d62a17ae 5257 pim_if_addr_del_all_igmp(ifp);
12e41d03 5258
d62a17ae 5259 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
5260 pim_if_delete(ifp);
5261 }
12e41d03 5262
d62a17ae 5263 return CMD_SUCCESS;
12e41d03
DL
5264}
5265
5266DEFUN (interface_ip_igmp_join,
5267 interface_ip_igmp_join_cmd,
5268 "ip igmp join A.B.C.D A.B.C.D",
5269 IP_STR
5270 IFACE_IGMP_STR
5271 "IGMP join multicast group\n"
5272 "Multicast group address\n"
5273 "Source address\n")
5274{
d62a17ae 5275 VTY_DECLVAR_CONTEXT(interface, ifp);
5276 int idx_ipv4 = 3;
5277 int idx_ipv4_2 = 4;
5278 const char *group_str;
5279 const char *source_str;
5280 struct in_addr group_addr;
5281 struct in_addr source_addr;
5282 int result;
5283
5284 /* Group address */
5285 group_str = argv[idx_ipv4]->arg;
5286 result = inet_pton(AF_INET, group_str, &group_addr);
5287 if (result <= 0) {
5288 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
5289 errno, safe_strerror(errno));
5290 return CMD_WARNING_CONFIG_FAILED;
5291 }
5292
5293 /* Source address */
5294 source_str = argv[idx_ipv4_2]->arg;
5295 result = inet_pton(AF_INET, source_str, &source_addr);
5296 if (result <= 0) {
5297 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
5298 source_str, errno, safe_strerror(errno));
5299 return CMD_WARNING_CONFIG_FAILED;
5300 }
5301
5302 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
5303 if (result) {
5304 vty_out(vty,
5305 "%% Failure joining IGMP group %s source %s on interface %s: %d\n",
5306 group_str, source_str, ifp->name, result);
5307 return CMD_WARNING_CONFIG_FAILED;
5308 }
5309
5310 return CMD_SUCCESS;
12e41d03
DL
5311}
5312
5313DEFUN (interface_no_ip_igmp_join,
5314 interface_no_ip_igmp_join_cmd,
5315 "no ip igmp join A.B.C.D A.B.C.D",
5316 NO_STR
5317 IP_STR
5318 IFACE_IGMP_STR
5319 "IGMP join multicast group\n"
5320 "Multicast group address\n"
5321 "Source address\n")
5322{
d62a17ae 5323 VTY_DECLVAR_CONTEXT(interface, ifp);
5324 int idx_ipv4 = 4;
5325 int idx_ipv4_2 = 5;
5326 const char *group_str;
5327 const char *source_str;
5328 struct in_addr group_addr;
5329 struct in_addr source_addr;
5330 int result;
5331
5332 /* Group address */
5333 group_str = argv[idx_ipv4]->arg;
5334 result = inet_pton(AF_INET, group_str, &group_addr);
5335 if (result <= 0) {
5336 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
5337 errno, safe_strerror(errno));
5338 return CMD_WARNING_CONFIG_FAILED;
5339 }
5340
5341 /* Source address */
5342 source_str = argv[idx_ipv4_2]->arg;
5343 result = inet_pton(AF_INET, source_str, &source_addr);
5344 if (result <= 0) {
5345 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
5346 source_str, errno, safe_strerror(errno));
5347 return CMD_WARNING_CONFIG_FAILED;
5348 }
5349
5350 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
5351 if (result) {
5352 vty_out(vty,
5353 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5354 group_str, source_str, ifp->name, result);
5355 return CMD_WARNING_CONFIG_FAILED;
5356 }
5357
5358 return CMD_SUCCESS;
12e41d03
DL
5359}
5360
5361/*
5362 CLI reconfiguration affects the interface level (struct pim_interface).
5363 This function propagates the reconfiguration to every active socket
5364 for that interface.
5365 */
5366static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
5367{
d62a17ae 5368 struct interface *ifp;
5369 struct pim_interface *pim_ifp;
12e41d03 5370
d62a17ae 5371 zassert(igmp);
12e41d03 5372
d62a17ae 5373 /* other querier present? */
12e41d03 5374
d62a17ae 5375 if (igmp->t_other_querier_timer)
5376 return;
12e41d03 5377
d62a17ae 5378 /* this is the querier */
12e41d03 5379
d62a17ae 5380 zassert(igmp->interface);
5381 zassert(igmp->interface->info);
12e41d03 5382
d62a17ae 5383 ifp = igmp->interface;
5384 pim_ifp = ifp->info;
12e41d03 5385
d62a17ae 5386 if (PIM_DEBUG_IGMP_TRACE) {
5387 char ifaddr_str[INET_ADDRSTRLEN];
5388 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
5389 sizeof(ifaddr_str));
5390 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5391 __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
5392 pim_ifp->igmp_default_query_interval);
5393 }
12e41d03 5394
d62a17ae 5395 /*
5396 igmp_startup_mode_on() will reset QQI:
12e41d03 5397
d62a17ae 5398 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5399 */
5400 igmp_startup_mode_on(igmp);
12e41d03
DL
5401}
5402
5403static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
5404{
d62a17ae 5405 if (igmp->t_igmp_query_timer) {
5406 /* other querier present */
5407 zassert(igmp->t_igmp_query_timer);
5408 zassert(!igmp->t_other_querier_timer);
12e41d03 5409
d62a17ae 5410 pim_igmp_general_query_off(igmp);
5411 pim_igmp_general_query_on(igmp);
12e41d03 5412
d62a17ae 5413 zassert(igmp->t_igmp_query_timer);
5414 zassert(!igmp->t_other_querier_timer);
5415 } else {
5416 /* this is the querier */
12e41d03 5417
d62a17ae 5418 zassert(!igmp->t_igmp_query_timer);
5419 zassert(igmp->t_other_querier_timer);
12e41d03 5420
d62a17ae 5421 pim_igmp_other_querier_timer_off(igmp);
5422 pim_igmp_other_querier_timer_on(igmp);
12e41d03 5423
d62a17ae 5424 zassert(!igmp->t_igmp_query_timer);
5425 zassert(igmp->t_other_querier_timer);
5426 }
12e41d03
DL
5427}
5428
5429static void change_query_interval(struct pim_interface *pim_ifp,
5430 int query_interval)
5431{
d62a17ae 5432 struct listnode *sock_node;
5433 struct igmp_sock *igmp;
12e41d03 5434
d62a17ae 5435 pim_ifp->igmp_default_query_interval = query_interval;
12e41d03 5436
d62a17ae 5437 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
5438 igmp_sock_query_interval_reconfig(igmp);
5439 igmp_sock_query_reschedule(igmp);
5440 }
12e41d03
DL
5441}
5442
5443static void change_query_max_response_time(struct pim_interface *pim_ifp,
5444 int query_max_response_time_dsec)
5445{
d62a17ae 5446 struct listnode *sock_node;
5447 struct igmp_sock *igmp;
5448
5449 pim_ifp->igmp_query_max_response_time_dsec =
5450 query_max_response_time_dsec;
5451
5452 /*
5453 Below we modify socket/group/source timers in order to quickly
5454 reflect the change. Otherwise, those timers would eventually catch
5455 up.
5456 */
5457
5458 /* scan all sockets */
5459 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
5460 struct listnode *grp_node;
5461 struct igmp_group *grp;
5462
5463 /* reschedule socket general query */
5464 igmp_sock_query_reschedule(igmp);
5465
5466 /* scan socket groups */
5467 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
5468 grp)) {
5469 struct listnode *src_node;
5470 struct igmp_source *src;
5471
5472 /* reset group timers for groups in EXCLUDE mode */
5473 if (grp->group_filtermode_isexcl) {
5474 igmp_group_reset_gmi(grp);
5475 }
5476
5477 /* scan group sources */
5478 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
5479 src_node, src)) {
5480
5481 /* reset source timers for sources with running
5482 * timers */
5483 if (src->t_source_timer) {
5484 igmp_source_reset_gmi(igmp, grp, src);
5485 }
5486 }
5487 }
12e41d03 5488 }
12e41d03
DL
5489}
5490
5491#define IGMP_QUERY_INTERVAL_MIN (1)
5492#define IGMP_QUERY_INTERVAL_MAX (1800)
5493
5494DEFUN (interface_ip_igmp_query_interval,
5495 interface_ip_igmp_query_interval_cmd,
9ccf14f7 5496 "ip igmp query-interval (1-1800)",
12e41d03
DL
5497 IP_STR
5498 IFACE_IGMP_STR
5499 IFACE_IGMP_QUERY_INTERVAL_STR
5500 "Query interval in seconds\n")
5501{
d62a17ae 5502 VTY_DECLVAR_CONTEXT(interface, ifp);
5503 struct pim_interface *pim_ifp = ifp->info;
5504 int query_interval;
5505 int query_interval_dsec;
5506 int ret;
5507
5508 if (!pim_ifp) {
5509 ret = pim_cmd_igmp_start(vty, ifp);
5510 if (ret != CMD_SUCCESS)
5511 return ret;
5512 pim_ifp = ifp->info;
5513 }
5514
5515 query_interval = atoi(argv[3]->arg);
5516 query_interval_dsec = 10 * query_interval;
5517
5518 /*
5519 It seems we don't need to check bounds since command.c does it
5520 already, but we verify them anyway for extra safety.
5521 */
5522 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
5523 vty_out(vty,
5524 "General query interval %d lower than minimum %d\n",
5525 query_interval, IGMP_QUERY_INTERVAL_MIN);
5526 return CMD_WARNING_CONFIG_FAILED;
5527 }
5528 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
5529 vty_out(vty,
5530 "General query interval %d higher than maximum %d\n",
5531 query_interval, IGMP_QUERY_INTERVAL_MAX);
5532 return CMD_WARNING_CONFIG_FAILED;
5533 }
5534
5535 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
5536 vty_out(vty,
5537 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
5538 query_interval_dsec,
5539 pim_ifp->igmp_query_max_response_time_dsec);
5540 return CMD_WARNING_CONFIG_FAILED;
5541 }
5542
5543 change_query_interval(pim_ifp, query_interval);
5544
5545 return CMD_SUCCESS;
12e41d03
DL
5546}
5547
5548DEFUN (interface_no_ip_igmp_query_interval,
5549 interface_no_ip_igmp_query_interval_cmd,
9ccf14f7 5550 "no ip igmp query-interval",
12e41d03
DL
5551 NO_STR
5552 IP_STR
5553 IFACE_IGMP_STR
5554 IFACE_IGMP_QUERY_INTERVAL_STR)
5555{
d62a17ae 5556 VTY_DECLVAR_CONTEXT(interface, ifp);
5557 struct pim_interface *pim_ifp = ifp->info;
5558 int default_query_interval_dsec;
12e41d03 5559
d62a17ae 5560 if (!pim_ifp)
5561 return CMD_SUCCESS;
12e41d03 5562
d62a17ae 5563 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
12e41d03 5564
d62a17ae 5565 if (default_query_interval_dsec
5566 <= pim_ifp->igmp_query_max_response_time_dsec) {
5567 vty_out(vty,
5568 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
5569 default_query_interval_dsec,
5570 pim_ifp->igmp_query_max_response_time_dsec);
5571 return CMD_WARNING_CONFIG_FAILED;
5572 }
12e41d03 5573
d62a17ae 5574 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
12e41d03 5575
d62a17ae 5576 return CMD_SUCCESS;
12e41d03
DL
5577}
5578
b05b72e8
DW
5579DEFUN (interface_ip_igmp_version,
5580 interface_ip_igmp_version_cmd,
72e81cf4 5581 "ip igmp version (2-3)",
b05b72e8
DW
5582 IP_STR
5583 IFACE_IGMP_STR
5584 "IGMP version\n"
5585 "IGMP version number\n")
5586{
d62a17ae 5587 VTY_DECLVAR_CONTEXT(interface, ifp);
5588 struct pim_interface *pim_ifp = ifp->info;
5589 int igmp_version, old_version = 0;
5590 int ret;
5591
5592 if (!pim_ifp) {
5593 ret = pim_cmd_igmp_start(vty, ifp);
5594 if (ret != CMD_SUCCESS)
5595 return ret;
5596 pim_ifp = ifp->info;
5597 }
5598
5599 igmp_version = atoi(argv[3]->arg);
5600 old_version = pim_ifp->igmp_version;
5601 pim_ifp->igmp_version = igmp_version;
5602
5603 // Check if IGMP is Enabled otherwise, enable on interface
5604 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
5605 PIM_IF_DO_IGMP(pim_ifp->options);
5606 pim_if_addr_add_all(ifp);
5607 pim_if_membership_refresh(ifp);
5608 old_version = igmp_version; // avoid refreshing membership
5609 // again.
5610 }
5611 /* Current and new version is different refresh existing
5612 membership. Going from 3 -> 2 or 2 -> 3. */
5613 if (old_version != igmp_version)
5614 pim_if_membership_refresh(ifp);
5615
5616 return CMD_SUCCESS;
b05b72e8
DW
5617}
5618
5619DEFUN (interface_no_ip_igmp_version,
5620 interface_no_ip_igmp_version_cmd,
72e81cf4 5621 "no ip igmp version (2-3)",
b05b72e8
DW
5622 NO_STR
5623 IP_STR
5624 IFACE_IGMP_STR
5625 "IGMP version\n"
5626 "IGMP version number\n")
5627{
d62a17ae 5628 VTY_DECLVAR_CONTEXT(interface, ifp);
5629 struct pim_interface *pim_ifp = ifp->info;
b05b72e8 5630
d62a17ae 5631 if (!pim_ifp)
5632 return CMD_SUCCESS;
b05b72e8 5633
d62a17ae 5634 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
b05b72e8 5635
d62a17ae 5636 return CMD_SUCCESS;
b05b72e8
DW
5637}
5638
58344b65
DS
5639#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5640#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
12e41d03
DL
5641
5642DEFUN (interface_ip_igmp_query_max_response_time,
5643 interface_ip_igmp_query_max_response_time_cmd,
58344b65 5644 "ip igmp query-max-response-time (10-250)",
12e41d03
DL
5645 IP_STR
5646 IFACE_IGMP_STR
5647 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
58344b65 5648 "Query response value in deci-seconds\n")
12e41d03 5649{
d62a17ae 5650 VTY_DECLVAR_CONTEXT(interface, ifp);
5651 struct pim_interface *pim_ifp = ifp->info;
5652 int query_max_response_time;
5653 int ret;
12e41d03 5654
d62a17ae 5655 if (!pim_ifp) {
5656 ret = pim_cmd_igmp_start(vty, ifp);
5657 if (ret != CMD_SUCCESS)
5658 return ret;
5659 pim_ifp = ifp->info;
5660 }
12e41d03 5661
d62a17ae 5662 query_max_response_time = atoi(argv[3]->arg);
12e41d03 5663
d62a17ae 5664 if (query_max_response_time
5665 >= pim_ifp->igmp_default_query_interval * 10) {
5666 vty_out(vty,
5667 "Can't set query max response time %d sec >= general query interval %d sec\n",
5668 query_max_response_time,
5669 pim_ifp->igmp_default_query_interval);
5670 return CMD_WARNING_CONFIG_FAILED;
5671 }
12e41d03 5672
d62a17ae 5673 change_query_max_response_time(pim_ifp, query_max_response_time);
12e41d03 5674
d62a17ae 5675 return CMD_SUCCESS;
12e41d03
DL
5676}
5677
5678DEFUN (interface_no_ip_igmp_query_max_response_time,
5679 interface_no_ip_igmp_query_max_response_time_cmd,
72e81cf4 5680 "no ip igmp query-max-response-time (10-250)",
12e41d03
DL
5681 NO_STR
5682 IP_STR
5683 IFACE_IGMP_STR
a957a05b
DS
5684 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
5685 "Time for response in deci-seconds\n")
12e41d03 5686{
d62a17ae 5687 VTY_DECLVAR_CONTEXT(interface, ifp);
5688 struct pim_interface *pim_ifp = ifp->info;
12e41d03 5689
d62a17ae 5690 if (!pim_ifp)
5691 return CMD_SUCCESS;
12e41d03 5692
d62a17ae 5693 change_query_max_response_time(pim_ifp,
5694 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
12e41d03 5695
d62a17ae 5696 return CMD_SUCCESS;
12e41d03
DL
5697}
5698
5699#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
5700#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
5701
58344b65
DS
5702DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
5703 interface_ip_igmp_query_max_response_time_dsec_cmd,
5704 "ip igmp query-max-response-time-dsec (10-250)",
5705 IP_STR
5706 IFACE_IGMP_STR
5707 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
5708 "Query response value in deciseconds\n")
12e41d03 5709{
d62a17ae 5710 VTY_DECLVAR_CONTEXT(interface, ifp);
5711 struct pim_interface *pim_ifp = ifp->info;
5712 int query_max_response_time_dsec;
5713 int default_query_interval_dsec;
5714 int ret;
5715
5716 if (!pim_ifp) {
5717 ret = pim_cmd_igmp_start(vty, ifp);
5718 if (ret != CMD_SUCCESS)
5719 return ret;
5720 pim_ifp = ifp->info;
5721 }
12e41d03 5722
d62a17ae 5723 query_max_response_time_dsec = atoi(argv[4]->arg);
12e41d03 5724
d62a17ae 5725 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
12e41d03 5726
d62a17ae 5727 if (query_max_response_time_dsec >= default_query_interval_dsec) {
5728 vty_out(vty,
5729 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
5730 query_max_response_time_dsec,
5731 default_query_interval_dsec);
5732 return CMD_WARNING_CONFIG_FAILED;
5733 }
12e41d03 5734
d62a17ae 5735 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
12e41d03 5736
d62a17ae 5737 return CMD_SUCCESS;
12e41d03
DL
5738}
5739
58344b65
DS
5740DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
5741 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
5742 "no ip igmp query-max-response-time-dsec",
5743 NO_STR
5744 IP_STR
5745 IFACE_IGMP_STR
5746 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
12e41d03 5747{
d62a17ae 5748 VTY_DECLVAR_CONTEXT(interface, ifp);
5749 struct pim_interface *pim_ifp = ifp->info;
12e41d03 5750
d62a17ae 5751 if (!pim_ifp)
5752 return CMD_SUCCESS;
12e41d03 5753
d62a17ae 5754 change_query_max_response_time(pim_ifp,
5755 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
12e41d03 5756
d62a17ae 5757 return CMD_SUCCESS;
12e41d03
DL
5758}
5759
dedccda6
DS
5760DEFUN (interface_ip_pim_drprio,
5761 interface_ip_pim_drprio_cmd,
b181fa04 5762 "ip pim drpriority (1-4294967295)",
dedccda6
DS
5763 IP_STR
5764 PIM_STR
5765 "Set the Designated Router Election Priority\n"
5766 "Value of the new DR Priority\n")
5767{
d62a17ae 5768 VTY_DECLVAR_CONTEXT(interface, ifp);
5769 int idx_number = 3;
5770 struct pim_interface *pim_ifp = ifp->info;
5771 uint32_t old_dr_prio;
dedccda6 5772
d62a17ae 5773 if (!pim_ifp) {
5774 vty_out(vty, "Please enable PIM on interface, first\n");
5775 return CMD_WARNING_CONFIG_FAILED;
5776 }
dedccda6 5777
d62a17ae 5778 old_dr_prio = pim_ifp->pim_dr_priority;
dedccda6 5779
d62a17ae 5780 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
dedccda6 5781
d62a17ae 5782 if (old_dr_prio != pim_ifp->pim_dr_priority) {
5783 if (pim_if_dr_election(ifp))
5784 pim_hello_restart_now(ifp);
5785 }
dedccda6 5786
d62a17ae 5787 return CMD_SUCCESS;
dedccda6
DS
5788}
5789
5790DEFUN (interface_no_ip_pim_drprio,
5791 interface_no_ip_pim_drprio_cmd,
b181fa04 5792 "no ip pim drpriority [(1-4294967295)]",
d7fa34c1 5793 NO_STR
dedccda6
DS
5794 IP_STR
5795 PIM_STR
5796 "Revert the Designated Router Priority to default\n"
5797 "Old Value of the Priority\n")
5798{
d62a17ae 5799 VTY_DECLVAR_CONTEXT(interface, ifp);
5800 struct pim_interface *pim_ifp = ifp->info;
dedccda6 5801
d62a17ae 5802 if (!pim_ifp) {
5803 vty_out(vty, "Pim not enabled on this interface\n");
5804 return CMD_WARNING_CONFIG_FAILED;
5805 }
dedccda6 5806
d62a17ae 5807 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
5808 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
5809 if (pim_if_dr_election(ifp))
5810 pim_hello_restart_now(ifp);
5811 }
dedccda6 5812
d62a17ae 5813 return CMD_SUCCESS;
dedccda6
DS
5814}
5815
d62a17ae 5816static int pim_cmd_interface_add(struct interface *ifp)
12e41d03 5817{
d62a17ae 5818 struct pim_interface *pim_ifp = ifp->info;
12e41d03 5819
d62a17ae 5820 if (!pim_ifp) {
5821 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
5822 if (!pim_ifp) {
5823 return 0;
5824 }
5825 } else {
5826 PIM_IF_DO_PIM(pim_ifp->options);
5827 }
12e41d03 5828
d62a17ae 5829 pim_if_addr_add_all(ifp);
5830 pim_if_membership_refresh(ifp);
5831 return 1;
981d6c7a
DS
5832}
5833
d2772e7b 5834DEFUN_HIDDEN (interface_ip_pim_ssm,
981d6c7a
DS
5835 interface_ip_pim_ssm_cmd,
5836 "ip pim ssm",
5837 IP_STR
5838 PIM_STR
5839 IFACE_PIM_STR)
5840{
d62a17ae 5841 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a 5842
d62a17ae 5843 if (!pim_cmd_interface_add(ifp)) {
5844 vty_out(vty, "Could not enable PIM SM on interface\n");
5845 return CMD_WARNING_CONFIG_FAILED;
5846 }
981d6c7a 5847
d62a17ae 5848 vty_out(vty,
5849 "WARN: Enabled PIM SM on interface; configure PIM SSM "
5850 "range if needed\n");
5851 return CMD_SUCCESS;
12e41d03
DL
5852}
5853
981d6c7a
DS
5854DEFUN (interface_ip_pim_sm,
5855 interface_ip_pim_sm_cmd,
5856 "ip pim sm",
12e41d03
DL
5857 IP_STR
5858 PIM_STR
8371bd60 5859 IFACE_PIM_SM_STR)
12e41d03 5860{
43e40fdf
DS
5861 struct pim_interface *pim_ifp;
5862
d62a17ae 5863 VTY_DECLVAR_CONTEXT(interface, ifp);
5864 if (!pim_cmd_interface_add(ifp)) {
5865 vty_out(vty, "Could not enable PIM SM on interface\n");
5866 return CMD_WARNING_CONFIG_FAILED;
5867 }
981d6c7a 5868
43e40fdf 5869 pim_ifp = ifp->info;
ecca97ac 5870
43e40fdf 5871 pim_if_create_pimreg(pim_ifp->pim);
c992c9a0 5872
d62a17ae 5873 return CMD_SUCCESS;
981d6c7a
DS
5874}
5875
d62a17ae 5876static int pim_cmd_interface_delete(struct interface *ifp)
981d6c7a 5877{
d62a17ae 5878 struct pim_interface *pim_ifp = ifp->info;
981d6c7a 5879
d62a17ae 5880 if (!pim_ifp)
5881 return 1;
12e41d03 5882
d62a17ae 5883 PIM_IF_DONT_PIM(pim_ifp->options);
12e41d03 5884
d62a17ae 5885 pim_if_membership_clear(ifp);
12e41d03 5886
d62a17ae 5887 /*
5888 pim_sock_delete() removes all neighbors from
5889 pim_ifp->pim_neighbor_list.
5890 */
5891 pim_sock_delete(ifp, "pim unconfigured on interface");
12e41d03 5892
d62a17ae 5893 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
5894 pim_if_addr_del_all(ifp);
5895 pim_if_delete(ifp);
5896 }
12e41d03 5897
d62a17ae 5898 return 1;
981d6c7a
DS
5899}
5900
d2772e7b 5901DEFUN_HIDDEN (interface_no_ip_pim_ssm,
981d6c7a
DS
5902 interface_no_ip_pim_ssm_cmd,
5903 "no ip pim ssm",
5904 NO_STR
5905 IP_STR
5906 PIM_STR
5907 IFACE_PIM_STR)
5908{
d62a17ae 5909 VTY_DECLVAR_CONTEXT(interface, ifp);
5910 if (!pim_cmd_interface_delete(ifp)) {
5911 vty_out(vty, "Unable to delete interface information\n");
5912 return CMD_WARNING_CONFIG_FAILED;
5913 }
981d6c7a 5914
d62a17ae 5915 return CMD_SUCCESS;
981d6c7a
DS
5916}
5917
5918DEFUN (interface_no_ip_pim_sm,
5919 interface_no_ip_pim_sm_cmd,
5920 "no ip pim sm",
5921 NO_STR
5922 IP_STR
5923 PIM_STR
8371bd60 5924 IFACE_PIM_SM_STR)
981d6c7a 5925{
d62a17ae 5926 VTY_DECLVAR_CONTEXT(interface, ifp);
5927 if (!pim_cmd_interface_delete(ifp)) {
5928 vty_out(vty, "Unable to delete interface information\n");
5929 return CMD_WARNING_CONFIG_FAILED;
5930 }
981d6c7a 5931
d62a17ae 5932 return CMD_SUCCESS;
12e41d03
DL
5933}
5934
6250610a
JAG
5935DEFUN (interface_ip_mroute,
5936 interface_ip_mroute_cmd,
5937 "ip mroute INTERFACE A.B.C.D",
5938 IP_STR
5939 "Add multicast route\n"
5940 "Outgoing interface name\n"
5941 "Group address\n")
5942{
d62a17ae 5943 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
5944 struct pim_interface *pim_ifp;
5945 struct pim_instance *pim;
d62a17ae 5946 int idx_interface = 2;
5947 int idx_ipv4 = 3;
5948 struct interface *oif;
5949 const char *oifname;
5950 const char *grp_str;
5951 struct in_addr grp_addr;
5952 struct in_addr src_addr;
5953 int result;
5954
4e0bc0f0
DS
5955 pim_ifp = iif->info;
5956 pim = pim_ifp->pim;
5957
d62a17ae 5958 oifname = argv[idx_interface]->arg;
4e0bc0f0 5959 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 5960 if (!oif) {
5961 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 5962 return CMD_WARNING;
d62a17ae 5963 }
5964
5965 grp_str = argv[idx_ipv4]->arg;
5966 result = inet_pton(AF_INET, grp_str, &grp_addr);
5967 if (result <= 0) {
5968 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
5969 errno, safe_strerror(errno));
4e0bc0f0 5970 return CMD_WARNING;
d62a17ae 5971 }
5972
5973 src_addr.s_addr = INADDR_ANY;
5974
4e0bc0f0 5975 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 5976 vty_out(vty, "Failed to add route\n");
4e0bc0f0 5977 return CMD_WARNING;
d62a17ae 5978 }
5979
5980 return CMD_SUCCESS;
6250610a
JAG
5981}
5982
5983DEFUN (interface_ip_mroute_source,
5984 interface_ip_mroute_source_cmd,
5985 "ip mroute INTERFACE A.B.C.D A.B.C.D",
5986 IP_STR
5987 "Add multicast route\n"
5988 "Outgoing interface name\n"
5989 "Group address\n"
5990 "Source address\n")
5991{
d62a17ae 5992 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
5993 struct pim_interface *pim_ifp;
5994 struct pim_instance *pim;
d62a17ae 5995 int idx_interface = 2;
5996 int idx_ipv4 = 3;
5997 int idx_ipv4_2 = 4;
5998 struct interface *oif;
5999 const char *oifname;
6000 const char *grp_str;
6001 struct in_addr grp_addr;
6002 const char *src_str;
6003 struct in_addr src_addr;
6004 int result;
6005
4e0bc0f0
DS
6006 pim_ifp = iif->info;
6007 pim = pim_ifp->pim;
6008
d62a17ae 6009 oifname = argv[idx_interface]->arg;
4e0bc0f0 6010 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 6011 if (!oif) {
6012 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 6013 return CMD_WARNING;
d62a17ae 6014 }
6015
6016 grp_str = argv[idx_ipv4]->arg;
6017 result = inet_pton(AF_INET, grp_str, &grp_addr);
6018 if (result <= 0) {
6019 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
6020 errno, safe_strerror(errno));
4e0bc0f0 6021 return CMD_WARNING;
d62a17ae 6022 }
6023
6024 src_str = argv[idx_ipv4_2]->arg;
6025 result = inet_pton(AF_INET, src_str, &src_addr);
6026 if (result <= 0) {
6027 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
6028 errno, safe_strerror(errno));
4e0bc0f0 6029 return CMD_WARNING;
d62a17ae 6030 }
6031
4e0bc0f0 6032 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 6033 vty_out(vty, "Failed to add route\n");
4e0bc0f0 6034 return CMD_WARNING;
d62a17ae 6035 }
6036
6037 return CMD_SUCCESS;
6250610a
JAG
6038}
6039
6040DEFUN (interface_no_ip_mroute,
6041 interface_no_ip_mroute_cmd,
6042 "no ip mroute INTERFACE A.B.C.D",
6043 NO_STR
6044 IP_STR
6045 "Add multicast route\n"
6046 "Outgoing interface name\n"
6047 "Group Address\n")
6048{
d62a17ae 6049 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
6050 struct pim_interface *pim_ifp;
6051 struct pim_instance *pim;
d62a17ae 6052 int idx_interface = 3;
6053 int idx_ipv4 = 4;
6054 struct interface *oif;
6055 const char *oifname;
6056 const char *grp_str;
6057 struct in_addr grp_addr;
6058 struct in_addr src_addr;
6059 int result;
6060
4e0bc0f0
DS
6061 pim_ifp = iif->info;
6062 pim = pim_ifp->pim;
6063
d62a17ae 6064 oifname = argv[idx_interface]->arg;
4e0bc0f0 6065 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 6066 if (!oif) {
6067 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 6068 return CMD_WARNING;
d62a17ae 6069 }
6070
6071 grp_str = argv[idx_ipv4]->arg;
6072 result = inet_pton(AF_INET, grp_str, &grp_addr);
6073 if (result <= 0) {
6074 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
6075 errno, safe_strerror(errno));
4e0bc0f0 6076 return CMD_WARNING;
d62a17ae 6077 }
6078
6079 src_addr.s_addr = INADDR_ANY;
6080
4e0bc0f0 6081 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 6082 vty_out(vty, "Failed to remove route\n");
4e0bc0f0 6083 return CMD_WARNING;
d62a17ae 6084 }
6085
6086 return CMD_SUCCESS;
6250610a
JAG
6087}
6088
6089DEFUN (interface_no_ip_mroute_source,
6090 interface_no_ip_mroute_source_cmd,
6091 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6092 NO_STR
6093 IP_STR
6094 "Add multicast route\n"
6095 "Outgoing interface name\n"
6096 "Group Address\n"
6097 "Source Address\n")
6098{
d62a17ae 6099 VTY_DECLVAR_CONTEXT(interface, iif);
4e0bc0f0
DS
6100 struct pim_interface *pim_ifp;
6101 struct pim_instance *pim;
d62a17ae 6102 int idx_interface = 3;
6103 int idx_ipv4 = 4;
6104 int idx_ipv4_2 = 5;
6105 struct interface *oif;
6106 const char *oifname;
6107 const char *grp_str;
6108 struct in_addr grp_addr;
6109 const char *src_str;
6110 struct in_addr src_addr;
6111 int result;
6112
4e0bc0f0
DS
6113 pim_ifp = iif->info;
6114 pim = pim_ifp->pim;
6115
d62a17ae 6116 oifname = argv[idx_interface]->arg;
4e0bc0f0 6117 oif = if_lookup_by_name(oifname, pim->vrf_id);
d62a17ae 6118 if (!oif) {
6119 vty_out(vty, "No such interface name %s\n", oifname);
4e0bc0f0 6120 return CMD_WARNING;
d62a17ae 6121 }
6122
6123 grp_str = argv[idx_ipv4]->arg;
6124 result = inet_pton(AF_INET, grp_str, &grp_addr);
6125 if (result <= 0) {
6126 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
6127 errno, safe_strerror(errno));
4e0bc0f0 6128 return CMD_WARNING;
d62a17ae 6129 }
6130
6131 src_str = argv[idx_ipv4_2]->arg;
6132 result = inet_pton(AF_INET, src_str, &src_addr);
6133 if (result <= 0) {
6134 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
6135 errno, safe_strerror(errno));
4e0bc0f0 6136 return CMD_WARNING;
d62a17ae 6137 }
6138
4e0bc0f0 6139 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
d62a17ae 6140 vty_out(vty, "Failed to remove route\n");
4e0bc0f0 6141 return CMD_WARNING;
d62a17ae 6142 }
6143
6144 return CMD_SUCCESS;
6250610a
JAG
6145}
6146
7960fa8f
DS
6147DEFUN (interface_ip_pim_hello,
6148 interface_ip_pim_hello_cmd,
80d3d26b 6149 "ip pim hello (1-180) [(1-180)]",
7960fa8f
DS
6150 IP_STR
6151 PIM_STR
6152 IFACE_PIM_HELLO_STR
80d3d26b
DW
6153 IFACE_PIM_HELLO_TIME_STR
6154 IFACE_PIM_HELLO_HOLD_STR)
7960fa8f 6155{
d62a17ae 6156 VTY_DECLVAR_CONTEXT(interface, ifp);
6157 int idx_time = 3;
6158 int idx_hold = 4;
6159 struct pim_interface *pim_ifp = ifp->info;
7960fa8f 6160
d62a17ae 6161 if (!pim_ifp) {
6162 if (!pim_cmd_interface_add(ifp)) {
6163 vty_out(vty, "Could not enable PIM SM on interface\n");
6164 return CMD_WARNING_CONFIG_FAILED;
6165 }
6166 }
7960fa8f 6167
d62a17ae 6168 pim_ifp = ifp->info;
6169 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
7960fa8f 6170
d62a17ae 6171 if (argc == idx_hold + 1)
6172 pim_ifp->pim_default_holdtime =
6173 strtol(argv[idx_hold]->arg, NULL, 10);
7960fa8f 6174
d62a17ae 6175 return CMD_SUCCESS;
7960fa8f
DS
6176}
6177
7960fa8f
DS
6178DEFUN (interface_no_ip_pim_hello,
6179 interface_no_ip_pim_hello_cmd,
b181fa04 6180 "no ip pim hello [(1-180) (1-180)]",
7960fa8f
DS
6181 NO_STR
6182 IP_STR
6183 PIM_STR
6184 IFACE_PIM_HELLO_STR
6185 IFACE_PIM_HELLO_TIME_STR
6186 IFACE_PIM_HELLO_HOLD_STR)
6187{
d62a17ae 6188 VTY_DECLVAR_CONTEXT(interface, ifp);
6189 struct pim_interface *pim_ifp = ifp->info;
7960fa8f 6190
d62a17ae 6191 if (!pim_ifp) {
6192 vty_out(vty, "Pim not enabled on this interface\n");
6193 return CMD_WARNING_CONFIG_FAILED;
6194 }
7960fa8f 6195
d62a17ae 6196 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
6197 pim_ifp->pim_default_holdtime = -1;
7960fa8f 6198
d62a17ae 6199 return CMD_SUCCESS;
7960fa8f
DS
6200}
6201
12e41d03
DL
6202DEFUN (debug_igmp,
6203 debug_igmp_cmd,
6204 "debug igmp",
6205 DEBUG_STR
6206 DEBUG_IGMP_STR)
6207{
d62a17ae 6208 PIM_DO_DEBUG_IGMP_EVENTS;
6209 PIM_DO_DEBUG_IGMP_PACKETS;
6210 PIM_DO_DEBUG_IGMP_TRACE;
6211 return CMD_SUCCESS;
12e41d03
DL
6212}
6213
6214DEFUN (no_debug_igmp,
6215 no_debug_igmp_cmd,
6216 "no debug igmp",
6217 NO_STR
6218 DEBUG_STR
6219 DEBUG_IGMP_STR)
6220{
d62a17ae 6221 PIM_DONT_DEBUG_IGMP_EVENTS;
6222 PIM_DONT_DEBUG_IGMP_PACKETS;
6223 PIM_DONT_DEBUG_IGMP_TRACE;
6224 return CMD_SUCCESS;
12e41d03
DL
6225}
6226
12e41d03
DL
6227
6228DEFUN (debug_igmp_events,
6229 debug_igmp_events_cmd,
6230 "debug igmp events",
6231 DEBUG_STR
6232 DEBUG_IGMP_STR
6233 DEBUG_IGMP_EVENTS_STR)
6234{
d62a17ae 6235 PIM_DO_DEBUG_IGMP_EVENTS;
6236 return CMD_SUCCESS;
12e41d03
DL
6237}
6238
6239DEFUN (no_debug_igmp_events,
6240 no_debug_igmp_events_cmd,
6241 "no debug igmp events",
6242 NO_STR
6243 DEBUG_STR
6244 DEBUG_IGMP_STR
6245 DEBUG_IGMP_EVENTS_STR)
6246{
d62a17ae 6247 PIM_DONT_DEBUG_IGMP_EVENTS;
6248 return CMD_SUCCESS;
12e41d03
DL
6249}
6250
12e41d03
DL
6251
6252DEFUN (debug_igmp_packets,
6253 debug_igmp_packets_cmd,
6254 "debug igmp packets",
6255 DEBUG_STR
6256 DEBUG_IGMP_STR
6257 DEBUG_IGMP_PACKETS_STR)
6258{
d62a17ae 6259 PIM_DO_DEBUG_IGMP_PACKETS;
6260 return CMD_SUCCESS;
12e41d03
DL
6261}
6262
6263DEFUN (no_debug_igmp_packets,
6264 no_debug_igmp_packets_cmd,
6265 "no debug igmp packets",
6266 NO_STR
6267 DEBUG_STR
6268 DEBUG_IGMP_STR
6269 DEBUG_IGMP_PACKETS_STR)
6270{
d62a17ae 6271 PIM_DONT_DEBUG_IGMP_PACKETS;
6272 return CMD_SUCCESS;
12e41d03
DL
6273}
6274
12e41d03
DL
6275
6276DEFUN (debug_igmp_trace,
6277 debug_igmp_trace_cmd,
6278 "debug igmp trace",
6279 DEBUG_STR
6280 DEBUG_IGMP_STR
6281 DEBUG_IGMP_TRACE_STR)
6282{
d62a17ae 6283 PIM_DO_DEBUG_IGMP_TRACE;
6284 return CMD_SUCCESS;
12e41d03
DL
6285}
6286
6287DEFUN (no_debug_igmp_trace,
6288 no_debug_igmp_trace_cmd,
6289 "no debug igmp trace",
6290 NO_STR
6291 DEBUG_STR
6292 DEBUG_IGMP_STR
6293 DEBUG_IGMP_TRACE_STR)
6294{
d62a17ae 6295 PIM_DONT_DEBUG_IGMP_TRACE;
6296 return CMD_SUCCESS;
12e41d03
DL
6297}
6298
12e41d03
DL
6299
6300DEFUN (debug_mroute,
6301 debug_mroute_cmd,
6302 "debug mroute",
6303 DEBUG_STR
6304 DEBUG_MROUTE_STR)
6305{
d62a17ae 6306 PIM_DO_DEBUG_MROUTE;
6307 return CMD_SUCCESS;
12e41d03
DL
6308}
6309
6c7197b1
DS
6310DEFUN (debug_mroute_detail,
6311 debug_mroute_detail_cmd,
6312 "debug mroute detail",
6313 DEBUG_STR
6314 DEBUG_MROUTE_STR
6315 "detailed\n")
6316{
d62a17ae 6317 PIM_DO_DEBUG_MROUTE_DETAIL;
6318 return CMD_SUCCESS;
6c7197b1
DS
6319}
6320
12e41d03
DL
6321DEFUN (no_debug_mroute,
6322 no_debug_mroute_cmd,
6323 "no debug mroute",
6324 NO_STR
6325 DEBUG_STR
6326 DEBUG_MROUTE_STR)
6327{
d62a17ae 6328 PIM_DONT_DEBUG_MROUTE;
6329 return CMD_SUCCESS;
12e41d03
DL
6330}
6331
6c7197b1
DS
6332DEFUN (no_debug_mroute_detail,
6333 no_debug_mroute_detail_cmd,
6334 "no debug mroute detail",
6335 NO_STR
6336 DEBUG_STR
6337 DEBUG_MROUTE_STR
6338 "detailed\n")
6339{
d62a17ae 6340 PIM_DONT_DEBUG_MROUTE_DETAIL;
6341 return CMD_SUCCESS;
6c7197b1 6342}
12e41d03 6343
6250610a
JAG
6344DEFUN (debug_static,
6345 debug_static_cmd,
6346 "debug static",
6347 DEBUG_STR
6348 DEBUG_STATIC_STR)
6349{
d62a17ae 6350 PIM_DO_DEBUG_STATIC;
6351 return CMD_SUCCESS;
6250610a
JAG
6352}
6353
6354DEFUN (no_debug_static,
6355 no_debug_static_cmd,
6356 "no debug static",
6357 NO_STR
6358 DEBUG_STR
6359 DEBUG_STATIC_STR)
6360{
d62a17ae 6361 PIM_DONT_DEBUG_STATIC;
6362 return CMD_SUCCESS;
6250610a
JAG
6363}
6364
6250610a 6365
12e41d03
DL
6366DEFUN (debug_pim,
6367 debug_pim_cmd,
6368 "debug pim",
6369 DEBUG_STR
6370 DEBUG_PIM_STR)
6371{
d62a17ae 6372 PIM_DO_DEBUG_PIM_EVENTS;
6373 PIM_DO_DEBUG_PIM_PACKETS;
6374 PIM_DO_DEBUG_PIM_TRACE;
6375 PIM_DO_DEBUG_MSDP_EVENTS;
6376 PIM_DO_DEBUG_MSDP_PACKETS;
6377 return CMD_SUCCESS;
12e41d03
DL
6378}
6379
6380DEFUN (no_debug_pim,
6381 no_debug_pim_cmd,
6382 "no debug pim",
6383 NO_STR
6384 DEBUG_STR
6385 DEBUG_PIM_STR)
6386{
d62a17ae 6387 PIM_DONT_DEBUG_PIM_EVENTS;
6388 PIM_DONT_DEBUG_PIM_PACKETS;
6389 PIM_DONT_DEBUG_PIM_TRACE;
6390 PIM_DONT_DEBUG_MSDP_EVENTS;
6391 PIM_DONT_DEBUG_MSDP_PACKETS;
12e41d03 6392
d62a17ae 6393 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
6394 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
12e41d03 6395
d62a17ae 6396 return CMD_SUCCESS;
12e41d03
DL
6397}
6398
12e41d03
DL
6399
6400DEFUN (debug_pim_events,
6401 debug_pim_events_cmd,
6402 "debug pim events",
6403 DEBUG_STR
6404 DEBUG_PIM_STR
6405 DEBUG_PIM_EVENTS_STR)
6406{
d62a17ae 6407 PIM_DO_DEBUG_PIM_EVENTS;
6408 return CMD_SUCCESS;
12e41d03
DL
6409}
6410
6411DEFUN (no_debug_pim_events,
6412 no_debug_pim_events_cmd,
6413 "no debug pim events",
6414 NO_STR
6415 DEBUG_STR
6416 DEBUG_PIM_STR
6417 DEBUG_PIM_EVENTS_STR)
6418{
d62a17ae 6419 PIM_DONT_DEBUG_PIM_EVENTS;
6420 return CMD_SUCCESS;
12e41d03
DL
6421}
6422
12e41d03
DL
6423DEFUN (debug_pim_packets,
6424 debug_pim_packets_cmd,
a957a05b 6425 "debug pim packets [<hello|joins|register>]",
12e41d03
DL
6426 DEBUG_STR
6427 DEBUG_PIM_STR
6428 DEBUG_PIM_PACKETS_STR
6429 DEBUG_PIM_HELLO_PACKETS_STR
9add3b88
DS
6430 DEBUG_PIM_J_P_PACKETS_STR
6431 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 6432{
d62a17ae 6433 int idx = 0;
6434 if (argv_find(argv, argc, "hello", &idx)) {
6435 PIM_DO_DEBUG_PIM_HELLO;
6436 vty_out(vty, "PIM Hello debugging is on\n");
6437 } else if (argv_find(argv, argc, "joins", &idx)) {
6438 PIM_DO_DEBUG_PIM_J_P;
6439 vty_out(vty, "PIM Join/Prune debugging is on\n");
6440 } else if (argv_find(argv, argc, "register", &idx)) {
6441 PIM_DO_DEBUG_PIM_REG;
6442 vty_out(vty, "PIM Register debugging is on\n");
6443 } else {
6444 PIM_DO_DEBUG_PIM_PACKETS;
6445 vty_out(vty, "PIM Packet debugging is on \n");
6446 }
6447 return CMD_SUCCESS;
12e41d03
DL
6448}
6449
6450DEFUN (no_debug_pim_packets,
6451 no_debug_pim_packets_cmd,
a957a05b 6452 "no debug pim packets [<hello|joins|register>]",
12e41d03
DL
6453 NO_STR
6454 DEBUG_STR
6455 DEBUG_PIM_STR
6456 DEBUG_PIM_PACKETS_STR
6457 DEBUG_PIM_HELLO_PACKETS_STR
a957a05b
DS
6458 DEBUG_PIM_J_P_PACKETS_STR
6459 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 6460{
d62a17ae 6461 int idx = 0;
6462 if (argv_find(argv, argc, "hello", &idx)) {
6463 PIM_DONT_DEBUG_PIM_HELLO;
6464 vty_out(vty, "PIM Hello debugging is off \n");
6465 } else if (argv_find(argv, argc, "joins", &idx)) {
6466 PIM_DONT_DEBUG_PIM_J_P;
6467 vty_out(vty, "PIM Join/Prune debugging is off \n");
6468 } else if (argv_find(argv, argc, "register", &idx)) {
6469 PIM_DONT_DEBUG_PIM_REG;
6470 vty_out(vty, "PIM Register debugging is off\n");
6471 } else
6472 PIM_DONT_DEBUG_PIM_PACKETS;
6473
6474 return CMD_SUCCESS;
12e41d03
DL
6475}
6476
12e41d03
DL
6477
6478DEFUN (debug_pim_packetdump_send,
6479 debug_pim_packetdump_send_cmd,
6480 "debug pim packet-dump send",
6481 DEBUG_STR
6482 DEBUG_PIM_STR
6483 DEBUG_PIM_PACKETDUMP_STR
6484 DEBUG_PIM_PACKETDUMP_SEND_STR)
6485{
d62a17ae 6486 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
6487 return CMD_SUCCESS;
12e41d03
DL
6488}
6489
6490DEFUN (no_debug_pim_packetdump_send,
6491 no_debug_pim_packetdump_send_cmd,
6492 "no debug pim packet-dump send",
6493 NO_STR
6494 DEBUG_STR
6495 DEBUG_PIM_STR
6496 DEBUG_PIM_PACKETDUMP_STR
6497 DEBUG_PIM_PACKETDUMP_SEND_STR)
6498{
d62a17ae 6499 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
6500 return CMD_SUCCESS;
12e41d03
DL
6501}
6502
12e41d03
DL
6503DEFUN (debug_pim_packetdump_recv,
6504 debug_pim_packetdump_recv_cmd,
6505 "debug pim packet-dump receive",
6506 DEBUG_STR
6507 DEBUG_PIM_STR
6508 DEBUG_PIM_PACKETDUMP_STR
6509 DEBUG_PIM_PACKETDUMP_RECV_STR)
6510{
d62a17ae 6511 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
6512 return CMD_SUCCESS;
12e41d03
DL
6513}
6514
6515DEFUN (no_debug_pim_packetdump_recv,
6516 no_debug_pim_packetdump_recv_cmd,
6517 "no debug pim packet-dump receive",
6518 NO_STR
6519 DEBUG_STR
6520 DEBUG_PIM_STR
6521 DEBUG_PIM_PACKETDUMP_STR
6522 DEBUG_PIM_PACKETDUMP_RECV_STR)
6523{
d62a17ae 6524 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
6525 return CMD_SUCCESS;
12e41d03
DL
6526}
6527
12e41d03
DL
6528DEFUN (debug_pim_trace,
6529 debug_pim_trace_cmd,
6530 "debug pim trace",
6531 DEBUG_STR
6532 DEBUG_PIM_STR
6533 DEBUG_PIM_TRACE_STR)
6534{
d62a17ae 6535 PIM_DO_DEBUG_PIM_TRACE;
6536 return CMD_SUCCESS;
12e41d03
DL
6537}
6538
56c238c9
DS
6539DEFUN (debug_pim_trace_detail,
6540 debug_pim_trace_detail_cmd,
6541 "debug pim trace detail",
6542 DEBUG_STR
6543 DEBUG_PIM_STR
5f40dada
DS
6544 DEBUG_PIM_TRACE_STR
6545 "Detailed Information\n")
56c238c9
DS
6546{
6547 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
6548 return CMD_SUCCESS;
6549}
6550
12e41d03
DL
6551DEFUN (no_debug_pim_trace,
6552 no_debug_pim_trace_cmd,
6553 "no debug pim trace",
6554 NO_STR
6555 DEBUG_STR
6556 DEBUG_PIM_STR
6557 DEBUG_PIM_TRACE_STR)
6558{
d62a17ae 6559 PIM_DONT_DEBUG_PIM_TRACE;
6560 return CMD_SUCCESS;
12e41d03
DL
6561}
6562
56c238c9
DS
6563DEFUN (no_debug_pim_trace_detail,
6564 no_debug_pim_trace_detail_cmd,
9853a7a5 6565 "no debug pim trace detail",
56c238c9
DS
6566 NO_STR
6567 DEBUG_STR
6568 DEBUG_PIM_STR
6569 DEBUG_PIM_TRACE_STR)
6570{
6571 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
6572 return CMD_SUCCESS;
6573}
6574
12e41d03
DL
6575DEFUN (debug_ssmpingd,
6576 debug_ssmpingd_cmd,
6577 "debug ssmpingd",
6578 DEBUG_STR
12e41d03
DL
6579 DEBUG_SSMPINGD_STR)
6580{
d62a17ae 6581 PIM_DO_DEBUG_SSMPINGD;
6582 return CMD_SUCCESS;
12e41d03
DL
6583}
6584
6585DEFUN (no_debug_ssmpingd,
6586 no_debug_ssmpingd_cmd,
6587 "no debug ssmpingd",
6588 NO_STR
6589 DEBUG_STR
12e41d03
DL
6590 DEBUG_SSMPINGD_STR)
6591{
d62a17ae 6592 PIM_DONT_DEBUG_SSMPINGD;
6593 return CMD_SUCCESS;
12e41d03
DL
6594}
6595
12e41d03
DL
6596DEFUN (debug_pim_zebra,
6597 debug_pim_zebra_cmd,
6598 "debug pim zebra",
6599 DEBUG_STR
6600 DEBUG_PIM_STR
6601 DEBUG_PIM_ZEBRA_STR)
6602{
d62a17ae 6603 PIM_DO_DEBUG_ZEBRA;
6604 return CMD_SUCCESS;
12e41d03
DL
6605}
6606
6607DEFUN (no_debug_pim_zebra,
6608 no_debug_pim_zebra_cmd,
6609 "no debug pim zebra",
6610 NO_STR
6611 DEBUG_STR
6612 DEBUG_PIM_STR
6613 DEBUG_PIM_ZEBRA_STR)
6614{
d62a17ae 6615 PIM_DONT_DEBUG_ZEBRA;
6616 return CMD_SUCCESS;
12e41d03
DL
6617}
6618
2a333e0f 6619DEFUN (debug_msdp,
6620 debug_msdp_cmd,
6621 "debug msdp",
6622 DEBUG_STR
6623 DEBUG_MSDP_STR)
6624{
d62a17ae 6625 PIM_DO_DEBUG_MSDP_EVENTS;
6626 PIM_DO_DEBUG_MSDP_PACKETS;
6627 return CMD_SUCCESS;
2a333e0f 6628}
6629
6630DEFUN (no_debug_msdp,
6631 no_debug_msdp_cmd,
6632 "no debug msdp",
6633 NO_STR
6634 DEBUG_STR
6635 DEBUG_MSDP_STR)
6636{
d62a17ae 6637 PIM_DONT_DEBUG_MSDP_EVENTS;
6638 PIM_DONT_DEBUG_MSDP_PACKETS;
6639 return CMD_SUCCESS;
2a333e0f 6640}
6641
d62a17ae 6642ALIAS(no_debug_msdp, undebug_msdp_cmd, "undebug msdp",
6643 UNDEBUG_STR DEBUG_MSDP_STR)
2a333e0f 6644
6645DEFUN (debug_msdp_events,
6646 debug_msdp_events_cmd,
6647 "debug msdp events",
6648 DEBUG_STR
6649 DEBUG_MSDP_STR
6650 DEBUG_MSDP_EVENTS_STR)
6651{
d62a17ae 6652 PIM_DO_DEBUG_MSDP_EVENTS;
6653 return CMD_SUCCESS;
2a333e0f 6654}
6655
6656DEFUN (no_debug_msdp_events,
6657 no_debug_msdp_events_cmd,
6658 "no debug msdp events",
6659 NO_STR
6660 DEBUG_STR
6661 DEBUG_MSDP_STR
6662 DEBUG_MSDP_EVENTS_STR)
6663{
d62a17ae 6664 PIM_DONT_DEBUG_MSDP_EVENTS;
6665 return CMD_SUCCESS;
2a333e0f 6666}
6667
d62a17ae 6668ALIAS(no_debug_msdp_events, undebug_msdp_events_cmd, "undebug msdp events",
6669 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR)
2a333e0f 6670
6671DEFUN (debug_msdp_packets,
6672 debug_msdp_packets_cmd,
6673 "debug msdp packets",
6674 DEBUG_STR
6675 DEBUG_MSDP_STR
6676 DEBUG_MSDP_PACKETS_STR)
6677{
d62a17ae 6678 PIM_DO_DEBUG_MSDP_PACKETS;
6679 return CMD_SUCCESS;
2a333e0f 6680}
6681
6682DEFUN (no_debug_msdp_packets,
6683 no_debug_msdp_packets_cmd,
6684 "no debug msdp packets",
6685 NO_STR
6686 DEBUG_STR
6687 DEBUG_MSDP_STR
6688 DEBUG_MSDP_PACKETS_STR)
6689{
d62a17ae 6690 PIM_DONT_DEBUG_MSDP_PACKETS;
6691 return CMD_SUCCESS;
2a333e0f 6692}
6693
d62a17ae 6694ALIAS(no_debug_msdp_packets, undebug_msdp_packets_cmd, "undebug msdp packets",
6695 UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR)
2a333e0f 6696
7a1d58ce
DS
6697DEFUN (show_debugging_pim,
6698 show_debugging_pim_cmd,
6699 "show debugging pim",
12e41d03 6700 SHOW_STR
7a1d58ce
DS
6701 DEBUG_STR
6702 PIM_STR)
12e41d03 6703{
d62a17ae 6704 pim_debug_config_write(vty);
6705 return CMD_SUCCESS;
12e41d03
DL
6706}
6707
d62a17ae 6708static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
4763cd0e 6709{
d62a17ae 6710 int result;
6711 struct in_addr source_addr;
6712 VTY_DECLVAR_CONTEXT(interface, ifp);
4763cd0e 6713
d62a17ae 6714 result = inet_pton(AF_INET, source, &source_addr);
6715 if (result <= 0) {
6716 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
6717 errno, safe_strerror(errno));
6718 return CMD_WARNING_CONFIG_FAILED;
6719 }
4763cd0e 6720
d62a17ae 6721 result = pim_update_source_set(ifp, source_addr);
6722 switch (result) {
6723 case PIM_SUCCESS:
6724 break;
6725 case PIM_IFACE_NOT_FOUND:
6726 vty_out(vty, "Pim not enabled on this interface\n");
6727 break;
6728 case PIM_UPDATE_SOURCE_DUP:
6729 vty_out(vty, "%% Source already set to %s\n", source);
6730 break;
6731 default:
6732 vty_out(vty, "%% Source set failed\n");
6733 }
4763cd0e 6734
d62a17ae 6735 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
4763cd0e 6736}
6737
6738DEFUN (interface_pim_use_source,
6739 interface_pim_use_source_cmd,
6740 "ip pim use-source A.B.C.D",
6741 IP_STR
6742 "pim multicast routing\n"
6743 "Configure primary IP address\n"
6744 "source ip address\n")
6745{
d62a17ae 6746 return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
4763cd0e 6747}
6748
6749DEFUN (interface_no_pim_use_source,
6750 interface_no_pim_use_source_cmd,
6751 "no ip pim use-source",
6752 NO_STR
6753 IP_STR
6754 "pim multicast routing\n"
6755 "Delete source IP address\n")
6756{
d62a17ae 6757 return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
4763cd0e 6758}
6759
ba4eb1bc
CS
6760DEFUN (ip_pim_bfd,
6761 ip_pim_bfd_cmd,
6762 "ip pim bfd",
6763 IP_STR
6764 PIM_STR
6765 "Enables BFD support\n")
6766{
d62a17ae 6767 VTY_DECLVAR_CONTEXT(interface, ifp);
6768 struct pim_interface *pim_ifp = ifp->info;
6769 struct bfd_info *bfd_info = NULL;
ba4eb1bc 6770
d62a17ae 6771 if (!pim_ifp)
6772 return CMD_SUCCESS;
6773 bfd_info = pim_ifp->bfd_info;
ba4eb1bc 6774
d62a17ae 6775 if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
6776 pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
6777 BFD_DEF_DETECT_MULT, 1);
ba4eb1bc 6778
d62a17ae 6779 return CMD_SUCCESS;
ba4eb1bc
CS
6780}
6781
6782DEFUN (no_ip_pim_bfd,
6783 no_ip_pim_bfd_cmd,
6784 "no ip pim bfd",
6785 NO_STR
6786 IP_STR
6787 PIM_STR
6788 "Disables BFD support\n")
6789{
d62a17ae 6790 VTY_DECLVAR_CONTEXT(interface, ifp);
6791 struct pim_interface *pim_ifp = ifp->info;
ba4eb1bc 6792
d62a17ae 6793 if (!pim_ifp)
6794 return CMD_SUCCESS;
ba4eb1bc 6795
d62a17ae 6796 if (pim_ifp->bfd_info) {
6797 pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
6798 bfd_info_free(&(pim_ifp->bfd_info));
6799 }
ba4eb1bc 6800
d62a17ae 6801 return CMD_SUCCESS;
ba4eb1bc
CS
6802}
6803
6804DEFUN (ip_pim_bfd_param,
6805 ip_pim_bfd_param_cmd,
6806 "ip pim bfd (2-255) (50-60000) (50-60000)",
6807 IP_STR
6808 PIM_STR
6809 "Enables BFD support\n"
6810 "Detect Multiplier\n"
6811 "Required min receive interval\n"
6812 "Desired min transmit interval\n")
6813{
d62a17ae 6814 VTY_DECLVAR_CONTEXT(interface, ifp);
6815 int idx_number = 3;
6816 int idx_number_2 = 4;
6817 int idx_number_3 = 5;
6818 u_int32_t rx_val;
6819 u_int32_t tx_val;
6820 u_int8_t dm_val;
6821 int ret;
ba4eb1bc
CS
6822
6823
d62a17ae 6824 if ((ret = bfd_validate_param(
6825 vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
6826 argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
6827 != CMD_SUCCESS)
6828 return ret;
ba4eb1bc 6829
d62a17ae 6830 pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
ba4eb1bc 6831
d62a17ae 6832 return CMD_SUCCESS;
ba4eb1bc
CS
6833}
6834
d62a17ae 6835ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
9d303b37 6836 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
d62a17ae 6837 "Enables BFD support\n"
6838 "Detect Multiplier\n"
6839 "Required min receive interval\n"
6840 "Desired min transmit interval\n")
6841
64c86530 6842static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925 6843 const char *peer, const char *local)
d62a17ae 6844{
6845 enum pim_msdp_err result;
6846 struct in_addr peer_addr;
6847 struct in_addr local_addr;
6848
6849 result = inet_pton(AF_INET, peer, &peer_addr);
6850 if (result <= 0) {
6851 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
6852 errno, safe_strerror(errno));
6853 return CMD_WARNING_CONFIG_FAILED;
6854 }
6855
6856 result = inet_pton(AF_INET, local, &local_addr);
6857 if (result <= 0) {
6858 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
6859 errno, safe_strerror(errno));
6860 return CMD_WARNING_CONFIG_FAILED;
6861 }
ba4eb1bc 6862
4f9f3925 6863 result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
d62a17ae 6864 NULL /* mp_p */);
6865 switch (result) {
6866 case PIM_MSDP_ERR_NONE:
6867 break;
6868 case PIM_MSDP_ERR_OOM:
6869 vty_out(vty, "%% Out of memory\n");
6870 break;
6871 case PIM_MSDP_ERR_PEER_EXISTS:
6872 vty_out(vty, "%% Peer exists\n");
6873 break;
6874 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
6875 vty_out(vty, "%% Only one mesh-group allowed currently\n");
6876 break;
6877 default:
6878 vty_out(vty, "%% peer add failed\n");
6879 }
6880
6881 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
2a333e0f 6882}
6883
977d71cc 6884DEFUN_HIDDEN (ip_msdp_peer,
2a333e0f 6885 ip_msdp_peer_cmd,
6886 "ip msdp peer A.B.C.D source A.B.C.D",
6887 IP_STR
6888 CFG_MSDP_STR
6889 "Configure MSDP peer\n"
6890 "peer ip address\n"
6891 "Source address for TCP connection\n"
6892 "local ip address\n")
6893{
4f9f3925 6894 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 6895 return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg);
2a333e0f 6896}
6897
64c86530 6898static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
4f9f3925 6899 const char *peer)
2a333e0f 6900{
d62a17ae 6901 enum pim_msdp_err result;
6902 struct in_addr peer_addr;
2a333e0f 6903
d62a17ae 6904 result = inet_pton(AF_INET, peer, &peer_addr);
6905 if (result <= 0) {
6906 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
6907 errno, safe_strerror(errno));
6908 return CMD_WARNING_CONFIG_FAILED;
6909 }
2a333e0f 6910
4f9f3925 6911 result = pim_msdp_peer_del(pim, peer_addr);
d62a17ae 6912 switch (result) {
6913 case PIM_MSDP_ERR_NONE:
6914 break;
6915 case PIM_MSDP_ERR_NO_PEER:
6916 vty_out(vty, "%% Peer does not exist\n");
6917 break;
6918 default:
6919 vty_out(vty, "%% peer del failed\n");
6920 }
2a333e0f 6921
d62a17ae 6922 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
2a333e0f 6923}
6924
977d71cc 6925DEFUN_HIDDEN (no_ip_msdp_peer,
2a333e0f 6926 no_ip_msdp_peer_cmd,
6927 "no ip msdp peer A.B.C.D",
977d71cc 6928 NO_STR
2a333e0f 6929 IP_STR
6930 CFG_MSDP_STR
6931 "Delete MSDP peer\n"
6932 "peer ip address\n")
6933{
4f9f3925 6934 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 6935 return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg);
2a333e0f 6936}
6937
64c86530
DS
6938static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
6939 struct vty *vty, const char *mg,
6940 const char *mbr)
977d71cc 6941{
d62a17ae 6942 enum pim_msdp_err result;
6943 struct in_addr mbr_ip;
977d71cc 6944
d62a17ae 6945 result = inet_pton(AF_INET, mbr, &mbr_ip);
6946 if (result <= 0) {
6947 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
6948 errno, safe_strerror(errno));
6949 return CMD_WARNING_CONFIG_FAILED;
6950 }
977d71cc 6951
02a16316 6952 result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
d62a17ae 6953 switch (result) {
6954 case PIM_MSDP_ERR_NONE:
6955 break;
6956 case PIM_MSDP_ERR_OOM:
6957 vty_out(vty, "%% Out of memory\n");
6958 break;
6959 case PIM_MSDP_ERR_MG_MBR_EXISTS:
6960 vty_out(vty, "%% mesh-group member exists\n");
6961 break;
6962 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
6963 vty_out(vty, "%% Only one mesh-group allowed currently\n");
6964 break;
6965 default:
6966 vty_out(vty, "%% member add failed\n");
6967 }
977d71cc 6968
d62a17ae 6969 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 6970}
6971
6972DEFUN (ip_msdp_mesh_group_member,
6973 ip_msdp_mesh_group_member_cmd,
6974 "ip msdp mesh-group WORD member A.B.C.D",
6975 IP_STR
6976 CFG_MSDP_STR
6977 "Configure MSDP mesh-group\n"
6978 "mesh group name\n"
6979 "mesh group member\n"
6980 "peer ip address\n")
6981{
02a16316 6982 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 6983 return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg,
d62a17ae 6984 argv[5]->arg);
977d71cc 6985}
6986
64c86530
DS
6987static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
6988 struct vty *vty,
d62a17ae 6989 const char *mg,
6990 const char *mbr)
977d71cc 6991{
d62a17ae 6992 enum pim_msdp_err result;
6993 struct in_addr mbr_ip;
977d71cc 6994
d62a17ae 6995 result = inet_pton(AF_INET, mbr, &mbr_ip);
6996 if (result <= 0) {
6997 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
6998 errno, safe_strerror(errno));
6999 return CMD_WARNING_CONFIG_FAILED;
7000 }
977d71cc 7001
02a16316 7002 result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
d62a17ae 7003 switch (result) {
7004 case PIM_MSDP_ERR_NONE:
7005 break;
7006 case PIM_MSDP_ERR_NO_MG:
7007 vty_out(vty, "%% mesh-group does not exist\n");
7008 break;
7009 case PIM_MSDP_ERR_NO_MG_MBR:
7010 vty_out(vty, "%% mesh-group member does not exist\n");
7011 break;
7012 default:
7013 vty_out(vty, "%% mesh-group member del failed\n");
7014 }
977d71cc 7015
d62a17ae 7016 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 7017}
7018DEFUN (no_ip_msdp_mesh_group_member,
7019 no_ip_msdp_mesh_group_member_cmd,
7020 "no ip msdp mesh-group WORD member A.B.C.D",
7021 NO_STR
7022 IP_STR
7023 CFG_MSDP_STR
7024 "Delete MSDP mesh-group member\n"
7025 "mesh group name\n"
7026 "mesh group member\n"
7027 "peer ip address\n")
7028{
02a16316 7029 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 7030 return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg,
d62a17ae 7031 argv[6]->arg);
977d71cc 7032}
7033
64c86530
DS
7034static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
7035 struct vty *vty, const char *mg,
7036 const char *src)
977d71cc 7037{
d62a17ae 7038 enum pim_msdp_err result;
7039 struct in_addr src_ip;
977d71cc 7040
d62a17ae 7041 result = inet_pton(AF_INET, src, &src_ip);
7042 if (result <= 0) {
7043 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
7044 errno, safe_strerror(errno));
7045 return CMD_WARNING_CONFIG_FAILED;
7046 }
977d71cc 7047
02a16316 7048 result = pim_msdp_mg_src_add(pim, mg, src_ip);
d62a17ae 7049 switch (result) {
7050 case PIM_MSDP_ERR_NONE:
7051 break;
7052 case PIM_MSDP_ERR_OOM:
7053 vty_out(vty, "%% Out of memory\n");
7054 break;
7055 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
7056 vty_out(vty, "%% Only one mesh-group allowed currently\n");
7057 break;
7058 default:
7059 vty_out(vty, "%% source add failed\n");
7060 }
977d71cc 7061
d62a17ae 7062 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 7063}
7064
7065
7066DEFUN (ip_msdp_mesh_group_source,
7067 ip_msdp_mesh_group_source_cmd,
7068 "ip msdp mesh-group WORD source A.B.C.D",
7069 IP_STR
7070 CFG_MSDP_STR
7071 "Configure MSDP mesh-group\n"
7072 "mesh group name\n"
7073 "mesh group local address\n"
7074 "source ip address for the TCP connection\n")
7075{
02a16316 7076 PIM_DECLVAR_CONTEXT(vrf, pim);
64c86530 7077 return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg,
d62a17ae 7078 argv[5]->arg);
977d71cc 7079}
7080
64c86530
DS
7081static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
7082 struct vty *vty,
d62a17ae 7083 const char *mg)
977d71cc 7084{
d62a17ae 7085 enum pim_msdp_err result;
977d71cc 7086
02a16316 7087 result = pim_msdp_mg_src_del(pim, mg);
d62a17ae 7088 switch (result) {
7089 case PIM_MSDP_ERR_NONE:
7090 break;
7091 case PIM_MSDP_ERR_NO_MG:
7092 vty_out(vty, "%% mesh-group does not exist\n");
7093 break;
7094 default:
7095 vty_out(vty, "%% mesh-group source del failed\n");
7096 }
977d71cc 7097
d62a17ae 7098 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 7099}
7100
64c86530
DS
7101static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
7102 struct vty *vty, const char *mg)
977d71cc 7103{
d62a17ae 7104 enum pim_msdp_err result;
977d71cc 7105
02a16316 7106 result = pim_msdp_mg_del(pim, mg);
d62a17ae 7107 switch (result) {
7108 case PIM_MSDP_ERR_NONE:
7109 break;
7110 case PIM_MSDP_ERR_NO_MG:
7111 vty_out(vty, "%% mesh-group does not exist\n");
7112 break;
7113 default:
7114 vty_out(vty, "%% mesh-group source del failed\n");
7115 }
977d71cc 7116
d62a17ae 7117 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
977d71cc 7118}
7119
58344b65
DS
7120DEFUN (no_ip_msdp_mesh_group_source,
7121 no_ip_msdp_mesh_group_source_cmd,
7122 "no ip msdp mesh-group WORD source [A.B.C.D]",
977d71cc 7123 NO_STR
7124 IP_STR
7125 CFG_MSDP_STR
58344b65
DS
7126 "Delete MSDP mesh-group source\n"
7127 "mesh group name\n"
a957a05b 7128 "mesh group source\n"
58344b65 7129 "mesh group local address\n")
977d71cc 7130{
02a16316 7131 PIM_DECLVAR_CONTEXT(vrf, pim);
d62a17ae 7132 if (argc == 7)
64c86530 7133 return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[6]->arg);
d62a17ae 7134 else
64c86530 7135 return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty,
d62a17ae 7136 argv[4]->arg);
7137}
7138
7139static void print_empty_json_obj(struct vty *vty)
7140{
7141 json_object *json;
7142 json = json_object_new_object();
7143 vty_out(vty, "%s\n",
7144 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
7145 json_object_free(json);
7146}
7147
64c86530 7148static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
02a16316 7149 u_char uj)
d62a17ae 7150{
7151 struct listnode *mbrnode;
7152 struct pim_msdp_mg_mbr *mbr;
02a16316 7153 struct pim_msdp_mg *mg = pim->msdp.mg;
d62a17ae 7154 char mbr_str[INET_ADDRSTRLEN];
7155 char src_str[INET_ADDRSTRLEN];
7156 char state_str[PIM_MSDP_STATE_STRLEN];
7157 enum pim_msdp_peer_state state;
7158 json_object *json = NULL;
7159 json_object *json_mg_row = NULL;
7160 json_object *json_members = NULL;
7161 json_object *json_row = NULL;
7162
7163 if (!mg) {
7164 if (uj)
7165 print_empty_json_obj(vty);
7166 return;
7167 }
7168
7169 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
7170 if (uj) {
7171 json = json_object_new_object();
7172 /* currently there is only one mesh group but we should still
7173 * make
7174 * it a dict with mg-name as key */
7175 json_mg_row = json_object_new_object();
7176 json_object_string_add(json_mg_row, "name",
7177 mg->mesh_group_name);
7178 json_object_string_add(json_mg_row, "source", src_str);
7179 } else {
7180 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
7181 vty_out(vty, " Source : %s\n", src_str);
7182 vty_out(vty, " Member State\n");
7183 }
7184
7185 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
7186 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
7187 if (mbr->mp) {
7188 state = mbr->mp->state;
7189 } else {
7190 state = PIM_MSDP_DISABLED;
7191 }
7192 pim_msdp_state_dump(state, state_str, sizeof(state_str));
7193 if (uj) {
7194 json_row = json_object_new_object();
7195 json_object_string_add(json_row, "member", mbr_str);
7196 json_object_string_add(json_row, "state", state_str);
7197 if (!json_members) {
7198 json_members = json_object_new_object();
7199 json_object_object_add(json_mg_row, "members",
7200 json_members);
7201 }
7202 json_object_object_add(json_members, mbr_str, json_row);
7203 } else {
7204 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
7205 }
7206 }
7207
7208 if (uj) {
7209 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
9d303b37
DL
7210 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7211 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 7212 json_object_free(json);
7213 }
977d71cc 7214}
7215
7216DEFUN (show_ip_msdp_mesh_group,
7217 show_ip_msdp_mesh_group_cmd,
20a7e5fd 7218 "show ip msdp [vrf NAME] mesh-group [json]",
977d71cc 7219 SHOW_STR
7220 IP_STR
7221 MSDP_STR
f02d59db 7222 VRF_CMD_HELP_STR
977d71cc 7223 "MSDP mesh-group information\n"
7224 "JavaScript Object Notation\n")
7225{
d62a17ae 7226 u_char uj = use_json(argc, argv);
c68ba0d7 7227 int idx = 2;
02a16316
DS
7228 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
7229
7230 if (!vrf)
7231 return CMD_WARNING;
7232
64c86530 7233 ip_msdp_show_mesh_group(vrf->info, vty, uj);
d62a17ae 7234
7235 return CMD_SUCCESS;
7236}
7237
64c86530 7238static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
02a16316 7239 u_char uj)
d62a17ae 7240{
7241 struct listnode *mpnode;
7242 struct pim_msdp_peer *mp;
7243 char peer_str[INET_ADDRSTRLEN];
7244 char local_str[INET_ADDRSTRLEN];
7245 char state_str[PIM_MSDP_STATE_STRLEN];
7246 char timebuf[PIM_MSDP_UPTIME_STRLEN];
7247 int64_t now;
7248 json_object *json = NULL;
7249 json_object *json_row = NULL;
7250
7251
7252 if (uj) {
7253 json = json_object_new_object();
7254 } else {
7255 vty_out(vty,
7256 "Peer Local State Uptime SaCnt\n");
7257 }
7258
02a16316 7259 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 7260 if (mp->state == PIM_MSDP_ESTABLISHED) {
7261 now = pim_time_monotonic_sec();
7262 pim_time_uptime(timebuf, sizeof(timebuf),
7263 now - mp->uptime);
7264 } else {
7265 strcpy(timebuf, "-");
7266 }
7267 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
7268 pim_inet4_dump("<local?>", mp->local, local_str,
7269 sizeof(local_str));
7270 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
7271 if (uj) {
7272 json_row = json_object_new_object();
7273 json_object_string_add(json_row, "peer", peer_str);
7274 json_object_string_add(json_row, "local", local_str);
7275 json_object_string_add(json_row, "state", state_str);
7276 json_object_string_add(json_row, "upTime", timebuf);
7277 json_object_int_add(json_row, "saCount", mp->sa_cnt);
7278 json_object_object_add(json, peer_str, json_row);
7279 } else {
7280 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
7281 local_str, state_str, timebuf, mp->sa_cnt);
7282 }
7283 }
7284
7285 if (uj) {
9d303b37
DL
7286 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7287 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 7288 json_object_free(json);
7289 }
7290}
7291
64c86530 7292static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
02a16316 7293 const char *peer, u_char uj)
d62a17ae 7294{
7295 struct listnode *mpnode;
7296 struct pim_msdp_peer *mp;
7297 char peer_str[INET_ADDRSTRLEN];
7298 char local_str[INET_ADDRSTRLEN];
7299 char state_str[PIM_MSDP_STATE_STRLEN];
7300 char timebuf[PIM_MSDP_UPTIME_STRLEN];
7301 char katimer[PIM_MSDP_TIMER_STRLEN];
7302 char crtimer[PIM_MSDP_TIMER_STRLEN];
7303 char holdtimer[PIM_MSDP_TIMER_STRLEN];
7304 int64_t now;
7305 json_object *json = NULL;
7306 json_object *json_row = NULL;
7307
7308 if (uj) {
7309 json = json_object_new_object();
7310 }
7311
02a16316 7312 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
d62a17ae 7313 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
7314 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
7315 continue;
7316
7317 if (mp->state == PIM_MSDP_ESTABLISHED) {
7318 now = pim_time_monotonic_sec();
7319 pim_time_uptime(timebuf, sizeof(timebuf),
7320 now - mp->uptime);
7321 } else {
7322 strcpy(timebuf, "-");
7323 }
7324 pim_inet4_dump("<local?>", mp->local, local_str,
7325 sizeof(local_str));
7326 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
7327 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
7328 mp->ka_timer);
7329 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
7330 mp->cr_timer);
7331 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
7332 mp->hold_timer);
7333
7334 if (uj) {
7335 json_row = json_object_new_object();
7336 json_object_string_add(json_row, "peer", peer_str);
7337 json_object_string_add(json_row, "local", local_str);
7338 json_object_string_add(json_row, "meshGroupName",
7339 mp->mesh_group_name);
7340 json_object_string_add(json_row, "state", state_str);
7341 json_object_string_add(json_row, "upTime", timebuf);
7342 json_object_string_add(json_row, "keepAliveTimer",
7343 katimer);
7344 json_object_string_add(json_row, "connRetryTimer",
7345 crtimer);
7346 json_object_string_add(json_row, "holdTimer",
7347 holdtimer);
7348 json_object_string_add(json_row, "lastReset",
7349 mp->last_reset);
7350 json_object_int_add(json_row, "connAttempts",
7351 mp->conn_attempts);
7352 json_object_int_add(json_row, "establishedChanges",
7353 mp->est_flaps);
7354 json_object_int_add(json_row, "saCount", mp->sa_cnt);
7355 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
7356 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
7357 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
7358 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
7359 json_object_object_add(json, peer_str, json_row);
7360 } else {
7361 vty_out(vty, "Peer : %s\n", peer_str);
7362 vty_out(vty, " Local : %s\n", local_str);
7363 vty_out(vty, " Mesh Group : %s\n",
7364 mp->mesh_group_name);
7365 vty_out(vty, " State : %s\n", state_str);
7366 vty_out(vty, " Uptime : %s\n", timebuf);
7367
7368 vty_out(vty, " Keepalive Timer : %s\n", katimer);
7369 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
7370 vty_out(vty, " Hold Timer : %s\n", holdtimer);
7371 vty_out(vty, " Last Reset : %s\n",
7372 mp->last_reset);
7373 vty_out(vty, " Conn Attempts : %d\n",
7374 mp->conn_attempts);
7375 vty_out(vty, " Established Changes : %d\n",
7376 mp->est_flaps);
7377 vty_out(vty, " SA Count : %d\n",
7378 mp->sa_cnt);
7379 vty_out(vty, " Statistics :\n");
7380 vty_out(vty,
7381 " Sent Rcvd\n");
7382 vty_out(vty, " Keepalives : %10d %10d\n",
7383 mp->ka_tx_cnt, mp->ka_rx_cnt);
7384 vty_out(vty, " SAs : %10d %10d\n",
7385 mp->sa_tx_cnt, mp->sa_rx_cnt);
7386 vty_out(vty, "\n");
7387 }
7388 }
7389
7390 if (uj) {
9d303b37
DL
7391 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7392 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 7393 json_object_free(json);
7394 }
977d71cc 7395}
7396
7397DEFUN (show_ip_msdp_peer_detail,
7398 show_ip_msdp_peer_detail_cmd,
20a7e5fd 7399 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
2a333e0f 7400 SHOW_STR
7401 IP_STR
7402 MSDP_STR
f02d59db 7403 VRF_CMD_HELP_STR
2a333e0f 7404 "MSDP peer information\n"
977d71cc 7405 "Detailed output\n"
7406 "peer ip address\n"
2a333e0f 7407 "JavaScript Object Notation\n")
7408{
d62a17ae 7409 u_char uj = use_json(argc, argv);
c68ba0d7 7410 int idx = 2;
02a16316 7411 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
d62a17ae 7412 if (uj)
7413 argc--;
7414
200e2fe4
DS
7415 if (argv_find(argv, argc, "detail", &idx)
7416 || argv_find(argv, argc, "A.B.C.D", &idx))
64c86530 7417 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
d62a17ae 7418 else
64c86530 7419 ip_msdp_show_peers(vrf->info, vty, uj);
d62a17ae 7420
7421 return CMD_SUCCESS;
7422}
7423
64c86530 7424static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty,
02a16316 7425 u_char uj)
d62a17ae 7426{
7427 struct listnode *sanode;
7428 struct pim_msdp_sa *sa;
7429 char src_str[INET_ADDRSTRLEN];
7430 char grp_str[INET_ADDRSTRLEN];
7431 char rp_str[INET_ADDRSTRLEN];
7432 char timebuf[PIM_MSDP_UPTIME_STRLEN];
7433 char spt_str[8];
7434 char local_str[8];
7435 int64_t now;
7436 json_object *json = NULL;
7437 json_object *json_group = NULL;
7438 json_object *json_row = NULL;
7439
7440 if (uj) {
7441 json = json_object_new_object();
7442 } else {
7443 vty_out(vty,
7444 "Source Group RP Local SPT Uptime\n");
7445 }
7446
02a16316 7447 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 7448 now = pim_time_monotonic_sec();
7449 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
7450 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
7451 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
7452 if (sa->flags & PIM_MSDP_SAF_PEER) {
7453 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
7454 if (sa->up) {
7455 strcpy(spt_str, "yes");
7456 } else {
7457 strcpy(spt_str, "no");
7458 }
7459 } else {
7460 strcpy(rp_str, "-");
7461 strcpy(spt_str, "-");
7462 }
7463 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
7464 strcpy(local_str, "yes");
7465 } else {
7466 strcpy(local_str, "no");
7467 }
7468 if (uj) {
7469 json_object_object_get_ex(json, grp_str, &json_group);
7470
7471 if (!json_group) {
7472 json_group = json_object_new_object();
7473 json_object_object_add(json, grp_str,
7474 json_group);
7475 }
7476
7477 json_row = json_object_new_object();
7478 json_object_string_add(json_row, "source", src_str);
7479 json_object_string_add(json_row, "group", grp_str);
7480 json_object_string_add(json_row, "rp", rp_str);
7481 json_object_string_add(json_row, "local", local_str);
7482 json_object_string_add(json_row, "sptSetup", spt_str);
7483 json_object_string_add(json_row, "upTime", timebuf);
7484 json_object_object_add(json_group, src_str, json_row);
7485 } else {
7486 vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
7487 src_str, grp_str, rp_str, local_str[0],
7488 spt_str[0], timebuf);
7489 }
7490 }
7491
d62a17ae 7492 if (uj) {
9d303b37
DL
7493 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7494 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 7495 json_object_free(json);
7496 }
7497}
7498
7499static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
7500 const char *src_str,
7501 const char *grp_str, struct vty *vty,
7502 u_char uj, json_object *json)
7503{
7504 char rp_str[INET_ADDRSTRLEN];
7505 char peer_str[INET_ADDRSTRLEN];
7506 char timebuf[PIM_MSDP_UPTIME_STRLEN];
7507 char spt_str[8];
7508 char local_str[8];
7509 char statetimer[PIM_MSDP_TIMER_STRLEN];
7510 int64_t now;
7511 json_object *json_group = NULL;
7512 json_object *json_row = NULL;
7513
7514 now = pim_time_monotonic_sec();
7515 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
7516 if (sa->flags & PIM_MSDP_SAF_PEER) {
7517 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
7518 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
7519 if (sa->up) {
7520 strcpy(spt_str, "yes");
7521 } else {
7522 strcpy(spt_str, "no");
7523 }
7524 } else {
7525 strcpy(rp_str, "-");
7526 strcpy(peer_str, "-");
7527 strcpy(spt_str, "-");
7528 }
7529 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
7530 strcpy(local_str, "yes");
7531 } else {
7532 strcpy(local_str, "no");
7533 }
7534 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
7535 sa->sa_state_timer);
7536 if (uj) {
7537 json_object_object_get_ex(json, grp_str, &json_group);
7538
7539 if (!json_group) {
7540 json_group = json_object_new_object();
7541 json_object_object_add(json, grp_str, json_group);
7542 }
7543
7544 json_row = json_object_new_object();
7545 json_object_string_add(json_row, "source", src_str);
7546 json_object_string_add(json_row, "group", grp_str);
7547 json_object_string_add(json_row, "rp", rp_str);
7548 json_object_string_add(json_row, "local", local_str);
7549 json_object_string_add(json_row, "sptSetup", spt_str);
7550 json_object_string_add(json_row, "upTime", timebuf);
7551 json_object_string_add(json_row, "stateTimer", statetimer);
7552 json_object_object_add(json_group, src_str, json_row);
7553 } else {
7554 vty_out(vty, "SA : %s\n", sa->sg_str);
7555 vty_out(vty, " RP : %s\n", rp_str);
7556 vty_out(vty, " Peer : %s\n", peer_str);
7557 vty_out(vty, " Local : %s\n", local_str);
7558 vty_out(vty, " SPT Setup : %s\n", spt_str);
7559 vty_out(vty, " Uptime : %s\n", timebuf);
7560 vty_out(vty, " State Timer : %s\n", statetimer);
7561 vty_out(vty, "\n");
7562 }
7563}
7564
64c86530 7565static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
02a16316 7566 u_char uj)
d62a17ae 7567{
7568 struct listnode *sanode;
7569 struct pim_msdp_sa *sa;
7570 char src_str[INET_ADDRSTRLEN];
7571 char grp_str[INET_ADDRSTRLEN];
7572 json_object *json = NULL;
7573
7574 if (uj) {
7575 json = json_object_new_object();
7576 }
7577
02a16316 7578 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 7579 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
7580 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
7581 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
7582 json);
7583 }
7584
7585 if (uj) {
9d303b37
DL
7586 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7587 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 7588 json_object_free(json);
7589 }
977d71cc 7590}
7591
7592DEFUN (show_ip_msdp_sa_detail,
7593 show_ip_msdp_sa_detail_cmd,
20a7e5fd 7594 "show ip msdp [vrf NAME] sa detail [json]",
3c72d654 7595 SHOW_STR
7596 IP_STR
7597 MSDP_STR
f02d59db 7598 VRF_CMD_HELP_STR
3c72d654 7599 "MSDP active-source information\n"
977d71cc 7600 "Detailed output\n"
3c72d654 7601 "JavaScript Object Notation\n")
7602{
d62a17ae 7603 u_char uj = use_json(argc, argv);
c68ba0d7 7604 int idx = 2;
02a16316
DS
7605 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
7606
7607 if (!vrf)
7608 return CMD_WARNING;
7609
64c86530 7610 ip_msdp_show_sa_detail(vrf->info, vty, uj);
977d71cc 7611
d62a17ae 7612 return CMD_SUCCESS;
977d71cc 7613}
7614
64c86530 7615static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
02a16316 7616 const char *addr, u_char uj)
977d71cc 7617{
d62a17ae 7618 struct listnode *sanode;
7619 struct pim_msdp_sa *sa;
7620 char src_str[INET_ADDRSTRLEN];
7621 char grp_str[INET_ADDRSTRLEN];
7622 json_object *json = NULL;
977d71cc 7623
d62a17ae 7624 if (uj) {
7625 json = json_object_new_object();
7626 }
977d71cc 7627
02a16316 7628 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 7629 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
7630 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
7631 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
7632 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
7633 uj, json);
7634 }
7635 }
977d71cc 7636
d62a17ae 7637 if (uj) {
9d303b37
DL
7638 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7639 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 7640 json_object_free(json);
7641 }
977d71cc 7642}
7643
64c86530 7644static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
02a16316 7645 const char *src, const char *grp, u_char uj)
977d71cc 7646{
d62a17ae 7647 struct listnode *sanode;
7648 struct pim_msdp_sa *sa;
7649 char src_str[INET_ADDRSTRLEN];
7650 char grp_str[INET_ADDRSTRLEN];
7651 json_object *json = NULL;
977d71cc 7652
d62a17ae 7653 if (uj) {
7654 json = json_object_new_object();
7655 }
977d71cc 7656
02a16316 7657 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
d62a17ae 7658 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
7659 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
7660 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
7661 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
7662 uj, json);
7663 }
7664 }
977d71cc 7665
d62a17ae 7666 if (uj) {
9d303b37
DL
7667 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7668 json, JSON_C_TO_STRING_PRETTY));
d62a17ae 7669 json_object_free(json);
7670 }
977d71cc 7671}
7672
7673DEFUN (show_ip_msdp_sa_sg,
7674 show_ip_msdp_sa_sg_cmd,
20a7e5fd 7675 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
977d71cc 7676 SHOW_STR
7677 IP_STR
7678 MSDP_STR
f02d59db 7679 VRF_CMD_HELP_STR
977d71cc 7680 "MSDP active-source information\n"
7681 "source or group ip\n"
a957a05b 7682 "group ip\n"
977d71cc 7683 "JavaScript Object Notation\n")
7684{
d62a17ae 7685 u_char uj = use_json(argc, argv);
02a16316 7686 struct vrf *vrf;
c68ba0d7 7687 int idx = 2;
02a16316
DS
7688
7689 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
7690
7691 if (!vrf)
7692 return CMD_WARNING;
7693
d62a17ae 7694 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
7695 : NULL;
7696 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
7697 ? argv[idx]->arg
7698 : NULL;
9ea49d61 7699
d62a17ae 7700 if (src_ip && grp_ip)
64c86530 7701 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
d62a17ae 7702 else if (src_ip)
64c86530 7703 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
d62a17ae 7704 else
64c86530 7705 ip_msdp_show_sa(vrf->info, vty, uj);
3c72d654 7706
d62a17ae 7707 return CMD_SUCCESS;
3c72d654 7708}
7709
c68ba0d7 7710void pim_cmd_init(void)
12e41d03 7711{
d62a17ae 7712 install_node(&pim_global_node, pim_global_config_write); /* PIM_NODE */
7713 install_node(&interface_node,
7714 pim_interface_config_write); /* INTERFACE_NODE */
7715 if_cmd_init();
7716
7717 install_node(&debug_node, pim_debug_config_write);
7718
7719 install_element(CONFIG_NODE, &ip_multicast_routing_cmd);
7720 install_element(CONFIG_NODE, &no_ip_multicast_routing_cmd);
7721 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
9ecb7b77 7722 install_element(VRF_NODE, &ip_pim_rp_cmd);
d62a17ae 7723 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
9ecb7b77 7724 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
d62a17ae 7725 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
4f9f3925 7726 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
d62a17ae 7727 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
4f9f3925 7728 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
d62a17ae 7729 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
4f9f3925 7730 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
d62a17ae 7731 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
4f9f3925 7732 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
d62a17ae 7733 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
4f9f3925 7734 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
d62a17ae 7735 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
4f9f3925 7736 install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
d62a17ae 7737 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
4f9f3925 7738 install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
d62a17ae 7739 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
4f9f3925 7740 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
d62a17ae 7741 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 7742 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 7743 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
4f9f3925 7744 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
d62a17ae 7745 install_element(CONFIG_NODE,
7746 &no_ip_pim_spt_switchover_infinity_plist_cmd);
4f9f3925 7747 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
d62a17ae 7748 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
4f9f3925 7749 install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
d62a17ae 7750 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
4f9f3925 7751 install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
d62a17ae 7752 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
4f9f3925 7753 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
d62a17ae 7754 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
4f9f3925 7755 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
d62a17ae 7756 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
4f9f3925 7757 install_element(VRF_NODE, &ip_pim_packets_cmd);
d62a17ae 7758 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
4f9f3925 7759 install_element(VRF_NODE, &no_ip_pim_packets_cmd);
d62a17ae 7760 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
4f9f3925 7761 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
d62a17ae 7762 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
4f9f3925 7763 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
d62a17ae 7764 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
4f9f3925 7765 install_element(VRF_NODE, &ip_ssmpingd_cmd);
d62a17ae 7766 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
4f9f3925 7767 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
d62a17ae 7768 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
4f9f3925 7769 install_element(VRF_NODE, &ip_msdp_peer_cmd);
d62a17ae 7770 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
4f9f3925 7771 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
d62a17ae 7772 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
4f9f3925 7773 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
d62a17ae 7774 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
4f9f3925 7775 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
d62a17ae 7776 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
4f9f3925 7777 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
d62a17ae 7778 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
4f9f3925 7779 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
d62a17ae 7780
7781 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
7782 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
7783 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
7784 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
7785 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
7786 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
7787 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
7788 install_element(INTERFACE_NODE,
7789 &interface_no_ip_igmp_query_interval_cmd);
7790 install_element(INTERFACE_NODE,
7791 &interface_ip_igmp_query_max_response_time_cmd);
7792 install_element(INTERFACE_NODE,
7793 &interface_no_ip_igmp_query_max_response_time_cmd);
7794 install_element(INTERFACE_NODE,
7795 &interface_ip_igmp_query_max_response_time_dsec_cmd);
7796 install_element(INTERFACE_NODE,
7797 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
7798 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
7799 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
7800 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
7801 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
7802 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
7803 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
7804 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
7805 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
7806
7807 // Static mroutes NEB
7808 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
7809 install_element(INTERFACE_NODE, &interface_ip_mroute_source_cmd);
7810 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
7811 install_element(INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
7812
7813 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
7814 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
7815 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
7816 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
7817 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
7818 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
7819 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
7820 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
7821 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
7822 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
7823 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
7824 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
7825 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
7826 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
7827 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
7828 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
7829 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
7830 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
7831 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
7832 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
7833 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
7834 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
7835 install_element(VIEW_NODE, &show_ip_multicast_cmd);
7836 install_element(VIEW_NODE, &show_ip_mroute_cmd);
b283a4ca 7837 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
d62a17ae 7838 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
7839 install_element(VIEW_NODE, &show_ip_rib_cmd);
7840 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
7841 install_element(VIEW_NODE, &show_debugging_pim_cmd);
7842 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
7843 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
7844
7845 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
7846 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
7847 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
7848 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
7849 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
7850 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
7851
7852 install_element(ENABLE_NODE, &debug_igmp_cmd);
7853 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
7854 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
7855 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
7856 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
7857 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
7858 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
7859 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
7860 install_element(ENABLE_NODE, &debug_mroute_cmd);
7861 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
7862 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
7863 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
7864 install_element(ENABLE_NODE, &debug_static_cmd);
7865 install_element(ENABLE_NODE, &no_debug_static_cmd);
7866 install_element(ENABLE_NODE, &debug_pim_cmd);
7867 install_element(ENABLE_NODE, &no_debug_pim_cmd);
7868 install_element(ENABLE_NODE, &debug_pim_events_cmd);
7869 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
7870 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
7871 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
7872 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
7873 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
7874 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
7875 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
7876 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
7877 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
7878 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
7879 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 7880 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
7881 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
7882 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
7883 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
7884 install_element(ENABLE_NODE, &debug_msdp_cmd);
7885 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
7886 install_element(ENABLE_NODE, &undebug_msdp_cmd);
7887 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
7888 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
7889 install_element(ENABLE_NODE, &undebug_msdp_events_cmd);
7890 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
7891 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
7892 install_element(ENABLE_NODE, &undebug_msdp_packets_cmd);
7893
7894 install_element(CONFIG_NODE, &debug_igmp_cmd);
7895 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
7896 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
7897 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
7898 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
7899 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
7900 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
7901 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
7902 install_element(CONFIG_NODE, &debug_mroute_cmd);
7903 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
7904 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
7905 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
7906 install_element(CONFIG_NODE, &debug_static_cmd);
7907 install_element(CONFIG_NODE, &no_debug_static_cmd);
7908 install_element(CONFIG_NODE, &debug_pim_cmd);
7909 install_element(CONFIG_NODE, &no_debug_pim_cmd);
7910 install_element(CONFIG_NODE, &debug_pim_events_cmd);
7911 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
7912 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
7913 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
7914 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
7915 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
56c238c9
DS
7916 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
7917 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
d62a17ae 7918 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
7919 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
7920 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
7921 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
7922 install_element(CONFIG_NODE, &debug_msdp_cmd);
7923 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
7924 install_element(CONFIG_NODE, &undebug_msdp_cmd);
7925 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
7926 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
7927 install_element(CONFIG_NODE, &undebug_msdp_events_cmd);
7928 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
7929 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
7930 install_element(CONFIG_NODE, &undebug_msdp_packets_cmd);
02a16316 7931
d62a17ae 7932 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
02a16316 7933 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
d62a17ae 7934 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
1b973cb7 7935 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
d62a17ae 7936 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
02a16316 7937 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
d62a17ae 7938 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
02a16316 7939 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
d62a17ae 7940 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
7941 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
7942 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
7943 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
7944 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
7945 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
7946 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
7947 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
7948 /* Install BFD command */
7949 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
7950 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
7951 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
7952 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
12e41d03 7953}