blob: 140812c2acc20540513d20e8e331a4db51086abd [file] [log] [blame]
Everton Marques871dbcf2009-08-11 15:43:05 -03001/*
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
23#include <sys/ioctl.h>
24
25#include <zebra.h>
26
27#include "command.h"
28#include "if.h"
29#include "prefix.h"
30
31#include "pimd.h"
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_igmpv3.h"
38#include "pim_sock.h"
39#include "pim_time.h"
40#include "pim_util.h"
41#include "pim_oil.h"
42#include "pim_neighbor.h"
43#include "pim_pim.h"
44#include "pim_ifchannel.h"
45#include "pim_hello.h"
46#include "pim_msg.h"
47#include "pim_upstream.h"
48#include "pim_rpf.h"
49#include "pim_macro.h"
50
51static struct cmd_node pim_global_node = {
52 PIM_NODE,
53 "",
54 1 /* vtysh ? yes */
55};
56
Leonard Herve596470f2009-08-11 15:45:26 -030057static struct cmd_node interface_node = {
Everton Marques871dbcf2009-08-11 15:43:05 -030058 INTERFACE_NODE,
Leonard Herve596470f2009-08-11 15:45:26 -030059 "%s(config-if)# ",
Everton Marques871dbcf2009-08-11 15:43:05 -030060 1 /* vtysh ? yes */
61};
62
63static void pim_if_membership_clear(struct interface *ifp)
64{
65 struct pim_interface *pim_ifp;
66
67 pim_ifp = ifp->info;
68 zassert(pim_ifp);
69
70 if (PIM_IF_TEST_PIM(pim_ifp->options) &&
71 PIM_IF_TEST_IGMP(pim_ifp->options)) {
72 return;
73 }
74
75 pim_ifchannel_membership_clear(ifp);
76}
77
78/*
79 When PIM is disabled on interface, IGMPv3 local membership
80 information is not injected into PIM interface state.
81
82 The function pim_if_membership_refresh() fetches all IGMPv3 local
83 membership information into PIM. It is intented to be called
84 whenever PIM is enabled on the interface in order to collect missed
85 local membership information.
86 */
87static void pim_if_membership_refresh(struct interface *ifp)
88{
89 struct pim_interface *pim_ifp;
90 struct listnode *sock_node;
91 struct igmp_sock *igmp;
92
93 pim_ifp = ifp->info;
94 zassert(pim_ifp);
95
96 if (!PIM_IF_TEST_PIM(pim_ifp->options))
97 return;
98 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
99 return;
100
101 /*
102 First clear off membership from all PIM (S,G) entries on the
103 interface
104 */
105
106 pim_ifchannel_membership_clear(ifp);
107
108 /*
109 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
110 the interface
111 */
112
113 /* scan igmp sockets */
114 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
115 struct listnode *grpnode;
116 struct igmp_group *grp;
117
118 /* scan igmp groups */
119 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
120 struct listnode *srcnode;
121 struct igmp_source *src;
122
123 /* scan group sources */
124 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
125
126 if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
127 pim_ifchannel_local_membership_add(ifp,
128 src->source_addr,
129 grp->group_addr);
130 }
131
132 } /* scan group sources */
133 } /* scan igmp groups */
134 } /* scan igmp sockets */
135
136 /*
137 Finally delete every PIM (S,G) entry lacking all state info
138 */
139
140 pim_ifchannel_delete_on_noinfo(ifp);
141
142}
143
144static void pim_show_assert(struct vty *vty)
145{
146 struct listnode *ifnode;
147 struct interface *ifp;
148 time_t now;
149
150 now = pim_time_monotonic_sec();
151
152 vty_out(vty,
153 "Interface Address Source Group State Winner Uptime Timer%s",
154 VTY_NEWLINE);
155
156 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
157 struct pim_interface *pim_ifp;
158 struct in_addr ifaddr;
159 struct listnode *ch_node;
160 struct pim_ifchannel *ch;
161
162 pim_ifp = ifp->info;
163
164 if (!pim_ifp)
165 continue;
166
167 ifaddr = pim_ifp->primary_address;
168
169 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
170 char ch_src_str[100];
171 char ch_grp_str[100];
172 char winner_str[100];
173 char uptime[10];
174 char timer[10];
175
176 pim_inet4_dump("<ch_src?>", ch->source_addr,
177 ch_src_str, sizeof(ch_src_str));
178 pim_inet4_dump("<ch_grp?>", ch->group_addr,
179 ch_grp_str, sizeof(ch_grp_str));
180 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
181 winner_str, sizeof(winner_str));
182
183 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
184 pim_time_timer_to_mmss(timer, sizeof(timer),
185 ch->t_ifassert_timer);
186
187 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
188 ifp->name,
189 inet_ntoa(ifaddr),
190 ch_src_str,
191 ch_grp_str,
192 pim_ifchannel_ifassert_name(ch->ifassert_state),
193 winner_str,
194 uptime,
195 timer,
196 VTY_NEWLINE);
197 } /* scan interface channels */
198 } /* scan interfaces */
199}
200
201static void pim_show_assert_internal(struct vty *vty)
202{
203 struct listnode *ifnode;
204 struct interface *ifp;
205
206 vty_out(vty,
207 "CA: CouldAssert%s"
208 "ECA: Evaluate CouldAssert%s"
209 "ATD: AssertTrackingDesired%s"
210 "eATD: Evaluate AssertTrackingDesired%s%s",
211 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
212
213 vty_out(vty,
214 "Interface Address Source Group CA eCA ATD eATD%s",
215 VTY_NEWLINE);
216
217 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
218 struct pim_interface *pim_ifp;
219 struct in_addr ifaddr;
220 struct listnode *ch_node;
221 struct pim_ifchannel *ch;
222
223 pim_ifp = ifp->info;
224
225 if (!pim_ifp)
226 continue;
227
228 ifaddr = pim_ifp->primary_address;
229
230 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
231 char ch_src_str[100];
232 char ch_grp_str[100];
233
234 pim_inet4_dump("<ch_src?>", ch->source_addr,
235 ch_src_str, sizeof(ch_src_str));
236 pim_inet4_dump("<ch_grp?>", ch->group_addr,
237 ch_grp_str, sizeof(ch_grp_str));
238 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
239 ifp->name,
240 inet_ntoa(ifaddr),
241 ch_src_str,
242 ch_grp_str,
243 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
244 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
245 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
246 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
247 VTY_NEWLINE);
248 } /* scan interface channels */
249 } /* scan interfaces */
250}
251
252static void pim_show_assert_metric(struct vty *vty)
253{
254 struct listnode *ifnode;
255 struct interface *ifp;
256
257 vty_out(vty,
258 "Interface Address Source Group RPT Pref Metric Address %s",
259 VTY_NEWLINE);
260
261 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
262 struct pim_interface *pim_ifp;
263 struct in_addr ifaddr;
264 struct listnode *ch_node;
265 struct pim_ifchannel *ch;
266
267 pim_ifp = ifp->info;
268
269 if (!pim_ifp)
270 continue;
271
272 ifaddr = pim_ifp->primary_address;
273
274 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
275 char ch_src_str[100];
276 char ch_grp_str[100];
277 char addr_str[100];
278 struct pim_assert_metric am;
279
280 am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
281
282 pim_inet4_dump("<ch_src?>", ch->source_addr,
283 ch_src_str, sizeof(ch_src_str));
284 pim_inet4_dump("<ch_grp?>", ch->group_addr,
285 ch_grp_str, sizeof(ch_grp_str));
286 pim_inet4_dump("<addr?>", am.ip_address,
287 addr_str, sizeof(addr_str));
288
289 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
290 ifp->name,
291 inet_ntoa(ifaddr),
292 ch_src_str,
293 ch_grp_str,
294 am.rpt_bit_flag ? "yes" : "no",
295 am.metric_preference,
296 am.route_metric,
297 addr_str,
298 VTY_NEWLINE);
299 } /* scan interface channels */
300 } /* scan interfaces */
301}
302
303static void pim_show_assert_winner_metric(struct vty *vty)
304{
305 struct listnode *ifnode;
306 struct interface *ifp;
307
308 vty_out(vty,
309 "Interface Address Source Group RPT Pref Metric Address %s",
310 VTY_NEWLINE);
311
312 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
313 struct pim_interface *pim_ifp;
314 struct in_addr ifaddr;
315 struct listnode *ch_node;
316 struct pim_ifchannel *ch;
317
318 pim_ifp = ifp->info;
319
320 if (!pim_ifp)
321 continue;
322
323 ifaddr = pim_ifp->primary_address;
324
325 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
326 char ch_src_str[100];
327 char ch_grp_str[100];
328 char addr_str[100];
329 struct pim_assert_metric *am;
330 char pref_str[5];
331 char metr_str[7];
332
333 am = &ch->ifassert_winner_metric;
334
335 pim_inet4_dump("<ch_src?>", ch->source_addr,
336 ch_src_str, sizeof(ch_src_str));
337 pim_inet4_dump("<ch_grp?>", ch->group_addr,
338 ch_grp_str, sizeof(ch_grp_str));
339 pim_inet4_dump("<addr?>", am->ip_address,
340 addr_str, sizeof(addr_str));
341
342 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
343 snprintf(pref_str, sizeof(pref_str), "INFI");
344 else
345 snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
346
347 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
348 snprintf(metr_str, sizeof(metr_str), "INFI");
349 else
350 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
351
352 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
353 ifp->name,
354 inet_ntoa(ifaddr),
355 ch_src_str,
356 ch_grp_str,
357 am->rpt_bit_flag ? "yes" : "no",
358 pref_str,
359 metr_str,
360 addr_str,
361 VTY_NEWLINE);
362 } /* scan interface channels */
363 } /* scan interfaces */
364}
365
366static void pim_show_membership(struct vty *vty)
367{
368 struct listnode *ifnode;
369 struct interface *ifp;
370
371 vty_out(vty,
372 "Interface Address Source Group Membership%s",
373 VTY_NEWLINE);
374
375 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
376 struct pim_interface *pim_ifp;
377 struct in_addr ifaddr;
378 struct listnode *ch_node;
379 struct pim_ifchannel *ch;
380
381 pim_ifp = ifp->info;
382
383 if (!pim_ifp)
384 continue;
385
386 ifaddr = pim_ifp->primary_address;
387
388 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
389 char ch_src_str[100];
390 char ch_grp_str[100];
391
392 pim_inet4_dump("<ch_src?>", ch->source_addr,
393 ch_src_str, sizeof(ch_src_str));
394 pim_inet4_dump("<ch_grp?>", ch->group_addr,
395 ch_grp_str, sizeof(ch_grp_str));
396
397 vty_out(vty, "%-9s %-15s %-15s %-15s %-10s%s",
398 ifp->name,
399 inet_ntoa(ifaddr),
400 ch_src_str,
401 ch_grp_str,
402 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?
403 "NOINFO" : "INCLUDE",
404 VTY_NEWLINE);
405 } /* scan interface channels */
406 } /* scan interfaces */
407
408}
409
410static void igmp_show_interfaces(struct vty *vty)
411{
412 struct listnode *node;
413 struct interface *ifp;
414 time_t now;
415
416 now = pim_time_monotonic_sec();
417
418 vty_out(vty,
419 "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s",
420 VTY_NEWLINE);
421
422 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
423 struct pim_interface *pim_ifp;
424 struct listnode *sock_node;
425 struct igmp_sock *igmp;
426
427 pim_ifp = ifp->info;
428
429 if (!pim_ifp)
430 continue;
431
432 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
433 char uptime[10];
434 int mloop;
435
436 pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
437
438 mloop = pim_socket_mcastloop_get(igmp->fd);
439
440 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
441 ifp->name,
442 inet_ntoa(igmp->ifaddr),
443 ifp->ifindex,
444 igmp->fd,
445 uptime,
446 if_is_multicast(ifp) ? "yes" : "no",
447 if_is_broadcast(ifp) ? "yes" : "no",
448 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
449 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
450 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
451 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
452 VTY_NEWLINE);
453 }
454 }
455}
456
457static void show_interface_address(struct vty *vty)
458{
459 struct listnode *ifpnode;
460 struct interface *ifp;
461
462 vty_out(vty,
463 "Interface Primary Secondary %s",
464 VTY_NEWLINE);
465
466 for (ALL_LIST_ELEMENTS_RO(iflist, ifpnode, ifp)) {
467 struct listnode *ifcnode;
468 struct connected *ifc;
469 struct in_addr pri_addr;
470 char pri_addr_str[100];
471
472 pri_addr = pim_find_primary_addr(ifp);
473
474 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
475
476 for (ALL_LIST_ELEMENTS_RO(ifp->connected, ifcnode, ifc)) {
477 char sec_addr_str[100];
478 struct prefix *p = ifc->address;
479
480 if (p->family != AF_INET)
481 continue;
482
483 if (p->u.prefix4.s_addr == pri_addr.s_addr) {
484 sec_addr_str[0] = '\0';
485 }
486 else {
487 pim_inet4_dump("<sec?>", p->u.prefix4, sec_addr_str, sizeof(sec_addr_str));
488 }
489
490 vty_out(vty, "%-9s %-15s %-15s%s",
491 ifp->name,
492 pri_addr_str,
493 sec_addr_str,
494 VTY_NEWLINE);
495 }
496 }
497}
498
499static void pim_show_dr(struct vty *vty)
500{
501 struct listnode *node;
502 struct interface *ifp;
503 time_t now;
504
505 now = pim_time_monotonic_sec();
506
507 vty_out(vty,
508 "NonPri: Number of neighbors missing DR Priority hello option%s%s",
509 VTY_NEWLINE, VTY_NEWLINE);
510
511 vty_out(vty, "Interface Address DR Uptime Elections NonPri%s", VTY_NEWLINE);
512
513 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
514 struct pim_interface *pim_ifp;
515 struct in_addr ifaddr;
516 char dr_str[100];
517 char dr_uptime[10];
518
519 pim_ifp = ifp->info;
520
521 if (!pim_ifp)
522 continue;
523
524 if (pim_ifp->pim_sock_fd < 0)
525 continue;
526
527 ifaddr = pim_ifp->primary_address;
528
529 pim_time_uptime(dr_uptime, sizeof(dr_uptime),
530 now - pim_ifp->pim_dr_election_last);
531
532 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr,
533 dr_str, sizeof(dr_str));
534
535 vty_out(vty, "%-9s %-15s %-15s %8s %9d %6d%s",
536 ifp->name,
537 inet_ntoa(ifaddr),
538 dr_str,
539 dr_uptime,
540 pim_ifp->pim_dr_election_count,
541 pim_ifp->pim_dr_num_nondrpri_neighbors,
542 VTY_NEWLINE);
543 }
544}
545
546static void pim_show_hello(struct vty *vty)
547{
548 struct listnode *node;
549 struct interface *ifp;
550 time_t now;
551
552 now = pim_time_monotonic_sec();
553
554 vty_out(vty, "Interface Address Period Timer StatStart Recv Rfail Send Sfail%s", VTY_NEWLINE);
555
556 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
557 struct pim_interface *pim_ifp;
558 struct in_addr ifaddr;
559 char hello_period[10];
560 char hello_timer[10];
561 char stat_uptime[10];
562
563 pim_ifp = ifp->info;
564
565 if (!pim_ifp)
566 continue;
567
568 if (pim_ifp->pim_sock_fd < 0)
569 continue;
570
571 ifaddr = pim_ifp->primary_address;
572
573 pim_time_timer_to_mmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
574 pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
575 pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
576
577 vty_out(vty, "%-9s %-15s %6s %5s %9s %4u %5u %4u %5u%s",
578 ifp->name,
579 inet_ntoa(ifaddr),
580 hello_period,
581 hello_timer,
582 stat_uptime,
583 pim_ifp->pim_ifstat_hello_recv,
584 pim_ifp->pim_ifstat_hello_recvfail,
585 pim_ifp->pim_ifstat_hello_sent,
586 pim_ifp->pim_ifstat_hello_sendfail,
587 VTY_NEWLINE);
588 }
589}
590
591static void pim_show_interfaces(struct vty *vty)
592{
593 struct listnode *node;
594 struct interface *ifp;
595 time_t now;
596
597 now = pim_time_monotonic_sec();
598
599 vty_out(vty, "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s", VTY_NEWLINE);
600
601 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
602 struct pim_interface *pim_ifp;
603 struct in_addr ifaddr;
604 char uptime[10];
605 int mloop;
606
607 pim_ifp = ifp->info;
608
609 if (!pim_ifp)
610 continue;
611
612 if (pim_ifp->pim_sock_fd < 0)
613 continue;
614
615 ifaddr = pim_ifp->primary_address;
616
617 pim_time_uptime(uptime, sizeof(uptime), now - pim_ifp->pim_sock_creation);
618
619 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
620
621 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
622 ifp->name,
623 inet_ntoa(ifaddr),
624 ifp->ifindex,
625 pim_ifp->pim_sock_fd,
626 uptime,
627 if_is_multicast(ifp) ? "yes" : "no",
628 if_is_broadcast(ifp) ? "yes" : "no",
629 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
630 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
631 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
632 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
633 VTY_NEWLINE);
634 }
635}
636
637static void pim_show_join(struct vty *vty)
638{
639 struct listnode *ifnode;
640 struct interface *ifp;
641 time_t now;
642
643 now = pim_time_monotonic_sec();
644
645 vty_out(vty,
646 "Interface Address Source Group State Uptime Expire Prune%s",
647 VTY_NEWLINE);
648
649 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
650 struct pim_interface *pim_ifp;
651 struct in_addr ifaddr;
652 struct listnode *ch_node;
653 struct pim_ifchannel *ch;
654
655 pim_ifp = ifp->info;
656
657 if (!pim_ifp)
658 continue;
659
660 ifaddr = pim_ifp->primary_address;
661
662 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
663 char ch_src_str[100];
664 char ch_grp_str[100];
665 char uptime[10];
666 char expire[10];
667 char prune[10];
668
669 pim_inet4_dump("<ch_src?>", ch->source_addr,
670 ch_src_str, sizeof(ch_src_str));
671 pim_inet4_dump("<ch_grp?>", ch->group_addr,
672 ch_grp_str, sizeof(ch_grp_str));
673
674 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifjoin_creation);
675 pim_time_timer_to_mmss(expire, sizeof(expire),
676 ch->t_ifjoin_expiry_timer);
677 pim_time_timer_to_mmss(prune, sizeof(prune),
678 ch->t_ifjoin_prune_pending_timer);
679
680 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
681 ifp->name,
682 inet_ntoa(ifaddr),
683 ch_src_str,
684 ch_grp_str,
685 pim_ifchannel_ifjoin_name(ch->ifjoin_state),
686 uptime,
687 expire,
688 prune,
689 VTY_NEWLINE);
690 } /* scan interface channels */
691 } /* scan interfaces */
692
693}
694
695static void pim_show_neighbors(struct vty *vty)
696{
697 struct listnode *node;
698 struct interface *ifp;
699 time_t now;
700
701 now = pim_time_monotonic_sec();
702
703 vty_out(vty,
704 "Recv flags: H=holdtime L=lan_prune_delay P=dr_priority G=generation_id A=address_list%s"
705 " T=can_disable_join_suppression%s%s",
706 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
707
708 vty_out(vty, "Interface Address Neighbor Uptime Timer Holdt DrPri GenId Recv %s", VTY_NEWLINE);
709
710 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
711 struct pim_interface *pim_ifp;
712 struct in_addr ifaddr;
713 struct listnode *neighnode;
714 struct pim_neighbor *neigh;
715
716 pim_ifp = ifp->info;
717
718 if (!pim_ifp)
719 continue;
720
721 if (pim_ifp->pim_sock_fd < 0)
722 continue;
723
724 ifaddr = pim_ifp->primary_address;
725
726 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
727 char uptime[10];
728 char holdtime[10];
729 char expire[10];
730 char neigh_src_str[100];
731 char recv[7];
732
733 pim_inet4_dump("<src?>", neigh->source_addr,
734 neigh_src_str, sizeof(neigh_src_str));
735 pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
736 pim_time_mmss(holdtime, sizeof(holdtime), neigh->holdtime);
737 pim_time_timer_to_mmss(expire, sizeof(expire), neigh->t_expire_timer);
738
739 recv[0] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME) ? 'H' : ' ';
740 recv[1] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? 'L' : ' ';
741 recv[2] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY) ? 'P' : ' ';
742 recv[3] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ? 'G' : ' ';
743 recv[4] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST) ? 'A' : ' ';
744 recv[5] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION) ? 'T' : ' ';
745 recv[6] = '\0';
746
747 vty_out(vty, "%-9s %-15s %-15s %8s %5s %5s %5u %08x %6s%s",
748 ifp->name,
749 inet_ntoa(ifaddr),
750 neigh_src_str,
751 uptime,
752 expire,
753 holdtime,
754 neigh->dr_priority,
755 neigh->generation_id,
756 recv,
757 VTY_NEWLINE);
758 }
759
760
761 }
762}
763
764static void pim_show_lan_prune_delay(struct vty *vty)
765{
766 struct listnode *node;
767 struct interface *ifp;
768
769 vty_out(vty,
770 "PrDly=propagation_delay (msec) OvInt=override_interval (msec)%s"
771 "HiDly=highest_propagation_delay (msec) HiInt=highest_override_interval (msec)%s"
772 "NoDly=number_of_non_lan_delay_neighbors%s"
773 "T=t_bit LPD=lan_prune_delay_hello_option%s%s",
774 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
775
776 vty_out(vty, "Interface Address PrDly OvInt NoDly HiDly HiInt T Neighbor LPD PrDly OvInt T%s", VTY_NEWLINE);
777
778 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
779 struct pim_interface *pim_ifp;
780 struct in_addr ifaddr;
781 struct listnode *neighnode;
782 struct pim_neighbor *neigh;
783
784 pim_ifp = ifp->info;
785
786 if (!pim_ifp)
787 continue;
788
789 if (pim_ifp->pim_sock_fd < 0)
790 continue;
791
792 ifaddr = pim_ifp->primary_address;
793
794 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
795 char neigh_src_str[100];
796
797 pim_inet4_dump("<src?>", neigh->source_addr,
798 neigh_src_str, sizeof(neigh_src_str));
799
Everton Marques5f35a522009-08-20 11:57:41 -0300800 vty_out(vty, "%-9s %-15s %5u %5u %5u %5u %5u %1u %-15s %-3s %5u %5u %1u%s",
Everton Marques871dbcf2009-08-11 15:43:05 -0300801 ifp->name,
802 inet_ntoa(ifaddr),
803 pim_ifp->pim_propagation_delay_msec,
804 pim_ifp->pim_override_interval_msec,
805 pim_ifp->pim_number_of_nonlandelay_neighbors,
806 pim_ifp->pim_neighbors_highest_propagation_delay_msec,
807 pim_ifp->pim_neighbors_highest_override_interval_msec,
808 PIM_FORCE_BOOLEAN(PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options)),
809 neigh_src_str,
810 PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? "yes" : "no",
811 neigh->propagation_delay_msec,
812 neigh->override_interval_msec,
813 PIM_FORCE_BOOLEAN(PIM_OPTION_IS_SET(neigh->hello_options,
814 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION)),
815 VTY_NEWLINE);
816 }
817
818 }
819}
820
821static void pim_show_jp_override_interval(struct vty *vty)
822{
823 struct listnode *node;
824 struct interface *ifp;
825
826 vty_out(vty,
827 "EffPDelay=effective_propagation_delay (msec)%s"
828 "EffOvrInt=override_interval (msec)%s"
829 "JPOvrInt=jp_override_interval (msec)%s%s",
830 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
831
832 vty_out(vty, "Interface Address LAN_Delay EffPDelay EffOvrInt JPOvrInt%s", VTY_NEWLINE);
833
834 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
835 struct pim_interface *pim_ifp;
836 struct in_addr ifaddr;
837
838 pim_ifp = ifp->info;
839
840 if (!pim_ifp)
841 continue;
842
843 if (pim_ifp->pim_sock_fd < 0)
844 continue;
845
846 ifaddr = pim_ifp->primary_address;
847
848 vty_out(vty, "%-9s %-15s %-9s %9u %9u %8u%s",
849 ifp->name,
850 inet_ntoa(ifaddr),
851 pim_if_lan_delay_enabled(ifp) ? "enabled" : "disabled",
852 pim_if_effective_propagation_delay_msec(ifp),
853 pim_if_effective_override_interval_msec(ifp),
854 pim_if_jp_override_interval_msec(ifp),
855 VTY_NEWLINE);
856 }
857}
858
859static void pim_show_neighbors_secondary(struct vty *vty)
860{
861 struct listnode *node;
862 struct interface *ifp;
863
864 vty_out(vty, "Interface Address Neighbor Secondary %s", VTY_NEWLINE);
865
866 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
867 struct pim_interface *pim_ifp;
868 struct in_addr ifaddr;
869 struct listnode *neighnode;
870 struct pim_neighbor *neigh;
871
872 pim_ifp = ifp->info;
873
874 if (!pim_ifp)
875 continue;
876
877 if (pim_ifp->pim_sock_fd < 0)
878 continue;
879
880 ifaddr = pim_ifp->primary_address;
881
882 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
883 char neigh_src_str[100];
884 struct listnode *prefix_node;
885 struct prefix *p;
886
887 if (!neigh->prefix_list)
888 continue;
889
890 pim_inet4_dump("<src?>", neigh->source_addr,
891 neigh_src_str, sizeof(neigh_src_str));
892
893 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
894 char neigh_sec_str[100];
895
896 if (p->family != AF_INET)
897 continue;
898
899 pim_inet4_dump("<src?>", p->u.prefix4,
900 neigh_sec_str, sizeof(neigh_sec_str));
901
902 vty_out(vty, "%-9s %-15s %-15s %-15s%s",
903 ifp->name,
904 inet_ntoa(ifaddr),
905 neigh_src_str,
906 neigh_sec_str,
907 VTY_NEWLINE);
908 }
909 }
910 }
911}
912
913static void pim_show_upstream(struct vty *vty)
914{
915 struct listnode *upnode;
916 struct pim_upstream *up;
917 time_t now;
918
919 now = pim_time_monotonic_sec();
920
921 vty_out(vty, "Source Group State Uptime JoinTimer RefCnt%s", VTY_NEWLINE);
922
923 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
924 char src_str[100];
925 char grp_str[100];
926 char uptime[10];
927 char join_timer[10];
928
929 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
930 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
931 pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
932 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer), up->t_join_timer);
933
934 vty_out(vty, "%-15s %-15s %-5s %-8s %-9s %6d%s",
935 src_str,
936 grp_str,
937 up->join_state == PIM_UPSTREAM_JOINED ? "Jnd" : "NtJnd",
938 uptime,
939 join_timer,
940 up->ref_count,
941 VTY_NEWLINE);
942 }
943}
944
945static void pim_show_join_desired(struct vty *vty)
946{
947 struct listnode *ifnode;
948 struct listnode *chnode;
949 struct interface *ifp;
950 struct pim_interface *pim_ifp;
951 struct pim_ifchannel *ch;
952 struct in_addr me_ifaddr;
953 char src_str[100];
954 char grp_str[100];
955
956 vty_out(vty,
957 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
958 VTY_NEWLINE);
959
960 /* scan all interfaces */
961 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
962 pim_ifp = ifp->info;
963 if (!pim_ifp)
964 continue;
965
966 me_ifaddr = pim_ifp->primary_address;
967
968 /* scan per-interface (S,G) state */
969 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
970 struct pim_upstream *up = ch->upstream;
971
972 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
973 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
974
975 vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
976 ifp->name,
977 src_str,
978 grp_str,
979 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
980 pim_macro_chisin_joins(ch) ? "yes" : "no",
981 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
982 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
983 pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
984 VTY_NEWLINE);
985 }
986 }
987}
988
989static void pim_show_upstream_rpf(struct vty *vty)
990{
991 struct listnode *upnode;
992 struct pim_upstream *up;
993
994 vty_out(vty,
995 "Source Group RpfIface RibNextHop RpfAddress %s",
996 VTY_NEWLINE);
997
998 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
999 char src_str[100];
1000 char grp_str[100];
1001 char rpf_nexthop_str[100];
1002 char rpf_addr_str[100];
1003 struct pim_rpf *rpf;
1004 const char *rpf_ifname;
1005
1006 rpf = &up->rpf;
1007
1008 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1009 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1010 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
1011 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1012
1013 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1014
1015 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
1016 src_str,
1017 grp_str,
1018 rpf_ifname,
1019 rpf_nexthop_str,
1020 rpf_addr_str,
1021 VTY_NEWLINE);
1022 }
1023}
1024
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001025static void show_rpf_refresh_stats(struct vty *vty, time_t now)
Everton Marques613938d2009-08-13 15:39:31 -03001026{
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001027 char refresh_uptime[10];
1028
1029 pim_time_uptime(refresh_uptime, sizeof(refresh_uptime), now - qpim_rpf_cache_refresh_last);
1030
Everton Marques613938d2009-08-13 15:39:31 -03001031 vty_out(vty,
1032 "RPF Cache Refresh Delay: %ld msecs%s"
1033 "RPF Cache Refresh Timer: %ld msecs%s"
1034 "RPF Cache Refresh Requests: %lld%s"
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001035 "RPF Cache Refresh Events: %lld%s"
1036 "RPF Cache Refresh Last: %s%s",
Everton Marques613938d2009-08-13 15:39:31 -03001037 qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
1038 pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
1039 qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001040 qpim_rpf_cache_refresh_events, VTY_NEWLINE,
1041 refresh_uptime, VTY_NEWLINE);
Everton Marques613938d2009-08-13 15:39:31 -03001042}
1043
Everton Marques871dbcf2009-08-11 15:43:05 -03001044static void pim_show_rpf(struct vty *vty)
1045{
1046 struct listnode *up_node;
1047 struct pim_upstream *up;
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001048 time_t now = pim_time_monotonic_sec();
Everton Marques871dbcf2009-08-11 15:43:05 -03001049
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001050 show_rpf_refresh_stats(vty, now);
Everton Marques613938d2009-08-13 15:39:31 -03001051
1052 vty_out(vty, "%s", VTY_NEWLINE);
1053
Everton Marques871dbcf2009-08-11 15:43:05 -03001054 vty_out(vty,
1055 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1056 VTY_NEWLINE);
1057
Everton Marques871dbcf2009-08-11 15:43:05 -03001058 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
1059 char src_str[100];
1060 char grp_str[100];
1061 char rpf_addr_str[100];
1062 char rib_nexthop_str[100];
1063 const char *rpf_ifname;
1064 struct pim_rpf *rpf = &up->rpf;
1065
1066 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1067 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1068 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1069 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
1070
1071 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1072
1073 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1074 src_str,
1075 grp_str,
1076 rpf_ifname,
1077 rpf_addr_str,
1078 rib_nexthop_str,
1079 rpf->source_nexthop.mrib_route_metric,
1080 rpf->source_nexthop.mrib_metric_preference,
1081 VTY_NEWLINE);
1082 }
1083}
1084
1085static void igmp_show_querier(struct vty *vty)
1086{
1087 struct listnode *node;
1088 struct interface *ifp;
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001089 time_t now = pim_time_monotonic_sec();
Everton Marques871dbcf2009-08-11 15:43:05 -03001090
1091 vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
1092
1093 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
1094 struct pim_interface *pim_ifp = ifp->info;
1095 struct listnode *sock_node;
1096 struct igmp_sock *igmp;
1097
1098 if (!pim_ifp)
1099 continue;
1100
1101 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1102 char query_hhmmss[10];
1103 char other_hhmmss[10];
1104
1105 pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
1106 pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
1107
Everton Marquese96f0af2009-08-11 15:48:02 -03001108 vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03001109 ifp->name,
1110 inet_ntoa(igmp->ifaddr),
1111 igmp->t_igmp_query_timer ? "THIS" : "OTHER",
1112 igmp->startup_query_count,
1113 query_hhmmss,
1114 other_hhmmss,
1115 VTY_NEWLINE);
1116 }
1117 }
1118}
1119
1120static void igmp_show_groups(struct vty *vty)
1121{
1122 struct listnode *ifnode;
1123 struct interface *ifp;
1124 time_t now;
1125
1126 now = pim_time_monotonic_sec();
1127
1128 vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
1129
1130 /* scan interfaces */
1131 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1132 struct pim_interface *pim_ifp = ifp->info;
1133 struct listnode *sock_node;
1134 struct igmp_sock *igmp;
1135
1136 if (!pim_ifp)
1137 continue;
1138
1139 /* scan igmp sockets */
1140 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1141 char ifaddr_str[100];
1142 struct listnode *grpnode;
1143 struct igmp_group *grp;
1144
1145 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1146
1147 /* scan igmp groups */
1148 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1149 char group_str[100];
1150 char hhmmss[10];
1151 char uptime[10];
1152
1153 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1154 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
1155 pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
1156
1157 vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
1158 ifp->name,
1159 ifaddr_str,
1160 group_str,
1161 grp->group_filtermode_isexcl ? "EXCL" : "INCL",
1162 hhmmss,
1163 grp->group_source_list ? listcount(grp->group_source_list) : 0,
1164 igmp_group_compat_mode(igmp, grp),
1165 uptime,
1166 VTY_NEWLINE);
1167
1168 } /* scan igmp groups */
1169 } /* scan igmp sockets */
1170 } /* scan interfaces */
1171}
1172
1173static void igmp_show_group_retransmission(struct vty *vty)
1174{
1175 struct listnode *ifnode;
1176 struct interface *ifp;
1177 time_t now;
1178
1179 now = pim_time_monotonic_sec();
1180
1181 vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
1182
1183 /* scan interfaces */
1184 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1185 struct pim_interface *pim_ifp = ifp->info;
1186 struct listnode *sock_node;
1187 struct igmp_sock *igmp;
1188
1189 if (!pim_ifp)
1190 continue;
1191
1192 /* scan igmp sockets */
1193 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1194 char ifaddr_str[100];
1195 struct listnode *grpnode;
1196 struct igmp_group *grp;
1197
1198 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1199
1200 /* scan igmp groups */
1201 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1202 char group_str[100];
1203 char grp_retr_mmss[10];
1204 struct listnode *src_node;
1205 struct igmp_source *src;
1206 int grp_retr_sources = 0;
1207
1208 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1209 pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
1210
1211
1212 /* count group sources with retransmission state */
1213 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
1214 if (src->source_query_retransmit_count > 0) {
1215 ++grp_retr_sources;
1216 }
1217 }
1218
1219 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
1220 ifp->name,
1221 ifaddr_str,
1222 group_str,
1223 grp_retr_mmss,
1224 grp->group_specific_query_retransmit_count,
1225 grp_retr_sources,
1226 VTY_NEWLINE);
1227
1228 } /* scan igmp groups */
1229 } /* scan igmp sockets */
1230 } /* scan interfaces */
1231}
1232
1233static void igmp_show_parameters(struct vty *vty)
1234{
1235 struct listnode *ifnode;
1236 struct interface *ifp;
1237
1238 vty_out(vty,
1239 "QRV: Robustness Variable SQI: Startup Query Interval%s"
1240 "QQI: Query Interval OQPI: Other Querier Present Interval%s"
1241 "QRI: Query Response Interval LMQT: Last Member Query Time%s"
1242 "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
1243 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1244
1245 vty_out(vty,
1246 "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
1247 VTY_NEWLINE);
1248
1249 /* scan interfaces */
1250 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1251 struct pim_interface *pim_ifp = ifp->info;
1252 struct listnode *sock_node;
1253 struct igmp_sock *igmp;
1254
1255 if (!pim_ifp)
1256 continue;
1257
1258 /* scan igmp sockets */
1259 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1260 char ifaddr_str[100];
1261 long gmi_dsec; /* Group Membership Interval */
1262 long oqpi_dsec; /* Other Querier Present Interval */
1263 int sqi;
1264 long lmqt_dsec;
1265 long ohpi_dsec;
1266 long qri_dsec;
1267
1268 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1269
1270 gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
1271 igmp->querier_query_interval,
1272 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1273
1274 sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
1275
1276 oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
1277 igmp->querier_query_interval,
1278 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1279
1280 lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
1281 igmp->querier_robustness_variable) / 100;
1282
1283 ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
1284 igmp->querier_query_interval,
1285 pim_ifp->igmp_query_max_response_time_dsec);
1286
1287 qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
1288
1289 vty_out(vty,
1290 "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
1291 ifp->name,
1292 ifaddr_str,
1293 igmp->querier_robustness_variable,
1294 igmp->querier_query_interval,
1295 qri_dsec / 10, qri_dsec % 10,
1296 gmi_dsec / 10, gmi_dsec % 10,
1297 sqi,
1298 oqpi_dsec / 10, oqpi_dsec % 10,
1299 lmqt_dsec / 10, lmqt_dsec % 10,
1300 ohpi_dsec / 10, ohpi_dsec % 10,
1301 VTY_NEWLINE);
1302
1303 } /* scan igmp sockets */
1304 } /* scan interfaces */
1305}
1306
1307static void igmp_show_sources(struct vty *vty)
1308{
1309 struct listnode *ifnode;
1310 struct interface *ifp;
1311 time_t now;
1312
1313 now = pim_time_monotonic_sec();
1314
1315 vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
1316
1317 /* scan interfaces */
1318 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1319 struct pim_interface *pim_ifp = ifp->info;
1320 struct listnode *sock_node;
1321 struct igmp_sock *igmp;
1322
1323 if (!pim_ifp)
1324 continue;
1325
1326 /* scan igmp sockets */
1327 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1328 char ifaddr_str[100];
1329 struct listnode *grpnode;
1330 struct igmp_group *grp;
1331
1332 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1333
1334 /* scan igmp groups */
1335 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1336 char group_str[100];
1337 struct listnode *srcnode;
1338 struct igmp_source *src;
1339
1340 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1341
1342 /* scan group sources */
1343 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1344 char source_str[100];
1345 char mmss[10];
1346 char uptime[10];
1347
1348 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1349
1350 pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
1351
1352 pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
1353
1354 vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
1355 ifp->name,
1356 ifaddr_str,
1357 group_str,
1358 source_str,
1359 mmss,
1360 IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
1361 uptime,
1362 VTY_NEWLINE);
1363
1364 } /* scan group sources */
1365 } /* scan igmp groups */
1366 } /* scan igmp sockets */
1367 } /* scan interfaces */
1368}
1369
1370static void igmp_show_source_retransmission(struct vty *vty)
1371{
1372 struct listnode *ifnode;
1373 struct interface *ifp;
1374 time_t now;
1375
1376 now = pim_time_monotonic_sec();
1377
1378 vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
1379
1380 /* scan interfaces */
1381 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1382 struct pim_interface *pim_ifp = ifp->info;
1383 struct listnode *sock_node;
1384 struct igmp_sock *igmp;
1385
1386 if (!pim_ifp)
1387 continue;
1388
1389 /* scan igmp sockets */
1390 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1391 char ifaddr_str[100];
1392 struct listnode *grpnode;
1393 struct igmp_group *grp;
1394
1395 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1396
1397 /* scan igmp groups */
1398 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1399 char group_str[100];
1400 struct listnode *srcnode;
1401 struct igmp_source *src;
1402
1403 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1404
1405 /* scan group sources */
1406 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1407 char source_str[100];
1408
1409 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1410
1411 vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
1412 ifp->name,
1413 ifaddr_str,
1414 group_str,
1415 source_str,
1416 src->source_query_retransmit_count,
1417 VTY_NEWLINE);
1418
1419 } /* scan group sources */
1420 } /* scan igmp groups */
1421 } /* scan igmp sockets */
1422 } /* scan interfaces */
1423}
1424
1425static void clear_igmp_interfaces()
1426{
1427 struct listnode *ifnode;
1428 struct listnode *ifnextnode;
1429 struct interface *ifp;
1430
1431 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1432 pim_if_addr_del_all_igmp(ifp);
1433 }
1434
1435 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1436 pim_if_addr_add_all(ifp);
1437 }
1438}
1439
1440static void clear_pim_interfaces()
1441{
1442 struct listnode *ifnode;
1443 struct listnode *ifnextnode;
1444 struct interface *ifp;
1445
1446 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1447 if (ifp->info) {
1448 pim_neighbor_delete_all(ifp, "interface cleared");
1449 }
1450 }
1451}
1452
1453static void clear_interfaces()
1454{
1455 clear_igmp_interfaces();
1456 clear_pim_interfaces();
1457}
1458
1459DEFUN (pim_interface,
1460 pim_interface_cmd,
1461 "interface IFNAME",
1462 "Select an interface to configure\n"
1463 "Interface's name\n")
1464{
1465 struct interface *ifp;
1466 const char *ifname = argv[0];
1467 size_t sl;
1468
1469 sl = strlen(ifname);
1470 if (sl > INTERFACE_NAMSIZ) {
1471 vty_out(vty, "%% Interface name %s is invalid: length exceeds "
1472 "%d characters%s",
1473 ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
1474 return CMD_WARNING;
1475 }
1476
1477 ifp = if_lookup_by_name_len(ifname, sl);
1478 if (!ifp) {
1479 vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
1480
1481 /* Returning here would prevent pimd from booting when there are
1482 interface commands in pimd.conf, since all interfaces are
1483 unknown at pimd boot time (the zebra daemon has not been
1484 contacted for interface discovery). */
1485
1486 ifp = if_get_by_name_len(ifname, sl);
1487 if (!ifp) {
1488 vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
1489 return CMD_WARNING;
1490 }
1491 }
1492
1493 vty->index = ifp;
1494 vty->node = INTERFACE_NODE;
1495
1496 return CMD_SUCCESS;
1497}
1498
1499DEFUN (clear_ip_interfaces,
1500 clear_ip_interfaces_cmd,
1501 "clear ip interfaces",
1502 CLEAR_STR
1503 IP_STR
1504 "Reset interfaces\n")
1505{
1506 clear_interfaces();
1507
1508 return CMD_SUCCESS;
1509}
1510
1511DEFUN (clear_ip_igmp_interfaces,
1512 clear_ip_igmp_interfaces_cmd,
1513 "clear ip igmp interfaces",
1514 CLEAR_STR
1515 IP_STR
1516 CLEAR_IP_IGMP_STR
1517 "Reset IGMP interfaces\n")
1518{
1519 clear_igmp_interfaces();
1520
1521 return CMD_SUCCESS;
1522}
1523
1524DEFUN (clear_ip_pim_interfaces,
1525 clear_ip_pim_interfaces_cmd,
1526 "clear ip pim interfaces",
1527 CLEAR_STR
1528 IP_STR
1529 CLEAR_IP_PIM_STR
1530 "Reset PIM interfaces\n")
1531{
1532 clear_pim_interfaces();
1533
1534 return CMD_SUCCESS;
1535}
1536
1537DEFUN (show_ip_igmp_interface,
1538 show_ip_igmp_interface_cmd,
1539 "show ip igmp interface",
1540 SHOW_STR
1541 IP_STR
1542 IGMP_STR
1543 "IGMP interface information\n")
1544{
1545 igmp_show_interfaces(vty);
1546
1547 return CMD_SUCCESS;
1548}
1549
1550DEFUN (show_ip_igmp_groups,
1551 show_ip_igmp_groups_cmd,
1552 "show ip igmp groups",
1553 SHOW_STR
1554 IP_STR
1555 IGMP_STR
1556 IGMP_GROUP_STR)
1557{
1558 igmp_show_groups(vty);
1559
1560 return CMD_SUCCESS;
1561}
1562
1563DEFUN (show_ip_igmp_groups_retransmissions,
1564 show_ip_igmp_groups_retransmissions_cmd,
1565 "show ip igmp groups retransmissions",
1566 SHOW_STR
1567 IP_STR
1568 IGMP_STR
1569 IGMP_GROUP_STR
1570 "IGMP group retransmissions\n")
1571{
1572 igmp_show_group_retransmission(vty);
1573
1574 return CMD_SUCCESS;
1575}
1576
1577DEFUN (show_ip_igmp_parameters,
1578 show_ip_igmp_parameters_cmd,
1579 "show ip igmp parameters",
1580 SHOW_STR
1581 IP_STR
1582 IGMP_STR
1583 "IGMP parameters information\n")
1584{
1585 igmp_show_parameters(vty);
1586
1587 return CMD_SUCCESS;
1588}
1589
1590DEFUN (show_ip_igmp_sources,
1591 show_ip_igmp_sources_cmd,
1592 "show ip igmp sources",
1593 SHOW_STR
1594 IP_STR
1595 IGMP_STR
1596 IGMP_SOURCE_STR)
1597{
1598 igmp_show_sources(vty);
1599
1600 return CMD_SUCCESS;
1601}
1602
1603DEFUN (show_ip_igmp_sources_retransmissions,
1604 show_ip_igmp_sources_retransmissions_cmd,
1605 "show ip igmp sources retransmissions",
1606 SHOW_STR
1607 IP_STR
1608 IGMP_STR
1609 IGMP_SOURCE_STR
1610 "IGMP source retransmissions\n")
1611{
1612 igmp_show_source_retransmission(vty);
1613
1614 return CMD_SUCCESS;
1615}
1616
1617DEFUN (show_ip_igmp_querier,
1618 show_ip_igmp_querier_cmd,
1619 "show ip igmp querier",
1620 SHOW_STR
1621 IP_STR
1622 IGMP_STR
1623 "IGMP querier information\n")
1624{
1625 igmp_show_querier(vty);
1626
1627 return CMD_SUCCESS;
1628}
1629
1630DEFUN (show_ip_pim_address,
1631 show_ip_pim_address_cmd,
1632 "show ip pim address",
1633 SHOW_STR
1634 IP_STR
1635 PIM_STR
1636 "PIM interface address\n")
1637{
1638 show_interface_address(vty);
1639
1640 return CMD_SUCCESS;
1641}
1642
1643DEFUN (show_ip_pim_assert,
1644 show_ip_pim_assert_cmd,
1645 "show ip pim assert",
1646 SHOW_STR
1647 IP_STR
1648 PIM_STR
1649 "PIM interface assert\n")
1650{
1651 pim_show_assert(vty);
1652
1653 return CMD_SUCCESS;
1654}
1655
1656DEFUN (show_ip_pim_assert_internal,
1657 show_ip_pim_assert_internal_cmd,
1658 "show ip pim assert-internal",
1659 SHOW_STR
1660 IP_STR
1661 PIM_STR
1662 "PIM interface internal assert state\n")
1663{
1664 pim_show_assert_internal(vty);
1665
1666 return CMD_SUCCESS;
1667}
1668
1669DEFUN (show_ip_pim_assert_metric,
1670 show_ip_pim_assert_metric_cmd,
1671 "show ip pim assert-metric",
1672 SHOW_STR
1673 IP_STR
1674 PIM_STR
1675 "PIM interface assert metric\n")
1676{
1677 pim_show_assert_metric(vty);
1678
1679 return CMD_SUCCESS;
1680}
1681
1682DEFUN (show_ip_pim_assert_winner_metric,
1683 show_ip_pim_assert_winner_metric_cmd,
1684 "show ip pim assert-winner-metric",
1685 SHOW_STR
1686 IP_STR
1687 PIM_STR
1688 "PIM interface assert winner metric\n")
1689{
1690 pim_show_assert_winner_metric(vty);
1691
1692 return CMD_SUCCESS;
1693}
1694
1695DEFUN (show_ip_pim_dr,
1696 show_ip_pim_dr_cmd,
1697 "show ip pim designated-router",
1698 SHOW_STR
1699 IP_STR
1700 PIM_STR
1701 "PIM interface designated router\n")
1702{
1703 pim_show_dr(vty);
1704
1705 return CMD_SUCCESS;
1706}
1707
1708DEFUN (show_ip_pim_hello,
1709 show_ip_pim_hello_cmd,
1710 "show ip pim hello",
1711 SHOW_STR
1712 IP_STR
1713 PIM_STR
1714 "PIM interface hello information\n")
1715{
1716 pim_show_hello(vty);
1717
1718 return CMD_SUCCESS;
1719}
1720
1721DEFUN (show_ip_pim_interface,
1722 show_ip_pim_interface_cmd,
1723 "show ip pim interface",
1724 SHOW_STR
1725 IP_STR
1726 PIM_STR
1727 "PIM interface information\n")
1728{
1729 pim_show_interfaces(vty);
1730
1731 return CMD_SUCCESS;
1732}
1733
1734DEFUN (show_ip_pim_join,
1735 show_ip_pim_join_cmd,
1736 "show ip pim join",
1737 SHOW_STR
1738 IP_STR
1739 PIM_STR
1740 "PIM interface join information\n")
1741{
1742 pim_show_join(vty);
1743
1744 return CMD_SUCCESS;
1745}
1746
1747DEFUN (show_ip_pim_lan_prune_delay,
1748 show_ip_pim_lan_prune_delay_cmd,
1749 "show ip pim lan-prune-delay",
1750 SHOW_STR
1751 IP_STR
1752 PIM_STR
1753 "PIM neighbors LAN prune delay parameters\n")
1754{
1755 pim_show_lan_prune_delay(vty);
1756
1757 return CMD_SUCCESS;
1758}
1759
1760DEFUN (show_ip_pim_local_membership,
1761 show_ip_pim_local_membership_cmd,
1762 "show ip pim local-membership",
1763 SHOW_STR
1764 IP_STR
1765 PIM_STR
1766 "PIM interface local-membership\n")
1767{
1768 pim_show_membership(vty);
1769
1770 return CMD_SUCCESS;
1771}
1772
1773DEFUN (show_ip_pim_jp_override_interval,
1774 show_ip_pim_jp_override_interval_cmd,
1775 "show ip pim jp-override-interval",
1776 SHOW_STR
1777 IP_STR
1778 PIM_STR
1779 "PIM interface J/P override interval\n")
1780{
1781 pim_show_jp_override_interval(vty);
1782
1783 return CMD_SUCCESS;
1784}
1785
1786DEFUN (show_ip_pim_neighbor,
1787 show_ip_pim_neighbor_cmd,
1788 "show ip pim neighbor",
1789 SHOW_STR
1790 IP_STR
1791 PIM_STR
1792 "PIM neighbor information\n")
1793{
1794 pim_show_neighbors(vty);
1795
1796 return CMD_SUCCESS;
1797}
1798
1799DEFUN (show_ip_pim_secondary,
1800 show_ip_pim_secondary_cmd,
1801 "show ip pim secondary",
1802 SHOW_STR
1803 IP_STR
1804 PIM_STR
1805 "PIM neighbor addresses\n")
1806{
1807 pim_show_neighbors_secondary(vty);
1808
1809 return CMD_SUCCESS;
1810}
1811
1812DEFUN (show_ip_pim_upstream,
1813 show_ip_pim_upstream_cmd,
1814 "show ip pim upstream",
1815 SHOW_STR
1816 IP_STR
1817 PIM_STR
1818 "PIM upstream information\n")
1819{
1820 pim_show_upstream(vty);
1821
1822 return CMD_SUCCESS;
1823}
1824
1825DEFUN (show_ip_pim_upstream_join_desired,
1826 show_ip_pim_upstream_join_desired_cmd,
1827 "show ip pim upstream-join-desired",
1828 SHOW_STR
1829 IP_STR
1830 PIM_STR
1831 "PIM upstream join-desired\n")
1832{
1833 pim_show_join_desired(vty);
1834
1835 return CMD_SUCCESS;
1836}
1837
1838DEFUN (show_ip_pim_upstream_rpf,
1839 show_ip_pim_upstream_rpf_cmd,
1840 "show ip pim upstream-rpf",
1841 SHOW_STR
1842 IP_STR
1843 PIM_STR
1844 "PIM upstream source rpf\n")
1845{
1846 pim_show_upstream_rpf(vty);
1847
1848 return CMD_SUCCESS;
1849}
1850
1851DEFUN (show_ip_pim_rpf,
1852 show_ip_pim_rpf_cmd,
1853 "show ip pim rpf",
1854 SHOW_STR
1855 IP_STR
1856 PIM_STR
1857 "PIM cached source rpf information\n")
1858{
1859 pim_show_rpf(vty);
1860
1861 return CMD_SUCCESS;
1862}
1863
1864static void show_multicast_interfaces(struct vty *vty)
1865{
1866 struct listnode *node;
1867 struct interface *ifp;
1868
1869 vty_out(vty, "%s", VTY_NEWLINE);
1870
Everton Marques613938d2009-08-13 15:39:31 -03001871 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03001872 VTY_NEWLINE);
1873
1874 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
1875 struct pim_interface *pim_ifp;
1876 struct in_addr ifaddr;
1877 struct sioc_vif_req vreq;
1878
1879 pim_ifp = ifp->info;
1880
1881 if (!pim_ifp)
1882 continue;
1883
1884 memset(&vreq, 0, sizeof(vreq));
1885 vreq.vifi = pim_ifp->mroute_vif_index;
1886
1887 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
1888 int e = errno;
1889 vty_out(vty,
1890 "ioctl(SIOCGETVIFCNT=%d) failure for interface %s vif_index=%d: errno=%d: %s%s",
1891 SIOCGETVIFCNT,
1892 ifp->name,
1893 pim_ifp->mroute_vif_index,
1894 e,
Everton Marquese96f0af2009-08-11 15:48:02 -03001895 safe_strerror(e),
Everton Marques871dbcf2009-08-11 15:43:05 -03001896 VTY_NEWLINE);
1897 continue;
1898 }
1899
1900 ifaddr = pim_ifp->primary_address;
1901
Everton Marques613938d2009-08-13 15:39:31 -03001902 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03001903 ifp->name,
1904 inet_ntoa(ifaddr),
1905 ifp->ifindex,
1906 pim_ifp->mroute_vif_index,
1907 vreq.icount,
1908 vreq.ocount,
1909 vreq.ibytes,
1910 vreq.obytes,
1911 VTY_NEWLINE);
1912 }
1913}
1914
1915DEFUN (show_ip_multicast,
1916 show_ip_multicast_cmd,
1917 "show ip multicast",
1918 SHOW_STR
1919 IP_STR
1920 "Multicast global information\n")
1921{
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001922 time_t now = pim_time_monotonic_sec();
1923
Everton Marques871dbcf2009-08-11 15:43:05 -03001924 if (PIM_MROUTE_IS_ENABLED) {
Everton Marques871dbcf2009-08-11 15:43:05 -03001925 char uptime[10];
1926
1927 vty_out(vty, "Mroute socket descriptor: %d%s",
1928 qpim_mroute_socket_fd,
1929 VTY_NEWLINE);
1930
Everton Marques871dbcf2009-08-11 15:43:05 -03001931 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
1932 vty_out(vty, "Mroute socket uptime: %s%s",
1933 uptime,
1934 VTY_NEWLINE);
1935 }
1936 else {
1937 vty_out(vty, "Multicast disabled%s",
1938 VTY_NEWLINE);
1939 }
1940
1941 vty_out(vty, "%s", VTY_NEWLINE);
1942 vty_out(vty, "Current highest VifIndex: %d%s",
1943 qpim_mroute_oif_highest_vif_index,
1944 VTY_NEWLINE);
1945 vty_out(vty, "Maximum highest VifIndex: %d%s",
1946 MAXVIFS - 1,
1947 VTY_NEWLINE);
1948
1949 vty_out(vty, "%s", VTY_NEWLINE);
1950 vty_out(vty, "Upstream Join Timer: %d secs%s",
1951 qpim_t_periodic,
1952 VTY_NEWLINE);
1953 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
1954 PIM_JP_HOLDTIME,
1955 VTY_NEWLINE);
1956
1957 vty_out(vty, "%s", VTY_NEWLINE);
Everton Marques613938d2009-08-13 15:39:31 -03001958
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001959 show_rpf_refresh_stats(vty, now);
Everton Marques871dbcf2009-08-11 15:43:05 -03001960
1961 show_multicast_interfaces(vty);
1962
1963 return CMD_SUCCESS;
1964}
1965
1966static void show_mroute(struct vty *vty)
1967{
1968 struct listnode *node;
1969 struct channel_oil *c_oil;
1970 time_t now;
1971
1972 vty_out(vty, "Proto: I=IGMP P=PIM%s%s", VTY_NEWLINE, VTY_NEWLINE);
1973
1974 vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
1975 VTY_NEWLINE);
1976
1977 now = pim_time_monotonic_sec();
1978
1979 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1980 char group_str[100];
1981 char source_str[100];
1982 int oif_vif_index;
1983
1984 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1985 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1986
1987 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
1988 struct interface *ifp_in;
1989 struct interface *ifp_out;
1990 char oif_uptime[10];
1991 int ttl;
1992 char proto[5];
1993
1994 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
1995 if (ttl < 1)
1996 continue;
1997
1998 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
1999 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2000
2001 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
2002
2003 proto[0] = '\0';
2004 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2005 strcat(proto, "P");
2006 }
2007 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2008 strcat(proto, "I");
2009 }
2010
2011 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2012 source_str,
2013 group_str,
2014 proto,
2015 ifp_in ? ifp_in->name : "<iif?>",
2016 c_oil->oil.mfcc_parent,
2017 ifp_out ? ifp_out->name : "<oif?>",
2018 oif_vif_index,
2019 ttl,
2020 oif_uptime,
2021 VTY_NEWLINE);
2022 }
2023 }
2024}
2025
2026DEFUN (show_ip_mroute,
2027 show_ip_mroute_cmd,
2028 "show ip mroute",
2029 SHOW_STR
2030 IP_STR
2031 MROUTE_STR)
2032{
2033 show_mroute(vty);
2034 return CMD_SUCCESS;
2035}
2036
2037static void show_mroute_count(struct vty *vty)
2038{
2039 struct listnode *node;
2040 struct channel_oil *c_oil;
2041
2042 vty_out(vty, "%s", VTY_NEWLINE);
2043
2044 vty_out(vty, "Source Group Packets Bytes WrongIf %s",
2045 VTY_NEWLINE);
2046
2047 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2048 char group_str[100];
2049 char source_str[100];
2050 struct sioc_sg_req sgreq;
2051
2052 memset(&sgreq, 0, sizeof(sgreq));
2053 sgreq.src = c_oil->oil.mfcc_origin;
2054 sgreq.grp = c_oil->oil.mfcc_mcastgrp;
2055
2056 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2057 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2058
2059 if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
2060 int e = errno;
2061 vty_out(vty,
2062 "ioctl(SIOCGETSGCNT=%d) failure for (S,G)=(%s,%s): errno=%d: %s%s",
2063 SIOCGETSGCNT,
2064 source_str,
2065 group_str,
2066 e,
Everton Marquese96f0af2009-08-11 15:48:02 -03002067 safe_strerror(e),
Everton Marques871dbcf2009-08-11 15:43:05 -03002068 VTY_NEWLINE);
2069 continue;
2070 }
2071
2072 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2073 source_str,
2074 group_str,
2075 sgreq.pktcnt,
2076 sgreq.bytecnt,
2077 sgreq.wrong_if,
2078 VTY_NEWLINE);
2079
2080 }
2081}
2082
2083DEFUN (show_ip_mroute_count,
2084 show_ip_mroute_count_cmd,
2085 "show ip mroute count",
2086 SHOW_STR
2087 IP_STR
2088 MROUTE_STR
2089 "Route and packet count data\n")
2090{
2091 show_mroute_count(vty);
2092 return CMD_SUCCESS;
2093}
2094
2095DEFUN (show_ip_route,
2096 show_ip_route_cmd,
2097 "show ip route A.B.C.D",
2098 SHOW_STR
2099 IP_STR
2100 ROUTE_STR
2101 "Unicast address\n")
2102{
2103 struct in_addr addr;
2104 const char *addr_str;
2105 struct pim_nexthop nexthop;
2106 char nexthop_addr_str[100];
2107 int result;
2108
2109 addr_str = argv[0];
2110 result = inet_pton(AF_INET, addr_str, &addr);
2111 if (result <= 0) {
2112 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002113 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002114 return CMD_WARNING;
2115 }
2116
2117 if (pim_nexthop_lookup(&nexthop, addr)) {
2118 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
2119 addr_str, VTY_NEWLINE);
2120 return CMD_WARNING;
2121 }
2122
2123 vty_out(vty, "Address NextHop Interface Metric Preference%s",
2124 VTY_NEWLINE);
2125
2126 pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
2127 nexthop_addr_str, sizeof(nexthop_addr_str));
2128
2129 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
2130 addr_str,
2131 nexthop_addr_str,
2132 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2133 nexthop.mrib_route_metric,
2134 nexthop.mrib_metric_preference,
2135 VTY_NEWLINE);
2136
2137 return CMD_SUCCESS;
2138}
2139
2140static void mroute_add_all()
2141{
2142 struct listnode *node;
2143 struct channel_oil *c_oil;
2144
2145 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2146 if (pim_mroute_add(&c_oil->oil)) {
2147 /* just log warning */
2148 char source_str[100];
2149 char group_str[100];
2150 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2151 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2152 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2153 __FILE__, __PRETTY_FUNCTION__,
2154 source_str, group_str);
2155 }
2156 }
2157}
2158
2159static void mroute_del_all()
2160{
2161 struct listnode *node;
2162 struct channel_oil *c_oil;
2163
2164 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2165 if (pim_mroute_del(&c_oil->oil)) {
2166 /* just log warning */
2167 char source_str[100];
2168 char group_str[100];
2169 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2170 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2171 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2172 __FILE__, __PRETTY_FUNCTION__,
2173 source_str, group_str);
2174 }
2175 }
2176}
2177
2178DEFUN (ip_multicast_routing,
2179 ip_multicast_routing_cmd,
2180 PIM_CMD_IP_MULTICAST_ROUTING,
2181 IP_STR
2182 "Enable IP multicast forwarding\n")
2183{
2184 pim_mroute_socket_enable();
2185 pim_if_add_vif_all();
2186 mroute_add_all();
2187 return CMD_SUCCESS;
2188}
2189
2190DEFUN (no_ip_multicast_routing,
2191 no_ip_multicast_routing_cmd,
2192 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
2193 NO_STR
2194 IP_STR
2195 "Global IP configuration subcommands\n"
2196 "Enable IP multicast forwarding\n")
2197{
2198 mroute_del_all();
2199 pim_if_del_vif_all();
2200 pim_mroute_socket_disable();
2201 return CMD_SUCCESS;
2202}
2203
2204DEFUN (interface_ip_igmp,
2205 interface_ip_igmp_cmd,
2206 "ip igmp",
2207 IP_STR
2208 IFACE_IGMP_STR)
2209{
2210 struct interface *ifp;
2211 struct pim_interface *pim_ifp;
2212
2213 ifp = vty->index;
2214 pim_ifp = ifp->info;
2215
2216 if (!pim_ifp) {
2217 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2218 if (!pim_ifp) {
2219 vty_out(vty, "Could not enable IGMP on interface %s%s",
2220 ifp->name, VTY_NEWLINE);
2221 return CMD_WARNING;
2222 }
2223 }
2224 else {
2225 PIM_IF_DO_IGMP(pim_ifp->options);
2226 }
2227
2228 pim_if_addr_add_all(ifp);
2229 pim_if_membership_refresh(ifp);
2230
2231 return CMD_SUCCESS;
2232}
2233
2234DEFUN (interface_no_ip_igmp,
2235 interface_no_ip_igmp_cmd,
2236 "no ip igmp",
2237 NO_STR
2238 IP_STR
2239 IFACE_IGMP_STR)
2240{
2241 struct interface *ifp;
2242 struct pim_interface *pim_ifp;
2243
2244 ifp = vty->index;
2245 pim_ifp = ifp->info;
2246 if (!pim_ifp)
2247 return CMD_SUCCESS;
2248
2249 PIM_IF_DONT_IGMP(pim_ifp->options);
2250
2251 pim_if_membership_clear(ifp);
2252
2253 pim_if_addr_del_all(ifp);
2254
2255 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2256 pim_if_delete(ifp);
2257 }
2258
2259 return CMD_SUCCESS;
2260}
2261
2262DEFUN (interface_ip_igmp_join,
2263 interface_ip_igmp_join_cmd,
2264 "ip igmp join A.B.C.D A.B.C.D",
2265 IP_STR
2266 IFACE_IGMP_STR
2267 "IGMP join multicast group\n"
2268 "Multicast group address\n"
2269 "Source address\n")
2270{
2271 struct interface *ifp;
2272 const char *group_str;
2273 const char *source_str;
2274 struct in_addr group_addr;
2275 struct in_addr source_addr;
2276 int result;
2277
2278 ifp = vty->index;
2279
2280 /* Group address */
2281 group_str = argv[0];
2282 result = inet_pton(AF_INET, group_str, &group_addr);
2283 if (result <= 0) {
2284 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002285 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002286 return CMD_WARNING;
2287 }
2288
2289 /* Source address */
2290 source_str = argv[1];
2291 result = inet_pton(AF_INET, source_str, &source_addr);
2292 if (result <= 0) {
2293 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002294 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002295 return CMD_WARNING;
2296 }
2297
2298 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2299 if (result) {
2300 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2301 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2302 return CMD_WARNING;
2303 }
2304
2305 return CMD_SUCCESS;
2306}
2307
2308DEFUN (interface_no_ip_igmp_join,
2309 interface_no_ip_igmp_join_cmd,
2310 "no ip igmp join A.B.C.D A.B.C.D",
2311 NO_STR
2312 IP_STR
2313 IFACE_IGMP_STR
2314 "IGMP join multicast group\n"
2315 "Multicast group address\n"
2316 "Source address\n")
2317{
2318 struct interface *ifp;
2319 const char *group_str;
2320 const char *source_str;
2321 struct in_addr group_addr;
2322 struct in_addr source_addr;
2323 int result;
2324
2325 ifp = vty->index;
2326
2327 /* Group address */
2328 group_str = argv[0];
2329 result = inet_pton(AF_INET, group_str, &group_addr);
2330 if (result <= 0) {
2331 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002332 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002333 return CMD_WARNING;
2334 }
2335
2336 /* Source address */
2337 source_str = argv[1];
2338 result = inet_pton(AF_INET, source_str, &source_addr);
2339 if (result <= 0) {
2340 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002341 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002342 return CMD_WARNING;
2343 }
2344
2345 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2346 if (result) {
2347 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2348 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2349 return CMD_WARNING;
2350 }
2351
2352 return CMD_SUCCESS;
2353}
2354
2355/*
2356 CLI reconfiguration affects the interface level (struct pim_interface).
2357 This function propagates the reconfiguration to every active socket
2358 for that interface.
2359 */
2360static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2361{
2362 struct interface *ifp;
2363 struct pim_interface *pim_ifp;
2364
2365 zassert(igmp);
2366
2367 /* other querier present? */
2368
2369 if (igmp->t_other_querier_timer)
2370 return;
2371
2372 /* this is the querier */
2373
2374 zassert(igmp->interface);
2375 zassert(igmp->interface->info);
2376
2377 ifp = igmp->interface;
2378 pim_ifp = ifp->info;
2379
2380 if (PIM_DEBUG_IGMP_TRACE) {
2381 char ifaddr_str[100];
2382 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2383 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2384 __PRETTY_FUNCTION__,
2385 ifaddr_str,
2386 ifp->name,
2387 pim_ifp->igmp_default_query_interval);
2388 }
2389
2390 /*
2391 igmp_startup_mode_on() will reset QQI:
2392
2393 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2394 */
2395 igmp_startup_mode_on(igmp);
2396}
2397
2398static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2399{
2400 if (igmp->t_igmp_query_timer) {
2401 /* other querier present */
2402 zassert(igmp->t_igmp_query_timer);
2403 zassert(!igmp->t_other_querier_timer);
2404
2405 pim_igmp_general_query_off(igmp);
2406 pim_igmp_general_query_on(igmp);
2407
2408 zassert(igmp->t_igmp_query_timer);
2409 zassert(!igmp->t_other_querier_timer);
2410 }
2411 else {
2412 /* this is the querier */
2413
2414 zassert(!igmp->t_igmp_query_timer);
2415 zassert(igmp->t_other_querier_timer);
2416
2417 pim_igmp_other_querier_timer_off(igmp);
2418 pim_igmp_other_querier_timer_on(igmp);
2419
2420 zassert(!igmp->t_igmp_query_timer);
2421 zassert(igmp->t_other_querier_timer);
2422 }
2423}
2424
2425static void change_query_interval(struct pim_interface *pim_ifp,
2426 int query_interval)
2427{
2428 struct listnode *sock_node;
2429 struct igmp_sock *igmp;
2430
2431 pim_ifp->igmp_default_query_interval = query_interval;
2432
2433 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2434 igmp_sock_query_interval_reconfig(igmp);
2435 igmp_sock_query_reschedule(igmp);
2436 }
2437}
2438
2439static void change_query_max_response_time(struct pim_interface *pim_ifp,
2440 int query_max_response_time_dsec)
2441{
2442 struct listnode *sock_node;
2443 struct igmp_sock *igmp;
2444
2445 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2446
2447 /*
2448 Below we modify socket/group/source timers in order to quickly
2449 reflect the change. Otherwise, those timers would eventually catch
2450 up.
2451 */
2452
2453 /* scan all sockets */
2454 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2455 struct listnode *grp_node;
2456 struct igmp_group *grp;
2457
2458 /* reschedule socket general query */
2459 igmp_sock_query_reschedule(igmp);
2460
2461 /* scan socket groups */
2462 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2463 struct listnode *src_node;
2464 struct igmp_source *src;
2465
2466 /* reset group timers for groups in EXCLUDE mode */
2467 if (grp->group_filtermode_isexcl) {
2468 igmp_group_reset_gmi(grp);
2469 }
2470
2471 /* scan group sources */
2472 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2473
2474 /* reset source timers for sources with running timers */
2475 if (src->t_source_timer) {
2476 igmp_source_reset_gmi(igmp, grp, src);
2477 }
2478 }
2479 }
2480 }
2481}
2482
2483#define IGMP_QUERY_INTERVAL_MIN (1)
2484#define IGMP_QUERY_INTERVAL_MAX (1800)
2485
2486DEFUN (interface_ip_igmp_query_interval,
2487 interface_ip_igmp_query_interval_cmd,
2488 PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
2489 IP_STR
2490 IFACE_IGMP_STR
2491 IFACE_IGMP_QUERY_INTERVAL_STR
2492 "Query interval in seconds\n")
2493{
2494 struct interface *ifp;
2495 struct pim_interface *pim_ifp;
2496 int query_interval;
2497 int query_interval_dsec;
2498
2499 ifp = vty->index;
2500 pim_ifp = ifp->info;
2501
2502 if (!pim_ifp) {
2503 vty_out(vty,
2504 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2505 ifp->name,
2506 VTY_NEWLINE);
2507 return CMD_WARNING;
2508 }
2509
2510 query_interval = atoi(argv[0]);
2511 query_interval_dsec = 10 * query_interval;
2512
2513 /*
2514 It seems we don't need to check bounds since command.c does it
2515 already, but we verify them anyway for extra safety.
2516 */
2517 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
2518 vty_out(vty, "General query interval %d lower than minimum %d%s",
2519 query_interval,
2520 IGMP_QUERY_INTERVAL_MIN,
2521 VTY_NEWLINE);
2522 return CMD_WARNING;
2523 }
2524 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
2525 vty_out(vty, "General query interval %d higher than maximum %d%s",
2526 query_interval,
2527 IGMP_QUERY_INTERVAL_MAX,
2528 VTY_NEWLINE);
2529 return CMD_WARNING;
2530 }
2531
2532 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2533 vty_out(vty,
2534 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
2535 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2536 VTY_NEWLINE);
2537 return CMD_WARNING;
2538 }
2539
2540 change_query_interval(pim_ifp, query_interval);
2541
2542 return CMD_SUCCESS;
2543}
2544
2545DEFUN (interface_no_ip_igmp_query_interval,
2546 interface_no_ip_igmp_query_interval_cmd,
2547 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
2548 NO_STR
2549 IP_STR
2550 IFACE_IGMP_STR
2551 IFACE_IGMP_QUERY_INTERVAL_STR)
2552{
2553 struct interface *ifp;
2554 struct pim_interface *pim_ifp;
2555 int default_query_interval_dsec;
2556
2557 ifp = vty->index;
2558 pim_ifp = ifp->info;
2559
2560 if (!pim_ifp)
2561 return CMD_SUCCESS;
2562
2563 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
2564
2565 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2566 vty_out(vty,
2567 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
2568 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2569 VTY_NEWLINE);
2570 return CMD_WARNING;
2571 }
2572
2573 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
2574
2575 return CMD_SUCCESS;
2576}
2577
2578#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
2579#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
2580
2581DEFUN (interface_ip_igmp_query_max_response_time,
2582 interface_ip_igmp_query_max_response_time_cmd,
2583 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
2584 IP_STR
2585 IFACE_IGMP_STR
2586 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
2587 "Query response value in seconds\n")
2588{
2589 struct interface *ifp;
2590 struct pim_interface *pim_ifp;
2591 int query_max_response_time;
2592
2593 ifp = vty->index;
2594 pim_ifp = ifp->info;
2595
2596 if (!pim_ifp) {
2597 vty_out(vty,
2598 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2599 ifp->name,
2600 VTY_NEWLINE);
2601 return CMD_WARNING;
2602 }
2603
2604 query_max_response_time = atoi(argv[0]);
2605
2606 /*
2607 It seems we don't need to check bounds since command.c does it
2608 already, but we verify them anyway for extra safety.
2609 */
2610 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
2611 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
2612 query_max_response_time,
2613 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
2614 VTY_NEWLINE);
2615 return CMD_WARNING;
2616 }
2617 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
2618 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
2619 query_max_response_time,
2620 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
2621 VTY_NEWLINE);
2622 return CMD_WARNING;
2623 }
2624
2625 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
2626 vty_out(vty,
2627 "Can't set query max response time %d sec >= general query interval %d sec%s",
2628 query_max_response_time, pim_ifp->igmp_default_query_interval,
2629 VTY_NEWLINE);
2630 return CMD_WARNING;
2631 }
2632
2633 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
2634
2635 return CMD_SUCCESS;
2636}
2637
2638DEFUN (interface_no_ip_igmp_query_max_response_time,
2639 interface_no_ip_igmp_query_max_response_time_cmd,
2640 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
2641 NO_STR
2642 IP_STR
2643 IFACE_IGMP_STR
2644 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
2645{
2646 struct interface *ifp;
2647 struct pim_interface *pim_ifp;
2648 int default_query_interval_dsec;
2649
2650 ifp = vty->index;
2651 pim_ifp = ifp->info;
2652
2653 if (!pim_ifp)
2654 return CMD_SUCCESS;
2655
2656 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2657
2658 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
2659 vty_out(vty,
2660 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
2661 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
2662 VTY_NEWLINE);
2663 return CMD_WARNING;
2664 }
2665
2666 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
2667
2668 return CMD_SUCCESS;
2669}
2670
2671#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
2672#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
2673
2674DEFUN (interface_ip_igmp_query_max_response_time_dsec,
2675 interface_ip_igmp_query_max_response_time_dsec_cmd,
2676 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
2677 IP_STR
2678 IFACE_IGMP_STR
2679 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
2680 "Query response value in deciseconds\n")
2681{
2682 struct interface *ifp;
2683 struct pim_interface *pim_ifp;
2684 int query_max_response_time_dsec;
2685 int default_query_interval_dsec;
2686
2687 ifp = vty->index;
2688 pim_ifp = ifp->info;
2689
2690 if (!pim_ifp) {
2691 vty_out(vty,
2692 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2693 ifp->name,
2694 VTY_NEWLINE);
2695 return CMD_WARNING;
2696 }
2697
2698 query_max_response_time_dsec = atoi(argv[0]);
2699
2700 /*
2701 It seems we don't need to check bounds since command.c does it
2702 already, but we verify them anyway for extra safety.
2703 */
2704 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
2705 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
2706 query_max_response_time_dsec,
2707 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
2708 VTY_NEWLINE);
2709 return CMD_WARNING;
2710 }
2711 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
2712 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
2713 query_max_response_time_dsec,
2714 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
2715 VTY_NEWLINE);
2716 return CMD_WARNING;
2717 }
2718
2719 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2720
2721 if (query_max_response_time_dsec >= default_query_interval_dsec) {
2722 vty_out(vty,
2723 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
2724 query_max_response_time_dsec, default_query_interval_dsec,
2725 VTY_NEWLINE);
2726 return CMD_WARNING;
2727 }
2728
2729 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
2730
2731 return CMD_SUCCESS;
2732}
2733
2734DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
2735 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
2736 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
2737 NO_STR
2738 IP_STR
2739 IFACE_IGMP_STR
2740 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
2741{
2742 struct interface *ifp;
2743 struct pim_interface *pim_ifp;
2744 int default_query_interval_dsec;
2745
2746 ifp = vty->index;
2747 pim_ifp = ifp->info;
2748
2749 if (!pim_ifp)
2750 return CMD_SUCCESS;
2751
2752 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2753
2754 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
2755 vty_out(vty,
2756 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
2757 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
2758 VTY_NEWLINE);
2759 return CMD_WARNING;
2760 }
2761
2762 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
2763
2764 return CMD_SUCCESS;
2765}
2766
2767DEFUN (interface_ip_pim_ssm,
2768 interface_ip_pim_ssm_cmd,
2769 "ip pim ssm",
2770 IP_STR
2771 PIM_STR
2772 IFACE_PIM_STR)
2773{
2774 struct interface *ifp;
2775 struct pim_interface *pim_ifp;
2776
2777 ifp = vty->index;
2778 pim_ifp = ifp->info;
2779
2780 if (!pim_ifp) {
2781 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
2782 if (!pim_ifp) {
2783 vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
2784 return CMD_WARNING;
2785 }
2786 }
2787 else {
2788 PIM_IF_DO_PIM(pim_ifp->options);
2789 }
2790
2791 pim_if_addr_add_all(ifp);
2792 pim_if_membership_refresh(ifp);
2793
2794 return CMD_SUCCESS;
2795}
2796
2797DEFUN (interface_no_ip_pim_ssm,
2798 interface_no_ip_pim_ssm_cmd,
2799 "no ip pim ssm",
2800 NO_STR
2801 IP_STR
2802 PIM_STR
2803 IFACE_PIM_STR)
2804{
2805 struct interface *ifp;
2806 struct pim_interface *pim_ifp;
2807
2808 ifp = vty->index;
2809 pim_ifp = ifp->info;
2810 if (!pim_ifp)
2811 return CMD_SUCCESS;
2812
2813 PIM_IF_DONT_PIM(pim_ifp->options);
2814
2815 pim_if_membership_clear(ifp);
2816
2817 /*
2818 pim_if_addr_del_all() removes all sockets from
2819 pim_ifp->igmp_socket_list.
2820 */
2821 pim_if_addr_del_all(ifp);
2822
2823 /*
2824 pim_sock_delete() removes all neighbors from
2825 pim_ifp->pim_neighbor_list.
2826 */
2827 pim_sock_delete(ifp, "pim unconfigured on interface");
2828
2829 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
2830 pim_if_delete(ifp);
2831 }
2832
2833 return CMD_SUCCESS;
2834}
2835
2836DEFUN (debug_igmp,
2837 debug_igmp_cmd,
2838 "debug igmp",
2839 DEBUG_STR
2840 DEBUG_IGMP_STR)
2841{
2842 PIM_DO_DEBUG_IGMP_EVENTS;
2843 PIM_DO_DEBUG_IGMP_PACKETS;
2844 PIM_DO_DEBUG_IGMP_TRACE;
2845 return CMD_SUCCESS;
2846}
2847
2848DEFUN (no_debug_igmp,
2849 no_debug_igmp_cmd,
2850 "no debug igmp",
2851 NO_STR
2852 DEBUG_STR
2853 DEBUG_IGMP_STR)
2854{
2855 PIM_DONT_DEBUG_IGMP_EVENTS;
2856 PIM_DONT_DEBUG_IGMP_PACKETS;
2857 PIM_DONT_DEBUG_IGMP_TRACE;
2858 return CMD_SUCCESS;
2859}
2860
2861ALIAS (no_debug_igmp,
2862 undebug_igmp_cmd,
2863 "undebug igmp",
2864 UNDEBUG_STR
2865 DEBUG_IGMP_STR)
2866
2867DEFUN (debug_igmp_events,
2868 debug_igmp_events_cmd,
2869 "debug igmp events",
2870 DEBUG_STR
2871 DEBUG_IGMP_STR
2872 DEBUG_IGMP_EVENTS_STR)
2873{
2874 PIM_DO_DEBUG_IGMP_EVENTS;
2875 return CMD_SUCCESS;
2876}
2877
2878DEFUN (no_debug_igmp_events,
2879 no_debug_igmp_events_cmd,
2880 "no debug igmp events",
2881 NO_STR
2882 DEBUG_STR
2883 DEBUG_IGMP_STR
2884 DEBUG_IGMP_EVENTS_STR)
2885{
2886 PIM_DONT_DEBUG_IGMP_EVENTS;
2887 return CMD_SUCCESS;
2888}
2889
2890ALIAS (no_debug_igmp_events,
2891 undebug_igmp_events_cmd,
2892 "undebug igmp events",
2893 UNDEBUG_STR
2894 DEBUG_IGMP_STR
2895 DEBUG_IGMP_EVENTS_STR)
2896
2897DEFUN (debug_igmp_packets,
2898 debug_igmp_packets_cmd,
2899 "debug igmp packets",
2900 DEBUG_STR
2901 DEBUG_IGMP_STR
2902 DEBUG_IGMP_PACKETS_STR)
2903{
2904 PIM_DO_DEBUG_IGMP_PACKETS;
2905 return CMD_SUCCESS;
2906}
2907
2908DEFUN (no_debug_igmp_packets,
2909 no_debug_igmp_packets_cmd,
2910 "no debug igmp packets",
2911 NO_STR
2912 DEBUG_STR
2913 DEBUG_IGMP_STR
2914 DEBUG_IGMP_PACKETS_STR)
2915{
2916 PIM_DONT_DEBUG_IGMP_PACKETS;
2917 return CMD_SUCCESS;
2918}
2919
2920ALIAS (no_debug_igmp_packets,
2921 undebug_igmp_packets_cmd,
2922 "undebug igmp packets",
2923 UNDEBUG_STR
2924 DEBUG_IGMP_STR
2925 DEBUG_IGMP_PACKETS_STR)
2926
2927DEFUN (debug_igmp_trace,
2928 debug_igmp_trace_cmd,
2929 "debug igmp trace",
2930 DEBUG_STR
2931 DEBUG_IGMP_STR
2932 DEBUG_IGMP_TRACE_STR)
2933{
2934 PIM_DO_DEBUG_IGMP_TRACE;
2935 return CMD_SUCCESS;
2936}
2937
2938DEFUN (no_debug_igmp_trace,
2939 no_debug_igmp_trace_cmd,
2940 "no debug igmp trace",
2941 NO_STR
2942 DEBUG_STR
2943 DEBUG_IGMP_STR
2944 DEBUG_IGMP_TRACE_STR)
2945{
2946 PIM_DONT_DEBUG_IGMP_TRACE;
2947 return CMD_SUCCESS;
2948}
2949
2950ALIAS (no_debug_igmp_trace,
2951 undebug_igmp_trace_cmd,
2952 "undebug igmp trace",
2953 UNDEBUG_STR
2954 DEBUG_IGMP_STR
2955 DEBUG_IGMP_TRACE_STR)
2956
2957DEFUN (debug_pim,
2958 debug_pim_cmd,
2959 "debug pim",
2960 DEBUG_STR
2961 DEBUG_PIM_STR)
2962{
2963 PIM_DO_DEBUG_PIM_EVENTS;
2964 PIM_DO_DEBUG_PIM_PACKETS;
2965 PIM_DO_DEBUG_PIM_TRACE;
2966 return CMD_SUCCESS;
2967}
2968
2969DEFUN (no_debug_pim,
2970 no_debug_pim_cmd,
2971 "no debug pim",
2972 NO_STR
2973 DEBUG_STR
2974 DEBUG_PIM_STR)
2975{
2976 PIM_DONT_DEBUG_PIM_EVENTS;
2977 PIM_DONT_DEBUG_PIM_PACKETS;
2978 PIM_DONT_DEBUG_PIM_TRACE;
2979 return CMD_SUCCESS;
2980}
2981
2982ALIAS (no_debug_pim,
2983 undebug_pim_cmd,
2984 "undebug pim",
2985 UNDEBUG_STR
2986 DEBUG_PIM_STR)
2987
2988DEFUN (debug_pim_events,
2989 debug_pim_events_cmd,
2990 "debug pim events",
2991 DEBUG_STR
2992 DEBUG_PIM_STR
2993 DEBUG_PIM_EVENTS_STR)
2994{
2995 PIM_DO_DEBUG_PIM_EVENTS;
2996 return CMD_SUCCESS;
2997}
2998
2999DEFUN (no_debug_pim_events,
3000 no_debug_pim_events_cmd,
3001 "no debug pim events",
3002 NO_STR
3003 DEBUG_STR
3004 DEBUG_PIM_STR
3005 DEBUG_PIM_EVENTS_STR)
3006{
3007 PIM_DONT_DEBUG_PIM_EVENTS;
3008 return CMD_SUCCESS;
3009}
3010
3011ALIAS (no_debug_pim_events,
3012 undebug_pim_events_cmd,
3013 "undebug pim events",
3014 UNDEBUG_STR
3015 DEBUG_PIM_STR
3016 DEBUG_PIM_EVENTS_STR)
3017
3018DEFUN (debug_pim_packets,
3019 debug_pim_packets_cmd,
3020 "debug pim packets",
3021 DEBUG_STR
3022 DEBUG_PIM_STR
3023 DEBUG_PIM_PACKETS_STR)
3024{
3025 PIM_DO_DEBUG_PIM_PACKETS;
3026 return CMD_SUCCESS;
3027}
3028
3029DEFUN (no_debug_pim_packets,
3030 no_debug_pim_packets_cmd,
3031 "no debug pim packets",
3032 NO_STR
3033 DEBUG_STR
3034 DEBUG_PIM_STR
3035 DEBUG_PIM_PACKETS_STR)
3036{
3037 PIM_DONT_DEBUG_PIM_PACKETS;
3038 return CMD_SUCCESS;
3039}
3040
3041ALIAS (no_debug_pim_packets,
3042 undebug_pim_packets_cmd,
3043 "undebug pim packets",
3044 UNDEBUG_STR
3045 DEBUG_PIM_STR
3046 DEBUG_PIM_PACKETS_STR)
3047
3048DEFUN (debug_pim_trace,
3049 debug_pim_trace_cmd,
3050 "debug pim trace",
3051 DEBUG_STR
3052 DEBUG_PIM_STR
3053 DEBUG_PIM_TRACE_STR)
3054{
3055 PIM_DO_DEBUG_PIM_TRACE;
3056 return CMD_SUCCESS;
3057}
3058
3059DEFUN (no_debug_pim_trace,
3060 no_debug_pim_trace_cmd,
3061 "no debug pim trace",
3062 NO_STR
3063 DEBUG_STR
3064 DEBUG_PIM_STR
3065 DEBUG_PIM_TRACE_STR)
3066{
3067 PIM_DONT_DEBUG_PIM_TRACE;
3068 return CMD_SUCCESS;
3069}
3070
3071ALIAS (no_debug_pim_trace,
3072 undebug_pim_trace_cmd,
3073 "undebug pim trace",
3074 UNDEBUG_STR
3075 DEBUG_PIM_STR
3076 DEBUG_PIM_TRACE_STR)
3077
3078DEFUN (debug_pim_zebra,
3079 debug_pim_zebra_cmd,
3080 "debug pim zebra",
3081 DEBUG_STR
3082 DEBUG_PIM_STR
3083 DEBUG_PIM_ZEBRA_STR)
3084{
3085 PIM_DO_DEBUG_ZEBRA;
3086 return CMD_SUCCESS;
3087}
3088
3089DEFUN (no_debug_pim_zebra,
3090 no_debug_pim_zebra_cmd,
3091 "no debug pim zebra",
3092 NO_STR
3093 DEBUG_STR
3094 DEBUG_PIM_STR
3095 DEBUG_PIM_ZEBRA_STR)
3096{
3097 PIM_DONT_DEBUG_ZEBRA;
3098 return CMD_SUCCESS;
3099}
3100
3101ALIAS (no_debug_pim_zebra,
3102 undebug_pim_zebra_cmd,
3103 "undebug pim zebra",
3104 UNDEBUG_STR
3105 DEBUG_PIM_STR
3106 DEBUG_PIM_ZEBRA_STR)
3107
3108DEFUN (show_debugging,
3109 show_debugging_cmd,
3110 "show debugging",
3111 SHOW_STR
3112 "State of each debugging option\n")
3113{
3114 pim_debug_config_write(vty);
3115 return CMD_SUCCESS;
3116}
3117
3118static struct igmp_sock *find_igmp_sock_by_fd(int fd)
3119{
3120 struct listnode *ifnode;
3121 struct interface *ifp;
3122
3123 /* scan all interfaces */
3124 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
3125 struct pim_interface *pim_ifp;
3126 struct igmp_sock *igmp;
3127
3128 if (!ifp->info)
3129 continue;
3130
3131 pim_ifp = ifp->info;
3132
3133 /* lookup igmp socket under current interface */
3134 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
3135 if (igmp)
3136 return igmp;
3137 }
3138
3139 return 0;
3140}
3141
3142DEFUN (test_igmp_receive_report,
3143 test_igmp_receive_report_cmd,
3144 "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
3145 "Test\n"
3146 "Test IGMP protocol\n"
3147 "Test IGMP message\n"
3148 "Test IGMP report\n"
3149 "Socket\n"
3150 "IGMP group address\n"
3151 "Record type\n"
3152 "Sources\n")
3153{
3154 char buf[1000];
3155 char *igmp_msg;
3156 struct ip *ip_hdr;
3157 size_t ip_hlen; /* ip header length in bytes */
3158 int ip_msg_len;
3159 int igmp_msg_len;
3160 const char *socket;
3161 int socket_fd;
3162 const char *grp_str;
3163 struct in_addr grp_addr;
3164 const char *record_type_str;
3165 int record_type;
3166 const char *src_str;
3167 int result;
3168 struct igmp_sock *igmp;
3169 char *group_record;
3170 int num_sources;
3171 struct in_addr *sources;
3172 struct in_addr *src_addr;
3173 int argi;
3174
3175 socket = argv[0];
3176 socket_fd = atoi(socket);
3177 igmp = find_igmp_sock_by_fd(socket_fd);
3178 if (!igmp) {
3179 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
3180 socket, socket_fd, VTY_NEWLINE);
3181 return CMD_WARNING;
3182 }
3183
3184 grp_str = argv[1];
3185 result = inet_pton(AF_INET, grp_str, &grp_addr);
3186 if (result <= 0) {
3187 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003188 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003189 return CMD_WARNING;
3190 }
3191
3192 record_type_str = argv[2];
3193 record_type = atoi(record_type_str);
3194
3195 /*
3196 Tweak IP header
3197 */
3198 ip_hdr = (struct ip *) buf;
3199 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
3200 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3201 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3202 ip_hdr->ip_src = igmp->ifaddr;
3203 ip_hdr->ip_dst = igmp->ifaddr;
3204
3205 /*
3206 Build IGMP v3 report message
3207 */
3208 igmp_msg = buf + ip_hlen;
3209 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
3210 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
3211 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
3212 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
3213 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
3214 *(struct in_addr *)(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET) = grp_addr;
3215
3216 /* Scan LINE sources */
3217 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
3218 src_addr = sources;
3219 for (argi = 3; argi < argc; ++argi,++src_addr) {
3220 src_str = argv[argi];
3221 result = inet_pton(AF_INET, src_str, src_addr);
3222 if (result <= 0) {
3223 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003224 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003225 return CMD_WARNING;
3226 }
3227 }
3228 num_sources = src_addr - sources;
3229
3230 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
3231
3232 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
3233
3234 /* compute checksum */
3235 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = pim_inet_checksum(igmp_msg, igmp_msg_len);
3236
3237 /* "receive" message */
3238
3239 ip_msg_len = ip_hlen + igmp_msg_len;
3240 result = pim_igmp_packet(igmp, buf, ip_msg_len);
3241 if (result) {
3242 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
3243 ip_msg_len, result, VTY_NEWLINE);
3244 return CMD_WARNING;
3245 }
3246
3247 return CMD_SUCCESS;
3248}
3249
3250DEFUN (test_pim_receive_hello,
3251 test_pim_receive_hello_cmd,
3252 "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
3253 "Test\n"
3254 "Test PIM protocol\n"
3255 "Test PIM message reception\n"
3256 "Test PIM hello reception from neighbor\n"
3257 "Interface\n"
3258 "Neighbor address\n"
3259 "Neighbor holdtime\n"
3260 "Neighbor DR priority\n"
3261 "Neighbor generation ID\n"
3262 "Neighbor propagation delay (msec)\n"
3263 "Neighbor override interval (msec)\n"
3264 "Neighbor LAN prune delay T-bit\n"
3265 "Neighbor secondary addresses\n")
3266{
3267 char buf[1000];
3268 char *pim_msg;
3269 struct ip *ip_hdr;
3270 size_t ip_hlen; /* ip header length in bytes */
3271 int ip_msg_len;
3272 int pim_tlv_size;
3273 int pim_msg_size;
3274 const char *neigh_str;
3275 struct in_addr neigh_addr;
3276 const char *ifname;
3277 struct interface *ifp;
3278 uint16_t neigh_holdtime;
3279 uint16_t neigh_propagation_delay;
3280 uint16_t neigh_override_interval;
3281 int neigh_can_disable_join_suppression;
3282 uint32_t neigh_dr_priority;
3283 uint32_t neigh_generation_id;
3284 int argi;
3285 int result;
3286
3287 /* Find interface */
3288 ifname = argv[0];
3289 ifp = if_lookup_by_name(ifname);
3290 if (!ifp) {
3291 vty_out(vty, "No such interface name %s%s",
3292 ifname, VTY_NEWLINE);
3293 return CMD_WARNING;
3294 }
3295
3296 /* Neighbor address */
3297 neigh_str = argv[1];
3298 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3299 if (result <= 0) {
3300 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003301 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003302 return CMD_WARNING;
3303 }
3304
3305 neigh_holdtime = atoi(argv[2]);
3306 neigh_dr_priority = atoi(argv[3]);
3307 neigh_generation_id = atoi(argv[4]);
3308 neigh_propagation_delay = atoi(argv[5]);
3309 neigh_override_interval = atoi(argv[6]);
3310 neigh_can_disable_join_suppression = atoi(argv[7]);
3311
3312 /*
3313 Tweak IP header
3314 */
3315 ip_hdr = (struct ip *) buf;
3316 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3317 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3318 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3319 ip_hdr->ip_src = neigh_addr;
3320 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3321
3322 /*
3323 Build PIM hello message
3324 */
3325 pim_msg = buf + ip_hlen;
3326
3327 /* Scan LINE addresses */
3328 for (argi = 8; argi < argc; ++argi) {
3329 const char *sec_str = argv[argi];
3330 struct in_addr sec_addr;
3331 result = inet_pton(AF_INET, sec_str, &sec_addr);
3332 if (result <= 0) {
3333 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003334 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003335 return CMD_WARNING;
3336 }
3337
3338 vty_out(vty,
3339 "FIXME WRITEME consider neighbor secondary address %s%s",
3340 sec_str, VTY_NEWLINE);
3341 }
3342
3343 pim_tlv_size = pim_hello_build_tlv(ifp->name,
3344 pim_msg + PIM_PIM_MIN_LEN,
3345 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
3346 neigh_holdtime,
3347 neigh_dr_priority,
3348 neigh_generation_id,
3349 neigh_propagation_delay,
3350 neigh_override_interval,
3351 neigh_can_disable_join_suppression,
3352 0 /* FIXME secondary address list */);
3353 if (pim_tlv_size < 0) {
3354 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
3355 pim_tlv_size, VTY_NEWLINE);
3356 return CMD_WARNING;
3357 }
3358
3359 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
3360
3361 pim_msg_build_header(pim_msg, pim_msg_size,
3362 PIM_MSG_TYPE_HELLO);
3363
3364 /* "receive" message */
3365
3366 ip_msg_len = ip_hlen + pim_msg_size;
3367 result = pim_pim_packet(ifp, buf, ip_msg_len);
3368 if (result) {
3369 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3370 ip_msg_len, result, VTY_NEWLINE);
3371 return CMD_WARNING;
3372 }
3373
3374 return CMD_SUCCESS;
3375}
3376
3377DEFUN (test_pim_receive_assert,
3378 test_pim_receive_assert_cmd,
3379 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
3380 "Test\n"
3381 "Test PIM protocol\n"
3382 "Test PIM message reception\n"
3383 "Test reception of PIM assert\n"
3384 "Interface\n"
3385 "Neighbor address\n"
3386 "Assert multicast group address\n"
3387 "Assert unicast source address\n"
3388 "Assert metric preference\n"
3389 "Assert route metric\n"
3390 "Assert RPT bit flag\n")
3391{
3392 char buf[1000];
3393 char *buf_pastend = buf + sizeof(buf);
3394 char *pim_msg;
3395 struct ip *ip_hdr;
3396 size_t ip_hlen; /* ip header length in bytes */
3397 int ip_msg_len;
3398 int pim_msg_size;
3399 const char *neigh_str;
3400 struct in_addr neigh_addr;
3401 const char *group_str;
3402 struct in_addr group_addr;
3403 const char *source_str;
3404 struct in_addr source_addr;
3405 const char *ifname;
3406 struct interface *ifp;
3407 uint32_t assert_metric_preference;
3408 uint32_t assert_route_metric;
3409 uint32_t assert_rpt_bit_flag;
3410 int remain;
3411 int result;
3412
3413 /* Find interface */
3414 ifname = argv[0];
3415 ifp = if_lookup_by_name(ifname);
3416 if (!ifp) {
3417 vty_out(vty, "No such interface name %s%s",
3418 ifname, VTY_NEWLINE);
3419 return CMD_WARNING;
3420 }
3421
3422 /* Neighbor address */
3423 neigh_str = argv[1];
3424 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3425 if (result <= 0) {
3426 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003427 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003428 return CMD_WARNING;
3429 }
3430
3431 /* Group address */
3432 group_str = argv[2];
3433 result = inet_pton(AF_INET, group_str, &group_addr);
3434 if (result <= 0) {
3435 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003436 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003437 return CMD_WARNING;
3438 }
3439
3440 /* Source address */
3441 source_str = argv[3];
3442 result = inet_pton(AF_INET, source_str, &source_addr);
3443 if (result <= 0) {
3444 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003445 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003446 return CMD_WARNING;
3447 }
3448
3449 assert_metric_preference = atoi(argv[4]);
3450 assert_route_metric = atoi(argv[5]);
3451 assert_rpt_bit_flag = atoi(argv[6]);
3452
3453 remain = buf_pastend - buf;
3454 if (remain < (int) sizeof(struct ip)) {
3455 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%d%s",
3456 remain, sizeof(struct ip), VTY_NEWLINE);
3457 return CMD_WARNING;
3458 }
3459
3460 /*
3461 Tweak IP header
3462 */
3463 ip_hdr = (struct ip *) buf;
3464 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3465 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3466 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3467 ip_hdr->ip_src = neigh_addr;
3468 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3469
3470 /*
3471 Build PIM assert message
3472 */
3473 pim_msg = buf + ip_hlen; /* skip ip header */
3474
3475 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
3476 group_addr, source_addr,
3477 assert_metric_preference,
3478 assert_route_metric,
3479 assert_rpt_bit_flag);
3480 if (pim_msg_size < 0) {
3481 vty_out(vty, "Failure building PIM assert message: size=%d%s",
3482 pim_msg_size, VTY_NEWLINE);
3483 return CMD_WARNING;
3484 }
3485
3486 /* "receive" message */
3487
3488 ip_msg_len = ip_hlen + pim_msg_size;
3489 result = pim_pim_packet(ifp, buf, ip_msg_len);
3490 if (result) {
3491 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3492 ip_msg_len, result, VTY_NEWLINE);
3493 return CMD_WARNING;
3494 }
3495
3496 return CMD_SUCCESS;
3497}
3498
3499static int recv_joinprune(struct vty *vty,
3500 const char *argv[],
3501 int src_is_join)
3502{
3503 char buf[1000];
3504 const char *buf_pastend = buf + sizeof(buf);
3505 char *pim_msg;
3506 char *pim_msg_curr;
3507 int pim_msg_size;
3508 struct ip *ip_hdr;
3509 size_t ip_hlen; /* ip header length in bytes */
3510 int ip_msg_len;
3511 uint16_t neigh_holdtime;
3512 const char *neigh_dst_str;
3513 struct in_addr neigh_dst_addr;
3514 const char *neigh_src_str;
3515 struct in_addr neigh_src_addr;
3516 const char *group_str;
3517 struct in_addr group_addr;
3518 const char *source_str;
3519 struct in_addr source_addr;
3520 const char *ifname;
3521 struct interface *ifp;
3522 int result;
3523 int remain;
3524 uint16_t num_joined;
3525 uint16_t num_pruned;
3526
3527 /* Find interface */
3528 ifname = argv[0];
3529 ifp = if_lookup_by_name(ifname);
3530 if (!ifp) {
3531 vty_out(vty, "No such interface name %s%s",
3532 ifname, VTY_NEWLINE);
3533 return CMD_WARNING;
3534 }
3535
3536 neigh_holdtime = atoi(argv[1]);
3537
3538 /* Neighbor destination address */
3539 neigh_dst_str = argv[2];
3540 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
3541 if (result <= 0) {
3542 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003543 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003544 return CMD_WARNING;
3545 }
3546
3547 /* Neighbor source address */
3548 neigh_src_str = argv[3];
3549 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
3550 if (result <= 0) {
3551 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003552 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003553 return CMD_WARNING;
3554 }
3555
3556 /* Multicast group address */
3557 group_str = argv[4];
3558 result = inet_pton(AF_INET, group_str, &group_addr);
3559 if (result <= 0) {
3560 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003561 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003562 return CMD_WARNING;
3563 }
3564
3565 /* Multicast source address */
3566 source_str = argv[5];
3567 result = inet_pton(AF_INET, source_str, &source_addr);
3568 if (result <= 0) {
3569 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003570 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003571 return CMD_WARNING;
3572 }
3573
3574 /*
3575 Tweak IP header
3576 */
3577 ip_hdr = (struct ip *) buf;
3578 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3579 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3580 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3581 ip_hdr->ip_src = neigh_src_addr;
3582 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3583
3584 /*
3585 Build PIM message
3586 */
3587 pim_msg = buf + ip_hlen;
3588
3589 /* skip room for pim header */
3590 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
3591
3592 remain = buf_pastend - pim_msg_curr;
3593 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
3594 remain,
3595 neigh_dst_addr);
3596 if (!pim_msg_curr) {
3597 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
3598 neigh_dst_str, remain, VTY_NEWLINE);
3599 return CMD_WARNING;
3600 }
3601
3602 remain = buf_pastend - pim_msg_curr;
3603 if (remain < 4) {
3604 vty_out(vty, "Group will not fit: space left=%d%s",
3605 remain, VTY_NEWLINE);
3606 return CMD_WARNING;
3607 }
3608
3609 *pim_msg_curr = 0; /* reserved */
3610 ++pim_msg_curr;
3611 *pim_msg_curr = 1; /* number of groups */
3612 ++pim_msg_curr;
3613 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
3614 ++pim_msg_curr;
3615 ++pim_msg_curr;
3616
3617 remain = buf_pastend - pim_msg_curr;
3618 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
3619 remain,
3620 group_addr);
3621 if (!pim_msg_curr) {
3622 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
3623 group_str, remain, VTY_NEWLINE);
3624 return CMD_WARNING;
3625 }
3626
3627 remain = buf_pastend - pim_msg_curr;
3628 if (remain < 4) {
3629 vty_out(vty, "Sources will not fit: space left=%d%s",
3630 remain, VTY_NEWLINE);
3631 return CMD_WARNING;
3632 }
3633
3634 if (src_is_join) {
3635 num_joined = 1;
3636 num_pruned = 0;
3637 }
3638 else {
3639 num_joined = 0;
3640 num_pruned = 1;
3641 }
3642
3643 /* number of joined sources */
3644 *((uint16_t *) pim_msg_curr) = htons(num_joined);
3645 ++pim_msg_curr;
3646 ++pim_msg_curr;
3647
3648 /* number of pruned sources */
3649 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
3650 ++pim_msg_curr;
3651 ++pim_msg_curr;
3652
3653 remain = buf_pastend - pim_msg_curr;
3654 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
3655 remain,
3656 source_addr);
3657 if (!pim_msg_curr) {
3658 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
3659 source_str, remain, VTY_NEWLINE);
3660 return CMD_WARNING;
3661 }
3662
3663 /* Add PIM header */
3664
3665 pim_msg_size = pim_msg_curr - pim_msg;
3666
3667 pim_msg_build_header(pim_msg, pim_msg_size,
3668 PIM_MSG_TYPE_JOIN_PRUNE);
3669
3670 /*
3671 "Receive" message
3672 */
3673
3674 ip_msg_len = ip_hlen + pim_msg_size;
3675 result = pim_pim_packet(ifp, buf, ip_msg_len);
3676 if (result) {
3677 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3678 ip_msg_len, result, VTY_NEWLINE);
3679 return CMD_WARNING;
3680 }
3681
3682 return CMD_SUCCESS;
3683}
3684
3685DEFUN (test_pim_receive_join,
3686 test_pim_receive_join_cmd,
3687 "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
3688 "Test\n"
3689 "Test PIM protocol\n"
3690 "Test PIM message reception\n"
3691 "Test PIM join reception from neighbor\n"
3692 "Interface\n"
3693 "Neighbor holdtime\n"
3694 "Upstream neighbor unicast destination address\n"
3695 "Downstream neighbor unicast source address\n"
3696 "Multicast group address\n"
3697 "Unicast source address\n")
3698{
3699 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
3700}
3701
3702DEFUN (test_pim_receive_prune,
3703 test_pim_receive_prune_cmd,
3704 "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
3705 "Test\n"
3706 "Test PIM protocol\n"
3707 "Test PIM message reception\n"
3708 "Test PIM prune reception from neighbor\n"
3709 "Interface\n"
3710 "Neighbor holdtime\n"
3711 "Upstream neighbor unicast destination address\n"
3712 "Downstream neighbor unicast source address\n"
3713 "Multicast group address\n"
3714 "Unicast source address\n")
3715{
3716 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
3717}
3718
3719DEFUN (test_pim_receive_upcall,
3720 test_pim_receive_upcall_cmd,
3721 "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
3722 "Test\n"
3723 "Test PIM protocol\n"
3724 "Test PIM message reception\n"
3725 "Test reception of kernel upcall\n"
3726 "NOCACHE kernel upcall\n"
3727 "WRONGVIF kernel upcall\n"
3728 "WHOLEPKT kernel upcall\n"
3729 "Input interface vif index\n"
3730 "Multicast group address\n"
3731 "Multicast source address\n")
3732{
3733 struct igmpmsg msg;
3734 const char *upcall_type;
3735 const char *group_str;
3736 const char *source_str;
3737 int result;
3738
3739 upcall_type = argv[0];
3740
3741 if (upcall_type[0] == 'n')
3742 msg.im_msgtype = IGMPMSG_NOCACHE;
3743 else if (upcall_type[1] == 'r')
3744 msg.im_msgtype = IGMPMSG_WRONGVIF;
3745 else if (upcall_type[1] == 'h')
3746 msg.im_msgtype = IGMPMSG_WHOLEPKT;
3747 else {
3748 vty_out(vty, "Unknown kernel upcall type: %s%s",
3749 upcall_type, VTY_NEWLINE);
3750 return CMD_WARNING;
3751 }
3752
3753 msg.im_vif = atoi(argv[1]);
3754
3755 /* Group address */
3756 group_str = argv[2];
3757 result = inet_pton(AF_INET, group_str, &msg.im_dst);
3758 if (result <= 0) {
3759 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003760 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003761 return CMD_WARNING;
3762 }
3763
3764 /* Source address */
3765 source_str = argv[3];
3766 result = inet_pton(AF_INET, source_str, &msg.im_src);
3767 if (result <= 0) {
3768 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003769 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003770 return CMD_WARNING;
3771 }
3772
3773 msg.im_mbz = 0; /* Must be zero */
3774
3775 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
3776 if (result) {
3777 vty_out(vty, "pim_mroute_msg(len=%d) returned failure: %d%s",
3778 sizeof(msg), result, VTY_NEWLINE);
3779 return CMD_WARNING;
3780 }
3781
3782 return CMD_SUCCESS;
3783}
3784
3785void pim_cmd_init()
3786{
Leonard Herve596470f2009-08-11 15:45:26 -03003787 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
3788 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
Everton Marques871dbcf2009-08-11 15:43:05 -03003789
Leonard Herve596470f2009-08-11 15:45:26 -03003790 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
3791 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003792#if 0
Leonard Herve596470f2009-08-11 15:45:26 -03003793 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03003794#else
Leonard Herve596470f2009-08-11 15:45:26 -03003795 install_element (CONFIG_NODE, &pim_interface_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003796#endif
Leonard Herve596470f2009-08-11 15:45:26 -03003797 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03003798
Leonard Herve596470f2009-08-11 15:45:26 -03003799 install_default (INTERFACE_NODE);
3800 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
3801 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
3802 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
3803 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
3804 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
3805 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
3806 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
3807 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
3808 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
3809 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
3810 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
3811 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003812
Leonard Herve596470f2009-08-11 15:45:26 -03003813 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
3814 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
3815 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
3816 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
3817 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
3818 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
3819 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
3820 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
3821 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
3822 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
3823 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
3824 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
3825 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
3826 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
3827 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
3828 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
3829 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
3830 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
3831 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
3832 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
3833 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
3834 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
3835 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
3836 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
3837 install_element (VIEW_NODE, &show_ip_multicast_cmd);
3838 install_element (VIEW_NODE, &show_ip_mroute_cmd);
3839 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
3840 install_element (VIEW_NODE, &show_ip_route_cmd);
3841 install_element (VIEW_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003842
Leonard Herve596470f2009-08-11 15:45:26 -03003843 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
3844 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
3845 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003846
Leonard Herve596470f2009-08-11 15:45:26 -03003847 install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
3848 install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
3849 install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
3850 install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
3851 install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
3852 install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
3853 install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
3854 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
3855 install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
3856 install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
3857 install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
3858 install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
3859 install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
3860 install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
3861 install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
3862 install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
3863 install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
3864 install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
3865 install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
3866 install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
3867 install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
3868 install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
3869 install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
3870 install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
3871 install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
3872 install_element (ENABLE_NODE, &show_ip_multicast_cmd);
3873 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
3874 install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
3875 install_element (ENABLE_NODE, &show_ip_route_cmd);
3876 install_element (ENABLE_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003877
Leonard Herve596470f2009-08-11 15:45:26 -03003878 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
3879 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
3880 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
3881 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
3882 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
3883 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003884
Leonard Herve596470f2009-08-11 15:45:26 -03003885 install_element (ENABLE_NODE, &debug_igmp_cmd);
3886 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
3887 install_element (ENABLE_NODE, &undebug_igmp_cmd);
3888 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
3889 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
3890 install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
3891 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
3892 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
3893 install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
3894 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
3895 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
3896 install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
3897 install_element (ENABLE_NODE, &debug_pim_cmd);
3898 install_element (ENABLE_NODE, &no_debug_pim_cmd);
3899 install_element (ENABLE_NODE, &undebug_pim_cmd);
3900 install_element (ENABLE_NODE, &debug_pim_events_cmd);
3901 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
3902 install_element (ENABLE_NODE, &undebug_pim_events_cmd);
3903 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
3904 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
3905 install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
3906 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
3907 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
3908 install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
3909 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
3910 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
3911 install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003912
Leonard Herve596470f2009-08-11 15:45:26 -03003913 install_element (CONFIG_NODE, &debug_igmp_cmd);
3914 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
3915 install_element (CONFIG_NODE, &undebug_igmp_cmd);
3916 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
3917 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
3918 install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
3919 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
3920 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
3921 install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
3922 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
3923 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
3924 install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
3925 install_element (CONFIG_NODE, &debug_pim_cmd);
3926 install_element (CONFIG_NODE, &no_debug_pim_cmd);
3927 install_element (CONFIG_NODE, &undebug_pim_cmd);
3928 install_element (CONFIG_NODE, &debug_pim_events_cmd);
3929 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
3930 install_element (CONFIG_NODE, &undebug_pim_events_cmd);
3931 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
3932 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
3933 install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
3934 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
3935 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
3936 install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
3937 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
3938 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
3939 install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003940}