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