blob: 6176fe55862aab2ac512bd520644a94125aa6a3d [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
Everton Marques3456a802014-07-22 14:52:57 -03001566DEFUN (clear_zclient_update,
1567 clear_zclient_update_cmd,
1568 "clear zclient-update",
1569 CLEAR_STR
1570 "Reset zclient update connection to zebra daemon\n")
1571{
1572 zclient_reset(qpim_zclient_update);
1573
1574 return CMD_SUCCESS;
1575}
1576
Everton Marques871dbcf2009-08-11 15:43:05 -03001577DEFUN (clear_ip_interfaces,
1578 clear_ip_interfaces_cmd,
1579 "clear ip interfaces",
1580 CLEAR_STR
1581 IP_STR
1582 "Reset interfaces\n")
1583{
1584 clear_interfaces();
1585
1586 return CMD_SUCCESS;
1587}
1588
1589DEFUN (clear_ip_igmp_interfaces,
1590 clear_ip_igmp_interfaces_cmd,
1591 "clear ip igmp interfaces",
1592 CLEAR_STR
1593 IP_STR
1594 CLEAR_IP_IGMP_STR
1595 "Reset IGMP interfaces\n")
1596{
1597 clear_igmp_interfaces();
1598
1599 return CMD_SUCCESS;
1600}
1601
Everton Marquesf24200d2014-02-14 16:40:34 -02001602static void mroute_add_all()
1603{
1604 struct listnode *node;
1605 struct channel_oil *c_oil;
1606
1607 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1608 if (pim_mroute_add(&c_oil->oil)) {
1609 /* just log warning */
1610 char source_str[100];
1611 char group_str[100];
1612 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1613 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1614 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1615 __FILE__, __PRETTY_FUNCTION__,
1616 source_str, group_str);
1617 }
1618 }
1619}
1620
1621static void mroute_del_all()
1622{
1623 struct listnode *node;
1624 struct channel_oil *c_oil;
1625
1626 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1627 if (pim_mroute_del(&c_oil->oil)) {
1628 /* just log warning */
1629 char source_str[100];
1630 char group_str[100];
1631 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1632 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1633 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1634 __FILE__, __PRETTY_FUNCTION__,
1635 source_str, group_str);
1636 }
1637 }
1638}
1639
1640DEFUN (clear_ip_mroute,
1641 clear_ip_mroute_cmd,
1642 "clear ip mroute",
1643 CLEAR_STR
1644 IP_STR
1645 "Reset multicast routes\n")
1646{
1647 mroute_del_all();
1648 mroute_add_all();
1649
1650 return CMD_SUCCESS;
1651}
1652
Everton Marques871dbcf2009-08-11 15:43:05 -03001653DEFUN (clear_ip_pim_interfaces,
1654 clear_ip_pim_interfaces_cmd,
1655 "clear ip pim interfaces",
1656 CLEAR_STR
1657 IP_STR
1658 CLEAR_IP_PIM_STR
1659 "Reset PIM interfaces\n")
1660{
1661 clear_pim_interfaces();
1662
1663 return CMD_SUCCESS;
1664}
1665
Everton Marquesf24200d2014-02-14 16:40:34 -02001666DEFUN (clear_ip_pim_oil,
1667 clear_ip_pim_oil_cmd,
1668 "clear ip pim oil",
1669 CLEAR_STR
1670 IP_STR
1671 CLEAR_IP_PIM_STR
1672 "Rescan PIM OIL (output interface list)\n")
1673{
1674 pim_scan_oil();
1675
1676 return CMD_SUCCESS;
1677}
1678
Everton Marques871dbcf2009-08-11 15:43:05 -03001679DEFUN (show_ip_igmp_interface,
1680 show_ip_igmp_interface_cmd,
1681 "show ip igmp interface",
1682 SHOW_STR
1683 IP_STR
1684 IGMP_STR
1685 "IGMP interface information\n")
1686{
1687 igmp_show_interfaces(vty);
1688
1689 return CMD_SUCCESS;
1690}
1691
Everton Marques567f9272010-02-19 19:07:00 -02001692DEFUN (show_ip_igmp_join,
1693 show_ip_igmp_join_cmd,
1694 "show ip igmp join",
1695 SHOW_STR
1696 IP_STR
1697 IGMP_STR
1698 "IGMP static join information\n")
1699{
1700 igmp_show_interface_join(vty);
1701
1702 return CMD_SUCCESS;
1703}
1704
Everton Marques871dbcf2009-08-11 15:43:05 -03001705DEFUN (show_ip_igmp_groups,
1706 show_ip_igmp_groups_cmd,
1707 "show ip igmp groups",
1708 SHOW_STR
1709 IP_STR
1710 IGMP_STR
1711 IGMP_GROUP_STR)
1712{
1713 igmp_show_groups(vty);
1714
1715 return CMD_SUCCESS;
1716}
1717
1718DEFUN (show_ip_igmp_groups_retransmissions,
1719 show_ip_igmp_groups_retransmissions_cmd,
1720 "show ip igmp groups retransmissions",
1721 SHOW_STR
1722 IP_STR
1723 IGMP_STR
1724 IGMP_GROUP_STR
1725 "IGMP group retransmissions\n")
1726{
1727 igmp_show_group_retransmission(vty);
1728
1729 return CMD_SUCCESS;
1730}
1731
1732DEFUN (show_ip_igmp_parameters,
1733 show_ip_igmp_parameters_cmd,
1734 "show ip igmp parameters",
1735 SHOW_STR
1736 IP_STR
1737 IGMP_STR
1738 "IGMP parameters information\n")
1739{
1740 igmp_show_parameters(vty);
1741
1742 return CMD_SUCCESS;
1743}
1744
1745DEFUN (show_ip_igmp_sources,
1746 show_ip_igmp_sources_cmd,
1747 "show ip igmp sources",
1748 SHOW_STR
1749 IP_STR
1750 IGMP_STR
1751 IGMP_SOURCE_STR)
1752{
1753 igmp_show_sources(vty);
1754
1755 return CMD_SUCCESS;
1756}
1757
1758DEFUN (show_ip_igmp_sources_retransmissions,
1759 show_ip_igmp_sources_retransmissions_cmd,
1760 "show ip igmp sources retransmissions",
1761 SHOW_STR
1762 IP_STR
1763 IGMP_STR
1764 IGMP_SOURCE_STR
1765 "IGMP source retransmissions\n")
1766{
1767 igmp_show_source_retransmission(vty);
1768
1769 return CMD_SUCCESS;
1770}
1771
1772DEFUN (show_ip_igmp_querier,
1773 show_ip_igmp_querier_cmd,
1774 "show ip igmp querier",
1775 SHOW_STR
1776 IP_STR
1777 IGMP_STR
1778 "IGMP querier information\n")
1779{
1780 igmp_show_querier(vty);
1781
1782 return CMD_SUCCESS;
1783}
1784
1785DEFUN (show_ip_pim_address,
1786 show_ip_pim_address_cmd,
1787 "show ip pim address",
1788 SHOW_STR
1789 IP_STR
1790 PIM_STR
1791 "PIM interface address\n")
1792{
1793 show_interface_address(vty);
1794
1795 return CMD_SUCCESS;
1796}
1797
1798DEFUN (show_ip_pim_assert,
1799 show_ip_pim_assert_cmd,
1800 "show ip pim assert",
1801 SHOW_STR
1802 IP_STR
1803 PIM_STR
1804 "PIM interface assert\n")
1805{
1806 pim_show_assert(vty);
1807
1808 return CMD_SUCCESS;
1809}
1810
1811DEFUN (show_ip_pim_assert_internal,
1812 show_ip_pim_assert_internal_cmd,
1813 "show ip pim assert-internal",
1814 SHOW_STR
1815 IP_STR
1816 PIM_STR
1817 "PIM interface internal assert state\n")
1818{
1819 pim_show_assert_internal(vty);
1820
1821 return CMD_SUCCESS;
1822}
1823
1824DEFUN (show_ip_pim_assert_metric,
1825 show_ip_pim_assert_metric_cmd,
1826 "show ip pim assert-metric",
1827 SHOW_STR
1828 IP_STR
1829 PIM_STR
1830 "PIM interface assert metric\n")
1831{
1832 pim_show_assert_metric(vty);
1833
1834 return CMD_SUCCESS;
1835}
1836
1837DEFUN (show_ip_pim_assert_winner_metric,
1838 show_ip_pim_assert_winner_metric_cmd,
1839 "show ip pim assert-winner-metric",
1840 SHOW_STR
1841 IP_STR
1842 PIM_STR
1843 "PIM interface assert winner metric\n")
1844{
1845 pim_show_assert_winner_metric(vty);
1846
1847 return CMD_SUCCESS;
1848}
1849
1850DEFUN (show_ip_pim_dr,
1851 show_ip_pim_dr_cmd,
1852 "show ip pim designated-router",
1853 SHOW_STR
1854 IP_STR
1855 PIM_STR
1856 "PIM interface designated router\n")
1857{
1858 pim_show_dr(vty);
1859
1860 return CMD_SUCCESS;
1861}
1862
1863DEFUN (show_ip_pim_hello,
1864 show_ip_pim_hello_cmd,
1865 "show ip pim hello",
1866 SHOW_STR
1867 IP_STR
1868 PIM_STR
1869 "PIM interface hello information\n")
1870{
1871 pim_show_hello(vty);
1872
1873 return CMD_SUCCESS;
1874}
1875
1876DEFUN (show_ip_pim_interface,
1877 show_ip_pim_interface_cmd,
1878 "show ip pim interface",
1879 SHOW_STR
1880 IP_STR
1881 PIM_STR
1882 "PIM interface information\n")
1883{
1884 pim_show_interfaces(vty);
1885
1886 return CMD_SUCCESS;
1887}
1888
1889DEFUN (show_ip_pim_join,
1890 show_ip_pim_join_cmd,
1891 "show ip pim join",
1892 SHOW_STR
1893 IP_STR
1894 PIM_STR
1895 "PIM interface join information\n")
1896{
1897 pim_show_join(vty);
1898
1899 return CMD_SUCCESS;
1900}
1901
1902DEFUN (show_ip_pim_lan_prune_delay,
1903 show_ip_pim_lan_prune_delay_cmd,
1904 "show ip pim lan-prune-delay",
1905 SHOW_STR
1906 IP_STR
1907 PIM_STR
1908 "PIM neighbors LAN prune delay parameters\n")
1909{
1910 pim_show_lan_prune_delay(vty);
1911
1912 return CMD_SUCCESS;
1913}
1914
1915DEFUN (show_ip_pim_local_membership,
1916 show_ip_pim_local_membership_cmd,
1917 "show ip pim local-membership",
1918 SHOW_STR
1919 IP_STR
1920 PIM_STR
1921 "PIM interface local-membership\n")
1922{
1923 pim_show_membership(vty);
1924
1925 return CMD_SUCCESS;
1926}
1927
1928DEFUN (show_ip_pim_jp_override_interval,
1929 show_ip_pim_jp_override_interval_cmd,
1930 "show ip pim jp-override-interval",
1931 SHOW_STR
1932 IP_STR
1933 PIM_STR
1934 "PIM interface J/P override interval\n")
1935{
1936 pim_show_jp_override_interval(vty);
1937
1938 return CMD_SUCCESS;
1939}
1940
1941DEFUN (show_ip_pim_neighbor,
1942 show_ip_pim_neighbor_cmd,
1943 "show ip pim neighbor",
1944 SHOW_STR
1945 IP_STR
1946 PIM_STR
1947 "PIM neighbor information\n")
1948{
1949 pim_show_neighbors(vty);
1950
1951 return CMD_SUCCESS;
1952}
1953
1954DEFUN (show_ip_pim_secondary,
1955 show_ip_pim_secondary_cmd,
1956 "show ip pim secondary",
1957 SHOW_STR
1958 IP_STR
1959 PIM_STR
1960 "PIM neighbor addresses\n")
1961{
1962 pim_show_neighbors_secondary(vty);
1963
1964 return CMD_SUCCESS;
1965}
1966
1967DEFUN (show_ip_pim_upstream,
1968 show_ip_pim_upstream_cmd,
1969 "show ip pim upstream",
1970 SHOW_STR
1971 IP_STR
1972 PIM_STR
1973 "PIM upstream information\n")
1974{
1975 pim_show_upstream(vty);
1976
1977 return CMD_SUCCESS;
1978}
1979
1980DEFUN (show_ip_pim_upstream_join_desired,
1981 show_ip_pim_upstream_join_desired_cmd,
1982 "show ip pim upstream-join-desired",
1983 SHOW_STR
1984 IP_STR
1985 PIM_STR
1986 "PIM upstream join-desired\n")
1987{
1988 pim_show_join_desired(vty);
1989
1990 return CMD_SUCCESS;
1991}
1992
1993DEFUN (show_ip_pim_upstream_rpf,
1994 show_ip_pim_upstream_rpf_cmd,
1995 "show ip pim upstream-rpf",
1996 SHOW_STR
1997 IP_STR
1998 PIM_STR
1999 "PIM upstream source rpf\n")
2000{
2001 pim_show_upstream_rpf(vty);
2002
2003 return CMD_SUCCESS;
2004}
2005
2006DEFUN (show_ip_pim_rpf,
2007 show_ip_pim_rpf_cmd,
2008 "show ip pim rpf",
2009 SHOW_STR
2010 IP_STR
2011 PIM_STR
2012 "PIM cached source rpf information\n")
2013{
2014 pim_show_rpf(vty);
2015
2016 return CMD_SUCCESS;
2017}
2018
2019static void show_multicast_interfaces(struct vty *vty)
2020{
2021 struct listnode *node;
2022 struct interface *ifp;
2023
2024 vty_out(vty, "%s", VTY_NEWLINE);
2025
Everton Marques613938d2009-08-13 15:39:31 -03002026 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03002027 VTY_NEWLINE);
2028
2029 for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
2030 struct pim_interface *pim_ifp;
2031 struct in_addr ifaddr;
2032 struct sioc_vif_req vreq;
2033
2034 pim_ifp = ifp->info;
2035
2036 if (!pim_ifp)
2037 continue;
2038
2039 memset(&vreq, 0, sizeof(vreq));
2040 vreq.vifi = pim_ifp->mroute_vif_index;
2041
2042 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
2043 int e = errno;
2044 vty_out(vty,
2045 "ioctl(SIOCGETVIFCNT=%d) failure for interface %s vif_index=%d: errno=%d: %s%s",
2046 SIOCGETVIFCNT,
2047 ifp->name,
2048 pim_ifp->mroute_vif_index,
2049 e,
Everton Marquese96f0af2009-08-11 15:48:02 -03002050 safe_strerror(e),
Everton Marques871dbcf2009-08-11 15:43:05 -03002051 VTY_NEWLINE);
2052 continue;
2053 }
2054
2055 ifaddr = pim_ifp->primary_address;
2056
Everton Marques613938d2009-08-13 15:39:31 -03002057 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03002058 ifp->name,
2059 inet_ntoa(ifaddr),
2060 ifp->ifindex,
2061 pim_ifp->mroute_vif_index,
2062 vreq.icount,
2063 vreq.ocount,
2064 vreq.ibytes,
2065 vreq.obytes,
2066 VTY_NEWLINE);
2067 }
2068}
2069
2070DEFUN (show_ip_multicast,
2071 show_ip_multicast_cmd,
2072 "show ip multicast",
2073 SHOW_STR
2074 IP_STR
2075 "Multicast global information\n")
2076{
Everton Marquesbcc4abe2009-08-17 18:18:59 -03002077 time_t now = pim_time_monotonic_sec();
2078
Everton Marques871dbcf2009-08-11 15:43:05 -03002079 if (PIM_MROUTE_IS_ENABLED) {
Everton Marques871dbcf2009-08-11 15:43:05 -03002080 char uptime[10];
2081
2082 vty_out(vty, "Mroute socket descriptor: %d%s",
2083 qpim_mroute_socket_fd,
2084 VTY_NEWLINE);
2085
Everton Marques871dbcf2009-08-11 15:43:05 -03002086 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
2087 vty_out(vty, "Mroute socket uptime: %s%s",
2088 uptime,
2089 VTY_NEWLINE);
2090 }
2091 else {
2092 vty_out(vty, "Multicast disabled%s",
2093 VTY_NEWLINE);
2094 }
2095
2096 vty_out(vty, "%s", VTY_NEWLINE);
Everton Marquese324ddc2014-09-29 17:59:02 -03002097 vty_out(vty, "Zclient update socket: ");
2098 if (qpim_zclient_update) {
Everton Marquesddc66592014-09-30 16:49:36 -03002099 vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
2100 qpim_zclient_update->fail, VTY_NEWLINE);
Everton Marquese324ddc2014-09-29 17:59:02 -03002101 }
2102 else {
2103 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2104 }
2105 vty_out(vty, "Zclient lookup socket: ");
2106 if (qpim_zclient_lookup) {
Everton Marquesddc66592014-09-30 16:49:36 -03002107 vty_out(vty, "%d failures=%d%s", qpim_zclient_lookup->sock,
2108 qpim_zclient_lookup->fail, VTY_NEWLINE);
Everton Marquese324ddc2014-09-29 17:59:02 -03002109 }
2110 else {
2111 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2112 }
2113
2114 vty_out(vty, "%s", VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002115 vty_out(vty, "Current highest VifIndex: %d%s",
2116 qpim_mroute_oif_highest_vif_index,
2117 VTY_NEWLINE);
2118 vty_out(vty, "Maximum highest VifIndex: %d%s",
2119 MAXVIFS - 1,
2120 VTY_NEWLINE);
2121
2122 vty_out(vty, "%s", VTY_NEWLINE);
2123 vty_out(vty, "Upstream Join Timer: %d secs%s",
2124 qpim_t_periodic,
2125 VTY_NEWLINE);
2126 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
2127 PIM_JP_HOLDTIME,
2128 VTY_NEWLINE);
2129
2130 vty_out(vty, "%s", VTY_NEWLINE);
Everton Marques613938d2009-08-13 15:39:31 -03002131
Everton Marquesbcc4abe2009-08-17 18:18:59 -03002132 show_rpf_refresh_stats(vty, now);
Everton Marques871dbcf2009-08-11 15:43:05 -03002133
Everton Marquesf24200d2014-02-14 16:40:34 -02002134 vty_out(vty, "%s", VTY_NEWLINE);
2135
2136 show_scan_oil_stats(vty, now);
2137
Everton Marques871dbcf2009-08-11 15:43:05 -03002138 show_multicast_interfaces(vty);
2139
2140 return CMD_SUCCESS;
2141}
2142
2143static void show_mroute(struct vty *vty)
2144{
2145 struct listnode *node;
2146 struct channel_oil *c_oil;
2147 time_t now;
2148
2149 vty_out(vty, "Proto: I=IGMP P=PIM%s%s", VTY_NEWLINE, VTY_NEWLINE);
2150
2151 vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
2152 VTY_NEWLINE);
2153
2154 now = pim_time_monotonic_sec();
2155
2156 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2157 char group_str[100];
2158 char source_str[100];
2159 int oif_vif_index;
2160
2161 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2162 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2163
2164 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2165 struct interface *ifp_in;
2166 struct interface *ifp_out;
2167 char oif_uptime[10];
2168 int ttl;
2169 char proto[5];
2170
2171 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2172 if (ttl < 1)
2173 continue;
2174
2175 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
2176 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2177
2178 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
2179
2180 proto[0] = '\0';
2181 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2182 strcat(proto, "P");
2183 }
2184 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2185 strcat(proto, "I");
2186 }
2187
2188 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2189 source_str,
2190 group_str,
2191 proto,
2192 ifp_in ? ifp_in->name : "<iif?>",
2193 c_oil->oil.mfcc_parent,
2194 ifp_out ? ifp_out->name : "<oif?>",
2195 oif_vif_index,
2196 ttl,
2197 oif_uptime,
2198 VTY_NEWLINE);
2199 }
2200 }
2201}
2202
2203DEFUN (show_ip_mroute,
2204 show_ip_mroute_cmd,
2205 "show ip mroute",
2206 SHOW_STR
2207 IP_STR
2208 MROUTE_STR)
2209{
2210 show_mroute(vty);
2211 return CMD_SUCCESS;
2212}
2213
2214static void show_mroute_count(struct vty *vty)
2215{
2216 struct listnode *node;
2217 struct channel_oil *c_oil;
2218
2219 vty_out(vty, "%s", VTY_NEWLINE);
2220
2221 vty_out(vty, "Source Group Packets Bytes WrongIf %s",
2222 VTY_NEWLINE);
2223
2224 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2225 char group_str[100];
2226 char source_str[100];
2227 struct sioc_sg_req sgreq;
2228
2229 memset(&sgreq, 0, sizeof(sgreq));
2230 sgreq.src = c_oil->oil.mfcc_origin;
2231 sgreq.grp = c_oil->oil.mfcc_mcastgrp;
2232
2233 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2234 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2235
2236 if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
2237 int e = errno;
2238 vty_out(vty,
2239 "ioctl(SIOCGETSGCNT=%d) failure for (S,G)=(%s,%s): errno=%d: %s%s",
2240 SIOCGETSGCNT,
2241 source_str,
2242 group_str,
2243 e,
Everton Marquese96f0af2009-08-11 15:48:02 -03002244 safe_strerror(e),
Everton Marques871dbcf2009-08-11 15:43:05 -03002245 VTY_NEWLINE);
2246 continue;
2247 }
2248
2249 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2250 source_str,
2251 group_str,
2252 sgreq.pktcnt,
2253 sgreq.bytecnt,
2254 sgreq.wrong_if,
2255 VTY_NEWLINE);
2256
2257 }
2258}
2259
2260DEFUN (show_ip_mroute_count,
2261 show_ip_mroute_count_cmd,
2262 "show ip mroute count",
2263 SHOW_STR
2264 IP_STR
2265 MROUTE_STR
2266 "Route and packet count data\n")
2267{
2268 show_mroute_count(vty);
2269 return CMD_SUCCESS;
2270}
2271
Everton Marques05e573d2010-04-20 12:20:46 -03002272DEFUN (show_ip_rib,
2273 show_ip_rib_cmd,
2274 "show ip rib A.B.C.D",
Everton Marques871dbcf2009-08-11 15:43:05 -03002275 SHOW_STR
2276 IP_STR
Everton Marques05e573d2010-04-20 12:20:46 -03002277 RIB_STR
Everton Marques871dbcf2009-08-11 15:43:05 -03002278 "Unicast address\n")
2279{
2280 struct in_addr addr;
2281 const char *addr_str;
2282 struct pim_nexthop nexthop;
2283 char nexthop_addr_str[100];
2284 int result;
2285
2286 addr_str = argv[0];
2287 result = inet_pton(AF_INET, addr_str, &addr);
2288 if (result <= 0) {
2289 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002290 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002291 return CMD_WARNING;
2292 }
2293
2294 if (pim_nexthop_lookup(&nexthop, addr)) {
2295 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
2296 addr_str, VTY_NEWLINE);
2297 return CMD_WARNING;
2298 }
2299
2300 vty_out(vty, "Address NextHop Interface Metric Preference%s",
2301 VTY_NEWLINE);
2302
2303 pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
2304 nexthop_addr_str, sizeof(nexthop_addr_str));
2305
2306 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
2307 addr_str,
2308 nexthop_addr_str,
2309 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2310 nexthop.mrib_route_metric,
2311 nexthop.mrib_metric_preference,
2312 VTY_NEWLINE);
2313
2314 return CMD_SUCCESS;
2315}
2316
Everton Marques824adbe2009-10-08 09:16:27 -03002317static void show_ssmpingd(struct vty *vty)
2318{
2319 struct listnode *node;
2320 struct ssmpingd_sock *ss;
2321 time_t now;
2322
Everton Marquese8c11bb2009-10-08 15:06:32 -03002323 vty_out(vty, "Source Socket Address Port Uptime Requests%s",
Everton Marques824adbe2009-10-08 09:16:27 -03002324 VTY_NEWLINE);
2325
2326 if (!qpim_ssmpingd_list)
2327 return;
2328
2329 now = pim_time_monotonic_sec();
2330
2331 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
2332 char source_str[100];
2333 char ss_uptime[10];
Everton Marquese8c11bb2009-10-08 15:06:32 -03002334 struct sockaddr_in bind_addr;
David Lampartere269b962012-02-16 04:32:08 +00002335 socklen_t len = sizeof(bind_addr);
Everton Marquese8c11bb2009-10-08 15:06:32 -03002336 char bind_addr_str[100];
Everton Marques824adbe2009-10-08 09:16:27 -03002337
2338 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
Everton Marquese8c11bb2009-10-08 15:06:32 -03002339
2340 if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
2341 vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
2342 source_str, ss->sock_fd, VTY_NEWLINE);
2343 }
2344
2345 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
Everton Marques824adbe2009-10-08 09:16:27 -03002346 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
2347
Everton Marquese8c11bb2009-10-08 15:06:32 -03002348 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
Everton Marques824adbe2009-10-08 09:16:27 -03002349 source_str,
2350 ss->sock_fd,
Everton Marquese8c11bb2009-10-08 15:06:32 -03002351 bind_addr_str,
2352 ntohs(bind_addr.sin_port),
Everton Marques824adbe2009-10-08 09:16:27 -03002353 ss_uptime,
David Lamparter5c697982012-02-16 04:47:56 +01002354 (long long)ss->requests,
Everton Marques824adbe2009-10-08 09:16:27 -03002355 VTY_NEWLINE);
2356 }
2357}
2358
2359DEFUN (show_ip_ssmpingd,
2360 show_ip_ssmpingd_cmd,
2361 "show ip ssmpingd",
2362 SHOW_STR
2363 IP_STR
2364 SHOW_SSMPINGD_STR)
2365{
2366 show_ssmpingd(vty);
2367 return CMD_SUCCESS;
2368}
2369
Everton Marques871dbcf2009-08-11 15:43:05 -03002370DEFUN (ip_multicast_routing,
2371 ip_multicast_routing_cmd,
2372 PIM_CMD_IP_MULTICAST_ROUTING,
2373 IP_STR
2374 "Enable IP multicast forwarding\n")
2375{
2376 pim_mroute_socket_enable();
2377 pim_if_add_vif_all();
2378 mroute_add_all();
2379 return CMD_SUCCESS;
2380}
2381
2382DEFUN (no_ip_multicast_routing,
2383 no_ip_multicast_routing_cmd,
2384 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
2385 NO_STR
2386 IP_STR
2387 "Global IP configuration subcommands\n"
2388 "Enable IP multicast forwarding\n")
2389{
2390 mroute_del_all();
2391 pim_if_del_vif_all();
2392 pim_mroute_socket_disable();
2393 return CMD_SUCCESS;
2394}
2395
Everton Marques96f91ae2009-10-07 18:41:45 -03002396DEFUN (ip_ssmpingd,
2397 ip_ssmpingd_cmd,
2398 "ip ssmpingd [A.B.C.D]",
2399 IP_STR
Everton Marques824adbe2009-10-08 09:16:27 -03002400 CONF_SSMPINGD_STR
Everton Marques96f91ae2009-10-07 18:41:45 -03002401 "Source address\n")
2402{
2403 int result;
2404 struct in_addr source_addr;
2405 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2406
2407 result = inet_pton(AF_INET, source_str, &source_addr);
2408 if (result <= 0) {
2409 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2410 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2411 return CMD_WARNING;
2412 }
2413
2414 result = pim_ssmpingd_start(source_addr);
2415 if (result) {
2416 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
2417 source_str, result, VTY_NEWLINE);
2418 return CMD_WARNING;
2419 }
2420
2421 return CMD_SUCCESS;
2422}
2423
2424DEFUN (no_ip_ssmpingd,
2425 no_ip_ssmpingd_cmd,
2426 "no ip ssmpingd [A.B.C.D]",
2427 NO_STR
2428 IP_STR
Everton Marques824adbe2009-10-08 09:16:27 -03002429 CONF_SSMPINGD_STR
Everton Marques96f91ae2009-10-07 18:41:45 -03002430 "Source address\n")
2431{
2432 int result;
2433 struct in_addr source_addr;
2434 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2435
2436 result = inet_pton(AF_INET, source_str, &source_addr);
2437 if (result <= 0) {
2438 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2439 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2440 return CMD_WARNING;
2441 }
2442
2443 result = pim_ssmpingd_stop(source_addr);
2444 if (result) {
2445 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
2446 source_str, result, VTY_NEWLINE);
2447 return CMD_WARNING;
2448 }
2449
2450 return CMD_SUCCESS;
2451}
2452
Everton Marques871dbcf2009-08-11 15:43:05 -03002453DEFUN (interface_ip_igmp,
2454 interface_ip_igmp_cmd,
2455 "ip igmp",
2456 IP_STR
2457 IFACE_IGMP_STR)
2458{
2459 struct interface *ifp;
2460 struct pim_interface *pim_ifp;
2461
2462 ifp = vty->index;
2463 pim_ifp = ifp->info;
2464
2465 if (!pim_ifp) {
2466 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2467 if (!pim_ifp) {
2468 vty_out(vty, "Could not enable IGMP on interface %s%s",
2469 ifp->name, VTY_NEWLINE);
2470 return CMD_WARNING;
2471 }
2472 }
2473 else {
2474 PIM_IF_DO_IGMP(pim_ifp->options);
2475 }
2476
2477 pim_if_addr_add_all(ifp);
2478 pim_if_membership_refresh(ifp);
2479
2480 return CMD_SUCCESS;
2481}
2482
2483DEFUN (interface_no_ip_igmp,
2484 interface_no_ip_igmp_cmd,
2485 "no ip igmp",
2486 NO_STR
2487 IP_STR
2488 IFACE_IGMP_STR)
2489{
2490 struct interface *ifp;
2491 struct pim_interface *pim_ifp;
2492
2493 ifp = vty->index;
2494 pim_ifp = ifp->info;
2495 if (!pim_ifp)
2496 return CMD_SUCCESS;
2497
2498 PIM_IF_DONT_IGMP(pim_ifp->options);
2499
2500 pim_if_membership_clear(ifp);
2501
Everton Marques275e24d2014-08-22 11:12:23 -03002502 pim_if_addr_del_all_igmp(ifp);
Everton Marques871dbcf2009-08-11 15:43:05 -03002503
2504 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2505 pim_if_delete(ifp);
2506 }
2507
2508 return CMD_SUCCESS;
2509}
2510
2511DEFUN (interface_ip_igmp_join,
2512 interface_ip_igmp_join_cmd,
2513 "ip igmp join A.B.C.D A.B.C.D",
2514 IP_STR
2515 IFACE_IGMP_STR
2516 "IGMP join multicast group\n"
2517 "Multicast group address\n"
2518 "Source address\n")
2519{
2520 struct interface *ifp;
2521 const char *group_str;
2522 const char *source_str;
2523 struct in_addr group_addr;
2524 struct in_addr source_addr;
2525 int result;
2526
2527 ifp = vty->index;
2528
2529 /* Group address */
2530 group_str = argv[0];
2531 result = inet_pton(AF_INET, group_str, &group_addr);
2532 if (result <= 0) {
2533 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002534 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002535 return CMD_WARNING;
2536 }
2537
2538 /* Source address */
2539 source_str = argv[1];
2540 result = inet_pton(AF_INET, source_str, &source_addr);
2541 if (result <= 0) {
2542 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002543 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002544 return CMD_WARNING;
2545 }
2546
2547 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2548 if (result) {
2549 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2550 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2551 return CMD_WARNING;
2552 }
2553
2554 return CMD_SUCCESS;
2555}
2556
2557DEFUN (interface_no_ip_igmp_join,
2558 interface_no_ip_igmp_join_cmd,
2559 "no ip igmp join A.B.C.D A.B.C.D",
2560 NO_STR
2561 IP_STR
2562 IFACE_IGMP_STR
2563 "IGMP join multicast group\n"
2564 "Multicast group address\n"
2565 "Source address\n")
2566{
2567 struct interface *ifp;
2568 const char *group_str;
2569 const char *source_str;
2570 struct in_addr group_addr;
2571 struct in_addr source_addr;
2572 int result;
2573
2574 ifp = vty->index;
2575
2576 /* Group address */
2577 group_str = argv[0];
2578 result = inet_pton(AF_INET, group_str, &group_addr);
2579 if (result <= 0) {
2580 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002581 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002582 return CMD_WARNING;
2583 }
2584
2585 /* Source address */
2586 source_str = argv[1];
2587 result = inet_pton(AF_INET, source_str, &source_addr);
2588 if (result <= 0) {
2589 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03002590 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03002591 return CMD_WARNING;
2592 }
2593
2594 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2595 if (result) {
2596 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2597 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2598 return CMD_WARNING;
2599 }
2600
2601 return CMD_SUCCESS;
2602}
2603
2604/*
2605 CLI reconfiguration affects the interface level (struct pim_interface).
2606 This function propagates the reconfiguration to every active socket
2607 for that interface.
2608 */
2609static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2610{
2611 struct interface *ifp;
2612 struct pim_interface *pim_ifp;
2613
2614 zassert(igmp);
2615
2616 /* other querier present? */
2617
2618 if (igmp->t_other_querier_timer)
2619 return;
2620
2621 /* this is the querier */
2622
2623 zassert(igmp->interface);
2624 zassert(igmp->interface->info);
2625
2626 ifp = igmp->interface;
2627 pim_ifp = ifp->info;
2628
2629 if (PIM_DEBUG_IGMP_TRACE) {
2630 char ifaddr_str[100];
2631 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2632 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2633 __PRETTY_FUNCTION__,
2634 ifaddr_str,
2635 ifp->name,
2636 pim_ifp->igmp_default_query_interval);
2637 }
2638
2639 /*
2640 igmp_startup_mode_on() will reset QQI:
2641
2642 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2643 */
2644 igmp_startup_mode_on(igmp);
2645}
2646
2647static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2648{
2649 if (igmp->t_igmp_query_timer) {
2650 /* other querier present */
2651 zassert(igmp->t_igmp_query_timer);
2652 zassert(!igmp->t_other_querier_timer);
2653
2654 pim_igmp_general_query_off(igmp);
2655 pim_igmp_general_query_on(igmp);
2656
2657 zassert(igmp->t_igmp_query_timer);
2658 zassert(!igmp->t_other_querier_timer);
2659 }
2660 else {
2661 /* this is the querier */
2662
2663 zassert(!igmp->t_igmp_query_timer);
2664 zassert(igmp->t_other_querier_timer);
2665
2666 pim_igmp_other_querier_timer_off(igmp);
2667 pim_igmp_other_querier_timer_on(igmp);
2668
2669 zassert(!igmp->t_igmp_query_timer);
2670 zassert(igmp->t_other_querier_timer);
2671 }
2672}
2673
2674static void change_query_interval(struct pim_interface *pim_ifp,
2675 int query_interval)
2676{
2677 struct listnode *sock_node;
2678 struct igmp_sock *igmp;
2679
2680 pim_ifp->igmp_default_query_interval = query_interval;
2681
2682 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2683 igmp_sock_query_interval_reconfig(igmp);
2684 igmp_sock_query_reschedule(igmp);
2685 }
2686}
2687
2688static void change_query_max_response_time(struct pim_interface *pim_ifp,
2689 int query_max_response_time_dsec)
2690{
2691 struct listnode *sock_node;
2692 struct igmp_sock *igmp;
2693
2694 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2695
2696 /*
2697 Below we modify socket/group/source timers in order to quickly
2698 reflect the change. Otherwise, those timers would eventually catch
2699 up.
2700 */
2701
2702 /* scan all sockets */
2703 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2704 struct listnode *grp_node;
2705 struct igmp_group *grp;
2706
2707 /* reschedule socket general query */
2708 igmp_sock_query_reschedule(igmp);
2709
2710 /* scan socket groups */
2711 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2712 struct listnode *src_node;
2713 struct igmp_source *src;
2714
2715 /* reset group timers for groups in EXCLUDE mode */
2716 if (grp->group_filtermode_isexcl) {
2717 igmp_group_reset_gmi(grp);
2718 }
2719
2720 /* scan group sources */
2721 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2722
2723 /* reset source timers for sources with running timers */
2724 if (src->t_source_timer) {
2725 igmp_source_reset_gmi(igmp, grp, src);
2726 }
2727 }
2728 }
2729 }
2730}
2731
2732#define IGMP_QUERY_INTERVAL_MIN (1)
2733#define IGMP_QUERY_INTERVAL_MAX (1800)
2734
2735DEFUN (interface_ip_igmp_query_interval,
2736 interface_ip_igmp_query_interval_cmd,
2737 PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
2738 IP_STR
2739 IFACE_IGMP_STR
2740 IFACE_IGMP_QUERY_INTERVAL_STR
2741 "Query interval in seconds\n")
2742{
2743 struct interface *ifp;
2744 struct pim_interface *pim_ifp;
2745 int query_interval;
2746 int query_interval_dsec;
2747
2748 ifp = vty->index;
2749 pim_ifp = ifp->info;
2750
2751 if (!pim_ifp) {
2752 vty_out(vty,
2753 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2754 ifp->name,
2755 VTY_NEWLINE);
2756 return CMD_WARNING;
2757 }
2758
2759 query_interval = atoi(argv[0]);
2760 query_interval_dsec = 10 * query_interval;
2761
2762 /*
2763 It seems we don't need to check bounds since command.c does it
2764 already, but we verify them anyway for extra safety.
2765 */
2766 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
2767 vty_out(vty, "General query interval %d lower than minimum %d%s",
2768 query_interval,
2769 IGMP_QUERY_INTERVAL_MIN,
2770 VTY_NEWLINE);
2771 return CMD_WARNING;
2772 }
2773 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
2774 vty_out(vty, "General query interval %d higher than maximum %d%s",
2775 query_interval,
2776 IGMP_QUERY_INTERVAL_MAX,
2777 VTY_NEWLINE);
2778 return CMD_WARNING;
2779 }
2780
2781 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2782 vty_out(vty,
2783 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
2784 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2785 VTY_NEWLINE);
2786 return CMD_WARNING;
2787 }
2788
2789 change_query_interval(pim_ifp, query_interval);
2790
2791 return CMD_SUCCESS;
2792}
2793
2794DEFUN (interface_no_ip_igmp_query_interval,
2795 interface_no_ip_igmp_query_interval_cmd,
2796 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
2797 NO_STR
2798 IP_STR
2799 IFACE_IGMP_STR
2800 IFACE_IGMP_QUERY_INTERVAL_STR)
2801{
2802 struct interface *ifp;
2803 struct pim_interface *pim_ifp;
2804 int default_query_interval_dsec;
2805
2806 ifp = vty->index;
2807 pim_ifp = ifp->info;
2808
2809 if (!pim_ifp)
2810 return CMD_SUCCESS;
2811
2812 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
2813
2814 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2815 vty_out(vty,
2816 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
2817 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2818 VTY_NEWLINE);
2819 return CMD_WARNING;
2820 }
2821
2822 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
2823
2824 return CMD_SUCCESS;
2825}
2826
2827#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
2828#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
2829
2830DEFUN (interface_ip_igmp_query_max_response_time,
2831 interface_ip_igmp_query_max_response_time_cmd,
2832 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
2833 IP_STR
2834 IFACE_IGMP_STR
2835 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
2836 "Query response value in seconds\n")
2837{
2838 struct interface *ifp;
2839 struct pim_interface *pim_ifp;
2840 int query_max_response_time;
2841
2842 ifp = vty->index;
2843 pim_ifp = ifp->info;
2844
2845 if (!pim_ifp) {
2846 vty_out(vty,
2847 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2848 ifp->name,
2849 VTY_NEWLINE);
2850 return CMD_WARNING;
2851 }
2852
2853 query_max_response_time = atoi(argv[0]);
2854
2855 /*
2856 It seems we don't need to check bounds since command.c does it
2857 already, but we verify them anyway for extra safety.
2858 */
2859 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
2860 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
2861 query_max_response_time,
2862 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
2863 VTY_NEWLINE);
2864 return CMD_WARNING;
2865 }
2866 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
2867 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
2868 query_max_response_time,
2869 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
2870 VTY_NEWLINE);
2871 return CMD_WARNING;
2872 }
2873
2874 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
2875 vty_out(vty,
2876 "Can't set query max response time %d sec >= general query interval %d sec%s",
2877 query_max_response_time, pim_ifp->igmp_default_query_interval,
2878 VTY_NEWLINE);
2879 return CMD_WARNING;
2880 }
2881
2882 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
2883
2884 return CMD_SUCCESS;
2885}
2886
2887DEFUN (interface_no_ip_igmp_query_max_response_time,
2888 interface_no_ip_igmp_query_max_response_time_cmd,
2889 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
2890 NO_STR
2891 IP_STR
2892 IFACE_IGMP_STR
2893 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
2894{
2895 struct interface *ifp;
2896 struct pim_interface *pim_ifp;
2897 int default_query_interval_dsec;
2898
2899 ifp = vty->index;
2900 pim_ifp = ifp->info;
2901
2902 if (!pim_ifp)
2903 return CMD_SUCCESS;
2904
2905 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2906
2907 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
2908 vty_out(vty,
2909 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
2910 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
2911 VTY_NEWLINE);
2912 return CMD_WARNING;
2913 }
2914
2915 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
2916
2917 return CMD_SUCCESS;
2918}
2919
2920#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
2921#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
2922
2923DEFUN (interface_ip_igmp_query_max_response_time_dsec,
2924 interface_ip_igmp_query_max_response_time_dsec_cmd,
2925 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
2926 IP_STR
2927 IFACE_IGMP_STR
2928 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
2929 "Query response value in deciseconds\n")
2930{
2931 struct interface *ifp;
2932 struct pim_interface *pim_ifp;
2933 int query_max_response_time_dsec;
2934 int default_query_interval_dsec;
2935
2936 ifp = vty->index;
2937 pim_ifp = ifp->info;
2938
2939 if (!pim_ifp) {
2940 vty_out(vty,
2941 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2942 ifp->name,
2943 VTY_NEWLINE);
2944 return CMD_WARNING;
2945 }
2946
2947 query_max_response_time_dsec = atoi(argv[0]);
2948
2949 /*
2950 It seems we don't need to check bounds since command.c does it
2951 already, but we verify them anyway for extra safety.
2952 */
2953 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
2954 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
2955 query_max_response_time_dsec,
2956 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
2957 VTY_NEWLINE);
2958 return CMD_WARNING;
2959 }
2960 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
2961 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
2962 query_max_response_time_dsec,
2963 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
2964 VTY_NEWLINE);
2965 return CMD_WARNING;
2966 }
2967
2968 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
2969
2970 if (query_max_response_time_dsec >= default_query_interval_dsec) {
2971 vty_out(vty,
2972 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
2973 query_max_response_time_dsec, default_query_interval_dsec,
2974 VTY_NEWLINE);
2975 return CMD_WARNING;
2976 }
2977
2978 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
2979
2980 return CMD_SUCCESS;
2981}
2982
2983DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
2984 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
2985 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
2986 NO_STR
2987 IP_STR
2988 IFACE_IGMP_STR
2989 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
2990{
2991 struct interface *ifp;
2992 struct pim_interface *pim_ifp;
2993 int default_query_interval_dsec;
2994
2995 ifp = vty->index;
2996 pim_ifp = ifp->info;
2997
2998 if (!pim_ifp)
2999 return CMD_SUCCESS;
3000
3001 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3002
3003 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3004 vty_out(vty,
3005 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3006 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3007 VTY_NEWLINE);
3008 return CMD_WARNING;
3009 }
3010
3011 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3012
3013 return CMD_SUCCESS;
3014}
3015
3016DEFUN (interface_ip_pim_ssm,
3017 interface_ip_pim_ssm_cmd,
3018 "ip pim ssm",
3019 IP_STR
3020 PIM_STR
3021 IFACE_PIM_STR)
3022{
3023 struct interface *ifp;
3024 struct pim_interface *pim_ifp;
3025
3026 ifp = vty->index;
3027 pim_ifp = ifp->info;
3028
3029 if (!pim_ifp) {
3030 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
3031 if (!pim_ifp) {
3032 vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
3033 return CMD_WARNING;
3034 }
3035 }
3036 else {
3037 PIM_IF_DO_PIM(pim_ifp->options);
3038 }
3039
3040 pim_if_addr_add_all(ifp);
3041 pim_if_membership_refresh(ifp);
3042
3043 return CMD_SUCCESS;
3044}
3045
3046DEFUN (interface_no_ip_pim_ssm,
3047 interface_no_ip_pim_ssm_cmd,
3048 "no ip pim ssm",
3049 NO_STR
3050 IP_STR
3051 PIM_STR
3052 IFACE_PIM_STR)
3053{
3054 struct interface *ifp;
3055 struct pim_interface *pim_ifp;
3056
3057 ifp = vty->index;
3058 pim_ifp = ifp->info;
3059 if (!pim_ifp)
3060 return CMD_SUCCESS;
3061
3062 PIM_IF_DONT_PIM(pim_ifp->options);
3063
3064 pim_if_membership_clear(ifp);
3065
3066 /*
3067 pim_if_addr_del_all() removes all sockets from
3068 pim_ifp->igmp_socket_list.
3069 */
3070 pim_if_addr_del_all(ifp);
3071
3072 /*
3073 pim_sock_delete() removes all neighbors from
3074 pim_ifp->pim_neighbor_list.
3075 */
3076 pim_sock_delete(ifp, "pim unconfigured on interface");
3077
3078 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
3079 pim_if_delete(ifp);
3080 }
3081
3082 return CMD_SUCCESS;
3083}
3084
3085DEFUN (debug_igmp,
3086 debug_igmp_cmd,
3087 "debug igmp",
3088 DEBUG_STR
3089 DEBUG_IGMP_STR)
3090{
3091 PIM_DO_DEBUG_IGMP_EVENTS;
3092 PIM_DO_DEBUG_IGMP_PACKETS;
3093 PIM_DO_DEBUG_IGMP_TRACE;
3094 return CMD_SUCCESS;
3095}
3096
3097DEFUN (no_debug_igmp,
3098 no_debug_igmp_cmd,
3099 "no debug igmp",
3100 NO_STR
3101 DEBUG_STR
3102 DEBUG_IGMP_STR)
3103{
3104 PIM_DONT_DEBUG_IGMP_EVENTS;
3105 PIM_DONT_DEBUG_IGMP_PACKETS;
3106 PIM_DONT_DEBUG_IGMP_TRACE;
3107 return CMD_SUCCESS;
3108}
3109
3110ALIAS (no_debug_igmp,
3111 undebug_igmp_cmd,
3112 "undebug igmp",
3113 UNDEBUG_STR
3114 DEBUG_IGMP_STR)
3115
3116DEFUN (debug_igmp_events,
3117 debug_igmp_events_cmd,
3118 "debug igmp events",
3119 DEBUG_STR
3120 DEBUG_IGMP_STR
3121 DEBUG_IGMP_EVENTS_STR)
3122{
3123 PIM_DO_DEBUG_IGMP_EVENTS;
3124 return CMD_SUCCESS;
3125}
3126
3127DEFUN (no_debug_igmp_events,
3128 no_debug_igmp_events_cmd,
3129 "no debug igmp events",
3130 NO_STR
3131 DEBUG_STR
3132 DEBUG_IGMP_STR
3133 DEBUG_IGMP_EVENTS_STR)
3134{
3135 PIM_DONT_DEBUG_IGMP_EVENTS;
3136 return CMD_SUCCESS;
3137}
3138
3139ALIAS (no_debug_igmp_events,
3140 undebug_igmp_events_cmd,
3141 "undebug igmp events",
3142 UNDEBUG_STR
3143 DEBUG_IGMP_STR
3144 DEBUG_IGMP_EVENTS_STR)
3145
3146DEFUN (debug_igmp_packets,
3147 debug_igmp_packets_cmd,
3148 "debug igmp packets",
3149 DEBUG_STR
3150 DEBUG_IGMP_STR
3151 DEBUG_IGMP_PACKETS_STR)
3152{
3153 PIM_DO_DEBUG_IGMP_PACKETS;
3154 return CMD_SUCCESS;
3155}
3156
3157DEFUN (no_debug_igmp_packets,
3158 no_debug_igmp_packets_cmd,
3159 "no debug igmp packets",
3160 NO_STR
3161 DEBUG_STR
3162 DEBUG_IGMP_STR
3163 DEBUG_IGMP_PACKETS_STR)
3164{
3165 PIM_DONT_DEBUG_IGMP_PACKETS;
3166 return CMD_SUCCESS;
3167}
3168
3169ALIAS (no_debug_igmp_packets,
3170 undebug_igmp_packets_cmd,
3171 "undebug igmp packets",
3172 UNDEBUG_STR
3173 DEBUG_IGMP_STR
3174 DEBUG_IGMP_PACKETS_STR)
3175
3176DEFUN (debug_igmp_trace,
3177 debug_igmp_trace_cmd,
3178 "debug igmp trace",
3179 DEBUG_STR
3180 DEBUG_IGMP_STR
3181 DEBUG_IGMP_TRACE_STR)
3182{
3183 PIM_DO_DEBUG_IGMP_TRACE;
3184 return CMD_SUCCESS;
3185}
3186
3187DEFUN (no_debug_igmp_trace,
3188 no_debug_igmp_trace_cmd,
3189 "no debug igmp trace",
3190 NO_STR
3191 DEBUG_STR
3192 DEBUG_IGMP_STR
3193 DEBUG_IGMP_TRACE_STR)
3194{
3195 PIM_DONT_DEBUG_IGMP_TRACE;
3196 return CMD_SUCCESS;
3197}
3198
3199ALIAS (no_debug_igmp_trace,
3200 undebug_igmp_trace_cmd,
3201 "undebug igmp trace",
3202 UNDEBUG_STR
3203 DEBUG_IGMP_STR
3204 DEBUG_IGMP_TRACE_STR)
3205
Everton Marques67faabc2010-02-23 12:11:11 -03003206DEFUN (debug_mroute,
3207 debug_mroute_cmd,
3208 "debug mroute",
3209 DEBUG_STR
3210 DEBUG_MROUTE_STR)
3211{
3212 PIM_DO_DEBUG_MROUTE;
3213 return CMD_SUCCESS;
3214}
3215
3216DEFUN (no_debug_mroute,
3217 no_debug_mroute_cmd,
3218 "no debug mroute",
3219 NO_STR
3220 DEBUG_STR
3221 DEBUG_MROUTE_STR)
3222{
3223 PIM_DONT_DEBUG_MROUTE;
3224 return CMD_SUCCESS;
3225}
3226
3227ALIAS (no_debug_mroute,
3228 undebug_mroute_cmd,
3229 "undebug mroute",
3230 UNDEBUG_STR
3231 DEBUG_MROUTE_STR)
3232
Everton Marques871dbcf2009-08-11 15:43:05 -03003233DEFUN (debug_pim,
3234 debug_pim_cmd,
3235 "debug pim",
3236 DEBUG_STR
3237 DEBUG_PIM_STR)
3238{
3239 PIM_DO_DEBUG_PIM_EVENTS;
3240 PIM_DO_DEBUG_PIM_PACKETS;
3241 PIM_DO_DEBUG_PIM_TRACE;
3242 return CMD_SUCCESS;
3243}
3244
3245DEFUN (no_debug_pim,
3246 no_debug_pim_cmd,
3247 "no debug pim",
3248 NO_STR
3249 DEBUG_STR
3250 DEBUG_PIM_STR)
3251{
3252 PIM_DONT_DEBUG_PIM_EVENTS;
3253 PIM_DONT_DEBUG_PIM_PACKETS;
3254 PIM_DONT_DEBUG_PIM_TRACE;
Everton Marques62738042009-11-18 10:44:13 -02003255
3256 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3257 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3258
Everton Marques871dbcf2009-08-11 15:43:05 -03003259 return CMD_SUCCESS;
3260}
3261
3262ALIAS (no_debug_pim,
3263 undebug_pim_cmd,
3264 "undebug pim",
3265 UNDEBUG_STR
3266 DEBUG_PIM_STR)
3267
3268DEFUN (debug_pim_events,
3269 debug_pim_events_cmd,
3270 "debug pim events",
3271 DEBUG_STR
3272 DEBUG_PIM_STR
3273 DEBUG_PIM_EVENTS_STR)
3274{
3275 PIM_DO_DEBUG_PIM_EVENTS;
3276 return CMD_SUCCESS;
3277}
3278
3279DEFUN (no_debug_pim_events,
3280 no_debug_pim_events_cmd,
3281 "no debug pim events",
3282 NO_STR
3283 DEBUG_STR
3284 DEBUG_PIM_STR
3285 DEBUG_PIM_EVENTS_STR)
3286{
3287 PIM_DONT_DEBUG_PIM_EVENTS;
3288 return CMD_SUCCESS;
3289}
3290
3291ALIAS (no_debug_pim_events,
3292 undebug_pim_events_cmd,
3293 "undebug pim events",
3294 UNDEBUG_STR
3295 DEBUG_PIM_STR
3296 DEBUG_PIM_EVENTS_STR)
3297
3298DEFUN (debug_pim_packets,
3299 debug_pim_packets_cmd,
3300 "debug pim packets",
3301 DEBUG_STR
3302 DEBUG_PIM_STR
3303 DEBUG_PIM_PACKETS_STR)
3304{
Balaji.Ged14fa02014-10-08 01:11:31 -03003305 PIM_DO_DEBUG_PIM_PACKETS;
3306 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
3307 return CMD_SUCCESS;
3308}
3309
3310DEFUN (debug_pim_packets_filter,
3311 debug_pim_packets_filter_cmd,
3312 "debug pim packets (hello|joins)",
3313 DEBUG_STR
3314 DEBUG_PIM_STR
3315 DEBUG_PIM_PACKETS_STR
3316 DEBUG_PIM_HELLO_PACKETS_STR
3317 DEBUG_PIM_J_P_PACKETS_STR)
3318{
3319 if (strncmp(argv[0],"h",1) == 0)
3320 {
3321 PIM_DO_DEBUG_PIM_HELLO;
3322 vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
3323 }
3324 else if (strncmp(argv[0],"j",1) == 0)
3325 {
3326 PIM_DO_DEBUG_PIM_J_P;
3327 vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
3328 }
Everton Marques871dbcf2009-08-11 15:43:05 -03003329 return CMD_SUCCESS;
3330}
3331
3332DEFUN (no_debug_pim_packets,
3333 no_debug_pim_packets_cmd,
3334 "no debug pim packets",
3335 NO_STR
3336 DEBUG_STR
3337 DEBUG_PIM_STR
Balaji.Ged14fa02014-10-08 01:11:31 -03003338 DEBUG_PIM_PACKETS_STR
3339 DEBUG_PIM_HELLO_PACKETS_STR
3340 DEBUG_PIM_J_P_PACKETS_STR)
Everton Marques871dbcf2009-08-11 15:43:05 -03003341{
3342 PIM_DONT_DEBUG_PIM_PACKETS;
Balaji.Ged14fa02014-10-08 01:11:31 -03003343 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003344 return CMD_SUCCESS;
3345}
3346
Balaji.Ged14fa02014-10-08 01:11:31 -03003347DEFUN (no_debug_pim_packets_filter,
3348 no_debug_pim_packets_filter_cmd,
3349 "no debug pim packets (hello|joins)",
3350 NO_STR
3351 DEBUG_STR
3352 DEBUG_PIM_STR
3353 DEBUG_PIM_PACKETS_STR
3354 DEBUG_PIM_HELLO_PACKETS_STR
3355 DEBUG_PIM_J_P_PACKETS_STR)
3356{
3357 if (strncmp(argv[0],"h",1) == 0)
3358 {
3359 PIM_DONT_DEBUG_PIM_HELLO;
3360 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
3361 }
3362 else if (strncmp(argv[0],"j",1) == 0)
3363 {
3364 PIM_DONT_DEBUG_PIM_J_P;
3365 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
3366 }
3367 return CMD_SUCCESS;
3368}
3369
Everton Marques871dbcf2009-08-11 15:43:05 -03003370ALIAS (no_debug_pim_packets,
3371 undebug_pim_packets_cmd,
3372 "undebug pim packets",
3373 UNDEBUG_STR
3374 DEBUG_PIM_STR
3375 DEBUG_PIM_PACKETS_STR)
3376
Everton Marques62738042009-11-18 10:44:13 -02003377DEFUN (debug_pim_packetdump_send,
3378 debug_pim_packetdump_send_cmd,
3379 "debug pim packet-dump send",
3380 DEBUG_STR
3381 DEBUG_PIM_STR
3382 DEBUG_PIM_PACKETDUMP_STR
3383 DEBUG_PIM_PACKETDUMP_SEND_STR)
3384{
3385 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
3386 return CMD_SUCCESS;
3387}
3388
3389DEFUN (no_debug_pim_packetdump_send,
3390 no_debug_pim_packetdump_send_cmd,
3391 "no debug pim packet-dump send",
3392 NO_STR
3393 DEBUG_STR
3394 DEBUG_PIM_STR
3395 DEBUG_PIM_PACKETDUMP_STR
3396 DEBUG_PIM_PACKETDUMP_SEND_STR)
3397{
3398 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3399 return CMD_SUCCESS;
3400}
3401
3402ALIAS (no_debug_pim_packetdump_send,
3403 undebug_pim_packetdump_send_cmd,
3404 "undebug pim packet-dump send",
3405 UNDEBUG_STR
3406 DEBUG_PIM_STR
3407 DEBUG_PIM_PACKETDUMP_STR
3408 DEBUG_PIM_PACKETDUMP_SEND_STR)
3409
3410DEFUN (debug_pim_packetdump_recv,
3411 debug_pim_packetdump_recv_cmd,
3412 "debug pim packet-dump receive",
3413 DEBUG_STR
3414 DEBUG_PIM_STR
3415 DEBUG_PIM_PACKETDUMP_STR
3416 DEBUG_PIM_PACKETDUMP_RECV_STR)
3417{
3418 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
3419 return CMD_SUCCESS;
3420}
3421
3422DEFUN (no_debug_pim_packetdump_recv,
3423 no_debug_pim_packetdump_recv_cmd,
3424 "no debug pim packet-dump receive",
3425 NO_STR
3426 DEBUG_STR
3427 DEBUG_PIM_STR
3428 DEBUG_PIM_PACKETDUMP_STR
3429 DEBUG_PIM_PACKETDUMP_RECV_STR)
3430{
3431 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3432 return CMD_SUCCESS;
3433}
3434
3435ALIAS (no_debug_pim_packetdump_recv,
3436 undebug_pim_packetdump_recv_cmd,
3437 "undebug pim packet-dump receive",
3438 UNDEBUG_STR
3439 DEBUG_PIM_STR
3440 DEBUG_PIM_PACKETDUMP_STR
3441 DEBUG_PIM_PACKETDUMP_RECV_STR)
3442
Everton Marques871dbcf2009-08-11 15:43:05 -03003443DEFUN (debug_pim_trace,
3444 debug_pim_trace_cmd,
3445 "debug pim trace",
3446 DEBUG_STR
3447 DEBUG_PIM_STR
3448 DEBUG_PIM_TRACE_STR)
3449{
3450 PIM_DO_DEBUG_PIM_TRACE;
3451 return CMD_SUCCESS;
3452}
3453
3454DEFUN (no_debug_pim_trace,
3455 no_debug_pim_trace_cmd,
3456 "no debug pim trace",
3457 NO_STR
3458 DEBUG_STR
3459 DEBUG_PIM_STR
3460 DEBUG_PIM_TRACE_STR)
3461{
3462 PIM_DONT_DEBUG_PIM_TRACE;
3463 return CMD_SUCCESS;
3464}
3465
3466ALIAS (no_debug_pim_trace,
3467 undebug_pim_trace_cmd,
3468 "undebug pim trace",
3469 UNDEBUG_STR
3470 DEBUG_PIM_STR
3471 DEBUG_PIM_TRACE_STR)
3472
Everton Marques824adbe2009-10-08 09:16:27 -03003473DEFUN (debug_ssmpingd,
3474 debug_ssmpingd_cmd,
3475 "debug ssmpingd",
3476 DEBUG_STR
3477 DEBUG_PIM_STR
3478 DEBUG_SSMPINGD_STR)
3479{
3480 PIM_DO_DEBUG_SSMPINGD;
3481 return CMD_SUCCESS;
3482}
3483
3484DEFUN (no_debug_ssmpingd,
3485 no_debug_ssmpingd_cmd,
3486 "no debug ssmpingd",
3487 NO_STR
3488 DEBUG_STR
3489 DEBUG_PIM_STR
3490 DEBUG_SSMPINGD_STR)
3491{
3492 PIM_DONT_DEBUG_SSMPINGD;
3493 return CMD_SUCCESS;
3494}
3495
3496ALIAS (no_debug_ssmpingd,
3497 undebug_ssmpingd_cmd,
3498 "undebug ssmpingd",
3499 UNDEBUG_STR
3500 DEBUG_PIM_STR
3501 DEBUG_SSMPINGD_STR)
3502
Everton Marques871dbcf2009-08-11 15:43:05 -03003503DEFUN (debug_pim_zebra,
3504 debug_pim_zebra_cmd,
3505 "debug pim zebra",
3506 DEBUG_STR
3507 DEBUG_PIM_STR
3508 DEBUG_PIM_ZEBRA_STR)
3509{
3510 PIM_DO_DEBUG_ZEBRA;
3511 return CMD_SUCCESS;
3512}
3513
3514DEFUN (no_debug_pim_zebra,
3515 no_debug_pim_zebra_cmd,
3516 "no debug pim zebra",
3517 NO_STR
3518 DEBUG_STR
3519 DEBUG_PIM_STR
3520 DEBUG_PIM_ZEBRA_STR)
3521{
3522 PIM_DONT_DEBUG_ZEBRA;
3523 return CMD_SUCCESS;
3524}
3525
3526ALIAS (no_debug_pim_zebra,
3527 undebug_pim_zebra_cmd,
3528 "undebug pim zebra",
3529 UNDEBUG_STR
3530 DEBUG_PIM_STR
3531 DEBUG_PIM_ZEBRA_STR)
3532
3533DEFUN (show_debugging,
3534 show_debugging_cmd,
3535 "show debugging",
3536 SHOW_STR
3537 "State of each debugging option\n")
3538{
3539 pim_debug_config_write(vty);
3540 return CMD_SUCCESS;
3541}
3542
3543static struct igmp_sock *find_igmp_sock_by_fd(int fd)
3544{
3545 struct listnode *ifnode;
3546 struct interface *ifp;
3547
3548 /* scan all interfaces */
3549 for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
3550 struct pim_interface *pim_ifp;
3551 struct igmp_sock *igmp;
3552
3553 if (!ifp->info)
3554 continue;
3555
3556 pim_ifp = ifp->info;
3557
3558 /* lookup igmp socket under current interface */
3559 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
3560 if (igmp)
3561 return igmp;
3562 }
3563
3564 return 0;
3565}
3566
3567DEFUN (test_igmp_receive_report,
3568 test_igmp_receive_report_cmd,
3569 "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
3570 "Test\n"
3571 "Test IGMP protocol\n"
3572 "Test IGMP message\n"
3573 "Test IGMP report\n"
3574 "Socket\n"
3575 "IGMP group address\n"
3576 "Record type\n"
3577 "Sources\n")
3578{
3579 char buf[1000];
3580 char *igmp_msg;
3581 struct ip *ip_hdr;
3582 size_t ip_hlen; /* ip header length in bytes */
3583 int ip_msg_len;
3584 int igmp_msg_len;
3585 const char *socket;
3586 int socket_fd;
3587 const char *grp_str;
3588 struct in_addr grp_addr;
3589 const char *record_type_str;
3590 int record_type;
3591 const char *src_str;
3592 int result;
3593 struct igmp_sock *igmp;
3594 char *group_record;
3595 int num_sources;
3596 struct in_addr *sources;
3597 struct in_addr *src_addr;
3598 int argi;
3599
3600 socket = argv[0];
3601 socket_fd = atoi(socket);
3602 igmp = find_igmp_sock_by_fd(socket_fd);
3603 if (!igmp) {
3604 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
3605 socket, socket_fd, VTY_NEWLINE);
3606 return CMD_WARNING;
3607 }
3608
3609 grp_str = argv[1];
3610 result = inet_pton(AF_INET, grp_str, &grp_addr);
3611 if (result <= 0) {
3612 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003613 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003614 return CMD_WARNING;
3615 }
3616
3617 record_type_str = argv[2];
3618 record_type = atoi(record_type_str);
3619
3620 /*
3621 Tweak IP header
3622 */
3623 ip_hdr = (struct ip *) buf;
3624 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
3625 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3626 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3627 ip_hdr->ip_src = igmp->ifaddr;
3628 ip_hdr->ip_dst = igmp->ifaddr;
3629
3630 /*
3631 Build IGMP v3 report message
3632 */
3633 igmp_msg = buf + ip_hlen;
3634 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
3635 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
3636 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
3637 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
3638 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
Klemen Sladic3defeb32014-02-07 16:23:44 +13003639 memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
Everton Marques871dbcf2009-08-11 15:43:05 -03003640
3641 /* Scan LINE sources */
3642 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
3643 src_addr = sources;
3644 for (argi = 3; argi < argc; ++argi,++src_addr) {
3645 src_str = argv[argi];
3646 result = inet_pton(AF_INET, src_str, src_addr);
3647 if (result <= 0) {
3648 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003649 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003650 return CMD_WARNING;
3651 }
3652 }
3653 num_sources = src_addr - sources;
3654
3655 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
3656
3657 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
3658
3659 /* compute checksum */
Everton Marques93911262014-09-18 11:10:58 -03003660 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
Everton Marques871dbcf2009-08-11 15:43:05 -03003661
3662 /* "receive" message */
3663
3664 ip_msg_len = ip_hlen + igmp_msg_len;
3665 result = pim_igmp_packet(igmp, buf, ip_msg_len);
3666 if (result) {
3667 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
3668 ip_msg_len, result, VTY_NEWLINE);
3669 return CMD_WARNING;
3670 }
3671
3672 return CMD_SUCCESS;
3673}
3674
Everton Marquesdba77582009-11-19 10:32:19 -02003675static int hexval(uint8_t ch)
3676{
3677 return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
3678}
3679
Everton Marques3e92c452009-11-18 16:26:38 -02003680DEFUN (test_pim_receive_dump,
3681 test_pim_receive_dump_cmd,
3682 "test pim receive dump INTERFACE A.B.C.D .LINE",
3683 "Test\n"
3684 "Test PIM protocol\n"
3685 "Test PIM message reception\n"
3686 "Test PIM packet dump reception from neighbor\n"
3687 "Interface\n"
3688 "Neighbor address\n"
3689 "Packet dump\n")
3690{
David Lamparterf8cfeb22012-02-16 04:31:08 +00003691 uint8_t buf[1000];
3692 uint8_t *pim_msg;
Everton Marques3e92c452009-11-18 16:26:38 -02003693 struct ip *ip_hdr;
3694 size_t ip_hlen; /* ip header length in bytes */
3695 int ip_msg_len;
3696 int pim_msg_size;
3697 const char *neigh_str;
3698 struct in_addr neigh_addr;
3699 const char *ifname;
3700 struct interface *ifp;
3701 int argi;
3702 int result;
3703
3704 /* Find interface */
3705 ifname = argv[0];
3706 ifp = if_lookup_by_name(ifname);
3707 if (!ifp) {
3708 vty_out(vty, "No such interface name %s%s",
3709 ifname, VTY_NEWLINE);
3710 return CMD_WARNING;
3711 }
3712
3713 /* Neighbor address */
3714 neigh_str = argv[1];
3715 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3716 if (result <= 0) {
3717 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
3718 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
3719 return CMD_WARNING;
3720 }
3721
3722 /*
3723 Tweak IP header
3724 */
3725 ip_hdr = (struct ip *) buf;
3726 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3727 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3728 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3729 ip_hdr->ip_src = neigh_addr;
3730 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3731
3732 /*
3733 Build PIM hello message
3734 */
3735 pim_msg = buf + ip_hlen;
3736 pim_msg_size = 0;
3737
3738 /* Scan LINE dump into buffer */
Everton Marquesdba77582009-11-19 10:32:19 -02003739 for (argi = 2; argi < argc; ++argi) {
3740 const char *str = argv[argi];
3741 int str_len = strlen(str);
3742 int str_last = str_len - 1;
3743 int i;
Everton Marques3e92c452009-11-18 16:26:38 -02003744
Everton Marquesdba77582009-11-19 10:32:19 -02003745 if (str_len % 2) {
3746 vty_out(vty, "%% Uneven hex array arg %d=%s%s",
3747 argi, str, VTY_NEWLINE);
Everton Marques3e92c452009-11-18 16:26:38 -02003748 return CMD_WARNING;
3749 }
3750
Everton Marquesdba77582009-11-19 10:32:19 -02003751 for (i = 0; i < str_last; i += 2) {
3752 uint8_t octet;
3753 int left;
3754 uint8_t h1 = str[i];
3755 uint8_t h2 = str[i + 1];
3756
3757 if (!isxdigit(h1) || !isxdigit(h2)) {
3758 vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
3759 h1, h2, argi, str, VTY_NEWLINE);
3760 return CMD_WARNING;
3761 }
3762 octet = (hexval(h1) << 4) + hexval(h2);
3763
3764 left = sizeof(buf) - ip_hlen - pim_msg_size;
3765 if (left < 1) {
David Lamparter5c697982012-02-16 04:47:56 +01003766 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 -02003767 sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
3768 return CMD_WARNING;
3769 }
3770
3771 pim_msg[pim_msg_size++] = octet;
3772 }
Everton Marques3e92c452009-11-18 16:26:38 -02003773 }
3774
3775 ip_msg_len = ip_hlen + pim_msg_size;
3776
David Lamparter5c697982012-02-16 04:47:56 +01003777 vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
Everton Marques3e92c452009-11-18 16:26:38 -02003778 sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
3779
3780 /* "receive" message */
3781
3782 result = pim_pim_packet(ifp, buf, ip_msg_len);
3783 if (result) {
3784 vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
3785 ip_msg_len, result, VTY_NEWLINE);
3786 return CMD_WARNING;
3787 }
3788
3789 return CMD_SUCCESS;
3790}
3791
Everton Marques871dbcf2009-08-11 15:43:05 -03003792DEFUN (test_pim_receive_hello,
3793 test_pim_receive_hello_cmd,
3794 "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
3795 "Test\n"
3796 "Test PIM protocol\n"
3797 "Test PIM message reception\n"
3798 "Test PIM hello reception from neighbor\n"
3799 "Interface\n"
3800 "Neighbor address\n"
3801 "Neighbor holdtime\n"
3802 "Neighbor DR priority\n"
3803 "Neighbor generation ID\n"
3804 "Neighbor propagation delay (msec)\n"
3805 "Neighbor override interval (msec)\n"
3806 "Neighbor LAN prune delay T-bit\n"
3807 "Neighbor secondary addresses\n")
3808{
David Lamparterf8cfeb22012-02-16 04:31:08 +00003809 uint8_t buf[1000];
3810 uint8_t *pim_msg;
Everton Marques871dbcf2009-08-11 15:43:05 -03003811 struct ip *ip_hdr;
3812 size_t ip_hlen; /* ip header length in bytes */
3813 int ip_msg_len;
3814 int pim_tlv_size;
3815 int pim_msg_size;
3816 const char *neigh_str;
3817 struct in_addr neigh_addr;
3818 const char *ifname;
3819 struct interface *ifp;
3820 uint16_t neigh_holdtime;
3821 uint16_t neigh_propagation_delay;
3822 uint16_t neigh_override_interval;
3823 int neigh_can_disable_join_suppression;
3824 uint32_t neigh_dr_priority;
3825 uint32_t neigh_generation_id;
3826 int argi;
3827 int result;
3828
3829 /* Find interface */
3830 ifname = argv[0];
3831 ifp = if_lookup_by_name(ifname);
3832 if (!ifp) {
3833 vty_out(vty, "No such interface name %s%s",
3834 ifname, VTY_NEWLINE);
3835 return CMD_WARNING;
3836 }
3837
3838 /* Neighbor address */
3839 neigh_str = argv[1];
3840 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3841 if (result <= 0) {
3842 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003843 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003844 return CMD_WARNING;
3845 }
3846
3847 neigh_holdtime = atoi(argv[2]);
3848 neigh_dr_priority = atoi(argv[3]);
3849 neigh_generation_id = atoi(argv[4]);
3850 neigh_propagation_delay = atoi(argv[5]);
3851 neigh_override_interval = atoi(argv[6]);
3852 neigh_can_disable_join_suppression = atoi(argv[7]);
3853
3854 /*
3855 Tweak IP header
3856 */
3857 ip_hdr = (struct ip *) buf;
3858 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
3859 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
3860 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
3861 ip_hdr->ip_src = neigh_addr;
3862 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
3863
3864 /*
3865 Build PIM hello message
3866 */
3867 pim_msg = buf + ip_hlen;
3868
3869 /* Scan LINE addresses */
3870 for (argi = 8; argi < argc; ++argi) {
3871 const char *sec_str = argv[argi];
3872 struct in_addr sec_addr;
3873 result = inet_pton(AF_INET, sec_str, &sec_addr);
3874 if (result <= 0) {
3875 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003876 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003877 return CMD_WARNING;
3878 }
3879
3880 vty_out(vty,
3881 "FIXME WRITEME consider neighbor secondary address %s%s",
3882 sec_str, VTY_NEWLINE);
3883 }
3884
3885 pim_tlv_size = pim_hello_build_tlv(ifp->name,
3886 pim_msg + PIM_PIM_MIN_LEN,
3887 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
3888 neigh_holdtime,
3889 neigh_dr_priority,
3890 neigh_generation_id,
3891 neigh_propagation_delay,
3892 neigh_override_interval,
3893 neigh_can_disable_join_suppression,
3894 0 /* FIXME secondary address list */);
3895 if (pim_tlv_size < 0) {
3896 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
3897 pim_tlv_size, VTY_NEWLINE);
3898 return CMD_WARNING;
3899 }
3900
3901 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
3902
3903 pim_msg_build_header(pim_msg, pim_msg_size,
3904 PIM_MSG_TYPE_HELLO);
3905
3906 /* "receive" message */
3907
3908 ip_msg_len = ip_hlen + pim_msg_size;
3909 result = pim_pim_packet(ifp, buf, ip_msg_len);
3910 if (result) {
3911 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
3912 ip_msg_len, result, VTY_NEWLINE);
3913 return CMD_WARNING;
3914 }
3915
3916 return CMD_SUCCESS;
3917}
3918
3919DEFUN (test_pim_receive_assert,
3920 test_pim_receive_assert_cmd,
3921 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
3922 "Test\n"
3923 "Test PIM protocol\n"
3924 "Test PIM message reception\n"
3925 "Test reception of PIM assert\n"
3926 "Interface\n"
3927 "Neighbor address\n"
3928 "Assert multicast group address\n"
3929 "Assert unicast source address\n"
3930 "Assert metric preference\n"
3931 "Assert route metric\n"
3932 "Assert RPT bit flag\n")
3933{
David Lamparterf8cfeb22012-02-16 04:31:08 +00003934 uint8_t buf[1000];
3935 uint8_t *buf_pastend = buf + sizeof(buf);
3936 uint8_t *pim_msg;
Everton Marques871dbcf2009-08-11 15:43:05 -03003937 struct ip *ip_hdr;
3938 size_t ip_hlen; /* ip header length in bytes */
3939 int ip_msg_len;
3940 int pim_msg_size;
3941 const char *neigh_str;
3942 struct in_addr neigh_addr;
3943 const char *group_str;
3944 struct in_addr group_addr;
3945 const char *source_str;
3946 struct in_addr source_addr;
3947 const char *ifname;
3948 struct interface *ifp;
3949 uint32_t assert_metric_preference;
3950 uint32_t assert_route_metric;
3951 uint32_t assert_rpt_bit_flag;
3952 int remain;
3953 int result;
3954
3955 /* Find interface */
3956 ifname = argv[0];
3957 ifp = if_lookup_by_name(ifname);
3958 if (!ifp) {
3959 vty_out(vty, "No such interface name %s%s",
3960 ifname, VTY_NEWLINE);
3961 return CMD_WARNING;
3962 }
3963
3964 /* Neighbor address */
3965 neigh_str = argv[1];
3966 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
3967 if (result <= 0) {
3968 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003969 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003970 return CMD_WARNING;
3971 }
3972
3973 /* Group address */
3974 group_str = argv[2];
3975 result = inet_pton(AF_INET, group_str, &group_addr);
3976 if (result <= 0) {
3977 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003978 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003979 return CMD_WARNING;
3980 }
3981
3982 /* Source address */
3983 source_str = argv[3];
3984 result = inet_pton(AF_INET, source_str, &source_addr);
3985 if (result <= 0) {
3986 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03003987 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03003988 return CMD_WARNING;
3989 }
3990
3991 assert_metric_preference = atoi(argv[4]);
3992 assert_route_metric = atoi(argv[5]);
3993 assert_rpt_bit_flag = atoi(argv[6]);
3994
3995 remain = buf_pastend - buf;
3996 if (remain < (int) sizeof(struct ip)) {
David Lamparter5c697982012-02-16 04:47:56 +01003997 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03003998 remain, sizeof(struct ip), VTY_NEWLINE);
3999 return CMD_WARNING;
4000 }
4001
4002 /*
4003 Tweak IP header
4004 */
4005 ip_hdr = (struct ip *) buf;
4006 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4007 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4008 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4009 ip_hdr->ip_src = neigh_addr;
4010 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4011
4012 /*
4013 Build PIM assert message
4014 */
4015 pim_msg = buf + ip_hlen; /* skip ip header */
4016
4017 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
4018 group_addr, source_addr,
4019 assert_metric_preference,
4020 assert_route_metric,
4021 assert_rpt_bit_flag);
4022 if (pim_msg_size < 0) {
4023 vty_out(vty, "Failure building PIM assert message: size=%d%s",
4024 pim_msg_size, VTY_NEWLINE);
4025 return CMD_WARNING;
4026 }
4027
4028 /* "receive" message */
4029
4030 ip_msg_len = ip_hlen + pim_msg_size;
4031 result = pim_pim_packet(ifp, buf, ip_msg_len);
4032 if (result) {
4033 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4034 ip_msg_len, result, VTY_NEWLINE);
4035 return CMD_WARNING;
4036 }
4037
4038 return CMD_SUCCESS;
4039}
4040
4041static int recv_joinprune(struct vty *vty,
4042 const char *argv[],
4043 int src_is_join)
4044{
David Lamparterf8cfeb22012-02-16 04:31:08 +00004045 uint8_t buf[1000];
4046 const uint8_t *buf_pastend = buf + sizeof(buf);
4047 uint8_t *pim_msg;
4048 uint8_t *pim_msg_curr;
Everton Marques871dbcf2009-08-11 15:43:05 -03004049 int pim_msg_size;
4050 struct ip *ip_hdr;
4051 size_t ip_hlen; /* ip header length in bytes */
4052 int ip_msg_len;
4053 uint16_t neigh_holdtime;
4054 const char *neigh_dst_str;
4055 struct in_addr neigh_dst_addr;
4056 const char *neigh_src_str;
4057 struct in_addr neigh_src_addr;
4058 const char *group_str;
4059 struct in_addr group_addr;
4060 const char *source_str;
4061 struct in_addr source_addr;
4062 const char *ifname;
4063 struct interface *ifp;
4064 int result;
4065 int remain;
4066 uint16_t num_joined;
4067 uint16_t num_pruned;
4068
4069 /* Find interface */
4070 ifname = argv[0];
4071 ifp = if_lookup_by_name(ifname);
4072 if (!ifp) {
4073 vty_out(vty, "No such interface name %s%s",
4074 ifname, VTY_NEWLINE);
4075 return CMD_WARNING;
4076 }
4077
4078 neigh_holdtime = atoi(argv[1]);
4079
4080 /* Neighbor destination address */
4081 neigh_dst_str = argv[2];
4082 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
4083 if (result <= 0) {
4084 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03004085 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03004086 return CMD_WARNING;
4087 }
4088
4089 /* Neighbor source address */
4090 neigh_src_str = argv[3];
4091 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
4092 if (result <= 0) {
4093 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03004094 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03004095 return CMD_WARNING;
4096 }
4097
4098 /* Multicast group address */
4099 group_str = argv[4];
4100 result = inet_pton(AF_INET, group_str, &group_addr);
4101 if (result <= 0) {
4102 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03004103 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03004104 return CMD_WARNING;
4105 }
4106
4107 /* Multicast source address */
4108 source_str = argv[5];
4109 result = inet_pton(AF_INET, source_str, &source_addr);
4110 if (result <= 0) {
4111 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03004112 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03004113 return CMD_WARNING;
4114 }
4115
4116 /*
4117 Tweak IP header
4118 */
4119 ip_hdr = (struct ip *) buf;
4120 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4121 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4122 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4123 ip_hdr->ip_src = neigh_src_addr;
4124 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4125
4126 /*
4127 Build PIM message
4128 */
4129 pim_msg = buf + ip_hlen;
4130
4131 /* skip room for pim header */
4132 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
4133
4134 remain = buf_pastend - pim_msg_curr;
4135 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
4136 remain,
4137 neigh_dst_addr);
4138 if (!pim_msg_curr) {
4139 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
4140 neigh_dst_str, remain, VTY_NEWLINE);
4141 return CMD_WARNING;
4142 }
4143
4144 remain = buf_pastend - pim_msg_curr;
4145 if (remain < 4) {
4146 vty_out(vty, "Group will not fit: space left=%d%s",
4147 remain, VTY_NEWLINE);
4148 return CMD_WARNING;
4149 }
4150
4151 *pim_msg_curr = 0; /* reserved */
4152 ++pim_msg_curr;
4153 *pim_msg_curr = 1; /* number of groups */
4154 ++pim_msg_curr;
4155 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
4156 ++pim_msg_curr;
4157 ++pim_msg_curr;
4158
4159 remain = buf_pastend - pim_msg_curr;
4160 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
4161 remain,
4162 group_addr);
4163 if (!pim_msg_curr) {
4164 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
4165 group_str, remain, VTY_NEWLINE);
4166 return CMD_WARNING;
4167 }
4168
4169 remain = buf_pastend - pim_msg_curr;
4170 if (remain < 4) {
4171 vty_out(vty, "Sources will not fit: space left=%d%s",
4172 remain, VTY_NEWLINE);
4173 return CMD_WARNING;
4174 }
4175
4176 if (src_is_join) {
4177 num_joined = 1;
4178 num_pruned = 0;
4179 }
4180 else {
4181 num_joined = 0;
4182 num_pruned = 1;
4183 }
4184
4185 /* number of joined sources */
4186 *((uint16_t *) pim_msg_curr) = htons(num_joined);
4187 ++pim_msg_curr;
4188 ++pim_msg_curr;
4189
4190 /* number of pruned sources */
4191 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
4192 ++pim_msg_curr;
4193 ++pim_msg_curr;
4194
4195 remain = buf_pastend - pim_msg_curr;
4196 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
4197 remain,
4198 source_addr);
4199 if (!pim_msg_curr) {
4200 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
4201 source_str, remain, VTY_NEWLINE);
4202 return CMD_WARNING;
4203 }
4204
4205 /* Add PIM header */
4206
4207 pim_msg_size = pim_msg_curr - pim_msg;
4208
4209 pim_msg_build_header(pim_msg, pim_msg_size,
4210 PIM_MSG_TYPE_JOIN_PRUNE);
4211
4212 /*
4213 "Receive" message
4214 */
4215
4216 ip_msg_len = ip_hlen + pim_msg_size;
4217 result = pim_pim_packet(ifp, buf, ip_msg_len);
4218 if (result) {
4219 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4220 ip_msg_len, result, VTY_NEWLINE);
4221 return CMD_WARNING;
4222 }
4223
4224 return CMD_SUCCESS;
4225}
4226
4227DEFUN (test_pim_receive_join,
4228 test_pim_receive_join_cmd,
4229 "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4230 "Test\n"
4231 "Test PIM protocol\n"
4232 "Test PIM message reception\n"
4233 "Test PIM join reception from neighbor\n"
4234 "Interface\n"
4235 "Neighbor holdtime\n"
4236 "Upstream neighbor unicast destination address\n"
4237 "Downstream neighbor unicast source address\n"
4238 "Multicast group address\n"
4239 "Unicast source address\n")
4240{
4241 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
4242}
4243
4244DEFUN (test_pim_receive_prune,
4245 test_pim_receive_prune_cmd,
4246 "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4247 "Test\n"
4248 "Test PIM protocol\n"
4249 "Test PIM message reception\n"
4250 "Test PIM prune reception from neighbor\n"
4251 "Interface\n"
4252 "Neighbor holdtime\n"
4253 "Upstream neighbor unicast destination address\n"
4254 "Downstream neighbor unicast source address\n"
4255 "Multicast group address\n"
4256 "Unicast source address\n")
4257{
4258 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
4259}
4260
4261DEFUN (test_pim_receive_upcall,
4262 test_pim_receive_upcall_cmd,
4263 "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
4264 "Test\n"
4265 "Test PIM protocol\n"
4266 "Test PIM message reception\n"
4267 "Test reception of kernel upcall\n"
4268 "NOCACHE kernel upcall\n"
4269 "WRONGVIF kernel upcall\n"
4270 "WHOLEPKT kernel upcall\n"
4271 "Input interface vif index\n"
4272 "Multicast group address\n"
4273 "Multicast source address\n")
4274{
4275 struct igmpmsg msg;
4276 const char *upcall_type;
4277 const char *group_str;
4278 const char *source_str;
4279 int result;
4280
4281 upcall_type = argv[0];
4282
4283 if (upcall_type[0] == 'n')
4284 msg.im_msgtype = IGMPMSG_NOCACHE;
4285 else if (upcall_type[1] == 'r')
4286 msg.im_msgtype = IGMPMSG_WRONGVIF;
4287 else if (upcall_type[1] == 'h')
4288 msg.im_msgtype = IGMPMSG_WHOLEPKT;
4289 else {
4290 vty_out(vty, "Unknown kernel upcall type: %s%s",
4291 upcall_type, VTY_NEWLINE);
4292 return CMD_WARNING;
4293 }
4294
4295 msg.im_vif = atoi(argv[1]);
4296
4297 /* Group address */
4298 group_str = argv[2];
4299 result = inet_pton(AF_INET, group_str, &msg.im_dst);
4300 if (result <= 0) {
4301 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03004302 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03004303 return CMD_WARNING;
4304 }
4305
4306 /* Source address */
4307 source_str = argv[3];
4308 result = inet_pton(AF_INET, source_str, &msg.im_src);
4309 if (result <= 0) {
4310 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
Everton Marquese96f0af2009-08-11 15:48:02 -03004311 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
Everton Marques871dbcf2009-08-11 15:43:05 -03004312 return CMD_WARNING;
4313 }
4314
4315 msg.im_mbz = 0; /* Must be zero */
4316
4317 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
4318 if (result) {
David Lamparter5c697982012-02-16 04:47:56 +01004319 vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
Everton Marques871dbcf2009-08-11 15:43:05 -03004320 sizeof(msg), result, VTY_NEWLINE);
4321 return CMD_WARNING;
4322 }
4323
4324 return CMD_SUCCESS;
4325}
4326
4327void pim_cmd_init()
4328{
Leonard Herve596470f2009-08-11 15:45:26 -03004329 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
4330 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
Everton Marques871dbcf2009-08-11 15:43:05 -03004331
Leonard Herve596470f2009-08-11 15:45:26 -03004332 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
4333 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
Everton Marques96f91ae2009-10-07 18:41:45 -03004334 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
4335 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004336#if 0
Leonard Herve596470f2009-08-11 15:45:26 -03004337 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03004338#else
Leonard Herve596470f2009-08-11 15:45:26 -03004339 install_element (CONFIG_NODE, &pim_interface_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004340#endif
Leonard Herve596470f2009-08-11 15:45:26 -03004341 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
Everton Marques871dbcf2009-08-11 15:43:05 -03004342
Leonard Herve596470f2009-08-11 15:45:26 -03004343 install_default (INTERFACE_NODE);
4344 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
4345 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
4346 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
4347 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
4348 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
4349 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
4350 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
4351 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
4352 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
4353 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
4354 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
4355 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004356
Leonard Herve596470f2009-08-11 15:45:26 -03004357 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
Everton Marques567f9272010-02-19 19:07:00 -02004358 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004359 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
4360 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
4361 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4362 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
4363 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4364 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
4365 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
4366 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
4367 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
4368 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
4369 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
4370 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
4371 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
4372 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
4373 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
4374 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
4375 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
4376 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
4377 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
4378 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
4379 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
4380 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
4381 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
4382 install_element (VIEW_NODE, &show_ip_multicast_cmd);
4383 install_element (VIEW_NODE, &show_ip_mroute_cmd);
4384 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
Everton Marques05e573d2010-04-20 12:20:46 -03004385 install_element (VIEW_NODE, &show_ip_rib_cmd);
Everton Marques824adbe2009-10-08 09:16:27 -03004386 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004387 install_element (VIEW_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004388
Leonard Herve596470f2009-08-11 15:45:26 -03004389 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
4390 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
Everton Marquesf24200d2014-02-14 16:40:34 -02004391 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004392 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
Everton Marquesf24200d2014-02-14 16:40:34 -02004393 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
Everton Marques3456a802014-07-22 14:52:57 -03004394 install_element (ENABLE_NODE, &clear_zclient_update_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004395
Leonard Herve596470f2009-08-11 15:45:26 -03004396 install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
Everton Marques567f9272010-02-19 19:07:00 -02004397 install_element (ENABLE_NODE, &show_ip_igmp_join_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004398 install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
4399 install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
4400 install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4401 install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
4402 install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4403 install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
4404 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
4405 install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
4406 install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
4407 install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
4408 install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
4409 install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
4410 install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
4411 install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
4412 install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
4413 install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
4414 install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
4415 install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
4416 install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
4417 install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
4418 install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
4419 install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
4420 install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
4421 install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
4422 install_element (ENABLE_NODE, &show_ip_multicast_cmd);
4423 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
4424 install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
Everton Marques05e573d2010-04-20 12:20:46 -03004425 install_element (ENABLE_NODE, &show_ip_rib_cmd);
Everton Marquese8c11bb2009-10-08 15:06:32 -03004426 install_element (ENABLE_NODE, &show_ip_ssmpingd_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004427 install_element (ENABLE_NODE, &show_debugging_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004428
Leonard Herve596470f2009-08-11 15:45:26 -03004429 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
4430 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
Everton Marques3e92c452009-11-18 16:26:38 -02004431 install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004432 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
4433 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
4434 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
4435 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004436
Leonard Herve596470f2009-08-11 15:45:26 -03004437 install_element (ENABLE_NODE, &debug_igmp_cmd);
4438 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
4439 install_element (ENABLE_NODE, &undebug_igmp_cmd);
4440 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
4441 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
4442 install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
4443 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
4444 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
4445 install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
4446 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
4447 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
4448 install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
Everton Marques67faabc2010-02-23 12:11:11 -03004449 install_element (ENABLE_NODE, &debug_mroute_cmd);
4450 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004451 install_element (ENABLE_NODE, &debug_pim_cmd);
4452 install_element (ENABLE_NODE, &no_debug_pim_cmd);
4453 install_element (ENABLE_NODE, &undebug_pim_cmd);
4454 install_element (ENABLE_NODE, &debug_pim_events_cmd);
4455 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
4456 install_element (ENABLE_NODE, &undebug_pim_events_cmd);
4457 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
Balaji.Ged14fa02014-10-08 01:11:31 -03004458 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004459 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
Balaji.Ged14fa02014-10-08 01:11:31 -03004460 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004461 install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
Everton Marques62738042009-11-18 10:44:13 -02004462 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
4463 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
4464 install_element (ENABLE_NODE, &undebug_pim_packetdump_send_cmd);
4465 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
4466 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
4467 install_element (ENABLE_NODE, &undebug_pim_packetdump_recv_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004468 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
4469 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
4470 install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
Everton Marques824adbe2009-10-08 09:16:27 -03004471 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
4472 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
4473 install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004474 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
4475 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
4476 install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004477
Leonard Herve596470f2009-08-11 15:45:26 -03004478 install_element (CONFIG_NODE, &debug_igmp_cmd);
4479 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
4480 install_element (CONFIG_NODE, &undebug_igmp_cmd);
4481 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
4482 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
4483 install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
4484 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
4485 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
4486 install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
4487 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
4488 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
4489 install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
Everton Marques67faabc2010-02-23 12:11:11 -03004490 install_element (CONFIG_NODE, &debug_mroute_cmd);
4491 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004492 install_element (CONFIG_NODE, &debug_pim_cmd);
4493 install_element (CONFIG_NODE, &no_debug_pim_cmd);
4494 install_element (CONFIG_NODE, &undebug_pim_cmd);
4495 install_element (CONFIG_NODE, &debug_pim_events_cmd);
4496 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
4497 install_element (CONFIG_NODE, &undebug_pim_events_cmd);
4498 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
Balaji.Ged14fa02014-10-08 01:11:31 -03004499 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004500 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
Balaji.Ged14fa02014-10-08 01:11:31 -03004501 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004502 install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
4503 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
4504 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
4505 install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
Everton Marques824adbe2009-10-08 09:16:27 -03004506 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
4507 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
4508 install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
Leonard Herve596470f2009-08-11 15:45:26 -03004509 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
4510 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
4511 install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
Everton Marques871dbcf2009-08-11 15:43:05 -03004512}