]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
PIM: prefix-list support for selecting RP
[mirror_frr.git] / pimd / pim_cmd.c
CommitLineData
12e41d03
DL
1/*
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
12e41d03
DL
20*/
21
12e41d03
DL
22#include <zebra.h>
23
24#include "command.h"
25#include "if.h"
26#include "prefix.h"
27#include "zclient.h"
dfe43e25 28#include "plist.h"
12e41d03
DL
29
30#include "pimd.h"
9867746a 31#include "pim_mroute.h"
12e41d03
DL
32#include "pim_cmd.h"
33#include "pim_iface.h"
34#include "pim_vty.h"
35#include "pim_mroute.h"
36#include "pim_str.h"
37#include "pim_igmp.h"
38#include "pim_igmpv3.h"
39#include "pim_sock.h"
40#include "pim_time.h"
41#include "pim_util.h"
42#include "pim_oil.h"
43#include "pim_neighbor.h"
44#include "pim_pim.h"
45#include "pim_ifchannel.h"
46#include "pim_hello.h"
47#include "pim_msg.h"
48#include "pim_upstream.h"
49#include "pim_rpf.h"
50#include "pim_macro.h"
51#include "pim_ssmpingd.h"
52#include "pim_zebra.h"
6250610a 53#include "pim_static.h"
a920d6e7 54#include "pim_rp.h"
05b0d0d0 55#include "pim_zlookup.h"
12e41d03
DL
56
57static struct cmd_node pim_global_node = {
58 PIM_NODE,
59 "",
60 1 /* vtysh ? yes */
61};
62
63static struct cmd_node interface_node = {
64 INTERFACE_NODE,
65 "%s(config-if)# ",
66 1 /* vtysh ? yes */
67};
68
69static void pim_if_membership_clear(struct interface *ifp)
70{
71 struct pim_interface *pim_ifp;
72
73 pim_ifp = ifp->info;
74 zassert(pim_ifp);
75
76 if (PIM_IF_TEST_PIM(pim_ifp->options) &&
77 PIM_IF_TEST_IGMP(pim_ifp->options)) {
78 return;
79 }
80
81 pim_ifchannel_membership_clear(ifp);
82}
83
84/*
85 When PIM is disabled on interface, IGMPv3 local membership
86 information is not injected into PIM interface state.
87
88 The function pim_if_membership_refresh() fetches all IGMPv3 local
89 membership information into PIM. It is intented to be called
90 whenever PIM is enabled on the interface in order to collect missed
91 local membership information.
92 */
93static void pim_if_membership_refresh(struct interface *ifp)
94{
95 struct pim_interface *pim_ifp;
96 struct listnode *sock_node;
97 struct igmp_sock *igmp;
98
99 pim_ifp = ifp->info;
100 zassert(pim_ifp);
101
102 if (!PIM_IF_TEST_PIM(pim_ifp->options))
103 return;
104 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
105 return;
106
107 /*
108 First clear off membership from all PIM (S,G) entries on the
109 interface
110 */
111
112 pim_ifchannel_membership_clear(ifp);
113
114 /*
115 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
116 the interface
117 */
118
119 /* scan igmp sockets */
120 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
121 struct listnode *grpnode;
122 struct igmp_group *grp;
123
124 /* scan igmp groups */
125 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
126 struct listnode *srcnode;
127 struct igmp_source *src;
128
129 /* scan group sources */
130 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
131
132 if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
4ed0af70 133 struct prefix_sg sg;
69283639 134
4ed0af70
DS
135 memset (&sg, 0, sizeof (struct prefix_sg));
136 sg.src = src->source_addr;
137 sg.grp = grp->group_addr;
69283639 138 pim_ifchannel_local_membership_add(ifp, &sg);
12e41d03
DL
139 }
140
141 } /* scan group sources */
142 } /* scan igmp groups */
143 } /* scan igmp sockets */
144
145 /*
146 Finally delete every PIM (S,G) entry lacking all state info
147 */
148
149 pim_ifchannel_delete_on_noinfo(ifp);
150
151}
152
153static void pim_show_assert(struct vty *vty)
154{
155 struct listnode *ifnode;
156 struct interface *ifp;
157 time_t now;
158
159 now = pim_time_monotonic_sec();
160
161 vty_out(vty,
162 "Interface Address Source Group State Winner Uptime Timer%s",
163 VTY_NEWLINE);
164
469351b3 165 for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
166 struct pim_interface *pim_ifp;
167 struct in_addr ifaddr;
168 struct listnode *ch_node;
169 struct pim_ifchannel *ch;
170
171 pim_ifp = ifp->info;
172
173 if (!pim_ifp)
174 continue;
175
176 ifaddr = pim_ifp->primary_address;
177
178 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
179 char ch_src_str[100];
180 char ch_grp_str[100];
181 char winner_str[100];
182 char uptime[10];
183 char timer[10];
184
4ed0af70 185 pim_inet4_dump("<ch_src?>", ch->sg.src,
12e41d03 186 ch_src_str, sizeof(ch_src_str));
4ed0af70 187 pim_inet4_dump("<ch_grp?>", ch->sg.grp,
12e41d03
DL
188 ch_grp_str, sizeof(ch_grp_str));
189 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
190 winner_str, sizeof(winner_str));
191
192 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
193 pim_time_timer_to_mmss(timer, sizeof(timer),
194 ch->t_ifassert_timer);
195
196 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
197 ifp->name,
198 inet_ntoa(ifaddr),
199 ch_src_str,
200 ch_grp_str,
201 pim_ifchannel_ifassert_name(ch->ifassert_state),
202 winner_str,
203 uptime,
204 timer,
205 VTY_NEWLINE);
206 } /* scan interface channels */
207 } /* scan interfaces */
208}
209
210static void pim_show_assert_internal(struct vty *vty)
211{
212 struct listnode *ifnode;
213 struct interface *ifp;
214
215 vty_out(vty,
216 "CA: CouldAssert%s"
217 "ECA: Evaluate CouldAssert%s"
218 "ATD: AssertTrackingDesired%s"
219 "eATD: Evaluate AssertTrackingDesired%s%s",
220 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
221
222 vty_out(vty,
223 "Interface Address Source Group CA eCA ATD eATD%s",
224 VTY_NEWLINE);
225
469351b3 226 for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
227 struct pim_interface *pim_ifp;
228 struct in_addr ifaddr;
229 struct listnode *ch_node;
230 struct pim_ifchannel *ch;
231
232 pim_ifp = ifp->info;
233
234 if (!pim_ifp)
235 continue;
236
237 ifaddr = pim_ifp->primary_address;
238
239 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
240 char ch_src_str[100];
241 char ch_grp_str[100];
242
4ed0af70 243 pim_inet4_dump("<ch_src?>", ch->sg.src,
12e41d03 244 ch_src_str, sizeof(ch_src_str));
4ed0af70 245 pim_inet4_dump("<ch_grp?>", ch->sg.grp,
12e41d03
DL
246 ch_grp_str, sizeof(ch_grp_str));
247 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
248 ifp->name,
249 inet_ntoa(ifaddr),
250 ch_src_str,
251 ch_grp_str,
252 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
253 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
254 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
255 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
256 VTY_NEWLINE);
257 } /* scan interface channels */
258 } /* scan interfaces */
259}
260
261static void pim_show_assert_metric(struct vty *vty)
262{
263 struct listnode *ifnode;
264 struct interface *ifp;
265
266 vty_out(vty,
267 "Interface Address Source Group RPT Pref Metric Address %s",
268 VTY_NEWLINE);
269
469351b3 270 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
271 struct pim_interface *pim_ifp;
272 struct in_addr ifaddr;
273 struct listnode *ch_node;
274 struct pim_ifchannel *ch;
275
276 pim_ifp = ifp->info;
277
278 if (!pim_ifp)
279 continue;
280
281 ifaddr = pim_ifp->primary_address;
282
283 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
284 char ch_src_str[100];
285 char ch_grp_str[100];
286 char addr_str[100];
287 struct pim_assert_metric am;
288
289 am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
290
4ed0af70 291 pim_inet4_dump("<ch_src?>", ch->sg.src,
12e41d03 292 ch_src_str, sizeof(ch_src_str));
4ed0af70 293 pim_inet4_dump("<ch_grp?>", ch->sg.grp,
12e41d03
DL
294 ch_grp_str, sizeof(ch_grp_str));
295 pim_inet4_dump("<addr?>", am.ip_address,
296 addr_str, sizeof(addr_str));
297
298 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
299 ifp->name,
300 inet_ntoa(ifaddr),
301 ch_src_str,
302 ch_grp_str,
303 am.rpt_bit_flag ? "yes" : "no",
304 am.metric_preference,
305 am.route_metric,
306 addr_str,
307 VTY_NEWLINE);
308 } /* scan interface channels */
309 } /* scan interfaces */
310}
311
312static void pim_show_assert_winner_metric(struct vty *vty)
313{
314 struct listnode *ifnode;
315 struct interface *ifp;
316
317 vty_out(vty,
318 "Interface Address Source Group RPT Pref Metric Address %s",
319 VTY_NEWLINE);
320
469351b3 321 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
322 struct pim_interface *pim_ifp;
323 struct in_addr ifaddr;
324 struct listnode *ch_node;
325 struct pim_ifchannel *ch;
326
327 pim_ifp = ifp->info;
328
329 if (!pim_ifp)
330 continue;
331
332 ifaddr = pim_ifp->primary_address;
333
334 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
335 char ch_src_str[100];
336 char ch_grp_str[100];
337 char addr_str[100];
338 struct pim_assert_metric *am;
339 char pref_str[5];
340 char metr_str[7];
341
342 am = &ch->ifassert_winner_metric;
343
4ed0af70 344 pim_inet4_dump("<ch_src?>", ch->sg.src,
12e41d03 345 ch_src_str, sizeof(ch_src_str));
4ed0af70 346 pim_inet4_dump("<ch_grp?>", ch->sg.grp,
12e41d03
DL
347 ch_grp_str, sizeof(ch_grp_str));
348 pim_inet4_dump("<addr?>", am->ip_address,
349 addr_str, sizeof(addr_str));
350
351 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
352 snprintf(pref_str, sizeof(pref_str), "INFI");
353 else
354 snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
355
356 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
357 snprintf(metr_str, sizeof(metr_str), "INFI");
358 else
359 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
360
361 vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
362 ifp->name,
363 inet_ntoa(ifaddr),
364 ch_src_str,
365 ch_grp_str,
366 am->rpt_bit_flag ? "yes" : "no",
367 pref_str,
368 metr_str,
369 addr_str,
370 VTY_NEWLINE);
371 } /* scan interface channels */
372 } /* scan interfaces */
373}
374
375static void pim_show_membership(struct vty *vty)
376{
377 struct listnode *ifnode;
378 struct interface *ifp;
379
380 vty_out(vty,
381 "Interface Address Source Group Membership%s",
382 VTY_NEWLINE);
383
469351b3 384 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
385 struct pim_interface *pim_ifp;
386 struct in_addr ifaddr;
387 struct listnode *ch_node;
388 struct pim_ifchannel *ch;
389
390 pim_ifp = ifp->info;
391
392 if (!pim_ifp)
393 continue;
394
395 ifaddr = pim_ifp->primary_address;
396
397 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
398 char ch_src_str[100];
399 char ch_grp_str[100];
400
4ed0af70 401 pim_inet4_dump("<ch_src?>", ch->sg.src,
12e41d03 402 ch_src_str, sizeof(ch_src_str));
4ed0af70 403 pim_inet4_dump("<ch_grp?>", ch->sg.grp,
12e41d03
DL
404 ch_grp_str, sizeof(ch_grp_str));
405
406 vty_out(vty, "%-9s %-15s %-15s %-15s %-10s%s",
407 ifp->name,
408 inet_ntoa(ifaddr),
409 ch_src_str,
410 ch_grp_str,
411 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?
412 "NOINFO" : "INCLUDE",
413 VTY_NEWLINE);
414 } /* scan interface channels */
415 } /* scan interfaces */
416
417}
418
419static void igmp_show_interfaces(struct vty *vty)
420{
421 struct listnode *node;
422 struct interface *ifp;
423 time_t now;
424
425 now = pim_time_monotonic_sec();
426
427 vty_out(vty,
428 "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s",
429 VTY_NEWLINE);
430
469351b3 431 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
432 struct pim_interface *pim_ifp;
433 struct listnode *sock_node;
434 struct igmp_sock *igmp;
435
436 pim_ifp = ifp->info;
437
438 if (!pim_ifp)
439 continue;
440
441 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
442 char uptime[10];
443 int mloop;
444
445 pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
446
447 mloop = pim_socket_mcastloop_get(igmp->fd);
448
449 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
450 ifp->name,
451 inet_ntoa(igmp->ifaddr),
452 ifp->ifindex,
453 igmp->fd,
454 uptime,
455 if_is_multicast(ifp) ? "yes" : "no",
456 if_is_broadcast(ifp) ? "yes" : "no",
457 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
458 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
459 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
460 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
461 VTY_NEWLINE);
462 }
463 }
464}
465
466static void igmp_show_interface_join(struct vty *vty)
467{
468 struct listnode *node;
469 struct interface *ifp;
470 time_t now;
471
472 now = pim_time_monotonic_sec();
473
474 vty_out(vty,
475 "Interface Address Source Group Socket Uptime %s",
476 VTY_NEWLINE);
477
469351b3 478 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
479 struct pim_interface *pim_ifp;
480 struct listnode *join_node;
481 struct igmp_join *ij;
482 struct in_addr pri_addr;
483 char pri_addr_str[100];
484
485 pim_ifp = ifp->info;
486
487 if (!pim_ifp)
488 continue;
489
490 if (!pim_ifp->igmp_join_list)
491 continue;
492
493 pri_addr = pim_find_primary_addr(ifp);
494 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
495
496 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node, ij)) {
497 char group_str[100];
498 char source_str[100];
499 char uptime[10];
500
501 pim_time_uptime(uptime, sizeof(uptime), now - ij->sock_creation);
502 pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
503 pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
504
505 vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s%s",
506 ifp->name,
507 pri_addr_str,
508 source_str,
509 group_str,
510 ij->sock_fd,
511 uptime,
512 VTY_NEWLINE);
513 } /* for (pim_ifp->igmp_join_list) */
514
515 } /* for (iflist) */
516
517}
518
519static void show_interface_address(struct vty *vty)
520{
521 struct listnode *ifpnode;
522 struct interface *ifp;
523
524 vty_out(vty,
525 "Interface Primary Secondary %s",
526 VTY_NEWLINE);
527
469351b3 528 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifpnode, ifp)) {
12e41d03
DL
529 struct listnode *ifcnode;
530 struct connected *ifc;
531 struct in_addr pri_addr;
532 char pri_addr_str[100];
533
534 pri_addr = pim_find_primary_addr(ifp);
535
536 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
537
538 for (ALL_LIST_ELEMENTS_RO(ifp->connected, ifcnode, ifc)) {
539 char sec_addr_str[100];
540 struct prefix *p = ifc->address;
541
542 if (p->family != AF_INET)
543 continue;
544
545 if (p->u.prefix4.s_addr == pri_addr.s_addr) {
546 sec_addr_str[0] = '\0';
547 }
548 else {
549 pim_inet4_dump("<sec?>", p->u.prefix4, sec_addr_str, sizeof(sec_addr_str));
550 }
551
552 vty_out(vty, "%-9s %-15s %-15s%s",
553 ifp->name,
554 pri_addr_str,
555 sec_addr_str,
556 VTY_NEWLINE);
557 }
558 }
559}
560
561static void pim_show_dr(struct vty *vty)
562{
563 struct listnode *node;
564 struct interface *ifp;
565 time_t now;
566
567 now = pim_time_monotonic_sec();
568
569 vty_out(vty,
dedccda6
DS
570 "NonPri: Number of neighbors missing DR Priority hello option%s"
571 "DrPri: Designated Router Priority sent%s%s",
572 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
12e41d03 573
dedccda6 574 vty_out(vty, "Interface Address DR Uptime Elections Changes NonPri DrPri%s", VTY_NEWLINE);
12e41d03 575
469351b3 576 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
577 struct pim_interface *pim_ifp;
578 struct in_addr ifaddr;
579 char dr_str[100];
580 char dr_uptime[10];
581
582 pim_ifp = ifp->info;
583
584 if (!pim_ifp)
585 continue;
586
587 if (pim_ifp->pim_sock_fd < 0)
588 continue;
589
590 ifaddr = pim_ifp->primary_address;
591
592 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime),
593 now, pim_ifp->pim_dr_election_last);
594
595 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr,
596 dr_str, sizeof(dr_str));
597
dedccda6 598 vty_out(vty, "%-9s %-15s %-15s %8s %9d %7d %6d %10d%s",
12e41d03
DL
599 ifp->name,
600 inet_ntoa(ifaddr),
601 dr_str,
602 dr_uptime,
603 pim_ifp->pim_dr_election_count,
604 pim_ifp->pim_dr_election_changes,
605 pim_ifp->pim_dr_num_nondrpri_neighbors,
dedccda6 606 pim_ifp->pim_dr_priority,
12e41d03
DL
607 VTY_NEWLINE);
608 }
609}
610
611static void pim_show_hello(struct vty *vty)
612{
613 struct listnode *node;
614 struct interface *ifp;
615 time_t now;
616
617 now = pim_time_monotonic_sec();
618
2a05c94c 619 vty_out(vty, "Interface Address Period Timer StatStart Recv Rfail Send Sfail LGenid%s", VTY_NEWLINE);
12e41d03 620
469351b3 621 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
622 struct pim_interface *pim_ifp;
623 struct in_addr ifaddr;
624 char hello_period[10];
625 char hello_timer[10];
626 char stat_uptime[10];
627
628 pim_ifp = ifp->info;
629
630 if (!pim_ifp)
631 continue;
632
633 if (pim_ifp->pim_sock_fd < 0)
634 continue;
635
636 ifaddr = pim_ifp->primary_address;
637
638 pim_time_timer_to_mmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
639 pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
640 pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
641
2a05c94c 642 vty_out(vty, "%-9s %-15s %6s %5s %9s %4u %5u %4u %5u %08x%s",
12e41d03
DL
643 ifp->name,
644 inet_ntoa(ifaddr),
645 hello_period,
646 hello_timer,
647 stat_uptime,
648 pim_ifp->pim_ifstat_hello_recv,
649 pim_ifp->pim_ifstat_hello_recvfail,
650 pim_ifp->pim_ifstat_hello_sent,
651 pim_ifp->pim_ifstat_hello_sendfail,
2a05c94c 652 pim_ifp->pim_generation_id,
12e41d03
DL
653 VTY_NEWLINE);
654 }
655}
656
657static void pim_show_interfaces(struct vty *vty)
658{
659 struct listnode *node;
660 struct interface *ifp;
661 time_t now;
662
663 now = pim_time_monotonic_sec();
664
665 vty_out(vty, "Interface Address ifIndex Socket Uptime Multi Broad MLoop AllMu Prmsc Del%s", VTY_NEWLINE);
666
469351b3 667 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
668 struct pim_interface *pim_ifp;
669 struct in_addr ifaddr;
670 char uptime[10];
671 int mloop;
672
673 pim_ifp = ifp->info;
674
675 if (!pim_ifp)
676 continue;
677
678 if (pim_ifp->pim_sock_fd < 0)
679 continue;
680
681 ifaddr = pim_ifp->primary_address;
682
683 pim_time_uptime(uptime, sizeof(uptime), now - pim_ifp->pim_sock_creation);
684
685 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
686
687 vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
688 ifp->name,
689 inet_ntoa(ifaddr),
690 ifp->ifindex,
691 pim_ifp->pim_sock_fd,
692 uptime,
693 if_is_multicast(ifp) ? "yes" : "no",
694 if_is_broadcast(ifp) ? "yes" : "no",
695 (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
696 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
697 (ifp->flags & IFF_PROMISC) ? "yes" : "no",
698 PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
699 VTY_NEWLINE);
700 }
701}
702
703static void pim_show_join(struct vty *vty)
704{
705 struct listnode *ifnode;
706 struct interface *ifp;
707 time_t now;
708
709 now = pim_time_monotonic_sec();
710
711 vty_out(vty,
712 "Interface Address Source Group State Uptime Expire Prune%s",
713 VTY_NEWLINE);
714
469351b3 715 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
716 struct pim_interface *pim_ifp;
717 struct in_addr ifaddr;
718 struct listnode *ch_node;
719 struct pim_ifchannel *ch;
720
721 pim_ifp = ifp->info;
722
723 if (!pim_ifp)
724 continue;
725
726 ifaddr = pim_ifp->primary_address;
727
728 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
729 char ch_src_str[100];
730 char ch_grp_str[100];
731 char uptime[10];
732 char expire[10];
733 char prune[10];
734
4ed0af70 735 pim_inet4_dump("<ch_src?>", ch->sg.src,
12e41d03 736 ch_src_str, sizeof(ch_src_str));
4ed0af70 737 pim_inet4_dump("<ch_grp?>", ch->sg.grp,
12e41d03
DL
738 ch_grp_str, sizeof(ch_grp_str));
739
740 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
741 pim_time_timer_to_mmss(expire, sizeof(expire),
742 ch->t_ifjoin_expiry_timer);
743 pim_time_timer_to_mmss(prune, sizeof(prune),
744 ch->t_ifjoin_prune_pending_timer);
745
746 vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
747 ifp->name,
748 inet_ntoa(ifaddr),
749 ch_src_str,
750 ch_grp_str,
751 pim_ifchannel_ifjoin_name(ch->ifjoin_state),
752 uptime,
753 expire,
754 prune,
755 VTY_NEWLINE);
756 } /* scan interface channels */
757 } /* scan interfaces */
758
759}
760
761static void pim_show_neighbors(struct vty *vty)
762{
763 struct listnode *node;
764 struct interface *ifp;
765 time_t now;
766
767 now = pim_time_monotonic_sec();
768
769 vty_out(vty,
770 "Recv flags: H=holdtime L=lan_prune_delay P=dr_priority G=generation_id A=address_list%s"
771 " T=can_disable_join_suppression%s%s",
772 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
773
774 vty_out(vty, "Interface Address Neighbor Uptime Timer Holdt DrPri GenId Recv %s", VTY_NEWLINE);
775
469351b3 776 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
777 struct pim_interface *pim_ifp;
778 struct in_addr ifaddr;
779 struct listnode *neighnode;
780 struct pim_neighbor *neigh;
781
782 pim_ifp = ifp->info;
783
784 if (!pim_ifp)
785 continue;
786
787 if (pim_ifp->pim_sock_fd < 0)
788 continue;
789
790 ifaddr = pim_ifp->primary_address;
791
792 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
793 char uptime[10];
794 char holdtime[10];
795 char expire[10];
796 char neigh_src_str[100];
797 char recv[7];
798
799 pim_inet4_dump("<src?>", neigh->source_addr,
800 neigh_src_str, sizeof(neigh_src_str));
801 pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
802 pim_time_mmss(holdtime, sizeof(holdtime), neigh->holdtime);
803 pim_time_timer_to_mmss(expire, sizeof(expire), neigh->t_expire_timer);
804
805 recv[0] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME) ? 'H' : ' ';
806 recv[1] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? 'L' : ' ';
807 recv[2] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY) ? 'P' : ' ';
808 recv[3] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ? 'G' : ' ';
809 recv[4] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST) ? 'A' : ' ';
810 recv[5] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION) ? 'T' : ' ';
811 recv[6] = '\0';
812
813 vty_out(vty, "%-9s %-15s %-15s %8s %5s %5s %5u %08x %6s%s",
814 ifp->name,
815 inet_ntoa(ifaddr),
816 neigh_src_str,
817 uptime,
818 expire,
819 holdtime,
820 neigh->dr_priority,
821 neigh->generation_id,
822 recv,
823 VTY_NEWLINE);
824 }
825
826
827 }
828}
829
830static void pim_show_lan_prune_delay(struct vty *vty)
831{
832 struct listnode *node;
833 struct interface *ifp;
834
835 vty_out(vty,
836 "PrDly=propagation_delay (msec) OvInt=override_interval (msec)%s"
837 "HiDly=highest_propagation_delay (msec) HiInt=highest_override_interval (msec)%s"
838 "NoDly=number_of_non_lan_delay_neighbors%s"
839 "T=t_bit LPD=lan_prune_delay_hello_option%s%s",
840 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
841
842 vty_out(vty, "Interface Address PrDly OvInt NoDly HiDly HiInt T | Neighbor LPD PrDly OvInt T%s", VTY_NEWLINE);
843
469351b3 844 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
845 struct pim_interface *pim_ifp;
846 struct in_addr ifaddr;
847 struct listnode *neighnode;
848 struct pim_neighbor *neigh;
849
850 pim_ifp = ifp->info;
851
852 if (!pim_ifp)
853 continue;
854
855 if (pim_ifp->pim_sock_fd < 0)
856 continue;
857
858 ifaddr = pim_ifp->primary_address;
859
860 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
861 char neigh_src_str[100];
862
863 pim_inet4_dump("<src?>", neigh->source_addr,
864 neigh_src_str, sizeof(neigh_src_str));
865
866 vty_out(vty, "%-9s %-15s %5u %5u %5u %5u %5u %1u | %-15s %-3s %5u %5u %1u%s",
867 ifp->name,
868 inet_ntoa(ifaddr),
869 pim_ifp->pim_propagation_delay_msec,
870 pim_ifp->pim_override_interval_msec,
871 pim_ifp->pim_number_of_nonlandelay_neighbors,
872 pim_ifp->pim_neighbors_highest_propagation_delay_msec,
873 pim_ifp->pim_neighbors_highest_override_interval_msec,
874 PIM_FORCE_BOOLEAN(PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options)),
875 neigh_src_str,
876 PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? "yes" : "no",
877 neigh->propagation_delay_msec,
878 neigh->override_interval_msec,
879 PIM_FORCE_BOOLEAN(PIM_OPTION_IS_SET(neigh->hello_options,
880 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION)),
881 VTY_NEWLINE);
882 }
883
884 }
885}
886
887static void pim_show_jp_override_interval(struct vty *vty)
888{
889 struct listnode *node;
890 struct interface *ifp;
891
892 vty_out(vty,
893 "EffPDelay=effective_propagation_delay (msec)%s"
894 "EffOvrInt=override_interval (msec)%s"
895 "JPOvrInt=jp_override_interval (msec)%s%s",
896 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
897
898 vty_out(vty, "Interface Address LAN_Delay EffPDelay EffOvrInt JPOvrInt%s", VTY_NEWLINE);
899
469351b3 900 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
901 struct pim_interface *pim_ifp;
902 struct in_addr ifaddr;
903
904 pim_ifp = ifp->info;
905
906 if (!pim_ifp)
907 continue;
908
909 if (pim_ifp->pim_sock_fd < 0)
910 continue;
911
912 ifaddr = pim_ifp->primary_address;
913
914 vty_out(vty, "%-9s %-15s %-9s %9u %9u %8u%s",
915 ifp->name,
916 inet_ntoa(ifaddr),
917 pim_if_lan_delay_enabled(ifp) ? "enabled" : "disabled",
918 pim_if_effective_propagation_delay_msec(ifp),
919 pim_if_effective_override_interval_msec(ifp),
920 pim_if_jp_override_interval_msec(ifp),
921 VTY_NEWLINE);
922 }
923}
924
925static void pim_show_neighbors_secondary(struct vty *vty)
926{
927 struct listnode *node;
928 struct interface *ifp;
929
930 vty_out(vty, "Interface Address Neighbor Secondary %s", VTY_NEWLINE);
931
469351b3 932 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
933 struct pim_interface *pim_ifp;
934 struct in_addr ifaddr;
935 struct listnode *neighnode;
936 struct pim_neighbor *neigh;
937
938 pim_ifp = ifp->info;
939
940 if (!pim_ifp)
941 continue;
942
943 if (pim_ifp->pim_sock_fd < 0)
944 continue;
945
946 ifaddr = pim_ifp->primary_address;
947
948 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
949 char neigh_src_str[100];
950 struct listnode *prefix_node;
951 struct prefix *p;
952
953 if (!neigh->prefix_list)
954 continue;
955
956 pim_inet4_dump("<src?>", neigh->source_addr,
957 neigh_src_str, sizeof(neigh_src_str));
958
959 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
960 char neigh_sec_str[100];
961
962 if (p->family != AF_INET)
963 continue;
964
965 pim_inet4_dump("<src?>", p->u.prefix4,
966 neigh_sec_str, sizeof(neigh_sec_str));
967
968 vty_out(vty, "%-9s %-15s %-15s %-15s%s",
969 ifp->name,
970 inet_ntoa(ifaddr),
971 neigh_src_str,
972 neigh_sec_str,
973 VTY_NEWLINE);
974 }
975 }
976 }
977}
978
979static void pim_show_upstream(struct vty *vty)
980{
981 struct listnode *upnode;
982 struct pim_upstream *up;
983 time_t now;
984
985 now = pim_time_monotonic_sec();
986
2ecb76d3 987 vty_out(vty, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE);
12e41d03
DL
988
989 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
990 char src_str[100];
991 char grp_str[100];
992 char uptime[10];
993 char join_timer[10];
ad6ec47b 994 char rs_timer[10];
2ecb76d3 995 char ka_timer[10];
12e41d03 996
4ed0af70
DS
997 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
998 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
12e41d03 999 pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
2ecb76d3 1000 pim_time_timer_to_hhmmss (join_timer, sizeof(join_timer), up->t_join_timer);
ad6ec47b 1001 pim_time_timer_to_hhmmss (rs_timer, sizeof (rs_timer), up->t_rs_timer);
2ecb76d3 1002 pim_time_timer_to_hhmmss (ka_timer, sizeof (ka_timer), up->t_ka_timer);
12e41d03 1003
2ecb76d3 1004 vty_out(vty, "%-10s%-15s %-15s %-5s %-8s %-9s %-9s %-9s %6d%s",
2e948c78 1005 up->rpf.source_nexthop.interface->name,
12e41d03
DL
1006 src_str,
1007 grp_str,
c9802954 1008 pim_upstream_state2str (up->join_state),
12e41d03
DL
1009 uptime,
1010 join_timer,
ad6ec47b 1011 rs_timer,
2ecb76d3 1012 ka_timer,
12e41d03
DL
1013 up->ref_count,
1014 VTY_NEWLINE);
1015 }
1016}
1017
1018static void pim_show_join_desired(struct vty *vty)
1019{
1020 struct listnode *ifnode;
1021 struct listnode *chnode;
1022 struct interface *ifp;
1023 struct pim_interface *pim_ifp;
1024 struct pim_ifchannel *ch;
1025 char src_str[100];
1026 char grp_str[100];
1027
1028 vty_out(vty,
1029 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1030 VTY_NEWLINE);
1031
1032 /* scan all interfaces */
469351b3 1033 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1034 pim_ifp = ifp->info;
1035 if (!pim_ifp)
1036 continue;
1037
1038 /* scan per-interface (S,G) state */
1039 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
1040 struct pim_upstream *up = ch->upstream;
1041
4ed0af70
DS
1042 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
1043 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
12e41d03
DL
1044
1045 vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1046 ifp->name,
1047 src_str,
1048 grp_str,
1049 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
1050 pim_macro_chisin_joins(ch) ? "yes" : "no",
1051 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
1052 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
1053 pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
1054 VTY_NEWLINE);
1055 }
1056 }
1057}
1058
1059static void pim_show_upstream_rpf(struct vty *vty)
1060{
1061 struct listnode *upnode;
1062 struct pim_upstream *up;
1063
1064 vty_out(vty,
1065 "Source Group RpfIface RibNextHop RpfAddress %s",
1066 VTY_NEWLINE);
1067
1068 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
1069 char src_str[100];
1070 char grp_str[100];
1071 char rpf_nexthop_str[100];
1072 char rpf_addr_str[100];
1073 struct pim_rpf *rpf;
1074 const char *rpf_ifname;
1075
1076 rpf = &up->rpf;
1077
4ed0af70
DS
1078 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
1079 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
63c59d0c
DS
1080 pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
1081 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
12e41d03
DL
1082
1083 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1084
1085 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
1086 src_str,
1087 grp_str,
1088 rpf_ifname,
1089 rpf_nexthop_str,
1090 rpf_addr_str,
1091 VTY_NEWLINE);
1092 }
1093}
1094
1095static void show_rpf_refresh_stats(struct vty *vty, time_t now)
1096{
1097 char refresh_uptime[10];
1098
1099 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
1100
1101 vty_out(vty,
1102 "RPF Cache Refresh Delay: %ld msecs%s"
1103 "RPF Cache Refresh Timer: %ld msecs%s"
1104 "RPF Cache Refresh Requests: %lld%s"
1105 "RPF Cache Refresh Events: %lld%s"
284b4301
DS
1106 "RPF Cache Refresh Last: %s%s"
1107 "Nexthop Lookups: %lld%s",
12e41d03
DL
1108 qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
1109 pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
1110 (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
1111 (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
284b4301
DS
1112 refresh_uptime, VTY_NEWLINE,
1113 (long long) qpim_nexthop_lookups, VTY_NEWLINE);
12e41d03
DL
1114}
1115
1116static void show_scan_oil_stats(struct vty *vty, time_t now)
1117{
1118 char uptime_scan_oil[10];
1119 char uptime_mroute_add[10];
1120 char uptime_mroute_del[10];
1121
1122 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
1123 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
1124 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
1125
1126 vty_out(vty,
1127 "Scan OIL - Last: %s Events: %lld%s"
1128 "MFC Add - Last: %s Events: %lld%s"
1129 "MFC Del - Last: %s Events: %lld%s",
1130 uptime_scan_oil, (long long) qpim_scan_oil_events, VTY_NEWLINE,
1131 uptime_mroute_add, (long long) qpim_mroute_add_events, VTY_NEWLINE,
1132 uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
1133}
1134
1135static void pim_show_rpf(struct vty *vty)
1136{
1137 struct listnode *up_node;
1138 struct pim_upstream *up;
1139 time_t now = pim_time_monotonic_sec();
1140
1141 show_rpf_refresh_stats(vty, now);
1142
1143 vty_out(vty, "%s", VTY_NEWLINE);
1144
1145 vty_out(vty,
1146 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1147 VTY_NEWLINE);
1148
1149 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
1150 char src_str[100];
1151 char grp_str[100];
1152 char rpf_addr_str[100];
1153 char rib_nexthop_str[100];
1154 const char *rpf_ifname;
1155 struct pim_rpf *rpf = &up->rpf;
1156
4ed0af70
DS
1157 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
1158 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
63c59d0c
DS
1159 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1160 pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
12e41d03
DL
1161
1162 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1163
1164 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1165 src_str,
1166 grp_str,
1167 rpf_ifname,
1168 rpf_addr_str,
1169 rib_nexthop_str,
1170 rpf->source_nexthop.mrib_route_metric,
1171 rpf->source_nexthop.mrib_metric_preference,
1172 VTY_NEWLINE);
1173 }
1174}
1175
1176static void igmp_show_querier(struct vty *vty)
1177{
1178 struct listnode *node;
1179 struct interface *ifp;
1180
1181 vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
1182
469351b3 1183 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
1184 struct pim_interface *pim_ifp = ifp->info;
1185 struct listnode *sock_node;
1186 struct igmp_sock *igmp;
1187
1188 if (!pim_ifp)
1189 continue;
1190
1191 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1192 char query_hhmmss[10];
1193 char other_hhmmss[10];
1194
1195 pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
1196 pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
1197
1198 vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
1199 ifp->name,
1200 inet_ntoa(igmp->ifaddr),
1201 igmp->t_igmp_query_timer ? "THIS" : "OTHER",
1202 igmp->startup_query_count,
1203 query_hhmmss,
1204 other_hhmmss,
1205 VTY_NEWLINE);
1206 }
1207 }
1208}
1209
1210static void igmp_show_groups(struct vty *vty)
1211{
1212 struct listnode *ifnode;
1213 struct interface *ifp;
1214 time_t now;
1215
1216 now = pim_time_monotonic_sec();
1217
1218 vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
1219
1220 /* scan interfaces */
469351b3 1221 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1222 struct pim_interface *pim_ifp = ifp->info;
1223 struct listnode *sock_node;
1224 struct igmp_sock *igmp;
1225
1226 if (!pim_ifp)
1227 continue;
1228
1229 /* scan igmp sockets */
1230 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1231 char ifaddr_str[100];
1232 struct listnode *grpnode;
1233 struct igmp_group *grp;
1234
1235 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1236
1237 /* scan igmp groups */
1238 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1239 char group_str[100];
1240 char hhmmss[10];
1241 char uptime[10];
1242
1243 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1244 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
1245 pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
1246
1247 vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
1248 ifp->name,
1249 ifaddr_str,
1250 group_str,
1251 grp->group_filtermode_isexcl ? "EXCL" : "INCL",
1252 hhmmss,
1253 grp->group_source_list ? listcount(grp->group_source_list) : 0,
1254 igmp_group_compat_mode(igmp, grp),
1255 uptime,
1256 VTY_NEWLINE);
1257
1258 } /* scan igmp groups */
1259 } /* scan igmp sockets */
1260 } /* scan interfaces */
1261}
1262
1263static void igmp_show_group_retransmission(struct vty *vty)
1264{
1265 struct listnode *ifnode;
1266 struct interface *ifp;
1267
1268 vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
1269
1270 /* scan interfaces */
469351b3 1271 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1272 struct pim_interface *pim_ifp = ifp->info;
1273 struct listnode *sock_node;
1274 struct igmp_sock *igmp;
1275
1276 if (!pim_ifp)
1277 continue;
1278
1279 /* scan igmp sockets */
1280 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1281 char ifaddr_str[100];
1282 struct listnode *grpnode;
1283 struct igmp_group *grp;
1284
1285 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1286
1287 /* scan igmp groups */
1288 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1289 char group_str[100];
1290 char grp_retr_mmss[10];
1291 struct listnode *src_node;
1292 struct igmp_source *src;
1293 int grp_retr_sources = 0;
1294
1295 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1296 pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
1297
1298
1299 /* count group sources with retransmission state */
1300 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
1301 if (src->source_query_retransmit_count > 0) {
1302 ++grp_retr_sources;
1303 }
1304 }
1305
1306 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
1307 ifp->name,
1308 ifaddr_str,
1309 group_str,
1310 grp_retr_mmss,
1311 grp->group_specific_query_retransmit_count,
1312 grp_retr_sources,
1313 VTY_NEWLINE);
1314
1315 } /* scan igmp groups */
1316 } /* scan igmp sockets */
1317 } /* scan interfaces */
1318}
1319
1320static void igmp_show_parameters(struct vty *vty)
1321{
1322 struct listnode *ifnode;
1323 struct interface *ifp;
1324
1325 vty_out(vty,
1326 "QRV: Robustness Variable SQI: Startup Query Interval%s"
1327 "QQI: Query Interval OQPI: Other Querier Present Interval%s"
1328 "QRI: Query Response Interval LMQT: Last Member Query Time%s"
1329 "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
1330 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1331
1332 vty_out(vty,
1333 "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
1334 VTY_NEWLINE);
1335
1336 /* scan interfaces */
469351b3 1337 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1338 struct pim_interface *pim_ifp = ifp->info;
1339 struct listnode *sock_node;
1340 struct igmp_sock *igmp;
1341
1342 if (!pim_ifp)
1343 continue;
1344
1345 /* scan igmp sockets */
1346 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1347 char ifaddr_str[100];
1348 long gmi_dsec; /* Group Membership Interval */
1349 long oqpi_dsec; /* Other Querier Present Interval */
1350 int sqi;
1351 long lmqt_dsec;
1352 long ohpi_dsec;
1353 long qri_dsec;
1354
1355 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1356
1357 gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
1358 igmp->querier_query_interval,
1359 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1360
1361 sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
1362
1363 oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
1364 igmp->querier_query_interval,
1365 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1366
1367 lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
1368 igmp->querier_robustness_variable) / 100;
1369
1370 ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
1371 igmp->querier_query_interval,
1372 pim_ifp->igmp_query_max_response_time_dsec);
1373
1374 qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
1375
1376 vty_out(vty,
1377 "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
1378 ifp->name,
1379 ifaddr_str,
1380 igmp->querier_robustness_variable,
1381 igmp->querier_query_interval,
1382 qri_dsec / 10, qri_dsec % 10,
1383 gmi_dsec / 10, gmi_dsec % 10,
1384 sqi,
1385 oqpi_dsec / 10, oqpi_dsec % 10,
1386 lmqt_dsec / 10, lmqt_dsec % 10,
1387 ohpi_dsec / 10, ohpi_dsec % 10,
1388 VTY_NEWLINE);
1389
1390 } /* scan igmp sockets */
1391 } /* scan interfaces */
1392}
1393
1394static void igmp_show_sources(struct vty *vty)
1395{
1396 struct listnode *ifnode;
1397 struct interface *ifp;
1398 time_t now;
1399
1400 now = pim_time_monotonic_sec();
1401
1402 vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
1403
1404 /* scan interfaces */
469351b3 1405 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1406 struct pim_interface *pim_ifp = ifp->info;
1407 struct listnode *sock_node;
1408 struct igmp_sock *igmp;
1409
1410 if (!pim_ifp)
1411 continue;
1412
1413 /* scan igmp sockets */
1414 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1415 char ifaddr_str[100];
1416 struct listnode *grpnode;
1417 struct igmp_group *grp;
1418
1419 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1420
1421 /* scan igmp groups */
1422 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1423 char group_str[100];
1424 struct listnode *srcnode;
1425 struct igmp_source *src;
1426
1427 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1428
1429 /* scan group sources */
1430 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1431 char source_str[100];
1432 char mmss[10];
1433 char uptime[10];
1434
1435 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1436
1437 pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
1438
1439 pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
1440
1441 vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
1442 ifp->name,
1443 ifaddr_str,
1444 group_str,
1445 source_str,
1446 mmss,
1447 IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
1448 uptime,
1449 VTY_NEWLINE);
1450
1451 } /* scan group sources */
1452 } /* scan igmp groups */
1453 } /* scan igmp sockets */
1454 } /* scan interfaces */
1455}
1456
1457static void igmp_show_source_retransmission(struct vty *vty)
1458{
1459 struct listnode *ifnode;
1460 struct interface *ifp;
1461
1462 vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
1463
1464 /* scan interfaces */
469351b3 1465 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1466 struct pim_interface *pim_ifp = ifp->info;
1467 struct listnode *sock_node;
1468 struct igmp_sock *igmp;
1469
1470 if (!pim_ifp)
1471 continue;
1472
1473 /* scan igmp sockets */
1474 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1475 char ifaddr_str[100];
1476 struct listnode *grpnode;
1477 struct igmp_group *grp;
1478
1479 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1480
1481 /* scan igmp groups */
1482 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1483 char group_str[100];
1484 struct listnode *srcnode;
1485 struct igmp_source *src;
1486
1487 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1488
1489 /* scan group sources */
1490 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1491 char source_str[100];
1492
1493 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1494
1495 vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
1496 ifp->name,
1497 ifaddr_str,
1498 group_str,
1499 source_str,
1500 src->source_query_retransmit_count,
1501 VTY_NEWLINE);
1502
1503 } /* scan group sources */
1504 } /* scan igmp groups */
1505 } /* scan igmp sockets */
1506 } /* scan interfaces */
1507}
1508
1509static void clear_igmp_interfaces()
1510{
1511 struct listnode *ifnode;
1512 struct listnode *ifnextnode;
1513 struct interface *ifp;
1514
469351b3 1515 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1516 pim_if_addr_del_all_igmp(ifp);
1517 }
1518
469351b3 1519 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1520 pim_if_addr_add_all(ifp);
1521 }
1522}
1523
1524static void clear_pim_interfaces()
1525{
1526 struct listnode *ifnode;
1527 struct listnode *ifnextnode;
1528 struct interface *ifp;
1529
469351b3 1530 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1531 if (ifp->info) {
1532 pim_neighbor_delete_all(ifp, "interface cleared");
1533 }
1534 }
1535}
1536
1537static void clear_interfaces()
1538{
1539 clear_igmp_interfaces();
1540 clear_pim_interfaces();
1541}
1542
12e41d03
DL
1543DEFUN (clear_ip_interfaces,
1544 clear_ip_interfaces_cmd,
1545 "clear ip interfaces",
1546 CLEAR_STR
1547 IP_STR
1548 "Reset interfaces\n")
1549{
1550 clear_interfaces();
1551
1552 return CMD_SUCCESS;
1553}
1554
1555DEFUN (clear_ip_igmp_interfaces,
1556 clear_ip_igmp_interfaces_cmd,
1557 "clear ip igmp interfaces",
1558 CLEAR_STR
1559 IP_STR
1560 CLEAR_IP_IGMP_STR
1561 "Reset IGMP interfaces\n")
1562{
1563 clear_igmp_interfaces();
1564
1565 return CMD_SUCCESS;
1566}
1567
1568static void mroute_add_all()
1569{
1570 struct listnode *node;
1571 struct channel_oil *c_oil;
1572
1573 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
c171d6d8 1574 if (pim_mroute_add(c_oil)) {
12e41d03
DL
1575 /* just log warning */
1576 char source_str[100];
1577 char group_str[100];
1578 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1579 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1580 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1581 __FILE__, __PRETTY_FUNCTION__,
1582 source_str, group_str);
1583 }
1584 }
1585}
1586
1587static void mroute_del_all()
1588{
1589 struct listnode *node;
1590 struct channel_oil *c_oil;
1591
1592 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
c171d6d8 1593 if (pim_mroute_del(c_oil)) {
12e41d03
DL
1594 /* just log warning */
1595 char source_str[100];
1596 char group_str[100];
1597 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1598 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1599 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1600 __FILE__, __PRETTY_FUNCTION__,
1601 source_str, group_str);
1602 }
1603 }
1604}
1605
6250610a
JAG
1606static void static_mroute_add_all()
1607{
1608 struct listnode *node;
1609 struct static_route *s_route;
1610
1611 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
c171d6d8 1612 if (pim_mroute_add(&s_route->c_oil)) {
6250610a
JAG
1613 /* just log warning */
1614 char source_str[100];
1615 char group_str[100];
9867746a
DS
1616 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
1617 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
6250610a
JAG
1618 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1619 __FILE__, __PRETTY_FUNCTION__,
1620 source_str, group_str);
1621 }
1622 }
1623}
1624
1625static void static_mroute_del_all()
1626{
1627 struct listnode *node;
1628 struct static_route *s_route;
1629
1630 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
c171d6d8 1631 if (pim_mroute_del(&s_route->c_oil)) {
6250610a
JAG
1632 /* just log warning */
1633 char source_str[100];
1634 char group_str[100];
9867746a
DS
1635 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
1636 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
6250610a
JAG
1637 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1638 __FILE__, __PRETTY_FUNCTION__,
1639 source_str, group_str);
1640 }
1641 }
1642}
1643
12e41d03
DL
1644DEFUN (clear_ip_mroute,
1645 clear_ip_mroute_cmd,
1646 "clear ip mroute",
1647 CLEAR_STR
1648 IP_STR
1649 "Reset multicast routes\n")
1650{
1651 mroute_del_all();
1652 mroute_add_all();
1653
1654 return CMD_SUCCESS;
1655}
1656
1657DEFUN (clear_ip_pim_interfaces,
1658 clear_ip_pim_interfaces_cmd,
1659 "clear ip pim interfaces",
1660 CLEAR_STR
1661 IP_STR
1662 CLEAR_IP_PIM_STR
1663 "Reset PIM interfaces\n")
1664{
1665 clear_pim_interfaces();
1666
1667 return CMD_SUCCESS;
1668}
1669
1670DEFUN (clear_ip_pim_oil,
1671 clear_ip_pim_oil_cmd,
1672 "clear ip pim oil",
1673 CLEAR_STR
1674 IP_STR
1675 CLEAR_IP_PIM_STR
1676 "Rescan PIM OIL (output interface list)\n")
1677{
1678 pim_scan_oil();
1679
1680 return CMD_SUCCESS;
1681}
1682
1683DEFUN (show_ip_igmp_interface,
1684 show_ip_igmp_interface_cmd,
1685 "show ip igmp interface",
1686 SHOW_STR
1687 IP_STR
1688 IGMP_STR
1689 "IGMP interface information\n")
1690{
1691 igmp_show_interfaces(vty);
1692
1693 return CMD_SUCCESS;
1694}
1695
1696DEFUN (show_ip_igmp_join,
1697 show_ip_igmp_join_cmd,
1698 "show ip igmp join",
1699 SHOW_STR
1700 IP_STR
1701 IGMP_STR
1702 "IGMP static join information\n")
1703{
1704 igmp_show_interface_join(vty);
1705
1706 return CMD_SUCCESS;
1707}
1708
1709DEFUN (show_ip_igmp_groups,
1710 show_ip_igmp_groups_cmd,
1711 "show ip igmp groups",
1712 SHOW_STR
1713 IP_STR
1714 IGMP_STR
1715 IGMP_GROUP_STR)
1716{
1717 igmp_show_groups(vty);
1718
1719 return CMD_SUCCESS;
1720}
1721
1722DEFUN (show_ip_igmp_groups_retransmissions,
1723 show_ip_igmp_groups_retransmissions_cmd,
1724 "show ip igmp groups retransmissions",
1725 SHOW_STR
1726 IP_STR
1727 IGMP_STR
1728 IGMP_GROUP_STR
1729 "IGMP group retransmissions\n")
1730{
1731 igmp_show_group_retransmission(vty);
1732
1733 return CMD_SUCCESS;
1734}
1735
1736DEFUN (show_ip_igmp_parameters,
1737 show_ip_igmp_parameters_cmd,
1738 "show ip igmp parameters",
1739 SHOW_STR
1740 IP_STR
1741 IGMP_STR
1742 "IGMP parameters information\n")
1743{
1744 igmp_show_parameters(vty);
1745
1746 return CMD_SUCCESS;
1747}
1748
1749DEFUN (show_ip_igmp_sources,
1750 show_ip_igmp_sources_cmd,
1751 "show ip igmp sources",
1752 SHOW_STR
1753 IP_STR
1754 IGMP_STR
1755 IGMP_SOURCE_STR)
1756{
1757 igmp_show_sources(vty);
1758
1759 return CMD_SUCCESS;
1760}
1761
1762DEFUN (show_ip_igmp_sources_retransmissions,
1763 show_ip_igmp_sources_retransmissions_cmd,
1764 "show ip igmp sources retransmissions",
1765 SHOW_STR
1766 IP_STR
1767 IGMP_STR
1768 IGMP_SOURCE_STR
1769 "IGMP source retransmissions\n")
1770{
1771 igmp_show_source_retransmission(vty);
1772
1773 return CMD_SUCCESS;
1774}
1775
1776DEFUN (show_ip_igmp_querier,
1777 show_ip_igmp_querier_cmd,
1778 "show ip igmp querier",
1779 SHOW_STR
1780 IP_STR
1781 IGMP_STR
1782 "IGMP querier information\n")
1783{
1784 igmp_show_querier(vty);
1785
1786 return CMD_SUCCESS;
1787}
1788
1789DEFUN (show_ip_pim_address,
1790 show_ip_pim_address_cmd,
1791 "show ip pim address",
1792 SHOW_STR
1793 IP_STR
1794 PIM_STR
1795 "PIM interface address\n")
1796{
1797 show_interface_address(vty);
1798
1799 return CMD_SUCCESS;
1800}
1801
1802DEFUN (show_ip_pim_assert,
1803 show_ip_pim_assert_cmd,
1804 "show ip pim assert",
1805 SHOW_STR
1806 IP_STR
1807 PIM_STR
1808 "PIM interface assert\n")
1809{
1810 pim_show_assert(vty);
1811
1812 return CMD_SUCCESS;
1813}
1814
1815DEFUN (show_ip_pim_assert_internal,
1816 show_ip_pim_assert_internal_cmd,
1817 "show ip pim assert-internal",
1818 SHOW_STR
1819 IP_STR
1820 PIM_STR
1821 "PIM interface internal assert state\n")
1822{
1823 pim_show_assert_internal(vty);
1824
1825 return CMD_SUCCESS;
1826}
1827
1828DEFUN (show_ip_pim_assert_metric,
1829 show_ip_pim_assert_metric_cmd,
1830 "show ip pim assert-metric",
1831 SHOW_STR
1832 IP_STR
1833 PIM_STR
1834 "PIM interface assert metric\n")
1835{
1836 pim_show_assert_metric(vty);
1837
1838 return CMD_SUCCESS;
1839}
1840
1841DEFUN (show_ip_pim_assert_winner_metric,
1842 show_ip_pim_assert_winner_metric_cmd,
1843 "show ip pim assert-winner-metric",
1844 SHOW_STR
1845 IP_STR
1846 PIM_STR
1847 "PIM interface assert winner metric\n")
1848{
1849 pim_show_assert_winner_metric(vty);
1850
1851 return CMD_SUCCESS;
1852}
1853
1854DEFUN (show_ip_pim_dr,
1855 show_ip_pim_dr_cmd,
1856 "show ip pim designated-router",
1857 SHOW_STR
1858 IP_STR
1859 PIM_STR
1860 "PIM interface designated router\n")
1861{
1862 pim_show_dr(vty);
1863
1864 return CMD_SUCCESS;
1865}
1866
1867DEFUN (show_ip_pim_hello,
1868 show_ip_pim_hello_cmd,
1869 "show ip pim hello",
1870 SHOW_STR
1871 IP_STR
1872 PIM_STR
1873 "PIM interface hello information\n")
1874{
1875 pim_show_hello(vty);
1876
1877 return CMD_SUCCESS;
1878}
1879
1880DEFUN (show_ip_pim_interface,
1881 show_ip_pim_interface_cmd,
1882 "show ip pim interface",
1883 SHOW_STR
1884 IP_STR
1885 PIM_STR
1886 "PIM interface information\n")
1887{
1888 pim_show_interfaces(vty);
1889
1890 return CMD_SUCCESS;
1891}
1892
1893DEFUN (show_ip_pim_join,
1894 show_ip_pim_join_cmd,
1895 "show ip pim join",
1896 SHOW_STR
1897 IP_STR
1898 PIM_STR
1899 "PIM interface join information\n")
1900{
1901 pim_show_join(vty);
1902
1903 return CMD_SUCCESS;
1904}
1905
1906DEFUN (show_ip_pim_lan_prune_delay,
1907 show_ip_pim_lan_prune_delay_cmd,
1908 "show ip pim lan-prune-delay",
1909 SHOW_STR
1910 IP_STR
1911 PIM_STR
1912 "PIM neighbors LAN prune delay parameters\n")
1913{
1914 pim_show_lan_prune_delay(vty);
1915
1916 return CMD_SUCCESS;
1917}
1918
1919DEFUN (show_ip_pim_local_membership,
1920 show_ip_pim_local_membership_cmd,
1921 "show ip pim local-membership",
1922 SHOW_STR
1923 IP_STR
1924 PIM_STR
1925 "PIM interface local-membership\n")
1926{
1927 pim_show_membership(vty);
1928
1929 return CMD_SUCCESS;
1930}
1931
1932DEFUN (show_ip_pim_jp_override_interval,
1933 show_ip_pim_jp_override_interval_cmd,
1934 "show ip pim jp-override-interval",
1935 SHOW_STR
1936 IP_STR
1937 PIM_STR
1938 "PIM interface J/P override interval\n")
1939{
1940 pim_show_jp_override_interval(vty);
1941
1942 return CMD_SUCCESS;
1943}
1944
1945DEFUN (show_ip_pim_neighbor,
1946 show_ip_pim_neighbor_cmd,
1947 "show ip pim neighbor",
1948 SHOW_STR
1949 IP_STR
1950 PIM_STR
1951 "PIM neighbor information\n")
1952{
1953 pim_show_neighbors(vty);
1954
1955 return CMD_SUCCESS;
1956}
1957
1958DEFUN (show_ip_pim_secondary,
1959 show_ip_pim_secondary_cmd,
1960 "show ip pim secondary",
1961 SHOW_STR
1962 IP_STR
1963 PIM_STR
1964 "PIM neighbor addresses\n")
1965{
1966 pim_show_neighbors_secondary(vty);
1967
1968 return CMD_SUCCESS;
1969}
1970
1971DEFUN (show_ip_pim_upstream,
1972 show_ip_pim_upstream_cmd,
1973 "show ip pim upstream",
1974 SHOW_STR
1975 IP_STR
1976 PIM_STR
1977 "PIM upstream information\n")
1978{
1979 pim_show_upstream(vty);
1980
1981 return CMD_SUCCESS;
1982}
1983
1984DEFUN (show_ip_pim_upstream_join_desired,
1985 show_ip_pim_upstream_join_desired_cmd,
1986 "show ip pim upstream-join-desired",
1987 SHOW_STR
1988 IP_STR
1989 PIM_STR
1990 "PIM upstream join-desired\n")
1991{
1992 pim_show_join_desired(vty);
1993
1994 return CMD_SUCCESS;
1995}
1996
1997DEFUN (show_ip_pim_upstream_rpf,
1998 show_ip_pim_upstream_rpf_cmd,
1999 "show ip pim upstream-rpf",
2000 SHOW_STR
2001 IP_STR
2002 PIM_STR
2003 "PIM upstream source rpf\n")
2004{
2005 pim_show_upstream_rpf(vty);
2006
2007 return CMD_SUCCESS;
2008}
2009
00d07c6f
DS
2010DEFUN (show_ip_pim_rp,
2011 show_ip_pim_rp_cmd,
2012 "show ip pim rp-info ",
2013 SHOW_STR
2014 IP_STR
2015 PIM_STR
2016 "PIM RP information\n")
2017{
2018 pim_rp_show_information (vty);
2019
2020 return CMD_SUCCESS;
2021}
2022
12e41d03
DL
2023DEFUN (show_ip_pim_rpf,
2024 show_ip_pim_rpf_cmd,
2025 "show ip pim rpf",
2026 SHOW_STR
2027 IP_STR
2028 PIM_STR
2029 "PIM cached source rpf information\n")
2030{
2031 pim_show_rpf(vty);
2032
2033 return CMD_SUCCESS;
2034}
2035
2036static void show_multicast_interfaces(struct vty *vty)
2037{
2038 struct listnode *node;
2039 struct interface *ifp;
2040
2041 vty_out(vty, "%s", VTY_NEWLINE);
2042
2043 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2044 VTY_NEWLINE);
2045
469351b3 2046 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
2047 struct pim_interface *pim_ifp;
2048 struct in_addr ifaddr;
2049 struct sioc_vif_req vreq;
2050
2051 pim_ifp = ifp->info;
2052
2053 if (!pim_ifp)
2054 continue;
2055
2056 memset(&vreq, 0, sizeof(vreq));
2057 vreq.vifi = pim_ifp->mroute_vif_index;
2058
2059 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
6c44fe22
DS
2060 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2061 (unsigned long)SIOCGETVIFCNT,
2062 ifp->name,
2063 pim_ifp->mroute_vif_index,
2064 errno,
2065 safe_strerror(errno),
2066 VTY_NEWLINE);
12e41d03
DL
2067 }
2068
2069 ifaddr = pim_ifp->primary_address;
2070
2071 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2072 ifp->name,
2073 inet_ntoa(ifaddr),
2074 ifp->ifindex,
2075 pim_ifp->mroute_vif_index,
ea8b7c71
RW
2076 (unsigned long) vreq.icount,
2077 (unsigned long) vreq.ocount,
2078 (unsigned long) vreq.ibytes,
2079 (unsigned long) vreq.obytes,
12e41d03
DL
2080 VTY_NEWLINE);
2081 }
2082}
2083
2084DEFUN (show_ip_multicast,
2085 show_ip_multicast_cmd,
2086 "show ip multicast",
2087 SHOW_STR
2088 IP_STR
2089 "Multicast global information\n")
2090{
2091 time_t now = pim_time_monotonic_sec();
2092
2093 if (PIM_MROUTE_IS_ENABLED) {
2094 char uptime[10];
2095
2096 vty_out(vty, "Mroute socket descriptor: %d%s",
2097 qpim_mroute_socket_fd,
2098 VTY_NEWLINE);
2099
2100 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
2101 vty_out(vty, "Mroute socket uptime: %s%s",
2102 uptime,
2103 VTY_NEWLINE);
2104 }
2105 else {
2106 vty_out(vty, "Multicast disabled%s",
2107 VTY_NEWLINE);
2108 }
2109
2110 vty_out(vty, "%s", VTY_NEWLINE);
2111 vty_out(vty, "Zclient update socket: ");
2112 if (qpim_zclient_update) {
2113 vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
2114 qpim_zclient_update->fail, VTY_NEWLINE);
2115 }
2116 else {
2117 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2118 }
05b0d0d0
DS
2119
2120 pim_zlookup_show_ip_multicast (vty);
12e41d03
DL
2121
2122 vty_out(vty, "%s", VTY_NEWLINE);
2123 vty_out(vty, "Current highest VifIndex: %d%s",
2124 qpim_mroute_oif_highest_vif_index,
2125 VTY_NEWLINE);
2126 vty_out(vty, "Maximum highest VifIndex: %d%s",
1865a44a 2127 PIM_MAX_USABLE_VIFS,
12e41d03
DL
2128 VTY_NEWLINE);
2129
2130 vty_out(vty, "%s", VTY_NEWLINE);
2131 vty_out(vty, "Upstream Join Timer: %d secs%s",
2132 qpim_t_periodic,
2133 VTY_NEWLINE);
2134 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
2135 PIM_JP_HOLDTIME,
2136 VTY_NEWLINE);
2137
2138 vty_out(vty, "%s", VTY_NEWLINE);
2139
2140 show_rpf_refresh_stats(vty, now);
2141
2142 vty_out(vty, "%s", VTY_NEWLINE);
2143
2144 show_scan_oil_stats(vty, now);
2145
2146 show_multicast_interfaces(vty);
2147
2148 return CMD_SUCCESS;
2149}
2150
2151static void show_mroute(struct vty *vty)
2152{
2153 struct listnode *node;
2154 struct channel_oil *c_oil;
6250610a 2155 struct static_route *s_route;
12e41d03
DL
2156 time_t now;
2157
0fba6e63 2158 vty_out(vty, "Proto: I=IGMP P=PIM S=STATIC O=SOURCE%s%s", VTY_NEWLINE, VTY_NEWLINE);
12e41d03
DL
2159
2160 vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
2161 VTY_NEWLINE);
2162
2163 now = pim_time_monotonic_sec();
2164
6250610a 2165 /* print list of PIM and IGMP routes */
12e41d03
DL
2166 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2167 char group_str[100];
2168 char source_str[100];
2169 int oif_vif_index;
2170
58302dc7
DS
2171 if (!c_oil->installed)
2172 continue;
2173
12e41d03
DL
2174 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2175 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2176
2177 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2178 struct interface *ifp_in;
2179 struct interface *ifp_out;
2180 char oif_uptime[10];
2181 int ttl;
2182 char proto[5];
2183
2184 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2185 if (ttl < 1)
2186 continue;
2187
2188 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
2189 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2190
2191 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
2192
2193 proto[0] = '\0';
2194 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2195 strcat(proto, "P");
2196 }
2197 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2198 strcat(proto, "I");
2199 }
0fba6e63
DS
2200 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) {
2201 strcat(proto, "O");
2202 }
12e41d03
DL
2203
2204 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2205 source_str,
2206 group_str,
2207 proto,
2208 ifp_in ? ifp_in->name : "<iif?>",
2209 c_oil->oil.mfcc_parent,
2210 ifp_out ? ifp_out->name : "<oif?>",
2211 oif_vif_index,
2212 ttl,
2213 oif_uptime,
2214 VTY_NEWLINE);
2215 }
2216 }
6250610a
JAG
2217
2218 /* Print list of static routes */
2219 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2220 char group_str[100];
2221 char source_str[100];
2222 int oif_vif_index;
2223
58302dc7
DS
2224 if (!s_route->c_oil.installed)
2225 continue;
2226
6250610a
JAG
2227 pim_inet4_dump("<group?>", s_route->group, group_str, sizeof(group_str));
2228 pim_inet4_dump("<source?>", s_route->source, source_str, sizeof(source_str));
2229
2230 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2231 struct interface *ifp_in;
2232 struct interface *ifp_out;
2233 char oif_uptime[10];
2234 int ttl;
2235 char proto[5];
2236
2237 ttl = s_route->oif_ttls[oif_vif_index];
2238 if (ttl < 1)
2239 continue;
2240
2241 ifp_in = pim_if_find_by_vif_index(s_route->iif);
2242 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2243
9867746a 2244 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->c_oil.oif_creation[oif_vif_index]);
6250610a
JAG
2245
2246 proto[0] = '\0';
2247 strcat(proto, "S");
2248
2249 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2250 source_str,
2251 group_str,
2252 proto,
2253 ifp_in ? ifp_in->name : "<iif?>",
2254 s_route->iif,
2255 ifp_out ? ifp_out->name : "<oif?>",
2256 oif_vif_index,
2257 ttl,
2258 oif_uptime,
2259 VTY_NEWLINE);
2260 }
2261 }
12e41d03
DL
2262}
2263
2264DEFUN (show_ip_mroute,
2265 show_ip_mroute_cmd,
2266 "show ip mroute",
2267 SHOW_STR
2268 IP_STR
2269 MROUTE_STR)
2270{
2271 show_mroute(vty);
2272 return CMD_SUCCESS;
2273}
2274
2275static void show_mroute_count(struct vty *vty)
2276{
2277 struct listnode *node;
2278 struct channel_oil *c_oil;
6250610a 2279 struct static_route *s_route;
12e41d03
DL
2280
2281 vty_out(vty, "%s", VTY_NEWLINE);
2282
2283 vty_out(vty, "Source Group Packets Bytes WrongIf %s",
2284 VTY_NEWLINE);
2285
6250610a 2286 /* Print PIM and IGMP route counts */
12e41d03
DL
2287 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2288 char group_str[100];
2289 char source_str[100];
12e41d03 2290
58302dc7
DS
2291 if (!c_oil->installed)
2292 continue;
2293
3667e8a0 2294 pim_mroute_update_counters (c_oil);
12e41d03
DL
2295
2296 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2297 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2298
12e41d03
DL
2299 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2300 source_str,
2301 group_str,
3667e8a0
DS
2302 c_oil->cc.pktcnt,
2303 c_oil->cc.bytecnt,
2304 c_oil->cc.wrong_if,
12e41d03 2305 VTY_NEWLINE);
6250610a
JAG
2306 }
2307
2308 /* Print static route counts */
2309 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2310 char group_str[100];
2311 char source_str[100];
6250610a 2312
58302dc7
DS
2313 if (!s_route->c_oil.installed)
2314 continue;
2315
3667e8a0 2316 pim_mroute_update_counters (&s_route->c_oil);
6250610a 2317
9867746a
DS
2318 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2319 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
6250610a 2320
6250610a
JAG
2321 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2322 source_str,
2323 group_str,
3667e8a0
DS
2324 s_route->c_oil.cc.pktcnt,
2325 s_route->c_oil.cc.bytecnt,
2326 s_route->c_oil.cc.wrong_if,
6250610a 2327 VTY_NEWLINE);
12e41d03
DL
2328 }
2329}
2330
2331DEFUN (show_ip_mroute_count,
2332 show_ip_mroute_count_cmd,
2333 "show ip mroute count",
2334 SHOW_STR
2335 IP_STR
2336 MROUTE_STR
2337 "Route and packet count data\n")
2338{
2339 show_mroute_count(vty);
2340 return CMD_SUCCESS;
2341}
2342
2343DEFUN (show_ip_rib,
2344 show_ip_rib_cmd,
2345 "show ip rib A.B.C.D",
2346 SHOW_STR
2347 IP_STR
2348 RIB_STR
2349 "Unicast address\n")
2350{
b181fa04 2351 int idx_ipv4 = 3;
12e41d03
DL
2352 struct in_addr addr;
2353 const char *addr_str;
2354 struct pim_nexthop nexthop;
2355 char nexthop_addr_str[100];
2356 int result;
2357
b181fa04 2358 addr_str = argv[idx_ipv4]->arg;
12e41d03
DL
2359 result = inet_pton(AF_INET, addr_str, &addr);
2360 if (result <= 0) {
2361 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
2362 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
2363 return CMD_WARNING;
2364 }
2365
f24405b1 2366 if (pim_nexthop_lookup(&nexthop, addr)) {
12e41d03
DL
2367 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
2368 addr_str, VTY_NEWLINE);
2369 return CMD_WARNING;
2370 }
2371
2372 vty_out(vty, "Address NextHop Interface Metric Preference%s",
2373 VTY_NEWLINE);
2374
63c59d0c
DS
2375 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
2376 nexthop_addr_str, sizeof(nexthop_addr_str));
12e41d03
DL
2377
2378 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
2379 addr_str,
2380 nexthop_addr_str,
2381 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2382 nexthop.mrib_route_metric,
2383 nexthop.mrib_metric_preference,
2384 VTY_NEWLINE);
2385
2386 return CMD_SUCCESS;
2387}
2388
2389static void show_ssmpingd(struct vty *vty)
2390{
2391 struct listnode *node;
2392 struct ssmpingd_sock *ss;
2393 time_t now;
2394
2395 vty_out(vty, "Source Socket Address Port Uptime Requests%s",
2396 VTY_NEWLINE);
2397
2398 if (!qpim_ssmpingd_list)
2399 return;
2400
2401 now = pim_time_monotonic_sec();
2402
2403 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
2404 char source_str[100];
2405 char ss_uptime[10];
2406 struct sockaddr_in bind_addr;
2407 socklen_t len = sizeof(bind_addr);
2408 char bind_addr_str[100];
2409
2410 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
2411
2412 if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
2413 vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
2414 source_str, ss->sock_fd, VTY_NEWLINE);
2415 }
2416
2417 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
2418 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
2419
2420 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
2421 source_str,
2422 ss->sock_fd,
2423 bind_addr_str,
2424 ntohs(bind_addr.sin_port),
2425 ss_uptime,
2426 (long long)ss->requests,
2427 VTY_NEWLINE);
2428 }
2429}
2430
2431DEFUN (show_ip_ssmpingd,
2432 show_ip_ssmpingd_cmd,
2433 "show ip ssmpingd",
2434 SHOW_STR
2435 IP_STR
2436 SHOW_SSMPINGD_STR)
2437{
2438 show_ssmpingd(vty);
2439 return CMD_SUCCESS;
2440}
2441
36d6bd7d 2442static int
dfe43e25 2443pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const char *plist)
36d6bd7d
DS
2444{
2445 int result;
36d6bd7d 2446
dfe43e25
DW
2447 result = pim_rp_new (rp, group, plist);
2448
2449 if (result == PIM_MALLOC_FAIL)
2450 {
2451 vty_out (vty, "%% Out of memory%s", VTY_NEWLINE);
2452 return CMD_WARNING;
2453 }
2454
2455 if (result == PIM_GROUP_BAD_ADDRESS)
2456 {
2457 vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
2458 return CMD_WARNING;
2459 }
2460
2461 if (result == PIM_RP_BAD_ADDRESS)
36d6bd7d 2462 {
dfe43e25 2463 vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
36d6bd7d
DS
2464 return CMD_WARNING;
2465 }
2466
dfe43e25 2467 if (result == PIM_RP_NO_PATH)
36d6bd7d 2468 {
dfe43e25
DW
2469 vty_out (vty, "%% No Path to RP address specified: %s%s", rp, VTY_NEWLINE);
2470 return CMD_WARNING;
2471 }
2472
2473 if (result == PIM_GROUP_OVERLAP)
2474 {
2475 vty_out (vty, "%% Group range specified cannot overlap%s", VTY_NEWLINE);
2476 return CMD_WARNING;
2477 }
2478
2479 if (result == PIM_GROUP_PFXLIST_OVERLAP)
2480 {
2481 vty_out (vty, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE);
2482 return CMD_WARNING;
36d6bd7d
DS
2483 }
2484
dfe43e25 2485 if (result == PIM_RP_PFXLIST_IN_USE)
36d6bd7d 2486 {
dfe43e25
DW
2487 vty_out (vty, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE);
2488 return CMD_WARNING;
36d6bd7d
DS
2489 }
2490
2491 return CMD_SUCCESS;
2492}
2493
4304f95c
DS
2494DEFUN (ip_pim_keep_alive,
2495 ip_pim_keep_alive_cmd,
e8e277d5 2496 "ip pim keep-alive-timer <31-60000>",
4304f95c
DS
2497 IP_STR
2498 "pim multicast routing\n"
2499 "Keep alive Timer"
2500 "Seconds")
2501{
2502 qpim_keep_alive_time = atoi (argv[3]->arg);
2503 return CMD_SUCCESS;
2504}
2505
2506DEFUN (no_ip_pim_keep_alive,
2507 no_ip_pim_keep_alive_cmd,
e8e277d5 2508 "no ip pim keep-alive-timer <31-60000>",
4304f95c
DS
2509 NO_STR
2510 IP_STR
2511 "pim multicast routing\n"
01408ede
DS
2512 "Keep alive Timer\n"
2513 "Seconds\n")
4304f95c
DS
2514{
2515 qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
2516 return CMD_SUCCESS;
2517}
2518
01408ede
DS
2519DEFUN (ip_pim_rp_keep_alive,
2520 ip_pim_rp_keep_alive_cmd,
e8e277d5 2521 "ip pim rp keep-alive-timer <31-60000>",
01408ede
DS
2522 IP_STR
2523 "pim multicast routing\n"
2524 "Rendevous Point\n"
2525 "Keep alive Timer\n"
2526 "Seconds\n")
2527{
2528 qpim_rp_keep_alive_time = atoi (argv[4]->arg);
2529 return CMD_SUCCESS;
2530}
2531
2532DEFUN (no_ip_pim_rp_keep_alive,
2533 no_ip_pim_rp_keep_alive_cmd,
e8e277d5 2534 "no ip pim rp keep-alive-timer <31-60000>",
01408ede
DS
2535 NO_STR
2536 IP_STR
2537 "pim multicast routing\n"
2538 "Rendevous Point\n"
2539 "Keep alive Timer\n"
2540 "Seconds\n")
2541{
2542 qpim_rp_keep_alive_time = PIM_RP_KEEPALIVE_PERIOD;
2543 return CMD_SUCCESS;
2544}
2545
981d6c7a
DS
2546DEFUN (ip_pim_rp,
2547 ip_pim_rp_cmd,
75a26779 2548 "ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a 2549 IP_STR
9b34069d
QY
2550 "pim multicast routing\n"
2551 "Rendevous Point\n"
2552 "ip address of RP\n")
981d6c7a 2553{
b181fa04 2554 int idx_ipv4 = 3;
dfe43e25
DW
2555 return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
2556}
2557
2558DEFUN (ip_pim_rp_prefix_list,
2559 ip_pim_rp_prefix_list_cmd,
2560 "ip pim rp A.B.C.D prefix-list WORD",
2561 IP_STR
2562 "pim multicast routing\n"
2563 "Rendevous Point\n"
2564 "ip address of RP\n"
2565 "group prefix-list filter\n"
2566 "Name of a prefix-list\n")
2567{
2568 return pim_rp_cmd_worker (vty, argv[3]->arg, NULL, argv[5]->arg);
36d6bd7d 2569}
981d6c7a 2570
36d6bd7d 2571static int
dfe43e25
DW
2572pim_no_rp_cmd_worker (struct vty *vty, const char *rp, const char *group,
2573 const char *plist)
36d6bd7d 2574{
dfe43e25
DW
2575 int result = pim_rp_del (rp, group, plist);
2576
2577 if (result == PIM_GROUP_BAD_ADDRESS)
2578 {
2579 vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
2580 return CMD_WARNING;
2581 }
75a26779 2582
dfe43e25 2583 if (result == PIM_RP_BAD_ADDRESS)
75a26779 2584 {
dfe43e25 2585 vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
36d6bd7d 2586 return CMD_WARNING;
75a26779 2587 }
981d6c7a 2588
dfe43e25 2589 if (result == PIM_RP_NOT_FOUND)
13afbd05 2590 {
dfe43e25 2591 vty_out (vty, "%% Unable to find specified RP%s", VTY_NEWLINE);
13afbd05
DS
2592 return CMD_WARNING;
2593 }
c8ae3ce8 2594
981d6c7a
DS
2595 return CMD_SUCCESS;
2596}
2597
2598DEFUN (no_ip_pim_rp,
2599 no_ip_pim_rp_cmd,
75a26779 2600 "no ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a
DS
2601 NO_STR
2602 IP_STR
9b34069d
QY
2603 "pim multicast routing\n"
2604 "Rendevous Point\n"
2605 "ip address of RP\n")
981d6c7a 2606{
75a26779 2607 int idx_ipv4 = 4;
dfe43e25
DW
2608 return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
2609}
2610
2611DEFUN (no_ip_pim_rp_prefix_list,
2612 no_ip_pim_rp_prefix_list_cmd,
2613 "no ip pim rp A.B.C.D prefix-list WORD",
2614 NO_STR
2615 IP_STR
2616 "pim multicast routing\n"
2617 "Rendevous Point\n"
2618 "ip address of RP\n"
2619 "group prefix-list filter\n"
2620 "Name of a prefix-list\n")
2621{
2622 return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
981d6c7a
DS
2623}
2624
12e41d03
DL
2625DEFUN (ip_multicast_routing,
2626 ip_multicast_routing_cmd,
9ccf14f7 2627 "ip multicast-routing",
12e41d03
DL
2628 IP_STR
2629 "Enable IP multicast forwarding\n")
2630{
2631 pim_mroute_socket_enable();
2632 pim_if_add_vif_all();
2633 mroute_add_all();
6250610a 2634 static_mroute_add_all();
12e41d03
DL
2635 return CMD_SUCCESS;
2636}
2637
2638DEFUN (no_ip_multicast_routing,
2639 no_ip_multicast_routing_cmd,
9ccf14f7 2640 "no ip multicast-routing",
12e41d03
DL
2641 NO_STR
2642 IP_STR
2643 "Global IP configuration subcommands\n"
2644 "Enable IP multicast forwarding\n")
2645{
2646 mroute_del_all();
6250610a 2647 static_mroute_del_all();
12e41d03
DL
2648 pim_if_del_vif_all();
2649 pim_mroute_socket_disable();
2650 return CMD_SUCCESS;
2651}
2652
2653DEFUN (ip_ssmpingd,
2654 ip_ssmpingd_cmd,
2655 "ip ssmpingd [A.B.C.D]",
2656 IP_STR
2657 CONF_SSMPINGD_STR
2658 "Source address\n")
2659{
b181fa04 2660 int idx_ipv4 = 2;
12e41d03
DL
2661 int result;
2662 struct in_addr source_addr;
abddf075 2663 const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03
DL
2664
2665 result = inet_pton(AF_INET, source_str, &source_addr);
2666 if (result <= 0) {
2667 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2668 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2669 return CMD_WARNING;
2670 }
2671
2672 result = pim_ssmpingd_start(source_addr);
2673 if (result) {
2674 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
2675 source_str, result, VTY_NEWLINE);
2676 return CMD_WARNING;
2677 }
2678
2679 return CMD_SUCCESS;
2680}
2681
2682DEFUN (no_ip_ssmpingd,
2683 no_ip_ssmpingd_cmd,
2684 "no ip ssmpingd [A.B.C.D]",
2685 NO_STR
2686 IP_STR
2687 CONF_SSMPINGD_STR
2688 "Source address\n")
2689{
b181fa04 2690 int idx_ipv4 = 3;
12e41d03
DL
2691 int result;
2692 struct in_addr source_addr;
abddf075 2693 const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03
DL
2694
2695 result = inet_pton(AF_INET, source_str, &source_addr);
2696 if (result <= 0) {
2697 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2698 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2699 return CMD_WARNING;
2700 }
2701
2702 result = pim_ssmpingd_stop(source_addr);
2703 if (result) {
2704 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
2705 source_str, result, VTY_NEWLINE);
2706 return CMD_WARNING;
2707 }
2708
2709 return CMD_SUCCESS;
2710}
2711
2712DEFUN (interface_ip_igmp,
2713 interface_ip_igmp_cmd,
2714 "ip igmp",
2715 IP_STR
2716 IFACE_IGMP_STR)
2717{
cdc2d765 2718 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
2719 struct pim_interface *pim_ifp;
2720
12e41d03
DL
2721 pim_ifp = ifp->info;
2722
2723 if (!pim_ifp) {
2724 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2725 if (!pim_ifp) {
2726 vty_out(vty, "Could not enable IGMP on interface %s%s",
2727 ifp->name, VTY_NEWLINE);
2728 return CMD_WARNING;
2729 }
2730 }
2731 else {
2732 PIM_IF_DO_IGMP(pim_ifp->options);
2733 }
2734
2735 pim_if_addr_add_all(ifp);
2736 pim_if_membership_refresh(ifp);
2737
2738 return CMD_SUCCESS;
2739}
2740
2741DEFUN (interface_no_ip_igmp,
2742 interface_no_ip_igmp_cmd,
2743 "no ip igmp",
2744 NO_STR
2745 IP_STR
2746 IFACE_IGMP_STR)
2747{
cdc2d765 2748 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
2749 struct pim_interface *pim_ifp;
2750
12e41d03
DL
2751 pim_ifp = ifp->info;
2752 if (!pim_ifp)
2753 return CMD_SUCCESS;
2754
2755 PIM_IF_DONT_IGMP(pim_ifp->options);
2756
2757 pim_if_membership_clear(ifp);
2758
2759 pim_if_addr_del_all_igmp(ifp);
2760
2761 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2762 pim_if_delete(ifp);
2763 }
2764
2765 return CMD_SUCCESS;
2766}
2767
2768DEFUN (interface_ip_igmp_join,
2769 interface_ip_igmp_join_cmd,
2770 "ip igmp join A.B.C.D A.B.C.D",
2771 IP_STR
2772 IFACE_IGMP_STR
2773 "IGMP join multicast group\n"
2774 "Multicast group address\n"
2775 "Source address\n")
2776{
cdc2d765 2777 VTY_DECLVAR_CONTEXT(interface, ifp);
b181fa04
DW
2778 int idx_ipv4 = 3;
2779 int idx_ipv4_2 = 4;
12e41d03
DL
2780 const char *group_str;
2781 const char *source_str;
2782 struct in_addr group_addr;
2783 struct in_addr source_addr;
2784 int result;
2785
12e41d03 2786 /* Group address */
b181fa04 2787 group_str = argv[idx_ipv4]->arg;
12e41d03
DL
2788 result = inet_pton(AF_INET, group_str, &group_addr);
2789 if (result <= 0) {
2790 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2791 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2792 return CMD_WARNING;
2793 }
2794
2795 /* Source address */
b181fa04 2796 source_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
2797 result = inet_pton(AF_INET, source_str, &source_addr);
2798 if (result <= 0) {
2799 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2800 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2801 return CMD_WARNING;
2802 }
2803
2804 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2805 if (result) {
2806 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2807 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2808 return CMD_WARNING;
2809 }
2810
2811 return CMD_SUCCESS;
2812}
2813
2814DEFUN (interface_no_ip_igmp_join,
2815 interface_no_ip_igmp_join_cmd,
2816 "no ip igmp join A.B.C.D A.B.C.D",
2817 NO_STR
2818 IP_STR
2819 IFACE_IGMP_STR
2820 "IGMP join multicast group\n"
2821 "Multicast group address\n"
2822 "Source address\n")
2823{
cdc2d765 2824 VTY_DECLVAR_CONTEXT(interface, ifp);
b181fa04
DW
2825 int idx_ipv4 = 4;
2826 int idx_ipv4_2 = 5;
12e41d03
DL
2827 const char *group_str;
2828 const char *source_str;
2829 struct in_addr group_addr;
2830 struct in_addr source_addr;
2831 int result;
2832
12e41d03 2833 /* Group address */
b181fa04 2834 group_str = argv[idx_ipv4]->arg;
12e41d03
DL
2835 result = inet_pton(AF_INET, group_str, &group_addr);
2836 if (result <= 0) {
2837 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2838 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2839 return CMD_WARNING;
2840 }
2841
2842 /* Source address */
b181fa04 2843 source_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
2844 result = inet_pton(AF_INET, source_str, &source_addr);
2845 if (result <= 0) {
2846 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2847 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2848 return CMD_WARNING;
2849 }
2850
2851 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2852 if (result) {
2853 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2854 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2855 return CMD_WARNING;
2856 }
2857
2858 return CMD_SUCCESS;
2859}
2860
2861/*
2862 CLI reconfiguration affects the interface level (struct pim_interface).
2863 This function propagates the reconfiguration to every active socket
2864 for that interface.
2865 */
2866static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2867{
2868 struct interface *ifp;
2869 struct pim_interface *pim_ifp;
2870
2871 zassert(igmp);
2872
2873 /* other querier present? */
2874
2875 if (igmp->t_other_querier_timer)
2876 return;
2877
2878 /* this is the querier */
2879
2880 zassert(igmp->interface);
2881 zassert(igmp->interface->info);
2882
2883 ifp = igmp->interface;
2884 pim_ifp = ifp->info;
2885
2886 if (PIM_DEBUG_IGMP_TRACE) {
2887 char ifaddr_str[100];
2888 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2889 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2890 __PRETTY_FUNCTION__,
2891 ifaddr_str,
2892 ifp->name,
2893 pim_ifp->igmp_default_query_interval);
2894 }
2895
2896 /*
2897 igmp_startup_mode_on() will reset QQI:
2898
2899 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2900 */
2901 igmp_startup_mode_on(igmp);
2902}
2903
2904static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2905{
2906 if (igmp->t_igmp_query_timer) {
2907 /* other querier present */
2908 zassert(igmp->t_igmp_query_timer);
2909 zassert(!igmp->t_other_querier_timer);
2910
2911 pim_igmp_general_query_off(igmp);
2912 pim_igmp_general_query_on(igmp);
2913
2914 zassert(igmp->t_igmp_query_timer);
2915 zassert(!igmp->t_other_querier_timer);
2916 }
2917 else {
2918 /* this is the querier */
2919
2920 zassert(!igmp->t_igmp_query_timer);
2921 zassert(igmp->t_other_querier_timer);
2922
2923 pim_igmp_other_querier_timer_off(igmp);
2924 pim_igmp_other_querier_timer_on(igmp);
2925
2926 zassert(!igmp->t_igmp_query_timer);
2927 zassert(igmp->t_other_querier_timer);
2928 }
2929}
2930
2931static void change_query_interval(struct pim_interface *pim_ifp,
2932 int query_interval)
2933{
2934 struct listnode *sock_node;
2935 struct igmp_sock *igmp;
2936
2937 pim_ifp->igmp_default_query_interval = query_interval;
2938
2939 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2940 igmp_sock_query_interval_reconfig(igmp);
2941 igmp_sock_query_reschedule(igmp);
2942 }
2943}
2944
2945static void change_query_max_response_time(struct pim_interface *pim_ifp,
2946 int query_max_response_time_dsec)
2947{
2948 struct listnode *sock_node;
2949 struct igmp_sock *igmp;
2950
2951 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2952
2953 /*
2954 Below we modify socket/group/source timers in order to quickly
2955 reflect the change. Otherwise, those timers would eventually catch
2956 up.
2957 */
2958
2959 /* scan all sockets */
2960 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2961 struct listnode *grp_node;
2962 struct igmp_group *grp;
2963
2964 /* reschedule socket general query */
2965 igmp_sock_query_reschedule(igmp);
2966
2967 /* scan socket groups */
2968 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2969 struct listnode *src_node;
2970 struct igmp_source *src;
2971
2972 /* reset group timers for groups in EXCLUDE mode */
2973 if (grp->group_filtermode_isexcl) {
2974 igmp_group_reset_gmi(grp);
2975 }
2976
2977 /* scan group sources */
2978 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2979
2980 /* reset source timers for sources with running timers */
2981 if (src->t_source_timer) {
2982 igmp_source_reset_gmi(igmp, grp, src);
2983 }
2984 }
2985 }
2986 }
2987}
2988
2989#define IGMP_QUERY_INTERVAL_MIN (1)
2990#define IGMP_QUERY_INTERVAL_MAX (1800)
2991
2992DEFUN (interface_ip_igmp_query_interval,
2993 interface_ip_igmp_query_interval_cmd,
9ccf14f7 2994 "ip igmp query-interval (1-1800)",
12e41d03
DL
2995 IP_STR
2996 IFACE_IGMP_STR
2997 IFACE_IGMP_QUERY_INTERVAL_STR
2998 "Query interval in seconds\n")
2999{
cdc2d765 3000 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3001 struct pim_interface *pim_ifp;
3002 int query_interval;
3003 int query_interval_dsec;
3004
12e41d03
DL
3005 pim_ifp = ifp->info;
3006
3007 if (!pim_ifp) {
3008 vty_out(vty,
3009 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3010 ifp->name,
3011 VTY_NEWLINE);
3012 return CMD_WARNING;
3013 }
3014
91ac1d43 3015 query_interval = atoi(argv[4]->arg);
12e41d03
DL
3016 query_interval_dsec = 10 * query_interval;
3017
3018 /*
3019 It seems we don't need to check bounds since command.c does it
3020 already, but we verify them anyway for extra safety.
3021 */
3022 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
3023 vty_out(vty, "General query interval %d lower than minimum %d%s",
3024 query_interval,
3025 IGMP_QUERY_INTERVAL_MIN,
3026 VTY_NEWLINE);
3027 return CMD_WARNING;
3028 }
3029 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
3030 vty_out(vty, "General query interval %d higher than maximum %d%s",
3031 query_interval,
3032 IGMP_QUERY_INTERVAL_MAX,
3033 VTY_NEWLINE);
3034 return CMD_WARNING;
3035 }
3036
3037 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
3038 vty_out(vty,
3039 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
3040 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
3041 VTY_NEWLINE);
3042 return CMD_WARNING;
3043 }
3044
3045 change_query_interval(pim_ifp, query_interval);
3046
3047 return CMD_SUCCESS;
3048}
3049
3050DEFUN (interface_no_ip_igmp_query_interval,
3051 interface_no_ip_igmp_query_interval_cmd,
9ccf14f7 3052 "no ip igmp query-interval",
12e41d03
DL
3053 NO_STR
3054 IP_STR
3055 IFACE_IGMP_STR
3056 IFACE_IGMP_QUERY_INTERVAL_STR)
3057{
cdc2d765 3058 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3059 struct pim_interface *pim_ifp;
3060 int default_query_interval_dsec;
3061
12e41d03
DL
3062 pim_ifp = ifp->info;
3063
3064 if (!pim_ifp)
3065 return CMD_SUCCESS;
3066
3067 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
3068
3069 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
3070 vty_out(vty,
3071 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
3072 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
3073 VTY_NEWLINE);
3074 return CMD_WARNING;
3075 }
3076
3077 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
3078
3079 return CMD_SUCCESS;
3080}
3081
3082#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
3083#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
3084
3085DEFUN (interface_ip_igmp_query_max_response_time,
3086 interface_ip_igmp_query_max_response_time_cmd,
9ccf14f7 3087 "ip igmp query-max-response-time (1-25)",
12e41d03
DL
3088 IP_STR
3089 IFACE_IGMP_STR
3090 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
3091 "Query response value in seconds\n")
3092{
cdc2d765 3093 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3094 struct pim_interface *pim_ifp;
3095 int query_max_response_time;
3096
12e41d03
DL
3097 pim_ifp = ifp->info;
3098
3099 if (!pim_ifp) {
3100 vty_out(vty,
3101 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3102 ifp->name,
3103 VTY_NEWLINE);
3104 return CMD_WARNING;
3105 }
3106
91ac1d43 3107 query_max_response_time = atoi(argv[4]->arg);
12e41d03
DL
3108
3109 /*
3110 It seems we don't need to check bounds since command.c does it
3111 already, but we verify them anyway for extra safety.
3112 */
3113 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
3114 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
3115 query_max_response_time,
3116 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
3117 VTY_NEWLINE);
3118 return CMD_WARNING;
3119 }
3120 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
3121 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
3122 query_max_response_time,
3123 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
3124 VTY_NEWLINE);
3125 return CMD_WARNING;
3126 }
3127
3128 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
3129 vty_out(vty,
3130 "Can't set query max response time %d sec >= general query interval %d sec%s",
3131 query_max_response_time, pim_ifp->igmp_default_query_interval,
3132 VTY_NEWLINE);
3133 return CMD_WARNING;
3134 }
3135
3136 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
3137
3138 return CMD_SUCCESS;
3139}
3140
3141DEFUN (interface_no_ip_igmp_query_max_response_time,
3142 interface_no_ip_igmp_query_max_response_time_cmd,
9ccf14f7 3143 "no ip igmp query-max-response-time",
12e41d03
DL
3144 NO_STR
3145 IP_STR
3146 IFACE_IGMP_STR
3147 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
3148{
cdc2d765 3149 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3150 struct pim_interface *pim_ifp;
3151 int default_query_interval_dsec;
3152
12e41d03
DL
3153 pim_ifp = ifp->info;
3154
3155 if (!pim_ifp)
3156 return CMD_SUCCESS;
3157
3158 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3159
3160 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3161 vty_out(vty,
3162 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3163 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3164 VTY_NEWLINE);
3165 return CMD_WARNING;
3166 }
3167
3168 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3169
3170 return CMD_SUCCESS;
3171}
3172
3173#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
3174#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
3175
3176DEFUN (interface_ip_igmp_query_max_response_time_dsec,
3177 interface_ip_igmp_query_max_response_time_dsec_cmd,
9ccf14f7 3178 "ip igmp query-max-response-time-dsec (10-250)",
12e41d03
DL
3179 IP_STR
3180 IFACE_IGMP_STR
3181 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3182 "Query response value in deciseconds\n")
3183{
cdc2d765 3184 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3185 struct pim_interface *pim_ifp;
3186 int query_max_response_time_dsec;
3187 int default_query_interval_dsec;
3188
12e41d03
DL
3189 pim_ifp = ifp->info;
3190
3191 if (!pim_ifp) {
3192 vty_out(vty,
3193 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3194 ifp->name,
3195 VTY_NEWLINE);
3196 return CMD_WARNING;
3197 }
3198
91ac1d43 3199 query_max_response_time_dsec = atoi(argv[4]->arg);
12e41d03
DL
3200
3201 /*
3202 It seems we don't need to check bounds since command.c does it
3203 already, but we verify them anyway for extra safety.
3204 */
3205 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
3206 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
3207 query_max_response_time_dsec,
3208 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
3209 VTY_NEWLINE);
3210 return CMD_WARNING;
3211 }
3212 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
3213 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
3214 query_max_response_time_dsec,
3215 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
3216 VTY_NEWLINE);
3217 return CMD_WARNING;
3218 }
3219
3220 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3221
3222 if (query_max_response_time_dsec >= default_query_interval_dsec) {
3223 vty_out(vty,
3224 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
3225 query_max_response_time_dsec, default_query_interval_dsec,
3226 VTY_NEWLINE);
3227 return CMD_WARNING;
3228 }
3229
3230 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
3231
3232 return CMD_SUCCESS;
3233}
3234
3235DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
3236 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
9ccf14f7 3237 "no ip igmp query-max-response-time-dsec",
12e41d03
DL
3238 NO_STR
3239 IP_STR
3240 IFACE_IGMP_STR
3241 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
3242{
cdc2d765 3243 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3244 struct pim_interface *pim_ifp;
3245 int default_query_interval_dsec;
3246
12e41d03
DL
3247 pim_ifp = ifp->info;
3248
3249 if (!pim_ifp)
3250 return CMD_SUCCESS;
3251
3252 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3253
3254 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3255 vty_out(vty,
3256 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3257 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3258 VTY_NEWLINE);
3259 return CMD_WARNING;
3260 }
3261
3262 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3263
3264 return CMD_SUCCESS;
3265}
3266
dedccda6
DS
3267DEFUN (interface_ip_pim_drprio,
3268 interface_ip_pim_drprio_cmd,
b181fa04 3269 "ip pim drpriority (1-4294967295)",
dedccda6
DS
3270 IP_STR
3271 PIM_STR
3272 "Set the Designated Router Election Priority\n"
3273 "Value of the new DR Priority\n")
3274{
cdc2d765 3275 VTY_DECLVAR_CONTEXT(interface, ifp);
b181fa04 3276 int idx_number = 3;
dedccda6
DS
3277 struct pim_interface *pim_ifp;
3278 uint32_t old_dr_prio;
3279
dedccda6
DS
3280 pim_ifp = ifp->info;
3281
3282 if (!pim_ifp) {
3283 vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
3284 return CMD_WARNING;
3285 }
3286
3287 old_dr_prio = pim_ifp->pim_dr_priority;
3288
b181fa04 3289 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
dedccda6
DS
3290
3291 if (old_dr_prio != pim_ifp->pim_dr_priority) {
3292 if (pim_if_dr_election(ifp))
3293 pim_hello_restart_now(ifp);
3294 }
3295
3296 return CMD_SUCCESS;
3297}
3298
3299DEFUN (interface_no_ip_pim_drprio,
3300 interface_no_ip_pim_drprio_cmd,
b181fa04 3301 "no ip pim drpriority [(1-4294967295)]",
d7fa34c1 3302 NO_STR
dedccda6
DS
3303 IP_STR
3304 PIM_STR
3305 "Revert the Designated Router Priority to default\n"
3306 "Old Value of the Priority\n")
3307{
cdc2d765 3308 VTY_DECLVAR_CONTEXT(interface, ifp);
dedccda6
DS
3309 struct pim_interface *pim_ifp;
3310
dedccda6
DS
3311 pim_ifp = ifp->info;
3312
3313 if (!pim_ifp) {
7960fa8f 3314 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
dedccda6
DS
3315 return CMD_WARNING;
3316 }
3317
3318 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
3319 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
3320 if (pim_if_dr_election(ifp))
3321 pim_hello_restart_now(ifp);
3322 }
3323
3324 return CMD_SUCCESS;
3325}
3326
981d6c7a
DS
3327static int
3328pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
12e41d03 3329{
981d6c7a 3330 struct pim_interface *pim_ifp = ifp->info;
a920d6e7 3331 struct in_addr null = { .s_addr = 0 };
12e41d03
DL
3332
3333 if (!pim_ifp) {
3334 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
3335 if (!pim_ifp) {
981d6c7a 3336 return 0;
12e41d03
DL
3337 }
3338 }
3339 else {
3340 PIM_IF_DO_PIM(pim_ifp->options);
3341 }
3342
981d6c7a 3343 pim_ifp->itype = itype;
12e41d03
DL
3344 pim_if_addr_add_all(ifp);
3345 pim_if_membership_refresh(ifp);
3346
a920d6e7 3347 pim_rp_check_rp (null, pim_ifp->primary_address);
981d6c7a
DS
3348 return 1;
3349}
3350
3351
3352DEFUN (interface_ip_pim_ssm,
3353 interface_ip_pim_ssm_cmd,
3354 "ip pim ssm",
3355 IP_STR
3356 PIM_STR
3357 IFACE_PIM_STR)
3358{
cdc2d765 3359 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
3360
3361 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) {
3362 vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE);
3363 return CMD_WARNING;
3364 }
3365
12e41d03
DL
3366 return CMD_SUCCESS;
3367}
3368
981d6c7a
DS
3369DEFUN (interface_ip_pim_sm,
3370 interface_ip_pim_sm_cmd,
3371 "ip pim sm",
12e41d03
DL
3372 IP_STR
3373 PIM_STR
8371bd60 3374 IFACE_PIM_SM_STR)
12e41d03 3375{
cdc2d765 3376 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
3377 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) {
3378 vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
3379 return CMD_WARNING;
3380 }
3381
c992c9a0
DS
3382 pim_if_create_pimreg();
3383
981d6c7a
DS
3384 return CMD_SUCCESS;
3385}
3386
3387static int
3388pim_cmd_interface_delete (struct interface *ifp)
3389{
3390 struct pim_interface *pim_ifp = ifp->info;
3391
12e41d03 3392 if (!pim_ifp)
981d6c7a 3393 return 1;
12e41d03
DL
3394
3395 PIM_IF_DONT_PIM(pim_ifp->options);
3396
3397 pim_if_membership_clear(ifp);
3398
3399 /*
3400 pim_if_addr_del_all() removes all sockets from
3401 pim_ifp->igmp_socket_list.
3402 */
3403 pim_if_addr_del_all(ifp);
3404
3405 /*
3406 pim_sock_delete() removes all neighbors from
3407 pim_ifp->pim_neighbor_list.
3408 */
3409 pim_sock_delete(ifp, "pim unconfigured on interface");
3410
3411 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
3412 pim_if_delete(ifp);
3413 }
3414
981d6c7a
DS
3415 return 1;
3416}
3417
3418DEFUN (interface_no_ip_pim_ssm,
3419 interface_no_ip_pim_ssm_cmd,
3420 "no ip pim ssm",
3421 NO_STR
3422 IP_STR
3423 PIM_STR
3424 IFACE_PIM_STR)
3425{
cdc2d765 3426 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
3427 if (!pim_cmd_interface_delete(ifp)) {
3428 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
3429 return CMD_WARNING;
3430 }
3431
3432 return CMD_SUCCESS;
3433}
3434
3435DEFUN (interface_no_ip_pim_sm,
3436 interface_no_ip_pim_sm_cmd,
3437 "no ip pim sm",
3438 NO_STR
3439 IP_STR
3440 PIM_STR
8371bd60 3441 IFACE_PIM_SM_STR)
981d6c7a 3442{
cdc2d765 3443 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
3444 if (!pim_cmd_interface_delete(ifp)) {
3445 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
3446 return CMD_WARNING;
3447 }
3448
12e41d03
DL
3449 return CMD_SUCCESS;
3450}
3451
6250610a
JAG
3452DEFUN (interface_ip_mroute,
3453 interface_ip_mroute_cmd,
3454 "ip mroute INTERFACE A.B.C.D",
3455 IP_STR
3456 "Add multicast route\n"
3457 "Outgoing interface name\n"
3458 "Group address\n")
3459{
cdc2d765 3460 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
3461 int idx_interface = 2;
3462 int idx_ipv4 = 3;
6250610a
JAG
3463 struct interface *oif;
3464 const char *oifname;
3465 const char *grp_str;
3466 struct in_addr grp_addr;
3467 struct in_addr src_addr;
3468 int result;
3469
b181fa04 3470 oifname = argv[idx_interface]->arg;
6250610a
JAG
3471 oif = if_lookup_by_name(oifname);
3472 if (!oif) {
3473 vty_out(vty, "No such interface name %s%s",
3474 oifname, VTY_NEWLINE);
3475 return CMD_WARNING;
3476 }
3477
b181fa04 3478 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
3479 result = inet_pton(AF_INET, grp_str, &grp_addr);
3480 if (result <= 0) {
3481 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3482 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3483 return CMD_WARNING;
3484 }
3485
3486 src_addr.s_addr = INADDR_ANY;
3487
3488 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3489 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3490 return CMD_WARNING;
3491 }
3492
3493 return CMD_SUCCESS;
3494}
3495
3496DEFUN (interface_ip_mroute_source,
3497 interface_ip_mroute_source_cmd,
3498 "ip mroute INTERFACE A.B.C.D A.B.C.D",
3499 IP_STR
3500 "Add multicast route\n"
3501 "Outgoing interface name\n"
3502 "Group address\n"
3503 "Source address\n")
3504{
cdc2d765 3505 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
3506 int idx_interface = 2;
3507 int idx_ipv4 = 3;
3508 int idx_ipv4_2 = 4;
6250610a
JAG
3509 struct interface *oif;
3510 const char *oifname;
3511 const char *grp_str;
3512 struct in_addr grp_addr;
3513 const char *src_str;
3514 struct in_addr src_addr;
3515 int result;
3516
b181fa04 3517 oifname = argv[idx_interface]->arg;
6250610a
JAG
3518 oif = if_lookup_by_name(oifname);
3519 if (!oif) {
3520 vty_out(vty, "No such interface name %s%s",
3521 oifname, VTY_NEWLINE);
3522 return CMD_WARNING;
3523 }
3524
b181fa04 3525 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
3526 result = inet_pton(AF_INET, grp_str, &grp_addr);
3527 if (result <= 0) {
3528 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3529 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3530 return CMD_WARNING;
3531 }
3532
b181fa04 3533 src_str = argv[idx_ipv4_2]->arg;
6250610a
JAG
3534 result = inet_pton(AF_INET, src_str, &src_addr);
3535 if (result <= 0) {
3536 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3537 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
3538 return CMD_WARNING;
3539 }
3540
3541 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3542 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3543 return CMD_WARNING;
3544 }
3545
3546 return CMD_SUCCESS;
3547}
3548
3549DEFUN (interface_no_ip_mroute,
3550 interface_no_ip_mroute_cmd,
3551 "no ip mroute INTERFACE A.B.C.D",
3552 NO_STR
3553 IP_STR
3554 "Add multicast route\n"
3555 "Outgoing interface name\n"
3556 "Group Address\n")
3557{
cdc2d765 3558 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
3559 int idx_interface = 3;
3560 int idx_ipv4 = 4;
6250610a
JAG
3561 struct interface *oif;
3562 const char *oifname;
3563 const char *grp_str;
3564 struct in_addr grp_addr;
3565 struct in_addr src_addr;
3566 int result;
3567
b181fa04 3568 oifname = argv[idx_interface]->arg;
6250610a
JAG
3569 oif = if_lookup_by_name(oifname);
3570 if (!oif) {
3571 vty_out(vty, "No such interface name %s%s",
3572 oifname, VTY_NEWLINE);
3573 return CMD_WARNING;
3574 }
3575
b181fa04 3576 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
3577 result = inet_pton(AF_INET, grp_str, &grp_addr);
3578 if (result <= 0) {
3579 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3580 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3581 return CMD_WARNING;
3582 }
3583
3584 src_addr.s_addr = INADDR_ANY;
3585
3586 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
3587 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3588 return CMD_WARNING;
3589 }
3590
3591 return CMD_SUCCESS;
3592}
3593
3594DEFUN (interface_no_ip_mroute_source,
3595 interface_no_ip_mroute_source_cmd,
3596 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
3597 NO_STR
3598 IP_STR
3599 "Add multicast route\n"
3600 "Outgoing interface name\n"
3601 "Group Address\n"
3602 "Source Address\n")
3603{
cdc2d765 3604 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
3605 int idx_interface = 3;
3606 int idx_ipv4 = 4;
3607 int idx_ipv4_2 = 5;
6250610a
JAG
3608 struct interface *oif;
3609 const char *oifname;
3610 const char *grp_str;
3611 struct in_addr grp_addr;
3612 const char *src_str;
3613 struct in_addr src_addr;
3614 int result;
3615
b181fa04 3616 oifname = argv[idx_interface]->arg;
6250610a
JAG
3617 oif = if_lookup_by_name(oifname);
3618 if (!oif) {
3619 vty_out(vty, "No such interface name %s%s",
3620 oifname, VTY_NEWLINE);
3621 return CMD_WARNING;
3622 }
3623
b181fa04 3624 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
3625 result = inet_pton(AF_INET, grp_str, &grp_addr);
3626 if (result <= 0) {
3627 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3628 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3629 return CMD_WARNING;
3630 }
3631
b181fa04 3632 src_str = argv[idx_ipv4_2]->arg;
6250610a
JAG
3633 result = inet_pton(AF_INET, src_str, &src_addr);
3634 if (result <= 0) {
3635 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3636 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
3637 return CMD_WARNING;
3638 }
3639
3640 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
3641 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3642 return CMD_WARNING;
3643 }
3644
3645 return CMD_SUCCESS;
3646}
3647
7960fa8f
DS
3648DEFUN (interface_ip_pim_hello,
3649 interface_ip_pim_hello_cmd,
80d3d26b 3650 "ip pim hello (1-180) [(1-180)]",
7960fa8f
DS
3651 IP_STR
3652 PIM_STR
3653 IFACE_PIM_HELLO_STR
80d3d26b
DW
3654 IFACE_PIM_HELLO_TIME_STR
3655 IFACE_PIM_HELLO_HOLD_STR)
7960fa8f 3656{
cdc2d765 3657 VTY_DECLVAR_CONTEXT(interface, ifp);
80d3d26b
DW
3658 int idx_time = 3;
3659 int idx_hold = 4;
7960fa8f
DS
3660 struct pim_interface *pim_ifp;
3661
7960fa8f
DS
3662 pim_ifp = ifp->info;
3663
3664 if (!pim_ifp) {
3665 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3666 return CMD_WARNING;
3667 }
3668
80d3d26b 3669 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
7960fa8f 3670
80d3d26b
DW
3671 if (argc > idx_hold)
3672 pim_ifp->pim_default_holdtime = strtol(argv[idx_hold]->arg, NULL, 10);
7960fa8f
DS
3673
3674 return CMD_SUCCESS;
3675}
3676
7960fa8f
DS
3677
3678
3679DEFUN (interface_no_ip_pim_hello,
3680 interface_no_ip_pim_hello_cmd,
b181fa04 3681 "no ip pim hello [(1-180) (1-180)]",
7960fa8f
DS
3682 NO_STR
3683 IP_STR
3684 PIM_STR
3685 IFACE_PIM_HELLO_STR
3686 IFACE_PIM_HELLO_TIME_STR
3687 IFACE_PIM_HELLO_HOLD_STR)
3688{
cdc2d765 3689 VTY_DECLVAR_CONTEXT(interface, ifp);
7960fa8f
DS
3690 struct pim_interface *pim_ifp;
3691
7960fa8f
DS
3692 pim_ifp = ifp->info;
3693
3694 if (!pim_ifp) {
3695 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3696 return CMD_WARNING;
3697 }
3698
3699 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
3700 pim_ifp->pim_default_holdtime = -1;
3701
3702 return CMD_SUCCESS;
3703}
3704
12e41d03
DL
3705DEFUN (debug_igmp,
3706 debug_igmp_cmd,
3707 "debug igmp",
3708 DEBUG_STR
3709 DEBUG_IGMP_STR)
3710{
3711 PIM_DO_DEBUG_IGMP_EVENTS;
3712 PIM_DO_DEBUG_IGMP_PACKETS;
3713 PIM_DO_DEBUG_IGMP_TRACE;
3714 return CMD_SUCCESS;
3715}
3716
3717DEFUN (no_debug_igmp,
3718 no_debug_igmp_cmd,
3719 "no debug igmp",
3720 NO_STR
3721 DEBUG_STR
3722 DEBUG_IGMP_STR)
3723{
3724 PIM_DONT_DEBUG_IGMP_EVENTS;
3725 PIM_DONT_DEBUG_IGMP_PACKETS;
3726 PIM_DONT_DEBUG_IGMP_TRACE;
3727 return CMD_SUCCESS;
3728}
3729
12e41d03
DL
3730
3731DEFUN (debug_igmp_events,
3732 debug_igmp_events_cmd,
3733 "debug igmp events",
3734 DEBUG_STR
3735 DEBUG_IGMP_STR
3736 DEBUG_IGMP_EVENTS_STR)
3737{
3738 PIM_DO_DEBUG_IGMP_EVENTS;
3739 return CMD_SUCCESS;
3740}
3741
3742DEFUN (no_debug_igmp_events,
3743 no_debug_igmp_events_cmd,
3744 "no debug igmp events",
3745 NO_STR
3746 DEBUG_STR
3747 DEBUG_IGMP_STR
3748 DEBUG_IGMP_EVENTS_STR)
3749{
3750 PIM_DONT_DEBUG_IGMP_EVENTS;
3751 return CMD_SUCCESS;
3752}
3753
12e41d03
DL
3754
3755DEFUN (debug_igmp_packets,
3756 debug_igmp_packets_cmd,
3757 "debug igmp packets",
3758 DEBUG_STR
3759 DEBUG_IGMP_STR
3760 DEBUG_IGMP_PACKETS_STR)
3761{
3762 PIM_DO_DEBUG_IGMP_PACKETS;
3763 return CMD_SUCCESS;
3764}
3765
3766DEFUN (no_debug_igmp_packets,
3767 no_debug_igmp_packets_cmd,
3768 "no debug igmp packets",
3769 NO_STR
3770 DEBUG_STR
3771 DEBUG_IGMP_STR
3772 DEBUG_IGMP_PACKETS_STR)
3773{
3774 PIM_DONT_DEBUG_IGMP_PACKETS;
3775 return CMD_SUCCESS;
3776}
3777
12e41d03
DL
3778
3779DEFUN (debug_igmp_trace,
3780 debug_igmp_trace_cmd,
3781 "debug igmp trace",
3782 DEBUG_STR
3783 DEBUG_IGMP_STR
3784 DEBUG_IGMP_TRACE_STR)
3785{
3786 PIM_DO_DEBUG_IGMP_TRACE;
3787 return CMD_SUCCESS;
3788}
3789
3790DEFUN (no_debug_igmp_trace,
3791 no_debug_igmp_trace_cmd,
3792 "no debug igmp trace",
3793 NO_STR
3794 DEBUG_STR
3795 DEBUG_IGMP_STR
3796 DEBUG_IGMP_TRACE_STR)
3797{
3798 PIM_DONT_DEBUG_IGMP_TRACE;
3799 return CMD_SUCCESS;
3800}
3801
12e41d03
DL
3802
3803DEFUN (debug_mroute,
3804 debug_mroute_cmd,
3805 "debug mroute",
3806 DEBUG_STR
3807 DEBUG_MROUTE_STR)
3808{
3809 PIM_DO_DEBUG_MROUTE;
3810 return CMD_SUCCESS;
3811}
3812
6c7197b1
DS
3813DEFUN (debug_mroute_detail,
3814 debug_mroute_detail_cmd,
3815 "debug mroute detail",
3816 DEBUG_STR
3817 DEBUG_MROUTE_STR
3818 "detailed\n")
3819{
3820 PIM_DO_DEBUG_MROUTE_DETAIL;
3821 return CMD_SUCCESS;
3822}
3823
12e41d03
DL
3824DEFUN (no_debug_mroute,
3825 no_debug_mroute_cmd,
3826 "no debug mroute",
3827 NO_STR
3828 DEBUG_STR
3829 DEBUG_MROUTE_STR)
3830{
3831 PIM_DONT_DEBUG_MROUTE;
3832 return CMD_SUCCESS;
3833}
3834
6c7197b1
DS
3835DEFUN (no_debug_mroute_detail,
3836 no_debug_mroute_detail_cmd,
3837 "no debug mroute detail",
3838 NO_STR
3839 DEBUG_STR
3840 DEBUG_MROUTE_STR
3841 "detailed\n")
3842{
3843 PIM_DONT_DEBUG_MROUTE_DETAIL;
3844 return CMD_SUCCESS;
3845}
12e41d03 3846
6250610a
JAG
3847DEFUN (debug_static,
3848 debug_static_cmd,
3849 "debug static",
3850 DEBUG_STR
3851 DEBUG_STATIC_STR)
3852{
3853 PIM_DO_DEBUG_STATIC;
3854 return CMD_SUCCESS;
3855}
3856
3857DEFUN (no_debug_static,
3858 no_debug_static_cmd,
3859 "no debug static",
3860 NO_STR
3861 DEBUG_STR
3862 DEBUG_STATIC_STR)
3863{
3864 PIM_DONT_DEBUG_STATIC;
3865 return CMD_SUCCESS;
3866}
3867
6250610a 3868
12e41d03
DL
3869DEFUN (debug_pim,
3870 debug_pim_cmd,
3871 "debug pim",
3872 DEBUG_STR
3873 DEBUG_PIM_STR)
3874{
3875 PIM_DO_DEBUG_PIM_EVENTS;
3876 PIM_DO_DEBUG_PIM_PACKETS;
3877 PIM_DO_DEBUG_PIM_TRACE;
3878 return CMD_SUCCESS;
3879}
3880
3881DEFUN (no_debug_pim,
3882 no_debug_pim_cmd,
3883 "no debug pim",
3884 NO_STR
3885 DEBUG_STR
3886 DEBUG_PIM_STR)
3887{
3888 PIM_DONT_DEBUG_PIM_EVENTS;
3889 PIM_DONT_DEBUG_PIM_PACKETS;
3890 PIM_DONT_DEBUG_PIM_TRACE;
3891
3892 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3893 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3894
3895 return CMD_SUCCESS;
3896}
3897
12e41d03
DL
3898
3899DEFUN (debug_pim_events,
3900 debug_pim_events_cmd,
3901 "debug pim events",
3902 DEBUG_STR
3903 DEBUG_PIM_STR
3904 DEBUG_PIM_EVENTS_STR)
3905{
3906 PIM_DO_DEBUG_PIM_EVENTS;
3907 return CMD_SUCCESS;
3908}
3909
3910DEFUN (no_debug_pim_events,
3911 no_debug_pim_events_cmd,
3912 "no debug pim events",
3913 NO_STR
3914 DEBUG_STR
3915 DEBUG_PIM_STR
3916 DEBUG_PIM_EVENTS_STR)
3917{
3918 PIM_DONT_DEBUG_PIM_EVENTS;
3919 return CMD_SUCCESS;
3920}
3921
12e41d03
DL
3922
3923DEFUN (debug_pim_packets,
3924 debug_pim_packets_cmd,
3925 "debug pim packets",
3926 DEBUG_STR
3927 DEBUG_PIM_STR
3928 DEBUG_PIM_PACKETS_STR)
3929{
3930 PIM_DO_DEBUG_PIM_PACKETS;
3931 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
3932 return CMD_SUCCESS;
3933}
3934
3935DEFUN (debug_pim_packets_filter,
3936 debug_pim_packets_filter_cmd,
9add3b88 3937 "debug pim packets <hello|joins|register>",
12e41d03
DL
3938 DEBUG_STR
3939 DEBUG_PIM_STR
3940 DEBUG_PIM_PACKETS_STR
3941 DEBUG_PIM_HELLO_PACKETS_STR
9add3b88
DS
3942 DEBUG_PIM_J_P_PACKETS_STR
3943 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 3944{
b181fa04 3945 int idx_hello_join = 3;
9add3b88 3946 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
12e41d03
DL
3947 {
3948 PIM_DO_DEBUG_PIM_HELLO;
9add3b88 3949 vty_out (vty, "PIM Hello debugging is on%s", VTY_NEWLINE);
12e41d03 3950 }
9add3b88 3951 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
12e41d03
DL
3952 {
3953 PIM_DO_DEBUG_PIM_J_P;
9add3b88
DS
3954 vty_out (vty, "PIM Join/Prune debugging is on%s", VTY_NEWLINE);
3955 }
3956 else if (strncmp(argv[idx_hello_join]->arg,"r",1) == 0)
3957 {
3958 PIM_DO_DEBUG_PIM_REG;
3959 vty_out (vty, "PIM Register debugging is on%s", VTY_NEWLINE);
12e41d03
DL
3960 }
3961 return CMD_SUCCESS;
3962}
3963
3964DEFUN (no_debug_pim_packets,
3965 no_debug_pim_packets_cmd,
3966 "no debug pim packets",
3967 NO_STR
3968 DEBUG_STR
3969 DEBUG_PIM_STR
3970 DEBUG_PIM_PACKETS_STR
3971 DEBUG_PIM_HELLO_PACKETS_STR
3972 DEBUG_PIM_J_P_PACKETS_STR)
3973{
3974 PIM_DONT_DEBUG_PIM_PACKETS;
3975 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
3976 return CMD_SUCCESS;
3977}
3978
3979DEFUN (no_debug_pim_packets_filter,
3980 no_debug_pim_packets_filter_cmd,
9add3b88 3981 "no debug pim packets <hello|joins|register>",
12e41d03
DL
3982 NO_STR
3983 DEBUG_STR
3984 DEBUG_PIM_STR
3985 DEBUG_PIM_PACKETS_STR
3986 DEBUG_PIM_HELLO_PACKETS_STR
3987 DEBUG_PIM_J_P_PACKETS_STR)
3988{
b181fa04 3989 int idx_hello_join = 4;
9add3b88 3990 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
12e41d03
DL
3991 {
3992 PIM_DONT_DEBUG_PIM_HELLO;
3993 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
3994 }
9add3b88 3995 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
12e41d03
DL
3996 {
3997 PIM_DONT_DEBUG_PIM_J_P;
3998 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
3999 }
9add3b88
DS
4000 else if (strncmp (argv[idx_hello_join]->arg, "r", 1) == 0)
4001 {
4002 PIM_DONT_DEBUG_PIM_REG;
4003 vty_out (vty, "PIM Register debugging is off%s", VTY_NEWLINE);
4004 }
4005 return CMD_SUCCESS;
12e41d03
DL
4006}
4007
12e41d03
DL
4008
4009DEFUN (debug_pim_packetdump_send,
4010 debug_pim_packetdump_send_cmd,
4011 "debug pim packet-dump send",
4012 DEBUG_STR
4013 DEBUG_PIM_STR
4014 DEBUG_PIM_PACKETDUMP_STR
4015 DEBUG_PIM_PACKETDUMP_SEND_STR)
4016{
4017 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
4018 return CMD_SUCCESS;
4019}
4020
4021DEFUN (no_debug_pim_packetdump_send,
4022 no_debug_pim_packetdump_send_cmd,
4023 "no debug pim packet-dump send",
4024 NO_STR
4025 DEBUG_STR
4026 DEBUG_PIM_STR
4027 DEBUG_PIM_PACKETDUMP_STR
4028 DEBUG_PIM_PACKETDUMP_SEND_STR)
4029{
4030 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
4031 return CMD_SUCCESS;
4032}
4033
12e41d03
DL
4034
4035DEFUN (debug_pim_packetdump_recv,
4036 debug_pim_packetdump_recv_cmd,
4037 "debug pim packet-dump receive",
4038 DEBUG_STR
4039 DEBUG_PIM_STR
4040 DEBUG_PIM_PACKETDUMP_STR
4041 DEBUG_PIM_PACKETDUMP_RECV_STR)
4042{
4043 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
4044 return CMD_SUCCESS;
4045}
4046
4047DEFUN (no_debug_pim_packetdump_recv,
4048 no_debug_pim_packetdump_recv_cmd,
4049 "no debug pim packet-dump receive",
4050 NO_STR
4051 DEBUG_STR
4052 DEBUG_PIM_STR
4053 DEBUG_PIM_PACKETDUMP_STR
4054 DEBUG_PIM_PACKETDUMP_RECV_STR)
4055{
4056 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4057 return CMD_SUCCESS;
4058}
4059
12e41d03
DL
4060
4061DEFUN (debug_pim_trace,
4062 debug_pim_trace_cmd,
4063 "debug pim trace",
4064 DEBUG_STR
4065 DEBUG_PIM_STR
4066 DEBUG_PIM_TRACE_STR)
4067{
4068 PIM_DO_DEBUG_PIM_TRACE;
4069 return CMD_SUCCESS;
4070}
4071
4072DEFUN (no_debug_pim_trace,
4073 no_debug_pim_trace_cmd,
4074 "no debug pim trace",
4075 NO_STR
4076 DEBUG_STR
4077 DEBUG_PIM_STR
4078 DEBUG_PIM_TRACE_STR)
4079{
4080 PIM_DONT_DEBUG_PIM_TRACE;
4081 return CMD_SUCCESS;
4082}
4083
12e41d03
DL
4084
4085DEFUN (debug_ssmpingd,
4086 debug_ssmpingd_cmd,
4087 "debug ssmpingd",
4088 DEBUG_STR
4089 DEBUG_PIM_STR
4090 DEBUG_SSMPINGD_STR)
4091{
4092 PIM_DO_DEBUG_SSMPINGD;
4093 return CMD_SUCCESS;
4094}
4095
4096DEFUN (no_debug_ssmpingd,
4097 no_debug_ssmpingd_cmd,
4098 "no debug ssmpingd",
4099 NO_STR
4100 DEBUG_STR
4101 DEBUG_PIM_STR
4102 DEBUG_SSMPINGD_STR)
4103{
4104 PIM_DONT_DEBUG_SSMPINGD;
4105 return CMD_SUCCESS;
4106}
4107
12e41d03
DL
4108
4109DEFUN (debug_pim_zebra,
4110 debug_pim_zebra_cmd,
4111 "debug pim zebra",
4112 DEBUG_STR
4113 DEBUG_PIM_STR
4114 DEBUG_PIM_ZEBRA_STR)
4115{
4116 PIM_DO_DEBUG_ZEBRA;
4117 return CMD_SUCCESS;
4118}
4119
4120DEFUN (no_debug_pim_zebra,
4121 no_debug_pim_zebra_cmd,
4122 "no debug pim zebra",
4123 NO_STR
4124 DEBUG_STR
4125 DEBUG_PIM_STR
4126 DEBUG_PIM_ZEBRA_STR)
4127{
4128 PIM_DONT_DEBUG_ZEBRA;
4129 return CMD_SUCCESS;
4130}
4131
12e41d03 4132
7a1d58ce
DS
4133DEFUN (show_debugging_pim,
4134 show_debugging_pim_cmd,
4135 "show debugging pim",
12e41d03 4136 SHOW_STR
7a1d58ce
DS
4137 DEBUG_STR
4138 PIM_STR)
12e41d03
DL
4139{
4140 pim_debug_config_write(vty);
4141 return CMD_SUCCESS;
4142}
4143
4144static struct igmp_sock *find_igmp_sock_by_fd(int fd)
4145{
4146 struct listnode *ifnode;
4147 struct interface *ifp;
4148
4149 /* scan all interfaces */
469351b3 4150 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
4151 struct pim_interface *pim_ifp;
4152 struct igmp_sock *igmp;
4153
4154 if (!ifp->info)
4155 continue;
4156
4157 pim_ifp = ifp->info;
4158
4159 /* lookup igmp socket under current interface */
4160 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
4161 if (igmp)
4162 return igmp;
4163 }
4164
4165 return 0;
4166}
4167
4168DEFUN (test_igmp_receive_report,
4169 test_igmp_receive_report_cmd,
e961923c 4170 "test igmp receive report (0-65535) A.B.C.D (1-6) LINE...",
12e41d03
DL
4171 "Test\n"
4172 "Test IGMP protocol\n"
4173 "Test IGMP message\n"
4174 "Test IGMP report\n"
4175 "Socket\n"
4176 "IGMP group address\n"
4177 "Record type\n"
4178 "Sources\n")
4179{
b181fa04
DW
4180 int idx_number = 4;
4181 int idx_ipv4 = 5;
4182 int idx_number_2 = 6;
58749582 4183 int idx_line = 7;
12e41d03
DL
4184 char buf[1000];
4185 char *igmp_msg;
4186 struct ip *ip_hdr;
4187 size_t ip_hlen; /* ip header length in bytes */
4188 int ip_msg_len;
4189 int igmp_msg_len;
4190 const char *socket;
4191 int socket_fd;
4192 const char *grp_str;
4193 struct in_addr grp_addr;
4194 const char *record_type_str;
4195 int record_type;
4196 const char *src_str;
4197 int result;
4198 struct igmp_sock *igmp;
4199 char *group_record;
4200 int num_sources;
4201 struct in_addr *sources;
4202 struct in_addr *src_addr;
4203 int argi;
4204
b181fa04 4205 socket = argv[idx_number]->arg;
12e41d03
DL
4206 socket_fd = atoi(socket);
4207 igmp = find_igmp_sock_by_fd(socket_fd);
4208 if (!igmp) {
4209 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
4210 socket, socket_fd, VTY_NEWLINE);
4211 return CMD_WARNING;
4212 }
4213
b181fa04 4214 grp_str = argv[idx_ipv4]->arg;
12e41d03
DL
4215 result = inet_pton(AF_INET, grp_str, &grp_addr);
4216 if (result <= 0) {
4217 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4218 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4219 return CMD_WARNING;
4220 }
4221
b181fa04 4222 record_type_str = argv[idx_number_2]->arg;
12e41d03
DL
4223 record_type = atoi(record_type_str);
4224
4225 /*
4226 Tweak IP header
4227 */
4228 ip_hdr = (struct ip *) buf;
4229 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
4230 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4231 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4232 ip_hdr->ip_src = igmp->ifaddr;
4233 ip_hdr->ip_dst = igmp->ifaddr;
4234
4235 /*
4236 Build IGMP v3 report message
4237 */
4238 igmp_msg = buf + ip_hlen;
4239 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
4240 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
4241 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
4242 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
4243 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
4244 memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
4245
4246 /* Scan LINE sources */
4247 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
4248 src_addr = sources;
58749582 4249 for (argi = idx_line; argi < argc; ++argi,++src_addr) {
91ac1d43 4250 src_str = argv[argi]->arg;
12e41d03
DL
4251 result = inet_pton(AF_INET, src_str, src_addr);
4252 if (result <= 0) {
4253 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4254 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4255 return CMD_WARNING;
4256 }
4257 }
4258 num_sources = src_addr - sources;
4259
4260 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
4261
4262 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
4263
4264 /* compute checksum */
4265 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
4266
4267 /* "receive" message */
4268
4269 ip_msg_len = ip_hlen + igmp_msg_len;
4270 result = pim_igmp_packet(igmp, buf, ip_msg_len);
4271 if (result) {
4272 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
4273 ip_msg_len, result, VTY_NEWLINE);
4274 return CMD_WARNING;
4275 }
4276
4277 return CMD_SUCCESS;
4278}
4279
4280static int hexval(uint8_t ch)
4281{
4282 return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
4283}
4284
4285DEFUN (test_pim_receive_dump,
4286 test_pim_receive_dump_cmd,
e961923c 4287 "test pim receive dump INTERFACE A.B.C.D LINE...",
12e41d03
DL
4288 "Test\n"
4289 "Test PIM protocol\n"
4290 "Test PIM message reception\n"
4291 "Test PIM packet dump reception from neighbor\n"
4292 "Interface\n"
4293 "Neighbor address\n"
4294 "Packet dump\n")
4295{
b181fa04
DW
4296 int idx_interface = 4;
4297 int idx_ipv4 = 5;
58749582 4298 int idx_line = 6;
12e41d03
DL
4299 uint8_t buf[1000];
4300 uint8_t *pim_msg;
4301 struct ip *ip_hdr;
4302 size_t ip_hlen; /* ip header length in bytes */
4303 int ip_msg_len;
4304 int pim_msg_size;
4305 const char *neigh_str;
4306 struct in_addr neigh_addr;
4307 const char *ifname;
4308 struct interface *ifp;
4309 int argi;
4310 int result;
4311
4312 /* Find interface */
b181fa04 4313 ifname = argv[idx_interface]->arg;
12e41d03
DL
4314 ifp = if_lookup_by_name(ifname);
4315 if (!ifp) {
4316 vty_out(vty, "No such interface name %s%s",
4317 ifname, VTY_NEWLINE);
4318 return CMD_WARNING;
4319 }
4320
4321 /* Neighbor address */
b181fa04 4322 neigh_str = argv[idx_ipv4]->arg;
12e41d03
DL
4323 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4324 if (result <= 0) {
4325 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4326 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4327 return CMD_WARNING;
4328 }
4329
4330 /*
4331 Tweak IP header
4332 */
4333 ip_hdr = (struct ip *) buf;
4334 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4335 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4336 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4337 ip_hdr->ip_src = neigh_addr;
4338 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4339
4340 /*
4341 Build PIM hello message
4342 */
4343 pim_msg = buf + ip_hlen;
4344 pim_msg_size = 0;
4345
4346 /* Scan LINE dump into buffer */
58749582 4347 for (argi = idx_line; argi < argc; ++argi) {
91ac1d43 4348 const char *str = argv[argi]->arg;
12e41d03
DL
4349 int str_len = strlen(str);
4350 int str_last = str_len - 1;
4351 int i;
4352
4353 if (str_len % 2) {
4354 vty_out(vty, "%% Uneven hex array arg %d=%s%s",
4355 argi, str, VTY_NEWLINE);
4356 return CMD_WARNING;
4357 }
4358
4359 for (i = 0; i < str_last; i += 2) {
4360 uint8_t octet;
4361 int left;
4362 uint8_t h1 = str[i];
4363 uint8_t h2 = str[i + 1];
4364
4365 if (!isxdigit(h1) || !isxdigit(h2)) {
4366 vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
4367 h1, h2, argi, str, VTY_NEWLINE);
4368 return CMD_WARNING;
4369 }
4370 octet = (hexval(h1) << 4) + hexval(h2);
4371
4372 left = sizeof(buf) - ip_hlen - pim_msg_size;
4373 if (left < 1) {
4374 vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
4375 sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
4376 return CMD_WARNING;
4377 }
4378
4379 pim_msg[pim_msg_size++] = octet;
4380 }
4381 }
4382
4383 ip_msg_len = ip_hlen + pim_msg_size;
4384
4385 vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
4386 sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
4387
4388 /* "receive" message */
4389
4390 result = pim_pim_packet(ifp, buf, ip_msg_len);
4391 if (result) {
4392 vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
4393 ip_msg_len, result, VTY_NEWLINE);
4394 return CMD_WARNING;
4395 }
4396
4397 return CMD_SUCCESS;
4398}
4399
4400DEFUN (test_pim_receive_hello,
4401 test_pim_receive_hello_cmd,
b181fa04 4402 "test pim receive hello INTERFACE A.B.C.D (0-65535) (0-65535) (0-65535) (0-32767) (0-65535) (0-1) [LINE]",
12e41d03
DL
4403 "Test\n"
4404 "Test PIM protocol\n"
4405 "Test PIM message reception\n"
4406 "Test PIM hello reception from neighbor\n"
4407 "Interface\n"
4408 "Neighbor address\n"
4409 "Neighbor holdtime\n"
4410 "Neighbor DR priority\n"
4411 "Neighbor generation ID\n"
4412 "Neighbor propagation delay (msec)\n"
4413 "Neighbor override interval (msec)\n"
4414 "Neighbor LAN prune delay T-bit\n"
4415 "Neighbor secondary addresses\n")
4416{
b181fa04
DW
4417 int idx_interface = 4;
4418 int idx_ipv4 = 5;
4419 int idx_number = 6;
4420 int idx_number_2 = 7;
4421 int idx_number_3 = 8;
4422 int idx_number_4 = 9;
4423 int idx_number_5 = 10;
4424 int idx_number_6 = 11;
58749582 4425 int idx_line = 12;
12e41d03
DL
4426 uint8_t buf[1000];
4427 uint8_t *pim_msg;
4428 struct ip *ip_hdr;
4429 size_t ip_hlen; /* ip header length in bytes */
4430 int ip_msg_len;
4431 int pim_tlv_size;
4432 int pim_msg_size;
4433 const char *neigh_str;
4434 struct in_addr neigh_addr;
4435 const char *ifname;
4436 struct interface *ifp;
4437 uint16_t neigh_holdtime;
4438 uint16_t neigh_propagation_delay;
4439 uint16_t neigh_override_interval;
4440 int neigh_can_disable_join_suppression;
4441 uint32_t neigh_dr_priority;
4442 uint32_t neigh_generation_id;
4443 int argi;
4444 int result;
4445
4446 /* Find interface */
b181fa04 4447 ifname = argv[idx_interface]->arg;
12e41d03
DL
4448 ifp = if_lookup_by_name(ifname);
4449 if (!ifp) {
4450 vty_out(vty, "No such interface name %s%s",
4451 ifname, VTY_NEWLINE);
4452 return CMD_WARNING;
4453 }
4454
4455 /* Neighbor address */
b181fa04 4456 neigh_str = argv[idx_ipv4]->arg;
12e41d03
DL
4457 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4458 if (result <= 0) {
4459 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4460 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4461 return CMD_WARNING;
4462 }
4463
b181fa04
DW
4464 neigh_holdtime = atoi(argv[idx_number]->arg);
4465 neigh_dr_priority = atoi(argv[idx_number_2]->arg);
4466 neigh_generation_id = atoi(argv[idx_number_3]->arg);
4467 neigh_propagation_delay = atoi(argv[idx_number_4]->arg);
4468 neigh_override_interval = atoi(argv[idx_number_5]->arg);
4469 neigh_can_disable_join_suppression = atoi(argv[idx_number_6]->arg);
12e41d03
DL
4470
4471 /*
4472 Tweak IP header
4473 */
4474 ip_hdr = (struct ip *) buf;
4475 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4476 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4477 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4478 ip_hdr->ip_src = neigh_addr;
4479 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4480
4481 /*
4482 Build PIM hello message
4483 */
4484 pim_msg = buf + ip_hlen;
4485
4486 /* Scan LINE addresses */
58749582 4487 for (argi = idx_line; argi < argc; ++argi) {
91ac1d43 4488 const char *sec_str = argv[argi]->arg;
12e41d03
DL
4489 struct in_addr sec_addr;
4490 result = inet_pton(AF_INET, sec_str, &sec_addr);
4491 if (result <= 0) {
4492 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
4493 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
4494 return CMD_WARNING;
4495 }
4496
4497 vty_out(vty,
4498 "FIXME WRITEME consider neighbor secondary address %s%s",
4499 sec_str, VTY_NEWLINE);
4500 }
4501
4502 pim_tlv_size = pim_hello_build_tlv(ifp->name,
4503 pim_msg + PIM_PIM_MIN_LEN,
4504 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
4505 neigh_holdtime,
4506 neigh_dr_priority,
4507 neigh_generation_id,
4508 neigh_propagation_delay,
4509 neigh_override_interval,
4510 neigh_can_disable_join_suppression,
4511 0 /* FIXME secondary address list */);
4512 if (pim_tlv_size < 0) {
4513 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
4514 pim_tlv_size, VTY_NEWLINE);
4515 return CMD_WARNING;
4516 }
4517
4518 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
4519
4520 pim_msg_build_header(pim_msg, pim_msg_size,
4521 PIM_MSG_TYPE_HELLO);
4522
4523 /* "receive" message */
4524
4525 ip_msg_len = ip_hlen + pim_msg_size;
4526 result = pim_pim_packet(ifp, buf, ip_msg_len);
4527 if (result) {
4528 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4529 ip_msg_len, result, VTY_NEWLINE);
4530 return CMD_WARNING;
4531 }
4532
4533 return CMD_SUCCESS;
4534}
4535
4536DEFUN (test_pim_receive_assert,
4537 test_pim_receive_assert_cmd,
b181fa04 4538 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D (0-65535) (0-65535) (0-1)",
12e41d03
DL
4539 "Test\n"
4540 "Test PIM protocol\n"
4541 "Test PIM message reception\n"
4542 "Test reception of PIM assert\n"
4543 "Interface\n"
4544 "Neighbor address\n"
4545 "Assert multicast group address\n"
4546 "Assert unicast source address\n"
4547 "Assert metric preference\n"
4548 "Assert route metric\n"
4549 "Assert RPT bit flag\n")
4550{
b181fa04
DW
4551 int idx_interface = 4;
4552 int idx_ipv4 = 5;
4553 int idx_ipv4_2 = 6;
4554 int idx_ipv4_3 = 7;
4555 int idx_number = 8;
4556 int idx_number_2 = 9;
4557 int idx_number_3 = 10;
12e41d03
DL
4558 uint8_t buf[1000];
4559 uint8_t *buf_pastend = buf + sizeof(buf);
4560 uint8_t *pim_msg;
4561 struct ip *ip_hdr;
4562 size_t ip_hlen; /* ip header length in bytes */
4563 int ip_msg_len;
4564 int pim_msg_size;
4565 const char *neigh_str;
4566 struct in_addr neigh_addr;
4567 const char *group_str;
4568 struct in_addr group_addr;
4569 const char *source_str;
4570 struct in_addr source_addr;
4571 const char *ifname;
4572 struct interface *ifp;
4573 uint32_t assert_metric_preference;
4574 uint32_t assert_route_metric;
4575 uint32_t assert_rpt_bit_flag;
4576 int remain;
4577 int result;
4578
4579 /* Find interface */
b181fa04 4580 ifname = argv[idx_interface]->arg;
12e41d03
DL
4581 ifp = if_lookup_by_name(ifname);
4582 if (!ifp) {
4583 vty_out(vty, "No such interface name %s%s",
4584 ifname, VTY_NEWLINE);
4585 return CMD_WARNING;
4586 }
4587
4588 /* Neighbor address */
b181fa04 4589 neigh_str = argv[idx_ipv4]->arg;
12e41d03
DL
4590 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4591 if (result <= 0) {
4592 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4593 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4594 return CMD_WARNING;
4595 }
4596
4597 /* Group address */
b181fa04 4598 group_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
4599 result = inet_pton(AF_INET, group_str, &group_addr);
4600 if (result <= 0) {
4601 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4602 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4603 return CMD_WARNING;
4604 }
4605
4606 /* Source address */
b181fa04 4607 source_str = argv[idx_ipv4_3]->arg;
12e41d03
DL
4608 result = inet_pton(AF_INET, source_str, &source_addr);
4609 if (result <= 0) {
4610 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4611 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4612 return CMD_WARNING;
4613 }
4614
b181fa04
DW
4615 assert_metric_preference = atoi(argv[idx_number]->arg);
4616 assert_route_metric = atoi(argv[idx_number_2]->arg);
4617 assert_rpt_bit_flag = atoi(argv[idx_number_3]->arg);
12e41d03
DL
4618
4619 remain = buf_pastend - buf;
4620 if (remain < (int) sizeof(struct ip)) {
4621 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
4622 remain, sizeof(struct ip), VTY_NEWLINE);
4623 return CMD_WARNING;
4624 }
4625
4626 /*
4627 Tweak IP header
4628 */
4629 ip_hdr = (struct ip *) buf;
4630 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4631 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4632 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4633 ip_hdr->ip_src = neigh_addr;
4634 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4635
4636 /*
4637 Build PIM assert message
4638 */
4639 pim_msg = buf + ip_hlen; /* skip ip header */
4640
4641 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
4642 group_addr, source_addr,
4643 assert_metric_preference,
4644 assert_route_metric,
4645 assert_rpt_bit_flag);
4646 if (pim_msg_size < 0) {
4647 vty_out(vty, "Failure building PIM assert message: size=%d%s",
4648 pim_msg_size, VTY_NEWLINE);
4649 return CMD_WARNING;
4650 }
4651
4652 /* "receive" message */
4653
4654 ip_msg_len = ip_hlen + pim_msg_size;
4655 result = pim_pim_packet(ifp, buf, ip_msg_len);
4656 if (result) {
4657 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4658 ip_msg_len, result, VTY_NEWLINE);
4659 return CMD_WARNING;
4660 }
4661
4662 return CMD_SUCCESS;
4663}
4664
4665static int recv_joinprune(struct vty *vty,
91ac1d43 4666 struct cmd_token **argv,
12e41d03
DL
4667 int src_is_join)
4668{
4669 uint8_t buf[1000];
4670 const uint8_t *buf_pastend = buf + sizeof(buf);
4671 uint8_t *pim_msg;
12e41d03
DL
4672 int pim_msg_size;
4673 struct ip *ip_hdr;
4674 size_t ip_hlen; /* ip header length in bytes */
4675 int ip_msg_len;
4676 uint16_t neigh_holdtime;
4677 const char *neigh_dst_str;
4678 struct in_addr neigh_dst_addr;
4679 const char *neigh_src_str;
4680 struct in_addr neigh_src_addr;
4681 const char *group_str;
4682 struct in_addr group_addr;
4683 const char *source_str;
4684 struct in_addr source_addr;
4685 const char *ifname;
4686 struct interface *ifp;
4687 int result;
12e41d03
DL
4688
4689 /* Find interface */
91ac1d43 4690 ifname = argv[0]->arg;
12e41d03
DL
4691 ifp = if_lookup_by_name(ifname);
4692 if (!ifp) {
4693 vty_out(vty, "No such interface name %s%s",
4694 ifname, VTY_NEWLINE);
4695 return CMD_WARNING;
4696 }
4697
91ac1d43 4698 neigh_holdtime = atoi(argv[1]->arg);
12e41d03
DL
4699
4700 /* Neighbor destination address */
91ac1d43 4701 neigh_dst_str = argv[2]->arg;
12e41d03
DL
4702 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
4703 if (result <= 0) {
4704 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
4705 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
4706 return CMD_WARNING;
4707 }
4708
4709 /* Neighbor source address */
91ac1d43 4710 neigh_src_str = argv[3]->arg;
12e41d03
DL
4711 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
4712 if (result <= 0) {
4713 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
4714 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4715 return CMD_WARNING;
4716 }
4717
4718 /* Multicast group address */
91ac1d43 4719 group_str = argv[4]->arg;
12e41d03
DL
4720 result = inet_pton(AF_INET, group_str, &group_addr);
4721 if (result <= 0) {
4722 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4723 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4724 return CMD_WARNING;
4725 }
4726
4727 /* Multicast source address */
91ac1d43 4728 source_str = argv[5]->arg;
12e41d03
DL
4729 result = inet_pton(AF_INET, source_str, &source_addr);
4730 if (result <= 0) {
4731 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4732 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4733 return CMD_WARNING;
4734 }
4735
4736 /*
4737 Tweak IP header
4738 */
4739 ip_hdr = (struct ip *) buf;
4740 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4741 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4742 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4743 ip_hdr->ip_src = neigh_src_addr;
4744 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4745
4746 /*
4747 Build PIM message
4748 */
4749 pim_msg = buf + ip_hlen;
4750
346cffe3
DS
4751 pim_msg_size = pim_msg_join_prune_encode (pim_msg, buf_pastend - pim_msg, src_is_join,
4752 source_addr, group_addr, neigh_dst_addr,
4753 neigh_holdtime);
12e41d03
DL
4754
4755 /*
4756 "Receive" message
4757 */
4758
4759 ip_msg_len = ip_hlen + pim_msg_size;
4760 result = pim_pim_packet(ifp, buf, ip_msg_len);
4761 if (result) {
4762 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4763 ip_msg_len, result, VTY_NEWLINE);
4764 return CMD_WARNING;
4765 }
4766
4767 return CMD_SUCCESS;
4768}
4769
4770DEFUN (test_pim_receive_join,
4771 test_pim_receive_join_cmd,
b181fa04 4772 "test pim receive join INTERFACE (0-65535) A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
12e41d03
DL
4773 "Test\n"
4774 "Test PIM protocol\n"
4775 "Test PIM message reception\n"
4776 "Test PIM join reception from neighbor\n"
4777 "Interface\n"
4778 "Neighbor holdtime\n"
4779 "Upstream neighbor unicast destination address\n"
4780 "Downstream neighbor unicast source address\n"
4781 "Multicast group address\n"
4782 "Unicast source address\n")
4783{
4784 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
4785}
4786
4787DEFUN (test_pim_receive_prune,
4788 test_pim_receive_prune_cmd,
b181fa04 4789 "test pim receive prune INTERFACE (0-65535) A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
12e41d03
DL
4790 "Test\n"
4791 "Test PIM protocol\n"
4792 "Test PIM message reception\n"
4793 "Test PIM prune reception from neighbor\n"
4794 "Interface\n"
4795 "Neighbor holdtime\n"
4796 "Upstream neighbor unicast destination address\n"
4797 "Downstream neighbor unicast source address\n"
4798 "Multicast group address\n"
4799 "Unicast source address\n")
4800{
4801 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
4802}
4803
4804DEFUN (test_pim_receive_upcall,
4805 test_pim_receive_upcall_cmd,
b181fa04 4806 "test pim receive upcall <nocache|wrongvif|wholepkt> (0-65535) A.B.C.D A.B.C.D",
12e41d03
DL
4807 "Test\n"
4808 "Test PIM protocol\n"
4809 "Test PIM message reception\n"
4810 "Test reception of kernel upcall\n"
4811 "NOCACHE kernel upcall\n"
4812 "WRONGVIF kernel upcall\n"
4813 "WHOLEPKT kernel upcall\n"
4814 "Input interface vif index\n"
4815 "Multicast group address\n"
4816 "Multicast source address\n")
4817{
b181fa04
DW
4818 int idx_type = 4;
4819 int idx_number = 5;
4820 int idx_ipv4 = 6;
4821 int idx_ipv4_2 = 7;
12e41d03
DL
4822 struct igmpmsg msg;
4823 const char *upcall_type;
4824 const char *group_str;
4825 const char *source_str;
4826 int result;
4827
b181fa04 4828 upcall_type = argv[idx_type]->arg;
12e41d03
DL
4829
4830 if (upcall_type[0] == 'n')
4831 msg.im_msgtype = IGMPMSG_NOCACHE;
4832 else if (upcall_type[1] == 'r')
4833 msg.im_msgtype = IGMPMSG_WRONGVIF;
4834 else if (upcall_type[1] == 'h')
4835 msg.im_msgtype = IGMPMSG_WHOLEPKT;
4836 else {
4837 vty_out(vty, "Unknown kernel upcall type: %s%s",
4838 upcall_type, VTY_NEWLINE);
4839 return CMD_WARNING;
4840 }
4841
b181fa04 4842 msg.im_vif = atoi(argv[idx_number]->arg);
12e41d03
DL
4843
4844 /* Group address */
b181fa04 4845 group_str = argv[idx_ipv4]->arg;
12e41d03
DL
4846 result = inet_pton(AF_INET, group_str, &msg.im_dst);
4847 if (result <= 0) {
4848 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4849 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4850 return CMD_WARNING;
4851 }
4852
4853 /* Source address */
b181fa04 4854 source_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
4855 result = inet_pton(AF_INET, source_str, &msg.im_src);
4856 if (result <= 0) {
4857 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4858 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4859 return CMD_WARNING;
4860 }
4861
4862 msg.im_mbz = 0; /* Must be zero */
4863
4864 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
4865 if (result) {
4866 vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
4867 sizeof(msg), result, VTY_NEWLINE);
4868 return CMD_WARNING;
4869 }
4870
4871 return CMD_SUCCESS;
4872}
4873
4874void pim_cmd_init()
4875{
4876 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
4877 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
0b84f294 4878 if_cmd_init ();
12e41d03
DL
4879
4880 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
4881 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
981d6c7a
DS
4882 install_element (CONFIG_NODE, &ip_pim_rp_cmd);
4883 install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
dfe43e25
DW
4884 install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
4885 install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
4304f95c
DS
4886 install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
4887 install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
01408ede
DS
4888 install_element (CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
4889 install_element (CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
12e41d03
DL
4890 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
4891 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
0b84f294 4892
12e41d03
DL
4893 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
4894 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
4895 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
4896 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
4897 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
4898 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
4899 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
4900 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
4901 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
4902 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
4903 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
dedccda6 4904 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
981d6c7a 4905 install_element (INTERFACE_NODE, &interface_ip_pim_sm_cmd);
8371bd60 4906 install_element (INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
dedccda6
DS
4907 install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
4908 install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
7960fa8f 4909 install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
7960fa8f 4910 install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
12e41d03 4911
6250610a
JAG
4912 // Static mroutes NEB
4913 install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
4914 install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
4915 install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
4916 install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
4917
12e41d03
DL
4918 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
4919 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
4920 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
4921 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
4922 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4923 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
4924 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4925 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
4926 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
4927 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
4928 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
4929 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
4930 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
4931 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
4932 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
4933 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
4934 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
4935 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
4936 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
4937 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
4938 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
4939 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
4940 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
4941 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
4942 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
00d07c6f 4943 install_element (VIEW_NODE, &show_ip_pim_rp_cmd);
12e41d03
DL
4944 install_element (VIEW_NODE, &show_ip_multicast_cmd);
4945 install_element (VIEW_NODE, &show_ip_mroute_cmd);
4946 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
4947 install_element (VIEW_NODE, &show_ip_rib_cmd);
4948 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 4949 install_element (VIEW_NODE, &show_debugging_pim_cmd);
12e41d03 4950
0b1442e3
DS
4951 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
4952
12e41d03
DL
4953 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
4954 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
4955 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
4956 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
4957 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
4958
12e41d03
DL
4959 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
4960 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
4961 install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
4962 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
4963 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
4964 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
4965 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
4966
4967 install_element (ENABLE_NODE, &debug_igmp_cmd);
4968 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
12e41d03
DL
4969 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
4970 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
12e41d03
DL
4971 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
4972 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
12e41d03
DL
4973 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
4974 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
12e41d03 4975 install_element (ENABLE_NODE, &debug_mroute_cmd);
6c7197b1 4976 install_element (ENABLE_NODE, &debug_mroute_detail_cmd);
12e41d03 4977 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
6c7197b1 4978 install_element (ENABLE_NODE, &no_debug_mroute_detail_cmd);
6250610a
JAG
4979 install_element (ENABLE_NODE, &debug_static_cmd);
4980 install_element (ENABLE_NODE, &no_debug_static_cmd);
12e41d03
DL
4981 install_element (ENABLE_NODE, &debug_pim_cmd);
4982 install_element (ENABLE_NODE, &no_debug_pim_cmd);
12e41d03
DL
4983 install_element (ENABLE_NODE, &debug_pim_events_cmd);
4984 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
12e41d03
DL
4985 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
4986 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
4987 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
4988 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
12e41d03
DL
4989 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
4990 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
12e41d03
DL
4991 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
4992 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
12e41d03
DL
4993 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
4994 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
12e41d03
DL
4995 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
4996 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
12e41d03
DL
4997 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
4998 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
12e41d03
DL
4999
5000 install_element (CONFIG_NODE, &debug_igmp_cmd);
5001 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
12e41d03
DL
5002 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
5003 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
12e41d03
DL
5004 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
5005 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
12e41d03
DL
5006 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
5007 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
12e41d03 5008 install_element (CONFIG_NODE, &debug_mroute_cmd);
6c7197b1 5009 install_element (CONFIG_NODE, &debug_mroute_detail_cmd);
12e41d03 5010 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
6c7197b1 5011 install_element (CONFIG_NODE, &no_debug_mroute_detail_cmd);
6250610a
JAG
5012 install_element (CONFIG_NODE, &debug_static_cmd);
5013 install_element (CONFIG_NODE, &no_debug_static_cmd);
12e41d03
DL
5014 install_element (CONFIG_NODE, &debug_pim_cmd);
5015 install_element (CONFIG_NODE, &no_debug_pim_cmd);
12e41d03
DL
5016 install_element (CONFIG_NODE, &debug_pim_events_cmd);
5017 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
12e41d03
DL
5018 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
5019 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
5020 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
5021 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
12e41d03
DL
5022 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
5023 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
12e41d03
DL
5024 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
5025 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
12e41d03
DL
5026 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
5027 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
12e41d03 5028}