]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
zebra: CHECK ME fixes
[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,
2504 PIM_CMD_IP_MULTICAST_ROUTING,
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,
2517 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
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;
b181fa04 2540 const char *source_str = (argc > 0) ? 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;
b181fa04 2570 const char *source_str = (argc > 0) ? 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,
b181fa04 2877 PIM_CMD_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,
2936 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
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,
b181fa04 2972 PIM_CMD_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,
3029 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
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,
b181fa04 3065 PIM_CMD_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,
3125 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
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
f412b39a
DW
3554/*
3555 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3556 * "ip pim hello <1-180> <1-180>",
3557 * IP_STR
3558 * PIM_STR
3559 * IFACE_PIM_HELLO_STR
3560 * IFACE_PIM_HELLO_TIME_STR
3561 * IFACE_PIM_HELLO_HOLD_STR
3562 *
3563 */
7960fa8f
DS
3564DEFUN (interface_ip_pim_hello,
3565 interface_ip_pim_hello_cmd,
b181fa04 3566 "ip pim hello (1-180)",
7960fa8f
DS
3567 IP_STR
3568 PIM_STR
3569 IFACE_PIM_HELLO_STR
3570 IFACE_PIM_HELLO_TIME_STR)
3571{
b181fa04 3572 int idx_number = 3;
7960fa8f
DS
3573 struct interface *ifp;
3574 struct pim_interface *pim_ifp;
3575
3576 ifp = vty->index;
3577 pim_ifp = ifp->info;
3578
3579 if (!pim_ifp) {
3580 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3581 return CMD_WARNING;
3582 }
3583
b181fa04 3584 pim_ifp->pim_hello_period = strtol(argv[idx_number]->arg, NULL, 10);
7960fa8f
DS
3585
3586 if (argc == 2)
91ac1d43 3587 pim_ifp->pim_default_holdtime = strtol(argv[4]->arg, NULL, 10);
7960fa8f
DS
3588
3589 return CMD_SUCCESS;
3590}
3591
7960fa8f
DS
3592
3593
3594DEFUN (interface_no_ip_pim_hello,
3595 interface_no_ip_pim_hello_cmd,
b181fa04 3596 "no ip pim hello [(1-180) (1-180)]",
7960fa8f
DS
3597 NO_STR
3598 IP_STR
3599 PIM_STR
3600 IFACE_PIM_HELLO_STR
3601 IFACE_PIM_HELLO_TIME_STR
3602 IFACE_PIM_HELLO_HOLD_STR)
3603{
3604 struct interface *ifp;
3605 struct pim_interface *pim_ifp;
3606
3607 ifp = vty->index;
3608 pim_ifp = ifp->info;
3609
3610 if (!pim_ifp) {
3611 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
3612 return CMD_WARNING;
3613 }
3614
3615 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
3616 pim_ifp->pim_default_holdtime = -1;
3617
3618 return CMD_SUCCESS;
3619}
3620
12e41d03
DL
3621DEFUN (debug_igmp,
3622 debug_igmp_cmd,
3623 "debug igmp",
3624 DEBUG_STR
3625 DEBUG_IGMP_STR)
3626{
3627 PIM_DO_DEBUG_IGMP_EVENTS;
3628 PIM_DO_DEBUG_IGMP_PACKETS;
3629 PIM_DO_DEBUG_IGMP_TRACE;
3630 return CMD_SUCCESS;
3631}
3632
f412b39a
DW
3633/*
3634 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3635 * "undebug igmp",
3636 * UNDEBUG_STR
3637 * DEBUG_IGMP_STR
3638 *
3639 */
12e41d03
DL
3640DEFUN (no_debug_igmp,
3641 no_debug_igmp_cmd,
3642 "no debug igmp",
3643 NO_STR
3644 DEBUG_STR
3645 DEBUG_IGMP_STR)
3646{
3647 PIM_DONT_DEBUG_IGMP_EVENTS;
3648 PIM_DONT_DEBUG_IGMP_PACKETS;
3649 PIM_DONT_DEBUG_IGMP_TRACE;
3650 return CMD_SUCCESS;
3651}
3652
12e41d03
DL
3653
3654DEFUN (debug_igmp_events,
3655 debug_igmp_events_cmd,
3656 "debug igmp events",
3657 DEBUG_STR
3658 DEBUG_IGMP_STR
3659 DEBUG_IGMP_EVENTS_STR)
3660{
3661 PIM_DO_DEBUG_IGMP_EVENTS;
3662 return CMD_SUCCESS;
3663}
3664
f412b39a
DW
3665/*
3666 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3667 * "undebug igmp events",
3668 * UNDEBUG_STR
3669 * DEBUG_IGMP_STR
3670 * DEBUG_IGMP_EVENTS_STR
3671 *
3672 */
12e41d03
DL
3673DEFUN (no_debug_igmp_events,
3674 no_debug_igmp_events_cmd,
3675 "no debug igmp events",
3676 NO_STR
3677 DEBUG_STR
3678 DEBUG_IGMP_STR
3679 DEBUG_IGMP_EVENTS_STR)
3680{
3681 PIM_DONT_DEBUG_IGMP_EVENTS;
3682 return CMD_SUCCESS;
3683}
3684
12e41d03
DL
3685
3686DEFUN (debug_igmp_packets,
3687 debug_igmp_packets_cmd,
3688 "debug igmp packets",
3689 DEBUG_STR
3690 DEBUG_IGMP_STR
3691 DEBUG_IGMP_PACKETS_STR)
3692{
3693 PIM_DO_DEBUG_IGMP_PACKETS;
3694 return CMD_SUCCESS;
3695}
3696
f412b39a
DW
3697/*
3698 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3699 * "undebug igmp packets",
3700 * UNDEBUG_STR
3701 * DEBUG_IGMP_STR
3702 * DEBUG_IGMP_PACKETS_STR
3703 *
3704 */
12e41d03
DL
3705DEFUN (no_debug_igmp_packets,
3706 no_debug_igmp_packets_cmd,
3707 "no debug igmp packets",
3708 NO_STR
3709 DEBUG_STR
3710 DEBUG_IGMP_STR
3711 DEBUG_IGMP_PACKETS_STR)
3712{
3713 PIM_DONT_DEBUG_IGMP_PACKETS;
3714 return CMD_SUCCESS;
3715}
3716
12e41d03
DL
3717
3718DEFUN (debug_igmp_trace,
3719 debug_igmp_trace_cmd,
3720 "debug igmp trace",
3721 DEBUG_STR
3722 DEBUG_IGMP_STR
3723 DEBUG_IGMP_TRACE_STR)
3724{
3725 PIM_DO_DEBUG_IGMP_TRACE;
3726 return CMD_SUCCESS;
3727}
3728
f412b39a
DW
3729/*
3730 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3731 * "undebug igmp trace",
3732 * UNDEBUG_STR
3733 * DEBUG_IGMP_STR
3734 * DEBUG_IGMP_TRACE_STR
3735 *
3736 */
12e41d03
DL
3737DEFUN (no_debug_igmp_trace,
3738 no_debug_igmp_trace_cmd,
3739 "no debug igmp trace",
3740 NO_STR
3741 DEBUG_STR
3742 DEBUG_IGMP_STR
3743 DEBUG_IGMP_TRACE_STR)
3744{
3745 PIM_DONT_DEBUG_IGMP_TRACE;
3746 return CMD_SUCCESS;
3747}
3748
12e41d03
DL
3749
3750DEFUN (debug_mroute,
3751 debug_mroute_cmd,
3752 "debug mroute",
3753 DEBUG_STR
3754 DEBUG_MROUTE_STR)
3755{
3756 PIM_DO_DEBUG_MROUTE;
3757 return CMD_SUCCESS;
3758}
3759
f412b39a
DW
3760/*
3761 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3762 * "undebug mroute",
3763 * UNDEBUG_STR
3764 * DEBUG_MROUTE_STR
3765 *
3766 */
12e41d03
DL
3767DEFUN (no_debug_mroute,
3768 no_debug_mroute_cmd,
3769 "no debug mroute",
3770 NO_STR
3771 DEBUG_STR
3772 DEBUG_MROUTE_STR)
3773{
3774 PIM_DONT_DEBUG_MROUTE;
3775 return CMD_SUCCESS;
3776}
3777
12e41d03 3778
6250610a
JAG
3779DEFUN (debug_static,
3780 debug_static_cmd,
3781 "debug static",
3782 DEBUG_STR
3783 DEBUG_STATIC_STR)
3784{
3785 PIM_DO_DEBUG_STATIC;
3786 return CMD_SUCCESS;
3787}
3788
f412b39a
DW
3789/*
3790 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3791 * "undebug static",
3792 * UNDEBUG_STR
3793 * DEBUG_STATIC_STR
3794 *
3795 */
6250610a
JAG
3796DEFUN (no_debug_static,
3797 no_debug_static_cmd,
3798 "no debug static",
3799 NO_STR
3800 DEBUG_STR
3801 DEBUG_STATIC_STR)
3802{
3803 PIM_DONT_DEBUG_STATIC;
3804 return CMD_SUCCESS;
3805}
3806
6250610a 3807
12e41d03
DL
3808DEFUN (debug_pim,
3809 debug_pim_cmd,
3810 "debug pim",
3811 DEBUG_STR
3812 DEBUG_PIM_STR)
3813{
3814 PIM_DO_DEBUG_PIM_EVENTS;
3815 PIM_DO_DEBUG_PIM_PACKETS;
3816 PIM_DO_DEBUG_PIM_TRACE;
3817 return CMD_SUCCESS;
3818}
3819
f412b39a
DW
3820/*
3821 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3822 * "undebug pim",
3823 * UNDEBUG_STR
3824 * DEBUG_PIM_STR
3825 *
3826 */
12e41d03
DL
3827DEFUN (no_debug_pim,
3828 no_debug_pim_cmd,
3829 "no debug pim",
3830 NO_STR
3831 DEBUG_STR
3832 DEBUG_PIM_STR)
3833{
3834 PIM_DONT_DEBUG_PIM_EVENTS;
3835 PIM_DONT_DEBUG_PIM_PACKETS;
3836 PIM_DONT_DEBUG_PIM_TRACE;
3837
3838 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3839 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3840
3841 return CMD_SUCCESS;
3842}
3843
12e41d03
DL
3844
3845DEFUN (debug_pim_events,
3846 debug_pim_events_cmd,
3847 "debug pim events",
3848 DEBUG_STR
3849 DEBUG_PIM_STR
3850 DEBUG_PIM_EVENTS_STR)
3851{
3852 PIM_DO_DEBUG_PIM_EVENTS;
3853 return CMD_SUCCESS;
3854}
3855
f412b39a
DW
3856/*
3857 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3858 * "undebug pim events",
3859 * UNDEBUG_STR
3860 * DEBUG_PIM_STR
3861 * DEBUG_PIM_EVENTS_STR
3862 *
3863 */
12e41d03
DL
3864DEFUN (no_debug_pim_events,
3865 no_debug_pim_events_cmd,
3866 "no debug pim events",
3867 NO_STR
3868 DEBUG_STR
3869 DEBUG_PIM_STR
3870 DEBUG_PIM_EVENTS_STR)
3871{
3872 PIM_DONT_DEBUG_PIM_EVENTS;
3873 return CMD_SUCCESS;
3874}
3875
12e41d03
DL
3876
3877DEFUN (debug_pim_packets,
3878 debug_pim_packets_cmd,
3879 "debug pim packets",
3880 DEBUG_STR
3881 DEBUG_PIM_STR
3882 DEBUG_PIM_PACKETS_STR)
3883{
3884 PIM_DO_DEBUG_PIM_PACKETS;
3885 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
3886 return CMD_SUCCESS;
3887}
3888
3889DEFUN (debug_pim_packets_filter,
3890 debug_pim_packets_filter_cmd,
b181fa04 3891 "debug pim packets <hello|joins>",
12e41d03
DL
3892 DEBUG_STR
3893 DEBUG_PIM_STR
3894 DEBUG_PIM_PACKETS_STR
3895 DEBUG_PIM_HELLO_PACKETS_STR
3896 DEBUG_PIM_J_P_PACKETS_STR)
3897{
b181fa04
DW
3898 int idx_hello_join = 3;
3899 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
12e41d03
DL
3900 {
3901 PIM_DO_DEBUG_PIM_HELLO;
3902 vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
3903 }
b181fa04 3904 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
12e41d03
DL
3905 {
3906 PIM_DO_DEBUG_PIM_J_P;
3907 vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
3908 }
3909 return CMD_SUCCESS;
3910}
3911
f412b39a
DW
3912/*
3913 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3914 * "undebug pim packets",
3915 * UNDEBUG_STR
3916 * DEBUG_PIM_STR
3917 * DEBUG_PIM_PACKETS_STR
3918 *
3919 */
12e41d03
DL
3920DEFUN (no_debug_pim_packets,
3921 no_debug_pim_packets_cmd,
3922 "no debug pim packets",
3923 NO_STR
3924 DEBUG_STR
3925 DEBUG_PIM_STR
3926 DEBUG_PIM_PACKETS_STR
3927 DEBUG_PIM_HELLO_PACKETS_STR
3928 DEBUG_PIM_J_P_PACKETS_STR)
3929{
3930 PIM_DONT_DEBUG_PIM_PACKETS;
3931 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
3932 return CMD_SUCCESS;
3933}
3934
3935DEFUN (no_debug_pim_packets_filter,
3936 no_debug_pim_packets_filter_cmd,
b181fa04 3937 "no debug pim packets <hello|joins>",
12e41d03
DL
3938 NO_STR
3939 DEBUG_STR
3940 DEBUG_PIM_STR
3941 DEBUG_PIM_PACKETS_STR
3942 DEBUG_PIM_HELLO_PACKETS_STR
3943 DEBUG_PIM_J_P_PACKETS_STR)
3944{
b181fa04
DW
3945 int idx_hello_join = 4;
3946 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
12e41d03
DL
3947 {
3948 PIM_DONT_DEBUG_PIM_HELLO;
3949 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
3950 }
b181fa04 3951 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
12e41d03
DL
3952 {
3953 PIM_DONT_DEBUG_PIM_J_P;
3954 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
3955 }
3956 return CMD_SUCCESS;
3957}
3958
12e41d03
DL
3959
3960DEFUN (debug_pim_packetdump_send,
3961 debug_pim_packetdump_send_cmd,
3962 "debug pim packet-dump send",
3963 DEBUG_STR
3964 DEBUG_PIM_STR
3965 DEBUG_PIM_PACKETDUMP_STR
3966 DEBUG_PIM_PACKETDUMP_SEND_STR)
3967{
3968 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
3969 return CMD_SUCCESS;
3970}
3971
f412b39a
DW
3972/*
3973 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3974 * "undebug pim packet-dump send",
3975 * UNDEBUG_STR
3976 * DEBUG_PIM_STR
3977 * DEBUG_PIM_PACKETDUMP_STR
3978 * DEBUG_PIM_PACKETDUMP_SEND_STR
3979 *
3980 */
12e41d03
DL
3981DEFUN (no_debug_pim_packetdump_send,
3982 no_debug_pim_packetdump_send_cmd,
3983 "no debug pim packet-dump send",
3984 NO_STR
3985 DEBUG_STR
3986 DEBUG_PIM_STR
3987 DEBUG_PIM_PACKETDUMP_STR
3988 DEBUG_PIM_PACKETDUMP_SEND_STR)
3989{
3990 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3991 return CMD_SUCCESS;
3992}
3993
12e41d03
DL
3994
3995DEFUN (debug_pim_packetdump_recv,
3996 debug_pim_packetdump_recv_cmd,
3997 "debug pim packet-dump receive",
3998 DEBUG_STR
3999 DEBUG_PIM_STR
4000 DEBUG_PIM_PACKETDUMP_STR
4001 DEBUG_PIM_PACKETDUMP_RECV_STR)
4002{
4003 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
4004 return CMD_SUCCESS;
4005}
4006
f412b39a
DW
4007/*
4008 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4009 * "undebug pim packet-dump receive",
4010 * UNDEBUG_STR
4011 * DEBUG_PIM_STR
4012 * DEBUG_PIM_PACKETDUMP_STR
4013 * DEBUG_PIM_PACKETDUMP_RECV_STR
4014 *
4015 */
12e41d03
DL
4016DEFUN (no_debug_pim_packetdump_recv,
4017 no_debug_pim_packetdump_recv_cmd,
4018 "no debug pim packet-dump receive",
4019 NO_STR
4020 DEBUG_STR
4021 DEBUG_PIM_STR
4022 DEBUG_PIM_PACKETDUMP_STR
4023 DEBUG_PIM_PACKETDUMP_RECV_STR)
4024{
4025 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4026 return CMD_SUCCESS;
4027}
4028
12e41d03
DL
4029
4030DEFUN (debug_pim_trace,
4031 debug_pim_trace_cmd,
4032 "debug pim trace",
4033 DEBUG_STR
4034 DEBUG_PIM_STR
4035 DEBUG_PIM_TRACE_STR)
4036{
4037 PIM_DO_DEBUG_PIM_TRACE;
4038 return CMD_SUCCESS;
4039}
4040
f412b39a
DW
4041/*
4042 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4043 * "undebug pim trace",
4044 * UNDEBUG_STR
4045 * DEBUG_PIM_STR
4046 * DEBUG_PIM_TRACE_STR
4047 *
4048 */
12e41d03
DL
4049DEFUN (no_debug_pim_trace,
4050 no_debug_pim_trace_cmd,
4051 "no debug pim trace",
4052 NO_STR
4053 DEBUG_STR
4054 DEBUG_PIM_STR
4055 DEBUG_PIM_TRACE_STR)
4056{
4057 PIM_DONT_DEBUG_PIM_TRACE;
4058 return CMD_SUCCESS;
4059}
4060
12e41d03
DL
4061
4062DEFUN (debug_ssmpingd,
4063 debug_ssmpingd_cmd,
4064 "debug ssmpingd",
4065 DEBUG_STR
4066 DEBUG_PIM_STR
4067 DEBUG_SSMPINGD_STR)
4068{
4069 PIM_DO_DEBUG_SSMPINGD;
4070 return CMD_SUCCESS;
4071}
4072
f412b39a
DW
4073/*
4074 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4075 * "undebug ssmpingd",
4076 * UNDEBUG_STR
4077 * DEBUG_PIM_STR
4078 * DEBUG_SSMPINGD_STR
4079 *
4080 */
12e41d03
DL
4081DEFUN (no_debug_ssmpingd,
4082 no_debug_ssmpingd_cmd,
4083 "no debug ssmpingd",
4084 NO_STR
4085 DEBUG_STR
4086 DEBUG_PIM_STR
4087 DEBUG_SSMPINGD_STR)
4088{
4089 PIM_DONT_DEBUG_SSMPINGD;
4090 return CMD_SUCCESS;
4091}
4092
12e41d03
DL
4093
4094DEFUN (debug_pim_zebra,
4095 debug_pim_zebra_cmd,
4096 "debug pim zebra",
4097 DEBUG_STR
4098 DEBUG_PIM_STR
4099 DEBUG_PIM_ZEBRA_STR)
4100{
4101 PIM_DO_DEBUG_ZEBRA;
4102 return CMD_SUCCESS;
4103}
4104
f412b39a
DW
4105/*
4106 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4107 * "undebug pim zebra",
4108 * UNDEBUG_STR
4109 * DEBUG_PIM_STR
4110 * DEBUG_PIM_ZEBRA_STR
4111 *
4112 */
12e41d03
DL
4113DEFUN (no_debug_pim_zebra,
4114 no_debug_pim_zebra_cmd,
4115 "no debug pim zebra",
4116 NO_STR
4117 DEBUG_STR
4118 DEBUG_PIM_STR
4119 DEBUG_PIM_ZEBRA_STR)
4120{
4121 PIM_DONT_DEBUG_ZEBRA;
4122 return CMD_SUCCESS;
4123}
4124
12e41d03 4125
7a1d58ce
DS
4126DEFUN (show_debugging_pim,
4127 show_debugging_pim_cmd,
4128 "show debugging pim",
12e41d03 4129 SHOW_STR
7a1d58ce
DS
4130 DEBUG_STR
4131 PIM_STR)
12e41d03
DL
4132{
4133 pim_debug_config_write(vty);
4134 return CMD_SUCCESS;
4135}
4136
4137static struct igmp_sock *find_igmp_sock_by_fd(int fd)
4138{
4139 struct listnode *ifnode;
4140 struct interface *ifp;
4141
4142 /* scan all interfaces */
469351b3 4143 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
4144 struct pim_interface *pim_ifp;
4145 struct igmp_sock *igmp;
4146
4147 if (!ifp->info)
4148 continue;
4149
4150 pim_ifp = ifp->info;
4151
4152 /* lookup igmp socket under current interface */
4153 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
4154 if (igmp)
4155 return igmp;
4156 }
4157
4158 return 0;
4159}
4160
4161DEFUN (test_igmp_receive_report,
4162 test_igmp_receive_report_cmd,
b181fa04 4163 "test igmp receive report (0-65535) A.B.C.D (1-6) .LINE",
12e41d03
DL
4164 "Test\n"
4165 "Test IGMP protocol\n"
4166 "Test IGMP message\n"
4167 "Test IGMP report\n"
4168 "Socket\n"
4169 "IGMP group address\n"
4170 "Record type\n"
4171 "Sources\n")
4172{
b181fa04
DW
4173 int idx_number = 4;
4174 int idx_ipv4 = 5;
4175 int idx_number_2 = 6;
12e41d03
DL
4176 char buf[1000];
4177 char *igmp_msg;
4178 struct ip *ip_hdr;
4179 size_t ip_hlen; /* ip header length in bytes */
4180 int ip_msg_len;
4181 int igmp_msg_len;
4182 const char *socket;
4183 int socket_fd;
4184 const char *grp_str;
4185 struct in_addr grp_addr;
4186 const char *record_type_str;
4187 int record_type;
4188 const char *src_str;
4189 int result;
4190 struct igmp_sock *igmp;
4191 char *group_record;
4192 int num_sources;
4193 struct in_addr *sources;
4194 struct in_addr *src_addr;
4195 int argi;
4196
b181fa04 4197 socket = argv[idx_number]->arg;
12e41d03
DL
4198 socket_fd = atoi(socket);
4199 igmp = find_igmp_sock_by_fd(socket_fd);
4200 if (!igmp) {
4201 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
4202 socket, socket_fd, VTY_NEWLINE);
4203 return CMD_WARNING;
4204 }
4205
b181fa04 4206 grp_str = argv[idx_ipv4]->arg;
12e41d03
DL
4207 result = inet_pton(AF_INET, grp_str, &grp_addr);
4208 if (result <= 0) {
4209 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4210 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4211 return CMD_WARNING;
4212 }
4213
b181fa04 4214 record_type_str = argv[idx_number_2]->arg;
12e41d03
DL
4215 record_type = atoi(record_type_str);
4216
4217 /*
4218 Tweak IP header
4219 */
4220 ip_hdr = (struct ip *) buf;
4221 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
4222 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4223 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4224 ip_hdr->ip_src = igmp->ifaddr;
4225 ip_hdr->ip_dst = igmp->ifaddr;
4226
4227 /*
4228 Build IGMP v3 report message
4229 */
4230 igmp_msg = buf + ip_hlen;
4231 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
4232 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
4233 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
4234 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
4235 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
4236 memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
4237
4238 /* Scan LINE sources */
4239 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
4240 src_addr = sources;
4241 for (argi = 3; argi < argc; ++argi,++src_addr) {
91ac1d43 4242 src_str = argv[argi]->arg;
12e41d03
DL
4243 result = inet_pton(AF_INET, src_str, src_addr);
4244 if (result <= 0) {
4245 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4246 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4247 return CMD_WARNING;
4248 }
4249 }
4250 num_sources = src_addr - sources;
4251
4252 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
4253
4254 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
4255
4256 /* compute checksum */
4257 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
4258
4259 /* "receive" message */
4260
4261 ip_msg_len = ip_hlen + igmp_msg_len;
4262 result = pim_igmp_packet(igmp, buf, ip_msg_len);
4263 if (result) {
4264 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
4265 ip_msg_len, result, VTY_NEWLINE);
4266 return CMD_WARNING;
4267 }
4268
4269 return CMD_SUCCESS;
4270}
4271
4272static int hexval(uint8_t ch)
4273{
4274 return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
4275}
4276
4277DEFUN (test_pim_receive_dump,
4278 test_pim_receive_dump_cmd,
4279 "test pim receive dump INTERFACE A.B.C.D .LINE",
4280 "Test\n"
4281 "Test PIM protocol\n"
4282 "Test PIM message reception\n"
4283 "Test PIM packet dump reception from neighbor\n"
4284 "Interface\n"
4285 "Neighbor address\n"
4286 "Packet dump\n")
4287{
b181fa04
DW
4288 int idx_interface = 4;
4289 int idx_ipv4 = 5;
12e41d03
DL
4290 uint8_t buf[1000];
4291 uint8_t *pim_msg;
4292 struct ip *ip_hdr;
4293 size_t ip_hlen; /* ip header length in bytes */
4294 int ip_msg_len;
4295 int pim_msg_size;
4296 const char *neigh_str;
4297 struct in_addr neigh_addr;
4298 const char *ifname;
4299 struct interface *ifp;
4300 int argi;
4301 int result;
4302
4303 /* Find interface */
b181fa04 4304 ifname = argv[idx_interface]->arg;
12e41d03
DL
4305 ifp = if_lookup_by_name(ifname);
4306 if (!ifp) {
4307 vty_out(vty, "No such interface name %s%s",
4308 ifname, VTY_NEWLINE);
4309 return CMD_WARNING;
4310 }
4311
4312 /* Neighbor address */
b181fa04 4313 neigh_str = argv[idx_ipv4]->arg;
12e41d03
DL
4314 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4315 if (result <= 0) {
4316 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4317 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4318 return CMD_WARNING;
4319 }
4320
4321 /*
4322 Tweak IP header
4323 */
4324 ip_hdr = (struct ip *) buf;
4325 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4326 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4327 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4328 ip_hdr->ip_src = neigh_addr;
4329 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4330
4331 /*
4332 Build PIM hello message
4333 */
4334 pim_msg = buf + ip_hlen;
4335 pim_msg_size = 0;
4336
4337 /* Scan LINE dump into buffer */
4338 for (argi = 2; argi < argc; ++argi) {
91ac1d43 4339 const char *str = argv[argi]->arg;
12e41d03
DL
4340 int str_len = strlen(str);
4341 int str_last = str_len - 1;
4342 int i;
4343
4344 if (str_len % 2) {
4345 vty_out(vty, "%% Uneven hex array arg %d=%s%s",
4346 argi, str, VTY_NEWLINE);
4347 return CMD_WARNING;
4348 }
4349
4350 for (i = 0; i < str_last; i += 2) {
4351 uint8_t octet;
4352 int left;
4353 uint8_t h1 = str[i];
4354 uint8_t h2 = str[i + 1];
4355
4356 if (!isxdigit(h1) || !isxdigit(h2)) {
4357 vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
4358 h1, h2, argi, str, VTY_NEWLINE);
4359 return CMD_WARNING;
4360 }
4361 octet = (hexval(h1) << 4) + hexval(h2);
4362
4363 left = sizeof(buf) - ip_hlen - pim_msg_size;
4364 if (left < 1) {
4365 vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
4366 sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
4367 return CMD_WARNING;
4368 }
4369
4370 pim_msg[pim_msg_size++] = octet;
4371 }
4372 }
4373
4374 ip_msg_len = ip_hlen + pim_msg_size;
4375
4376 vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
4377 sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
4378
4379 /* "receive" message */
4380
4381 result = pim_pim_packet(ifp, buf, ip_msg_len);
4382 if (result) {
4383 vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
4384 ip_msg_len, result, VTY_NEWLINE);
4385 return CMD_WARNING;
4386 }
4387
4388 return CMD_SUCCESS;
4389}
4390
4391DEFUN (test_pim_receive_hello,
4392 test_pim_receive_hello_cmd,
b181fa04 4393 "test pim receive hello INTERFACE A.B.C.D (0-65535) (0-65535) (0-65535) (0-32767) (0-65535) (0-1) [LINE]",
12e41d03
DL
4394 "Test\n"
4395 "Test PIM protocol\n"
4396 "Test PIM message reception\n"
4397 "Test PIM hello reception from neighbor\n"
4398 "Interface\n"
4399 "Neighbor address\n"
4400 "Neighbor holdtime\n"
4401 "Neighbor DR priority\n"
4402 "Neighbor generation ID\n"
4403 "Neighbor propagation delay (msec)\n"
4404 "Neighbor override interval (msec)\n"
4405 "Neighbor LAN prune delay T-bit\n"
4406 "Neighbor secondary addresses\n")
4407{
b181fa04
DW
4408 int idx_interface = 4;
4409 int idx_ipv4 = 5;
4410 int idx_number = 6;
4411 int idx_number_2 = 7;
4412 int idx_number_3 = 8;
4413 int idx_number_4 = 9;
4414 int idx_number_5 = 10;
4415 int idx_number_6 = 11;
12e41d03
DL
4416 uint8_t buf[1000];
4417 uint8_t *pim_msg;
4418 struct ip *ip_hdr;
4419 size_t ip_hlen; /* ip header length in bytes */
4420 int ip_msg_len;
4421 int pim_tlv_size;
4422 int pim_msg_size;
4423 const char *neigh_str;
4424 struct in_addr neigh_addr;
4425 const char *ifname;
4426 struct interface *ifp;
4427 uint16_t neigh_holdtime;
4428 uint16_t neigh_propagation_delay;
4429 uint16_t neigh_override_interval;
4430 int neigh_can_disable_join_suppression;
4431 uint32_t neigh_dr_priority;
4432 uint32_t neigh_generation_id;
4433 int argi;
4434 int result;
4435
4436 /* Find interface */
b181fa04 4437 ifname = argv[idx_interface]->arg;
12e41d03
DL
4438 ifp = if_lookup_by_name(ifname);
4439 if (!ifp) {
4440 vty_out(vty, "No such interface name %s%s",
4441 ifname, VTY_NEWLINE);
4442 return CMD_WARNING;
4443 }
4444
4445 /* Neighbor address */
b181fa04 4446 neigh_str = argv[idx_ipv4]->arg;
12e41d03
DL
4447 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4448 if (result <= 0) {
4449 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4450 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4451 return CMD_WARNING;
4452 }
4453
b181fa04
DW
4454 neigh_holdtime = atoi(argv[idx_number]->arg);
4455 neigh_dr_priority = atoi(argv[idx_number_2]->arg);
4456 neigh_generation_id = atoi(argv[idx_number_3]->arg);
4457 neigh_propagation_delay = atoi(argv[idx_number_4]->arg);
4458 neigh_override_interval = atoi(argv[idx_number_5]->arg);
4459 neigh_can_disable_join_suppression = atoi(argv[idx_number_6]->arg);
12e41d03
DL
4460
4461 /*
4462 Tweak IP header
4463 */
4464 ip_hdr = (struct ip *) buf;
4465 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4466 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4467 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4468 ip_hdr->ip_src = neigh_addr;
4469 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4470
4471 /*
4472 Build PIM hello message
4473 */
4474 pim_msg = buf + ip_hlen;
4475
4476 /* Scan LINE addresses */
4477 for (argi = 8; argi < argc; ++argi) {
91ac1d43 4478 const char *sec_str = argv[argi]->arg;
12e41d03
DL
4479 struct in_addr sec_addr;
4480 result = inet_pton(AF_INET, sec_str, &sec_addr);
4481 if (result <= 0) {
4482 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
4483 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
4484 return CMD_WARNING;
4485 }
4486
4487 vty_out(vty,
4488 "FIXME WRITEME consider neighbor secondary address %s%s",
4489 sec_str, VTY_NEWLINE);
4490 }
4491
4492 pim_tlv_size = pim_hello_build_tlv(ifp->name,
4493 pim_msg + PIM_PIM_MIN_LEN,
4494 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
4495 neigh_holdtime,
4496 neigh_dr_priority,
4497 neigh_generation_id,
4498 neigh_propagation_delay,
4499 neigh_override_interval,
4500 neigh_can_disable_join_suppression,
4501 0 /* FIXME secondary address list */);
4502 if (pim_tlv_size < 0) {
4503 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
4504 pim_tlv_size, VTY_NEWLINE);
4505 return CMD_WARNING;
4506 }
4507
4508 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
4509
4510 pim_msg_build_header(pim_msg, pim_msg_size,
4511 PIM_MSG_TYPE_HELLO);
4512
4513 /* "receive" message */
4514
4515 ip_msg_len = ip_hlen + pim_msg_size;
4516 result = pim_pim_packet(ifp, buf, ip_msg_len);
4517 if (result) {
4518 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4519 ip_msg_len, result, VTY_NEWLINE);
4520 return CMD_WARNING;
4521 }
4522
4523 return CMD_SUCCESS;
4524}
4525
4526DEFUN (test_pim_receive_assert,
4527 test_pim_receive_assert_cmd,
b181fa04 4528 "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
4529 "Test\n"
4530 "Test PIM protocol\n"
4531 "Test PIM message reception\n"
4532 "Test reception of PIM assert\n"
4533 "Interface\n"
4534 "Neighbor address\n"
4535 "Assert multicast group address\n"
4536 "Assert unicast source address\n"
4537 "Assert metric preference\n"
4538 "Assert route metric\n"
4539 "Assert RPT bit flag\n")
4540{
b181fa04
DW
4541 int idx_interface = 4;
4542 int idx_ipv4 = 5;
4543 int idx_ipv4_2 = 6;
4544 int idx_ipv4_3 = 7;
4545 int idx_number = 8;
4546 int idx_number_2 = 9;
4547 int idx_number_3 = 10;
12e41d03
DL
4548 uint8_t buf[1000];
4549 uint8_t *buf_pastend = buf + sizeof(buf);
4550 uint8_t *pim_msg;
4551 struct ip *ip_hdr;
4552 size_t ip_hlen; /* ip header length in bytes */
4553 int ip_msg_len;
4554 int pim_msg_size;
4555 const char *neigh_str;
4556 struct in_addr neigh_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 uint32_t assert_metric_preference;
4564 uint32_t assert_route_metric;
4565 uint32_t assert_rpt_bit_flag;
4566 int remain;
4567 int result;
4568
4569 /* Find interface */
b181fa04 4570 ifname = argv[idx_interface]->arg;
12e41d03
DL
4571 ifp = if_lookup_by_name(ifname);
4572 if (!ifp) {
4573 vty_out(vty, "No such interface name %s%s",
4574 ifname, VTY_NEWLINE);
4575 return CMD_WARNING;
4576 }
4577
4578 /* Neighbor address */
b181fa04 4579 neigh_str = argv[idx_ipv4]->arg;
12e41d03
DL
4580 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4581 if (result <= 0) {
4582 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4583 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4584 return CMD_WARNING;
4585 }
4586
4587 /* Group address */
b181fa04 4588 group_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
4589 result = inet_pton(AF_INET, group_str, &group_addr);
4590 if (result <= 0) {
4591 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4592 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4593 return CMD_WARNING;
4594 }
4595
4596 /* Source address */
b181fa04 4597 source_str = argv[idx_ipv4_3]->arg;
12e41d03
DL
4598 result = inet_pton(AF_INET, source_str, &source_addr);
4599 if (result <= 0) {
4600 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4601 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4602 return CMD_WARNING;
4603 }
4604
b181fa04
DW
4605 assert_metric_preference = atoi(argv[idx_number]->arg);
4606 assert_route_metric = atoi(argv[idx_number_2]->arg);
4607 assert_rpt_bit_flag = atoi(argv[idx_number_3]->arg);
12e41d03
DL
4608
4609 remain = buf_pastend - buf;
4610 if (remain < (int) sizeof(struct ip)) {
4611 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
4612 remain, sizeof(struct ip), VTY_NEWLINE);
4613 return CMD_WARNING;
4614 }
4615
4616 /*
4617 Tweak IP header
4618 */
4619 ip_hdr = (struct ip *) buf;
4620 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4621 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4622 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4623 ip_hdr->ip_src = neigh_addr;
4624 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4625
4626 /*
4627 Build PIM assert message
4628 */
4629 pim_msg = buf + ip_hlen; /* skip ip header */
4630
4631 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
4632 group_addr, source_addr,
4633 assert_metric_preference,
4634 assert_route_metric,
4635 assert_rpt_bit_flag);
4636 if (pim_msg_size < 0) {
4637 vty_out(vty, "Failure building PIM assert message: size=%d%s",
4638 pim_msg_size, VTY_NEWLINE);
4639 return CMD_WARNING;
4640 }
4641
4642 /* "receive" message */
4643
4644 ip_msg_len = ip_hlen + pim_msg_size;
4645 result = pim_pim_packet(ifp, buf, ip_msg_len);
4646 if (result) {
4647 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4648 ip_msg_len, result, VTY_NEWLINE);
4649 return CMD_WARNING;
4650 }
4651
4652 return CMD_SUCCESS;
4653}
4654
4655static int recv_joinprune(struct vty *vty,
91ac1d43 4656 struct cmd_token **argv,
12e41d03
DL
4657 int src_is_join)
4658{
4659 uint8_t buf[1000];
4660 const uint8_t *buf_pastend = buf + sizeof(buf);
4661 uint8_t *pim_msg;
4662 uint8_t *pim_msg_curr;
4663 int pim_msg_size;
4664 struct ip *ip_hdr;
4665 size_t ip_hlen; /* ip header length in bytes */
4666 int ip_msg_len;
4667 uint16_t neigh_holdtime;
4668 const char *neigh_dst_str;
4669 struct in_addr neigh_dst_addr;
4670 const char *neigh_src_str;
4671 struct in_addr neigh_src_addr;
4672 const char *group_str;
4673 struct in_addr group_addr;
4674 const char *source_str;
4675 struct in_addr source_addr;
4676 const char *ifname;
4677 struct interface *ifp;
4678 int result;
4679 int remain;
4680 uint16_t num_joined;
4681 uint16_t num_pruned;
4682
4683 /* Find interface */
91ac1d43 4684 ifname = argv[0]->arg;
12e41d03
DL
4685 ifp = if_lookup_by_name(ifname);
4686 if (!ifp) {
4687 vty_out(vty, "No such interface name %s%s",
4688 ifname, VTY_NEWLINE);
4689 return CMD_WARNING;
4690 }
4691
91ac1d43 4692 neigh_holdtime = atoi(argv[1]->arg);
12e41d03
DL
4693
4694 /* Neighbor destination address */
91ac1d43 4695 neigh_dst_str = argv[2]->arg;
12e41d03
DL
4696 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
4697 if (result <= 0) {
4698 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
4699 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
4700 return CMD_WARNING;
4701 }
4702
4703 /* Neighbor source address */
91ac1d43 4704 neigh_src_str = argv[3]->arg;
12e41d03
DL
4705 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
4706 if (result <= 0) {
4707 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
4708 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4709 return CMD_WARNING;
4710 }
4711
4712 /* Multicast group address */
91ac1d43 4713 group_str = argv[4]->arg;
12e41d03
DL
4714 result = inet_pton(AF_INET, group_str, &group_addr);
4715 if (result <= 0) {
4716 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4717 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4718 return CMD_WARNING;
4719 }
4720
4721 /* Multicast source address */
91ac1d43 4722 source_str = argv[5]->arg;
12e41d03
DL
4723 result = inet_pton(AF_INET, source_str, &source_addr);
4724 if (result <= 0) {
4725 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4726 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4727 return CMD_WARNING;
4728 }
4729
4730 /*
4731 Tweak IP header
4732 */
4733 ip_hdr = (struct ip *) buf;
4734 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4735 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4736 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4737 ip_hdr->ip_src = neigh_src_addr;
4738 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4739
4740 /*
4741 Build PIM message
4742 */
4743 pim_msg = buf + ip_hlen;
4744
4745 /* skip room for pim header */
4746 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
4747
4748 remain = buf_pastend - pim_msg_curr;
4749 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
4750 remain,
4751 neigh_dst_addr);
4752 if (!pim_msg_curr) {
4753 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
4754 neigh_dst_str, remain, VTY_NEWLINE);
4755 return CMD_WARNING;
4756 }
4757
4758 remain = buf_pastend - pim_msg_curr;
4759 if (remain < 4) {
4760 vty_out(vty, "Group will not fit: space left=%d%s",
4761 remain, VTY_NEWLINE);
4762 return CMD_WARNING;
4763 }
4764
4765 *pim_msg_curr = 0; /* reserved */
4766 ++pim_msg_curr;
4767 *pim_msg_curr = 1; /* number of groups */
4768 ++pim_msg_curr;
4769 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
4770 ++pim_msg_curr;
4771 ++pim_msg_curr;
4772
4773 remain = buf_pastend - pim_msg_curr;
4774 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
4775 remain,
4776 group_addr);
4777 if (!pim_msg_curr) {
4778 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
4779 group_str, remain, VTY_NEWLINE);
4780 return CMD_WARNING;
4781 }
4782
4783 remain = buf_pastend - pim_msg_curr;
4784 if (remain < 4) {
4785 vty_out(vty, "Sources will not fit: space left=%d%s",
4786 remain, VTY_NEWLINE);
4787 return CMD_WARNING;
4788 }
4789
4790 if (src_is_join) {
4791 num_joined = 1;
4792 num_pruned = 0;
4793 }
4794 else {
4795 num_joined = 0;
4796 num_pruned = 1;
4797 }
4798
4799 /* number of joined sources */
4800 *((uint16_t *) pim_msg_curr) = htons(num_joined);
4801 ++pim_msg_curr;
4802 ++pim_msg_curr;
4803
4804 /* number of pruned sources */
4805 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
4806 ++pim_msg_curr;
4807 ++pim_msg_curr;
4808
4809 remain = buf_pastend - pim_msg_curr;
4810 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
4811 remain,
4812 source_addr);
4813 if (!pim_msg_curr) {
4814 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
4815 source_str, remain, VTY_NEWLINE);
4816 return CMD_WARNING;
4817 }
4818
4819 /* Add PIM header */
4820
4821 pim_msg_size = pim_msg_curr - pim_msg;
4822
4823 pim_msg_build_header(pim_msg, pim_msg_size,
4824 PIM_MSG_TYPE_JOIN_PRUNE);
4825
4826 /*
4827 "Receive" message
4828 */
4829
4830 ip_msg_len = ip_hlen + pim_msg_size;
4831 result = pim_pim_packet(ifp, buf, ip_msg_len);
4832 if (result) {
4833 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4834 ip_msg_len, result, VTY_NEWLINE);
4835 return CMD_WARNING;
4836 }
4837
4838 return CMD_SUCCESS;
4839}
4840
4841DEFUN (test_pim_receive_join,
4842 test_pim_receive_join_cmd,
b181fa04 4843 "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
4844 "Test\n"
4845 "Test PIM protocol\n"
4846 "Test PIM message reception\n"
4847 "Test PIM join reception from neighbor\n"
4848 "Interface\n"
4849 "Neighbor holdtime\n"
4850 "Upstream neighbor unicast destination address\n"
4851 "Downstream neighbor unicast source address\n"
4852 "Multicast group address\n"
4853 "Unicast source address\n")
4854{
4855 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
4856}
4857
4858DEFUN (test_pim_receive_prune,
4859 test_pim_receive_prune_cmd,
b181fa04 4860 "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
4861 "Test\n"
4862 "Test PIM protocol\n"
4863 "Test PIM message reception\n"
4864 "Test PIM prune reception from neighbor\n"
4865 "Interface\n"
4866 "Neighbor holdtime\n"
4867 "Upstream neighbor unicast destination address\n"
4868 "Downstream neighbor unicast source address\n"
4869 "Multicast group address\n"
4870 "Unicast source address\n")
4871{
4872 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
4873}
4874
4875DEFUN (test_pim_receive_upcall,
4876 test_pim_receive_upcall_cmd,
b181fa04 4877 "test pim receive upcall <nocache|wrongvif|wholepkt> (0-65535) A.B.C.D A.B.C.D",
12e41d03
DL
4878 "Test\n"
4879 "Test PIM protocol\n"
4880 "Test PIM message reception\n"
4881 "Test reception of kernel upcall\n"
4882 "NOCACHE kernel upcall\n"
4883 "WRONGVIF kernel upcall\n"
4884 "WHOLEPKT kernel upcall\n"
4885 "Input interface vif index\n"
4886 "Multicast group address\n"
4887 "Multicast source address\n")
4888{
b181fa04
DW
4889 int idx_type = 4;
4890 int idx_number = 5;
4891 int idx_ipv4 = 6;
4892 int idx_ipv4_2 = 7;
12e41d03
DL
4893 struct igmpmsg msg;
4894 const char *upcall_type;
4895 const char *group_str;
4896 const char *source_str;
4897 int result;
4898
b181fa04 4899 upcall_type = argv[idx_type]->arg;
12e41d03
DL
4900
4901 if (upcall_type[0] == 'n')
4902 msg.im_msgtype = IGMPMSG_NOCACHE;
4903 else if (upcall_type[1] == 'r')
4904 msg.im_msgtype = IGMPMSG_WRONGVIF;
4905 else if (upcall_type[1] == 'h')
4906 msg.im_msgtype = IGMPMSG_WHOLEPKT;
4907 else {
4908 vty_out(vty, "Unknown kernel upcall type: %s%s",
4909 upcall_type, VTY_NEWLINE);
4910 return CMD_WARNING;
4911 }
4912
b181fa04 4913 msg.im_vif = atoi(argv[idx_number]->arg);
12e41d03
DL
4914
4915 /* Group address */
b181fa04 4916 group_str = argv[idx_ipv4]->arg;
12e41d03
DL
4917 result = inet_pton(AF_INET, group_str, &msg.im_dst);
4918 if (result <= 0) {
4919 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4920 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4921 return CMD_WARNING;
4922 }
4923
4924 /* Source address */
b181fa04 4925 source_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
4926 result = inet_pton(AF_INET, source_str, &msg.im_src);
4927 if (result <= 0) {
4928 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4929 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4930 return CMD_WARNING;
4931 }
4932
4933 msg.im_mbz = 0; /* Must be zero */
4934
4935 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
4936 if (result) {
4937 vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
4938 sizeof(msg), result, VTY_NEWLINE);
4939 return CMD_WARNING;
4940 }
4941
4942 return CMD_SUCCESS;
4943}
4944
4945void pim_cmd_init()
4946{
4947 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
4948 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
4949
4950 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
4951 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
981d6c7a
DS
4952 install_element (CONFIG_NODE, &ip_pim_rp_cmd);
4953 install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
12e41d03
DL
4954 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
4955 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
4956#if 0
4957 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
4958#else
4959 install_element (CONFIG_NODE, &pim_interface_cmd);
4960#endif
4961 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
4962
4963 install_default (INTERFACE_NODE);
4964 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
4965 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
4966 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
4967 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
4968 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
4969 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
4970 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
4971 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
4972 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
4973 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
4974 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
dedccda6 4975 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
981d6c7a 4976 install_element (INTERFACE_NODE, &interface_ip_pim_sm_cmd);
8371bd60 4977 install_element (INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
dedccda6
DS
4978 install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
4979 install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
7960fa8f 4980 install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
7960fa8f 4981 install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
12e41d03 4982
6250610a
JAG
4983 // Static mroutes NEB
4984 install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
4985 install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
4986 install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
4987 install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
4988
12e41d03
DL
4989 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
4990 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
4991 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
4992 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
4993 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4994 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
4995 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4996 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
4997 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
4998 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
4999 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
5000 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
5001 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
5002 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
5003 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
5004 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
5005 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
5006 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
5007 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
5008 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
5009 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
5010 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
5011 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
5012 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
5013 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
5014 install_element (VIEW_NODE, &show_ip_multicast_cmd);
5015 install_element (VIEW_NODE, &show_ip_mroute_cmd);
5016 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
5017 install_element (VIEW_NODE, &show_ip_rib_cmd);
5018 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 5019 install_element (VIEW_NODE, &show_debugging_pim_cmd);
12e41d03
DL
5020
5021 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
5022 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
5023 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
5024 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
5025 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
5026
5027 install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
5028 install_element (ENABLE_NODE, &show_ip_igmp_join_cmd);
5029 install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
5030 install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
5031 install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
5032 install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
5033 install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
5034 install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
5035 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
5036 install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
5037 install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
5038 install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
5039 install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
5040 install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
5041 install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
5042 install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
5043 install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
5044 install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
5045 install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
5046 install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
5047 install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
5048 install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
5049 install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
5050 install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
5051 install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
5052 install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
5053 install_element (ENABLE_NODE, &show_ip_multicast_cmd);
5054 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
5055 install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
5056 install_element (ENABLE_NODE, &show_ip_rib_cmd);
5057 install_element (ENABLE_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 5058 install_element (ENABLE_NODE, &show_debugging_pim_cmd);
12e41d03
DL
5059
5060 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
5061 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
5062 install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
5063 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
5064 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
5065 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
5066 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
5067
5068 install_element (ENABLE_NODE, &debug_igmp_cmd);
5069 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
12e41d03
DL
5070 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
5071 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
12e41d03
DL
5072 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
5073 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
12e41d03
DL
5074 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
5075 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
12e41d03
DL
5076 install_element (ENABLE_NODE, &debug_mroute_cmd);
5077 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
6250610a
JAG
5078 install_element (ENABLE_NODE, &debug_static_cmd);
5079 install_element (ENABLE_NODE, &no_debug_static_cmd);
12e41d03
DL
5080 install_element (ENABLE_NODE, &debug_pim_cmd);
5081 install_element (ENABLE_NODE, &no_debug_pim_cmd);
12e41d03
DL
5082 install_element (ENABLE_NODE, &debug_pim_events_cmd);
5083 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
12e41d03
DL
5084 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
5085 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
5086 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
5087 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
12e41d03
DL
5088 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
5089 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
12e41d03
DL
5090 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
5091 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
12e41d03
DL
5092 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
5093 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
12e41d03
DL
5094 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
5095 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
12e41d03
DL
5096 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
5097 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
12e41d03
DL
5098
5099 install_element (CONFIG_NODE, &debug_igmp_cmd);
5100 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
12e41d03
DL
5101 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
5102 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
12e41d03
DL
5103 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
5104 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
12e41d03
DL
5105 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
5106 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
12e41d03
DL
5107 install_element (CONFIG_NODE, &debug_mroute_cmd);
5108 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
6250610a
JAG
5109 install_element (CONFIG_NODE, &debug_static_cmd);
5110 install_element (CONFIG_NODE, &no_debug_static_cmd);
12e41d03
DL
5111 install_element (CONFIG_NODE, &debug_pim_cmd);
5112 install_element (CONFIG_NODE, &no_debug_pim_cmd);
12e41d03
DL
5113 install_element (CONFIG_NODE, &debug_pim_events_cmd);
5114 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
12e41d03
DL
5115 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
5116 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
5117 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
5118 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
12e41d03
DL
5119 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
5120 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
12e41d03
DL
5121 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
5122 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
12e41d03
DL
5123 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
5124 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
12e41d03 5125}