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