blob: a4073f50b035e3526a98d5666d53463578dd61b9 [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
Everton Marques824adbe2009-10-08 09:16:27 -03002140static void show_ssmpingd(struct vty *vty)
2141{
2142 struct listnode *node;
2143 struct ssmpingd_sock *ss;
2144 time_t now;
2145
2146 vty_out(vty, "Source Socket Uptime Requests%s",
2147 VTY_NEWLINE);
2148
2149 if (!qpim_ssmpingd_list)
2150 return;
2151
2152 now = pim_time_monotonic_sec();
2153
2154 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
2155 char source_str[100];
2156 char ss_uptime[10];
2157
2158 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
2159 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
2160
2161 vty_out(vty, "%-15s %6d %8s %8lld%s",
2162 source_str,
2163 ss->sock_fd,
2164 ss_uptime,
2165 ss->requests,
2166 VTY_NEWLINE);
2167 }
2168}
2169
2170DEFUN (show_ip_ssmpingd,
2171 show_ip_ssmpingd_cmd,
2172 "show ip ssmpingd",
2173 SHOW_STR
2174 IP_STR
2175 SHOW_SSMPINGD_STR)
2176{
2177 show_ssmpingd(vty);
2178 return CMD_SUCCESS;
2179}
2180
Everton Marques871dbcf2009-08-11 15:43:05 -03002181static void mroute_add_all()
2182{
2183 struct listnode *node;
2184 struct channel_oil *c_oil;
2185
2186 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2187 if (pim_mroute_add(&c_oil->oil)) {
2188 /* just log warning */
2189 char source_str[100];
2190 char group_str[100];
2191 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2192 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2193 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2194 __FILE__, __PRETTY_FUNCTION__,
2195 source_str, group_str);
2196 }
2197 }
2198}
2199
2200static void mroute_del_all()
2201{
2202 struct listnode *node;
2203 struct channel_oil *c_oil;
2204
2205 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2206 if (pim_mroute_del(&c_oil->oil)) {
2207 /* just log warning */
2208 char source_str[100];
2209 char group_str[100];
2210 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2211 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2212 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2213 __FILE__, __PRETTY_FUNCTION__,
2214 source_str, group_str);
2215 }
2216 }
2217}
2218
2219DEFUN (ip_multicast_routing,
2220 ip_multicast_routing_cmd,
2221 PIM_CMD_IP_MULTICAST_ROUTING,
2222 IP_STR
2223 "Enable IP multicast forwarding\n")
2224{
2225 pim_mroute_socket_enable();
2226 pim_if_add_vif_all();
2227 mroute_add_all();
2228 return CMD_SUCCESS;
2229}
2230
2231DEFUN (no_ip_multicast_routing,
2232 no_ip_multicast_routing_cmd,
2233 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
2234 NO_STR
2235 IP_STR
2236 "Global IP configuration subcommands\n"
2237 "Enable IP multicast forwarding\n")
2238{
2239 mroute_del_all();
2240 pim_if_del_vif_all();
2241 pim_mroute_socket_disable();
2242 return CMD_SUCCESS;
2243}
2244
Everton Marques96f91ae2009-10-07 18:41:45 -03002245DEFUN (ip_ssmpingd,
2246 ip_ssmpingd_cmd,
2247 "ip ssmpingd [A.B.C.D]",
2248 IP_STR
Everton Marques824adbe2009-10-08 09:16:27 -03002249 CONF_SSMPINGD_STR
Everton Marques96f91ae2009-10-07 18:41:45 -03002250 "Source address\n")
2251{
2252 int result;
2253 struct in_addr source_addr;
2254 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2255
2256 result = inet_pton(AF_INET, source_str, &source_addr);
2257 if (result <= 0) {
2258 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2259 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2260 return CMD_WARNING;
2261 }
2262
2263 result = pim_ssmpingd_start(source_addr);
2264 if (result) {
2265 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
2266 source_str, result, VTY_NEWLINE);
2267 return CMD_WARNING;
2268 }
2269
2270 return CMD_SUCCESS;
2271}
2272
2273DEFUN (no_ip_ssmpingd,
2274 no_ip_ssmpingd_cmd,
2275 "no ip ssmpingd [A.B.C.D]",
2276 NO_STR
2277 IP_STR
Everton Marques824adbe2009-10-08 09:16:27 -03002278 CONF_SSMPINGD_STR
Everton Marques96f91ae2009-10-07 18:41:45 -03002279 "Source address\n")
2280{
2281 int result;
2282 struct in_addr source_addr;
2283 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2284
2285 result = inet_pton(AF_INET, source_str, &source_addr);
2286 if (result <= 0) {
2287 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2288 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2289 return CMD_WARNING;
2290 }
2291
2292 result = pim_ssmpingd_stop(source_addr);
2293 if (result) {
2294 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
2295 source_str, result, VTY_NEWLINE);
2296 return CMD_WARNING;
2297 }
2298
2299 return CMD_SUCCESS;
2300}
2301
Everton Marques871dbcf2009-08-11 15:43:05 -03002302DEFUN (interface_ip_igmp,
2303 interface_ip_igmp_cmd,
2304 "ip igmp",
2305 IP_STR
2306 IFACE_IGMP_STR)
2307{
2308 struct interface *ifp;
2309 struct pim_interface *pim_ifp;
2310
2311 ifp = vty->index;
2312 pim_ifp = ifp->info;
2313
2314 if (!pim_ifp) {
2315 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2316 if (!pim_ifp) {
2317 vty_out(vty, "Could not enable IGMP on interface %s%s",
2318 ifp->name, VTY_NEWLINE);
2319 return CMD_WARNING;
2320 }
2321 }
2322 else {
2323 PIM_IF_DO_IGMP(pim_ifp->options);
2324 }
2325
2326 pim_if_addr_add_all(ifp);
2327 pim_if_membership_refresh(ifp);
2328
2329 return CMD_SUCCESS;
2330}
2331
2332DEFUN (interface_no_ip_igmp,
2333 interface_no_ip_igmp_cmd,
2334 "no ip igmp",
2335 NO_STR
2336 IP_STR
2337 IFACE_IGMP_STR)
2338{
2339 struct interface *ifp;
2340 struct pim_interface *pim_ifp;
2341
2342 ifp = vty->index;
2343 pim_ifp = ifp->info;
2344 if (!pim_ifp)
2345 return CMD_SUCCESS;
2346
2347 PIM_IF_DONT_IGMP(pim_ifp->options);
2348
2349 pim_if_membership_clear(ifp);
2350
2351 pim_if_addr_del_all(ifp);
2352
2353 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2354 pim_if_delete(ifp);
2355 }
2356
2357 return CMD_SUCCESS;
2358}
2359
2360DEFUN (interface_ip_igmp_join,
2361 interface_ip_igmp_join_cmd,
2362 "ip igmp join A.B.C.D A.B.C.D",
2363 IP_STR
2364 IFACE_IGMP_STR
2365 "IGMP join multicast group\n"
2366 "Multicast group address\n"
2367 "Source address\n")
2368{
2369 struct interface *ifp;
2370 const char *group_str;
2371 const char *source_str;
2372 struct in_addr group_addr;
2373 struct in_addr source_addr;
2374 int result;
2375
2376 ifp = vty->index;
2377
2378 /* Group address */
2379 group_str = argv[0];
2380 result = inet_pton(AF_INET, group_str, &group_addr);
2381 if (result <= 0) {
2382 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002383 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002384 return CMD_WARNING;
2385 }
2386
2387 /* Source address */
2388 source_str = argv[1];
2389 result = inet_pton(AF_INET, source_str, &source_addr);
2390 if (result <= 0) {
2391 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002392 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002393 return CMD_WARNING;
2394 }
2395
2396 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2397 if (result) {
2398 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2399 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2400 return CMD_WARNING;
2401 }
2402
2403 return CMD_SUCCESS;
2404}
2405
2406DEFUN (interface_no_ip_igmp_join,
2407 interface_no_ip_igmp_join_cmd,
2408 "no ip igmp join A.B.C.D A.B.C.D",
2409 NO_STR
2410 IP_STR
2411 IFACE_IGMP_STR
2412 "IGMP join multicast group\n"
2413 "Multicast group address\n"
2414 "Source address\n")
2415{
2416 struct interface *ifp;
2417 const char *group_str;
2418 const char *source_str;
2419 struct in_addr group_addr;
2420 struct in_addr source_addr;
2421 int result;
2422
2423 ifp = vty->index;
2424
2425 /* Group address */
2426 group_str = argv[0];
2427 result = inet_pton(AF_INET, group_str, &group_addr);
2428 if (result <= 0) {
2429 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002430 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002431 return CMD_WARNING;
2432 }
2433
2434 /* Source address */
2435 source_str = argv[1];
2436 result = inet_pton(AF_INET, source_str, &source_addr);
2437 if (result <= 0) {
2438 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002439 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002440 return CMD_WARNING;
2441 }
2442
2443 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2444 if (result) {
2445 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2446 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2447 return CMD_WARNING;
2448 }
2449
2450 return CMD_SUCCESS;
2451}
2452
2453/*
2454 CLI reconfiguration affects the interface level (struct pim_interface).
2455 This function propagates the reconfiguration to every active socket
2456 for that interface.
2457 */
2458static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2459{
2460 struct interface *ifp;
2461 struct pim_interface *pim_ifp;
2462
2463 zassert(igmp);
2464
2465 /* other querier present? */
2466
2467 if (igmp->t_other_querier_timer)
2468 return;
2469
2470 /* this is the querier */
2471
2472 zassert(igmp->interface);
2473 zassert(igmp->interface->info);
2474
2475 ifp = igmp->interface;
2476 pim_ifp = ifp->info;
2477
2478 if (PIM_DEBUG_IGMP_TRACE) {
2479 char ifaddr_str[100];
2480 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2481 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2482 __PRETTY_FUNCTION__,
2483 ifaddr_str,
2484 ifp->name,
2485 pim_ifp->igmp_default_query_interval);
2486 }
2487
2488 /*
2489 igmp_startup_mode_on() will reset QQI:
2490
2491 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2492 */
2493 igmp_startup_mode_on(igmp);
2494}
2495
2496static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2497{
2498 if (igmp->t_igmp_query_timer) {
2499 /* other querier present */
2500 zassert(igmp->t_igmp_query_timer);
2501 zassert(!igmp->t_other_querier_timer);
2502
2503 pim_igmp_general_query_off(igmp);
2504 pim_igmp_general_query_on(igmp);
2505
2506 zassert(igmp->t_igmp_query_timer);
2507 zassert(!igmp->t_other_querier_timer);
2508 }
2509 else {
2510 /* this is the querier */
2511
2512 zassert(!igmp->t_igmp_query_timer);
2513 zassert(igmp->t_other_querier_timer);
2514
2515 pim_igmp_other_querier_timer_off(igmp);
2516 pim_igmp_other_querier_timer_on(igmp);
2517
2518 zassert(!igmp->t_igmp_query_timer);
2519 zassert(igmp->t_other_querier_timer);
2520 }
2521}
2522
2523static void change_query_interval(struct pim_interface *pim_ifp,
2524 int query_interval)
2525{
2526 struct listnode *sock_node;
2527 struct igmp_sock *igmp;
2528
2529 pim_ifp->igmp_default_query_interval = query_interval;
2530
2531 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2532 igmp_sock_query_interval_reconfig(igmp);
2533 igmp_sock_query_reschedule(igmp);
2534 }
2535}
2536
2537static void change_query_max_response_time(struct pim_interface *pim_ifp,
2538 int query_max_response_time_dsec)
2539{
2540 struct listnode *sock_node;
2541 struct igmp_sock *igmp;
2542
2543 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2544
2545 /*
2546 Below we modify socket/group/source timers in order to quickly
2547 reflect the change. Otherwise, those timers would eventually catch
2548 up.
2549 */
2550
2551 /* scan all sockets */
2552 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2553 struct listnode *grp_node;
2554 struct igmp_group *grp;
2555
2556 /* reschedule socket general query */
2557 igmp_sock_query_reschedule(igmp);
2558
2559 /* scan socket groups */
2560 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2561 struct listnode *src_node;
2562 struct igmp_source *src;
2563
2564 /* reset group timers for groups in EXCLUDE mode */
2565 if (grp->group_filtermode_isexcl) {
2566 igmp_group_reset_gmi(grp);
2567 }
2568
2569 /* scan group sources */
2570 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2571
2572 /* reset source timers for sources with running timers */
2573 if (src->t_source_timer) {
2574 igmp_source_reset_gmi(igmp, grp, src);
2575 }
2576 }
2577 }
2578 }
2579}
2580
2581#define IGMP_QUERY_INTERVAL_MIN (1)
2582#define IGMP_QUERY_INTERVAL_MAX (1800)
2583
2584DEFUN (interface_ip_igmp_query_interval,
2585 interface_ip_igmp_query_interval_cmd,
2586 PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
2587 IP_STR
2588 IFACE_IGMP_STR
2589 IFACE_IGMP_QUERY_INTERVAL_STR
2590 "Query interval in seconds\n")
2591{
2592 struct interface *ifp;
2593 struct pim_interface *pim_ifp;
2594 int query_interval;
2595 int query_interval_dsec;
2596
2597 ifp = vty->index;
2598 pim_ifp = ifp->info;
2599
2600 if (!pim_ifp) {
2601 vty_out(vty,
2602 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2603 ifp->name,
2604 VTY_NEWLINE);
2605 return CMD_WARNING;
2606 }
2607
2608 query_interval = atoi(argv[0]);
2609 query_interval_dsec = 10 * query_interval;
2610
2611 /*
2612 It seems we don't need to check bounds since command.c does it
2613 already, but we verify them anyway for extra safety.
2614 */
2615 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
2616 vty_out(vty, "General query interval %d lower than minimum %d%s",
2617 query_interval,
2618 IGMP_QUERY_INTERVAL_MIN,
2619 VTY_NEWLINE);
2620 return CMD_WARNING;
2621 }
2622 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
2623 vty_out(vty, "General query interval %d higher than maximum %d%s",
2624 query_interval,
2625 IGMP_QUERY_INTERVAL_MAX,
2626 VTY_NEWLINE);
2627 return CMD_WARNING;
2628 }
2629
2630 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2631 vty_out(vty,
2632 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
2633 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2634 VTY_NEWLINE);
2635 return CMD_WARNING;
2636 }
2637
2638 change_query_interval(pim_ifp, query_interval);
2639
2640 return CMD_SUCCESS;
2641}
2642
2643DEFUN (interface_no_ip_igmp_query_interval,
2644 interface_no_ip_igmp_query_interval_cmd,
2645 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
2646 NO_STR
2647 IP_STR
2648 IFACE_IGMP_STR
2649 IFACE_IGMP_QUERY_INTERVAL_STR)
2650{
2651 struct interface *ifp;
2652 struct pim_interface *pim_ifp;
2653 int default_query_interval_dsec;
2654
2655 ifp = vty->index;
2656 pim_ifp = ifp->info;
2657
2658 if (!pim_ifp)
2659 return CMD_SUCCESS;
2660
2661 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
2662
2663 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2664 vty_out(vty,
2665 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
2666 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2667 VTY_NEWLINE);
2668 return CMD_WARNING;
2669 }
2670
2671 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
2672
2673 return CMD_SUCCESS;
2674}
2675
2676#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
2677#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
2678
2679DEFUN (interface_ip_igmp_query_max_response_time,
2680 interface_ip_igmp_query_max_response_time_cmd,
2681 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
2682 IP_STR
2683 IFACE_IGMP_STR
2684 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
2685 "Query response value in seconds\n")
2686{
2687 struct interface *ifp;
2688 struct pim_interface *pim_ifp;
2689 int query_max_response_time;
2690
2691 ifp = vty->index;
2692 pim_ifp = ifp->info;
2693
2694 if (!pim_ifp) {
2695 vty_out(vty,
2696 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2697 ifp->name,
2698 VTY_NEWLINE);
2699 return CMD_WARNING;
2700 }
2701
2702 query_max_response_time = atoi(argv[0]);
2703
2704 /*
2705 It seems we don't need to check bounds since command.c does it
2706 already, but we verify them anyway for extra safety.
2707 */
2708 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
2709 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
2710 query_max_response_time,
2711 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
2712 VTY_NEWLINE);
2713 return CMD_WARNING;
2714 }
2715 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
2716 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
2717 query_max_response_time,
2718 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
2719 VTY_NEWLINE);
2720 return CMD_WARNING;
2721 }
2722
2723 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
2724 vty_out(vty,
2725 "Can't set query max response time %d sec >= general query interval %d sec%s",
2726 query_max_response_time, pim_ifp->igmp_default_query_interval,
2727 VTY_NEWLINE);
2728 return CMD_WARNING;
2729 }
2730
2731 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
2732
2733 return CMD_SUCCESS;
2734}
2735
2736DEFUN (interface_no_ip_igmp_query_max_response_time,
2737 interface_no_ip_igmp_query_max_response_time_cmd,
2738 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
2739 NO_STR
2740 IP_STR
2741 IFACE_IGMP_STR
2742 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
2743{
2744 struct interface *ifp;
2745 struct pim_interface *pim_ifp;
2746 int default_query_interval_dsec;
2747
2748 ifp = vty->index;
2749 pim_ifp = ifp->info;
2750
2751 if (!pim_ifp)
2752 return CMD_SUCCESS;
2753
2754 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2755
2756 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
2757 vty_out(vty,
2758 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
2759 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
2760 VTY_NEWLINE);
2761 return CMD_WARNING;
2762 }
2763
2764 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
2765
2766 return CMD_SUCCESS;
2767}
2768
2769#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
2770#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
2771
2772DEFUN (interface_ip_igmp_query_max_response_time_dsec,
2773 interface_ip_igmp_query_max_response_time_dsec_cmd,
2774 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
2775 IP_STR
2776 IFACE_IGMP_STR
2777 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
2778 "Query response value in deciseconds\n")
2779{
2780 struct interface *ifp;
2781 struct pim_interface *pim_ifp;
2782 int query_max_response_time_dsec;
2783 int default_query_interval_dsec;
2784
2785 ifp = vty->index;
2786 pim_ifp = ifp->info;
2787
2788 if (!pim_ifp) {
2789 vty_out(vty,
2790 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2791 ifp->name,
2792 VTY_NEWLINE);
2793 return CMD_WARNING;
2794 }
2795
2796 query_max_response_time_dsec = atoi(argv[0]);
2797
2798 /*
2799 It seems we don't need to check bounds since command.c does it
2800 already, but we verify them anyway for extra safety.
2801 */
2802 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
2803 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
2804 query_max_response_time_dsec,
2805 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
2806 VTY_NEWLINE);
2807 return CMD_WARNING;
2808 }
2809 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
2810 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
2811 query_max_response_time_dsec,
2812 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
2813 VTY_NEWLINE);
2814 return CMD_WARNING;
2815 }
2816
2817 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2818
2819 if (query_max_response_time_dsec >= default_query_interval_dsec) {
2820 vty_out(vty,
2821 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
2822 query_max_response_time_dsec, default_query_interval_dsec,
2823 VTY_NEWLINE);
2824 return CMD_WARNING;
2825 }
2826
2827 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
2828
2829 return CMD_SUCCESS;
2830}
2831
2832DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
2833 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
2834 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
2835 NO_STR
2836 IP_STR
2837 IFACE_IGMP_STR
2838 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
2839{
2840 struct interface *ifp;
2841 struct pim_interface *pim_ifp;
2842 int default_query_interval_dsec;
2843
2844 ifp = vty->index;
2845 pim_ifp = ifp->info;
2846
2847 if (!pim_ifp)
2848 return CMD_SUCCESS;
2849
2850 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2851
2852 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
2853 vty_out(vty,
2854 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
2855 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
2856 VTY_NEWLINE);
2857 return CMD_WARNING;
2858 }
2859
2860 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
2861
2862 return CMD_SUCCESS;
2863}
2864
2865DEFUN (interface_ip_pim_ssm,
2866 interface_ip_pim_ssm_cmd,
2867 "ip pim ssm",
2868 IP_STR
2869 PIM_STR
2870 IFACE_PIM_STR)
2871{
2872 struct interface *ifp;
2873 struct pim_interface *pim_ifp;
2874
2875 ifp = vty->index;
2876 pim_ifp = ifp->info;
2877
2878 if (!pim_ifp) {
2879 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
2880 if (!pim_ifp) {
2881 vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
2882 return CMD_WARNING;
2883 }
2884 }
2885 else {
2886 PIM_IF_DO_PIM(pim_ifp->options);
2887 }
2888
2889 pim_if_addr_add_all(ifp);
2890 pim_if_membership_refresh(ifp);
2891
2892 return CMD_SUCCESS;
2893}
2894
2895DEFUN (interface_no_ip_pim_ssm,
2896 interface_no_ip_pim_ssm_cmd,
2897 "no ip pim ssm",
2898 NO_STR
2899 IP_STR
2900 PIM_STR
2901 IFACE_PIM_STR)
2902{
2903 struct interface *ifp;
2904 struct pim_interface *pim_ifp;
2905
2906 ifp = vty->index;
2907 pim_ifp = ifp->info;
2908 if (!pim_ifp)
2909 return CMD_SUCCESS;
2910
2911 PIM_IF_DONT_PIM(pim_ifp->options);
2912
2913 pim_if_membership_clear(ifp);
2914
2915 /*
2916 pim_if_addr_del_all() removes all sockets from
2917 pim_ifp->igmp_socket_list.
2918 */
2919 pim_if_addr_del_all(ifp);
2920
2921 /*
2922 pim_sock_delete() removes all neighbors from
2923 pim_ifp->pim_neighbor_list.
2924 */
2925 pim_sock_delete(ifp, "pim unconfigured on interface");
2926
2927 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
2928 pim_if_delete(ifp);
2929 }
2930
2931 return CMD_SUCCESS;
2932}
2933
2934DEFUN (debug_igmp,
2935 debug_igmp_cmd,
2936 "debug igmp",
2937 DEBUG_STR
2938 DEBUG_IGMP_STR)
2939{
2940 PIM_DO_DEBUG_IGMP_EVENTS;
2941 PIM_DO_DEBUG_IGMP_PACKETS;
2942 PIM_DO_DEBUG_IGMP_TRACE;
2943 return CMD_SUCCESS;
2944}
2945
2946DEFUN (no_debug_igmp,
2947 no_debug_igmp_cmd,
2948 "no debug igmp",
2949 NO_STR
2950 DEBUG_STR
2951 DEBUG_IGMP_STR)
2952{
2953 PIM_DONT_DEBUG_IGMP_EVENTS;
2954 PIM_DONT_DEBUG_IGMP_PACKETS;
2955 PIM_DONT_DEBUG_IGMP_TRACE;
2956 return CMD_SUCCESS;
2957}
2958
2959ALIAS (no_debug_igmp,
2960 undebug_igmp_cmd,
2961 "undebug igmp",
2962 UNDEBUG_STR
2963 DEBUG_IGMP_STR)
2964
2965DEFUN (debug_igmp_events,
2966 debug_igmp_events_cmd,
2967 "debug igmp events",
2968 DEBUG_STR
2969 DEBUG_IGMP_STR
2970 DEBUG_IGMP_EVENTS_STR)
2971{
2972 PIM_DO_DEBUG_IGMP_EVENTS;
2973 return CMD_SUCCESS;
2974}
2975
2976DEFUN (no_debug_igmp_events,
2977 no_debug_igmp_events_cmd,
2978 "no debug igmp events",
2979 NO_STR
2980 DEBUG_STR
2981 DEBUG_IGMP_STR
2982 DEBUG_IGMP_EVENTS_STR)
2983{
2984 PIM_DONT_DEBUG_IGMP_EVENTS;
2985 return CMD_SUCCESS;
2986}
2987
2988ALIAS (no_debug_igmp_events,
2989 undebug_igmp_events_cmd,
2990 "undebug igmp events",
2991 UNDEBUG_STR
2992 DEBUG_IGMP_STR
2993 DEBUG_IGMP_EVENTS_STR)
2994
2995DEFUN (debug_igmp_packets,
2996 debug_igmp_packets_cmd,
2997 "debug igmp packets",
2998 DEBUG_STR
2999 DEBUG_IGMP_STR
3000 DEBUG_IGMP_PACKETS_STR)
3001{
3002 PIM_DO_DEBUG_IGMP_PACKETS;
3003 return CMD_SUCCESS;
3004}
3005
3006DEFUN (no_debug_igmp_packets,
3007 no_debug_igmp_packets_cmd,
3008 "no debug igmp packets",
3009 NO_STR
3010 DEBUG_STR
3011 DEBUG_IGMP_STR
3012 DEBUG_IGMP_PACKETS_STR)
3013{
3014 PIM_DONT_DEBUG_IGMP_PACKETS;
3015 return CMD_SUCCESS;
3016}
3017
3018ALIAS (no_debug_igmp_packets,
3019 undebug_igmp_packets_cmd,
3020 "undebug igmp packets",
3021 UNDEBUG_STR
3022 DEBUG_IGMP_STR
3023 DEBUG_IGMP_PACKETS_STR)
3024
3025DEFUN (debug_igmp_trace,
3026 debug_igmp_trace_cmd,
3027 "debug igmp trace",
3028 DEBUG_STR
3029 DEBUG_IGMP_STR
3030 DEBUG_IGMP_TRACE_STR)
3031{
3032 PIM_DO_DEBUG_IGMP_TRACE;
3033 return CMD_SUCCESS;
3034}
3035
3036DEFUN (no_debug_igmp_trace,
3037 no_debug_igmp_trace_cmd,
3038 "no debug igmp trace",
3039 NO_STR
3040 DEBUG_STR
3041 DEBUG_IGMP_STR
3042 DEBUG_IGMP_TRACE_STR)
3043{
3044 PIM_DONT_DEBUG_IGMP_TRACE;
3045 return CMD_SUCCESS;
3046}
3047
3048ALIAS (no_debug_igmp_trace,
3049 undebug_igmp_trace_cmd,
3050 "undebug igmp trace",
3051 UNDEBUG_STR
3052 DEBUG_IGMP_STR
3053 DEBUG_IGMP_TRACE_STR)
3054
3055DEFUN (debug_pim,
3056 debug_pim_cmd,
3057 "debug pim",
3058 DEBUG_STR
3059 DEBUG_PIM_STR)
3060{
3061 PIM_DO_DEBUG_PIM_EVENTS;
3062 PIM_DO_DEBUG_PIM_PACKETS;
3063 PIM_DO_DEBUG_PIM_TRACE;
3064 return CMD_SUCCESS;
3065}
3066
3067DEFUN (no_debug_pim,
3068 no_debug_pim_cmd,
3069 "no debug pim",
3070 NO_STR
3071 DEBUG_STR
3072 DEBUG_PIM_STR)
3073{
3074 PIM_DONT_DEBUG_PIM_EVENTS;
3075 PIM_DONT_DEBUG_PIM_PACKETS;
3076 PIM_DONT_DEBUG_PIM_TRACE;
3077 return CMD_SUCCESS;
3078}
3079
3080ALIAS (no_debug_pim,
3081 undebug_pim_cmd,
3082 "undebug pim",
3083 UNDEBUG_STR
3084 DEBUG_PIM_STR)
3085
3086DEFUN (debug_pim_events,
3087 debug_pim_events_cmd,
3088 "debug pim events",
3089 DEBUG_STR
3090 DEBUG_PIM_STR
3091 DEBUG_PIM_EVENTS_STR)
3092{
3093 PIM_DO_DEBUG_PIM_EVENTS;
3094 return CMD_SUCCESS;
3095}
3096
3097DEFUN (no_debug_pim_events,
3098 no_debug_pim_events_cmd,
3099 "no debug pim events",
3100 NO_STR
3101 DEBUG_STR
3102 DEBUG_PIM_STR
3103 DEBUG_PIM_EVENTS_STR)
3104{
3105 PIM_DONT_DEBUG_PIM_EVENTS;
3106 return CMD_SUCCESS;
3107}
3108
3109ALIAS (no_debug_pim_events,
3110 undebug_pim_events_cmd,
3111 "undebug pim events",
3112 UNDEBUG_STR
3113 DEBUG_PIM_STR
3114 DEBUG_PIM_EVENTS_STR)
3115
3116DEFUN (debug_pim_packets,
3117 debug_pim_packets_cmd,
3118 "debug pim packets",
3119 DEBUG_STR
3120 DEBUG_PIM_STR
3121 DEBUG_PIM_PACKETS_STR)
3122{
3123 PIM_DO_DEBUG_PIM_PACKETS;
3124 return CMD_SUCCESS;
3125}
3126
3127DEFUN (no_debug_pim_packets,
3128 no_debug_pim_packets_cmd,
3129 "no debug pim packets",
3130 NO_STR
3131 DEBUG_STR
3132 DEBUG_PIM_STR
3133 DEBUG_PIM_PACKETS_STR)
3134{
3135 PIM_DONT_DEBUG_PIM_PACKETS;
3136 return CMD_SUCCESS;
3137}
3138
3139ALIAS (no_debug_pim_packets,
3140 undebug_pim_packets_cmd,
3141 "undebug pim packets",
3142 UNDEBUG_STR
3143 DEBUG_PIM_STR
3144 DEBUG_PIM_PACKETS_STR)
3145
3146DEFUN (debug_pim_trace,
3147 debug_pim_trace_cmd,
3148 "debug pim trace",
3149 DEBUG_STR
3150 DEBUG_PIM_STR
3151 DEBUG_PIM_TRACE_STR)
3152{
3153 PIM_DO_DEBUG_PIM_TRACE;
3154 return CMD_SUCCESS;
3155}
3156
3157DEFUN (no_debug_pim_trace,
3158 no_debug_pim_trace_cmd,
3159 "no debug pim trace",
3160 NO_STR
3161 DEBUG_STR
3162 DEBUG_PIM_STR
3163 DEBUG_PIM_TRACE_STR)
3164{
3165 PIM_DONT_DEBUG_PIM_TRACE;
3166 return CMD_SUCCESS;
3167}
3168
3169ALIAS (no_debug_pim_trace,
3170 undebug_pim_trace_cmd,
3171 "undebug pim trace",
3172 UNDEBUG_STR
3173 DEBUG_PIM_STR
3174 DEBUG_PIM_TRACE_STR)
3175
Everton Marques824adbe2009-10-08 09:16:27 -03003176DEFUN (debug_ssmpingd,
3177 debug_ssmpingd_cmd,
3178 "debug ssmpingd",
3179 DEBUG_STR
3180 DEBUG_PIM_STR
3181 DEBUG_SSMPINGD_STR)
3182{
3183 PIM_DO_DEBUG_SSMPINGD;
3184 return CMD_SUCCESS;
3185}
3186
3187DEFUN (no_debug_ssmpingd,
3188 no_debug_ssmpingd_cmd,
3189 "no debug ssmpingd",
3190 NO_STR
3191 DEBUG_STR
3192 DEBUG_PIM_STR
3193 DEBUG_SSMPINGD_STR)
3194{
3195 PIM_DONT_DEBUG_SSMPINGD;
3196 return CMD_SUCCESS;
3197}
3198
3199ALIAS (no_debug_ssmpingd,
3200 undebug_ssmpingd_cmd,
3201 "undebug ssmpingd",
3202 UNDEBUG_STR
3203 DEBUG_PIM_STR
3204 DEBUG_SSMPINGD_STR)
3205
Everton Marques871dbcf2009-08-11 15:43:05 -03003206DEFUN (debug_pim_zebra,
3207 debug_pim_zebra_cmd,
3208 "debug pim zebra",
3209 DEBUG_STR
3210 DEBUG_PIM_STR
3211 DEBUG_PIM_ZEBRA_STR)
3212{
3213 PIM_DO_DEBUG_ZEBRA;
3214 return CMD_SUCCESS;
3215}
3216
3217DEFUN (no_debug_pim_zebra,
3218 no_debug_pim_zebra_cmd,
3219 "no debug pim zebra",
3220 NO_STR
3221 DEBUG_STR
3222 DEBUG_PIM_STR
3223 DEBUG_PIM_ZEBRA_STR)
3224{
3225 PIM_DONT_DEBUG_ZEBRA;
3226 return CMD_SUCCESS;
3227}
3228
3229ALIAS (no_debug_pim_zebra,
3230 undebug_pim_zebra_cmd,
3231 "undebug pim zebra",
3232 UNDEBUG_STR
3233 DEBUG_PIM_STR
3234 DEBUG_PIM_ZEBRA_STR)
3235
3236DEFUN (show_debugging,
3237 show_debugging_cmd,
3238 "show debugging",
3239 SHOW_STR
3240 "State of each debugging option\n")
3241{
3242 pim_debug_config_write(vty);
3243 return CMD_SUCCESS;
3244}
3245
3246static struct igmp_sock *find_igmp_sock_by_fd(int fd)
3247{
3248 struct listnode *ifnode;
3249 struct interface *ifp;
3250
3251 /* scan all interfaces */
3252 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
3253 struct pim_interface *pim_ifp;
3254 struct igmp_sock *igmp;
3255
3256 if (!ifp->info)
3257 continue;
3258
3259 pim_ifp = ifp->info;
3260
3261 /* lookup igmp socket under current interface */
3262 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
3263 if (igmp)
3264 return igmp;
3265 }
3266
3267 return 0;
3268}
3269
3270DEFUN (test_igmp_receive_report,
3271 test_igmp_receive_report_cmd,
3272 "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
3273 "Test\n"
3274 "Test IGMP protocol\n"
3275 "Test IGMP message\n"
3276 "Test IGMP report\n"
3277 "Socket\n"
3278 "IGMP group address\n"
3279 "Record type\n"
3280 "Sources\n")
3281{
3282 char buf[1000];
3283 char *igmp_msg;
3284 struct ip *ip_hdr;
3285 size_t ip_hlen; /* ip header length in bytes */
3286 int ip_msg_len;
3287 int igmp_msg_len;
3288 const char *socket;
3289 int socket_fd;
3290 const char *grp_str;
3291 struct in_addr grp_addr;
3292 const char *record_type_str;
3293 int record_type;
3294 const char *src_str;
3295 int result;
3296 struct igmp_sock *igmp;
3297 char *group_record;
3298 int num_sources;
3299 struct in_addr *sources;
3300 struct in_addr *src_addr;
3301 int argi;
3302
3303 socket = argv[0];
3304 socket_fd = atoi(socket);
3305 igmp = find_igmp_sock_by_fd(socket_fd);
3306 if (!igmp) {
3307 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
3308 socket, socket_fd, VTY_NEWLINE);
3309 return CMD_WARNING;
3310 }
3311
3312 grp_str = argv[1];
3313 result = inet_pton(AF_INET, grp_str, &grp_addr);
3314 if (result <= 0) {
3315 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003316 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003317 return CMD_WARNING;
3318 }
3319
3320 record_type_str = argv[2];
3321 record_type = atoi(record_type_str);
3322
3323 /*
3324 Tweak IP header
3325 */
3326 ip_hdr = (struct ip *) buf;
3327 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
3328 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3329 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3330 ip_hdr->ip_src = igmp->ifaddr;
3331 ip_hdr->ip_dst = igmp->ifaddr;
3332
3333 /*
3334 Build IGMP v3 report message
3335 */
3336 igmp_msg = buf + ip_hlen;
3337 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
3338 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
3339 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
3340 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
3341 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
3342 *(struct in_addr *)(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET) = grp_addr;
3343
3344 /* Scan LINE sources */
3345 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
3346 src_addr = sources;
3347 for (argi = 3; argi < argc; ++argi,++src_addr) {
3348 src_str = argv[argi];
3349 result = inet_pton(AF_INET, src_str, src_addr);
3350 if (result <= 0) {
3351 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003352 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003353 return CMD_WARNING;
3354 }
3355 }
3356 num_sources = src_addr - sources;
3357
3358 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
3359
3360 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
3361
3362 /* compute checksum */
3363 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = pim_inet_checksum(igmp_msg, igmp_msg_len);
3364
3365 /* "receive" message */
3366
3367 ip_msg_len = ip_hlen + igmp_msg_len;
3368 result = pim_igmp_packet(igmp, buf, ip_msg_len);
3369 if (result) {
3370 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
3371 ip_msg_len, result, VTY_NEWLINE);
3372 return CMD_WARNING;
3373 }
3374
3375 return CMD_SUCCESS;
3376}
3377
3378DEFUN (test_pim_receive_hello,
3379 test_pim_receive_hello_cmd,
3380 "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
3381 "Test\n"
3382 "Test PIM protocol\n"
3383 "Test PIM message reception\n"
3384 "Test PIM hello reception from neighbor\n"
3385 "Interface\n"
3386 "Neighbor address\n"
3387 "Neighbor holdtime\n"
3388 "Neighbor DR priority\n"
3389 "Neighbor generation ID\n"
3390 "Neighbor propagation delay (msec)\n"
3391 "Neighbor override interval (msec)\n"
3392 "Neighbor LAN prune delay T-bit\n"
3393 "Neighbor secondary addresses\n")
3394{
3395 char buf[1000];
3396 char *pim_msg;
3397 struct ip *ip_hdr;
3398 size_t ip_hlen; /* ip header length in bytes */
3399 int ip_msg_len;
3400 int pim_tlv_size;
3401 int pim_msg_size;
3402 const char *neigh_str;
3403 struct in_addr neigh_addr;
3404 const char *ifname;
3405 struct interface *ifp;
3406 uint16_t neigh_holdtime;
3407 uint16_t neigh_propagation_delay;
3408 uint16_t neigh_override_interval;
3409 int neigh_can_disable_join_suppression;
3410 uint32_t neigh_dr_priority;
3411 uint32_t neigh_generation_id;
3412 int argi;
3413 int result;
3414
3415 /* Find interface */
3416 ifname = argv[0];
3417 ifp = if_lookup_by_name(ifname);
3418 if (!ifp) {
3419 vty_out(vty, "No such interface name %s%s",
3420 ifname, VTY_NEWLINE);
3421 return CMD_WARNING;
3422 }
3423
3424 /* Neighbor address */
3425 neigh_str = argv[1];
3426 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3427 if (result <= 0) {
3428 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003429 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003430 return CMD_WARNING;
3431 }
3432
3433 neigh_holdtime = atoi(argv[2]);
3434 neigh_dr_priority = atoi(argv[3]);
3435 neigh_generation_id = atoi(argv[4]);
3436 neigh_propagation_delay = atoi(argv[5]);
3437 neigh_override_interval = atoi(argv[6]);
3438 neigh_can_disable_join_suppression = atoi(argv[7]);
3439
3440 /*
3441 Tweak IP header
3442 */
3443 ip_hdr = (struct ip *) buf;
3444 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3445 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3446 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3447 ip_hdr->ip_src = neigh_addr;
3448 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3449
3450 /*
3451 Build PIM hello message
3452 */
3453 pim_msg = buf + ip_hlen;
3454
3455 /* Scan LINE addresses */
3456 for (argi = 8; argi < argc; ++argi) {
3457 const char *sec_str = argv[argi];
3458 struct in_addr sec_addr;
3459 result = inet_pton(AF_INET, sec_str, &sec_addr);
3460 if (result <= 0) {
3461 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003462 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003463 return CMD_WARNING;
3464 }
3465
3466 vty_out(vty,
3467 "FIXME WRITEME consider neighbor secondary address %s%s",
3468 sec_str, VTY_NEWLINE);
3469 }
3470
3471 pim_tlv_size = pim_hello_build_tlv(ifp->name,
3472 pim_msg + PIM_PIM_MIN_LEN,
3473 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
3474 neigh_holdtime,
3475 neigh_dr_priority,
3476 neigh_generation_id,
3477 neigh_propagation_delay,
3478 neigh_override_interval,
3479 neigh_can_disable_join_suppression,
3480 0 /* FIXME secondary address list */);
3481 if (pim_tlv_size < 0) {
3482 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
3483 pim_tlv_size, VTY_NEWLINE);
3484 return CMD_WARNING;
3485 }
3486
3487 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
3488
3489 pim_msg_build_header(pim_msg, pim_msg_size,
3490 PIM_MSG_TYPE_HELLO);
3491
3492 /* "receive" message */
3493
3494 ip_msg_len = ip_hlen + pim_msg_size;
3495 result = pim_pim_packet(ifp, buf, ip_msg_len);
3496 if (result) {
3497 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3498 ip_msg_len, result, VTY_NEWLINE);
3499 return CMD_WARNING;
3500 }
3501
3502 return CMD_SUCCESS;
3503}
3504
3505DEFUN (test_pim_receive_assert,
3506 test_pim_receive_assert_cmd,
3507 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
3508 "Test\n"
3509 "Test PIM protocol\n"
3510 "Test PIM message reception\n"
3511 "Test reception of PIM assert\n"
3512 "Interface\n"
3513 "Neighbor address\n"
3514 "Assert multicast group address\n"
3515 "Assert unicast source address\n"
3516 "Assert metric preference\n"
3517 "Assert route metric\n"
3518 "Assert RPT bit flag\n")
3519{
3520 char buf[1000];
3521 char *buf_pastend = buf + sizeof(buf);
3522 char *pim_msg;
3523 struct ip *ip_hdr;
3524 size_t ip_hlen; /* ip header length in bytes */
3525 int ip_msg_len;
3526 int pim_msg_size;
3527 const char *neigh_str;
3528 struct in_addr neigh_addr;
3529 const char *group_str;
3530 struct in_addr group_addr;
3531 const char *source_str;
3532 struct in_addr source_addr;
3533 const char *ifname;
3534 struct interface *ifp;
3535 uint32_t assert_metric_preference;
3536 uint32_t assert_route_metric;
3537 uint32_t assert_rpt_bit_flag;
3538 int remain;
3539 int result;
3540
3541 /* Find interface */
3542 ifname = argv[0];
3543 ifp = if_lookup_by_name(ifname);
3544 if (!ifp) {
3545 vty_out(vty, "No such interface name %s%s",
3546 ifname, VTY_NEWLINE);
3547 return CMD_WARNING;
3548 }
3549
3550 /* Neighbor address */
3551 neigh_str = argv[1];
3552 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3553 if (result <= 0) {
3554 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003555 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003556 return CMD_WARNING;
3557 }
3558
3559 /* Group address */
3560 group_str = argv[2];
3561 result = inet_pton(AF_INET, group_str, &group_addr);
3562 if (result <= 0) {
3563 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003564 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003565 return CMD_WARNING;
3566 }
3567
3568 /* Source address */
3569 source_str = argv[3];
3570 result = inet_pton(AF_INET, source_str, &source_addr);
3571 if (result <= 0) {
3572 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003573 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003574 return CMD_WARNING;
3575 }
3576
3577 assert_metric_preference = atoi(argv[4]);
3578 assert_route_metric = atoi(argv[5]);
3579 assert_rpt_bit_flag = atoi(argv[6]);
3580
3581 remain = buf_pastend - buf;
3582 if (remain < (int) sizeof(struct ip)) {
3583 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%d%s",
3584 remain, sizeof(struct ip), VTY_NEWLINE);
3585 return CMD_WARNING;
3586 }
3587
3588 /*
3589 Tweak IP header
3590 */
3591 ip_hdr = (struct ip *) buf;
3592 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3593 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3594 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3595 ip_hdr->ip_src = neigh_addr;
3596 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3597
3598 /*
3599 Build PIM assert message
3600 */
3601 pim_msg = buf + ip_hlen; /* skip ip header */
3602
3603 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
3604 group_addr, source_addr,
3605 assert_metric_preference,
3606 assert_route_metric,
3607 assert_rpt_bit_flag);
3608 if (pim_msg_size < 0) {
3609 vty_out(vty, "Failure building PIM assert message: size=%d%s",
3610 pim_msg_size, VTY_NEWLINE);
3611 return CMD_WARNING;
3612 }
3613
3614 /* "receive" message */
3615
3616 ip_msg_len = ip_hlen + pim_msg_size;
3617 result = pim_pim_packet(ifp, buf, ip_msg_len);
3618 if (result) {
3619 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3620 ip_msg_len, result, VTY_NEWLINE);
3621 return CMD_WARNING;
3622 }
3623
3624 return CMD_SUCCESS;
3625}
3626
3627static int recv_joinprune(struct vty *vty,
3628 const char *argv[],
3629 int src_is_join)
3630{
3631 char buf[1000];
3632 const char *buf_pastend = buf + sizeof(buf);
3633 char *pim_msg;
3634 char *pim_msg_curr;
3635 int pim_msg_size;
3636 struct ip *ip_hdr;
3637 size_t ip_hlen; /* ip header length in bytes */
3638 int ip_msg_len;
3639 uint16_t neigh_holdtime;
3640 const char *neigh_dst_str;
3641 struct in_addr neigh_dst_addr;
3642 const char *neigh_src_str;
3643 struct in_addr neigh_src_addr;
3644 const char *group_str;
3645 struct in_addr group_addr;
3646 const char *source_str;
3647 struct in_addr source_addr;
3648 const char *ifname;
3649 struct interface *ifp;
3650 int result;
3651 int remain;
3652 uint16_t num_joined;
3653 uint16_t num_pruned;
3654
3655 /* Find interface */
3656 ifname = argv[0];
3657 ifp = if_lookup_by_name(ifname);
3658 if (!ifp) {
3659 vty_out(vty, "No such interface name %s%s",
3660 ifname, VTY_NEWLINE);
3661 return CMD_WARNING;
3662 }
3663
3664 neigh_holdtime = atoi(argv[1]);
3665
3666 /* Neighbor destination address */
3667 neigh_dst_str = argv[2];
3668 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
3669 if (result <= 0) {
3670 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003671 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003672 return CMD_WARNING;
3673 }
3674
3675 /* Neighbor source address */
3676 neigh_src_str = argv[3];
3677 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
3678 if (result <= 0) {
3679 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003680 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003681 return CMD_WARNING;
3682 }
3683
3684 /* Multicast group address */
3685 group_str = argv[4];
3686 result = inet_pton(AF_INET, group_str, &group_addr);
3687 if (result <= 0) {
3688 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003689 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003690 return CMD_WARNING;
3691 }
3692
3693 /* Multicast source address */
3694 source_str = argv[5];
3695 result = inet_pton(AF_INET, source_str, &source_addr);
3696 if (result <= 0) {
3697 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003698 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003699 return CMD_WARNING;
3700 }
3701
3702 /*
3703 Tweak IP header
3704 */
3705 ip_hdr = (struct ip *) buf;
3706 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3707 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3708 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3709 ip_hdr->ip_src = neigh_src_addr;
3710 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3711
3712 /*
3713 Build PIM message
3714 */
3715 pim_msg = buf + ip_hlen;
3716
3717 /* skip room for pim header */
3718 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
3719
3720 remain = buf_pastend - pim_msg_curr;
3721 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
3722 remain,
3723 neigh_dst_addr);
3724 if (!pim_msg_curr) {
3725 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
3726 neigh_dst_str, remain, VTY_NEWLINE);
3727 return CMD_WARNING;
3728 }
3729
3730 remain = buf_pastend - pim_msg_curr;
3731 if (remain < 4) {
3732 vty_out(vty, "Group will not fit: space left=%d%s",
3733 remain, VTY_NEWLINE);
3734 return CMD_WARNING;
3735 }
3736
3737 *pim_msg_curr = 0; /* reserved */
3738 ++pim_msg_curr;
3739 *pim_msg_curr = 1; /* number of groups */
3740 ++pim_msg_curr;
3741 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
3742 ++pim_msg_curr;
3743 ++pim_msg_curr;
3744
3745 remain = buf_pastend - pim_msg_curr;
3746 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
3747 remain,
3748 group_addr);
3749 if (!pim_msg_curr) {
3750 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
3751 group_str, remain, VTY_NEWLINE);
3752 return CMD_WARNING;
3753 }
3754
3755 remain = buf_pastend - pim_msg_curr;
3756 if (remain < 4) {
3757 vty_out(vty, "Sources will not fit: space left=%d%s",
3758 remain, VTY_NEWLINE);
3759 return CMD_WARNING;
3760 }
3761
3762 if (src_is_join) {
3763 num_joined = 1;
3764 num_pruned = 0;
3765 }
3766 else {
3767 num_joined = 0;
3768 num_pruned = 1;
3769 }
3770
3771 /* number of joined sources */
3772 *((uint16_t *) pim_msg_curr) = htons(num_joined);
3773 ++pim_msg_curr;
3774 ++pim_msg_curr;
3775
3776 /* number of pruned sources */
3777 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
3778 ++pim_msg_curr;
3779 ++pim_msg_curr;
3780
3781 remain = buf_pastend - pim_msg_curr;
3782 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
3783 remain,
3784 source_addr);
3785 if (!pim_msg_curr) {
3786 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
3787 source_str, remain, VTY_NEWLINE);
3788 return CMD_WARNING;
3789 }
3790
3791 /* Add PIM header */
3792
3793 pim_msg_size = pim_msg_curr - pim_msg;
3794
3795 pim_msg_build_header(pim_msg, pim_msg_size,
3796 PIM_MSG_TYPE_JOIN_PRUNE);
3797
3798 /*
3799 "Receive" message
3800 */
3801
3802 ip_msg_len = ip_hlen + pim_msg_size;
3803 result = pim_pim_packet(ifp, buf, ip_msg_len);
3804 if (result) {
3805 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3806 ip_msg_len, result, VTY_NEWLINE);
3807 return CMD_WARNING;
3808 }
3809
3810 return CMD_SUCCESS;
3811}
3812
3813DEFUN (test_pim_receive_join,
3814 test_pim_receive_join_cmd,
3815 "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
3816 "Test\n"
3817 "Test PIM protocol\n"
3818 "Test PIM message reception\n"
3819 "Test PIM join reception from neighbor\n"
3820 "Interface\n"
3821 "Neighbor holdtime\n"
3822 "Upstream neighbor unicast destination address\n"
3823 "Downstream neighbor unicast source address\n"
3824 "Multicast group address\n"
3825 "Unicast source address\n")
3826{
3827 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
3828}
3829
3830DEFUN (test_pim_receive_prune,
3831 test_pim_receive_prune_cmd,
3832 "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
3833 "Test\n"
3834 "Test PIM protocol\n"
3835 "Test PIM message reception\n"
3836 "Test PIM prune reception from neighbor\n"
3837 "Interface\n"
3838 "Neighbor holdtime\n"
3839 "Upstream neighbor unicast destination address\n"
3840 "Downstream neighbor unicast source address\n"
3841 "Multicast group address\n"
3842 "Unicast source address\n")
3843{
3844 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
3845}
3846
3847DEFUN (test_pim_receive_upcall,
3848 test_pim_receive_upcall_cmd,
3849 "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
3850 "Test\n"
3851 "Test PIM protocol\n"
3852 "Test PIM message reception\n"
3853 "Test reception of kernel upcall\n"
3854 "NOCACHE kernel upcall\n"
3855 "WRONGVIF kernel upcall\n"
3856 "WHOLEPKT kernel upcall\n"
3857 "Input interface vif index\n"
3858 "Multicast group address\n"
3859 "Multicast source address\n")
3860{
3861 struct igmpmsg msg;
3862 const char *upcall_type;
3863 const char *group_str;
3864 const char *source_str;
3865 int result;
3866
3867 upcall_type = argv[0];
3868
3869 if (upcall_type[0] == 'n')
3870 msg.im_msgtype = IGMPMSG_NOCACHE;
3871 else if (upcall_type[1] == 'r')
3872 msg.im_msgtype = IGMPMSG_WRONGVIF;
3873 else if (upcall_type[1] == 'h')
3874 msg.im_msgtype = IGMPMSG_WHOLEPKT;
3875 else {
3876 vty_out(vty, "Unknown kernel upcall type: %s%s",
3877 upcall_type, VTY_NEWLINE);
3878 return CMD_WARNING;
3879 }
3880
3881 msg.im_vif = atoi(argv[1]);
3882
3883 /* Group address */
3884 group_str = argv[2];
3885 result = inet_pton(AF_INET, group_str, &msg.im_dst);
3886 if (result <= 0) {
3887 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003888 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003889 return CMD_WARNING;
3890 }
3891
3892 /* Source address */
3893 source_str = argv[3];
3894 result = inet_pton(AF_INET, source_str, &msg.im_src);
3895 if (result <= 0) {
3896 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003897 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003898 return CMD_WARNING;
3899 }
3900
3901 msg.im_mbz = 0; /* Must be zero */
3902
3903 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
3904 if (result) {
3905 vty_out(vty, "pim_mroute_msg(len=%d) returned failure: %d%s",
3906 sizeof(msg), result, VTY_NEWLINE);
3907 return CMD_WARNING;
3908 }
3909
3910 return CMD_SUCCESS;
3911}
3912
3913void pim_cmd_init()
3914{
Leonard Herve596470f2009-08-11 15:45:26 -03003915 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
3916 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
Everton Marques871dbcf2009-08-11 15:43:05 -03003917
Leonard Herve596470f2009-08-11 15:45:26 -03003918 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
3919 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
Everton Marques96f91ae2009-10-07 18:41:45 -03003920 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
3921 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003922#if 0
Leonard Herve596470f2009-08-11 15:45:26 -03003923 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03003924#else
Leonard Herve596470f2009-08-11 15:45:26 -03003925 install_element (CONFIG_NODE, &pim_interface_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003926#endif
Leonard Herve596470f2009-08-11 15:45:26 -03003927 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03003928
Leonard Herve596470f2009-08-11 15:45:26 -03003929 install_default (INTERFACE_NODE);
3930 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
3931 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
3932 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
3933 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
3934 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
3935 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
3936 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
3937 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
3938 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
3939 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
3940 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
3941 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003942
Leonard Herve596470f2009-08-11 15:45:26 -03003943 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
3944 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
3945 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
3946 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
3947 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
3948 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
3949 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
3950 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
3951 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
3952 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
3953 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
3954 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
3955 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
3956 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
3957 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
3958 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
3959 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
3960 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
3961 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
3962 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
3963 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
3964 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
3965 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
3966 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
3967 install_element (VIEW_NODE, &show_ip_multicast_cmd);
3968 install_element (VIEW_NODE, &show_ip_mroute_cmd);
3969 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
3970 install_element (VIEW_NODE, &show_ip_route_cmd);
Everton Marques824adbe2009-10-08 09:16:27 -03003971 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03003972 install_element (VIEW_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003973
Leonard Herve596470f2009-08-11 15:45:26 -03003974 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
3975 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
3976 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03003977
Leonard Herve596470f2009-08-11 15:45:26 -03003978 install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
3979 install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
3980 install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
3981 install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
3982 install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
3983 install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
3984 install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
3985 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
3986 install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
3987 install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
3988 install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
3989 install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
3990 install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
3991 install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
3992 install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
3993 install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
3994 install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
3995 install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
3996 install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
3997 install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
3998 install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
3999 install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
4000 install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
4001 install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
4002 install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
4003 install_element (ENABLE_NODE, &show_ip_multicast_cmd);
4004 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
4005 install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
4006 install_element (ENABLE_NODE, &show_ip_route_cmd);
4007 install_element (ENABLE_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004008
Leonard Herve596470f2009-08-11 15:45:26 -03004009 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
4010 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
4011 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
4012 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
4013 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
4014 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004015
Leonard Herve596470f2009-08-11 15:45:26 -03004016 install_element (ENABLE_NODE, &debug_igmp_cmd);
4017 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
4018 install_element (ENABLE_NODE, &undebug_igmp_cmd);
4019 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
4020 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
4021 install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
4022 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
4023 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
4024 install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
4025 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
4026 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
4027 install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
4028 install_element (ENABLE_NODE, &debug_pim_cmd);
4029 install_element (ENABLE_NODE, &no_debug_pim_cmd);
4030 install_element (ENABLE_NODE, &undebug_pim_cmd);
4031 install_element (ENABLE_NODE, &debug_pim_events_cmd);
4032 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
4033 install_element (ENABLE_NODE, &undebug_pim_events_cmd);
4034 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
4035 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
4036 install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
4037 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
4038 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
4039 install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
Everton Marques824adbe2009-10-08 09:16:27 -03004040 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
4041 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
4042 install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004043 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
4044 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
4045 install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004046
Leonard Herve596470f2009-08-11 15:45:26 -03004047 install_element (CONFIG_NODE, &debug_igmp_cmd);
4048 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
4049 install_element (CONFIG_NODE, &undebug_igmp_cmd);
4050 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
4051 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
4052 install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
4053 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
4054 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
4055 install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
4056 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
4057 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
4058 install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
4059 install_element (CONFIG_NODE, &debug_pim_cmd);
4060 install_element (CONFIG_NODE, &no_debug_pim_cmd);
4061 install_element (CONFIG_NODE, &undebug_pim_cmd);
4062 install_element (CONFIG_NODE, &debug_pim_events_cmd);
4063 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
4064 install_element (CONFIG_NODE, &undebug_pim_events_cmd);
4065 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
4066 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
4067 install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
4068 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
4069 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
4070 install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
Everton Marques824adbe2009-10-08 09:16:27 -03004071 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
4072 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
4073 install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004074 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
4075 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
4076 install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004077}