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