]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
ripd: argv update
[mirror_frr.git] / pimd / pim_cmd.c
CommitLineData
12e41d03
DL
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 $QuaggaId: $Format:%an, %ai, %h$ $
21*/
22
12e41d03
DL
23#include <zebra.h>
24
25#include "command.h"
26#include "if.h"
27#include "prefix.h"
28#include "zclient.h"
29
30#include "pimd.h"
9867746a 31#include "pim_mroute.h"
12e41d03
DL
32#include "pim_cmd.h"
33#include "pim_iface.h"
34#include "pim_vty.h"
35#include "pim_mroute.h"
36#include "pim_str.h"
37#include "pim_igmp.h"
38#include "pim_igmpv3.h"
39#include "pim_sock.h"
40#include "pim_time.h"
41#include "pim_util.h"
42#include "pim_oil.h"
43#include "pim_neighbor.h"
44#include "pim_pim.h"
45#include "pim_ifchannel.h"
46#include "pim_hello.h"
47#include "pim_msg.h"
48#include "pim_upstream.h"
49#include "pim_rpf.h"
50#include "pim_macro.h"
51#include "pim_ssmpingd.h"
52#include "pim_zebra.h"
6250610a 53#include "pim_static.h"
a920d6e7 54#include "pim_rp.h"
12e41d03
DL
55
56static struct cmd_node pim_global_node = {
57 PIM_NODE,
58 "",
59 1 /* vtysh ? yes */
60};
61
62static struct cmd_node interface_node = {
63 INTERFACE_NODE,
64 "%s(config-if)# ",
65 1 /* vtysh ? yes */
66};
67
68static void pim_if_membership_clear(struct interface *ifp)
69{
70 struct pim_interface *pim_ifp;
71
72 pim_ifp = ifp->info;
73 zassert(pim_ifp);
74
75 if (PIM_IF_TEST_PIM(pim_ifp->options) &&
76 PIM_IF_TEST_IGMP(pim_ifp->options)) {
77 return;
78 }
79
80 pim_ifchannel_membership_clear(ifp);
81}
82
83/*
84 When PIM is disabled on interface, IGMPv3 local membership
85 information is not injected into PIM interface state.
86
87 The function pim_if_membership_refresh() fetches all IGMPv3 local
88 membership information into PIM. It is intented to be called
89 whenever PIM is enabled on the interface in order to collect missed
90 local membership information.
91 */
92static void pim_if_membership_refresh(struct interface *ifp)
93{
94 struct pim_interface *pim_ifp;
95 struct listnode *sock_node;
96 struct igmp_sock *igmp;
97
98 pim_ifp = ifp->info;
99 zassert(pim_ifp);
100
101 if (!PIM_IF_TEST_PIM(pim_ifp->options))
102 return;
103 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
104 return;
105
106 /*
107 First clear off membership from all PIM (S,G) entries on the
108 interface
109 */
110
111 pim_ifchannel_membership_clear(ifp);
112
113 /*
114 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
115 the interface
116 */
117
118 /* scan igmp sockets */
119 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
120 struct listnode *grpnode;
121 struct igmp_group *grp;
122
123 /* scan igmp groups */
124 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
125 struct listnode *srcnode;
126 struct igmp_source *src;
127
128 /* scan group sources */
129 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
130
131 if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
132 pim_ifchannel_local_membership_add(ifp,
133 src->source_addr,
134 grp->group_addr);
135 }
136
137 } /* scan group sources */
138 } /* scan igmp groups */
139 } /* scan igmp sockets */
140
141 /*
142 Finally delete every PIM (S,G) entry lacking all state info
143 */
144
145 pim_ifchannel_delete_on_noinfo(ifp);
146
147}
148
149static void pim_show_assert(struct vty *vty)
150{
151 struct listnode *ifnode;
152 struct interface *ifp;
153 time_t now;
154
155 now = pim_time_monotonic_sec();
156
157 vty_out(vty,
158 "Interface Address Source Group State Winner Uptime Timer%s",
159 VTY_NEWLINE);
160
469351b3 161 for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
162 struct pim_interface *pim_ifp;
163 struct in_addr ifaddr;
164 struct listnode *ch_node;
165 struct pim_ifchannel *ch;
166
167 pim_ifp = ifp->info;
168
169 if (!pim_ifp)
170 continue;
171
172 ifaddr = pim_ifp->primary_address;
173
174 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
175 char ch_src_str[100];
176 char ch_grp_str[100];
177 char winner_str[100];
178 char uptime[10];
179 char timer[10];
180
181 pim_inet4_dump("<ch_src?>", ch->source_addr,
182 ch_src_str, sizeof(ch_src_str));
183 pim_inet4_dump("<ch_grp?>", ch->group_addr,
184 ch_grp_str, sizeof(ch_grp_str));
185 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
186 winner_str, sizeof(winner_str));
187
188 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
189 pim_time_timer_to_mmss(timer, sizeof(timer),
190 ch->t_ifassert_timer);
191
192 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
193 ifp->name,
194 inet_ntoa(ifaddr),
195 ch_src_str,
196 ch_grp_str,
197 pim_ifchannel_ifassert_name(ch->ifassert_state),
198 winner_str,
199 uptime,
200 timer,
201 VTY_NEWLINE);
202 } /* scan interface channels */
203 } /* scan interfaces */
204}
205
206static void pim_show_assert_internal(struct vty *vty)
207{
208 struct listnode *ifnode;
209 struct interface *ifp;
210
211 vty_out(vty,
212 "CA: CouldAssert%s"
213 "ECA: Evaluate CouldAssert%s"
214 "ATD: AssertTrackingDesired%s"
215 "eATD: Evaluate AssertTrackingDesired%s%s",
216 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
217
218 vty_out(vty,
219 "Interface Address Source Group CA eCA ATD eATD%s",
220 VTY_NEWLINE);
221
469351b3 222 for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
223 struct pim_interface *pim_ifp;
224 struct in_addr ifaddr;
225 struct listnode *ch_node;
226 struct pim_ifchannel *ch;
227
228 pim_ifp = ifp->info;
229
230 if (!pim_ifp)
231 continue;
232
233 ifaddr = pim_ifp->primary_address;
234
235 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
236 char ch_src_str[100];
237 char ch_grp_str[100];
238
239 pim_inet4_dump("<ch_src?>", ch->source_addr,
240 ch_src_str, sizeof(ch_src_str));
241 pim_inet4_dump("<ch_grp?>", ch->group_addr,
242 ch_grp_str, sizeof(ch_grp_str));
243 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
244 ifp->name,
245 inet_ntoa(ifaddr),
246 ch_src_str,
247 ch_grp_str,
248 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
249 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
250 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
251 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
252 VTY_NEWLINE);
253 } /* scan interface channels */
254 } /* scan interfaces */
255}
256
257static void pim_show_assert_metric(struct vty *vty)
258{
259 struct listnode *ifnode;
260 struct interface *ifp;
261
262 vty_out(vty,
263 "Interface Address Source Group RPT Pref Metric Address %s",
264 VTY_NEWLINE);
265
469351b3 266 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
267 struct pim_interface *pim_ifp;
268 struct in_addr ifaddr;
269 struct listnode *ch_node;
270 struct pim_ifchannel *ch;
271
272 pim_ifp = ifp->info;
273
274 if (!pim_ifp)
275 continue;
276
277 ifaddr = pim_ifp->primary_address;
278
279 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
280 char ch_src_str[100];
281 char ch_grp_str[100];
282 char addr_str[100];
283 struct pim_assert_metric am;
284
285 am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
286
287 pim_inet4_dump("<ch_src?>", ch->source_addr,
288 ch_src_str, sizeof(ch_src_str));
289 pim_inet4_dump("<ch_grp?>", ch->group_addr,
290 ch_grp_str, sizeof(ch_grp_str));
291 pim_inet4_dump("<addr?>", am.ip_address,
292 addr_str, sizeof(addr_str));
293
294 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
295 ifp->name,
296 inet_ntoa(ifaddr),
297 ch_src_str,
298 ch_grp_str,
299 am.rpt_bit_flag ? "yes" : "no",
300 am.metric_preference,
301 am.route_metric,
302 addr_str,
303 VTY_NEWLINE);
304 } /* scan interface channels */
305 } /* scan interfaces */
306}
307
308static void pim_show_assert_winner_metric(struct vty *vty)
309{
310 struct listnode *ifnode;
311 struct interface *ifp;
312
313 vty_out(vty,
314 "Interface Address Source Group RPT Pref Metric Address %s",
315 VTY_NEWLINE);
316
469351b3 317 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
318 struct pim_interface *pim_ifp;
319 struct in_addr ifaddr;
320 struct listnode *ch_node;
321 struct pim_ifchannel *ch;
322
323 pim_ifp = ifp->info;
324
325 if (!pim_ifp)
326 continue;
327
328 ifaddr = pim_ifp->primary_address;
329
330 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
331 char ch_src_str[100];
332 char ch_grp_str[100];
333 char addr_str[100];
334 struct pim_assert_metric *am;
335 char pref_str[5];
336 char metr_str[7];
337
338 am = &ch->ifassert_winner_metric;
339
340 pim_inet4_dump("<ch_src?>", ch->source_addr,
341 ch_src_str, sizeof(ch_src_str));
342 pim_inet4_dump("<ch_grp?>", ch->group_addr,
343 ch_grp_str, sizeof(ch_grp_str));
344 pim_inet4_dump("<addr?>", am->ip_address,
345 addr_str, sizeof(addr_str));
346
347 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
348 snprintf(pref_str, sizeof(pref_str), "INFI");
349 else
350 snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
351
352 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
353 snprintf(metr_str, sizeof(metr_str), "INFI");
354 else
355 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
356
357 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
358 ifp->name,
359 inet_ntoa(ifaddr),
360 ch_src_str,
361 ch_grp_str,
362 am->rpt_bit_flag ? "yes" : "no",
363 pref_str,
364 metr_str,
365 addr_str,
366 VTY_NEWLINE);
367 } /* scan interface channels */
368 } /* scan interfaces */
369}
370
371static void pim_show_membership(struct vty *vty)
372{
373 struct listnode *ifnode;
374 struct interface *ifp;
375
376 vty_out(vty,
377 "Interface Address Source Group Membership%s",
378 VTY_NEWLINE);
379
469351b3 380 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
381 struct pim_interface *pim_ifp;
382 struct in_addr ifaddr;
383 struct listnode *ch_node;
384 struct pim_ifchannel *ch;
385
386 pim_ifp = ifp->info;
387
388 if (!pim_ifp)
389 continue;
390
391 ifaddr = pim_ifp->primary_address;
392
393 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
394 char ch_src_str[100];
395 char ch_grp_str[100];
396
397 pim_inet4_dump("<ch_src?>", ch->source_addr,
398 ch_src_str, sizeof(ch_src_str));
399 pim_inet4_dump("<ch_grp?>", ch->group_addr,
400 ch_grp_str, sizeof(ch_grp_str));
401
402 vty_out(vty, "%-9s %-15s %-15s %-15s %-10s%s",
403 ifp->name,
404 inet_ntoa(ifaddr),
405 ch_src_str,
406 ch_grp_str,
407 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?
408 "NOINFO" : "INCLUDE",
409 VTY_NEWLINE);
410 } /* scan interface channels */
411 } /* scan interfaces */
412
413}
414
415static void igmp_show_interfaces(struct vty *vty)
416{
417 struct listnode *node;
418 struct interface *ifp;
419 time_t now;
420
421 now = pim_time_monotonic_sec();
422
423 vty_out(vty,
424 "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s",
425 VTY_NEWLINE);
426
469351b3 427 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
428 struct pim_interface *pim_ifp;
429 struct listnode *sock_node;
430 struct igmp_sock *igmp;
431
432 pim_ifp = ifp->info;
433
434 if (!pim_ifp)
435 continue;
436
437 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
438 char uptime[10];
439 int mloop;
440
441 pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
442
443 mloop = pim_socket_mcastloop_get(igmp->fd);
444
445 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
446 ifp->name,
447 inet_ntoa(igmp->ifaddr),
448 ifp->ifindex,
449 igmp->fd,
450 uptime,
451 if_is_multicast(ifp) ? "yes" : "no",
452 if_is_broadcast(ifp) ? "yes" : "no",
453 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
454 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
455 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
456 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
457 VTY_NEWLINE);
458 }
459 }
460}
461
462static void igmp_show_interface_join(struct vty *vty)
463{
464 struct listnode *node;
465 struct interface *ifp;
466 time_t now;
467
468 now = pim_time_monotonic_sec();
469
470 vty_out(vty,
471 "Interface Address Source Group Socket Uptime %s",
472 VTY_NEWLINE);
473
469351b3 474 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
475 struct pim_interface *pim_ifp;
476 struct listnode *join_node;
477 struct igmp_join *ij;
478 struct in_addr pri_addr;
479 char pri_addr_str[100];
480
481 pim_ifp = ifp->info;
482
483 if (!pim_ifp)
484 continue;
485
486 if (!pim_ifp->igmp_join_list)
487 continue;
488
489 pri_addr = pim_find_primary_addr(ifp);
490 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
491
492 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node, ij)) {
493 char group_str[100];
494 char source_str[100];
495 char uptime[10];
496
497 pim_time_uptime(uptime, sizeof(uptime), now - ij->sock_creation);
498 pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
499 pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
500
501 vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s%s",
502 ifp->name,
503 pri_addr_str,
504 source_str,
505 group_str,
506 ij->sock_fd,
507 uptime,
508 VTY_NEWLINE);
509 } /* for (pim_ifp->igmp_join_list) */
510
511 } /* for (iflist) */
512
513}
514
515static void show_interface_address(struct vty *vty)
516{
517 struct listnode *ifpnode;
518 struct interface *ifp;
519
520 vty_out(vty,
521 "Interface Primary Secondary %s",
522 VTY_NEWLINE);
523
469351b3 524 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifpnode, ifp)) {
12e41d03
DL
525 struct listnode *ifcnode;
526 struct connected *ifc;
527 struct in_addr pri_addr;
528 char pri_addr_str[100];
529
530 pri_addr = pim_find_primary_addr(ifp);
531
532 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
533
534 for (ALL_LIST_ELEMENTS_RO(ifp->connected, ifcnode, ifc)) {
535 char sec_addr_str[100];
536 struct prefix *p = ifc->address;
537
538 if (p->family != AF_INET)
539 continue;
540
541 if (p->u.prefix4.s_addr == pri_addr.s_addr) {
542 sec_addr_str[0] = '\0';
543 }
544 else {
545 pim_inet4_dump("<sec?>", p->u.prefix4, sec_addr_str, sizeof(sec_addr_str));
546 }
547
548 vty_out(vty, "%-9s %-15s %-15s%s",
549 ifp->name,
550 pri_addr_str,
551 sec_addr_str,
552 VTY_NEWLINE);
553 }
554 }
555}
556
557static void pim_show_dr(struct vty *vty)
558{
559 struct listnode *node;
560 struct interface *ifp;
561 time_t now;
562
563 now = pim_time_monotonic_sec();
564
565 vty_out(vty,
dedccda6
DS
566 "NonPri: Number of neighbors missing DR Priority hello option%s"
567 "DrPri: Designated Router Priority sent%s%s",
568 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
12e41d03 569
dedccda6 570 vty_out(vty, "Interface Address DR Uptime Elections Changes NonPri DrPri%s", VTY_NEWLINE);
12e41d03 571
469351b3 572 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
573 struct pim_interface *pim_ifp;
574 struct in_addr ifaddr;
575 char dr_str[100];
576 char dr_uptime[10];
577
578 pim_ifp = ifp->info;
579
580 if (!pim_ifp)
581 continue;
582
583 if (pim_ifp->pim_sock_fd < 0)
584 continue;
585
586 ifaddr = pim_ifp->primary_address;
587
588 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime),
589 now, pim_ifp->pim_dr_election_last);
590
591 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr,
592 dr_str, sizeof(dr_str));
593
dedccda6 594 vty_out(vty, "%-9s %-15s %-15s %8s %9d %7d %6d %10d%s",
12e41d03
DL
595 ifp->name,
596 inet_ntoa(ifaddr),
597 dr_str,
598 dr_uptime,
599 pim_ifp->pim_dr_election_count,
600 pim_ifp->pim_dr_election_changes,
601 pim_ifp->pim_dr_num_nondrpri_neighbors,
dedccda6 602 pim_ifp->pim_dr_priority,
12e41d03
DL
603 VTY_NEWLINE);
604 }
605}
606
607static void pim_show_hello(struct vty *vty)
608{
609 struct listnode *node;
610 struct interface *ifp;
611 time_t now;
612
613 now = pim_time_monotonic_sec();
614
615 vty_out(vty, "Interface Address Period Timer StatStart Recv Rfail Send Sfail%s", VTY_NEWLINE);
616
469351b3 617 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
618 struct pim_interface *pim_ifp;
619 struct in_addr ifaddr;
620 char hello_period[10];
621 char hello_timer[10];
622 char stat_uptime[10];
623
624 pim_ifp = ifp->info;
625
626 if (!pim_ifp)
627 continue;
628
629 if (pim_ifp->pim_sock_fd < 0)
630 continue;
631
632 ifaddr = pim_ifp->primary_address;
633
634 pim_time_timer_to_mmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
635 pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
636 pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
637
638 vty_out(vty, "%-9s %-15s %6s %5s %9s %4u %5u %4u %5u%s",
639 ifp->name,
640 inet_ntoa(ifaddr),
641 hello_period,
642 hello_timer,
643 stat_uptime,
644 pim_ifp->pim_ifstat_hello_recv,
645 pim_ifp->pim_ifstat_hello_recvfail,
646 pim_ifp->pim_ifstat_hello_sent,
647 pim_ifp->pim_ifstat_hello_sendfail,
648 VTY_NEWLINE);
649 }
650}
651
652static void pim_show_interfaces(struct vty *vty)
653{
654 struct listnode *node;
655 struct interface *ifp;
656 time_t now;
657
658 now = pim_time_monotonic_sec();
659
660 vty_out(vty, "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s", VTY_NEWLINE);
661
469351b3 662 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
663 struct pim_interface *pim_ifp;
664 struct in_addr ifaddr;
665 char uptime[10];
666 int mloop;
667
668 pim_ifp = ifp->info;
669
670 if (!pim_ifp)
671 continue;
672
673 if (pim_ifp->pim_sock_fd < 0)
674 continue;
675
676 ifaddr = pim_ifp->primary_address;
677
678 pim_time_uptime(uptime, sizeof(uptime), now - pim_ifp->pim_sock_creation);
679
680 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
681
682 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
683 ifp->name,
684 inet_ntoa(ifaddr),
685 ifp->ifindex,
686 pim_ifp->pim_sock_fd,
687 uptime,
688 if_is_multicast(ifp) ? "yes" : "no",
689 if_is_broadcast(ifp) ? "yes" : "no",
690 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
691 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
692 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
693 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
694 VTY_NEWLINE);
695 }
696}
697
698static void pim_show_join(struct vty *vty)
699{
700 struct listnode *ifnode;
701 struct interface *ifp;
702 time_t now;
703
704 now = pim_time_monotonic_sec();
705
706 vty_out(vty,
707 "Interface Address Source Group State Uptime Expire Prune%s",
708 VTY_NEWLINE);
709
469351b3 710 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
711 struct pim_interface *pim_ifp;
712 struct in_addr ifaddr;
713 struct listnode *ch_node;
714 struct pim_ifchannel *ch;
715
716 pim_ifp = ifp->info;
717
718 if (!pim_ifp)
719 continue;
720
721 ifaddr = pim_ifp->primary_address;
722
723 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
724 char ch_src_str[100];
725 char ch_grp_str[100];
726 char uptime[10];
727 char expire[10];
728 char prune[10];
729
730 pim_inet4_dump("<ch_src?>", ch->source_addr,
731 ch_src_str, sizeof(ch_src_str));
732 pim_inet4_dump("<ch_grp?>", ch->group_addr,
733 ch_grp_str, sizeof(ch_grp_str));
734
735 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
736 pim_time_timer_to_mmss(expire, sizeof(expire),
737 ch->t_ifjoin_expiry_timer);
738 pim_time_timer_to_mmss(prune, sizeof(prune),
739 ch->t_ifjoin_prune_pending_timer);
740
741 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
742 ifp->name,
743 inet_ntoa(ifaddr),
744 ch_src_str,
745 ch_grp_str,
746 pim_ifchannel_ifjoin_name(ch->ifjoin_state),
747 uptime,
748 expire,
749 prune,
750 VTY_NEWLINE);
751 } /* scan interface channels */
752 } /* scan interfaces */
753
754}
755
756static void pim_show_neighbors(struct vty *vty)
757{
758 struct listnode *node;
759 struct interface *ifp;
760 time_t now;
761
762 now = pim_time_monotonic_sec();
763
764 vty_out(vty,
765 "Recv flags: H=holdtime L=lan_prune_delay P=dr_priority G=generation_id A=address_list%s"
766 " T=can_disable_join_suppression%s%s",
767 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
768
769 vty_out(vty, "Interface Address Neighbor Uptime Timer Holdt DrPri GenId Recv %s", VTY_NEWLINE);
770
469351b3 771 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
772 struct pim_interface *pim_ifp;
773 struct in_addr ifaddr;
774 struct listnode *neighnode;
775 struct pim_neighbor *neigh;
776
777 pim_ifp = ifp->info;
778
779 if (!pim_ifp)
780 continue;
781
782 if (pim_ifp->pim_sock_fd < 0)
783 continue;
784
785 ifaddr = pim_ifp->primary_address;
786
787 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
788 char uptime[10];
789 char holdtime[10];
790 char expire[10];
791 char neigh_src_str[100];
792 char recv[7];
793
794 pim_inet4_dump("<src?>", neigh->source_addr,
795 neigh_src_str, sizeof(neigh_src_str));
796 pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
797 pim_time_mmss(holdtime, sizeof(holdtime), neigh->holdtime);
798 pim_time_timer_to_mmss(expire, sizeof(expire), neigh->t_expire_timer);
799
800 recv[0] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME) ? 'H' : ' ';
801 recv[1] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? 'L' : ' ';
802 recv[2] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY) ? 'P' : ' ';
803 recv[3] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ? 'G' : ' ';
804 recv[4] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST) ? 'A' : ' ';
805 recv[5] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION) ? 'T' : ' ';
806 recv[6] = '\0';
807
808 vty_out(vty, "%-9s %-15s %-15s %8s %5s %5s %5u %08x %6s%s",
809 ifp->name,
810 inet_ntoa(ifaddr),
811 neigh_src_str,
812 uptime,
813 expire,
814 holdtime,
815 neigh->dr_priority,
816 neigh->generation_id,
817 recv,
818 VTY_NEWLINE);
819 }
820
821
822 }
823}
824
825static void pim_show_lan_prune_delay(struct vty *vty)
826{
827 struct listnode *node;
828 struct interface *ifp;
829
830 vty_out(vty,
831 "PrDly=propagation_delay (msec) OvInt=override_interval (msec)%s"
832 "HiDly=highest_propagation_delay (msec) HiInt=highest_override_interval (msec)%s"
833 "NoDly=number_of_non_lan_delay_neighbors%s"
834 "T=t_bit LPD=lan_prune_delay_hello_option%s%s",
835 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
836
837 vty_out(vty, "Interface Address PrDly OvInt NoDly HiDly HiInt T | Neighbor LPD PrDly OvInt T%s", VTY_NEWLINE);
838
469351b3 839 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
840 struct pim_interface *pim_ifp;
841 struct in_addr ifaddr;
842 struct listnode *neighnode;
843 struct pim_neighbor *neigh;
844
845 pim_ifp = ifp->info;
846
847 if (!pim_ifp)
848 continue;
849
850 if (pim_ifp->pim_sock_fd < 0)
851 continue;
852
853 ifaddr = pim_ifp->primary_address;
854
855 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
856 char neigh_src_str[100];
857
858 pim_inet4_dump("<src?>", neigh->source_addr,
859 neigh_src_str, sizeof(neigh_src_str));
860
861 vty_out(vty, "%-9s %-15s %5u %5u %5u %5u %5u %1u | %-15s %-3s %5u %5u %1u%s",
862 ifp->name,
863 inet_ntoa(ifaddr),
864 pim_ifp->pim_propagation_delay_msec,
865 pim_ifp->pim_override_interval_msec,
866 pim_ifp->pim_number_of_nonlandelay_neighbors,
867 pim_ifp->pim_neighbors_highest_propagation_delay_msec,
868 pim_ifp->pim_neighbors_highest_override_interval_msec,
869 PIM_FORCE_BOOLEAN(PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options)),
870 neigh_src_str,
871 PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? "yes" : "no",
872 neigh->propagation_delay_msec,
873 neigh->override_interval_msec,
874 PIM_FORCE_BOOLEAN(PIM_OPTION_IS_SET(neigh->hello_options,
875 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION)),
876 VTY_NEWLINE);
877 }
878
879 }
880}
881
882static void pim_show_jp_override_interval(struct vty *vty)
883{
884 struct listnode *node;
885 struct interface *ifp;
886
887 vty_out(vty,
888 "EffPDelay=effective_propagation_delay (msec)%s"
889 "EffOvrInt=override_interval (msec)%s"
890 "JPOvrInt=jp_override_interval (msec)%s%s",
891 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
892
893 vty_out(vty, "Interface Address LAN_Delay EffPDelay EffOvrInt JPOvrInt%s", VTY_NEWLINE);
894
469351b3 895 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
896 struct pim_interface *pim_ifp;
897 struct in_addr ifaddr;
898
899 pim_ifp = ifp->info;
900
901 if (!pim_ifp)
902 continue;
903
904 if (pim_ifp->pim_sock_fd < 0)
905 continue;
906
907 ifaddr = pim_ifp->primary_address;
908
909 vty_out(vty, "%-9s %-15s %-9s %9u %9u %8u%s",
910 ifp->name,
911 inet_ntoa(ifaddr),
912 pim_if_lan_delay_enabled(ifp) ? "enabled" : "disabled",
913 pim_if_effective_propagation_delay_msec(ifp),
914 pim_if_effective_override_interval_msec(ifp),
915 pim_if_jp_override_interval_msec(ifp),
916 VTY_NEWLINE);
917 }
918}
919
920static void pim_show_neighbors_secondary(struct vty *vty)
921{
922 struct listnode *node;
923 struct interface *ifp;
924
925 vty_out(vty, "Interface Address Neighbor Secondary %s", VTY_NEWLINE);
926
469351b3 927 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
928 struct pim_interface *pim_ifp;
929 struct in_addr ifaddr;
930 struct listnode *neighnode;
931 struct pim_neighbor *neigh;
932
933 pim_ifp = ifp->info;
934
935 if (!pim_ifp)
936 continue;
937
938 if (pim_ifp->pim_sock_fd < 0)
939 continue;
940
941 ifaddr = pim_ifp->primary_address;
942
943 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
944 char neigh_src_str[100];
945 struct listnode *prefix_node;
946 struct prefix *p;
947
948 if (!neigh->prefix_list)
949 continue;
950
951 pim_inet4_dump("<src?>", neigh->source_addr,
952 neigh_src_str, sizeof(neigh_src_str));
953
954 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
955 char neigh_sec_str[100];
956
957 if (p->family != AF_INET)
958 continue;
959
960 pim_inet4_dump("<src?>", p->u.prefix4,
961 neigh_sec_str, sizeof(neigh_sec_str));
962
963 vty_out(vty, "%-9s %-15s %-15s %-15s%s",
964 ifp->name,
965 inet_ntoa(ifaddr),
966 neigh_src_str,
967 neigh_sec_str,
968 VTY_NEWLINE);
969 }
970 }
971 }
972}
973
974static void pim_show_upstream(struct vty *vty)
975{
976 struct listnode *upnode;
977 struct pim_upstream *up;
978 time_t now;
979
980 now = pim_time_monotonic_sec();
981
2e948c78 982 vty_out(vty, "Iif Source Group State Uptime JoinTimer RefCnt%s", VTY_NEWLINE);
12e41d03
DL
983
984 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
985 char src_str[100];
986 char grp_str[100];
987 char uptime[10];
988 char join_timer[10];
989
990 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
991 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
992 pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
993 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer), up->t_join_timer);
994
2e948c78
DS
995 vty_out(vty, "%-10s%-15s %-15s %-5s %-8s %-9s %6d%s",
996 up->rpf.source_nexthop.interface->name,
12e41d03
DL
997 src_str,
998 grp_str,
999 up->join_state == PIM_UPSTREAM_JOINED ? "Jnd" : "NtJnd",
1000 uptime,
1001 join_timer,
1002 up->ref_count,
1003 VTY_NEWLINE);
1004 }
1005}
1006
1007static void pim_show_join_desired(struct vty *vty)
1008{
1009 struct listnode *ifnode;
1010 struct listnode *chnode;
1011 struct interface *ifp;
1012 struct pim_interface *pim_ifp;
1013 struct pim_ifchannel *ch;
1014 char src_str[100];
1015 char grp_str[100];
1016
1017 vty_out(vty,
1018 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1019 VTY_NEWLINE);
1020
1021 /* scan all interfaces */
469351b3 1022 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1023 pim_ifp = ifp->info;
1024 if (!pim_ifp)
1025 continue;
1026
1027 /* scan per-interface (S,G) state */
1028 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
1029 struct pim_upstream *up = ch->upstream;
1030
1031 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1032 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1033
1034 vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1035 ifp->name,
1036 src_str,
1037 grp_str,
1038 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
1039 pim_macro_chisin_joins(ch) ? "yes" : "no",
1040 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
1041 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
1042 pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
1043 VTY_NEWLINE);
1044 }
1045 }
1046}
1047
1048static void pim_show_upstream_rpf(struct vty *vty)
1049{
1050 struct listnode *upnode;
1051 struct pim_upstream *up;
1052
1053 vty_out(vty,
1054 "Source Group RpfIface RibNextHop RpfAddress %s",
1055 VTY_NEWLINE);
1056
1057 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
1058 char src_str[100];
1059 char grp_str[100];
1060 char rpf_nexthop_str[100];
1061 char rpf_addr_str[100];
1062 struct pim_rpf *rpf;
1063 const char *rpf_ifname;
1064
1065 rpf = &up->rpf;
1066
1067 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1068 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1069 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
1070 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1071
1072 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1073
1074 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
1075 src_str,
1076 grp_str,
1077 rpf_ifname,
1078 rpf_nexthop_str,
1079 rpf_addr_str,
1080 VTY_NEWLINE);
1081 }
1082}
1083
1084static void show_rpf_refresh_stats(struct vty *vty, time_t now)
1085{
1086 char refresh_uptime[10];
1087
1088 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
1089
1090 vty_out(vty,
1091 "RPF Cache Refresh Delay: %ld msecs%s"
1092 "RPF Cache Refresh Timer: %ld msecs%s"
1093 "RPF Cache Refresh Requests: %lld%s"
1094 "RPF Cache Refresh Events: %lld%s"
1095 "RPF Cache Refresh Last: %s%s",
1096 qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
1097 pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
1098 (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
1099 (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
1100 refresh_uptime, VTY_NEWLINE);
1101}
1102
1103static void show_scan_oil_stats(struct vty *vty, time_t now)
1104{
1105 char uptime_scan_oil[10];
1106 char uptime_mroute_add[10];
1107 char uptime_mroute_del[10];
1108
1109 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
1110 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
1111 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
1112
1113 vty_out(vty,
1114 "Scan OIL - Last: %s Events: %lld%s"
1115 "MFC Add - Last: %s Events: %lld%s"
1116 "MFC Del - Last: %s Events: %lld%s",
1117 uptime_scan_oil, (long long) qpim_scan_oil_events, VTY_NEWLINE,
1118 uptime_mroute_add, (long long) qpim_mroute_add_events, VTY_NEWLINE,
1119 uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
1120}
1121
1122static void pim_show_rpf(struct vty *vty)
1123{
1124 struct listnode *up_node;
1125 struct pim_upstream *up;
1126 time_t now = pim_time_monotonic_sec();
1127
1128 show_rpf_refresh_stats(vty, now);
1129
1130 vty_out(vty, "%s", VTY_NEWLINE);
1131
1132 vty_out(vty,
1133 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1134 VTY_NEWLINE);
1135
1136 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
1137 char src_str[100];
1138 char grp_str[100];
1139 char rpf_addr_str[100];
1140 char rib_nexthop_str[100];
1141 const char *rpf_ifname;
1142 struct pim_rpf *rpf = &up->rpf;
1143
1144 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1145 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1146 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1147 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
1148
1149 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1150
1151 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1152 src_str,
1153 grp_str,
1154 rpf_ifname,
1155 rpf_addr_str,
1156 rib_nexthop_str,
1157 rpf->source_nexthop.mrib_route_metric,
1158 rpf->source_nexthop.mrib_metric_preference,
1159 VTY_NEWLINE);
1160 }
1161}
1162
1163static void igmp_show_querier(struct vty *vty)
1164{
1165 struct listnode *node;
1166 struct interface *ifp;
1167
1168 vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
1169
469351b3 1170 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
1171 struct pim_interface *pim_ifp = ifp->info;
1172 struct listnode *sock_node;
1173 struct igmp_sock *igmp;
1174
1175 if (!pim_ifp)
1176 continue;
1177
1178 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1179 char query_hhmmss[10];
1180 char other_hhmmss[10];
1181
1182 pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
1183 pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
1184
1185 vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
1186 ifp->name,
1187 inet_ntoa(igmp->ifaddr),
1188 igmp->t_igmp_query_timer ? "THIS" : "OTHER",
1189 igmp->startup_query_count,
1190 query_hhmmss,
1191 other_hhmmss,
1192 VTY_NEWLINE);
1193 }
1194 }
1195}
1196
1197static void igmp_show_groups(struct vty *vty)
1198{
1199 struct listnode *ifnode;
1200 struct interface *ifp;
1201 time_t now;
1202
1203 now = pim_time_monotonic_sec();
1204
1205 vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
1206
1207 /* scan interfaces */
469351b3 1208 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1209 struct pim_interface *pim_ifp = ifp->info;
1210 struct listnode *sock_node;
1211 struct igmp_sock *igmp;
1212
1213 if (!pim_ifp)
1214 continue;
1215
1216 /* scan igmp sockets */
1217 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1218 char ifaddr_str[100];
1219 struct listnode *grpnode;
1220 struct igmp_group *grp;
1221
1222 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1223
1224 /* scan igmp groups */
1225 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1226 char group_str[100];
1227 char hhmmss[10];
1228 char uptime[10];
1229
1230 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1231 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
1232 pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
1233
1234 vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
1235 ifp->name,
1236 ifaddr_str,
1237 group_str,
1238 grp->group_filtermode_isexcl ? "EXCL" : "INCL",
1239 hhmmss,
1240 grp->group_source_list ? listcount(grp->group_source_list) : 0,
1241 igmp_group_compat_mode(igmp, grp),
1242 uptime,
1243 VTY_NEWLINE);
1244
1245 } /* scan igmp groups */
1246 } /* scan igmp sockets */
1247 } /* scan interfaces */
1248}
1249
1250static void igmp_show_group_retransmission(struct vty *vty)
1251{
1252 struct listnode *ifnode;
1253 struct interface *ifp;
1254
1255 vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
1256
1257 /* scan interfaces */
469351b3 1258 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1259 struct pim_interface *pim_ifp = ifp->info;
1260 struct listnode *sock_node;
1261 struct igmp_sock *igmp;
1262
1263 if (!pim_ifp)
1264 continue;
1265
1266 /* scan igmp sockets */
1267 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1268 char ifaddr_str[100];
1269 struct listnode *grpnode;
1270 struct igmp_group *grp;
1271
1272 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1273
1274 /* scan igmp groups */
1275 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1276 char group_str[100];
1277 char grp_retr_mmss[10];
1278 struct listnode *src_node;
1279 struct igmp_source *src;
1280 int grp_retr_sources = 0;
1281
1282 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1283 pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
1284
1285
1286 /* count group sources with retransmission state */
1287 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
1288 if (src->source_query_retransmit_count > 0) {
1289 ++grp_retr_sources;
1290 }
1291 }
1292
1293 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
1294 ifp->name,
1295 ifaddr_str,
1296 group_str,
1297 grp_retr_mmss,
1298 grp->group_specific_query_retransmit_count,
1299 grp_retr_sources,
1300 VTY_NEWLINE);
1301
1302 } /* scan igmp groups */
1303 } /* scan igmp sockets */
1304 } /* scan interfaces */
1305}
1306
1307static void igmp_show_parameters(struct vty *vty)
1308{
1309 struct listnode *ifnode;
1310 struct interface *ifp;
1311
1312 vty_out(vty,
1313 "QRV: Robustness Variable SQI: Startup Query Interval%s"
1314 "QQI: Query Interval OQPI: Other Querier Present Interval%s"
1315 "QRI: Query Response Interval LMQT: Last Member Query Time%s"
1316 "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
1317 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1318
1319 vty_out(vty,
1320 "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
1321 VTY_NEWLINE);
1322
1323 /* scan interfaces */
469351b3 1324 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1325 struct pim_interface *pim_ifp = ifp->info;
1326 struct listnode *sock_node;
1327 struct igmp_sock *igmp;
1328
1329 if (!pim_ifp)
1330 continue;
1331
1332 /* scan igmp sockets */
1333 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1334 char ifaddr_str[100];
1335 long gmi_dsec; /* Group Membership Interval */
1336 long oqpi_dsec; /* Other Querier Present Interval */
1337 int sqi;
1338 long lmqt_dsec;
1339 long ohpi_dsec;
1340 long qri_dsec;
1341
1342 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1343
1344 gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
1345 igmp->querier_query_interval,
1346 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1347
1348 sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
1349
1350 oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
1351 igmp->querier_query_interval,
1352 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1353
1354 lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
1355 igmp->querier_robustness_variable) / 100;
1356
1357 ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
1358 igmp->querier_query_interval,
1359 pim_ifp->igmp_query_max_response_time_dsec);
1360
1361 qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
1362
1363 vty_out(vty,
1364 "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
1365 ifp->name,
1366 ifaddr_str,
1367 igmp->querier_robustness_variable,
1368 igmp->querier_query_interval,
1369 qri_dsec / 10, qri_dsec % 10,
1370 gmi_dsec / 10, gmi_dsec % 10,
1371 sqi,
1372 oqpi_dsec / 10, oqpi_dsec % 10,
1373 lmqt_dsec / 10, lmqt_dsec % 10,
1374 ohpi_dsec / 10, ohpi_dsec % 10,
1375 VTY_NEWLINE);
1376
1377 } /* scan igmp sockets */
1378 } /* scan interfaces */
1379}
1380
1381static void igmp_show_sources(struct vty *vty)
1382{
1383 struct listnode *ifnode;
1384 struct interface *ifp;
1385 time_t now;
1386
1387 now = pim_time_monotonic_sec();
1388
1389 vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
1390
1391 /* scan interfaces */
469351b3 1392 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1393 struct pim_interface *pim_ifp = ifp->info;
1394 struct listnode *sock_node;
1395 struct igmp_sock *igmp;
1396
1397 if (!pim_ifp)
1398 continue;
1399
1400 /* scan igmp sockets */
1401 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1402 char ifaddr_str[100];
1403 struct listnode *grpnode;
1404 struct igmp_group *grp;
1405
1406 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1407
1408 /* scan igmp groups */
1409 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1410 char group_str[100];
1411 struct listnode *srcnode;
1412 struct igmp_source *src;
1413
1414 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1415
1416 /* scan group sources */
1417 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1418 char source_str[100];
1419 char mmss[10];
1420 char uptime[10];
1421
1422 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1423
1424 pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
1425
1426 pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
1427
1428 vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
1429 ifp->name,
1430 ifaddr_str,
1431 group_str,
1432 source_str,
1433 mmss,
1434 IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
1435 uptime,
1436 VTY_NEWLINE);
1437
1438 } /* scan group sources */
1439 } /* scan igmp groups */
1440 } /* scan igmp sockets */
1441 } /* scan interfaces */
1442}
1443
1444static void igmp_show_source_retransmission(struct vty *vty)
1445{
1446 struct listnode *ifnode;
1447 struct interface *ifp;
1448
1449 vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
1450
1451 /* scan interfaces */
469351b3 1452 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1453 struct pim_interface *pim_ifp = ifp->info;
1454 struct listnode *sock_node;
1455 struct igmp_sock *igmp;
1456
1457 if (!pim_ifp)
1458 continue;
1459
1460 /* scan igmp sockets */
1461 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1462 char ifaddr_str[100];
1463 struct listnode *grpnode;
1464 struct igmp_group *grp;
1465
1466 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1467
1468 /* scan igmp groups */
1469 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1470 char group_str[100];
1471 struct listnode *srcnode;
1472 struct igmp_source *src;
1473
1474 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1475
1476 /* scan group sources */
1477 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1478 char source_str[100];
1479
1480 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1481
1482 vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
1483 ifp->name,
1484 ifaddr_str,
1485 group_str,
1486 source_str,
1487 src->source_query_retransmit_count,
1488 VTY_NEWLINE);
1489
1490 } /* scan group sources */
1491 } /* scan igmp groups */
1492 } /* scan igmp sockets */
1493 } /* scan interfaces */
1494}
1495
1496static void clear_igmp_interfaces()
1497{
1498 struct listnode *ifnode;
1499 struct listnode *ifnextnode;
1500 struct interface *ifp;
1501
469351b3 1502 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1503 pim_if_addr_del_all_igmp(ifp);
1504 }
1505
469351b3 1506 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1507 pim_if_addr_add_all(ifp);
1508 }
1509}
1510
1511static void clear_pim_interfaces()
1512{
1513 struct listnode *ifnode;
1514 struct listnode *ifnextnode;
1515 struct interface *ifp;
1516
469351b3 1517 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1518 if (ifp->info) {
1519 pim_neighbor_delete_all(ifp, "interface cleared");
1520 }
1521 }
1522}
1523
1524static void clear_interfaces()
1525{
1526 clear_igmp_interfaces();
1527 clear_pim_interfaces();
1528}
1529
1530DEFUN (pim_interface,
1531 pim_interface_cmd,
1532 "interface IFNAME",
1533 "Select an interface to configure\n"
1534 "Interface's name\n")
1535{
1536 struct interface *ifp;
5cee71fb 1537 const char *ifname = argv[0];
12e41d03
DL
1538 size_t sl;
1539
1540 sl = strlen(ifname);
1541 if (sl > INTERFACE_NAMSIZ) {
1542 vty_out(vty, "%% Interface name %s is invalid: length exceeds "
1543 "%d characters%s",
1544 ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
1545 return CMD_WARNING;
1546 }
1547
1548 ifp = if_lookup_by_name_len(ifname, sl);
1549 if (!ifp) {
1550 vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
1551
1552 /* Returning here would prevent pimd from booting when there are
1553 interface commands in pimd.conf, since all interfaces are
1554 unknown at pimd boot time (the zebra daemon has not been
1555 contacted for interface discovery). */
1556
1557 ifp = if_get_by_name_len(ifname, sl);
1558 if (!ifp) {
1559 vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
1560 return CMD_WARNING;
1561 }
1562 }
1563
1564 vty->index = ifp;
1565 vty->node = INTERFACE_NODE;
1566
1567 return CMD_SUCCESS;
1568}
1569
1570DEFUN (clear_ip_interfaces,
1571 clear_ip_interfaces_cmd,
1572 "clear ip interfaces",
1573 CLEAR_STR
1574 IP_STR
1575 "Reset interfaces\n")
1576{
1577 clear_interfaces();
1578
1579 return CMD_SUCCESS;
1580}
1581
1582DEFUN (clear_ip_igmp_interfaces,
1583 clear_ip_igmp_interfaces_cmd,
1584 "clear ip igmp interfaces",
1585 CLEAR_STR
1586 IP_STR
1587 CLEAR_IP_IGMP_STR
1588 "Reset IGMP interfaces\n")
1589{
1590 clear_igmp_interfaces();
1591
1592 return CMD_SUCCESS;
1593}
1594
1595static void mroute_add_all()
1596{
1597 struct listnode *node;
1598 struct channel_oil *c_oil;
1599
1600 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
c171d6d8 1601 if (pim_mroute_add(c_oil)) {
12e41d03
DL
1602 /* just log warning */
1603 char source_str[100];
1604 char group_str[100];
1605 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1606 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1607 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1608 __FILE__, __PRETTY_FUNCTION__,
1609 source_str, group_str);
1610 }
1611 }
1612}
1613
1614static void mroute_del_all()
1615{
1616 struct listnode *node;
1617 struct channel_oil *c_oil;
1618
1619 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
c171d6d8 1620 if (pim_mroute_del(c_oil)) {
12e41d03
DL
1621 /* just log warning */
1622 char source_str[100];
1623 char group_str[100];
1624 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1625 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1626 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1627 __FILE__, __PRETTY_FUNCTION__,
1628 source_str, group_str);
1629 }
1630 }
1631}
1632
6250610a
JAG
1633static void static_mroute_add_all()
1634{
1635 struct listnode *node;
1636 struct static_route *s_route;
1637
1638 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
c171d6d8 1639 if (pim_mroute_add(&s_route->c_oil)) {
6250610a
JAG
1640 /* just log warning */
1641 char source_str[100];
1642 char group_str[100];
9867746a
DS
1643 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
1644 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
6250610a
JAG
1645 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1646 __FILE__, __PRETTY_FUNCTION__,
1647 source_str, group_str);
1648 }
1649 }
1650}
1651
1652static void static_mroute_del_all()
1653{
1654 struct listnode *node;
1655 struct static_route *s_route;
1656
1657 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
c171d6d8 1658 if (pim_mroute_del(&s_route->c_oil)) {
6250610a
JAG
1659 /* just log warning */
1660 char source_str[100];
1661 char group_str[100];
9867746a
DS
1662 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
1663 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
6250610a
JAG
1664 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1665 __FILE__, __PRETTY_FUNCTION__,
1666 source_str, group_str);
1667 }
1668 }
1669}
1670
12e41d03
DL
1671DEFUN (clear_ip_mroute,
1672 clear_ip_mroute_cmd,
1673 "clear ip mroute",
1674 CLEAR_STR
1675 IP_STR
1676 "Reset multicast routes\n")
1677{
1678 mroute_del_all();
1679 mroute_add_all();
1680
1681 return CMD_SUCCESS;
1682}
1683
1684DEFUN (clear_ip_pim_interfaces,
1685 clear_ip_pim_interfaces_cmd,
1686 "clear ip pim interfaces",
1687 CLEAR_STR
1688 IP_STR
1689 CLEAR_IP_PIM_STR
1690 "Reset PIM interfaces\n")
1691{
1692 clear_pim_interfaces();
1693
1694 return CMD_SUCCESS;
1695}
1696
1697DEFUN (clear_ip_pim_oil,
1698 clear_ip_pim_oil_cmd,
1699 "clear ip pim oil",
1700 CLEAR_STR
1701 IP_STR
1702 CLEAR_IP_PIM_STR
1703 "Rescan PIM OIL (output interface list)\n")
1704{
1705 pim_scan_oil();
1706
1707 return CMD_SUCCESS;
1708}
1709
1710DEFUN (show_ip_igmp_interface,
1711 show_ip_igmp_interface_cmd,
1712 "show ip igmp interface",
1713 SHOW_STR
1714 IP_STR
1715 IGMP_STR
1716 "IGMP interface information\n")
1717{
1718 igmp_show_interfaces(vty);
1719
1720 return CMD_SUCCESS;
1721}
1722
1723DEFUN (show_ip_igmp_join,
1724 show_ip_igmp_join_cmd,
1725 "show ip igmp join",
1726 SHOW_STR
1727 IP_STR
1728 IGMP_STR
1729 "IGMP static join information\n")
1730{
1731 igmp_show_interface_join(vty);
1732
1733 return CMD_SUCCESS;
1734}
1735
1736DEFUN (show_ip_igmp_groups,
1737 show_ip_igmp_groups_cmd,
1738 "show ip igmp groups",
1739 SHOW_STR
1740 IP_STR
1741 IGMP_STR
1742 IGMP_GROUP_STR)
1743{
1744 igmp_show_groups(vty);
1745
1746 return CMD_SUCCESS;
1747}
1748
1749DEFUN (show_ip_igmp_groups_retransmissions,
1750 show_ip_igmp_groups_retransmissions_cmd,
1751 "show ip igmp groups retransmissions",
1752 SHOW_STR
1753 IP_STR
1754 IGMP_STR
1755 IGMP_GROUP_STR
1756 "IGMP group retransmissions\n")
1757{
1758 igmp_show_group_retransmission(vty);
1759
1760 return CMD_SUCCESS;
1761}
1762
1763DEFUN (show_ip_igmp_parameters,
1764 show_ip_igmp_parameters_cmd,
1765 "show ip igmp parameters",
1766 SHOW_STR
1767 IP_STR
1768 IGMP_STR
1769 "IGMP parameters information\n")
1770{
1771 igmp_show_parameters(vty);
1772
1773 return CMD_SUCCESS;
1774}
1775
1776DEFUN (show_ip_igmp_sources,
1777 show_ip_igmp_sources_cmd,
1778 "show ip igmp sources",
1779 SHOW_STR
1780 IP_STR
1781 IGMP_STR
1782 IGMP_SOURCE_STR)
1783{
1784 igmp_show_sources(vty);
1785
1786 return CMD_SUCCESS;
1787}
1788
1789DEFUN (show_ip_igmp_sources_retransmissions,
1790 show_ip_igmp_sources_retransmissions_cmd,
1791 "show ip igmp sources retransmissions",
1792 SHOW_STR
1793 IP_STR
1794 IGMP_STR
1795 IGMP_SOURCE_STR
1796 "IGMP source retransmissions\n")
1797{
1798 igmp_show_source_retransmission(vty);
1799
1800 return CMD_SUCCESS;
1801}
1802
1803DEFUN (show_ip_igmp_querier,
1804 show_ip_igmp_querier_cmd,
1805 "show ip igmp querier",
1806 SHOW_STR
1807 IP_STR
1808 IGMP_STR
1809 "IGMP querier information\n")
1810{
1811 igmp_show_querier(vty);
1812
1813 return CMD_SUCCESS;
1814}
1815
1816DEFUN (show_ip_pim_address,
1817 show_ip_pim_address_cmd,
1818 "show ip pim address",
1819 SHOW_STR
1820 IP_STR
1821 PIM_STR
1822 "PIM interface address\n")
1823{
1824 show_interface_address(vty);
1825
1826 return CMD_SUCCESS;
1827}
1828
1829DEFUN (show_ip_pim_assert,
1830 show_ip_pim_assert_cmd,
1831 "show ip pim assert",
1832 SHOW_STR
1833 IP_STR
1834 PIM_STR
1835 "PIM interface assert\n")
1836{
1837 pim_show_assert(vty);
1838
1839 return CMD_SUCCESS;
1840}
1841
1842DEFUN (show_ip_pim_assert_internal,
1843 show_ip_pim_assert_internal_cmd,
1844 "show ip pim assert-internal",
1845 SHOW_STR
1846 IP_STR
1847 PIM_STR
1848 "PIM interface internal assert state\n")
1849{
1850 pim_show_assert_internal(vty);
1851
1852 return CMD_SUCCESS;
1853}
1854
1855DEFUN (show_ip_pim_assert_metric,
1856 show_ip_pim_assert_metric_cmd,
1857 "show ip pim assert-metric",
1858 SHOW_STR
1859 IP_STR
1860 PIM_STR
1861 "PIM interface assert metric\n")
1862{
1863 pim_show_assert_metric(vty);
1864
1865 return CMD_SUCCESS;
1866}
1867
1868DEFUN (show_ip_pim_assert_winner_metric,
1869 show_ip_pim_assert_winner_metric_cmd,
1870 "show ip pim assert-winner-metric",
1871 SHOW_STR
1872 IP_STR
1873 PIM_STR
1874 "PIM interface assert winner metric\n")
1875{
1876 pim_show_assert_winner_metric(vty);
1877
1878 return CMD_SUCCESS;
1879}
1880
1881DEFUN (show_ip_pim_dr,
1882 show_ip_pim_dr_cmd,
1883 "show ip pim designated-router",
1884 SHOW_STR
1885 IP_STR
1886 PIM_STR
1887 "PIM interface designated router\n")
1888{
1889 pim_show_dr(vty);
1890
1891 return CMD_SUCCESS;
1892}
1893
1894DEFUN (show_ip_pim_hello,
1895 show_ip_pim_hello_cmd,
1896 "show ip pim hello",
1897 SHOW_STR
1898 IP_STR
1899 PIM_STR
1900 "PIM interface hello information\n")
1901{
1902 pim_show_hello(vty);
1903
1904 return CMD_SUCCESS;
1905}
1906
1907DEFUN (show_ip_pim_interface,
1908 show_ip_pim_interface_cmd,
1909 "show ip pim interface",
1910 SHOW_STR
1911 IP_STR
1912 PIM_STR
1913 "PIM interface information\n")
1914{
1915 pim_show_interfaces(vty);
1916
1917 return CMD_SUCCESS;
1918}
1919
1920DEFUN (show_ip_pim_join,
1921 show_ip_pim_join_cmd,
1922 "show ip pim join",
1923 SHOW_STR
1924 IP_STR
1925 PIM_STR
1926 "PIM interface join information\n")
1927{
1928 pim_show_join(vty);
1929
1930 return CMD_SUCCESS;
1931}
1932
1933DEFUN (show_ip_pim_lan_prune_delay,
1934 show_ip_pim_lan_prune_delay_cmd,
1935 "show ip pim lan-prune-delay",
1936 SHOW_STR
1937 IP_STR
1938 PIM_STR
1939 "PIM neighbors LAN prune delay parameters\n")
1940{
1941 pim_show_lan_prune_delay(vty);
1942
1943 return CMD_SUCCESS;
1944}
1945
1946DEFUN (show_ip_pim_local_membership,
1947 show_ip_pim_local_membership_cmd,
1948 "show ip pim local-membership",
1949 SHOW_STR
1950 IP_STR
1951 PIM_STR
1952 "PIM interface local-membership\n")
1953{
1954 pim_show_membership(vty);
1955
1956 return CMD_SUCCESS;
1957}
1958
1959DEFUN (show_ip_pim_jp_override_interval,
1960 show_ip_pim_jp_override_interval_cmd,
1961 "show ip pim jp-override-interval",
1962 SHOW_STR
1963 IP_STR
1964 PIM_STR
1965 "PIM interface J/P override interval\n")
1966{
1967 pim_show_jp_override_interval(vty);
1968
1969 return CMD_SUCCESS;
1970}
1971
1972DEFUN (show_ip_pim_neighbor,
1973 show_ip_pim_neighbor_cmd,
1974 "show ip pim neighbor",
1975 SHOW_STR
1976 IP_STR
1977 PIM_STR
1978 "PIM neighbor information\n")
1979{
1980 pim_show_neighbors(vty);
1981
1982 return CMD_SUCCESS;
1983}
1984
1985DEFUN (show_ip_pim_secondary,
1986 show_ip_pim_secondary_cmd,
1987 "show ip pim secondary",
1988 SHOW_STR
1989 IP_STR
1990 PIM_STR
1991 "PIM neighbor addresses\n")
1992{
1993 pim_show_neighbors_secondary(vty);
1994
1995 return CMD_SUCCESS;
1996}
1997
1998DEFUN (show_ip_pim_upstream,
1999 show_ip_pim_upstream_cmd,
2000 "show ip pim upstream",
2001 SHOW_STR
2002 IP_STR
2003 PIM_STR
2004 "PIM upstream information\n")
2005{
2006 pim_show_upstream(vty);
2007
2008 return CMD_SUCCESS;
2009}
2010
2011DEFUN (show_ip_pim_upstream_join_desired,
2012 show_ip_pim_upstream_join_desired_cmd,
2013 "show ip pim upstream-join-desired",
2014 SHOW_STR
2015 IP_STR
2016 PIM_STR
2017 "PIM upstream join-desired\n")
2018{
2019 pim_show_join_desired(vty);
2020
2021 return CMD_SUCCESS;
2022}
2023
2024DEFUN (show_ip_pim_upstream_rpf,
2025 show_ip_pim_upstream_rpf_cmd,
2026 "show ip pim upstream-rpf",
2027 SHOW_STR
2028 IP_STR
2029 PIM_STR
2030 "PIM upstream source rpf\n")
2031{
2032 pim_show_upstream_rpf(vty);
2033
2034 return CMD_SUCCESS;
2035}
2036
2037DEFUN (show_ip_pim_rpf,
2038 show_ip_pim_rpf_cmd,
2039 "show ip pim rpf",
2040 SHOW_STR
2041 IP_STR
2042 PIM_STR
2043 "PIM cached source rpf information\n")
2044{
2045 pim_show_rpf(vty);
2046
2047 return CMD_SUCCESS;
2048}
2049
2050static void show_multicast_interfaces(struct vty *vty)
2051{
2052 struct listnode *node;
2053 struct interface *ifp;
2054
2055 vty_out(vty, "%s", VTY_NEWLINE);
2056
2057 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2058 VTY_NEWLINE);
2059
469351b3 2060 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
2061 struct pim_interface *pim_ifp;
2062 struct in_addr ifaddr;
2063 struct sioc_vif_req vreq;
2064
2065 pim_ifp = ifp->info;
2066
2067 if (!pim_ifp)
2068 continue;
2069
2070 memset(&vreq, 0, sizeof(vreq));
2071 vreq.vifi = pim_ifp->mroute_vif_index;
2072
2073 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
6c44fe22
DS
2074 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2075 (unsigned long)SIOCGETVIFCNT,
2076 ifp->name,
2077 pim_ifp->mroute_vif_index,
2078 errno,
2079 safe_strerror(errno),
2080 VTY_NEWLINE);
12e41d03
DL
2081 }
2082
2083 ifaddr = pim_ifp->primary_address;
2084
2085 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2086 ifp->name,
2087 inet_ntoa(ifaddr),
2088 ifp->ifindex,
2089 pim_ifp->mroute_vif_index,
ea8b7c71
RW
2090 (unsigned long) vreq.icount,
2091 (unsigned long) vreq.ocount,
2092 (unsigned long) vreq.ibytes,
2093 (unsigned long) vreq.obytes,
12e41d03
DL
2094 VTY_NEWLINE);
2095 }
2096}
2097
2098DEFUN (show_ip_multicast,
2099 show_ip_multicast_cmd,
2100 "show ip multicast",
2101 SHOW_STR
2102 IP_STR
2103 "Multicast global information\n")
2104{
2105 time_t now = pim_time_monotonic_sec();
2106
2107 if (PIM_MROUTE_IS_ENABLED) {
2108 char uptime[10];
2109
2110 vty_out(vty, "Mroute socket descriptor: %d%s",
2111 qpim_mroute_socket_fd,
2112 VTY_NEWLINE);
2113
2114 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
2115 vty_out(vty, "Mroute socket uptime: %s%s",
2116 uptime,
2117 VTY_NEWLINE);
2118 }
2119 else {
2120 vty_out(vty, "Multicast disabled%s",
2121 VTY_NEWLINE);
2122 }
2123
2124 vty_out(vty, "%s", VTY_NEWLINE);
2125 vty_out(vty, "Zclient update socket: ");
2126 if (qpim_zclient_update) {
2127 vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
2128 qpim_zclient_update->fail, VTY_NEWLINE);
2129 }
2130 else {
2131 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2132 }
2133 vty_out(vty, "Zclient lookup socket: ");
2134 if (qpim_zclient_lookup) {
2135 vty_out(vty, "%d failures=%d%s", qpim_zclient_lookup->sock,
2136 qpim_zclient_lookup->fail, VTY_NEWLINE);
2137 }
2138 else {
2139 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2140 }
2141
2142 vty_out(vty, "%s", VTY_NEWLINE);
2143 vty_out(vty, "Current highest VifIndex: %d%s",
2144 qpim_mroute_oif_highest_vif_index,
2145 VTY_NEWLINE);
2146 vty_out(vty, "Maximum highest VifIndex: %d%s",
1865a44a 2147 PIM_MAX_USABLE_VIFS,
12e41d03
DL
2148 VTY_NEWLINE);
2149
2150 vty_out(vty, "%s", VTY_NEWLINE);
2151 vty_out(vty, "Upstream Join Timer: %d secs%s",
2152 qpim_t_periodic,
2153 VTY_NEWLINE);
2154 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
2155 PIM_JP_HOLDTIME,
2156 VTY_NEWLINE);
2157
2158 vty_out(vty, "%s", VTY_NEWLINE);
2159
2160 show_rpf_refresh_stats(vty, now);
2161
2162 vty_out(vty, "%s", VTY_NEWLINE);
2163
2164 show_scan_oil_stats(vty, now);
2165
2166 show_multicast_interfaces(vty);
2167
2168 return CMD_SUCCESS;
2169}
2170
2171static void show_mroute(struct vty *vty)
2172{
2173 struct listnode *node;
2174 struct channel_oil *c_oil;
6250610a 2175 struct static_route *s_route;
12e41d03
DL
2176 time_t now;
2177
0fba6e63 2178 vty_out(vty, "Proto: I=IGMP P=PIM S=STATIC O=SOURCE%s%s", VTY_NEWLINE, VTY_NEWLINE);
12e41d03
DL
2179
2180 vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
2181 VTY_NEWLINE);
2182
2183 now = pim_time_monotonic_sec();
2184
6250610a 2185 /* print list of PIM and IGMP routes */
12e41d03
DL
2186 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2187 char group_str[100];
2188 char source_str[100];
2189 int oif_vif_index;
2190
58302dc7
DS
2191 if (!c_oil->installed)
2192 continue;
2193
12e41d03
DL
2194 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2195 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2196
2197 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2198 struct interface *ifp_in;
2199 struct interface *ifp_out;
2200 char oif_uptime[10];
2201 int ttl;
2202 char proto[5];
2203
2204 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2205 if (ttl < 1)
2206 continue;
2207
2208 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
2209 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2210
2211 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
2212
2213 proto[0] = '\0';
2214 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2215 strcat(proto, "P");
2216 }
2217 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2218 strcat(proto, "I");
2219 }
0fba6e63
DS
2220 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) {
2221 strcat(proto, "O");
2222 }
12e41d03
DL
2223
2224 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2225 source_str,
2226 group_str,
2227 proto,
2228 ifp_in ? ifp_in->name : "<iif?>",
2229 c_oil->oil.mfcc_parent,
2230 ifp_out ? ifp_out->name : "<oif?>",
2231 oif_vif_index,
2232 ttl,
2233 oif_uptime,
2234 VTY_NEWLINE);
2235 }
2236 }
6250610a
JAG
2237
2238 /* Print list of static routes */
2239 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2240 char group_str[100];
2241 char source_str[100];
2242 int oif_vif_index;
2243
58302dc7
DS
2244 if (!s_route->c_oil.installed)
2245 continue;
2246
6250610a
JAG
2247 pim_inet4_dump("<group?>", s_route->group, group_str, sizeof(group_str));
2248 pim_inet4_dump("<source?>", s_route->source, source_str, sizeof(source_str));
2249
2250 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2251 struct interface *ifp_in;
2252 struct interface *ifp_out;
2253 char oif_uptime[10];
2254 int ttl;
2255 char proto[5];
2256
2257 ttl = s_route->oif_ttls[oif_vif_index];
2258 if (ttl < 1)
2259 continue;
2260
2261 ifp_in = pim_if_find_by_vif_index(s_route->iif);
2262 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2263
9867746a 2264 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->c_oil.oif_creation[oif_vif_index]);
6250610a
JAG
2265
2266 proto[0] = '\0';
2267 strcat(proto, "S");
2268
2269 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2270 source_str,
2271 group_str,
2272 proto,
2273 ifp_in ? ifp_in->name : "<iif?>",
2274 s_route->iif,
2275 ifp_out ? ifp_out->name : "<oif?>",
2276 oif_vif_index,
2277 ttl,
2278 oif_uptime,
2279 VTY_NEWLINE);
2280 }
2281 }
12e41d03
DL
2282}
2283
2284DEFUN (show_ip_mroute,
2285 show_ip_mroute_cmd,
2286 "show ip mroute",
2287 SHOW_STR
2288 IP_STR
2289 MROUTE_STR)
2290{
2291 show_mroute(vty);
2292 return CMD_SUCCESS;
2293}
2294
2295static void show_mroute_count(struct vty *vty)
2296{
2297 struct listnode *node;
2298 struct channel_oil *c_oil;
6250610a 2299 struct static_route *s_route;
12e41d03
DL
2300
2301 vty_out(vty, "%s", VTY_NEWLINE);
2302
2303 vty_out(vty, "Source Group Packets Bytes WrongIf %s",
2304 VTY_NEWLINE);
2305
6250610a 2306 /* Print PIM and IGMP route counts */
12e41d03
DL
2307 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2308 char group_str[100];
2309 char source_str[100];
12e41d03 2310
58302dc7
DS
2311 if (!c_oil->installed)
2312 continue;
2313
3667e8a0 2314 pim_mroute_update_counters (c_oil);
12e41d03
DL
2315
2316 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2317 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2318
12e41d03
DL
2319 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2320 source_str,
2321 group_str,
3667e8a0
DS
2322 c_oil->cc.pktcnt,
2323 c_oil->cc.bytecnt,
2324 c_oil->cc.wrong_if,
12e41d03 2325 VTY_NEWLINE);
6250610a
JAG
2326 }
2327
2328 /* Print static route counts */
2329 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2330 char group_str[100];
2331 char source_str[100];
6250610a 2332
58302dc7
DS
2333 if (!s_route->c_oil.installed)
2334 continue;
2335
3667e8a0 2336 pim_mroute_update_counters (&s_route->c_oil);
6250610a 2337
9867746a
DS
2338 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2339 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
6250610a 2340
6250610a
JAG
2341 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2342 source_str,
2343 group_str,
3667e8a0
DS
2344 s_route->c_oil.cc.pktcnt,
2345 s_route->c_oil.cc.bytecnt,
2346 s_route->c_oil.cc.wrong_if,
6250610a 2347 VTY_NEWLINE);
12e41d03
DL
2348 }
2349}
2350
2351DEFUN (show_ip_mroute_count,
2352 show_ip_mroute_count_cmd,
2353 "show ip mroute count",
2354 SHOW_STR
2355 IP_STR
2356 MROUTE_STR
2357 "Route and packet count data\n")
2358{
2359 show_mroute_count(vty);
2360 return CMD_SUCCESS;
2361}
2362
2363DEFUN (show_ip_rib,
2364 show_ip_rib_cmd,
2365 "show ip rib A.B.C.D",
2366 SHOW_STR
2367 IP_STR
2368 RIB_STR
2369 "Unicast address\n")
2370{
2371 struct in_addr addr;
2372 const char *addr_str;
2373 struct pim_nexthop nexthop;
2374 char nexthop_addr_str[100];
2375 int result;
2376
5cee71fb 2377 addr_str = argv[0];
12e41d03
DL
2378 result = inet_pton(AF_INET, addr_str, &addr);
2379 if (result <= 0) {
2380 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
2381 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
2382 return CMD_WARNING;
2383 }
2384
651d0f71 2385 if (pim_nexthop_lookup(&nexthop, addr, NULL)) {
12e41d03
DL
2386 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
2387 addr_str, VTY_NEWLINE);
2388 return CMD_WARNING;
2389 }
2390
2391 vty_out(vty, "Address NextHop Interface Metric Preference%s",
2392 VTY_NEWLINE);
2393
2394 pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
2395 nexthop_addr_str, sizeof(nexthop_addr_str));
2396
2397 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
2398 addr_str,
2399 nexthop_addr_str,
2400 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2401 nexthop.mrib_route_metric,
2402 nexthop.mrib_metric_preference,
2403 VTY_NEWLINE);
2404
2405 return CMD_SUCCESS;
2406}
2407
2408static void show_ssmpingd(struct vty *vty)
2409{
2410 struct listnode *node;
2411 struct ssmpingd_sock *ss;
2412 time_t now;
2413
2414 vty_out(vty, "Source Socket Address Port Uptime Requests%s",
2415 VTY_NEWLINE);
2416
2417 if (!qpim_ssmpingd_list)
2418 return;
2419
2420 now = pim_time_monotonic_sec();
2421
2422 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
2423 char source_str[100];
2424 char ss_uptime[10];
2425 struct sockaddr_in bind_addr;
2426 socklen_t len = sizeof(bind_addr);
2427 char bind_addr_str[100];
2428
2429 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
2430
2431 if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
2432 vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
2433 source_str, ss->sock_fd, VTY_NEWLINE);
2434 }
2435
2436 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
2437 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
2438
2439 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
2440 source_str,
2441 ss->sock_fd,
2442 bind_addr_str,
2443 ntohs(bind_addr.sin_port),
2444 ss_uptime,
2445 (long long)ss->requests,
2446 VTY_NEWLINE);
2447 }
2448}
2449
2450DEFUN (show_ip_ssmpingd,
2451 show_ip_ssmpingd_cmd,
2452 "show ip ssmpingd",
2453 SHOW_STR
2454 IP_STR
2455 SHOW_SSMPINGD_STR)
2456{
2457 show_ssmpingd(vty);
2458 return CMD_SUCCESS;
2459}
2460
981d6c7a
DS
2461DEFUN (ip_pim_rp,
2462 ip_pim_rp_cmd,
2463 "ip pim rp A.B.C.D",
2464 IP_STR
9b34069d
QY
2465 "pim multicast routing\n"
2466 "Rendevous Point\n"
2467 "ip address of RP\n")
981d6c7a
DS
2468{
2469 int result;
2470
5cee71fb 2471 result = inet_pton(AF_INET, argv[0], &qpim_rp.rpf_addr.s_addr);
981d6c7a 2472 if (result <= 0) {
5cee71fb 2473 vty_out(vty, "%% Bad RP address specified: %s", argv[0]);
981d6c7a
DS
2474 return CMD_WARNING;
2475 }
2476
651d0f71 2477 if (pim_nexthop_lookup(&qpim_rp.source_nexthop, qpim_rp.rpf_addr, NULL) != 0) {
5cee71fb 2478 vty_out(vty, "%% No Path to RP address specified: %s", argv[0]);
c8ae3ce8
DS
2479 return CMD_WARNING;
2480 }
2481
981d6c7a
DS
2482 return CMD_SUCCESS;
2483}
2484
2485DEFUN (no_ip_pim_rp,
2486 no_ip_pim_rp_cmd,
2487 "no ip pim rp {A.B.C.D}",
2488 NO_STR
2489 IP_STR
9b34069d
QY
2490 "pim multicast routing\n"
2491 "Rendevous Point\n"
2492 "ip address of RP\n")
981d6c7a 2493{
c8ae3ce8 2494 qpim_rp.rpf_addr.s_addr = INADDR_NONE;
981d6c7a
DS
2495
2496 return CMD_SUCCESS;
2497}
2498
12e41d03
DL
2499DEFUN (ip_multicast_routing,
2500 ip_multicast_routing_cmd,
2501 PIM_CMD_IP_MULTICAST_ROUTING,
2502 IP_STR
2503 "Enable IP multicast forwarding\n")
2504{
2505 pim_mroute_socket_enable();
2506 pim_if_add_vif_all();
2507 mroute_add_all();
6250610a 2508 static_mroute_add_all();
12e41d03
DL
2509 return CMD_SUCCESS;
2510}
2511
2512DEFUN (no_ip_multicast_routing,
2513 no_ip_multicast_routing_cmd,
2514 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
2515 NO_STR
2516 IP_STR
2517 "Global IP configuration subcommands\n"
2518 "Enable IP multicast forwarding\n")
2519{
2520 mroute_del_all();
6250610a 2521 static_mroute_del_all();
12e41d03
DL
2522 pim_if_del_vif_all();
2523 pim_mroute_socket_disable();
2524 return CMD_SUCCESS;
2525}
2526
2527DEFUN (ip_ssmpingd,
2528 ip_ssmpingd_cmd,
2529 "ip ssmpingd [A.B.C.D]",
2530 IP_STR
2531 CONF_SSMPINGD_STR
2532 "Source address\n")
2533{
2534 int result;
2535 struct in_addr source_addr;
5cee71fb 2536 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
12e41d03
DL
2537
2538 result = inet_pton(AF_INET, source_str, &source_addr);
2539 if (result <= 0) {
2540 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2541 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2542 return CMD_WARNING;
2543 }
2544
2545 result = pim_ssmpingd_start(source_addr);
2546 if (result) {
2547 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
2548 source_str, result, VTY_NEWLINE);
2549 return CMD_WARNING;
2550 }
2551
2552 return CMD_SUCCESS;
2553}
2554
2555DEFUN (no_ip_ssmpingd,
2556 no_ip_ssmpingd_cmd,
2557 "no ip ssmpingd [A.B.C.D]",
2558 NO_STR
2559 IP_STR
2560 CONF_SSMPINGD_STR
2561 "Source address\n")
2562{
2563 int result;
2564 struct in_addr source_addr;
5cee71fb 2565 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
12e41d03
DL
2566
2567 result = inet_pton(AF_INET, source_str, &source_addr);
2568 if (result <= 0) {
2569 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2570 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2571 return CMD_WARNING;
2572 }
2573
2574 result = pim_ssmpingd_stop(source_addr);
2575 if (result) {
2576 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
2577 source_str, result, VTY_NEWLINE);
2578 return CMD_WARNING;
2579 }
2580
2581 return CMD_SUCCESS;
2582}
2583
2584DEFUN (interface_ip_igmp,
2585 interface_ip_igmp_cmd,
2586 "ip igmp",
2587 IP_STR
2588 IFACE_IGMP_STR)
2589{
2590 struct interface *ifp;
2591 struct pim_interface *pim_ifp;
2592
2593 ifp = vty->index;
2594 pim_ifp = ifp->info;
2595
2596 if (!pim_ifp) {
2597 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2598 if (!pim_ifp) {
2599 vty_out(vty, "Could not enable IGMP on interface %s%s",
2600 ifp->name, VTY_NEWLINE);
2601 return CMD_WARNING;
2602 }
2603 }
2604 else {
2605 PIM_IF_DO_IGMP(pim_ifp->options);
2606 }
2607
2608 pim_if_addr_add_all(ifp);
2609 pim_if_membership_refresh(ifp);
2610
2611 return CMD_SUCCESS;
2612}
2613
2614DEFUN (interface_no_ip_igmp,
2615 interface_no_ip_igmp_cmd,
2616 "no ip igmp",
2617 NO_STR
2618 IP_STR
2619 IFACE_IGMP_STR)
2620{
2621 struct interface *ifp;
2622 struct pim_interface *pim_ifp;
2623
2624 ifp = vty->index;
2625 pim_ifp = ifp->info;
2626 if (!pim_ifp)
2627 return CMD_SUCCESS;
2628
2629 PIM_IF_DONT_IGMP(pim_ifp->options);
2630
2631 pim_if_membership_clear(ifp);
2632
2633 pim_if_addr_del_all_igmp(ifp);
2634
2635 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2636 pim_if_delete(ifp);
2637 }
2638
2639 return CMD_SUCCESS;
2640}
2641
2642DEFUN (interface_ip_igmp_join,
2643 interface_ip_igmp_join_cmd,
2644 "ip igmp join A.B.C.D A.B.C.D",
2645 IP_STR
2646 IFACE_IGMP_STR
2647 "IGMP join multicast group\n"
2648 "Multicast group address\n"
2649 "Source address\n")
2650{
2651 struct interface *ifp;
2652 const char *group_str;
2653 const char *source_str;
2654 struct in_addr group_addr;
2655 struct in_addr source_addr;
2656 int result;
2657
2658 ifp = vty->index;
2659
2660 /* Group address */
5cee71fb 2661 group_str = argv[0];
12e41d03
DL
2662 result = inet_pton(AF_INET, group_str, &group_addr);
2663 if (result <= 0) {
2664 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2665 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2666 return CMD_WARNING;
2667 }
2668
2669 /* Source address */
5cee71fb 2670 source_str = argv[1];
12e41d03
DL
2671 result = inet_pton(AF_INET, source_str, &source_addr);
2672 if (result <= 0) {
2673 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2674 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2675 return CMD_WARNING;
2676 }
2677
2678 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2679 if (result) {
2680 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2681 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2682 return CMD_WARNING;
2683 }
2684
2685 return CMD_SUCCESS;
2686}
2687
2688DEFUN (interface_no_ip_igmp_join,
2689 interface_no_ip_igmp_join_cmd,
2690 "no ip igmp join A.B.C.D A.B.C.D",
2691 NO_STR
2692 IP_STR
2693 IFACE_IGMP_STR
2694 "IGMP join multicast group\n"
2695 "Multicast group address\n"
2696 "Source address\n")
2697{
2698 struct interface *ifp;
2699 const char *group_str;
2700 const char *source_str;
2701 struct in_addr group_addr;
2702 struct in_addr source_addr;
2703 int result;
2704
2705 ifp = vty->index;
2706
2707 /* Group address */
5cee71fb 2708 group_str = argv[0];
12e41d03
DL
2709 result = inet_pton(AF_INET, group_str, &group_addr);
2710 if (result <= 0) {
2711 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2712 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2713 return CMD_WARNING;
2714 }
2715
2716 /* Source address */
5cee71fb 2717 source_str = argv[1];
12e41d03
DL
2718 result = inet_pton(AF_INET, source_str, &source_addr);
2719 if (result <= 0) {
2720 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2721 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2722 return CMD_WARNING;
2723 }
2724
2725 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2726 if (result) {
2727 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2728 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2729 return CMD_WARNING;
2730 }
2731
2732 return CMD_SUCCESS;
2733}
2734
2735/*
2736 CLI reconfiguration affects the interface level (struct pim_interface).
2737 This function propagates the reconfiguration to every active socket
2738 for that interface.
2739 */
2740static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2741{
2742 struct interface *ifp;
2743 struct pim_interface *pim_ifp;
2744
2745 zassert(igmp);
2746
2747 /* other querier present? */
2748
2749 if (igmp->t_other_querier_timer)
2750 return;
2751
2752 /* this is the querier */
2753
2754 zassert(igmp->interface);
2755 zassert(igmp->interface->info);
2756
2757 ifp = igmp->interface;
2758 pim_ifp = ifp->info;
2759
2760 if (PIM_DEBUG_IGMP_TRACE) {
2761 char ifaddr_str[100];
2762 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2763 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2764 __PRETTY_FUNCTION__,
2765 ifaddr_str,
2766 ifp->name,
2767 pim_ifp->igmp_default_query_interval);
2768 }
2769
2770 /*
2771 igmp_startup_mode_on() will reset QQI:
2772
2773 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2774 */
2775 igmp_startup_mode_on(igmp);
2776}
2777
2778static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2779{
2780 if (igmp->t_igmp_query_timer) {
2781 /* other querier present */
2782 zassert(igmp->t_igmp_query_timer);
2783 zassert(!igmp->t_other_querier_timer);
2784
2785 pim_igmp_general_query_off(igmp);
2786 pim_igmp_general_query_on(igmp);
2787
2788 zassert(igmp->t_igmp_query_timer);
2789 zassert(!igmp->t_other_querier_timer);
2790 }
2791 else {
2792 /* this is the querier */
2793
2794 zassert(!igmp->t_igmp_query_timer);
2795 zassert(igmp->t_other_querier_timer);
2796
2797 pim_igmp_other_querier_timer_off(igmp);
2798 pim_igmp_other_querier_timer_on(igmp);
2799
2800 zassert(!igmp->t_igmp_query_timer);
2801 zassert(igmp->t_other_querier_timer);
2802 }
2803}
2804
2805static void change_query_interval(struct pim_interface *pim_ifp,
2806 int query_interval)
2807{
2808 struct listnode *sock_node;
2809 struct igmp_sock *igmp;
2810
2811 pim_ifp->igmp_default_query_interval = query_interval;
2812
2813 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2814 igmp_sock_query_interval_reconfig(igmp);
2815 igmp_sock_query_reschedule(igmp);
2816 }
2817}
2818
2819static void change_query_max_response_time(struct pim_interface *pim_ifp,
2820 int query_max_response_time_dsec)
2821{
2822 struct listnode *sock_node;
2823 struct igmp_sock *igmp;
2824
2825 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2826
2827 /*
2828 Below we modify socket/group/source timers in order to quickly
2829 reflect the change. Otherwise, those timers would eventually catch
2830 up.
2831 */
2832
2833 /* scan all sockets */
2834 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2835 struct listnode *grp_node;
2836 struct igmp_group *grp;
2837
2838 /* reschedule socket general query */
2839 igmp_sock_query_reschedule(igmp);
2840
2841 /* scan socket groups */
2842 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2843 struct listnode *src_node;
2844 struct igmp_source *src;
2845
2846 /* reset group timers for groups in EXCLUDE mode */
2847 if (grp->group_filtermode_isexcl) {
2848 igmp_group_reset_gmi(grp);
2849 }
2850
2851 /* scan group sources */
2852 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2853
2854 /* reset source timers for sources with running timers */
2855 if (src->t_source_timer) {
2856 igmp_source_reset_gmi(igmp, grp, src);
2857 }
2858 }
2859 }
2860 }
2861}
2862
2863#define IGMP_QUERY_INTERVAL_MIN (1)
2864#define IGMP_QUERY_INTERVAL_MAX (1800)
2865
2866DEFUN (interface_ip_igmp_query_interval,
2867 interface_ip_igmp_query_interval_cmd,
2868 PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
2869 IP_STR
2870 IFACE_IGMP_STR
2871 IFACE_IGMP_QUERY_INTERVAL_STR
2872 "Query interval in seconds\n")
2873{
2874 struct interface *ifp;
2875 struct pim_interface *pim_ifp;
2876 int query_interval;
2877 int query_interval_dsec;
2878
2879 ifp = vty->index;
2880 pim_ifp = ifp->info;
2881
2882 if (!pim_ifp) {
2883 vty_out(vty,
2884 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2885 ifp->name,
2886 VTY_NEWLINE);
2887 return CMD_WARNING;
2888 }
2889
5cee71fb 2890 query_interval = atoi(argv[0]);
12e41d03
DL
2891 query_interval_dsec = 10 * query_interval;
2892
2893 /*
2894 It seems we don't need to check bounds since command.c does it
2895 already, but we verify them anyway for extra safety.
2896 */
2897 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
2898 vty_out(vty, "General query interval %d lower than minimum %d%s",
2899 query_interval,
2900 IGMP_QUERY_INTERVAL_MIN,
2901 VTY_NEWLINE);
2902 return CMD_WARNING;
2903 }
2904 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
2905 vty_out(vty, "General query interval %d higher than maximum %d%s",
2906 query_interval,
2907 IGMP_QUERY_INTERVAL_MAX,
2908 VTY_NEWLINE);
2909 return CMD_WARNING;
2910 }
2911
2912 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2913 vty_out(vty,
2914 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
2915 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2916 VTY_NEWLINE);
2917 return CMD_WARNING;
2918 }
2919
2920 change_query_interval(pim_ifp, query_interval);
2921
2922 return CMD_SUCCESS;
2923}
2924
2925DEFUN (interface_no_ip_igmp_query_interval,
2926 interface_no_ip_igmp_query_interval_cmd,
2927 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
2928 NO_STR
2929 IP_STR
2930 IFACE_IGMP_STR
2931 IFACE_IGMP_QUERY_INTERVAL_STR)
2932{
2933 struct interface *ifp;
2934 struct pim_interface *pim_ifp;
2935 int default_query_interval_dsec;
2936
2937 ifp = vty->index;
2938 pim_ifp = ifp->info;
2939
2940 if (!pim_ifp)
2941 return CMD_SUCCESS;
2942
2943 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
2944
2945 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2946 vty_out(vty,
2947 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
2948 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2949 VTY_NEWLINE);
2950 return CMD_WARNING;
2951 }
2952
2953 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
2954
2955 return CMD_SUCCESS;
2956}
2957
2958#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
2959#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
2960
2961DEFUN (interface_ip_igmp_query_max_response_time,
2962 interface_ip_igmp_query_max_response_time_cmd,
2963 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
2964 IP_STR
2965 IFACE_IGMP_STR
2966 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
2967 "Query response value in seconds\n")
2968{
2969 struct interface *ifp;
2970 struct pim_interface *pim_ifp;
2971 int query_max_response_time;
2972
2973 ifp = vty->index;
2974 pim_ifp = ifp->info;
2975
2976 if (!pim_ifp) {
2977 vty_out(vty,
2978 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2979 ifp->name,
2980 VTY_NEWLINE);
2981 return CMD_WARNING;
2982 }
2983
5cee71fb 2984 query_max_response_time = atoi(argv[0]);
12e41d03
DL
2985
2986 /*
2987 It seems we don't need to check bounds since command.c does it
2988 already, but we verify them anyway for extra safety.
2989 */
2990 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
2991 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
2992 query_max_response_time,
2993 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
2994 VTY_NEWLINE);
2995 return CMD_WARNING;
2996 }
2997 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
2998 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
2999 query_max_response_time,
3000 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
3001 VTY_NEWLINE);
3002 return CMD_WARNING;
3003 }
3004
3005 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
3006 vty_out(vty,
3007 "Can't set query max response time %d sec >= general query interval %d sec%s",
3008 query_max_response_time, pim_ifp->igmp_default_query_interval,
3009 VTY_NEWLINE);
3010 return CMD_WARNING;
3011 }
3012
3013 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
3014
3015 return CMD_SUCCESS;
3016}
3017
3018DEFUN (interface_no_ip_igmp_query_max_response_time,
3019 interface_no_ip_igmp_query_max_response_time_cmd,
3020 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
3021 NO_STR
3022 IP_STR
3023 IFACE_IGMP_STR
3024 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
3025{
3026 struct interface *ifp;
3027 struct pim_interface *pim_ifp;
3028 int default_query_interval_dsec;
3029
3030 ifp = vty->index;
3031 pim_ifp = ifp->info;
3032
3033 if (!pim_ifp)
3034 return CMD_SUCCESS;
3035
3036 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3037
3038 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3039 vty_out(vty,
3040 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3041 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3042 VTY_NEWLINE);
3043 return CMD_WARNING;
3044 }
3045
3046 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3047
3048 return CMD_SUCCESS;
3049}
3050
3051#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
3052#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
3053
3054DEFUN (interface_ip_igmp_query_max_response_time_dsec,
3055 interface_ip_igmp_query_max_response_time_dsec_cmd,
3056 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
3057 IP_STR
3058 IFACE_IGMP_STR
3059 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3060 "Query response value in deciseconds\n")
3061{
3062 struct interface *ifp;
3063 struct pim_interface *pim_ifp;
3064 int query_max_response_time_dsec;
3065 int default_query_interval_dsec;
3066
3067 ifp = vty->index;
3068 pim_ifp = ifp->info;
3069
3070 if (!pim_ifp) {
3071 vty_out(vty,
3072 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3073 ifp->name,
3074 VTY_NEWLINE);
3075 return CMD_WARNING;
3076 }
3077
5cee71fb 3078 query_max_response_time_dsec = atoi(argv[0]);
12e41d03
DL
3079
3080 /*
3081 It seems we don't need to check bounds since command.c does it
3082 already, but we verify them anyway for extra safety.
3083 */
3084 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
3085 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
3086 query_max_response_time_dsec,
3087 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
3088 VTY_NEWLINE);
3089 return CMD_WARNING;
3090 }
3091 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
3092 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
3093 query_max_response_time_dsec,
3094 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
3095 VTY_NEWLINE);
3096 return CMD_WARNING;
3097 }
3098
3099 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3100
3101 if (query_max_response_time_dsec >= default_query_interval_dsec) {
3102 vty_out(vty,
3103 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
3104 query_max_response_time_dsec, default_query_interval_dsec,
3105 VTY_NEWLINE);
3106 return CMD_WARNING;
3107 }
3108
3109 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
3110
3111 return CMD_SUCCESS;
3112}
3113
3114DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
3115 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
3116 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
3117 NO_STR
3118 IP_STR
3119 IFACE_IGMP_STR
3120 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
3121{
3122 struct interface *ifp;
3123 struct pim_interface *pim_ifp;
3124 int default_query_interval_dsec;
3125
3126 ifp = vty->index;
3127 pim_ifp = ifp->info;
3128
3129 if (!pim_ifp)
3130 return CMD_SUCCESS;
3131
3132 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3133
3134 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3135 vty_out(vty,
3136 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3137 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3138 VTY_NEWLINE);
3139 return CMD_WARNING;
3140 }
3141
3142 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3143
3144 return CMD_SUCCESS;
3145}
3146
dedccda6
DS
3147DEFUN (interface_ip_pim_drprio,
3148 interface_ip_pim_drprio_cmd,
3149 "ip pim drpriority <1-4294967295>",
3150 IP_STR
3151 PIM_STR
3152 "Set the Designated Router Election Priority\n"
3153 "Value of the new DR Priority\n")
3154{
3155 struct interface *ifp;
3156 struct pim_interface *pim_ifp;
3157 uint32_t old_dr_prio;
3158
3159 ifp = vty->index;
3160 pim_ifp = ifp->info;
3161
3162 if (!pim_ifp) {
3163 vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
3164 return CMD_WARNING;
3165 }
3166
3167 old_dr_prio = pim_ifp->pim_dr_priority;
3168
5cee71fb 3169 pim_ifp->pim_dr_priority = strtol(argv[0], NULL, 10);
dedccda6
DS
3170
3171 if (old_dr_prio != pim_ifp->pim_dr_priority) {
3172 if (pim_if_dr_election(ifp))
3173 pim_hello_restart_now(ifp);
3174 }
3175
3176 return CMD_SUCCESS;
3177}
3178
3179DEFUN (interface_no_ip_pim_drprio,
3180 interface_no_ip_pim_drprio_cmd,
3181 "no ip pim drpriority {<1-4294967295>}",
3182 IP_STR
3183 PIM_STR
3184 "Revert the Designated Router Priority to default\n"
3185 "Old Value of the Priority\n")
3186{
3187 struct interface *ifp;
3188 struct pim_interface *pim_ifp;
3189
3190 ifp = vty->index;
3191 pim_ifp = ifp->info;
3192
3193 if (!pim_ifp) {
7960fa8f 3194 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
dedccda6
DS
3195 return CMD_WARNING;
3196 }
3197
3198 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
3199 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
3200 if (pim_if_dr_election(ifp))
3201 pim_hello_restart_now(ifp);
3202 }
3203
3204 return CMD_SUCCESS;
3205}
3206
981d6c7a
DS
3207static int
3208pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
12e41d03 3209{
981d6c7a 3210 struct pim_interface *pim_ifp = ifp->info;
a920d6e7 3211 struct in_addr null = { .s_addr = 0 };
12e41d03
DL
3212
3213 if (!pim_ifp) {
3214 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
3215 if (!pim_ifp) {
981d6c7a 3216 return 0;
12e41d03
DL
3217 }
3218 }
3219 else {
3220 PIM_IF_DO_PIM(pim_ifp->options);
3221 }
3222
981d6c7a 3223 pim_ifp->itype = itype;
12e41d03
DL
3224 pim_if_addr_add_all(ifp);
3225 pim_if_membership_refresh(ifp);
3226
a920d6e7 3227 pim_rp_check_rp (null, pim_ifp->primary_address);
981d6c7a
DS
3228 return 1;
3229}
3230
3231
3232DEFUN (interface_ip_pim_ssm,
3233 interface_ip_pim_ssm_cmd,
3234 "ip pim ssm",
3235 IP_STR
3236 PIM_STR
3237 IFACE_PIM_STR)
3238{
3239 struct interface *ifp;
3240
3241 ifp = vty->index;
3242
3243 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) {
3244 vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE);
3245 return CMD_WARNING;
3246 }
3247
12e41d03
DL
3248 return CMD_SUCCESS;
3249}
3250
981d6c7a
DS
3251DEFUN (interface_ip_pim_sm,
3252 interface_ip_pim_sm_cmd,
3253 "ip pim sm",
12e41d03
DL
3254 IP_STR
3255 PIM_STR
8371bd60 3256 IFACE_PIM_SM_STR)
12e41d03
DL
3257{
3258 struct interface *ifp;
12e41d03
DL
3259
3260 ifp = vty->index;
981d6c7a
DS
3261 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) {
3262 vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
3263 return CMD_WARNING;
3264 }
3265
c992c9a0
DS
3266 pim_if_create_pimreg();
3267
981d6c7a
DS
3268 return CMD_SUCCESS;
3269}
3270
3271static int
3272pim_cmd_interface_delete (struct interface *ifp)
3273{
3274 struct pim_interface *pim_ifp = ifp->info;
3275
12e41d03 3276 if (!pim_ifp)
981d6c7a 3277 return 1;
12e41d03
DL
3278
3279 PIM_IF_DONT_PIM(pim_ifp->options);
3280
3281 pim_if_membership_clear(ifp);
3282
3283 /*
3284 pim_if_addr_del_all() removes all sockets from
3285 pim_ifp->igmp_socket_list.
3286 */
3287 pim_if_addr_del_all(ifp);
3288
3289 /*
3290 pim_sock_delete() removes all neighbors from
3291 pim_ifp->pim_neighbor_list.
3292 */
3293 pim_sock_delete(ifp, "pim unconfigured on interface");
3294
3295 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
3296 pim_if_delete(ifp);
3297 }
3298
981d6c7a
DS
3299 return 1;
3300}
3301
3302DEFUN (interface_no_ip_pim_ssm,
3303 interface_no_ip_pim_ssm_cmd,
3304 "no ip pim ssm",
3305 NO_STR
3306 IP_STR
3307 PIM_STR
3308 IFACE_PIM_STR)
3309{
3310 struct interface *ifp;
3311
3312 ifp = vty->index;
3313 if (!pim_cmd_interface_delete(ifp)) {
3314 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
3315 return CMD_WARNING;
3316 }
3317
3318 return CMD_SUCCESS;
3319}
3320
3321DEFUN (interface_no_ip_pim_sm,
3322 interface_no_ip_pim_sm_cmd,
3323 "no ip pim sm",
3324 NO_STR
3325 IP_STR
3326 PIM_STR
8371bd60 3327 IFACE_PIM_SM_STR)
981d6c7a
DS
3328{
3329 struct interface *ifp;
3330
3331 ifp = vty->index;
3332 if (!pim_cmd_interface_delete(ifp)) {
3333 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
3334 return CMD_WARNING;
3335 }
3336
12e41d03
DL
3337 return CMD_SUCCESS;
3338}
3339
6250610a
JAG
3340DEFUN (interface_ip_mroute,
3341 interface_ip_mroute_cmd,
3342 "ip mroute INTERFACE A.B.C.D",
3343 IP_STR
3344 "Add multicast route\n"
3345 "Outgoing interface name\n"
3346 "Group address\n")
3347{
3348 struct interface *iif;
3349 struct interface *oif;
3350 const char *oifname;
3351 const char *grp_str;
3352 struct in_addr grp_addr;
3353 struct in_addr src_addr;
3354 int result;
3355
3356 iif = vty->index;
3357
5cee71fb 3358 oifname = argv[0];
6250610a
JAG
3359 oif = if_lookup_by_name(oifname);
3360 if (!oif) {
3361 vty_out(vty, "No such interface name %s%s",
3362 oifname, VTY_NEWLINE);
3363 return CMD_WARNING;
3364 }
3365
5cee71fb 3366 grp_str = argv[1];
6250610a
JAG
3367 result = inet_pton(AF_INET, grp_str, &grp_addr);
3368 if (result <= 0) {
3369 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3370 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3371 return CMD_WARNING;
3372 }
3373
3374 src_addr.s_addr = INADDR_ANY;
3375
3376 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3377 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3378 return CMD_WARNING;
3379 }
3380
3381 return CMD_SUCCESS;
3382}
3383
3384DEFUN (interface_ip_mroute_source,
3385 interface_ip_mroute_source_cmd,
3386 "ip mroute INTERFACE A.B.C.D A.B.C.D",
3387 IP_STR
3388 "Add multicast route\n"
3389 "Outgoing interface name\n"
3390 "Group address\n"
3391 "Source address\n")
3392{
3393 struct interface *iif;
3394 struct interface *oif;
3395 const char *oifname;
3396 const char *grp_str;
3397 struct in_addr grp_addr;
3398 const char *src_str;
3399 struct in_addr src_addr;
3400 int result;
3401
3402 iif = vty->index;
3403
5cee71fb 3404 oifname = argv[0];
6250610a
JAG
3405 oif = if_lookup_by_name(oifname);
3406 if (!oif) {
3407 vty_out(vty, "No such interface name %s%s",
3408 oifname, VTY_NEWLINE);
3409 return CMD_WARNING;
3410 }
3411
5cee71fb 3412 grp_str = argv[1];
6250610a
JAG
3413 result = inet_pton(AF_INET, grp_str, &grp_addr);
3414 if (result <= 0) {
3415 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3416 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3417 return CMD_WARNING;
3418 }
3419
5cee71fb 3420 src_str = argv[2];
6250610a
JAG
3421 result = inet_pton(AF_INET, src_str, &src_addr);
3422 if (result <= 0) {
3423 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3424 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
3425 return CMD_WARNING;
3426 }
3427
3428 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3429 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3430 return CMD_WARNING;
3431 }
3432
3433 return CMD_SUCCESS;
3434}
3435
3436DEFUN (interface_no_ip_mroute,
3437 interface_no_ip_mroute_cmd,
3438 "no ip mroute INTERFACE A.B.C.D",
3439 NO_STR
3440 IP_STR
3441 "Add multicast route\n"
3442 "Outgoing interface name\n"
3443 "Group Address\n")
3444{
3445 struct interface *iif;
3446 struct interface *oif;
3447 const char *oifname;
3448 const char *grp_str;
3449 struct in_addr grp_addr;
3450 struct in_addr src_addr;
3451 int result;
3452
3453 iif = vty->index;
3454
5cee71fb 3455 oifname = argv[0];
6250610a
JAG
3456 oif = if_lookup_by_name(oifname);
3457 if (!oif) {
3458 vty_out(vty, "No such interface name %s%s",
3459 oifname, VTY_NEWLINE);
3460 return CMD_WARNING;
3461 }
3462
5cee71fb 3463 grp_str = argv[1];
6250610a
JAG
3464 result = inet_pton(AF_INET, grp_str, &grp_addr);
3465 if (result <= 0) {
3466 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3467 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3468 return CMD_WARNING;
3469 }
3470
3471 src_addr.s_addr = INADDR_ANY;
3472
3473 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
3474 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3475 return CMD_WARNING;
3476 }
3477
3478 return CMD_SUCCESS;
3479}
3480
3481DEFUN (interface_no_ip_mroute_source,
3482 interface_no_ip_mroute_source_cmd,
3483 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
3484 NO_STR
3485 IP_STR
3486 "Add multicast route\n"
3487 "Outgoing interface name\n"
3488 "Group Address\n"
3489 "Source Address\n")
3490{
3491 struct interface *iif;
3492 struct interface *oif;
3493 const char *oifname;
3494 const char *grp_str;
3495 struct in_addr grp_addr;
3496 const char *src_str;
3497 struct in_addr src_addr;
3498 int result;
3499
3500 iif = vty->index;
3501
5cee71fb 3502 oifname = argv[0];
6250610a
JAG
3503 oif = if_lookup_by_name(oifname);
3504 if (!oif) {
3505 vty_out(vty, "No such interface name %s%s",
3506 oifname, VTY_NEWLINE);
3507 return CMD_WARNING;
3508 }
3509
5cee71fb 3510 grp_str = argv[1];
6250610a
JAG
3511 result = inet_pton(AF_INET, grp_str, &grp_addr);
3512 if (result <= 0) {
3513 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3514 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3515 return CMD_WARNING;
3516 }
3517
5cee71fb 3518 src_str = argv[2];
6250610a
JAG
3519 result = inet_pton(AF_INET, src_str, &src_addr);
3520 if (result <= 0) {
3521 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3522 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
3523 return CMD_WARNING;
3524 }
3525
3526 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
3527 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3528 return CMD_WARNING;
3529 }
3530
3531 return CMD_SUCCESS;
3532}
3533
7960fa8f
DS
3534DEFUN (interface_ip_pim_hello,
3535 interface_ip_pim_hello_cmd,
3536 "ip pim hello <1-180>",
3537 IP_STR
3538 PIM_STR
3539 IFACE_PIM_HELLO_STR
3540 IFACE_PIM_HELLO_TIME_STR)
3541{
3542 struct interface *ifp;
3543 struct pim_interface *pim_ifp;
3544
3545 ifp = vty->index;
3546 pim_ifp = ifp->info;
3547
3548 if (!pim_ifp) {
3549 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3550 return CMD_WARNING;
3551 }
3552
5cee71fb 3553 pim_ifp->pim_hello_period = strtol(argv[0], NULL, 10);
7960fa8f
DS
3554
3555 if (argc == 2)
5cee71fb 3556 pim_ifp->pim_default_holdtime = strtol(argv[1], NULL, 10);
7960fa8f
DS
3557
3558 return CMD_SUCCESS;
3559}
3560
3561ALIAS (interface_ip_pim_hello,
3562 interface_ip_pim_hello_hold_cmd,
3563 "ip pim hello <1-180> <1-180>",
3564 IP_STR
3565 PIM_STR
3566 IFACE_PIM_HELLO_STR
3567 IFACE_PIM_HELLO_TIME_STR
3568 IFACE_PIM_HELLO_HOLD_STR)
3569
3570
3571DEFUN (interface_no_ip_pim_hello,
3572 interface_no_ip_pim_hello_cmd,
3573 "no ip pim hello {<1-180> <1-180>}",
3574 NO_STR
3575 IP_STR
3576 PIM_STR
3577 IFACE_PIM_HELLO_STR
3578 IFACE_PIM_HELLO_TIME_STR
3579 IFACE_PIM_HELLO_HOLD_STR)
3580{
3581 struct interface *ifp;
3582 struct pim_interface *pim_ifp;
3583
3584 ifp = vty->index;
3585 pim_ifp = ifp->info;
3586
3587 if (!pim_ifp) {
3588 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3589 return CMD_WARNING;
3590 }
3591
3592 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
3593 pim_ifp->pim_default_holdtime = -1;
3594
3595 return CMD_SUCCESS;
3596}
3597
12e41d03
DL
3598DEFUN (debug_igmp,
3599 debug_igmp_cmd,
3600 "debug igmp",
3601 DEBUG_STR
3602 DEBUG_IGMP_STR)
3603{
3604 PIM_DO_DEBUG_IGMP_EVENTS;
3605 PIM_DO_DEBUG_IGMP_PACKETS;
3606 PIM_DO_DEBUG_IGMP_TRACE;
3607 return CMD_SUCCESS;
3608}
3609
3610DEFUN (no_debug_igmp,
3611 no_debug_igmp_cmd,
3612 "no debug igmp",
3613 NO_STR
3614 DEBUG_STR
3615 DEBUG_IGMP_STR)
3616{
3617 PIM_DONT_DEBUG_IGMP_EVENTS;
3618 PIM_DONT_DEBUG_IGMP_PACKETS;
3619 PIM_DONT_DEBUG_IGMP_TRACE;
3620 return CMD_SUCCESS;
3621}
3622
3623ALIAS (no_debug_igmp,
3624 undebug_igmp_cmd,
3625 "undebug igmp",
3626 UNDEBUG_STR
3627 DEBUG_IGMP_STR)
3628
3629DEFUN (debug_igmp_events,
3630 debug_igmp_events_cmd,
3631 "debug igmp events",
3632 DEBUG_STR
3633 DEBUG_IGMP_STR
3634 DEBUG_IGMP_EVENTS_STR)
3635{
3636 PIM_DO_DEBUG_IGMP_EVENTS;
3637 return CMD_SUCCESS;
3638}
3639
3640DEFUN (no_debug_igmp_events,
3641 no_debug_igmp_events_cmd,
3642 "no debug igmp events",
3643 NO_STR
3644 DEBUG_STR
3645 DEBUG_IGMP_STR
3646 DEBUG_IGMP_EVENTS_STR)
3647{
3648 PIM_DONT_DEBUG_IGMP_EVENTS;
3649 return CMD_SUCCESS;
3650}
3651
3652ALIAS (no_debug_igmp_events,
3653 undebug_igmp_events_cmd,
3654 "undebug igmp events",
3655 UNDEBUG_STR
3656 DEBUG_IGMP_STR
3657 DEBUG_IGMP_EVENTS_STR)
3658
3659DEFUN (debug_igmp_packets,
3660 debug_igmp_packets_cmd,
3661 "debug igmp packets",
3662 DEBUG_STR
3663 DEBUG_IGMP_STR
3664 DEBUG_IGMP_PACKETS_STR)
3665{
3666 PIM_DO_DEBUG_IGMP_PACKETS;
3667 return CMD_SUCCESS;
3668}
3669
3670DEFUN (no_debug_igmp_packets,
3671 no_debug_igmp_packets_cmd,
3672 "no debug igmp packets",
3673 NO_STR
3674 DEBUG_STR
3675 DEBUG_IGMP_STR
3676 DEBUG_IGMP_PACKETS_STR)
3677{
3678 PIM_DONT_DEBUG_IGMP_PACKETS;
3679 return CMD_SUCCESS;
3680}
3681
3682ALIAS (no_debug_igmp_packets,
3683 undebug_igmp_packets_cmd,
3684 "undebug igmp packets",
3685 UNDEBUG_STR
3686 DEBUG_IGMP_STR
3687 DEBUG_IGMP_PACKETS_STR)
3688
3689DEFUN (debug_igmp_trace,
3690 debug_igmp_trace_cmd,
3691 "debug igmp trace",
3692 DEBUG_STR
3693 DEBUG_IGMP_STR
3694 DEBUG_IGMP_TRACE_STR)
3695{
3696 PIM_DO_DEBUG_IGMP_TRACE;
3697 return CMD_SUCCESS;
3698}
3699
3700DEFUN (no_debug_igmp_trace,
3701 no_debug_igmp_trace_cmd,
3702 "no debug igmp trace",
3703 NO_STR
3704 DEBUG_STR
3705 DEBUG_IGMP_STR
3706 DEBUG_IGMP_TRACE_STR)
3707{
3708 PIM_DONT_DEBUG_IGMP_TRACE;
3709 return CMD_SUCCESS;
3710}
3711
3712ALIAS (no_debug_igmp_trace,
3713 undebug_igmp_trace_cmd,
3714 "undebug igmp trace",
3715 UNDEBUG_STR
3716 DEBUG_IGMP_STR
3717 DEBUG_IGMP_TRACE_STR)
3718
3719DEFUN (debug_mroute,
3720 debug_mroute_cmd,
3721 "debug mroute",
3722 DEBUG_STR
3723 DEBUG_MROUTE_STR)
3724{
3725 PIM_DO_DEBUG_MROUTE;
3726 return CMD_SUCCESS;
3727}
3728
3729DEFUN (no_debug_mroute,
3730 no_debug_mroute_cmd,
3731 "no debug mroute",
3732 NO_STR
3733 DEBUG_STR
3734 DEBUG_MROUTE_STR)
3735{
3736 PIM_DONT_DEBUG_MROUTE;
3737 return CMD_SUCCESS;
3738}
3739
3740ALIAS (no_debug_mroute,
3741 undebug_mroute_cmd,
3742 "undebug mroute",
3743 UNDEBUG_STR
3744 DEBUG_MROUTE_STR)
3745
6250610a
JAG
3746DEFUN (debug_static,
3747 debug_static_cmd,
3748 "debug static",
3749 DEBUG_STR
3750 DEBUG_STATIC_STR)
3751{
3752 PIM_DO_DEBUG_STATIC;
3753 return CMD_SUCCESS;
3754}
3755
3756DEFUN (no_debug_static,
3757 no_debug_static_cmd,
3758 "no debug static",
3759 NO_STR
3760 DEBUG_STR
3761 DEBUG_STATIC_STR)
3762{
3763 PIM_DONT_DEBUG_STATIC;
3764 return CMD_SUCCESS;
3765}
3766
3767ALIAS (no_debug_static,
3768 undebug_static_cmd,
3769 "undebug static",
3770 UNDEBUG_STR
3771 DEBUG_STATIC_STR)
3772
12e41d03
DL
3773DEFUN (debug_pim,
3774 debug_pim_cmd,
3775 "debug pim",
3776 DEBUG_STR
3777 DEBUG_PIM_STR)
3778{
3779 PIM_DO_DEBUG_PIM_EVENTS;
3780 PIM_DO_DEBUG_PIM_PACKETS;
3781 PIM_DO_DEBUG_PIM_TRACE;
3782 return CMD_SUCCESS;
3783}
3784
3785DEFUN (no_debug_pim,
3786 no_debug_pim_cmd,
3787 "no debug pim",
3788 NO_STR
3789 DEBUG_STR
3790 DEBUG_PIM_STR)
3791{
3792 PIM_DONT_DEBUG_PIM_EVENTS;
3793 PIM_DONT_DEBUG_PIM_PACKETS;
3794 PIM_DONT_DEBUG_PIM_TRACE;
3795
3796 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3797 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3798
3799 return CMD_SUCCESS;
3800}
3801
3802ALIAS (no_debug_pim,
3803 undebug_pim_cmd,
3804 "undebug pim",
3805 UNDEBUG_STR
3806 DEBUG_PIM_STR)
3807
3808DEFUN (debug_pim_events,
3809 debug_pim_events_cmd,
3810 "debug pim events",
3811 DEBUG_STR
3812 DEBUG_PIM_STR
3813 DEBUG_PIM_EVENTS_STR)
3814{
3815 PIM_DO_DEBUG_PIM_EVENTS;
3816 return CMD_SUCCESS;
3817}
3818
3819DEFUN (no_debug_pim_events,
3820 no_debug_pim_events_cmd,
3821 "no debug pim events",
3822 NO_STR
3823 DEBUG_STR
3824 DEBUG_PIM_STR
3825 DEBUG_PIM_EVENTS_STR)
3826{
3827 PIM_DONT_DEBUG_PIM_EVENTS;
3828 return CMD_SUCCESS;
3829}
3830
3831ALIAS (no_debug_pim_events,
3832 undebug_pim_events_cmd,
3833 "undebug pim events",
3834 UNDEBUG_STR
3835 DEBUG_PIM_STR
3836 DEBUG_PIM_EVENTS_STR)
3837
3838DEFUN (debug_pim_packets,
3839 debug_pim_packets_cmd,
3840 "debug pim packets",
3841 DEBUG_STR
3842 DEBUG_PIM_STR
3843 DEBUG_PIM_PACKETS_STR)
3844{
3845 PIM_DO_DEBUG_PIM_PACKETS;
3846 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
3847 return CMD_SUCCESS;
3848}
3849
3850DEFUN (debug_pim_packets_filter,
3851 debug_pim_packets_filter_cmd,
3852 "debug pim packets (hello|joins)",
3853 DEBUG_STR
3854 DEBUG_PIM_STR
3855 DEBUG_PIM_PACKETS_STR
3856 DEBUG_PIM_HELLO_PACKETS_STR
3857 DEBUG_PIM_J_P_PACKETS_STR)
3858{
5cee71fb 3859 if (strncmp(argv[0],"h",1) == 0)
12e41d03
DL
3860 {
3861 PIM_DO_DEBUG_PIM_HELLO;
3862 vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
3863 }
5cee71fb 3864 else if (strncmp(argv[0],"j",1) == 0)
12e41d03
DL
3865 {
3866 PIM_DO_DEBUG_PIM_J_P;
3867 vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
3868 }
3869 return CMD_SUCCESS;
3870}
3871
3872DEFUN (no_debug_pim_packets,
3873 no_debug_pim_packets_cmd,
3874 "no debug pim packets",
3875 NO_STR
3876 DEBUG_STR
3877 DEBUG_PIM_STR
3878 DEBUG_PIM_PACKETS_STR
3879 DEBUG_PIM_HELLO_PACKETS_STR
3880 DEBUG_PIM_J_P_PACKETS_STR)
3881{
3882 PIM_DONT_DEBUG_PIM_PACKETS;
3883 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
3884 return CMD_SUCCESS;
3885}
3886
3887DEFUN (no_debug_pim_packets_filter,
3888 no_debug_pim_packets_filter_cmd,
3889 "no debug pim packets (hello|joins)",
3890 NO_STR
3891 DEBUG_STR
3892 DEBUG_PIM_STR
3893 DEBUG_PIM_PACKETS_STR
3894 DEBUG_PIM_HELLO_PACKETS_STR
3895 DEBUG_PIM_J_P_PACKETS_STR)
3896{
5cee71fb 3897 if (strncmp(argv[0],"h",1) == 0)
12e41d03
DL
3898 {
3899 PIM_DONT_DEBUG_PIM_HELLO;
3900 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
3901 }
5cee71fb 3902 else if (strncmp(argv[0],"j",1) == 0)
12e41d03
DL
3903 {
3904 PIM_DONT_DEBUG_PIM_J_P;
3905 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
3906 }
3907 return CMD_SUCCESS;
3908}
3909
3910ALIAS (no_debug_pim_packets,
3911 undebug_pim_packets_cmd,
3912 "undebug pim packets",
3913 UNDEBUG_STR
3914 DEBUG_PIM_STR
3915 DEBUG_PIM_PACKETS_STR)
3916
3917DEFUN (debug_pim_packetdump_send,
3918 debug_pim_packetdump_send_cmd,
3919 "debug pim packet-dump send",
3920 DEBUG_STR
3921 DEBUG_PIM_STR
3922 DEBUG_PIM_PACKETDUMP_STR
3923 DEBUG_PIM_PACKETDUMP_SEND_STR)
3924{
3925 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
3926 return CMD_SUCCESS;
3927}
3928
3929DEFUN (no_debug_pim_packetdump_send,
3930 no_debug_pim_packetdump_send_cmd,
3931 "no debug pim packet-dump send",
3932 NO_STR
3933 DEBUG_STR
3934 DEBUG_PIM_STR
3935 DEBUG_PIM_PACKETDUMP_STR
3936 DEBUG_PIM_PACKETDUMP_SEND_STR)
3937{
3938 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3939 return CMD_SUCCESS;
3940}
3941
3942ALIAS (no_debug_pim_packetdump_send,
3943 undebug_pim_packetdump_send_cmd,
3944 "undebug pim packet-dump send",
3945 UNDEBUG_STR
3946 DEBUG_PIM_STR
3947 DEBUG_PIM_PACKETDUMP_STR
3948 DEBUG_PIM_PACKETDUMP_SEND_STR)
3949
3950DEFUN (debug_pim_packetdump_recv,
3951 debug_pim_packetdump_recv_cmd,
3952 "debug pim packet-dump receive",
3953 DEBUG_STR
3954 DEBUG_PIM_STR
3955 DEBUG_PIM_PACKETDUMP_STR
3956 DEBUG_PIM_PACKETDUMP_RECV_STR)
3957{
3958 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
3959 return CMD_SUCCESS;
3960}
3961
3962DEFUN (no_debug_pim_packetdump_recv,
3963 no_debug_pim_packetdump_recv_cmd,
3964 "no debug pim packet-dump receive",
3965 NO_STR
3966 DEBUG_STR
3967 DEBUG_PIM_STR
3968 DEBUG_PIM_PACKETDUMP_STR
3969 DEBUG_PIM_PACKETDUMP_RECV_STR)
3970{
3971 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3972 return CMD_SUCCESS;
3973}
3974
3975ALIAS (no_debug_pim_packetdump_recv,
3976 undebug_pim_packetdump_recv_cmd,
3977 "undebug pim packet-dump receive",
3978 UNDEBUG_STR
3979 DEBUG_PIM_STR
3980 DEBUG_PIM_PACKETDUMP_STR
3981 DEBUG_PIM_PACKETDUMP_RECV_STR)
3982
3983DEFUN (debug_pim_trace,
3984 debug_pim_trace_cmd,
3985 "debug pim trace",
3986 DEBUG_STR
3987 DEBUG_PIM_STR
3988 DEBUG_PIM_TRACE_STR)
3989{
3990 PIM_DO_DEBUG_PIM_TRACE;
3991 return CMD_SUCCESS;
3992}
3993
3994DEFUN (no_debug_pim_trace,
3995 no_debug_pim_trace_cmd,
3996 "no debug pim trace",
3997 NO_STR
3998 DEBUG_STR
3999 DEBUG_PIM_STR
4000 DEBUG_PIM_TRACE_STR)
4001{
4002 PIM_DONT_DEBUG_PIM_TRACE;
4003 return CMD_SUCCESS;
4004}
4005
4006ALIAS (no_debug_pim_trace,
4007 undebug_pim_trace_cmd,
4008 "undebug pim trace",
4009 UNDEBUG_STR
4010 DEBUG_PIM_STR
4011 DEBUG_PIM_TRACE_STR)
4012
4013DEFUN (debug_ssmpingd,
4014 debug_ssmpingd_cmd,
4015 "debug ssmpingd",
4016 DEBUG_STR
4017 DEBUG_PIM_STR
4018 DEBUG_SSMPINGD_STR)
4019{
4020 PIM_DO_DEBUG_SSMPINGD;
4021 return CMD_SUCCESS;
4022}
4023
4024DEFUN (no_debug_ssmpingd,
4025 no_debug_ssmpingd_cmd,
4026 "no debug ssmpingd",
4027 NO_STR
4028 DEBUG_STR
4029 DEBUG_PIM_STR
4030 DEBUG_SSMPINGD_STR)
4031{
4032 PIM_DONT_DEBUG_SSMPINGD;
4033 return CMD_SUCCESS;
4034}
4035
4036ALIAS (no_debug_ssmpingd,
4037 undebug_ssmpingd_cmd,
4038 "undebug ssmpingd",
4039 UNDEBUG_STR
4040 DEBUG_PIM_STR
4041 DEBUG_SSMPINGD_STR)
4042
4043DEFUN (debug_pim_zebra,
4044 debug_pim_zebra_cmd,
4045 "debug pim zebra",
4046 DEBUG_STR
4047 DEBUG_PIM_STR
4048 DEBUG_PIM_ZEBRA_STR)
4049{
4050 PIM_DO_DEBUG_ZEBRA;
4051 return CMD_SUCCESS;
4052}
4053
4054DEFUN (no_debug_pim_zebra,
4055 no_debug_pim_zebra_cmd,
4056 "no debug pim zebra",
4057 NO_STR
4058 DEBUG_STR
4059 DEBUG_PIM_STR
4060 DEBUG_PIM_ZEBRA_STR)
4061{
4062 PIM_DONT_DEBUG_ZEBRA;
4063 return CMD_SUCCESS;
4064}
4065
4066ALIAS (no_debug_pim_zebra,
4067 undebug_pim_zebra_cmd,
4068 "undebug pim zebra",
4069 UNDEBUG_STR
4070 DEBUG_PIM_STR
4071 DEBUG_PIM_ZEBRA_STR)
4072
7a1d58ce
DS
4073DEFUN (show_debugging_pim,
4074 show_debugging_pim_cmd,
4075 "show debugging pim",
12e41d03 4076 SHOW_STR
7a1d58ce
DS
4077 DEBUG_STR
4078 PIM_STR)
12e41d03
DL
4079{
4080 pim_debug_config_write(vty);
4081 return CMD_SUCCESS;
4082}
4083
4084static struct igmp_sock *find_igmp_sock_by_fd(int fd)
4085{
4086 struct listnode *ifnode;
4087 struct interface *ifp;
4088
4089 /* scan all interfaces */
469351b3 4090 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
4091 struct pim_interface *pim_ifp;
4092 struct igmp_sock *igmp;
4093
4094 if (!ifp->info)
4095 continue;
4096
4097 pim_ifp = ifp->info;
4098
4099 /* lookup igmp socket under current interface */
4100 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
4101 if (igmp)
4102 return igmp;
4103 }
4104
4105 return 0;
4106}
4107
4108DEFUN (test_igmp_receive_report,
4109 test_igmp_receive_report_cmd,
4110 "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
4111 "Test\n"
4112 "Test IGMP protocol\n"
4113 "Test IGMP message\n"
4114 "Test IGMP report\n"
4115 "Socket\n"
4116 "IGMP group address\n"
4117 "Record type\n"
4118 "Sources\n")
4119{
4120 char buf[1000];
4121 char *igmp_msg;
4122 struct ip *ip_hdr;
4123 size_t ip_hlen; /* ip header length in bytes */
4124 int ip_msg_len;
4125 int igmp_msg_len;
4126 const char *socket;
4127 int socket_fd;
4128 const char *grp_str;
4129 struct in_addr grp_addr;
4130 const char *record_type_str;
4131 int record_type;
4132 const char *src_str;
4133 int result;
4134 struct igmp_sock *igmp;
4135 char *group_record;
4136 int num_sources;
4137 struct in_addr *sources;
4138 struct in_addr *src_addr;
4139 int argi;
4140
5cee71fb 4141 socket = argv[0];
12e41d03
DL
4142 socket_fd = atoi(socket);
4143 igmp = find_igmp_sock_by_fd(socket_fd);
4144 if (!igmp) {
4145 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
4146 socket, socket_fd, VTY_NEWLINE);
4147 return CMD_WARNING;
4148 }
4149
5cee71fb 4150 grp_str = argv[1];
12e41d03
DL
4151 result = inet_pton(AF_INET, grp_str, &grp_addr);
4152 if (result <= 0) {
4153 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4154 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4155 return CMD_WARNING;
4156 }
4157
5cee71fb 4158 record_type_str = argv[2];
12e41d03
DL
4159 record_type = atoi(record_type_str);
4160
4161 /*
4162 Tweak IP header
4163 */
4164 ip_hdr = (struct ip *) buf;
4165 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
4166 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4167 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4168 ip_hdr->ip_src = igmp->ifaddr;
4169 ip_hdr->ip_dst = igmp->ifaddr;
4170
4171 /*
4172 Build IGMP v3 report message
4173 */
4174 igmp_msg = buf + ip_hlen;
4175 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
4176 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
4177 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
4178 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
4179 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
4180 memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
4181
4182 /* Scan LINE sources */
4183 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
4184 src_addr = sources;
4185 for (argi = 3; argi < argc; ++argi,++src_addr) {
5cee71fb 4186 src_str = argv[argi];
12e41d03
DL
4187 result = inet_pton(AF_INET, src_str, src_addr);
4188 if (result <= 0) {
4189 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4190 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4191 return CMD_WARNING;
4192 }
4193 }
4194 num_sources = src_addr - sources;
4195
4196 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
4197
4198 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
4199
4200 /* compute checksum */
4201 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
4202
4203 /* "receive" message */
4204
4205 ip_msg_len = ip_hlen + igmp_msg_len;
4206 result = pim_igmp_packet(igmp, buf, ip_msg_len);
4207 if (result) {
4208 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
4209 ip_msg_len, result, VTY_NEWLINE);
4210 return CMD_WARNING;
4211 }
4212
4213 return CMD_SUCCESS;
4214}
4215
4216static int hexval(uint8_t ch)
4217{
4218 return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
4219}
4220
4221DEFUN (test_pim_receive_dump,
4222 test_pim_receive_dump_cmd,
4223 "test pim receive dump INTERFACE A.B.C.D .LINE",
4224 "Test\n"
4225 "Test PIM protocol\n"
4226 "Test PIM message reception\n"
4227 "Test PIM packet dump reception from neighbor\n"
4228 "Interface\n"
4229 "Neighbor address\n"
4230 "Packet dump\n")
4231{
4232 uint8_t buf[1000];
4233 uint8_t *pim_msg;
4234 struct ip *ip_hdr;
4235 size_t ip_hlen; /* ip header length in bytes */
4236 int ip_msg_len;
4237 int pim_msg_size;
4238 const char *neigh_str;
4239 struct in_addr neigh_addr;
4240 const char *ifname;
4241 struct interface *ifp;
4242 int argi;
4243 int result;
4244
4245 /* Find interface */
5cee71fb 4246 ifname = argv[0];
12e41d03
DL
4247 ifp = if_lookup_by_name(ifname);
4248 if (!ifp) {
4249 vty_out(vty, "No such interface name %s%s",
4250 ifname, VTY_NEWLINE);
4251 return CMD_WARNING;
4252 }
4253
4254 /* Neighbor address */
5cee71fb 4255 neigh_str = argv[1];
12e41d03
DL
4256 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4257 if (result <= 0) {
4258 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4259 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4260 return CMD_WARNING;
4261 }
4262
4263 /*
4264 Tweak IP header
4265 */
4266 ip_hdr = (struct ip *) buf;
4267 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4268 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4269 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4270 ip_hdr->ip_src = neigh_addr;
4271 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4272
4273 /*
4274 Build PIM hello message
4275 */
4276 pim_msg = buf + ip_hlen;
4277 pim_msg_size = 0;
4278
4279 /* Scan LINE dump into buffer */
4280 for (argi = 2; argi < argc; ++argi) {
5cee71fb 4281 const char *str = argv[argi];
12e41d03
DL
4282 int str_len = strlen(str);
4283 int str_last = str_len - 1;
4284 int i;
4285
4286 if (str_len % 2) {
4287 vty_out(vty, "%% Uneven hex array arg %d=%s%s",
4288 argi, str, VTY_NEWLINE);
4289 return CMD_WARNING;
4290 }
4291
4292 for (i = 0; i < str_last; i += 2) {
4293 uint8_t octet;
4294 int left;
4295 uint8_t h1 = str[i];
4296 uint8_t h2 = str[i + 1];
4297
4298 if (!isxdigit(h1) || !isxdigit(h2)) {
4299 vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
4300 h1, h2, argi, str, VTY_NEWLINE);
4301 return CMD_WARNING;
4302 }
4303 octet = (hexval(h1) << 4) + hexval(h2);
4304
4305 left = sizeof(buf) - ip_hlen - pim_msg_size;
4306 if (left < 1) {
4307 vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
4308 sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
4309 return CMD_WARNING;
4310 }
4311
4312 pim_msg[pim_msg_size++] = octet;
4313 }
4314 }
4315
4316 ip_msg_len = ip_hlen + pim_msg_size;
4317
4318 vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
4319 sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
4320
4321 /* "receive" message */
4322
4323 result = pim_pim_packet(ifp, buf, ip_msg_len);
4324 if (result) {
4325 vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
4326 ip_msg_len, result, VTY_NEWLINE);
4327 return CMD_WARNING;
4328 }
4329
4330 return CMD_SUCCESS;
4331}
4332
4333DEFUN (test_pim_receive_hello,
4334 test_pim_receive_hello_cmd,
4335 "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
4336 "Test\n"
4337 "Test PIM protocol\n"
4338 "Test PIM message reception\n"
4339 "Test PIM hello reception from neighbor\n"
4340 "Interface\n"
4341 "Neighbor address\n"
4342 "Neighbor holdtime\n"
4343 "Neighbor DR priority\n"
4344 "Neighbor generation ID\n"
4345 "Neighbor propagation delay (msec)\n"
4346 "Neighbor override interval (msec)\n"
4347 "Neighbor LAN prune delay T-bit\n"
4348 "Neighbor secondary addresses\n")
4349{
4350 uint8_t buf[1000];
4351 uint8_t *pim_msg;
4352 struct ip *ip_hdr;
4353 size_t ip_hlen; /* ip header length in bytes */
4354 int ip_msg_len;
4355 int pim_tlv_size;
4356 int pim_msg_size;
4357 const char *neigh_str;
4358 struct in_addr neigh_addr;
4359 const char *ifname;
4360 struct interface *ifp;
4361 uint16_t neigh_holdtime;
4362 uint16_t neigh_propagation_delay;
4363 uint16_t neigh_override_interval;
4364 int neigh_can_disable_join_suppression;
4365 uint32_t neigh_dr_priority;
4366 uint32_t neigh_generation_id;
4367 int argi;
4368 int result;
4369
4370 /* Find interface */
5cee71fb 4371 ifname = argv[0];
12e41d03
DL
4372 ifp = if_lookup_by_name(ifname);
4373 if (!ifp) {
4374 vty_out(vty, "No such interface name %s%s",
4375 ifname, VTY_NEWLINE);
4376 return CMD_WARNING;
4377 }
4378
4379 /* Neighbor address */
5cee71fb 4380 neigh_str = argv[1];
12e41d03
DL
4381 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4382 if (result <= 0) {
4383 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4384 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4385 return CMD_WARNING;
4386 }
4387
5cee71fb
DW
4388 neigh_holdtime = atoi(argv[2]);
4389 neigh_dr_priority = atoi(argv[3]);
4390 neigh_generation_id = atoi(argv[4]);
4391 neigh_propagation_delay = atoi(argv[5]);
4392 neigh_override_interval = atoi(argv[6]);
4393 neigh_can_disable_join_suppression = atoi(argv[7]);
12e41d03
DL
4394
4395 /*
4396 Tweak IP header
4397 */
4398 ip_hdr = (struct ip *) buf;
4399 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4400 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4401 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4402 ip_hdr->ip_src = neigh_addr;
4403 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4404
4405 /*
4406 Build PIM hello message
4407 */
4408 pim_msg = buf + ip_hlen;
4409
4410 /* Scan LINE addresses */
4411 for (argi = 8; argi < argc; ++argi) {
5cee71fb 4412 const char *sec_str = argv[argi];
12e41d03
DL
4413 struct in_addr sec_addr;
4414 result = inet_pton(AF_INET, sec_str, &sec_addr);
4415 if (result <= 0) {
4416 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
4417 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
4418 return CMD_WARNING;
4419 }
4420
4421 vty_out(vty,
4422 "FIXME WRITEME consider neighbor secondary address %s%s",
4423 sec_str, VTY_NEWLINE);
4424 }
4425
4426 pim_tlv_size = pim_hello_build_tlv(ifp->name,
4427 pim_msg + PIM_PIM_MIN_LEN,
4428 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
4429 neigh_holdtime,
4430 neigh_dr_priority,
4431 neigh_generation_id,
4432 neigh_propagation_delay,
4433 neigh_override_interval,
4434 neigh_can_disable_join_suppression,
4435 0 /* FIXME secondary address list */);
4436 if (pim_tlv_size < 0) {
4437 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
4438 pim_tlv_size, VTY_NEWLINE);
4439 return CMD_WARNING;
4440 }
4441
4442 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
4443
4444 pim_msg_build_header(pim_msg, pim_msg_size,
4445 PIM_MSG_TYPE_HELLO);
4446
4447 /* "receive" message */
4448
4449 ip_msg_len = ip_hlen + pim_msg_size;
4450 result = pim_pim_packet(ifp, buf, ip_msg_len);
4451 if (result) {
4452 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4453 ip_msg_len, result, VTY_NEWLINE);
4454 return CMD_WARNING;
4455 }
4456
4457 return CMD_SUCCESS;
4458}
4459
4460DEFUN (test_pim_receive_assert,
4461 test_pim_receive_assert_cmd,
4462 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
4463 "Test\n"
4464 "Test PIM protocol\n"
4465 "Test PIM message reception\n"
4466 "Test reception of PIM assert\n"
4467 "Interface\n"
4468 "Neighbor address\n"
4469 "Assert multicast group address\n"
4470 "Assert unicast source address\n"
4471 "Assert metric preference\n"
4472 "Assert route metric\n"
4473 "Assert RPT bit flag\n")
4474{
4475 uint8_t buf[1000];
4476 uint8_t *buf_pastend = buf + sizeof(buf);
4477 uint8_t *pim_msg;
4478 struct ip *ip_hdr;
4479 size_t ip_hlen; /* ip header length in bytes */
4480 int ip_msg_len;
4481 int pim_msg_size;
4482 const char *neigh_str;
4483 struct in_addr neigh_addr;
4484 const char *group_str;
4485 struct in_addr group_addr;
4486 const char *source_str;
4487 struct in_addr source_addr;
4488 const char *ifname;
4489 struct interface *ifp;
4490 uint32_t assert_metric_preference;
4491 uint32_t assert_route_metric;
4492 uint32_t assert_rpt_bit_flag;
4493 int remain;
4494 int result;
4495
4496 /* Find interface */
5cee71fb 4497 ifname = argv[0];
12e41d03
DL
4498 ifp = if_lookup_by_name(ifname);
4499 if (!ifp) {
4500 vty_out(vty, "No such interface name %s%s",
4501 ifname, VTY_NEWLINE);
4502 return CMD_WARNING;
4503 }
4504
4505 /* Neighbor address */
5cee71fb 4506 neigh_str = argv[1];
12e41d03
DL
4507 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4508 if (result <= 0) {
4509 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4510 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4511 return CMD_WARNING;
4512 }
4513
4514 /* Group address */
5cee71fb 4515 group_str = argv[2];
12e41d03
DL
4516 result = inet_pton(AF_INET, group_str, &group_addr);
4517 if (result <= 0) {
4518 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4519 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4520 return CMD_WARNING;
4521 }
4522
4523 /* Source address */
5cee71fb 4524 source_str = argv[3];
12e41d03
DL
4525 result = inet_pton(AF_INET, source_str, &source_addr);
4526 if (result <= 0) {
4527 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4528 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4529 return CMD_WARNING;
4530 }
4531
5cee71fb
DW
4532 assert_metric_preference = atoi(argv[4]);
4533 assert_route_metric = atoi(argv[5]);
4534 assert_rpt_bit_flag = atoi(argv[6]);
12e41d03
DL
4535
4536 remain = buf_pastend - buf;
4537 if (remain < (int) sizeof(struct ip)) {
4538 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
4539 remain, sizeof(struct ip), VTY_NEWLINE);
4540 return CMD_WARNING;
4541 }
4542
4543 /*
4544 Tweak IP header
4545 */
4546 ip_hdr = (struct ip *) buf;
4547 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4548 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4549 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4550 ip_hdr->ip_src = neigh_addr;
4551 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4552
4553 /*
4554 Build PIM assert message
4555 */
4556 pim_msg = buf + ip_hlen; /* skip ip header */
4557
4558 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
4559 group_addr, source_addr,
4560 assert_metric_preference,
4561 assert_route_metric,
4562 assert_rpt_bit_flag);
4563 if (pim_msg_size < 0) {
4564 vty_out(vty, "Failure building PIM assert message: size=%d%s",
4565 pim_msg_size, VTY_NEWLINE);
4566 return CMD_WARNING;
4567 }
4568
4569 /* "receive" message */
4570
4571 ip_msg_len = ip_hlen + pim_msg_size;
4572 result = pim_pim_packet(ifp, buf, ip_msg_len);
4573 if (result) {
4574 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4575 ip_msg_len, result, VTY_NEWLINE);
4576 return CMD_WARNING;
4577 }
4578
4579 return CMD_SUCCESS;
4580}
4581
4582static int recv_joinprune(struct vty *vty,
5cee71fb 4583 const char *argv[],
12e41d03
DL
4584 int src_is_join)
4585{
4586 uint8_t buf[1000];
4587 const uint8_t *buf_pastend = buf + sizeof(buf);
4588 uint8_t *pim_msg;
4589 uint8_t *pim_msg_curr;
4590 int pim_msg_size;
4591 struct ip *ip_hdr;
4592 size_t ip_hlen; /* ip header length in bytes */
4593 int ip_msg_len;
4594 uint16_t neigh_holdtime;
4595 const char *neigh_dst_str;
4596 struct in_addr neigh_dst_addr;
4597 const char *neigh_src_str;
4598 struct in_addr neigh_src_addr;
4599 const char *group_str;
4600 struct in_addr group_addr;
4601 const char *source_str;
4602 struct in_addr source_addr;
4603 const char *ifname;
4604 struct interface *ifp;
4605 int result;
4606 int remain;
4607 uint16_t num_joined;
4608 uint16_t num_pruned;
4609
4610 /* Find interface */
5cee71fb 4611 ifname = argv[0];
12e41d03
DL
4612 ifp = if_lookup_by_name(ifname);
4613 if (!ifp) {
4614 vty_out(vty, "No such interface name %s%s",
4615 ifname, VTY_NEWLINE);
4616 return CMD_WARNING;
4617 }
4618
5cee71fb 4619 neigh_holdtime = atoi(argv[1]);
12e41d03
DL
4620
4621 /* Neighbor destination address */
5cee71fb 4622 neigh_dst_str = argv[2];
12e41d03
DL
4623 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
4624 if (result <= 0) {
4625 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
4626 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
4627 return CMD_WARNING;
4628 }
4629
4630 /* Neighbor source address */
5cee71fb 4631 neigh_src_str = argv[3];
12e41d03
DL
4632 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
4633 if (result <= 0) {
4634 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
4635 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4636 return CMD_WARNING;
4637 }
4638
4639 /* Multicast group address */
5cee71fb 4640 group_str = argv[4];
12e41d03
DL
4641 result = inet_pton(AF_INET, group_str, &group_addr);
4642 if (result <= 0) {
4643 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4644 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4645 return CMD_WARNING;
4646 }
4647
4648 /* Multicast source address */
5cee71fb 4649 source_str = argv[5];
12e41d03
DL
4650 result = inet_pton(AF_INET, source_str, &source_addr);
4651 if (result <= 0) {
4652 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4653 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4654 return CMD_WARNING;
4655 }
4656
4657 /*
4658 Tweak IP header
4659 */
4660 ip_hdr = (struct ip *) buf;
4661 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4662 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4663 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4664 ip_hdr->ip_src = neigh_src_addr;
4665 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4666
4667 /*
4668 Build PIM message
4669 */
4670 pim_msg = buf + ip_hlen;
4671
4672 /* skip room for pim header */
4673 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
4674
4675 remain = buf_pastend - pim_msg_curr;
4676 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
4677 remain,
4678 neigh_dst_addr);
4679 if (!pim_msg_curr) {
4680 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
4681 neigh_dst_str, remain, VTY_NEWLINE);
4682 return CMD_WARNING;
4683 }
4684
4685 remain = buf_pastend - pim_msg_curr;
4686 if (remain < 4) {
4687 vty_out(vty, "Group will not fit: space left=%d%s",
4688 remain, VTY_NEWLINE);
4689 return CMD_WARNING;
4690 }
4691
4692 *pim_msg_curr = 0; /* reserved */
4693 ++pim_msg_curr;
4694 *pim_msg_curr = 1; /* number of groups */
4695 ++pim_msg_curr;
4696 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
4697 ++pim_msg_curr;
4698 ++pim_msg_curr;
4699
4700 remain = buf_pastend - pim_msg_curr;
4701 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
4702 remain,
4703 group_addr);
4704 if (!pim_msg_curr) {
4705 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
4706 group_str, remain, VTY_NEWLINE);
4707 return CMD_WARNING;
4708 }
4709
4710 remain = buf_pastend - pim_msg_curr;
4711 if (remain < 4) {
4712 vty_out(vty, "Sources will not fit: space left=%d%s",
4713 remain, VTY_NEWLINE);
4714 return CMD_WARNING;
4715 }
4716
4717 if (src_is_join) {
4718 num_joined = 1;
4719 num_pruned = 0;
4720 }
4721 else {
4722 num_joined = 0;
4723 num_pruned = 1;
4724 }
4725
4726 /* number of joined sources */
4727 *((uint16_t *) pim_msg_curr) = htons(num_joined);
4728 ++pim_msg_curr;
4729 ++pim_msg_curr;
4730
4731 /* number of pruned sources */
4732 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
4733 ++pim_msg_curr;
4734 ++pim_msg_curr;
4735
4736 remain = buf_pastend - pim_msg_curr;
4737 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
4738 remain,
4739 source_addr);
4740 if (!pim_msg_curr) {
4741 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
4742 source_str, remain, VTY_NEWLINE);
4743 return CMD_WARNING;
4744 }
4745
4746 /* Add PIM header */
4747
4748 pim_msg_size = pim_msg_curr - pim_msg;
4749
4750 pim_msg_build_header(pim_msg, pim_msg_size,
4751 PIM_MSG_TYPE_JOIN_PRUNE);
4752
4753 /*
4754 "Receive" message
4755 */
4756
4757 ip_msg_len = ip_hlen + pim_msg_size;
4758 result = pim_pim_packet(ifp, buf, ip_msg_len);
4759 if (result) {
4760 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4761 ip_msg_len, result, VTY_NEWLINE);
4762 return CMD_WARNING;
4763 }
4764
4765 return CMD_SUCCESS;
4766}
4767
4768DEFUN (test_pim_receive_join,
4769 test_pim_receive_join_cmd,
4770 "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4771 "Test\n"
4772 "Test PIM protocol\n"
4773 "Test PIM message reception\n"
4774 "Test PIM join reception from neighbor\n"
4775 "Interface\n"
4776 "Neighbor holdtime\n"
4777 "Upstream neighbor unicast destination address\n"
4778 "Downstream neighbor unicast source address\n"
4779 "Multicast group address\n"
4780 "Unicast source address\n")
4781{
4782 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
4783}
4784
4785DEFUN (test_pim_receive_prune,
4786 test_pim_receive_prune_cmd,
4787 "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4788 "Test\n"
4789 "Test PIM protocol\n"
4790 "Test PIM message reception\n"
4791 "Test PIM prune reception from neighbor\n"
4792 "Interface\n"
4793 "Neighbor holdtime\n"
4794 "Upstream neighbor unicast destination address\n"
4795 "Downstream neighbor unicast source address\n"
4796 "Multicast group address\n"
4797 "Unicast source address\n")
4798{
4799 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
4800}
4801
4802DEFUN (test_pim_receive_upcall,
4803 test_pim_receive_upcall_cmd,
4804 "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
4805 "Test\n"
4806 "Test PIM protocol\n"
4807 "Test PIM message reception\n"
4808 "Test reception of kernel upcall\n"
4809 "NOCACHE kernel upcall\n"
4810 "WRONGVIF kernel upcall\n"
4811 "WHOLEPKT kernel upcall\n"
4812 "Input interface vif index\n"
4813 "Multicast group address\n"
4814 "Multicast source address\n")
4815{
4816 struct igmpmsg msg;
4817 const char *upcall_type;
4818 const char *group_str;
4819 const char *source_str;
4820 int result;
4821
5cee71fb 4822 upcall_type = argv[0];
12e41d03
DL
4823
4824 if (upcall_type[0] == 'n')
4825 msg.im_msgtype = IGMPMSG_NOCACHE;
4826 else if (upcall_type[1] == 'r')
4827 msg.im_msgtype = IGMPMSG_WRONGVIF;
4828 else if (upcall_type[1] == 'h')
4829 msg.im_msgtype = IGMPMSG_WHOLEPKT;
4830 else {
4831 vty_out(vty, "Unknown kernel upcall type: %s%s",
4832 upcall_type, VTY_NEWLINE);
4833 return CMD_WARNING;
4834 }
4835
5cee71fb 4836 msg.im_vif = atoi(argv[1]);
12e41d03
DL
4837
4838 /* Group address */
5cee71fb 4839 group_str = argv[2];
12e41d03
DL
4840 result = inet_pton(AF_INET, group_str, &msg.im_dst);
4841 if (result <= 0) {
4842 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4843 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4844 return CMD_WARNING;
4845 }
4846
4847 /* Source address */
5cee71fb 4848 source_str = argv[3];
12e41d03
DL
4849 result = inet_pton(AF_INET, source_str, &msg.im_src);
4850 if (result <= 0) {
4851 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4852 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4853 return CMD_WARNING;
4854 }
4855
4856 msg.im_mbz = 0; /* Must be zero */
4857
4858 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
4859 if (result) {
4860 vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
4861 sizeof(msg), result, VTY_NEWLINE);
4862 return CMD_WARNING;
4863 }
4864
4865 return CMD_SUCCESS;
4866}
4867
4868void pim_cmd_init()
4869{
4870 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
4871 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
4872
4873 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
4874 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
981d6c7a
DS
4875 install_element (CONFIG_NODE, &ip_pim_rp_cmd);
4876 install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
12e41d03
DL
4877 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
4878 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
4879#if 0
4880 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
4881#else
4882 install_element (CONFIG_NODE, &pim_interface_cmd);
4883#endif
4884 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
4885
4886 install_default (INTERFACE_NODE);
4887 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
4888 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
4889 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
4890 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
4891 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
4892 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
4893 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
4894 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
4895 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
4896 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
4897 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
dedccda6 4898 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
981d6c7a 4899 install_element (INTERFACE_NODE, &interface_ip_pim_sm_cmd);
8371bd60 4900 install_element (INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
dedccda6
DS
4901 install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
4902 install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
7960fa8f
DS
4903 install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
4904 install_element (INTERFACE_NODE, &interface_ip_pim_hello_hold_cmd);
4905 install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
12e41d03 4906
6250610a
JAG
4907 // Static mroutes NEB
4908 install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
4909 install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
4910 install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
4911 install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
4912
12e41d03
DL
4913 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
4914 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
4915 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
4916 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
4917 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4918 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
4919 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4920 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
4921 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
4922 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
4923 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
4924 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
4925 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
4926 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
4927 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
4928 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
4929 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
4930 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
4931 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
4932 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
4933 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
4934 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
4935 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
4936 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
4937 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
4938 install_element (VIEW_NODE, &show_ip_multicast_cmd);
4939 install_element (VIEW_NODE, &show_ip_mroute_cmd);
4940 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
4941 install_element (VIEW_NODE, &show_ip_rib_cmd);
4942 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 4943 install_element (VIEW_NODE, &show_debugging_pim_cmd);
12e41d03
DL
4944
4945 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
4946 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
4947 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
4948 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
4949 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
4950
4951 install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
4952 install_element (ENABLE_NODE, &show_ip_igmp_join_cmd);
4953 install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
4954 install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
4955 install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4956 install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
4957 install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4958 install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
4959 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
4960 install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
4961 install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
4962 install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
4963 install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
4964 install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
4965 install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
4966 install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
4967 install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
4968 install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
4969 install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
4970 install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
4971 install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
4972 install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
4973 install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
4974 install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
4975 install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
4976 install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
4977 install_element (ENABLE_NODE, &show_ip_multicast_cmd);
4978 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
4979 install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
4980 install_element (ENABLE_NODE, &show_ip_rib_cmd);
4981 install_element (ENABLE_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 4982 install_element (ENABLE_NODE, &show_debugging_pim_cmd);
12e41d03
DL
4983
4984 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
4985 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
4986 install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
4987 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
4988 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
4989 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
4990 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
4991
4992 install_element (ENABLE_NODE, &debug_igmp_cmd);
4993 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
4994 install_element (ENABLE_NODE, &undebug_igmp_cmd);
4995 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
4996 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
4997 install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
4998 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
4999 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
5000 install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
5001 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
5002 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
5003 install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
5004 install_element (ENABLE_NODE, &debug_mroute_cmd);
5005 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
6250610a
JAG
5006 install_element (ENABLE_NODE, &debug_static_cmd);
5007 install_element (ENABLE_NODE, &no_debug_static_cmd);
12e41d03
DL
5008 install_element (ENABLE_NODE, &debug_pim_cmd);
5009 install_element (ENABLE_NODE, &no_debug_pim_cmd);
5010 install_element (ENABLE_NODE, &undebug_pim_cmd);
5011 install_element (ENABLE_NODE, &debug_pim_events_cmd);
5012 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
5013 install_element (ENABLE_NODE, &undebug_pim_events_cmd);
5014 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
5015 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
5016 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
5017 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
5018 install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
5019 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
5020 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
5021 install_element (ENABLE_NODE, &undebug_pim_packetdump_send_cmd);
5022 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
5023 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
5024 install_element (ENABLE_NODE, &undebug_pim_packetdump_recv_cmd);
5025 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
5026 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
5027 install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
5028 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
5029 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
5030 install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
5031 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
5032 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
5033 install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
5034
5035 install_element (CONFIG_NODE, &debug_igmp_cmd);
5036 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
5037 install_element (CONFIG_NODE, &undebug_igmp_cmd);
5038 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
5039 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
5040 install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
5041 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
5042 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
5043 install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
5044 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
5045 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
5046 install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
5047 install_element (CONFIG_NODE, &debug_mroute_cmd);
5048 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
6250610a
JAG
5049 install_element (CONFIG_NODE, &debug_static_cmd);
5050 install_element (CONFIG_NODE, &no_debug_static_cmd);
12e41d03
DL
5051 install_element (CONFIG_NODE, &debug_pim_cmd);
5052 install_element (CONFIG_NODE, &no_debug_pim_cmd);
5053 install_element (CONFIG_NODE, &undebug_pim_cmd);
5054 install_element (CONFIG_NODE, &debug_pim_events_cmd);
5055 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
5056 install_element (CONFIG_NODE, &undebug_pim_events_cmd);
5057 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
5058 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
5059 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
5060 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
5061 install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
5062 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
5063 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
5064 install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
5065 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
5066 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
5067 install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
5068 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
5069 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
5070 install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
5071}