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