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