blob: 5b47f3bbbbfa81c259cfa287e2658cfed9712cdf [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 Marques871dbcf2009-08-11 15:43:05 -03001089
1090 vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
1091
1092 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
1093 struct pim_interface *pim_ifp = ifp->info;
1094 struct listnode *sock_node;
1095 struct igmp_sock *igmp;
1096
1097 if (!pim_ifp)
1098 continue;
1099
1100 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1101 char query_hhmmss[10];
1102 char other_hhmmss[10];
1103
1104 pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
1105 pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
1106
Everton Marquese96f0af2009-08-11 15:48:02 -03001107 vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03001108 ifp->name,
1109 inet_ntoa(igmp->ifaddr),
1110 igmp->t_igmp_query_timer ? "THIS" : "OTHER",
1111 igmp->startup_query_count,
1112 query_hhmmss,
1113 other_hhmmss,
1114 VTY_NEWLINE);
1115 }
1116 }
1117}
1118
1119static void igmp_show_groups(struct vty *vty)
1120{
1121 struct listnode *ifnode;
1122 struct interface *ifp;
1123 time_t now;
1124
1125 now = pim_time_monotonic_sec();
1126
1127 vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
1128
1129 /* scan interfaces */
1130 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1131 struct pim_interface *pim_ifp = ifp->info;
1132 struct listnode *sock_node;
1133 struct igmp_sock *igmp;
1134
1135 if (!pim_ifp)
1136 continue;
1137
1138 /* scan igmp sockets */
1139 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1140 char ifaddr_str[100];
1141 struct listnode *grpnode;
1142 struct igmp_group *grp;
1143
1144 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1145
1146 /* scan igmp groups */
1147 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1148 char group_str[100];
1149 char hhmmss[10];
1150 char uptime[10];
1151
1152 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1153 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
1154 pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
1155
1156 vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
1157 ifp->name,
1158 ifaddr_str,
1159 group_str,
1160 grp->group_filtermode_isexcl ? "EXCL" : "INCL",
1161 hhmmss,
1162 grp->group_source_list ? listcount(grp->group_source_list) : 0,
1163 igmp_group_compat_mode(igmp, grp),
1164 uptime,
1165 VTY_NEWLINE);
1166
1167 } /* scan igmp groups */
1168 } /* scan igmp sockets */
1169 } /* scan interfaces */
1170}
1171
1172static void igmp_show_group_retransmission(struct vty *vty)
1173{
1174 struct listnode *ifnode;
1175 struct interface *ifp;
1176 time_t now;
1177
1178 now = pim_time_monotonic_sec();
1179
1180 vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
1181
1182 /* scan interfaces */
1183 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1184 struct pim_interface *pim_ifp = ifp->info;
1185 struct listnode *sock_node;
1186 struct igmp_sock *igmp;
1187
1188 if (!pim_ifp)
1189 continue;
1190
1191 /* scan igmp sockets */
1192 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1193 char ifaddr_str[100];
1194 struct listnode *grpnode;
1195 struct igmp_group *grp;
1196
1197 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1198
1199 /* scan igmp groups */
1200 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1201 char group_str[100];
1202 char grp_retr_mmss[10];
1203 struct listnode *src_node;
1204 struct igmp_source *src;
1205 int grp_retr_sources = 0;
1206
1207 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1208 pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
1209
1210
1211 /* count group sources with retransmission state */
1212 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
1213 if (src->source_query_retransmit_count > 0) {
1214 ++grp_retr_sources;
1215 }
1216 }
1217
1218 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
1219 ifp->name,
1220 ifaddr_str,
1221 group_str,
1222 grp_retr_mmss,
1223 grp->group_specific_query_retransmit_count,
1224 grp_retr_sources,
1225 VTY_NEWLINE);
1226
1227 } /* scan igmp groups */
1228 } /* scan igmp sockets */
1229 } /* scan interfaces */
1230}
1231
1232static void igmp_show_parameters(struct vty *vty)
1233{
1234 struct listnode *ifnode;
1235 struct interface *ifp;
1236
1237 vty_out(vty,
1238 "QRV: Robustness Variable SQI: Startup Query Interval%s"
1239 "QQI: Query Interval OQPI: Other Querier Present Interval%s"
1240 "QRI: Query Response Interval LMQT: Last Member Query Time%s"
1241 "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
1242 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1243
1244 vty_out(vty,
1245 "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
1246 VTY_NEWLINE);
1247
1248 /* scan interfaces */
1249 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1250 struct pim_interface *pim_ifp = ifp->info;
1251 struct listnode *sock_node;
1252 struct igmp_sock *igmp;
1253
1254 if (!pim_ifp)
1255 continue;
1256
1257 /* scan igmp sockets */
1258 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1259 char ifaddr_str[100];
1260 long gmi_dsec; /* Group Membership Interval */
1261 long oqpi_dsec; /* Other Querier Present Interval */
1262 int sqi;
1263 long lmqt_dsec;
1264 long ohpi_dsec;
1265 long qri_dsec;
1266
1267 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1268
1269 gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
1270 igmp->querier_query_interval,
1271 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1272
1273 sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
1274
1275 oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
1276 igmp->querier_query_interval,
1277 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1278
1279 lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
1280 igmp->querier_robustness_variable) / 100;
1281
1282 ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
1283 igmp->querier_query_interval,
1284 pim_ifp->igmp_query_max_response_time_dsec);
1285
1286 qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
1287
1288 vty_out(vty,
1289 "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
1290 ifp->name,
1291 ifaddr_str,
1292 igmp->querier_robustness_variable,
1293 igmp->querier_query_interval,
1294 qri_dsec / 10, qri_dsec % 10,
1295 gmi_dsec / 10, gmi_dsec % 10,
1296 sqi,
1297 oqpi_dsec / 10, oqpi_dsec % 10,
1298 lmqt_dsec / 10, lmqt_dsec % 10,
1299 ohpi_dsec / 10, ohpi_dsec % 10,
1300 VTY_NEWLINE);
1301
1302 } /* scan igmp sockets */
1303 } /* scan interfaces */
1304}
1305
1306static void igmp_show_sources(struct vty *vty)
1307{
1308 struct listnode *ifnode;
1309 struct interface *ifp;
1310 time_t now;
1311
1312 now = pim_time_monotonic_sec();
1313
1314 vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
1315
1316 /* scan interfaces */
1317 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1318 struct pim_interface *pim_ifp = ifp->info;
1319 struct listnode *sock_node;
1320 struct igmp_sock *igmp;
1321
1322 if (!pim_ifp)
1323 continue;
1324
1325 /* scan igmp sockets */
1326 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1327 char ifaddr_str[100];
1328 struct listnode *grpnode;
1329 struct igmp_group *grp;
1330
1331 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1332
1333 /* scan igmp groups */
1334 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1335 char group_str[100];
1336 struct listnode *srcnode;
1337 struct igmp_source *src;
1338
1339 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1340
1341 /* scan group sources */
1342 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1343 char source_str[100];
1344 char mmss[10];
1345 char uptime[10];
1346
1347 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1348
1349 pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
1350
1351 pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
1352
1353 vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
1354 ifp->name,
1355 ifaddr_str,
1356 group_str,
1357 source_str,
1358 mmss,
1359 IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
1360 uptime,
1361 VTY_NEWLINE);
1362
1363 } /* scan group sources */
1364 } /* scan igmp groups */
1365 } /* scan igmp sockets */
1366 } /* scan interfaces */
1367}
1368
1369static void igmp_show_source_retransmission(struct vty *vty)
1370{
1371 struct listnode *ifnode;
1372 struct interface *ifp;
1373 time_t now;
1374
1375 now = pim_time_monotonic_sec();
1376
1377 vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
1378
1379 /* scan interfaces */
1380 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
1381 struct pim_interface *pim_ifp = ifp->info;
1382 struct listnode *sock_node;
1383 struct igmp_sock *igmp;
1384
1385 if (!pim_ifp)
1386 continue;
1387
1388 /* scan igmp sockets */
1389 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1390 char ifaddr_str[100];
1391 struct listnode *grpnode;
1392 struct igmp_group *grp;
1393
1394 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1395
1396 /* scan igmp groups */
1397 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1398 char group_str[100];
1399 struct listnode *srcnode;
1400 struct igmp_source *src;
1401
1402 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1403
1404 /* scan group sources */
1405 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1406 char source_str[100];
1407
1408 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1409
1410 vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
1411 ifp->name,
1412 ifaddr_str,
1413 group_str,
1414 source_str,
1415 src->source_query_retransmit_count,
1416 VTY_NEWLINE);
1417
1418 } /* scan group sources */
1419 } /* scan igmp groups */
1420 } /* scan igmp sockets */
1421 } /* scan interfaces */
1422}
1423
1424static void clear_igmp_interfaces()
1425{
1426 struct listnode *ifnode;
1427 struct listnode *ifnextnode;
1428 struct interface *ifp;
1429
1430 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1431 pim_if_addr_del_all_igmp(ifp);
1432 }
1433
1434 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1435 pim_if_addr_add_all(ifp);
1436 }
1437}
1438
1439static void clear_pim_interfaces()
1440{
1441 struct listnode *ifnode;
1442 struct listnode *ifnextnode;
1443 struct interface *ifp;
1444
1445 for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
1446 if (ifp->info) {
1447 pim_neighbor_delete_all(ifp, "interface cleared");
1448 }
1449 }
1450}
1451
1452static void clear_interfaces()
1453{
1454 clear_igmp_interfaces();
1455 clear_pim_interfaces();
1456}
1457
1458DEFUN (pim_interface,
1459 pim_interface_cmd,
1460 "interface IFNAME",
1461 "Select an interface to configure\n"
1462 "Interface's name\n")
1463{
1464 struct interface *ifp;
1465 const char *ifname = argv[0];
1466 size_t sl;
1467
1468 sl = strlen(ifname);
1469 if (sl > INTERFACE_NAMSIZ) {
1470 vty_out(vty, "%% Interface name %s is invalid: length exceeds "
1471 "%d characters%s",
1472 ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
1473 return CMD_WARNING;
1474 }
1475
1476 ifp = if_lookup_by_name_len(ifname, sl);
1477 if (!ifp) {
1478 vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
1479
1480 /* Returning here would prevent pimd from booting when there are
1481 interface commands in pimd.conf, since all interfaces are
1482 unknown at pimd boot time (the zebra daemon has not been
1483 contacted for interface discovery). */
1484
1485 ifp = if_get_by_name_len(ifname, sl);
1486 if (!ifp) {
1487 vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
1488 return CMD_WARNING;
1489 }
1490 }
1491
1492 vty->index = ifp;
1493 vty->node = INTERFACE_NODE;
1494
1495 return CMD_SUCCESS;
1496}
1497
1498DEFUN (clear_ip_interfaces,
1499 clear_ip_interfaces_cmd,
1500 "clear ip interfaces",
1501 CLEAR_STR
1502 IP_STR
1503 "Reset interfaces\n")
1504{
1505 clear_interfaces();
1506
1507 return CMD_SUCCESS;
1508}
1509
1510DEFUN (clear_ip_igmp_interfaces,
1511 clear_ip_igmp_interfaces_cmd,
1512 "clear ip igmp interfaces",
1513 CLEAR_STR
1514 IP_STR
1515 CLEAR_IP_IGMP_STR
1516 "Reset IGMP interfaces\n")
1517{
1518 clear_igmp_interfaces();
1519
1520 return CMD_SUCCESS;
1521}
1522
1523DEFUN (clear_ip_pim_interfaces,
1524 clear_ip_pim_interfaces_cmd,
1525 "clear ip pim interfaces",
1526 CLEAR_STR
1527 IP_STR
1528 CLEAR_IP_PIM_STR
1529 "Reset PIM interfaces\n")
1530{
1531 clear_pim_interfaces();
1532
1533 return CMD_SUCCESS;
1534}
1535
1536DEFUN (show_ip_igmp_interface,
1537 show_ip_igmp_interface_cmd,
1538 "show ip igmp interface",
1539 SHOW_STR
1540 IP_STR
1541 IGMP_STR
1542 "IGMP interface information\n")
1543{
1544 igmp_show_interfaces(vty);
1545
1546 return CMD_SUCCESS;
1547}
1548
1549DEFUN (show_ip_igmp_groups,
1550 show_ip_igmp_groups_cmd,
1551 "show ip igmp groups",
1552 SHOW_STR
1553 IP_STR
1554 IGMP_STR
1555 IGMP_GROUP_STR)
1556{
1557 igmp_show_groups(vty);
1558
1559 return CMD_SUCCESS;
1560}
1561
1562DEFUN (show_ip_igmp_groups_retransmissions,
1563 show_ip_igmp_groups_retransmissions_cmd,
1564 "show ip igmp groups retransmissions",
1565 SHOW_STR
1566 IP_STR
1567 IGMP_STR
1568 IGMP_GROUP_STR
1569 "IGMP group retransmissions\n")
1570{
1571 igmp_show_group_retransmission(vty);
1572
1573 return CMD_SUCCESS;
1574}
1575
1576DEFUN (show_ip_igmp_parameters,
1577 show_ip_igmp_parameters_cmd,
1578 "show ip igmp parameters",
1579 SHOW_STR
1580 IP_STR
1581 IGMP_STR
1582 "IGMP parameters information\n")
1583{
1584 igmp_show_parameters(vty);
1585
1586 return CMD_SUCCESS;
1587}
1588
1589DEFUN (show_ip_igmp_sources,
1590 show_ip_igmp_sources_cmd,
1591 "show ip igmp sources",
1592 SHOW_STR
1593 IP_STR
1594 IGMP_STR
1595 IGMP_SOURCE_STR)
1596{
1597 igmp_show_sources(vty);
1598
1599 return CMD_SUCCESS;
1600}
1601
1602DEFUN (show_ip_igmp_sources_retransmissions,
1603 show_ip_igmp_sources_retransmissions_cmd,
1604 "show ip igmp sources retransmissions",
1605 SHOW_STR
1606 IP_STR
1607 IGMP_STR
1608 IGMP_SOURCE_STR
1609 "IGMP source retransmissions\n")
1610{
1611 igmp_show_source_retransmission(vty);
1612
1613 return CMD_SUCCESS;
1614}
1615
1616DEFUN (show_ip_igmp_querier,
1617 show_ip_igmp_querier_cmd,
1618 "show ip igmp querier",
1619 SHOW_STR
1620 IP_STR
1621 IGMP_STR
1622 "IGMP querier information\n")
1623{
1624 igmp_show_querier(vty);
1625
1626 return CMD_SUCCESS;
1627}
1628
1629DEFUN (show_ip_pim_address,
1630 show_ip_pim_address_cmd,
1631 "show ip pim address",
1632 SHOW_STR
1633 IP_STR
1634 PIM_STR
1635 "PIM interface address\n")
1636{
1637 show_interface_address(vty);
1638
1639 return CMD_SUCCESS;
1640}
1641
1642DEFUN (show_ip_pim_assert,
1643 show_ip_pim_assert_cmd,
1644 "show ip pim assert",
1645 SHOW_STR
1646 IP_STR
1647 PIM_STR
1648 "PIM interface assert\n")
1649{
1650 pim_show_assert(vty);
1651
1652 return CMD_SUCCESS;
1653}
1654
1655DEFUN (show_ip_pim_assert_internal,
1656 show_ip_pim_assert_internal_cmd,
1657 "show ip pim assert-internal",
1658 SHOW_STR
1659 IP_STR
1660 PIM_STR
1661 "PIM interface internal assert state\n")
1662{
1663 pim_show_assert_internal(vty);
1664
1665 return CMD_SUCCESS;
1666}
1667
1668DEFUN (show_ip_pim_assert_metric,
1669 show_ip_pim_assert_metric_cmd,
1670 "show ip pim assert-metric",
1671 SHOW_STR
1672 IP_STR
1673 PIM_STR
1674 "PIM interface assert metric\n")
1675{
1676 pim_show_assert_metric(vty);
1677
1678 return CMD_SUCCESS;
1679}
1680
1681DEFUN (show_ip_pim_assert_winner_metric,
1682 show_ip_pim_assert_winner_metric_cmd,
1683 "show ip pim assert-winner-metric",
1684 SHOW_STR
1685 IP_STR
1686 PIM_STR
1687 "PIM interface assert winner metric\n")
1688{
1689 pim_show_assert_winner_metric(vty);
1690
1691 return CMD_SUCCESS;
1692}
1693
1694DEFUN (show_ip_pim_dr,
1695 show_ip_pim_dr_cmd,
1696 "show ip pim designated-router",
1697 SHOW_STR
1698 IP_STR
1699 PIM_STR
1700 "PIM interface designated router\n")
1701{
1702 pim_show_dr(vty);
1703
1704 return CMD_SUCCESS;
1705}
1706
1707DEFUN (show_ip_pim_hello,
1708 show_ip_pim_hello_cmd,
1709 "show ip pim hello",
1710 SHOW_STR
1711 IP_STR
1712 PIM_STR
1713 "PIM interface hello information\n")
1714{
1715 pim_show_hello(vty);
1716
1717 return CMD_SUCCESS;
1718}
1719
1720DEFUN (show_ip_pim_interface,
1721 show_ip_pim_interface_cmd,
1722 "show ip pim interface",
1723 SHOW_STR
1724 IP_STR
1725 PIM_STR
1726 "PIM interface information\n")
1727{
1728 pim_show_interfaces(vty);
1729
1730 return CMD_SUCCESS;
1731}
1732
1733DEFUN (show_ip_pim_join,
1734 show_ip_pim_join_cmd,
1735 "show ip pim join",
1736 SHOW_STR
1737 IP_STR
1738 PIM_STR
1739 "PIM interface join information\n")
1740{
1741 pim_show_join(vty);
1742
1743 return CMD_SUCCESS;
1744}
1745
1746DEFUN (show_ip_pim_lan_prune_delay,
1747 show_ip_pim_lan_prune_delay_cmd,
1748 "show ip pim lan-prune-delay",
1749 SHOW_STR
1750 IP_STR
1751 PIM_STR
1752 "PIM neighbors LAN prune delay parameters\n")
1753{
1754 pim_show_lan_prune_delay(vty);
1755
1756 return CMD_SUCCESS;
1757}
1758
1759DEFUN (show_ip_pim_local_membership,
1760 show_ip_pim_local_membership_cmd,
1761 "show ip pim local-membership",
1762 SHOW_STR
1763 IP_STR
1764 PIM_STR
1765 "PIM interface local-membership\n")
1766{
1767 pim_show_membership(vty);
1768
1769 return CMD_SUCCESS;
1770}
1771
1772DEFUN (show_ip_pim_jp_override_interval,
1773 show_ip_pim_jp_override_interval_cmd,
1774 "show ip pim jp-override-interval",
1775 SHOW_STR
1776 IP_STR
1777 PIM_STR
1778 "PIM interface J/P override interval\n")
1779{
1780 pim_show_jp_override_interval(vty);
1781
1782 return CMD_SUCCESS;
1783}
1784
1785DEFUN (show_ip_pim_neighbor,
1786 show_ip_pim_neighbor_cmd,
1787 "show ip pim neighbor",
1788 SHOW_STR
1789 IP_STR
1790 PIM_STR
1791 "PIM neighbor information\n")
1792{
1793 pim_show_neighbors(vty);
1794
1795 return CMD_SUCCESS;
1796}
1797
1798DEFUN (show_ip_pim_secondary,
1799 show_ip_pim_secondary_cmd,
1800 "show ip pim secondary",
1801 SHOW_STR
1802 IP_STR
1803 PIM_STR
1804 "PIM neighbor addresses\n")
1805{
1806 pim_show_neighbors_secondary(vty);
1807
1808 return CMD_SUCCESS;
1809}
1810
1811DEFUN (show_ip_pim_upstream,
1812 show_ip_pim_upstream_cmd,
1813 "show ip pim upstream",
1814 SHOW_STR
1815 IP_STR
1816 PIM_STR
1817 "PIM upstream information\n")
1818{
1819 pim_show_upstream(vty);
1820
1821 return CMD_SUCCESS;
1822}
1823
1824DEFUN (show_ip_pim_upstream_join_desired,
1825 show_ip_pim_upstream_join_desired_cmd,
1826 "show ip pim upstream-join-desired",
1827 SHOW_STR
1828 IP_STR
1829 PIM_STR
1830 "PIM upstream join-desired\n")
1831{
1832 pim_show_join_desired(vty);
1833
1834 return CMD_SUCCESS;
1835}
1836
1837DEFUN (show_ip_pim_upstream_rpf,
1838 show_ip_pim_upstream_rpf_cmd,
1839 "show ip pim upstream-rpf",
1840 SHOW_STR
1841 IP_STR
1842 PIM_STR
1843 "PIM upstream source rpf\n")
1844{
1845 pim_show_upstream_rpf(vty);
1846
1847 return CMD_SUCCESS;
1848}
1849
1850DEFUN (show_ip_pim_rpf,
1851 show_ip_pim_rpf_cmd,
1852 "show ip pim rpf",
1853 SHOW_STR
1854 IP_STR
1855 PIM_STR
1856 "PIM cached source rpf information\n")
1857{
1858 pim_show_rpf(vty);
1859
1860 return CMD_SUCCESS;
1861}
1862
1863static void show_multicast_interfaces(struct vty *vty)
1864{
1865 struct listnode *node;
1866 struct interface *ifp;
1867
1868 vty_out(vty, "%s", VTY_NEWLINE);
1869
Everton Marques613938d2009-08-13 15:39:31 -03001870 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03001871 VTY_NEWLINE);
1872
1873 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
1874 struct pim_interface *pim_ifp;
1875 struct in_addr ifaddr;
1876 struct sioc_vif_req vreq;
1877
1878 pim_ifp = ifp->info;
1879
1880 if (!pim_ifp)
1881 continue;
1882
1883 memset(&vreq, 0, sizeof(vreq));
1884 vreq.vifi = pim_ifp->mroute_vif_index;
1885
1886 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
1887 int e = errno;
1888 vty_out(vty,
1889 "ioctl(SIOCGETVIFCNT=%d) failure for interface %s vif_index=%d: errno=%d: %s%s",
1890 SIOCGETVIFCNT,
1891 ifp->name,
1892 pim_ifp->mroute_vif_index,
1893 e,
Everton Marquese96f0af2009-08-11 15:48:02 -03001894 safe_strerror(e),
Everton Marques871dbcf2009-08-11 15:43:05 -03001895 VTY_NEWLINE);
1896 continue;
1897 }
1898
1899 ifaddr = pim_ifp->primary_address;
1900
Everton Marques613938d2009-08-13 15:39:31 -03001901 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03001902 ifp->name,
1903 inet_ntoa(ifaddr),
1904 ifp->ifindex,
1905 pim_ifp->mroute_vif_index,
1906 vreq.icount,
1907 vreq.ocount,
1908 vreq.ibytes,
1909 vreq.obytes,
1910 VTY_NEWLINE);
1911 }
1912}
1913
1914DEFUN (show_ip_multicast,
1915 show_ip_multicast_cmd,
1916 "show ip multicast",
1917 SHOW_STR
1918 IP_STR
1919 "Multicast global information\n")
1920{
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001921 time_t now = pim_time_monotonic_sec();
1922
Everton Marques871dbcf2009-08-11 15:43:05 -03001923 if (PIM_MROUTE_IS_ENABLED) {
Everton Marques871dbcf2009-08-11 15:43:05 -03001924 char uptime[10];
1925
1926 vty_out(vty, "Mroute socket descriptor: %d%s",
1927 qpim_mroute_socket_fd,
1928 VTY_NEWLINE);
1929
Everton Marques871dbcf2009-08-11 15:43:05 -03001930 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
1931 vty_out(vty, "Mroute socket uptime: %s%s",
1932 uptime,
1933 VTY_NEWLINE);
1934 }
1935 else {
1936 vty_out(vty, "Multicast disabled%s",
1937 VTY_NEWLINE);
1938 }
1939
1940 vty_out(vty, "%s", VTY_NEWLINE);
1941 vty_out(vty, "Current highest VifIndex: %d%s",
1942 qpim_mroute_oif_highest_vif_index,
1943 VTY_NEWLINE);
1944 vty_out(vty, "Maximum highest VifIndex: %d%s",
1945 MAXVIFS - 1,
1946 VTY_NEWLINE);
1947
1948 vty_out(vty, "%s", VTY_NEWLINE);
1949 vty_out(vty, "Upstream Join Timer: %d secs%s",
1950 qpim_t_periodic,
1951 VTY_NEWLINE);
1952 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
1953 PIM_JP_HOLDTIME,
1954 VTY_NEWLINE);
1955
1956 vty_out(vty, "%s", VTY_NEWLINE);
Everton Marques613938d2009-08-13 15:39:31 -03001957
Everton Marquesbcc4abe2009-08-17 18:18:59 -03001958 show_rpf_refresh_stats(vty, now);
Everton Marques871dbcf2009-08-11 15:43:05 -03001959
1960 show_multicast_interfaces(vty);
1961
1962 return CMD_SUCCESS;
1963}
1964
1965static void show_mroute(struct vty *vty)
1966{
1967 struct listnode *node;
1968 struct channel_oil *c_oil;
1969 time_t now;
1970
1971 vty_out(vty, "Proto: I=IGMP P=PIM%s%s", VTY_NEWLINE, VTY_NEWLINE);
1972
1973 vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
1974 VTY_NEWLINE);
1975
1976 now = pim_time_monotonic_sec();
1977
1978 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1979 char group_str[100];
1980 char source_str[100];
1981 int oif_vif_index;
1982
1983 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1984 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1985
1986 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
1987 struct interface *ifp_in;
1988 struct interface *ifp_out;
1989 char oif_uptime[10];
1990 int ttl;
1991 char proto[5];
1992
1993 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
1994 if (ttl < 1)
1995 continue;
1996
1997 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
1998 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
1999
2000 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
2001
2002 proto[0] = '\0';
2003 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2004 strcat(proto, "P");
2005 }
2006 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2007 strcat(proto, "I");
2008 }
2009
2010 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2011 source_str,
2012 group_str,
2013 proto,
2014 ifp_in ? ifp_in->name : "<iif?>",
2015 c_oil->oil.mfcc_parent,
2016 ifp_out ? ifp_out->name : "<oif?>",
2017 oif_vif_index,
2018 ttl,
2019 oif_uptime,
2020 VTY_NEWLINE);
2021 }
2022 }
2023}
2024
2025DEFUN (show_ip_mroute,
2026 show_ip_mroute_cmd,
2027 "show ip mroute",
2028 SHOW_STR
2029 IP_STR
2030 MROUTE_STR)
2031{
2032 show_mroute(vty);
2033 return CMD_SUCCESS;
2034}
2035
2036static void show_mroute_count(struct vty *vty)
2037{
2038 struct listnode *node;
2039 struct channel_oil *c_oil;
2040
2041 vty_out(vty, "%s", VTY_NEWLINE);
2042
2043 vty_out(vty, "Source Group Packets Bytes WrongIf %s",
2044 VTY_NEWLINE);
2045
2046 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2047 char group_str[100];
2048 char source_str[100];
2049 struct sioc_sg_req sgreq;
2050
2051 memset(&sgreq, 0, sizeof(sgreq));
2052 sgreq.src = c_oil->oil.mfcc_origin;
2053 sgreq.grp = c_oil->oil.mfcc_mcastgrp;
2054
2055 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2056 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2057
2058 if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
2059 int e = errno;
2060 vty_out(vty,
2061 "ioctl(SIOCGETSGCNT=%d) failure for (S,G)=(%s,%s): errno=%d: %s%s",
2062 SIOCGETSGCNT,
2063 source_str,
2064 group_str,
2065 e,
Everton Marquese96f0af2009-08-11 15:48:02 -03002066 safe_strerror(e),
Everton Marques871dbcf2009-08-11 15:43:05 -03002067 VTY_NEWLINE);
2068 continue;
2069 }
2070
2071 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2072 source_str,
2073 group_str,
2074 sgreq.pktcnt,
2075 sgreq.bytecnt,
2076 sgreq.wrong_if,
2077 VTY_NEWLINE);
2078
2079 }
2080}
2081
2082DEFUN (show_ip_mroute_count,
2083 show_ip_mroute_count_cmd,
2084 "show ip mroute count",
2085 SHOW_STR
2086 IP_STR
2087 MROUTE_STR
2088 "Route and packet count data\n")
2089{
2090 show_mroute_count(vty);
2091 return CMD_SUCCESS;
2092}
2093
2094DEFUN (show_ip_route,
2095 show_ip_route_cmd,
2096 "show ip route A.B.C.D",
2097 SHOW_STR
2098 IP_STR
2099 ROUTE_STR
2100 "Unicast address\n")
2101{
2102 struct in_addr addr;
2103 const char *addr_str;
2104 struct pim_nexthop nexthop;
2105 char nexthop_addr_str[100];
2106 int result;
2107
2108 addr_str = argv[0];
2109 result = inet_pton(AF_INET, addr_str, &addr);
2110 if (result <= 0) {
2111 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002112 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002113 return CMD_WARNING;
2114 }
2115
2116 if (pim_nexthop_lookup(&nexthop, addr)) {
2117 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
2118 addr_str, VTY_NEWLINE);
2119 return CMD_WARNING;
2120 }
2121
2122 vty_out(vty, "Address NextHop Interface Metric Preference%s",
2123 VTY_NEWLINE);
2124
2125 pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
2126 nexthop_addr_str, sizeof(nexthop_addr_str));
2127
2128 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
2129 addr_str,
2130 nexthop_addr_str,
2131 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2132 nexthop.mrib_route_metric,
2133 nexthop.mrib_metric_preference,
2134 VTY_NEWLINE);
2135
2136 return CMD_SUCCESS;
2137}
2138
2139static void mroute_add_all()
2140{
2141 struct listnode *node;
2142 struct channel_oil *c_oil;
2143
2144 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2145 if (pim_mroute_add(&c_oil->oil)) {
2146 /* just log warning */
2147 char source_str[100];
2148 char group_str[100];
2149 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2150 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2151 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2152 __FILE__, __PRETTY_FUNCTION__,
2153 source_str, group_str);
2154 }
2155 }
2156}
2157
2158static void mroute_del_all()
2159{
2160 struct listnode *node;
2161 struct channel_oil *c_oil;
2162
2163 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2164 if (pim_mroute_del(&c_oil->oil)) {
2165 /* just log warning */
2166 char source_str[100];
2167 char group_str[100];
2168 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2169 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2170 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2171 __FILE__, __PRETTY_FUNCTION__,
2172 source_str, group_str);
2173 }
2174 }
2175}
2176
2177DEFUN (ip_multicast_routing,
2178 ip_multicast_routing_cmd,
2179 PIM_CMD_IP_MULTICAST_ROUTING,
2180 IP_STR
2181 "Enable IP multicast forwarding\n")
2182{
2183 pim_mroute_socket_enable();
2184 pim_if_add_vif_all();
2185 mroute_add_all();
2186 return CMD_SUCCESS;
2187}
2188
2189DEFUN (no_ip_multicast_routing,
2190 no_ip_multicast_routing_cmd,
2191 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
2192 NO_STR
2193 IP_STR
2194 "Global IP configuration subcommands\n"
2195 "Enable IP multicast forwarding\n")
2196{
2197 mroute_del_all();
2198 pim_if_del_vif_all();
2199 pim_mroute_socket_disable();
2200 return CMD_SUCCESS;
2201}
2202
2203DEFUN (interface_ip_igmp,
2204 interface_ip_igmp_cmd,
2205 "ip igmp",
2206 IP_STR
2207 IFACE_IGMP_STR)
2208{
2209 struct interface *ifp;
2210 struct pim_interface *pim_ifp;
2211
2212 ifp = vty->index;
2213 pim_ifp = ifp->info;
2214
2215 if (!pim_ifp) {
2216 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2217 if (!pim_ifp) {
2218 vty_out(vty, "Could not enable IGMP on interface %s%s",
2219 ifp->name, VTY_NEWLINE);
2220 return CMD_WARNING;
2221 }
2222 }
2223 else {
2224 PIM_IF_DO_IGMP(pim_ifp->options);
2225 }
2226
2227 pim_if_addr_add_all(ifp);
2228 pim_if_membership_refresh(ifp);
2229
2230 return CMD_SUCCESS;
2231}
2232
2233DEFUN (interface_no_ip_igmp,
2234 interface_no_ip_igmp_cmd,
2235 "no ip igmp",
2236 NO_STR
2237 IP_STR
2238 IFACE_IGMP_STR)
2239{
2240 struct interface *ifp;
2241 struct pim_interface *pim_ifp;
2242
2243 ifp = vty->index;
2244 pim_ifp = ifp->info;
2245 if (!pim_ifp)
2246 return CMD_SUCCESS;
2247
2248 PIM_IF_DONT_IGMP(pim_ifp->options);
2249
2250 pim_if_membership_clear(ifp);
2251
2252 pim_if_addr_del_all(ifp);
2253
2254 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2255 pim_if_delete(ifp);
2256 }
2257
2258 return CMD_SUCCESS;
2259}
2260
2261DEFUN (interface_ip_igmp_join,
2262 interface_ip_igmp_join_cmd,
2263 "ip igmp join A.B.C.D A.B.C.D",
2264 IP_STR
2265 IFACE_IGMP_STR
2266 "IGMP join multicast group\n"
2267 "Multicast group address\n"
2268 "Source address\n")
2269{
2270 struct interface *ifp;
2271 const char *group_str;
2272 const char *source_str;
2273 struct in_addr group_addr;
2274 struct in_addr source_addr;
2275 int result;
2276
2277 ifp = vty->index;
2278
2279 /* Group address */
2280 group_str = argv[0];
2281 result = inet_pton(AF_INET, group_str, &group_addr);
2282 if (result <= 0) {
2283 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002284 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002285 return CMD_WARNING;
2286 }
2287
2288 /* Source address */
2289 source_str = argv[1];
2290 result = inet_pton(AF_INET, source_str, &source_addr);
2291 if (result <= 0) {
2292 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002293 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002294 return CMD_WARNING;
2295 }
2296
2297 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2298 if (result) {
2299 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2300 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2301 return CMD_WARNING;
2302 }
2303
2304 return CMD_SUCCESS;
2305}
2306
2307DEFUN (interface_no_ip_igmp_join,
2308 interface_no_ip_igmp_join_cmd,
2309 "no ip igmp join A.B.C.D A.B.C.D",
2310 NO_STR
2311 IP_STR
2312 IFACE_IGMP_STR
2313 "IGMP join multicast group\n"
2314 "Multicast group address\n"
2315 "Source address\n")
2316{
2317 struct interface *ifp;
2318 const char *group_str;
2319 const char *source_str;
2320 struct in_addr group_addr;
2321 struct in_addr source_addr;
2322 int result;
2323
2324 ifp = vty->index;
2325
2326 /* Group address */
2327 group_str = argv[0];
2328 result = inet_pton(AF_INET, group_str, &group_addr);
2329 if (result <= 0) {
2330 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002331 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002332 return CMD_WARNING;
2333 }
2334
2335 /* Source address */
2336 source_str = argv[1];
2337 result = inet_pton(AF_INET, source_str, &source_addr);
2338 if (result <= 0) {
2339 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002340 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002341 return CMD_WARNING;
2342 }
2343
2344 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2345 if (result) {
2346 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2347 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2348 return CMD_WARNING;
2349 }
2350
2351 return CMD_SUCCESS;
2352}
2353
2354/*
2355 CLI reconfiguration affects the interface level (struct pim_interface).
2356 This function propagates the reconfiguration to every active socket
2357 for that interface.
2358 */
2359static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2360{
2361 struct interface *ifp;
2362 struct pim_interface *pim_ifp;
2363
2364 zassert(igmp);
2365
2366 /* other querier present? */
2367
2368 if (igmp->t_other_querier_timer)
2369 return;
2370
2371 /* this is the querier */
2372
2373 zassert(igmp->interface);
2374 zassert(igmp->interface->info);
2375
2376 ifp = igmp->interface;
2377 pim_ifp = ifp->info;
2378
2379 if (PIM_DEBUG_IGMP_TRACE) {
2380 char ifaddr_str[100];
2381 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2382 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2383 __PRETTY_FUNCTION__,
2384 ifaddr_str,
2385 ifp->name,
2386 pim_ifp->igmp_default_query_interval);
2387 }
2388
2389 /*
2390 igmp_startup_mode_on() will reset QQI:
2391
2392 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2393 */
2394 igmp_startup_mode_on(igmp);
2395}
2396
2397static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2398{
2399 if (igmp->t_igmp_query_timer) {
2400 /* other querier present */
2401 zassert(igmp->t_igmp_query_timer);
2402 zassert(!igmp->t_other_querier_timer);
2403
2404 pim_igmp_general_query_off(igmp);
2405 pim_igmp_general_query_on(igmp);
2406
2407 zassert(igmp->t_igmp_query_timer);
2408 zassert(!igmp->t_other_querier_timer);
2409 }
2410 else {
2411 /* this is the querier */
2412
2413 zassert(!igmp->t_igmp_query_timer);
2414 zassert(igmp->t_other_querier_timer);
2415
2416 pim_igmp_other_querier_timer_off(igmp);
2417 pim_igmp_other_querier_timer_on(igmp);
2418
2419 zassert(!igmp->t_igmp_query_timer);
2420 zassert(igmp->t_other_querier_timer);
2421 }
2422}
2423
2424static void change_query_interval(struct pim_interface *pim_ifp,
2425 int query_interval)
2426{
2427 struct listnode *sock_node;
2428 struct igmp_sock *igmp;
2429
2430 pim_ifp->igmp_default_query_interval = query_interval;
2431
2432 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2433 igmp_sock_query_interval_reconfig(igmp);
2434 igmp_sock_query_reschedule(igmp);
2435 }
2436}
2437
2438static void change_query_max_response_time(struct pim_interface *pim_ifp,
2439 int query_max_response_time_dsec)
2440{
2441 struct listnode *sock_node;
2442 struct igmp_sock *igmp;
2443
2444 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2445
2446 /*
2447 Below we modify socket/group/source timers in order to quickly
2448 reflect the change. Otherwise, those timers would eventually catch
2449 up.
2450 */
2451
2452 /* scan all sockets */
2453 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2454 struct listnode *grp_node;
2455 struct igmp_group *grp;
2456
2457 /* reschedule socket general query */
2458 igmp_sock_query_reschedule(igmp);
2459
2460 /* scan socket groups */
2461 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2462 struct listnode *src_node;
2463 struct igmp_source *src;
2464
2465 /* reset group timers for groups in EXCLUDE mode */
2466 if (grp->group_filtermode_isexcl) {
2467 igmp_group_reset_gmi(grp);
2468 }
2469
2470 /* scan group sources */
2471 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2472
2473 /* reset source timers for sources with running timers */
2474 if (src->t_source_timer) {
2475 igmp_source_reset_gmi(igmp, grp, src);
2476 }
2477 }
2478 }
2479 }
2480}
2481
2482#define IGMP_QUERY_INTERVAL_MIN (1)
2483#define IGMP_QUERY_INTERVAL_MAX (1800)
2484
2485DEFUN (interface_ip_igmp_query_interval,
2486 interface_ip_igmp_query_interval_cmd,
2487 PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
2488 IP_STR
2489 IFACE_IGMP_STR
2490 IFACE_IGMP_QUERY_INTERVAL_STR
2491 "Query interval in seconds\n")
2492{
2493 struct interface *ifp;
2494 struct pim_interface *pim_ifp;
2495 int query_interval;
2496 int query_interval_dsec;
2497
2498 ifp = vty->index;
2499 pim_ifp = ifp->info;
2500
2501 if (!pim_ifp) {
2502 vty_out(vty,
2503 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2504 ifp->name,
2505 VTY_NEWLINE);
2506 return CMD_WARNING;
2507 }
2508
2509 query_interval = atoi(argv[0]);
2510 query_interval_dsec = 10 * query_interval;
2511
2512 /*
2513 It seems we don't need to check bounds since command.c does it
2514 already, but we verify them anyway for extra safety.
2515 */
2516 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
2517 vty_out(vty, "General query interval %d lower than minimum %d%s",
2518 query_interval,
2519 IGMP_QUERY_INTERVAL_MIN,
2520 VTY_NEWLINE);
2521 return CMD_WARNING;
2522 }
2523 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
2524 vty_out(vty, "General query interval %d higher than maximum %d%s",
2525 query_interval,
2526 IGMP_QUERY_INTERVAL_MAX,
2527 VTY_NEWLINE);
2528 return CMD_WARNING;
2529 }
2530
2531 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2532 vty_out(vty,
2533 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
2534 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2535 VTY_NEWLINE);
2536 return CMD_WARNING;
2537 }
2538
2539 change_query_interval(pim_ifp, query_interval);
2540
2541 return CMD_SUCCESS;
2542}
2543
2544DEFUN (interface_no_ip_igmp_query_interval,
2545 interface_no_ip_igmp_query_interval_cmd,
2546 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
2547 NO_STR
2548 IP_STR
2549 IFACE_IGMP_STR
2550 IFACE_IGMP_QUERY_INTERVAL_STR)
2551{
2552 struct interface *ifp;
2553 struct pim_interface *pim_ifp;
2554 int default_query_interval_dsec;
2555
2556 ifp = vty->index;
2557 pim_ifp = ifp->info;
2558
2559 if (!pim_ifp)
2560 return CMD_SUCCESS;
2561
2562 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
2563
2564 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2565 vty_out(vty,
2566 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
2567 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2568 VTY_NEWLINE);
2569 return CMD_WARNING;
2570 }
2571
2572 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
2573
2574 return CMD_SUCCESS;
2575}
2576
2577#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
2578#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
2579
2580DEFUN (interface_ip_igmp_query_max_response_time,
2581 interface_ip_igmp_query_max_response_time_cmd,
2582 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
2583 IP_STR
2584 IFACE_IGMP_STR
2585 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
2586 "Query response value in seconds\n")
2587{
2588 struct interface *ifp;
2589 struct pim_interface *pim_ifp;
2590 int query_max_response_time;
2591
2592 ifp = vty->index;
2593 pim_ifp = ifp->info;
2594
2595 if (!pim_ifp) {
2596 vty_out(vty,
2597 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2598 ifp->name,
2599 VTY_NEWLINE);
2600 return CMD_WARNING;
2601 }
2602
2603 query_max_response_time = atoi(argv[0]);
2604
2605 /*
2606 It seems we don't need to check bounds since command.c does it
2607 already, but we verify them anyway for extra safety.
2608 */
2609 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
2610 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
2611 query_max_response_time,
2612 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
2613 VTY_NEWLINE);
2614 return CMD_WARNING;
2615 }
2616 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
2617 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
2618 query_max_response_time,
2619 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
2620 VTY_NEWLINE);
2621 return CMD_WARNING;
2622 }
2623
2624 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
2625 vty_out(vty,
2626 "Can't set query max response time %d sec >= general query interval %d sec%s",
2627 query_max_response_time, pim_ifp->igmp_default_query_interval,
2628 VTY_NEWLINE);
2629 return CMD_WARNING;
2630 }
2631
2632 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
2633
2634 return CMD_SUCCESS;
2635}
2636
2637DEFUN (interface_no_ip_igmp_query_max_response_time,
2638 interface_no_ip_igmp_query_max_response_time_cmd,
2639 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
2640 NO_STR
2641 IP_STR
2642 IFACE_IGMP_STR
2643 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
2644{
2645 struct interface *ifp;
2646 struct pim_interface *pim_ifp;
2647 int default_query_interval_dsec;
2648
2649 ifp = vty->index;
2650 pim_ifp = ifp->info;
2651
2652 if (!pim_ifp)
2653 return CMD_SUCCESS;
2654
2655 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2656
2657 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
2658 vty_out(vty,
2659 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
2660 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
2661 VTY_NEWLINE);
2662 return CMD_WARNING;
2663 }
2664
2665 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
2666
2667 return CMD_SUCCESS;
2668}
2669
2670#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
2671#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
2672
2673DEFUN (interface_ip_igmp_query_max_response_time_dsec,
2674 interface_ip_igmp_query_max_response_time_dsec_cmd,
2675 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
2676 IP_STR
2677 IFACE_IGMP_STR
2678 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
2679 "Query response value in deciseconds\n")
2680{
2681 struct interface *ifp;
2682 struct pim_interface *pim_ifp;
2683 int query_max_response_time_dsec;
2684 int default_query_interval_dsec;
2685
2686 ifp = vty->index;
2687 pim_ifp = ifp->info;
2688
2689 if (!pim_ifp) {
2690 vty_out(vty,
2691 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2692 ifp->name,
2693 VTY_NEWLINE);
2694 return CMD_WARNING;
2695 }
2696
2697 query_max_response_time_dsec = atoi(argv[0]);
2698
2699 /*
2700 It seems we don't need to check bounds since command.c does it
2701 already, but we verify them anyway for extra safety.
2702 */
2703 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
2704 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
2705 query_max_response_time_dsec,
2706 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
2707 VTY_NEWLINE);
2708 return CMD_WARNING;
2709 }
2710 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
2711 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
2712 query_max_response_time_dsec,
2713 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
2714 VTY_NEWLINE);
2715 return CMD_WARNING;
2716 }
2717
2718 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2719
2720 if (query_max_response_time_dsec >= default_query_interval_dsec) {
2721 vty_out(vty,
2722 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
2723 query_max_response_time_dsec, default_query_interval_dsec,
2724 VTY_NEWLINE);
2725 return CMD_WARNING;
2726 }
2727
2728 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
2729
2730 return CMD_SUCCESS;
2731}
2732
2733DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
2734 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
2735 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
2736 NO_STR
2737 IP_STR
2738 IFACE_IGMP_STR
2739 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
2740{
2741 struct interface *ifp;
2742 struct pim_interface *pim_ifp;
2743 int default_query_interval_dsec;
2744
2745 ifp = vty->index;
2746 pim_ifp = ifp->info;
2747
2748 if (!pim_ifp)
2749 return CMD_SUCCESS;
2750
2751 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2752
2753 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
2754 vty_out(vty,
2755 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
2756 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
2757 VTY_NEWLINE);
2758 return CMD_WARNING;
2759 }
2760
2761 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
2762
2763 return CMD_SUCCESS;
2764}
2765
2766DEFUN (interface_ip_pim_ssm,
2767 interface_ip_pim_ssm_cmd,
2768 "ip pim ssm",
2769 IP_STR
2770 PIM_STR
2771 IFACE_PIM_STR)
2772{
2773 struct interface *ifp;
2774 struct pim_interface *pim_ifp;
2775
2776 ifp = vty->index;
2777 pim_ifp = ifp->info;
2778
2779 if (!pim_ifp) {
2780 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
2781 if (!pim_ifp) {
2782 vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
2783 return CMD_WARNING;
2784 }
2785 }
2786 else {
2787 PIM_IF_DO_PIM(pim_ifp->options);
2788 }
2789
2790 pim_if_addr_add_all(ifp);
2791 pim_if_membership_refresh(ifp);
2792
2793 return CMD_SUCCESS;
2794}
2795
2796DEFUN (interface_no_ip_pim_ssm,
2797 interface_no_ip_pim_ssm_cmd,
2798 "no ip pim ssm",
2799 NO_STR
2800 IP_STR
2801 PIM_STR
2802 IFACE_PIM_STR)
2803{
2804 struct interface *ifp;
2805 struct pim_interface *pim_ifp;
2806
2807 ifp = vty->index;
2808 pim_ifp = ifp->info;
2809 if (!pim_ifp)
2810 return CMD_SUCCESS;
2811
2812 PIM_IF_DONT_PIM(pim_ifp->options);
2813
2814 pim_if_membership_clear(ifp);
2815
2816 /*
2817 pim_if_addr_del_all() removes all sockets from
2818 pim_ifp->igmp_socket_list.
2819 */
2820 pim_if_addr_del_all(ifp);
2821
2822 /*
2823 pim_sock_delete() removes all neighbors from
2824 pim_ifp->pim_neighbor_list.
2825 */
2826 pim_sock_delete(ifp, "pim unconfigured on interface");
2827
2828 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
2829 pim_if_delete(ifp);
2830 }
2831
2832 return CMD_SUCCESS;
2833}
2834
2835DEFUN (debug_igmp,
2836 debug_igmp_cmd,
2837 "debug igmp",
2838 DEBUG_STR
2839 DEBUG_IGMP_STR)
2840{
2841 PIM_DO_DEBUG_IGMP_EVENTS;
2842 PIM_DO_DEBUG_IGMP_PACKETS;
2843 PIM_DO_DEBUG_IGMP_TRACE;
2844 return CMD_SUCCESS;
2845}
2846
2847DEFUN (no_debug_igmp,
2848 no_debug_igmp_cmd,
2849 "no debug igmp",
2850 NO_STR
2851 DEBUG_STR
2852 DEBUG_IGMP_STR)
2853{
2854 PIM_DONT_DEBUG_IGMP_EVENTS;
2855 PIM_DONT_DEBUG_IGMP_PACKETS;
2856 PIM_DONT_DEBUG_IGMP_TRACE;
2857 return CMD_SUCCESS;
2858}
2859
2860ALIAS (no_debug_igmp,
2861 undebug_igmp_cmd,
2862 "undebug igmp",
2863 UNDEBUG_STR
2864 DEBUG_IGMP_STR)
2865
2866DEFUN (debug_igmp_events,
2867 debug_igmp_events_cmd,
2868 "debug igmp events",
2869 DEBUG_STR
2870 DEBUG_IGMP_STR
2871 DEBUG_IGMP_EVENTS_STR)
2872{
2873 PIM_DO_DEBUG_IGMP_EVENTS;
2874 return CMD_SUCCESS;
2875}
2876
2877DEFUN (no_debug_igmp_events,
2878 no_debug_igmp_events_cmd,
2879 "no debug igmp events",
2880 NO_STR
2881 DEBUG_STR
2882 DEBUG_IGMP_STR
2883 DEBUG_IGMP_EVENTS_STR)
2884{
2885 PIM_DONT_DEBUG_IGMP_EVENTS;
2886 return CMD_SUCCESS;
2887}
2888
2889ALIAS (no_debug_igmp_events,
2890 undebug_igmp_events_cmd,
2891 "undebug igmp events",
2892 UNDEBUG_STR
2893 DEBUG_IGMP_STR
2894 DEBUG_IGMP_EVENTS_STR)
2895
2896DEFUN (debug_igmp_packets,
2897 debug_igmp_packets_cmd,
2898 "debug igmp packets",
2899 DEBUG_STR
2900 DEBUG_IGMP_STR
2901 DEBUG_IGMP_PACKETS_STR)
2902{
2903 PIM_DO_DEBUG_IGMP_PACKETS;
2904 return CMD_SUCCESS;
2905}
2906
2907DEFUN (no_debug_igmp_packets,
2908 no_debug_igmp_packets_cmd,
2909 "no debug igmp packets",
2910 NO_STR
2911 DEBUG_STR
2912 DEBUG_IGMP_STR
2913 DEBUG_IGMP_PACKETS_STR)
2914{
2915 PIM_DONT_DEBUG_IGMP_PACKETS;
2916 return CMD_SUCCESS;
2917}
2918
2919ALIAS (no_debug_igmp_packets,
2920 undebug_igmp_packets_cmd,
2921 "undebug igmp packets",
2922 UNDEBUG_STR
2923 DEBUG_IGMP_STR
2924 DEBUG_IGMP_PACKETS_STR)
2925
2926DEFUN (debug_igmp_trace,
2927 debug_igmp_trace_cmd,
2928 "debug igmp trace",
2929 DEBUG_STR
2930 DEBUG_IGMP_STR
2931 DEBUG_IGMP_TRACE_STR)
2932{
2933 PIM_DO_DEBUG_IGMP_TRACE;
2934 return CMD_SUCCESS;
2935}
2936
2937DEFUN (no_debug_igmp_trace,
2938 no_debug_igmp_trace_cmd,
2939 "no debug igmp trace",
2940 NO_STR
2941 DEBUG_STR
2942 DEBUG_IGMP_STR
2943 DEBUG_IGMP_TRACE_STR)
2944{
2945 PIM_DONT_DEBUG_IGMP_TRACE;
2946 return CMD_SUCCESS;
2947}
2948
2949ALIAS (no_debug_igmp_trace,
2950 undebug_igmp_trace_cmd,
2951 "undebug igmp trace",
2952 UNDEBUG_STR
2953 DEBUG_IGMP_STR
2954 DEBUG_IGMP_TRACE_STR)
2955
2956DEFUN (debug_pim,
2957 debug_pim_cmd,
2958 "debug pim",
2959 DEBUG_STR
2960 DEBUG_PIM_STR)
2961{
2962 PIM_DO_DEBUG_PIM_EVENTS;
2963 PIM_DO_DEBUG_PIM_PACKETS;
2964 PIM_DO_DEBUG_PIM_TRACE;
2965 return CMD_SUCCESS;
2966}
2967
2968DEFUN (no_debug_pim,
2969 no_debug_pim_cmd,
2970 "no debug pim",
2971 NO_STR
2972 DEBUG_STR
2973 DEBUG_PIM_STR)
2974{
2975 PIM_DONT_DEBUG_PIM_EVENTS;
2976 PIM_DONT_DEBUG_PIM_PACKETS;
2977 PIM_DONT_DEBUG_PIM_TRACE;
2978 return CMD_SUCCESS;
2979}
2980
2981ALIAS (no_debug_pim,
2982 undebug_pim_cmd,
2983 "undebug pim",
2984 UNDEBUG_STR
2985 DEBUG_PIM_STR)
2986
2987DEFUN (debug_pim_events,
2988 debug_pim_events_cmd,
2989 "debug pim events",
2990 DEBUG_STR
2991 DEBUG_PIM_STR
2992 DEBUG_PIM_EVENTS_STR)
2993{
2994 PIM_DO_DEBUG_PIM_EVENTS;
2995 return CMD_SUCCESS;
2996}
2997
2998DEFUN (no_debug_pim_events,
2999 no_debug_pim_events_cmd,
3000 "no debug pim events",
3001 NO_STR
3002 DEBUG_STR
3003 DEBUG_PIM_STR
3004 DEBUG_PIM_EVENTS_STR)
3005{
3006 PIM_DONT_DEBUG_PIM_EVENTS;
3007 return CMD_SUCCESS;
3008}
3009
3010ALIAS (no_debug_pim_events,
3011 undebug_pim_events_cmd,
3012 "undebug pim events",
3013 UNDEBUG_STR
3014 DEBUG_PIM_STR
3015 DEBUG_PIM_EVENTS_STR)
3016
3017DEFUN (debug_pim_packets,
3018 debug_pim_packets_cmd,
3019 "debug pim packets",
3020 DEBUG_STR
3021 DEBUG_PIM_STR
3022 DEBUG_PIM_PACKETS_STR)
3023{
3024 PIM_DO_DEBUG_PIM_PACKETS;
3025 return CMD_SUCCESS;
3026}
3027
3028DEFUN (no_debug_pim_packets,
3029 no_debug_pim_packets_cmd,
3030 "no debug pim packets",
3031 NO_STR
3032 DEBUG_STR
3033 DEBUG_PIM_STR
3034 DEBUG_PIM_PACKETS_STR)
3035{
3036 PIM_DONT_DEBUG_PIM_PACKETS;
3037 return CMD_SUCCESS;
3038}
3039
3040ALIAS (no_debug_pim_packets,
3041 undebug_pim_packets_cmd,
3042 "undebug pim packets",
3043 UNDEBUG_STR
3044 DEBUG_PIM_STR
3045 DEBUG_PIM_PACKETS_STR)
3046
3047DEFUN (debug_pim_trace,
3048 debug_pim_trace_cmd,
3049 "debug pim trace",
3050 DEBUG_STR
3051 DEBUG_PIM_STR
3052 DEBUG_PIM_TRACE_STR)
3053{
3054 PIM_DO_DEBUG_PIM_TRACE;
3055 return CMD_SUCCESS;
3056}
3057
3058DEFUN (no_debug_pim_trace,
3059 no_debug_pim_trace_cmd,
3060 "no debug pim trace",
3061 NO_STR
3062 DEBUG_STR
3063 DEBUG_PIM_STR
3064 DEBUG_PIM_TRACE_STR)
3065{
3066 PIM_DONT_DEBUG_PIM_TRACE;
3067 return CMD_SUCCESS;
3068}
3069
3070ALIAS (no_debug_pim_trace,
3071 undebug_pim_trace_cmd,
3072 "undebug pim trace",
3073 UNDEBUG_STR
3074 DEBUG_PIM_STR
3075 DEBUG_PIM_TRACE_STR)
3076
3077DEFUN (debug_pim_zebra,
3078 debug_pim_zebra_cmd,
3079 "debug pim zebra",
3080 DEBUG_STR
3081 DEBUG_PIM_STR
3082 DEBUG_PIM_ZEBRA_STR)
3083{
3084 PIM_DO_DEBUG_ZEBRA;
3085 return CMD_SUCCESS;
3086}
3087
3088DEFUN (no_debug_pim_zebra,
3089 no_debug_pim_zebra_cmd,
3090 "no debug pim zebra",
3091 NO_STR
3092 DEBUG_STR
3093 DEBUG_PIM_STR
3094 DEBUG_PIM_ZEBRA_STR)
3095{
3096 PIM_DONT_DEBUG_ZEBRA;
3097 return CMD_SUCCESS;
3098}
3099
3100ALIAS (no_debug_pim_zebra,
3101 undebug_pim_zebra_cmd,
3102 "undebug pim zebra",
3103 UNDEBUG_STR
3104 DEBUG_PIM_STR
3105 DEBUG_PIM_ZEBRA_STR)
3106
3107DEFUN (show_debugging,
3108 show_debugging_cmd,
3109 "show debugging",
3110 SHOW_STR
3111 "State of each debugging option\n")
3112{
3113 pim_debug_config_write(vty);
3114 return CMD_SUCCESS;
3115}
3116
3117static struct igmp_sock *find_igmp_sock_by_fd(int fd)
3118{
3119 struct listnode *ifnode;
3120 struct interface *ifp;
3121
3122 /* scan all interfaces */
3123 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
3124 struct pim_interface *pim_ifp;
3125 struct igmp_sock *igmp;
3126
3127 if (!ifp->info)
3128 continue;
3129
3130 pim_ifp = ifp->info;
3131
3132 /* lookup igmp socket under current interface */
3133 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
3134 if (igmp)
3135 return igmp;
3136 }
3137
3138 return 0;
3139}
3140
3141DEFUN (test_igmp_receive_report,
3142 test_igmp_receive_report_cmd,
3143 "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
3144 "Test\n"
3145 "Test IGMP protocol\n"
3146 "Test IGMP message\n"
3147 "Test IGMP report\n"
3148 "Socket\n"
3149 "IGMP group address\n"
3150 "Record type\n"
3151 "Sources\n")
3152{
3153 char buf[1000];
3154 char *igmp_msg;
3155 struct ip *ip_hdr;
3156 size_t ip_hlen; /* ip header length in bytes */
3157 int ip_msg_len;
3158 int igmp_msg_len;
3159 const char *socket;
3160 int socket_fd;
3161 const char *grp_str;
3162 struct in_addr grp_addr;
3163 const char *record_type_str;
3164 int record_type;
3165 const char *src_str;
3166 int result;
3167 struct igmp_sock *igmp;
3168 char *group_record;
3169 int num_sources;
3170 struct in_addr *sources;
3171 struct in_addr *src_addr;
3172 int argi;
3173
3174 socket = argv[0];
3175 socket_fd = atoi(socket);
3176 igmp = find_igmp_sock_by_fd(socket_fd);
3177 if (!igmp) {
3178 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
3179 socket, socket_fd, VTY_NEWLINE);
3180 return CMD_WARNING;
3181 }
3182
3183 grp_str = argv[1];
3184 result = inet_pton(AF_INET, grp_str, &grp_addr);
3185 if (result <= 0) {
3186 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003187 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003188 return CMD_WARNING;
3189 }
3190
3191 record_type_str = argv[2];
3192 record_type = atoi(record_type_str);
3193
3194 /*
3195 Tweak IP header
3196 */
3197 ip_hdr = (struct ip *) buf;
3198 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
3199 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3200 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3201 ip_hdr->ip_src = igmp->ifaddr;
3202 ip_hdr->ip_dst = igmp->ifaddr;
3203
3204 /*
3205 Build IGMP v3 report message
3206 */
3207 igmp_msg = buf + ip_hlen;
3208 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
3209 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
3210 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
3211 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
3212 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
3213 *(struct in_addr *)(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET) = grp_addr;
3214
3215 /* Scan LINE sources */
3216 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
3217 src_addr = sources;
3218 for (argi = 3; argi < argc; ++argi,++src_addr) {
3219 src_str = argv[argi];
3220 result = inet_pton(AF_INET, src_str, src_addr);
3221 if (result <= 0) {
3222 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003223 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003224 return CMD_WARNING;
3225 }
3226 }
3227 num_sources = src_addr - sources;
3228
3229 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
3230
3231 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
3232
3233 /* compute checksum */
3234 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = pim_inet_checksum(igmp_msg, igmp_msg_len);
3235
3236 /* "receive" message */
3237
3238 ip_msg_len = ip_hlen + igmp_msg_len;
3239 result = pim_igmp_packet(igmp, buf, ip_msg_len);
3240 if (result) {
3241 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
3242 ip_msg_len, result, VTY_NEWLINE);
3243 return CMD_WARNING;
3244 }
3245
3246 return CMD_SUCCESS;
3247}
3248
3249DEFUN (test_pim_receive_hello,
3250 test_pim_receive_hello_cmd,
3251 "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
3252 "Test\n"
3253 "Test PIM protocol\n"
3254 "Test PIM message reception\n"
3255 "Test PIM hello reception from neighbor\n"
3256 "Interface\n"
3257 "Neighbor address\n"
3258 "Neighbor holdtime\n"
3259 "Neighbor DR priority\n"
3260 "Neighbor generation ID\n"
3261 "Neighbor propagation delay (msec)\n"
3262 "Neighbor override interval (msec)\n"
3263 "Neighbor LAN prune delay T-bit\n"
3264 "Neighbor secondary addresses\n")
3265{
3266 char buf[1000];
3267 char *pim_msg;
3268 struct ip *ip_hdr;
3269 size_t ip_hlen; /* ip header length in bytes */
3270 int ip_msg_len;
3271 int pim_tlv_size;
3272 int pim_msg_size;
3273 const char *neigh_str;
3274 struct in_addr neigh_addr;
3275 const char *ifname;
3276 struct interface *ifp;
3277 uint16_t neigh_holdtime;
3278 uint16_t neigh_propagation_delay;
3279 uint16_t neigh_override_interval;
3280 int neigh_can_disable_join_suppression;
3281 uint32_t neigh_dr_priority;
3282 uint32_t neigh_generation_id;
3283 int argi;
3284 int result;
3285
3286 /* Find interface */
3287 ifname = argv[0];
3288 ifp = if_lookup_by_name(ifname);
3289 if (!ifp) {
3290 vty_out(vty, "No such interface name %s%s",
3291 ifname, VTY_NEWLINE);
3292 return CMD_WARNING;
3293 }
3294
3295 /* Neighbor address */
3296 neigh_str = argv[1];
3297 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3298 if (result <= 0) {
3299 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003300 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003301 return CMD_WARNING;
3302 }
3303
3304 neigh_holdtime = atoi(argv[2]);
3305 neigh_dr_priority = atoi(argv[3]);
3306 neigh_generation_id = atoi(argv[4]);
3307 neigh_propagation_delay = atoi(argv[5]);
3308 neigh_override_interval = atoi(argv[6]);
3309 neigh_can_disable_join_suppression = atoi(argv[7]);
3310
3311 /*
3312 Tweak IP header
3313 */
3314 ip_hdr = (struct ip *) buf;
3315 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3316 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3317 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3318 ip_hdr->ip_src = neigh_addr;
3319 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3320
3321 /*
3322 Build PIM hello message
3323 */
3324 pim_msg = buf + ip_hlen;
3325
3326 /* Scan LINE addresses */
3327 for (argi = 8; argi < argc; ++argi) {
3328 const char *sec_str = argv[argi];
3329 struct in_addr sec_addr;
3330 result = inet_pton(AF_INET, sec_str, &sec_addr);
3331 if (result <= 0) {
3332 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003333 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003334 return CMD_WARNING;
3335 }
3336
3337 vty_out(vty,
3338 "FIXME WRITEME consider neighbor secondary address %s%s",
3339 sec_str, VTY_NEWLINE);
3340 }
3341
3342 pim_tlv_size = pim_hello_build_tlv(ifp->name,
3343 pim_msg + PIM_PIM_MIN_LEN,
3344 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
3345 neigh_holdtime,
3346 neigh_dr_priority,
3347 neigh_generation_id,
3348 neigh_propagation_delay,
3349 neigh_override_interval,
3350 neigh_can_disable_join_suppression,
3351 0 /* FIXME secondary address list */);
3352 if (pim_tlv_size < 0) {
3353 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
3354 pim_tlv_size, VTY_NEWLINE);
3355 return CMD_WARNING;
3356 }
3357
3358 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
3359
3360 pim_msg_build_header(pim_msg, pim_msg_size,
3361 PIM_MSG_TYPE_HELLO);
3362
3363 /* "receive" message */
3364
3365 ip_msg_len = ip_hlen + pim_msg_size;
3366 result = pim_pim_packet(ifp, buf, ip_msg_len);
3367 if (result) {
3368 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3369 ip_msg_len, result, VTY_NEWLINE);
3370 return CMD_WARNING;
3371 }
3372
3373 return CMD_SUCCESS;
3374}
3375
3376DEFUN (test_pim_receive_assert,
3377 test_pim_receive_assert_cmd,
3378 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
3379 "Test\n"
3380 "Test PIM protocol\n"
3381 "Test PIM message reception\n"
3382 "Test reception of PIM assert\n"
3383 "Interface\n"
3384 "Neighbor address\n"
3385 "Assert multicast group address\n"
3386 "Assert unicast source address\n"
3387 "Assert metric preference\n"
3388 "Assert route metric\n"
3389 "Assert RPT bit flag\n")
3390{
3391 char buf[1000];
3392 char *buf_pastend = buf + sizeof(buf);
3393 char *pim_msg;
3394 struct ip *ip_hdr;
3395 size_t ip_hlen; /* ip header length in bytes */
3396 int ip_msg_len;
3397 int pim_msg_size;
3398 const char *neigh_str;
3399 struct in_addr neigh_addr;
3400 const char *group_str;
3401 struct in_addr group_addr;
3402 const char *source_str;
3403 struct in_addr source_addr;
3404 const char *ifname;
3405 struct interface *ifp;
3406 uint32_t assert_metric_preference;
3407 uint32_t assert_route_metric;
3408 uint32_t assert_rpt_bit_flag;
3409 int remain;
3410 int result;
3411
3412 /* Find interface */
3413 ifname = argv[0];
3414 ifp = if_lookup_by_name(ifname);
3415 if (!ifp) {
3416 vty_out(vty, "No such interface name %s%s",
3417 ifname, VTY_NEWLINE);
3418 return CMD_WARNING;
3419 }
3420
3421 /* Neighbor address */
3422 neigh_str = argv[1];
3423 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3424 if (result <= 0) {
3425 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003426 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003427 return CMD_WARNING;
3428 }
3429
3430 /* Group address */
3431 group_str = argv[2];
3432 result = inet_pton(AF_INET, group_str, &group_addr);
3433 if (result <= 0) {
3434 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003435 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003436 return CMD_WARNING;
3437 }
3438
3439 /* Source address */
3440 source_str = argv[3];
3441 result = inet_pton(AF_INET, source_str, &source_addr);
3442 if (result <= 0) {
3443 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003444 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003445 return CMD_WARNING;
3446 }
3447
3448 assert_metric_preference = atoi(argv[4]);
3449 assert_route_metric = atoi(argv[5]);
3450 assert_rpt_bit_flag = atoi(argv[6]);
3451
3452 remain = buf_pastend - buf;
3453 if (remain < (int) sizeof(struct ip)) {
3454 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%d%s",
3455 remain, sizeof(struct ip), VTY_NEWLINE);
3456 return CMD_WARNING;
3457 }
3458
3459 /*
3460 Tweak IP header
3461 */
3462 ip_hdr = (struct ip *) buf;
3463 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3464 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3465 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3466 ip_hdr->ip_src = neigh_addr;
3467 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3468
3469 /*
3470 Build PIM assert message
3471 */
3472 pim_msg = buf + ip_hlen; /* skip ip header */
3473
3474 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
3475 group_addr, source_addr,
3476 assert_metric_preference,
3477 assert_route_metric,
3478 assert_rpt_bit_flag);
3479 if (pim_msg_size < 0) {
3480 vty_out(vty, "Failure building PIM assert message: size=%d%s",
3481 pim_msg_size, VTY_NEWLINE);
3482 return CMD_WARNING;
3483 }
3484
3485 /* "receive" message */
3486
3487 ip_msg_len = ip_hlen + pim_msg_size;
3488 result = pim_pim_packet(ifp, buf, ip_msg_len);
3489 if (result) {
3490 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3491 ip_msg_len, result, VTY_NEWLINE);
3492 return CMD_WARNING;
3493 }
3494
3495 return CMD_SUCCESS;
3496}
3497
3498static int recv_joinprune(struct vty *vty,
3499 const char *argv[],
3500 int src_is_join)
3501{
3502 char buf[1000];
3503 const char *buf_pastend = buf + sizeof(buf);
3504 char *pim_msg;
3505 char *pim_msg_curr;
3506 int pim_msg_size;
3507 struct ip *ip_hdr;
3508 size_t ip_hlen; /* ip header length in bytes */
3509 int ip_msg_len;
3510 uint16_t neigh_holdtime;
3511 const char *neigh_dst_str;
3512 struct in_addr neigh_dst_addr;
3513 const char *neigh_src_str;
3514 struct in_addr neigh_src_addr;
3515 const char *group_str;
3516 struct in_addr group_addr;
3517 const char *source_str;
3518 struct in_addr source_addr;
3519 const char *ifname;
3520 struct interface *ifp;
3521 int result;
3522 int remain;
3523 uint16_t num_joined;
3524 uint16_t num_pruned;
3525
3526 /* Find interface */
3527 ifname = argv[0];
3528 ifp = if_lookup_by_name(ifname);
3529 if (!ifp) {
3530 vty_out(vty, "No such interface name %s%s",
3531 ifname, VTY_NEWLINE);
3532 return CMD_WARNING;
3533 }
3534
3535 neigh_holdtime = atoi(argv[1]);
3536
3537 /* Neighbor destination address */
3538 neigh_dst_str = argv[2];
3539 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
3540 if (result <= 0) {
3541 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003542 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003543 return CMD_WARNING;
3544 }
3545
3546 /* Neighbor source address */
3547 neigh_src_str = argv[3];
3548 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
3549 if (result <= 0) {
3550 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003551 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003552 return CMD_WARNING;
3553 }
3554
3555 /* Multicast group address */
3556 group_str = argv[4];
3557 result = inet_pton(AF_INET, group_str, &group_addr);
3558 if (result <= 0) {
3559 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003560 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003561 return CMD_WARNING;
3562 }
3563
3564 /* Multicast source address */
3565 source_str = argv[5];
3566 result = inet_pton(AF_INET, source_str, &source_addr);
3567 if (result <= 0) {
3568 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003569 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003570 return CMD_WARNING;
3571 }
3572
3573 /*
3574 Tweak IP header
3575 */
3576 ip_hdr = (struct ip *) buf;
3577 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3578 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3579 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3580 ip_hdr->ip_src = neigh_src_addr;
3581 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3582
3583 /*
3584 Build PIM message
3585 */
3586 pim_msg = buf + ip_hlen;
3587
3588 /* skip room for pim header */
3589 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
3590
3591 remain = buf_pastend - pim_msg_curr;
3592 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
3593 remain,
3594 neigh_dst_addr);
3595 if (!pim_msg_curr) {
3596 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
3597 neigh_dst_str, remain, VTY_NEWLINE);
3598 return CMD_WARNING;
3599 }
3600
3601 remain = buf_pastend - pim_msg_curr;
3602 if (remain < 4) {
3603 vty_out(vty, "Group will not fit: space left=%d%s",
3604 remain, VTY_NEWLINE);
3605 return CMD_WARNING;
3606 }
3607
3608 *pim_msg_curr = 0; /* reserved */
3609 ++pim_msg_curr;
3610 *pim_msg_curr = 1; /* number of groups */
3611 ++pim_msg_curr;
3612 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
3613 ++pim_msg_curr;
3614 ++pim_msg_curr;
3615
3616 remain = buf_pastend - pim_msg_curr;
3617 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
3618 remain,
3619 group_addr);
3620 if (!pim_msg_curr) {
3621 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
3622 group_str, remain, VTY_NEWLINE);
3623 return CMD_WARNING;
3624 }
3625
3626 remain = buf_pastend - pim_msg_curr;
3627 if (remain < 4) {
3628 vty_out(vty, "Sources will not fit: space left=%d%s",
3629 remain, VTY_NEWLINE);
3630 return CMD_WARNING;
3631 }
3632
3633 if (src_is_join) {
3634 num_joined = 1;
3635 num_pruned = 0;
3636 }
3637 else {
3638 num_joined = 0;
3639 num_pruned = 1;
3640 }
3641
3642 /* number of joined sources */
3643 *((uint16_t *) pim_msg_curr) = htons(num_joined);
3644 ++pim_msg_curr;
3645 ++pim_msg_curr;
3646
3647 /* number of pruned sources */
3648 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
3649 ++pim_msg_curr;
3650 ++pim_msg_curr;
3651
3652 remain = buf_pastend - pim_msg_curr;
3653 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
3654 remain,
3655 source_addr);
3656 if (!pim_msg_curr) {
3657 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
3658 source_str, remain, VTY_NEWLINE);
3659 return CMD_WARNING;
3660 }
3661
3662 /* Add PIM header */
3663
3664 pim_msg_size = pim_msg_curr - pim_msg;
3665
3666 pim_msg_build_header(pim_msg, pim_msg_size,
3667 PIM_MSG_TYPE_JOIN_PRUNE);
3668
3669 /*
3670 "Receive" message
3671 */
3672
3673 ip_msg_len = ip_hlen + pim_msg_size;
3674 result = pim_pim_packet(ifp, buf, ip_msg_len);
3675 if (result) {
3676 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3677 ip_msg_len, result, VTY_NEWLINE);
3678 return CMD_WARNING;
3679 }
3680
3681 return CMD_SUCCESS;
3682}
3683
3684DEFUN (test_pim_receive_join,
3685 test_pim_receive_join_cmd,
3686 "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
3687 "Test\n"
3688 "Test PIM protocol\n"
3689 "Test PIM message reception\n"
3690 "Test PIM join reception from neighbor\n"
3691 "Interface\n"
3692 "Neighbor holdtime\n"
3693 "Upstream neighbor unicast destination address\n"
3694 "Downstream neighbor unicast source address\n"
3695 "Multicast group address\n"
3696 "Unicast source address\n")
3697{
3698 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
3699}
3700
3701DEFUN (test_pim_receive_prune,
3702 test_pim_receive_prune_cmd,
3703 "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
3704 "Test\n"
3705 "Test PIM protocol\n"
3706 "Test PIM message reception\n"
3707 "Test PIM prune reception from neighbor\n"
3708 "Interface\n"
3709 "Neighbor holdtime\n"
3710 "Upstream neighbor unicast destination address\n"
3711 "Downstream neighbor unicast source address\n"
3712 "Multicast group address\n"
3713 "Unicast source address\n")
3714{
3715 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
3716}
3717
3718DEFUN (test_pim_receive_upcall,
3719 test_pim_receive_upcall_cmd,
3720 "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
3721 "Test\n"
3722 "Test PIM protocol\n"
3723 "Test PIM message reception\n"
3724 "Test reception of kernel upcall\n"
3725 "NOCACHE kernel upcall\n"
3726 "WRONGVIF kernel upcall\n"
3727 "WHOLEPKT kernel upcall\n"
3728 "Input interface vif index\n"
3729 "Multicast group address\n"
3730 "Multicast source address\n")
3731{
3732 struct igmpmsg msg;
3733 const char *upcall_type;
3734 const char *group_str;
3735 const char *source_str;
3736 int result;
3737
3738 upcall_type = argv[0];
3739
3740 if (upcall_type[0] == 'n')
3741 msg.im_msgtype = IGMPMSG_NOCACHE;
3742 else if (upcall_type[1] == 'r')
3743 msg.im_msgtype = IGMPMSG_WRONGVIF;
3744 else if (upcall_type[1] == 'h')
3745 msg.im_msgtype = IGMPMSG_WHOLEPKT;
3746 else {
3747 vty_out(vty, "Unknown kernel upcall type: %s%s",
3748 upcall_type, VTY_NEWLINE);
3749 return CMD_WARNING;
3750 }
3751
3752 msg.im_vif = atoi(argv[1]);
3753
3754 /* Group address */
3755 group_str = argv[2];
3756 result = inet_pton(AF_INET, group_str, &msg.im_dst);
3757 if (result <= 0) {
3758 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003759 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003760 return CMD_WARNING;
3761 }
3762
3763 /* Source address */
3764 source_str = argv[3];
3765 result = inet_pton(AF_INET, source_str, &msg.im_src);
3766 if (result <= 0) {
3767 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003768 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003769 return CMD_WARNING;
3770 }
3771
3772 msg.im_mbz = 0; /* Must be zero */
3773
3774 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
3775 if (result) {
3776 vty_out(vty, "pim_mroute_msg(len=%d) returned failure: %d%s",
3777 sizeof(msg), result, VTY_NEWLINE);
3778 return CMD_WARNING;
3779 }
3780
3781 return CMD_SUCCESS;
3782}
3783
3784void pim_cmd_init()
3785{
Leonard Herve596470f2009-08-11 15:45:26 -03003786 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
3787 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
Everton Marques871dbcf2009-08-11 15:43:05 -03003788
Leonard Herve596470f2009-08-11 15:45:26 -03003789 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
3790 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003791#if 0
Leonard Herve596470f2009-08-11 15:45:26 -03003792 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03003793#else
Leonard Herve596470f2009-08-11 15:45:26 -03003794 install_element (CONFIG_NODE, &pim_interface_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003795#endif
Leonard Herve596470f2009-08-11 15:45:26 -03003796 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03003797
Leonard Herve596470f2009-08-11 15:45:26 -03003798 install_default (INTERFACE_NODE);
3799 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
3800 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
3801 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
3802 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
3803 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
3804 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
3805 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
3806 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
3807 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
3808 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
3809 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
3810 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003811
Leonard Herve596470f2009-08-11 15:45:26 -03003812 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
3813 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
3814 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
3815 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
3816 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
3817 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
3818 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
3819 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
3820 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
3821 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
3822 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
3823 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
3824 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
3825 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
3826 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
3827 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
3828 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
3829 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
3830 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
3831 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
3832 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
3833 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
3834 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
3835 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
3836 install_element (VIEW_NODE, &show_ip_multicast_cmd);
3837 install_element (VIEW_NODE, &show_ip_mroute_cmd);
3838 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
3839 install_element (VIEW_NODE, &show_ip_route_cmd);
3840 install_element (VIEW_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003841
Leonard Herve596470f2009-08-11 15:45:26 -03003842 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
3843 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
3844 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003845
Leonard Herve596470f2009-08-11 15:45:26 -03003846 install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
3847 install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
3848 install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
3849 install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
3850 install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
3851 install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
3852 install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
3853 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
3854 install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
3855 install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
3856 install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
3857 install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
3858 install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
3859 install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
3860 install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
3861 install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
3862 install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
3863 install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
3864 install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
3865 install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
3866 install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
3867 install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
3868 install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
3869 install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
3870 install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
3871 install_element (ENABLE_NODE, &show_ip_multicast_cmd);
3872 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
3873 install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
3874 install_element (ENABLE_NODE, &show_ip_route_cmd);
3875 install_element (ENABLE_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003876
Leonard Herve596470f2009-08-11 15:45:26 -03003877 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
3878 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
3879 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
3880 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
3881 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
3882 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003883
Leonard Herve596470f2009-08-11 15:45:26 -03003884 install_element (ENABLE_NODE, &debug_igmp_cmd);
3885 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
3886 install_element (ENABLE_NODE, &undebug_igmp_cmd);
3887 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
3888 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
3889 install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
3890 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
3891 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
3892 install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
3893 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
3894 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
3895 install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
3896 install_element (ENABLE_NODE, &debug_pim_cmd);
3897 install_element (ENABLE_NODE, &no_debug_pim_cmd);
3898 install_element (ENABLE_NODE, &undebug_pim_cmd);
3899 install_element (ENABLE_NODE, &debug_pim_events_cmd);
3900 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
3901 install_element (ENABLE_NODE, &undebug_pim_events_cmd);
3902 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
3903 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
3904 install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
3905 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
3906 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
3907 install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
3908 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
3909 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
3910 install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003911
Leonard Herve596470f2009-08-11 15:45:26 -03003912 install_element (CONFIG_NODE, &debug_igmp_cmd);
3913 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
3914 install_element (CONFIG_NODE, &undebug_igmp_cmd);
3915 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
3916 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
3917 install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
3918 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
3919 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
3920 install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
3921 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
3922 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
3923 install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
3924 install_element (CONFIG_NODE, &debug_pim_cmd);
3925 install_element (CONFIG_NODE, &no_debug_pim_cmd);
3926 install_element (CONFIG_NODE, &undebug_pim_cmd);
3927 install_element (CONFIG_NODE, &debug_pim_events_cmd);
3928 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
3929 install_element (CONFIG_NODE, &undebug_pim_events_cmd);
3930 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
3931 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
3932 install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
3933 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
3934 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
3935 install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
3936 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
3937 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
3938 install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003939}