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