]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
pimd: Ensure new generation_id is different from previous
[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
23#include <sys/ioctl.h>
24
25#include <zebra.h>
26
27#include "command.h"
28#include "if.h"
29#include "prefix.h"
30#include "zclient.h"
31
32#include "pimd.h"
33#include "pim_cmd.h"
34#include "pim_iface.h"
35#include "pim_vty.h"
36#include "pim_mroute.h"
37#include "pim_str.h"
38#include "pim_igmp.h"
39#include "pim_igmpv3.h"
40#include "pim_sock.h"
41#include "pim_time.h"
42#include "pim_util.h"
43#include "pim_oil.h"
44#include "pim_neighbor.h"
45#include "pim_pim.h"
46#include "pim_ifchannel.h"
47#include "pim_hello.h"
48#include "pim_msg.h"
49#include "pim_upstream.h"
50#include "pim_rpf.h"
51#include "pim_macro.h"
52#include "pim_ssmpingd.h"
53#include "pim_zebra.h"
6250610a 54#include "pim_static.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
982 vty_out(vty, "Source Group State Uptime JoinTimer RefCnt%s", VTY_NEWLINE);
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
995 vty_out(vty, "%-15s %-15s %-5s %-8s %-9s %6d%s",
996 src_str,
997 grp_str,
998 up->join_state == PIM_UPSTREAM_JOINED ? "Jnd" : "NtJnd",
999 uptime,
1000 join_timer,
1001 up->ref_count,
1002 VTY_NEWLINE);
1003 }
1004}
1005
1006static void pim_show_join_desired(struct vty *vty)
1007{
1008 struct listnode *ifnode;
1009 struct listnode *chnode;
1010 struct interface *ifp;
1011 struct pim_interface *pim_ifp;
1012 struct pim_ifchannel *ch;
1013 char src_str[100];
1014 char grp_str[100];
1015
1016 vty_out(vty,
1017 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1018 VTY_NEWLINE);
1019
1020 /* scan all interfaces */
469351b3 1021 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1022 pim_ifp = ifp->info;
1023 if (!pim_ifp)
1024 continue;
1025
1026 /* scan per-interface (S,G) state */
1027 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
1028 struct pim_upstream *up = ch->upstream;
1029
1030 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1031 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1032
1033 vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1034 ifp->name,
1035 src_str,
1036 grp_str,
1037 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
1038 pim_macro_chisin_joins(ch) ? "yes" : "no",
1039 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
1040 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
1041 pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
1042 VTY_NEWLINE);
1043 }
1044 }
1045}
1046
1047static void pim_show_upstream_rpf(struct vty *vty)
1048{
1049 struct listnode *upnode;
1050 struct pim_upstream *up;
1051
1052 vty_out(vty,
1053 "Source Group RpfIface RibNextHop RpfAddress %s",
1054 VTY_NEWLINE);
1055
1056 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
1057 char src_str[100];
1058 char grp_str[100];
1059 char rpf_nexthop_str[100];
1060 char rpf_addr_str[100];
1061 struct pim_rpf *rpf;
1062 const char *rpf_ifname;
1063
1064 rpf = &up->rpf;
1065
1066 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1067 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1068 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
1069 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1070
1071 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1072
1073 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
1074 src_str,
1075 grp_str,
1076 rpf_ifname,
1077 rpf_nexthop_str,
1078 rpf_addr_str,
1079 VTY_NEWLINE);
1080 }
1081}
1082
1083static void show_rpf_refresh_stats(struct vty *vty, time_t now)
1084{
1085 char refresh_uptime[10];
1086
1087 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
1088
1089 vty_out(vty,
1090 "RPF Cache Refresh Delay: %ld msecs%s"
1091 "RPF Cache Refresh Timer: %ld msecs%s"
1092 "RPF Cache Refresh Requests: %lld%s"
1093 "RPF Cache Refresh Events: %lld%s"
1094 "RPF Cache Refresh Last: %s%s",
1095 qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
1096 pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
1097 (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
1098 (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
1099 refresh_uptime, VTY_NEWLINE);
1100}
1101
1102static void show_scan_oil_stats(struct vty *vty, time_t now)
1103{
1104 char uptime_scan_oil[10];
1105 char uptime_mroute_add[10];
1106 char uptime_mroute_del[10];
1107
1108 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
1109 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
1110 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
1111
1112 vty_out(vty,
1113 "Scan OIL - Last: %s Events: %lld%s"
1114 "MFC Add - Last: %s Events: %lld%s"
1115 "MFC Del - Last: %s Events: %lld%s",
1116 uptime_scan_oil, (long long) qpim_scan_oil_events, VTY_NEWLINE,
1117 uptime_mroute_add, (long long) qpim_mroute_add_events, VTY_NEWLINE,
1118 uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
1119}
1120
1121static void pim_show_rpf(struct vty *vty)
1122{
1123 struct listnode *up_node;
1124 struct pim_upstream *up;
1125 time_t now = pim_time_monotonic_sec();
1126
1127 show_rpf_refresh_stats(vty, now);
1128
1129 vty_out(vty, "%s", VTY_NEWLINE);
1130
1131 vty_out(vty,
1132 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1133 VTY_NEWLINE);
1134
1135 for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
1136 char src_str[100];
1137 char grp_str[100];
1138 char rpf_addr_str[100];
1139 char rib_nexthop_str[100];
1140 const char *rpf_ifname;
1141 struct pim_rpf *rpf = &up->rpf;
1142
1143 pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
1144 pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
1145 pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1146 pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
1147
1148 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1149
1150 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1151 src_str,
1152 grp_str,
1153 rpf_ifname,
1154 rpf_addr_str,
1155 rib_nexthop_str,
1156 rpf->source_nexthop.mrib_route_metric,
1157 rpf->source_nexthop.mrib_metric_preference,
1158 VTY_NEWLINE);
1159 }
1160}
1161
1162static void igmp_show_querier(struct vty *vty)
1163{
1164 struct listnode *node;
1165 struct interface *ifp;
1166
1167 vty_out(vty, "Interface Address Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
1168
469351b3 1169 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
1170 struct pim_interface *pim_ifp = ifp->info;
1171 struct listnode *sock_node;
1172 struct igmp_sock *igmp;
1173
1174 if (!pim_ifp)
1175 continue;
1176
1177 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1178 char query_hhmmss[10];
1179 char other_hhmmss[10];
1180
1181 pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
1182 pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
1183
1184 vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
1185 ifp->name,
1186 inet_ntoa(igmp->ifaddr),
1187 igmp->t_igmp_query_timer ? "THIS" : "OTHER",
1188 igmp->startup_query_count,
1189 query_hhmmss,
1190 other_hhmmss,
1191 VTY_NEWLINE);
1192 }
1193 }
1194}
1195
1196static void igmp_show_groups(struct vty *vty)
1197{
1198 struct listnode *ifnode;
1199 struct interface *ifp;
1200 time_t now;
1201
1202 now = pim_time_monotonic_sec();
1203
1204 vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
1205
1206 /* scan interfaces */
469351b3 1207 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1208 struct pim_interface *pim_ifp = ifp->info;
1209 struct listnode *sock_node;
1210 struct igmp_sock *igmp;
1211
1212 if (!pim_ifp)
1213 continue;
1214
1215 /* scan igmp sockets */
1216 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1217 char ifaddr_str[100];
1218 struct listnode *grpnode;
1219 struct igmp_group *grp;
1220
1221 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1222
1223 /* scan igmp groups */
1224 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1225 char group_str[100];
1226 char hhmmss[10];
1227 char uptime[10];
1228
1229 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1230 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
1231 pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
1232
1233 vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
1234 ifp->name,
1235 ifaddr_str,
1236 group_str,
1237 grp->group_filtermode_isexcl ? "EXCL" : "INCL",
1238 hhmmss,
1239 grp->group_source_list ? listcount(grp->group_source_list) : 0,
1240 igmp_group_compat_mode(igmp, grp),
1241 uptime,
1242 VTY_NEWLINE);
1243
1244 } /* scan igmp groups */
1245 } /* scan igmp sockets */
1246 } /* scan interfaces */
1247}
1248
1249static void igmp_show_group_retransmission(struct vty *vty)
1250{
1251 struct listnode *ifnode;
1252 struct interface *ifp;
1253
1254 vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
1255
1256 /* scan interfaces */
469351b3 1257 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1258 struct pim_interface *pim_ifp = ifp->info;
1259 struct listnode *sock_node;
1260 struct igmp_sock *igmp;
1261
1262 if (!pim_ifp)
1263 continue;
1264
1265 /* scan igmp sockets */
1266 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1267 char ifaddr_str[100];
1268 struct listnode *grpnode;
1269 struct igmp_group *grp;
1270
1271 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1272
1273 /* scan igmp groups */
1274 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1275 char group_str[100];
1276 char grp_retr_mmss[10];
1277 struct listnode *src_node;
1278 struct igmp_source *src;
1279 int grp_retr_sources = 0;
1280
1281 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1282 pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
1283
1284
1285 /* count group sources with retransmission state */
1286 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
1287 if (src->source_query_retransmit_count > 0) {
1288 ++grp_retr_sources;
1289 }
1290 }
1291
1292 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
1293 ifp->name,
1294 ifaddr_str,
1295 group_str,
1296 grp_retr_mmss,
1297 grp->group_specific_query_retransmit_count,
1298 grp_retr_sources,
1299 VTY_NEWLINE);
1300
1301 } /* scan igmp groups */
1302 } /* scan igmp sockets */
1303 } /* scan interfaces */
1304}
1305
1306static void igmp_show_parameters(struct vty *vty)
1307{
1308 struct listnode *ifnode;
1309 struct interface *ifp;
1310
1311 vty_out(vty,
1312 "QRV: Robustness Variable SQI: Startup Query Interval%s"
1313 "QQI: Query Interval OQPI: Other Querier Present Interval%s"
1314 "QRI: Query Response Interval LMQT: Last Member Query Time%s"
1315 "GMI: Group Membership Interval OHPI: Older Host Present Interval%s%s",
1316 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
1317
1318 vty_out(vty,
1319 "Interface Address QRV QQI QRI GMI SQI OQPI LMQT OHPI %s",
1320 VTY_NEWLINE);
1321
1322 /* scan interfaces */
469351b3 1323 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1324 struct pim_interface *pim_ifp = ifp->info;
1325 struct listnode *sock_node;
1326 struct igmp_sock *igmp;
1327
1328 if (!pim_ifp)
1329 continue;
1330
1331 /* scan igmp sockets */
1332 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1333 char ifaddr_str[100];
1334 long gmi_dsec; /* Group Membership Interval */
1335 long oqpi_dsec; /* Other Querier Present Interval */
1336 int sqi;
1337 long lmqt_dsec;
1338 long ohpi_dsec;
1339 long qri_dsec;
1340
1341 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1342
1343 gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
1344 igmp->querier_query_interval,
1345 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1346
1347 sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
1348
1349 oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
1350 igmp->querier_query_interval,
1351 pim_ifp->igmp_query_max_response_time_dsec) / 100;
1352
1353 lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
1354 igmp->querier_robustness_variable) / 100;
1355
1356 ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
1357 igmp->querier_query_interval,
1358 pim_ifp->igmp_query_max_response_time_dsec);
1359
1360 qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
1361
1362 vty_out(vty,
1363 "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
1364 ifp->name,
1365 ifaddr_str,
1366 igmp->querier_robustness_variable,
1367 igmp->querier_query_interval,
1368 qri_dsec / 10, qri_dsec % 10,
1369 gmi_dsec / 10, gmi_dsec % 10,
1370 sqi,
1371 oqpi_dsec / 10, oqpi_dsec % 10,
1372 lmqt_dsec / 10, lmqt_dsec % 10,
1373 ohpi_dsec / 10, ohpi_dsec % 10,
1374 VTY_NEWLINE);
1375
1376 } /* scan igmp sockets */
1377 } /* scan interfaces */
1378}
1379
1380static void igmp_show_sources(struct vty *vty)
1381{
1382 struct listnode *ifnode;
1383 struct interface *ifp;
1384 time_t now;
1385
1386 now = pim_time_monotonic_sec();
1387
1388 vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
1389
1390 /* scan interfaces */
469351b3 1391 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1392 struct pim_interface *pim_ifp = ifp->info;
1393 struct listnode *sock_node;
1394 struct igmp_sock *igmp;
1395
1396 if (!pim_ifp)
1397 continue;
1398
1399 /* scan igmp sockets */
1400 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1401 char ifaddr_str[100];
1402 struct listnode *grpnode;
1403 struct igmp_group *grp;
1404
1405 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1406
1407 /* scan igmp groups */
1408 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1409 char group_str[100];
1410 struct listnode *srcnode;
1411 struct igmp_source *src;
1412
1413 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1414
1415 /* scan group sources */
1416 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1417 char source_str[100];
1418 char mmss[10];
1419 char uptime[10];
1420
1421 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1422
1423 pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
1424
1425 pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
1426
1427 vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
1428 ifp->name,
1429 ifaddr_str,
1430 group_str,
1431 source_str,
1432 mmss,
1433 IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
1434 uptime,
1435 VTY_NEWLINE);
1436
1437 } /* scan group sources */
1438 } /* scan igmp groups */
1439 } /* scan igmp sockets */
1440 } /* scan interfaces */
1441}
1442
1443static void igmp_show_source_retransmission(struct vty *vty)
1444{
1445 struct listnode *ifnode;
1446 struct interface *ifp;
1447
1448 vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
1449
1450 /* scan interfaces */
469351b3 1451 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1452 struct pim_interface *pim_ifp = ifp->info;
1453 struct listnode *sock_node;
1454 struct igmp_sock *igmp;
1455
1456 if (!pim_ifp)
1457 continue;
1458
1459 /* scan igmp sockets */
1460 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
1461 char ifaddr_str[100];
1462 struct listnode *grpnode;
1463 struct igmp_group *grp;
1464
1465 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
1466
1467 /* scan igmp groups */
1468 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
1469 char group_str[100];
1470 struct listnode *srcnode;
1471 struct igmp_source *src;
1472
1473 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
1474
1475 /* scan group sources */
1476 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
1477 char source_str[100];
1478
1479 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
1480
1481 vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
1482 ifp->name,
1483 ifaddr_str,
1484 group_str,
1485 source_str,
1486 src->source_query_retransmit_count,
1487 VTY_NEWLINE);
1488
1489 } /* scan group sources */
1490 } /* scan igmp groups */
1491 } /* scan igmp sockets */
1492 } /* scan interfaces */
1493}
1494
1495static void clear_igmp_interfaces()
1496{
1497 struct listnode *ifnode;
1498 struct listnode *ifnextnode;
1499 struct interface *ifp;
1500
469351b3 1501 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1502 pim_if_addr_del_all_igmp(ifp);
1503 }
1504
469351b3 1505 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1506 pim_if_addr_add_all(ifp);
1507 }
1508}
1509
1510static void clear_pim_interfaces()
1511{
1512 struct listnode *ifnode;
1513 struct listnode *ifnextnode;
1514 struct interface *ifp;
1515
469351b3 1516 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
1517 if (ifp->info) {
1518 pim_neighbor_delete_all(ifp, "interface cleared");
1519 }
1520 }
1521}
1522
1523static void clear_interfaces()
1524{
1525 clear_igmp_interfaces();
1526 clear_pim_interfaces();
1527}
1528
1529DEFUN (pim_interface,
1530 pim_interface_cmd,
1531 "interface IFNAME",
1532 "Select an interface to configure\n"
1533 "Interface's name\n")
1534{
1535 struct interface *ifp;
1536 const char *ifname = argv[0];
1537 size_t sl;
1538
1539 sl = strlen(ifname);
1540 if (sl > INTERFACE_NAMSIZ) {
1541 vty_out(vty, "%% Interface name %s is invalid: length exceeds "
1542 "%d characters%s",
1543 ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
1544 return CMD_WARNING;
1545 }
1546
1547 ifp = if_lookup_by_name_len(ifname, sl);
1548 if (!ifp) {
1549 vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
1550
1551 /* Returning here would prevent pimd from booting when there are
1552 interface commands in pimd.conf, since all interfaces are
1553 unknown at pimd boot time (the zebra daemon has not been
1554 contacted for interface discovery). */
1555
1556 ifp = if_get_by_name_len(ifname, sl);
1557 if (!ifp) {
1558 vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
1559 return CMD_WARNING;
1560 }
1561 }
1562
1563 vty->index = ifp;
1564 vty->node = INTERFACE_NODE;
1565
1566 return CMD_SUCCESS;
1567}
1568
1569DEFUN (clear_ip_interfaces,
1570 clear_ip_interfaces_cmd,
1571 "clear ip interfaces",
1572 CLEAR_STR
1573 IP_STR
1574 "Reset interfaces\n")
1575{
1576 clear_interfaces();
1577
1578 return CMD_SUCCESS;
1579}
1580
1581DEFUN (clear_ip_igmp_interfaces,
1582 clear_ip_igmp_interfaces_cmd,
1583 "clear ip igmp interfaces",
1584 CLEAR_STR
1585 IP_STR
1586 CLEAR_IP_IGMP_STR
1587 "Reset IGMP interfaces\n")
1588{
1589 clear_igmp_interfaces();
1590
1591 return CMD_SUCCESS;
1592}
1593
1594static void mroute_add_all()
1595{
1596 struct listnode *node;
1597 struct channel_oil *c_oil;
1598
1599 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1600 if (pim_mroute_add(&c_oil->oil)) {
1601 /* just log warning */
1602 char source_str[100];
1603 char group_str[100];
1604 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1605 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1606 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1607 __FILE__, __PRETTY_FUNCTION__,
1608 source_str, group_str);
1609 }
1610 }
1611}
1612
1613static void mroute_del_all()
1614{
1615 struct listnode *node;
1616 struct channel_oil *c_oil;
1617
1618 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
1619 if (pim_mroute_del(&c_oil->oil)) {
1620 /* just log warning */
1621 char source_str[100];
1622 char group_str[100];
1623 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
1624 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
1625 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1626 __FILE__, __PRETTY_FUNCTION__,
1627 source_str, group_str);
1628 }
1629 }
1630}
1631
6250610a
JAG
1632static void static_mroute_add_all()
1633{
1634 struct listnode *node;
1635 struct static_route *s_route;
1636
1637 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
1638 if (pim_mroute_add(&s_route->mc)) {
1639 /* just log warning */
1640 char source_str[100];
1641 char group_str[100];
1642 pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
1643 pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
1644 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
1645 __FILE__, __PRETTY_FUNCTION__,
1646 source_str, group_str);
1647 }
1648 }
1649}
1650
1651static void static_mroute_del_all()
1652{
1653 struct listnode *node;
1654 struct static_route *s_route;
1655
1656 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
1657 if (pim_mroute_del(&s_route->mc)) {
1658 /* just log warning */
1659 char source_str[100];
1660 char group_str[100];
1661 pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
1662 pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
1663 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
1664 __FILE__, __PRETTY_FUNCTION__,
1665 source_str, group_str);
1666 }
1667 }
1668}
1669
12e41d03
DL
1670DEFUN (clear_ip_mroute,
1671 clear_ip_mroute_cmd,
1672 "clear ip mroute",
1673 CLEAR_STR
1674 IP_STR
1675 "Reset multicast routes\n")
1676{
1677 mroute_del_all();
1678 mroute_add_all();
1679
1680 return CMD_SUCCESS;
1681}
1682
1683DEFUN (clear_ip_pim_interfaces,
1684 clear_ip_pim_interfaces_cmd,
1685 "clear ip pim interfaces",
1686 CLEAR_STR
1687 IP_STR
1688 CLEAR_IP_PIM_STR
1689 "Reset PIM interfaces\n")
1690{
1691 clear_pim_interfaces();
1692
1693 return CMD_SUCCESS;
1694}
1695
1696DEFUN (clear_ip_pim_oil,
1697 clear_ip_pim_oil_cmd,
1698 "clear ip pim oil",
1699 CLEAR_STR
1700 IP_STR
1701 CLEAR_IP_PIM_STR
1702 "Rescan PIM OIL (output interface list)\n")
1703{
1704 pim_scan_oil();
1705
1706 return CMD_SUCCESS;
1707}
1708
1709DEFUN (show_ip_igmp_interface,
1710 show_ip_igmp_interface_cmd,
1711 "show ip igmp interface",
1712 SHOW_STR
1713 IP_STR
1714 IGMP_STR
1715 "IGMP interface information\n")
1716{
1717 igmp_show_interfaces(vty);
1718
1719 return CMD_SUCCESS;
1720}
1721
1722DEFUN (show_ip_igmp_join,
1723 show_ip_igmp_join_cmd,
1724 "show ip igmp join",
1725 SHOW_STR
1726 IP_STR
1727 IGMP_STR
1728 "IGMP static join information\n")
1729{
1730 igmp_show_interface_join(vty);
1731
1732 return CMD_SUCCESS;
1733}
1734
1735DEFUN (show_ip_igmp_groups,
1736 show_ip_igmp_groups_cmd,
1737 "show ip igmp groups",
1738 SHOW_STR
1739 IP_STR
1740 IGMP_STR
1741 IGMP_GROUP_STR)
1742{
1743 igmp_show_groups(vty);
1744
1745 return CMD_SUCCESS;
1746}
1747
1748DEFUN (show_ip_igmp_groups_retransmissions,
1749 show_ip_igmp_groups_retransmissions_cmd,
1750 "show ip igmp groups retransmissions",
1751 SHOW_STR
1752 IP_STR
1753 IGMP_STR
1754 IGMP_GROUP_STR
1755 "IGMP group retransmissions\n")
1756{
1757 igmp_show_group_retransmission(vty);
1758
1759 return CMD_SUCCESS;
1760}
1761
1762DEFUN (show_ip_igmp_parameters,
1763 show_ip_igmp_parameters_cmd,
1764 "show ip igmp parameters",
1765 SHOW_STR
1766 IP_STR
1767 IGMP_STR
1768 "IGMP parameters information\n")
1769{
1770 igmp_show_parameters(vty);
1771
1772 return CMD_SUCCESS;
1773}
1774
1775DEFUN (show_ip_igmp_sources,
1776 show_ip_igmp_sources_cmd,
1777 "show ip igmp sources",
1778 SHOW_STR
1779 IP_STR
1780 IGMP_STR
1781 IGMP_SOURCE_STR)
1782{
1783 igmp_show_sources(vty);
1784
1785 return CMD_SUCCESS;
1786}
1787
1788DEFUN (show_ip_igmp_sources_retransmissions,
1789 show_ip_igmp_sources_retransmissions_cmd,
1790 "show ip igmp sources retransmissions",
1791 SHOW_STR
1792 IP_STR
1793 IGMP_STR
1794 IGMP_SOURCE_STR
1795 "IGMP source retransmissions\n")
1796{
1797 igmp_show_source_retransmission(vty);
1798
1799 return CMD_SUCCESS;
1800}
1801
1802DEFUN (show_ip_igmp_querier,
1803 show_ip_igmp_querier_cmd,
1804 "show ip igmp querier",
1805 SHOW_STR
1806 IP_STR
1807 IGMP_STR
1808 "IGMP querier information\n")
1809{
1810 igmp_show_querier(vty);
1811
1812 return CMD_SUCCESS;
1813}
1814
1815DEFUN (show_ip_pim_address,
1816 show_ip_pim_address_cmd,
1817 "show ip pim address",
1818 SHOW_STR
1819 IP_STR
1820 PIM_STR
1821 "PIM interface address\n")
1822{
1823 show_interface_address(vty);
1824
1825 return CMD_SUCCESS;
1826}
1827
1828DEFUN (show_ip_pim_assert,
1829 show_ip_pim_assert_cmd,
1830 "show ip pim assert",
1831 SHOW_STR
1832 IP_STR
1833 PIM_STR
1834 "PIM interface assert\n")
1835{
1836 pim_show_assert(vty);
1837
1838 return CMD_SUCCESS;
1839}
1840
1841DEFUN (show_ip_pim_assert_internal,
1842 show_ip_pim_assert_internal_cmd,
1843 "show ip pim assert-internal",
1844 SHOW_STR
1845 IP_STR
1846 PIM_STR
1847 "PIM interface internal assert state\n")
1848{
1849 pim_show_assert_internal(vty);
1850
1851 return CMD_SUCCESS;
1852}
1853
1854DEFUN (show_ip_pim_assert_metric,
1855 show_ip_pim_assert_metric_cmd,
1856 "show ip pim assert-metric",
1857 SHOW_STR
1858 IP_STR
1859 PIM_STR
1860 "PIM interface assert metric\n")
1861{
1862 pim_show_assert_metric(vty);
1863
1864 return CMD_SUCCESS;
1865}
1866
1867DEFUN (show_ip_pim_assert_winner_metric,
1868 show_ip_pim_assert_winner_metric_cmd,
1869 "show ip pim assert-winner-metric",
1870 SHOW_STR
1871 IP_STR
1872 PIM_STR
1873 "PIM interface assert winner metric\n")
1874{
1875 pim_show_assert_winner_metric(vty);
1876
1877 return CMD_SUCCESS;
1878}
1879
1880DEFUN (show_ip_pim_dr,
1881 show_ip_pim_dr_cmd,
1882 "show ip pim designated-router",
1883 SHOW_STR
1884 IP_STR
1885 PIM_STR
1886 "PIM interface designated router\n")
1887{
1888 pim_show_dr(vty);
1889
1890 return CMD_SUCCESS;
1891}
1892
1893DEFUN (show_ip_pim_hello,
1894 show_ip_pim_hello_cmd,
1895 "show ip pim hello",
1896 SHOW_STR
1897 IP_STR
1898 PIM_STR
1899 "PIM interface hello information\n")
1900{
1901 pim_show_hello(vty);
1902
1903 return CMD_SUCCESS;
1904}
1905
1906DEFUN (show_ip_pim_interface,
1907 show_ip_pim_interface_cmd,
1908 "show ip pim interface",
1909 SHOW_STR
1910 IP_STR
1911 PIM_STR
1912 "PIM interface information\n")
1913{
1914 pim_show_interfaces(vty);
1915
1916 return CMD_SUCCESS;
1917}
1918
1919DEFUN (show_ip_pim_join,
1920 show_ip_pim_join_cmd,
1921 "show ip pim join",
1922 SHOW_STR
1923 IP_STR
1924 PIM_STR
1925 "PIM interface join information\n")
1926{
1927 pim_show_join(vty);
1928
1929 return CMD_SUCCESS;
1930}
1931
1932DEFUN (show_ip_pim_lan_prune_delay,
1933 show_ip_pim_lan_prune_delay_cmd,
1934 "show ip pim lan-prune-delay",
1935 SHOW_STR
1936 IP_STR
1937 PIM_STR
1938 "PIM neighbors LAN prune delay parameters\n")
1939{
1940 pim_show_lan_prune_delay(vty);
1941
1942 return CMD_SUCCESS;
1943}
1944
1945DEFUN (show_ip_pim_local_membership,
1946 show_ip_pim_local_membership_cmd,
1947 "show ip pim local-membership",
1948 SHOW_STR
1949 IP_STR
1950 PIM_STR
1951 "PIM interface local-membership\n")
1952{
1953 pim_show_membership(vty);
1954
1955 return CMD_SUCCESS;
1956}
1957
1958DEFUN (show_ip_pim_jp_override_interval,
1959 show_ip_pim_jp_override_interval_cmd,
1960 "show ip pim jp-override-interval",
1961 SHOW_STR
1962 IP_STR
1963 PIM_STR
1964 "PIM interface J/P override interval\n")
1965{
1966 pim_show_jp_override_interval(vty);
1967
1968 return CMD_SUCCESS;
1969}
1970
1971DEFUN (show_ip_pim_neighbor,
1972 show_ip_pim_neighbor_cmd,
1973 "show ip pim neighbor",
1974 SHOW_STR
1975 IP_STR
1976 PIM_STR
1977 "PIM neighbor information\n")
1978{
1979 pim_show_neighbors(vty);
1980
1981 return CMD_SUCCESS;
1982}
1983
1984DEFUN (show_ip_pim_secondary,
1985 show_ip_pim_secondary_cmd,
1986 "show ip pim secondary",
1987 SHOW_STR
1988 IP_STR
1989 PIM_STR
1990 "PIM neighbor addresses\n")
1991{
1992 pim_show_neighbors_secondary(vty);
1993
1994 return CMD_SUCCESS;
1995}
1996
1997DEFUN (show_ip_pim_upstream,
1998 show_ip_pim_upstream_cmd,
1999 "show ip pim upstream",
2000 SHOW_STR
2001 IP_STR
2002 PIM_STR
2003 "PIM upstream information\n")
2004{
2005 pim_show_upstream(vty);
2006
2007 return CMD_SUCCESS;
2008}
2009
2010DEFUN (show_ip_pim_upstream_join_desired,
2011 show_ip_pim_upstream_join_desired_cmd,
2012 "show ip pim upstream-join-desired",
2013 SHOW_STR
2014 IP_STR
2015 PIM_STR
2016 "PIM upstream join-desired\n")
2017{
2018 pim_show_join_desired(vty);
2019
2020 return CMD_SUCCESS;
2021}
2022
2023DEFUN (show_ip_pim_upstream_rpf,
2024 show_ip_pim_upstream_rpf_cmd,
2025 "show ip pim upstream-rpf",
2026 SHOW_STR
2027 IP_STR
2028 PIM_STR
2029 "PIM upstream source rpf\n")
2030{
2031 pim_show_upstream_rpf(vty);
2032
2033 return CMD_SUCCESS;
2034}
2035
2036DEFUN (show_ip_pim_rpf,
2037 show_ip_pim_rpf_cmd,
2038 "show ip pim rpf",
2039 SHOW_STR
2040 IP_STR
2041 PIM_STR
2042 "PIM cached source rpf information\n")
2043{
2044 pim_show_rpf(vty);
2045
2046 return CMD_SUCCESS;
2047}
2048
2049static void show_multicast_interfaces(struct vty *vty)
2050{
2051 struct listnode *node;
2052 struct interface *ifp;
2053
2054 vty_out(vty, "%s", VTY_NEWLINE);
2055
2056 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2057 VTY_NEWLINE);
2058
469351b3 2059 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
2060 struct pim_interface *pim_ifp;
2061 struct in_addr ifaddr;
2062 struct sioc_vif_req vreq;
2063
2064 pim_ifp = ifp->info;
2065
2066 if (!pim_ifp)
2067 continue;
2068
2069 memset(&vreq, 0, sizeof(vreq));
2070 vreq.vifi = pim_ifp->mroute_vif_index;
2071
2072 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
2073 int e = errno;
2074 vty_out(vty,
1cb17fc7
DL
2075 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2076 (unsigned long)SIOCGETVIFCNT,
12e41d03
DL
2077 ifp->name,
2078 pim_ifp->mroute_vif_index,
2079 e,
2080 safe_strerror(e),
2081 VTY_NEWLINE);
2082 continue;
2083 }
2084
2085 ifaddr = pim_ifp->primary_address;
2086
2087 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2088 ifp->name,
2089 inet_ntoa(ifaddr),
2090 ifp->ifindex,
2091 pim_ifp->mroute_vif_index,
2092 vreq.icount,
2093 vreq.ocount,
2094 vreq.ibytes,
2095 vreq.obytes,
2096 VTY_NEWLINE);
2097 }
2098}
2099
2100DEFUN (show_ip_multicast,
2101 show_ip_multicast_cmd,
2102 "show ip multicast",
2103 SHOW_STR
2104 IP_STR
2105 "Multicast global information\n")
2106{
2107 time_t now = pim_time_monotonic_sec();
2108
2109 if (PIM_MROUTE_IS_ENABLED) {
2110 char uptime[10];
2111
2112 vty_out(vty, "Mroute socket descriptor: %d%s",
2113 qpim_mroute_socket_fd,
2114 VTY_NEWLINE);
2115
2116 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
2117 vty_out(vty, "Mroute socket uptime: %s%s",
2118 uptime,
2119 VTY_NEWLINE);
2120 }
2121 else {
2122 vty_out(vty, "Multicast disabled%s",
2123 VTY_NEWLINE);
2124 }
2125
2126 vty_out(vty, "%s", VTY_NEWLINE);
2127 vty_out(vty, "Zclient update socket: ");
2128 if (qpim_zclient_update) {
2129 vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
2130 qpim_zclient_update->fail, VTY_NEWLINE);
2131 }
2132 else {
2133 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2134 }
2135 vty_out(vty, "Zclient lookup socket: ");
2136 if (qpim_zclient_lookup) {
2137 vty_out(vty, "%d failures=%d%s", qpim_zclient_lookup->sock,
2138 qpim_zclient_lookup->fail, VTY_NEWLINE);
2139 }
2140 else {
2141 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2142 }
2143
2144 vty_out(vty, "%s", VTY_NEWLINE);
2145 vty_out(vty, "Current highest VifIndex: %d%s",
2146 qpim_mroute_oif_highest_vif_index,
2147 VTY_NEWLINE);
2148 vty_out(vty, "Maximum highest VifIndex: %d%s",
2149 MAXVIFS - 1,
2150 VTY_NEWLINE);
2151
2152 vty_out(vty, "%s", VTY_NEWLINE);
2153 vty_out(vty, "Upstream Join Timer: %d secs%s",
2154 qpim_t_periodic,
2155 VTY_NEWLINE);
2156 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
2157 PIM_JP_HOLDTIME,
2158 VTY_NEWLINE);
2159
2160 vty_out(vty, "%s", VTY_NEWLINE);
2161
2162 show_rpf_refresh_stats(vty, now);
2163
2164 vty_out(vty, "%s", VTY_NEWLINE);
2165
2166 show_scan_oil_stats(vty, now);
2167
2168 show_multicast_interfaces(vty);
2169
2170 return CMD_SUCCESS;
2171}
2172
2173static void show_mroute(struct vty *vty)
2174{
2175 struct listnode *node;
2176 struct channel_oil *c_oil;
6250610a 2177 struct static_route *s_route;
12e41d03
DL
2178 time_t now;
2179
6250610a 2180 vty_out(vty, "Proto: I=IGMP P=PIM S=STATIC%s%s", VTY_NEWLINE, VTY_NEWLINE);
12e41d03
DL
2181
2182 vty_out(vty, "Source Group Proto Input iVifI Output oVifI TTL Uptime %s",
2183 VTY_NEWLINE);
2184
2185 now = pim_time_monotonic_sec();
2186
6250610a 2187 /* print list of PIM and IGMP routes */
12e41d03
DL
2188 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2189 char group_str[100];
2190 char source_str[100];
2191 int oif_vif_index;
2192
2193 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2194 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2195
2196 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2197 struct interface *ifp_in;
2198 struct interface *ifp_out;
2199 char oif_uptime[10];
2200 int ttl;
2201 char proto[5];
2202
2203 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2204 if (ttl < 1)
2205 continue;
2206
2207 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
2208 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2209
2210 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
2211
2212 proto[0] = '\0';
2213 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2214 strcat(proto, "P");
2215 }
2216 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2217 strcat(proto, "I");
2218 }
2219
2220 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2221 source_str,
2222 group_str,
2223 proto,
2224 ifp_in ? ifp_in->name : "<iif?>",
2225 c_oil->oil.mfcc_parent,
2226 ifp_out ? ifp_out->name : "<oif?>",
2227 oif_vif_index,
2228 ttl,
2229 oif_uptime,
2230 VTY_NEWLINE);
2231 }
2232 }
6250610a
JAG
2233
2234 /* Print list of static routes */
2235 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2236 char group_str[100];
2237 char source_str[100];
2238 int oif_vif_index;
2239
2240 pim_inet4_dump("<group?>", s_route->group, group_str, sizeof(group_str));
2241 pim_inet4_dump("<source?>", s_route->source, source_str, sizeof(source_str));
2242
2243 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
2244 struct interface *ifp_in;
2245 struct interface *ifp_out;
2246 char oif_uptime[10];
2247 int ttl;
2248 char proto[5];
2249
2250 ttl = s_route->oif_ttls[oif_vif_index];
2251 if (ttl < 1)
2252 continue;
2253
2254 ifp_in = pim_if_find_by_vif_index(s_route->iif);
2255 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
2256
2257 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->creation[oif_vif_index]);
2258
2259 proto[0] = '\0';
2260 strcat(proto, "S");
2261
2262 vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
2263 source_str,
2264 group_str,
2265 proto,
2266 ifp_in ? ifp_in->name : "<iif?>",
2267 s_route->iif,
2268 ifp_out ? ifp_out->name : "<oif?>",
2269 oif_vif_index,
2270 ttl,
2271 oif_uptime,
2272 VTY_NEWLINE);
2273 }
2274 }
12e41d03
DL
2275}
2276
2277DEFUN (show_ip_mroute,
2278 show_ip_mroute_cmd,
2279 "show ip mroute",
2280 SHOW_STR
2281 IP_STR
2282 MROUTE_STR)
2283{
2284 show_mroute(vty);
2285 return CMD_SUCCESS;
2286}
2287
2288static void show_mroute_count(struct vty *vty)
2289{
2290 struct listnode *node;
2291 struct channel_oil *c_oil;
6250610a 2292 struct static_route *s_route;
12e41d03
DL
2293
2294 vty_out(vty, "%s", VTY_NEWLINE);
2295
2296 vty_out(vty, "Source Group Packets Bytes WrongIf %s",
2297 VTY_NEWLINE);
2298
6250610a 2299 /* Print PIM and IGMP route counts */
12e41d03
DL
2300 for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
2301 char group_str[100];
2302 char source_str[100];
2303 struct sioc_sg_req sgreq;
2304
2305 memset(&sgreq, 0, sizeof(sgreq));
2306 sgreq.src = c_oil->oil.mfcc_origin;
2307 sgreq.grp = c_oil->oil.mfcc_mcastgrp;
2308
2309 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2310 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2311
2312 if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
2313 int e = errno;
2314 vty_out(vty,
1cb17fc7
DL
2315 "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s,%s): errno=%d: %s%s",
2316 (unsigned long)SIOCGETSGCNT,
12e41d03
DL
2317 source_str,
2318 group_str,
2319 e,
2320 safe_strerror(e),
2321 VTY_NEWLINE);
2322 continue;
2323 }
2324
2325 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2326 source_str,
2327 group_str,
2328 sgreq.pktcnt,
2329 sgreq.bytecnt,
2330 sgreq.wrong_if,
2331 VTY_NEWLINE);
6250610a
JAG
2332 }
2333
2334 /* Print static route counts */
2335 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
2336 char group_str[100];
2337 char source_str[100];
2338 struct sioc_sg_req sgreq;
2339
2340 memset(&sgreq, 0, sizeof(sgreq));
2341 sgreq.src = s_route->mc.mfcc_origin;
2342 sgreq.grp = s_route->mc.mfcc_mcastgrp;
2343
2344 pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
2345 pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
2346
2347 if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
2348 int e = errno;
2349 vty_out(vty,
2350 "ioctl(SIOCGETSGCNT=%d) failure for (S,G)=(%s,%s): errno=%d: %s%s",
2351 SIOCGETSGCNT,
2352 source_str,
2353 group_str,
2354 e,
2355 safe_strerror(e),
2356 VTY_NEWLINE);
2357 continue;
2358 }
12e41d03 2359
6250610a
JAG
2360 vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
2361 source_str,
2362 group_str,
2363 sgreq.pktcnt,
2364 sgreq.bytecnt,
2365 sgreq.wrong_if,
2366 VTY_NEWLINE);
12e41d03
DL
2367 }
2368}
2369
2370DEFUN (show_ip_mroute_count,
2371 show_ip_mroute_count_cmd,
2372 "show ip mroute count",
2373 SHOW_STR
2374 IP_STR
2375 MROUTE_STR
2376 "Route and packet count data\n")
2377{
2378 show_mroute_count(vty);
2379 return CMD_SUCCESS;
2380}
2381
2382DEFUN (show_ip_rib,
2383 show_ip_rib_cmd,
2384 "show ip rib A.B.C.D",
2385 SHOW_STR
2386 IP_STR
2387 RIB_STR
2388 "Unicast address\n")
2389{
2390 struct in_addr addr;
2391 const char *addr_str;
2392 struct pim_nexthop nexthop;
2393 char nexthop_addr_str[100];
2394 int result;
2395
2396 addr_str = argv[0];
2397 result = inet_pton(AF_INET, addr_str, &addr);
2398 if (result <= 0) {
2399 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
2400 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
2401 return CMD_WARNING;
2402 }
2403
2404 if (pim_nexthop_lookup(&nexthop, addr)) {
2405 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
2406 addr_str, VTY_NEWLINE);
2407 return CMD_WARNING;
2408 }
2409
2410 vty_out(vty, "Address NextHop Interface Metric Preference%s",
2411 VTY_NEWLINE);
2412
2413 pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
2414 nexthop_addr_str, sizeof(nexthop_addr_str));
2415
2416 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
2417 addr_str,
2418 nexthop_addr_str,
2419 nexthop.interface ? nexthop.interface->name : "<ifname?>",
2420 nexthop.mrib_route_metric,
2421 nexthop.mrib_metric_preference,
2422 VTY_NEWLINE);
2423
2424 return CMD_SUCCESS;
2425}
2426
2427static void show_ssmpingd(struct vty *vty)
2428{
2429 struct listnode *node;
2430 struct ssmpingd_sock *ss;
2431 time_t now;
2432
2433 vty_out(vty, "Source Socket Address Port Uptime Requests%s",
2434 VTY_NEWLINE);
2435
2436 if (!qpim_ssmpingd_list)
2437 return;
2438
2439 now = pim_time_monotonic_sec();
2440
2441 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
2442 char source_str[100];
2443 char ss_uptime[10];
2444 struct sockaddr_in bind_addr;
2445 socklen_t len = sizeof(bind_addr);
2446 char bind_addr_str[100];
2447
2448 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
2449
2450 if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
2451 vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
2452 source_str, ss->sock_fd, VTY_NEWLINE);
2453 }
2454
2455 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
2456 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
2457
2458 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
2459 source_str,
2460 ss->sock_fd,
2461 bind_addr_str,
2462 ntohs(bind_addr.sin_port),
2463 ss_uptime,
2464 (long long)ss->requests,
2465 VTY_NEWLINE);
2466 }
2467}
2468
2469DEFUN (show_ip_ssmpingd,
2470 show_ip_ssmpingd_cmd,
2471 "show ip ssmpingd",
2472 SHOW_STR
2473 IP_STR
2474 SHOW_SSMPINGD_STR)
2475{
2476 show_ssmpingd(vty);
2477 return CMD_SUCCESS;
2478}
2479
2480DEFUN (ip_multicast_routing,
2481 ip_multicast_routing_cmd,
2482 PIM_CMD_IP_MULTICAST_ROUTING,
2483 IP_STR
2484 "Enable IP multicast forwarding\n")
2485{
2486 pim_mroute_socket_enable();
2487 pim_if_add_vif_all();
2488 mroute_add_all();
6250610a 2489 static_mroute_add_all();
12e41d03
DL
2490 return CMD_SUCCESS;
2491}
2492
2493DEFUN (no_ip_multicast_routing,
2494 no_ip_multicast_routing_cmd,
2495 PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
2496 NO_STR
2497 IP_STR
2498 "Global IP configuration subcommands\n"
2499 "Enable IP multicast forwarding\n")
2500{
2501 mroute_del_all();
6250610a 2502 static_mroute_del_all();
12e41d03
DL
2503 pim_if_del_vif_all();
2504 pim_mroute_socket_disable();
2505 return CMD_SUCCESS;
2506}
2507
2508DEFUN (ip_ssmpingd,
2509 ip_ssmpingd_cmd,
2510 "ip ssmpingd [A.B.C.D]",
2511 IP_STR
2512 CONF_SSMPINGD_STR
2513 "Source address\n")
2514{
2515 int result;
2516 struct in_addr source_addr;
2517 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2518
2519 result = inet_pton(AF_INET, source_str, &source_addr);
2520 if (result <= 0) {
2521 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2522 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2523 return CMD_WARNING;
2524 }
2525
2526 result = pim_ssmpingd_start(source_addr);
2527 if (result) {
2528 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
2529 source_str, result, VTY_NEWLINE);
2530 return CMD_WARNING;
2531 }
2532
2533 return CMD_SUCCESS;
2534}
2535
2536DEFUN (no_ip_ssmpingd,
2537 no_ip_ssmpingd_cmd,
2538 "no ip ssmpingd [A.B.C.D]",
2539 NO_STR
2540 IP_STR
2541 CONF_SSMPINGD_STR
2542 "Source address\n")
2543{
2544 int result;
2545 struct in_addr source_addr;
2546 const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
2547
2548 result = inet_pton(AF_INET, source_str, &source_addr);
2549 if (result <= 0) {
2550 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
2551 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2552 return CMD_WARNING;
2553 }
2554
2555 result = pim_ssmpingd_stop(source_addr);
2556 if (result) {
2557 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
2558 source_str, result, VTY_NEWLINE);
2559 return CMD_WARNING;
2560 }
2561
2562 return CMD_SUCCESS;
2563}
2564
2565DEFUN (interface_ip_igmp,
2566 interface_ip_igmp_cmd,
2567 "ip igmp",
2568 IP_STR
2569 IFACE_IGMP_STR)
2570{
2571 struct interface *ifp;
2572 struct pim_interface *pim_ifp;
2573
2574 ifp = vty->index;
2575 pim_ifp = ifp->info;
2576
2577 if (!pim_ifp) {
2578 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
2579 if (!pim_ifp) {
2580 vty_out(vty, "Could not enable IGMP on interface %s%s",
2581 ifp->name, VTY_NEWLINE);
2582 return CMD_WARNING;
2583 }
2584 }
2585 else {
2586 PIM_IF_DO_IGMP(pim_ifp->options);
2587 }
2588
2589 pim_if_addr_add_all(ifp);
2590 pim_if_membership_refresh(ifp);
2591
2592 return CMD_SUCCESS;
2593}
2594
2595DEFUN (interface_no_ip_igmp,
2596 interface_no_ip_igmp_cmd,
2597 "no ip igmp",
2598 NO_STR
2599 IP_STR
2600 IFACE_IGMP_STR)
2601{
2602 struct interface *ifp;
2603 struct pim_interface *pim_ifp;
2604
2605 ifp = vty->index;
2606 pim_ifp = ifp->info;
2607 if (!pim_ifp)
2608 return CMD_SUCCESS;
2609
2610 PIM_IF_DONT_IGMP(pim_ifp->options);
2611
2612 pim_if_membership_clear(ifp);
2613
2614 pim_if_addr_del_all_igmp(ifp);
2615
2616 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
2617 pim_if_delete(ifp);
2618 }
2619
2620 return CMD_SUCCESS;
2621}
2622
2623DEFUN (interface_ip_igmp_join,
2624 interface_ip_igmp_join_cmd,
2625 "ip igmp join A.B.C.D A.B.C.D",
2626 IP_STR
2627 IFACE_IGMP_STR
2628 "IGMP join multicast group\n"
2629 "Multicast group address\n"
2630 "Source address\n")
2631{
2632 struct interface *ifp;
2633 const char *group_str;
2634 const char *source_str;
2635 struct in_addr group_addr;
2636 struct in_addr source_addr;
2637 int result;
2638
2639 ifp = vty->index;
2640
2641 /* Group address */
2642 group_str = argv[0];
2643 result = inet_pton(AF_INET, group_str, &group_addr);
2644 if (result <= 0) {
2645 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2646 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2647 return CMD_WARNING;
2648 }
2649
2650 /* Source address */
2651 source_str = argv[1];
2652 result = inet_pton(AF_INET, source_str, &source_addr);
2653 if (result <= 0) {
2654 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2655 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2656 return CMD_WARNING;
2657 }
2658
2659 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
2660 if (result) {
2661 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
2662 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2663 return CMD_WARNING;
2664 }
2665
2666 return CMD_SUCCESS;
2667}
2668
2669DEFUN (interface_no_ip_igmp_join,
2670 interface_no_ip_igmp_join_cmd,
2671 "no ip igmp join A.B.C.D A.B.C.D",
2672 NO_STR
2673 IP_STR
2674 IFACE_IGMP_STR
2675 "IGMP join multicast group\n"
2676 "Multicast group address\n"
2677 "Source address\n")
2678{
2679 struct interface *ifp;
2680 const char *group_str;
2681 const char *source_str;
2682 struct in_addr group_addr;
2683 struct in_addr source_addr;
2684 int result;
2685
2686 ifp = vty->index;
2687
2688 /* Group address */
2689 group_str = argv[0];
2690 result = inet_pton(AF_INET, group_str, &group_addr);
2691 if (result <= 0) {
2692 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
2693 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
2694 return CMD_WARNING;
2695 }
2696
2697 /* Source address */
2698 source_str = argv[1];
2699 result = inet_pton(AF_INET, source_str, &source_addr);
2700 if (result <= 0) {
2701 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
2702 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
2703 return CMD_WARNING;
2704 }
2705
2706 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
2707 if (result) {
2708 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
2709 group_str, source_str, ifp->name, result, VTY_NEWLINE);
2710 return CMD_WARNING;
2711 }
2712
2713 return CMD_SUCCESS;
2714}
2715
2716/*
2717 CLI reconfiguration affects the interface level (struct pim_interface).
2718 This function propagates the reconfiguration to every active socket
2719 for that interface.
2720 */
2721static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
2722{
2723 struct interface *ifp;
2724 struct pim_interface *pim_ifp;
2725
2726 zassert(igmp);
2727
2728 /* other querier present? */
2729
2730 if (igmp->t_other_querier_timer)
2731 return;
2732
2733 /* this is the querier */
2734
2735 zassert(igmp->interface);
2736 zassert(igmp->interface->info);
2737
2738 ifp = igmp->interface;
2739 pim_ifp = ifp->info;
2740
2741 if (PIM_DEBUG_IGMP_TRACE) {
2742 char ifaddr_str[100];
2743 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2744 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
2745 __PRETTY_FUNCTION__,
2746 ifaddr_str,
2747 ifp->name,
2748 pim_ifp->igmp_default_query_interval);
2749 }
2750
2751 /*
2752 igmp_startup_mode_on() will reset QQI:
2753
2754 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
2755 */
2756 igmp_startup_mode_on(igmp);
2757}
2758
2759static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
2760{
2761 if (igmp->t_igmp_query_timer) {
2762 /* other querier present */
2763 zassert(igmp->t_igmp_query_timer);
2764 zassert(!igmp->t_other_querier_timer);
2765
2766 pim_igmp_general_query_off(igmp);
2767 pim_igmp_general_query_on(igmp);
2768
2769 zassert(igmp->t_igmp_query_timer);
2770 zassert(!igmp->t_other_querier_timer);
2771 }
2772 else {
2773 /* this is the querier */
2774
2775 zassert(!igmp->t_igmp_query_timer);
2776 zassert(igmp->t_other_querier_timer);
2777
2778 pim_igmp_other_querier_timer_off(igmp);
2779 pim_igmp_other_querier_timer_on(igmp);
2780
2781 zassert(!igmp->t_igmp_query_timer);
2782 zassert(igmp->t_other_querier_timer);
2783 }
2784}
2785
2786static void change_query_interval(struct pim_interface *pim_ifp,
2787 int query_interval)
2788{
2789 struct listnode *sock_node;
2790 struct igmp_sock *igmp;
2791
2792 pim_ifp->igmp_default_query_interval = query_interval;
2793
2794 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2795 igmp_sock_query_interval_reconfig(igmp);
2796 igmp_sock_query_reschedule(igmp);
2797 }
2798}
2799
2800static void change_query_max_response_time(struct pim_interface *pim_ifp,
2801 int query_max_response_time_dsec)
2802{
2803 struct listnode *sock_node;
2804 struct igmp_sock *igmp;
2805
2806 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
2807
2808 /*
2809 Below we modify socket/group/source timers in order to quickly
2810 reflect the change. Otherwise, those timers would eventually catch
2811 up.
2812 */
2813
2814 /* scan all sockets */
2815 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
2816 struct listnode *grp_node;
2817 struct igmp_group *grp;
2818
2819 /* reschedule socket general query */
2820 igmp_sock_query_reschedule(igmp);
2821
2822 /* scan socket groups */
2823 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
2824 struct listnode *src_node;
2825 struct igmp_source *src;
2826
2827 /* reset group timers for groups in EXCLUDE mode */
2828 if (grp->group_filtermode_isexcl) {
2829 igmp_group_reset_gmi(grp);
2830 }
2831
2832 /* scan group sources */
2833 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2834
2835 /* reset source timers for sources with running timers */
2836 if (src->t_source_timer) {
2837 igmp_source_reset_gmi(igmp, grp, src);
2838 }
2839 }
2840 }
2841 }
2842}
2843
2844#define IGMP_QUERY_INTERVAL_MIN (1)
2845#define IGMP_QUERY_INTERVAL_MAX (1800)
2846
2847DEFUN (interface_ip_igmp_query_interval,
2848 interface_ip_igmp_query_interval_cmd,
2849 PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
2850 IP_STR
2851 IFACE_IGMP_STR
2852 IFACE_IGMP_QUERY_INTERVAL_STR
2853 "Query interval in seconds\n")
2854{
2855 struct interface *ifp;
2856 struct pim_interface *pim_ifp;
2857 int query_interval;
2858 int query_interval_dsec;
2859
2860 ifp = vty->index;
2861 pim_ifp = ifp->info;
2862
2863 if (!pim_ifp) {
2864 vty_out(vty,
2865 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2866 ifp->name,
2867 VTY_NEWLINE);
2868 return CMD_WARNING;
2869 }
2870
2871 query_interval = atoi(argv[0]);
2872 query_interval_dsec = 10 * query_interval;
2873
2874 /*
2875 It seems we don't need to check bounds since command.c does it
2876 already, but we verify them anyway for extra safety.
2877 */
2878 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
2879 vty_out(vty, "General query interval %d lower than minimum %d%s",
2880 query_interval,
2881 IGMP_QUERY_INTERVAL_MIN,
2882 VTY_NEWLINE);
2883 return CMD_WARNING;
2884 }
2885 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
2886 vty_out(vty, "General query interval %d higher than maximum %d%s",
2887 query_interval,
2888 IGMP_QUERY_INTERVAL_MAX,
2889 VTY_NEWLINE);
2890 return CMD_WARNING;
2891 }
2892
2893 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2894 vty_out(vty,
2895 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
2896 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2897 VTY_NEWLINE);
2898 return CMD_WARNING;
2899 }
2900
2901 change_query_interval(pim_ifp, query_interval);
2902
2903 return CMD_SUCCESS;
2904}
2905
2906DEFUN (interface_no_ip_igmp_query_interval,
2907 interface_no_ip_igmp_query_interval_cmd,
2908 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
2909 NO_STR
2910 IP_STR
2911 IFACE_IGMP_STR
2912 IFACE_IGMP_QUERY_INTERVAL_STR)
2913{
2914 struct interface *ifp;
2915 struct pim_interface *pim_ifp;
2916 int default_query_interval_dsec;
2917
2918 ifp = vty->index;
2919 pim_ifp = ifp->info;
2920
2921 if (!pim_ifp)
2922 return CMD_SUCCESS;
2923
2924 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
2925
2926 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
2927 vty_out(vty,
2928 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
2929 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
2930 VTY_NEWLINE);
2931 return CMD_WARNING;
2932 }
2933
2934 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
2935
2936 return CMD_SUCCESS;
2937}
2938
2939#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
2940#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
2941
2942DEFUN (interface_ip_igmp_query_max_response_time,
2943 interface_ip_igmp_query_max_response_time_cmd,
2944 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
2945 IP_STR
2946 IFACE_IGMP_STR
2947 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
2948 "Query response value in seconds\n")
2949{
2950 struct interface *ifp;
2951 struct pim_interface *pim_ifp;
2952 int query_max_response_time;
2953
2954 ifp = vty->index;
2955 pim_ifp = ifp->info;
2956
2957 if (!pim_ifp) {
2958 vty_out(vty,
2959 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
2960 ifp->name,
2961 VTY_NEWLINE);
2962 return CMD_WARNING;
2963 }
2964
2965 query_max_response_time = atoi(argv[0]);
2966
2967 /*
2968 It seems we don't need to check bounds since command.c does it
2969 already, but we verify them anyway for extra safety.
2970 */
2971 if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
2972 vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
2973 query_max_response_time,
2974 IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
2975 VTY_NEWLINE);
2976 return CMD_WARNING;
2977 }
2978 if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
2979 vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
2980 query_max_response_time,
2981 IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
2982 VTY_NEWLINE);
2983 return CMD_WARNING;
2984 }
2985
2986 if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
2987 vty_out(vty,
2988 "Can't set query max response time %d sec >= general query interval %d sec%s",
2989 query_max_response_time, pim_ifp->igmp_default_query_interval,
2990 VTY_NEWLINE);
2991 return CMD_WARNING;
2992 }
2993
2994 change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
2995
2996 return CMD_SUCCESS;
2997}
2998
2999DEFUN (interface_no_ip_igmp_query_max_response_time,
3000 interface_no_ip_igmp_query_max_response_time_cmd,
3001 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
3002 NO_STR
3003 IP_STR
3004 IFACE_IGMP_STR
3005 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
3006{
3007 struct interface *ifp;
3008 struct pim_interface *pim_ifp;
3009 int default_query_interval_dsec;
3010
3011 ifp = vty->index;
3012 pim_ifp = ifp->info;
3013
3014 if (!pim_ifp)
3015 return CMD_SUCCESS;
3016
3017 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3018
3019 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3020 vty_out(vty,
3021 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3022 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3023 VTY_NEWLINE);
3024 return CMD_WARNING;
3025 }
3026
3027 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3028
3029 return CMD_SUCCESS;
3030}
3031
3032#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
3033#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
3034
3035DEFUN (interface_ip_igmp_query_max_response_time_dsec,
3036 interface_ip_igmp_query_max_response_time_dsec_cmd,
3037 PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
3038 IP_STR
3039 IFACE_IGMP_STR
3040 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3041 "Query response value in deciseconds\n")
3042{
3043 struct interface *ifp;
3044 struct pim_interface *pim_ifp;
3045 int query_max_response_time_dsec;
3046 int default_query_interval_dsec;
3047
3048 ifp = vty->index;
3049 pim_ifp = ifp->info;
3050
3051 if (!pim_ifp) {
3052 vty_out(vty,
3053 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3054 ifp->name,
3055 VTY_NEWLINE);
3056 return CMD_WARNING;
3057 }
3058
3059 query_max_response_time_dsec = atoi(argv[0]);
3060
3061 /*
3062 It seems we don't need to check bounds since command.c does it
3063 already, but we verify them anyway for extra safety.
3064 */
3065 if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
3066 vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
3067 query_max_response_time_dsec,
3068 IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
3069 VTY_NEWLINE);
3070 return CMD_WARNING;
3071 }
3072 if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
3073 vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
3074 query_max_response_time_dsec,
3075 IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
3076 VTY_NEWLINE);
3077 return CMD_WARNING;
3078 }
3079
3080 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3081
3082 if (query_max_response_time_dsec >= default_query_interval_dsec) {
3083 vty_out(vty,
3084 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
3085 query_max_response_time_dsec, default_query_interval_dsec,
3086 VTY_NEWLINE);
3087 return CMD_WARNING;
3088 }
3089
3090 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
3091
3092 return CMD_SUCCESS;
3093}
3094
3095DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
3096 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
3097 PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
3098 NO_STR
3099 IP_STR
3100 IFACE_IGMP_STR
3101 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
3102{
3103 struct interface *ifp;
3104 struct pim_interface *pim_ifp;
3105 int default_query_interval_dsec;
3106
3107 ifp = vty->index;
3108 pim_ifp = ifp->info;
3109
3110 if (!pim_ifp)
3111 return CMD_SUCCESS;
3112
3113 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
3114
3115 if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
3116 vty_out(vty,
3117 "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
3118 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
3119 VTY_NEWLINE);
3120 return CMD_WARNING;
3121 }
3122
3123 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
3124
3125 return CMD_SUCCESS;
3126}
3127
dedccda6
DS
3128DEFUN (interface_ip_pim_drprio,
3129 interface_ip_pim_drprio_cmd,
3130 "ip pim drpriority <1-4294967295>",
3131 IP_STR
3132 PIM_STR
3133 "Set the Designated Router Election Priority\n"
3134 "Value of the new DR Priority\n")
3135{
3136 struct interface *ifp;
3137 struct pim_interface *pim_ifp;
3138 uint32_t old_dr_prio;
3139
3140 ifp = vty->index;
3141 pim_ifp = ifp->info;
3142
3143 if (!pim_ifp) {
3144 vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
3145 return CMD_WARNING;
3146 }
3147
3148 old_dr_prio = pim_ifp->pim_dr_priority;
3149
3150 pim_ifp->pim_dr_priority = strtol(argv[0], NULL, 10);
3151
3152 if (old_dr_prio != pim_ifp->pim_dr_priority) {
3153 if (pim_if_dr_election(ifp))
3154 pim_hello_restart_now(ifp);
3155 }
3156
3157 return CMD_SUCCESS;
3158}
3159
3160DEFUN (interface_no_ip_pim_drprio,
3161 interface_no_ip_pim_drprio_cmd,
3162 "no ip pim drpriority {<1-4294967295>}",
3163 IP_STR
3164 PIM_STR
3165 "Revert the Designated Router Priority to default\n"
3166 "Old Value of the Priority\n")
3167{
3168 struct interface *ifp;
3169 struct pim_interface *pim_ifp;
3170
3171 ifp = vty->index;
3172 pim_ifp = ifp->info;
3173
3174 if (!pim_ifp) {
3175 vty_out(vty, "Pim no enabled on this interface%s", VTY_NEWLINE);
3176 return CMD_WARNING;
3177 }
3178
3179 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
3180 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
3181 if (pim_if_dr_election(ifp))
3182 pim_hello_restart_now(ifp);
3183 }
3184
3185 return CMD_SUCCESS;
3186}
3187
12e41d03
DL
3188DEFUN (interface_ip_pim_ssm,
3189 interface_ip_pim_ssm_cmd,
3190 "ip pim ssm",
3191 IP_STR
3192 PIM_STR
3193 IFACE_PIM_STR)
3194{
3195 struct interface *ifp;
3196 struct pim_interface *pim_ifp;
3197
3198 ifp = vty->index;
3199 pim_ifp = ifp->info;
3200
3201 if (!pim_ifp) {
3202 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
3203 if (!pim_ifp) {
3204 vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
3205 return CMD_WARNING;
3206 }
3207 }
3208 else {
3209 PIM_IF_DO_PIM(pim_ifp->options);
3210 }
3211
3212 pim_if_addr_add_all(ifp);
3213 pim_if_membership_refresh(ifp);
3214
3215 return CMD_SUCCESS;
3216}
3217
3218DEFUN (interface_no_ip_pim_ssm,
3219 interface_no_ip_pim_ssm_cmd,
3220 "no ip pim ssm",
3221 NO_STR
3222 IP_STR
3223 PIM_STR
3224 IFACE_PIM_STR)
3225{
3226 struct interface *ifp;
3227 struct pim_interface *pim_ifp;
3228
3229 ifp = vty->index;
3230 pim_ifp = ifp->info;
3231 if (!pim_ifp)
3232 return CMD_SUCCESS;
3233
3234 PIM_IF_DONT_PIM(pim_ifp->options);
3235
3236 pim_if_membership_clear(ifp);
3237
3238 /*
3239 pim_if_addr_del_all() removes all sockets from
3240 pim_ifp->igmp_socket_list.
3241 */
3242 pim_if_addr_del_all(ifp);
3243
3244 /*
3245 pim_sock_delete() removes all neighbors from
3246 pim_ifp->pim_neighbor_list.
3247 */
3248 pim_sock_delete(ifp, "pim unconfigured on interface");
3249
3250 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
3251 pim_if_delete(ifp);
3252 }
3253
3254 return CMD_SUCCESS;
3255}
3256
6250610a
JAG
3257DEFUN (interface_ip_mroute,
3258 interface_ip_mroute_cmd,
3259 "ip mroute INTERFACE A.B.C.D",
3260 IP_STR
3261 "Add multicast route\n"
3262 "Outgoing interface name\n"
3263 "Group address\n")
3264{
3265 struct interface *iif;
3266 struct interface *oif;
3267 const char *oifname;
3268 const char *grp_str;
3269 struct in_addr grp_addr;
3270 struct in_addr src_addr;
3271 int result;
3272
3273 iif = vty->index;
3274
3275 oifname = argv[0];
3276 oif = if_lookup_by_name(oifname);
3277 if (!oif) {
3278 vty_out(vty, "No such interface name %s%s",
3279 oifname, VTY_NEWLINE);
3280 return CMD_WARNING;
3281 }
3282
3283 grp_str = argv[1];
3284 result = inet_pton(AF_INET, grp_str, &grp_addr);
3285 if (result <= 0) {
3286 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3287 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3288 return CMD_WARNING;
3289 }
3290
3291 src_addr.s_addr = INADDR_ANY;
3292
3293 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3294 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3295 return CMD_WARNING;
3296 }
3297
3298 return CMD_SUCCESS;
3299}
3300
3301DEFUN (interface_ip_mroute_source,
3302 interface_ip_mroute_source_cmd,
3303 "ip mroute INTERFACE A.B.C.D A.B.C.D",
3304 IP_STR
3305 "Add multicast route\n"
3306 "Outgoing interface name\n"
3307 "Group address\n"
3308 "Source address\n")
3309{
3310 struct interface *iif;
3311 struct interface *oif;
3312 const char *oifname;
3313 const char *grp_str;
3314 struct in_addr grp_addr;
3315 const char *src_str;
3316 struct in_addr src_addr;
3317 int result;
3318
3319 iif = vty->index;
3320
3321 oifname = argv[0];
3322 oif = if_lookup_by_name(oifname);
3323 if (!oif) {
3324 vty_out(vty, "No such interface name %s%s",
3325 oifname, VTY_NEWLINE);
3326 return CMD_WARNING;
3327 }
3328
3329 grp_str = argv[1];
3330 result = inet_pton(AF_INET, grp_str, &grp_addr);
3331 if (result <= 0) {
3332 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3333 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3334 return CMD_WARNING;
3335 }
3336
3337 src_str = argv[2];
3338 result = inet_pton(AF_INET, src_str, &src_addr);
3339 if (result <= 0) {
3340 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3341 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
3342 return CMD_WARNING;
3343 }
3344
3345 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
3346 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
3347 return CMD_WARNING;
3348 }
3349
3350 return CMD_SUCCESS;
3351}
3352
3353DEFUN (interface_no_ip_mroute,
3354 interface_no_ip_mroute_cmd,
3355 "no ip mroute INTERFACE A.B.C.D",
3356 NO_STR
3357 IP_STR
3358 "Add multicast route\n"
3359 "Outgoing interface name\n"
3360 "Group Address\n")
3361{
3362 struct interface *iif;
3363 struct interface *oif;
3364 const char *oifname;
3365 const char *grp_str;
3366 struct in_addr grp_addr;
3367 struct in_addr src_addr;
3368 int result;
3369
3370 iif = vty->index;
3371
3372 oifname = argv[0];
3373 oif = if_lookup_by_name(oifname);
3374 if (!oif) {
3375 vty_out(vty, "No such interface name %s%s",
3376 oifname, VTY_NEWLINE);
3377 return CMD_WARNING;
3378 }
3379
3380 grp_str = argv[1];
3381 result = inet_pton(AF_INET, grp_str, &grp_addr);
3382 if (result <= 0) {
3383 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3384 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
3385 return CMD_WARNING;
3386 }
3387
3388 src_addr.s_addr = INADDR_ANY;
3389
3390 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
3391 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3392 return CMD_WARNING;
3393 }
3394
3395 return CMD_SUCCESS;
3396}
3397
3398DEFUN (interface_no_ip_mroute_source,
3399 interface_no_ip_mroute_source_cmd,
3400 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
3401 NO_STR
3402 IP_STR
3403 "Add multicast route\n"
3404 "Outgoing interface name\n"
3405 "Group Address\n"
3406 "Source Address\n")
3407{
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
3419 oifname = argv[0];
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
3427 grp_str = argv[1];
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
3435 src_str = argv[2];
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_del(iif, oif, grp_addr, src_addr)) {
3444 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
3445 return CMD_WARNING;
3446 }
3447
3448 return CMD_SUCCESS;
3449}
3450
12e41d03
DL
3451DEFUN (debug_igmp,
3452 debug_igmp_cmd,
3453 "debug igmp",
3454 DEBUG_STR
3455 DEBUG_IGMP_STR)
3456{
3457 PIM_DO_DEBUG_IGMP_EVENTS;
3458 PIM_DO_DEBUG_IGMP_PACKETS;
3459 PIM_DO_DEBUG_IGMP_TRACE;
3460 return CMD_SUCCESS;
3461}
3462
3463DEFUN (no_debug_igmp,
3464 no_debug_igmp_cmd,
3465 "no debug igmp",
3466 NO_STR
3467 DEBUG_STR
3468 DEBUG_IGMP_STR)
3469{
3470 PIM_DONT_DEBUG_IGMP_EVENTS;
3471 PIM_DONT_DEBUG_IGMP_PACKETS;
3472 PIM_DONT_DEBUG_IGMP_TRACE;
3473 return CMD_SUCCESS;
3474}
3475
3476ALIAS (no_debug_igmp,
3477 undebug_igmp_cmd,
3478 "undebug igmp",
3479 UNDEBUG_STR
3480 DEBUG_IGMP_STR)
3481
3482DEFUN (debug_igmp_events,
3483 debug_igmp_events_cmd,
3484 "debug igmp events",
3485 DEBUG_STR
3486 DEBUG_IGMP_STR
3487 DEBUG_IGMP_EVENTS_STR)
3488{
3489 PIM_DO_DEBUG_IGMP_EVENTS;
3490 return CMD_SUCCESS;
3491}
3492
3493DEFUN (no_debug_igmp_events,
3494 no_debug_igmp_events_cmd,
3495 "no debug igmp events",
3496 NO_STR
3497 DEBUG_STR
3498 DEBUG_IGMP_STR
3499 DEBUG_IGMP_EVENTS_STR)
3500{
3501 PIM_DONT_DEBUG_IGMP_EVENTS;
3502 return CMD_SUCCESS;
3503}
3504
3505ALIAS (no_debug_igmp_events,
3506 undebug_igmp_events_cmd,
3507 "undebug igmp events",
3508 UNDEBUG_STR
3509 DEBUG_IGMP_STR
3510 DEBUG_IGMP_EVENTS_STR)
3511
3512DEFUN (debug_igmp_packets,
3513 debug_igmp_packets_cmd,
3514 "debug igmp packets",
3515 DEBUG_STR
3516 DEBUG_IGMP_STR
3517 DEBUG_IGMP_PACKETS_STR)
3518{
3519 PIM_DO_DEBUG_IGMP_PACKETS;
3520 return CMD_SUCCESS;
3521}
3522
3523DEFUN (no_debug_igmp_packets,
3524 no_debug_igmp_packets_cmd,
3525 "no debug igmp packets",
3526 NO_STR
3527 DEBUG_STR
3528 DEBUG_IGMP_STR
3529 DEBUG_IGMP_PACKETS_STR)
3530{
3531 PIM_DONT_DEBUG_IGMP_PACKETS;
3532 return CMD_SUCCESS;
3533}
3534
3535ALIAS (no_debug_igmp_packets,
3536 undebug_igmp_packets_cmd,
3537 "undebug igmp packets",
3538 UNDEBUG_STR
3539 DEBUG_IGMP_STR
3540 DEBUG_IGMP_PACKETS_STR)
3541
3542DEFUN (debug_igmp_trace,
3543 debug_igmp_trace_cmd,
3544 "debug igmp trace",
3545 DEBUG_STR
3546 DEBUG_IGMP_STR
3547 DEBUG_IGMP_TRACE_STR)
3548{
3549 PIM_DO_DEBUG_IGMP_TRACE;
3550 return CMD_SUCCESS;
3551}
3552
3553DEFUN (no_debug_igmp_trace,
3554 no_debug_igmp_trace_cmd,
3555 "no debug igmp trace",
3556 NO_STR
3557 DEBUG_STR
3558 DEBUG_IGMP_STR
3559 DEBUG_IGMP_TRACE_STR)
3560{
3561 PIM_DONT_DEBUG_IGMP_TRACE;
3562 return CMD_SUCCESS;
3563}
3564
3565ALIAS (no_debug_igmp_trace,
3566 undebug_igmp_trace_cmd,
3567 "undebug igmp trace",
3568 UNDEBUG_STR
3569 DEBUG_IGMP_STR
3570 DEBUG_IGMP_TRACE_STR)
3571
3572DEFUN (debug_mroute,
3573 debug_mroute_cmd,
3574 "debug mroute",
3575 DEBUG_STR
3576 DEBUG_MROUTE_STR)
3577{
3578 PIM_DO_DEBUG_MROUTE;
3579 return CMD_SUCCESS;
3580}
3581
3582DEFUN (no_debug_mroute,
3583 no_debug_mroute_cmd,
3584 "no debug mroute",
3585 NO_STR
3586 DEBUG_STR
3587 DEBUG_MROUTE_STR)
3588{
3589 PIM_DONT_DEBUG_MROUTE;
3590 return CMD_SUCCESS;
3591}
3592
3593ALIAS (no_debug_mroute,
3594 undebug_mroute_cmd,
3595 "undebug mroute",
3596 UNDEBUG_STR
3597 DEBUG_MROUTE_STR)
3598
6250610a
JAG
3599DEFUN (debug_static,
3600 debug_static_cmd,
3601 "debug static",
3602 DEBUG_STR
3603 DEBUG_STATIC_STR)
3604{
3605 PIM_DO_DEBUG_STATIC;
3606 return CMD_SUCCESS;
3607}
3608
3609DEFUN (no_debug_static,
3610 no_debug_static_cmd,
3611 "no debug static",
3612 NO_STR
3613 DEBUG_STR
3614 DEBUG_STATIC_STR)
3615{
3616 PIM_DONT_DEBUG_STATIC;
3617 return CMD_SUCCESS;
3618}
3619
3620ALIAS (no_debug_static,
3621 undebug_static_cmd,
3622 "undebug static",
3623 UNDEBUG_STR
3624 DEBUG_STATIC_STR)
3625
12e41d03
DL
3626DEFUN (debug_pim,
3627 debug_pim_cmd,
3628 "debug pim",
3629 DEBUG_STR
3630 DEBUG_PIM_STR)
3631{
3632 PIM_DO_DEBUG_PIM_EVENTS;
3633 PIM_DO_DEBUG_PIM_PACKETS;
3634 PIM_DO_DEBUG_PIM_TRACE;
3635 return CMD_SUCCESS;
3636}
3637
3638DEFUN (no_debug_pim,
3639 no_debug_pim_cmd,
3640 "no debug pim",
3641 NO_STR
3642 DEBUG_STR
3643 DEBUG_PIM_STR)
3644{
3645 PIM_DONT_DEBUG_PIM_EVENTS;
3646 PIM_DONT_DEBUG_PIM_PACKETS;
3647 PIM_DONT_DEBUG_PIM_TRACE;
3648
3649 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3650 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3651
3652 return CMD_SUCCESS;
3653}
3654
3655ALIAS (no_debug_pim,
3656 undebug_pim_cmd,
3657 "undebug pim",
3658 UNDEBUG_STR
3659 DEBUG_PIM_STR)
3660
3661DEFUN (debug_pim_events,
3662 debug_pim_events_cmd,
3663 "debug pim events",
3664 DEBUG_STR
3665 DEBUG_PIM_STR
3666 DEBUG_PIM_EVENTS_STR)
3667{
3668 PIM_DO_DEBUG_PIM_EVENTS;
3669 return CMD_SUCCESS;
3670}
3671
3672DEFUN (no_debug_pim_events,
3673 no_debug_pim_events_cmd,
3674 "no debug pim events",
3675 NO_STR
3676 DEBUG_STR
3677 DEBUG_PIM_STR
3678 DEBUG_PIM_EVENTS_STR)
3679{
3680 PIM_DONT_DEBUG_PIM_EVENTS;
3681 return CMD_SUCCESS;
3682}
3683
3684ALIAS (no_debug_pim_events,
3685 undebug_pim_events_cmd,
3686 "undebug pim events",
3687 UNDEBUG_STR
3688 DEBUG_PIM_STR
3689 DEBUG_PIM_EVENTS_STR)
3690
3691DEFUN (debug_pim_packets,
3692 debug_pim_packets_cmd,
3693 "debug pim packets",
3694 DEBUG_STR
3695 DEBUG_PIM_STR
3696 DEBUG_PIM_PACKETS_STR)
3697{
3698 PIM_DO_DEBUG_PIM_PACKETS;
3699 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
3700 return CMD_SUCCESS;
3701}
3702
3703DEFUN (debug_pim_packets_filter,
3704 debug_pim_packets_filter_cmd,
3705 "debug pim packets (hello|joins)",
3706 DEBUG_STR
3707 DEBUG_PIM_STR
3708 DEBUG_PIM_PACKETS_STR
3709 DEBUG_PIM_HELLO_PACKETS_STR
3710 DEBUG_PIM_J_P_PACKETS_STR)
3711{
3712 if (strncmp(argv[0],"h",1) == 0)
3713 {
3714 PIM_DO_DEBUG_PIM_HELLO;
3715 vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
3716 }
3717 else if (strncmp(argv[0],"j",1) == 0)
3718 {
3719 PIM_DO_DEBUG_PIM_J_P;
3720 vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
3721 }
3722 return CMD_SUCCESS;
3723}
3724
3725DEFUN (no_debug_pim_packets,
3726 no_debug_pim_packets_cmd,
3727 "no debug pim packets",
3728 NO_STR
3729 DEBUG_STR
3730 DEBUG_PIM_STR
3731 DEBUG_PIM_PACKETS_STR
3732 DEBUG_PIM_HELLO_PACKETS_STR
3733 DEBUG_PIM_J_P_PACKETS_STR)
3734{
3735 PIM_DONT_DEBUG_PIM_PACKETS;
3736 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
3737 return CMD_SUCCESS;
3738}
3739
3740DEFUN (no_debug_pim_packets_filter,
3741 no_debug_pim_packets_filter_cmd,
3742 "no debug pim packets (hello|joins)",
3743 NO_STR
3744 DEBUG_STR
3745 DEBUG_PIM_STR
3746 DEBUG_PIM_PACKETS_STR
3747 DEBUG_PIM_HELLO_PACKETS_STR
3748 DEBUG_PIM_J_P_PACKETS_STR)
3749{
3750 if (strncmp(argv[0],"h",1) == 0)
3751 {
3752 PIM_DONT_DEBUG_PIM_HELLO;
3753 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
3754 }
3755 else if (strncmp(argv[0],"j",1) == 0)
3756 {
3757 PIM_DONT_DEBUG_PIM_J_P;
3758 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
3759 }
3760 return CMD_SUCCESS;
3761}
3762
3763ALIAS (no_debug_pim_packets,
3764 undebug_pim_packets_cmd,
3765 "undebug pim packets",
3766 UNDEBUG_STR
3767 DEBUG_PIM_STR
3768 DEBUG_PIM_PACKETS_STR)
3769
3770DEFUN (debug_pim_packetdump_send,
3771 debug_pim_packetdump_send_cmd,
3772 "debug pim packet-dump send",
3773 DEBUG_STR
3774 DEBUG_PIM_STR
3775 DEBUG_PIM_PACKETDUMP_STR
3776 DEBUG_PIM_PACKETDUMP_SEND_STR)
3777{
3778 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
3779 return CMD_SUCCESS;
3780}
3781
3782DEFUN (no_debug_pim_packetdump_send,
3783 no_debug_pim_packetdump_send_cmd,
3784 "no debug pim packet-dump send",
3785 NO_STR
3786 DEBUG_STR
3787 DEBUG_PIM_STR
3788 DEBUG_PIM_PACKETDUMP_STR
3789 DEBUG_PIM_PACKETDUMP_SEND_STR)
3790{
3791 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
3792 return CMD_SUCCESS;
3793}
3794
3795ALIAS (no_debug_pim_packetdump_send,
3796 undebug_pim_packetdump_send_cmd,
3797 "undebug pim packet-dump send",
3798 UNDEBUG_STR
3799 DEBUG_PIM_STR
3800 DEBUG_PIM_PACKETDUMP_STR
3801 DEBUG_PIM_PACKETDUMP_SEND_STR)
3802
3803DEFUN (debug_pim_packetdump_recv,
3804 debug_pim_packetdump_recv_cmd,
3805 "debug pim packet-dump receive",
3806 DEBUG_STR
3807 DEBUG_PIM_STR
3808 DEBUG_PIM_PACKETDUMP_STR
3809 DEBUG_PIM_PACKETDUMP_RECV_STR)
3810{
3811 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
3812 return CMD_SUCCESS;
3813}
3814
3815DEFUN (no_debug_pim_packetdump_recv,
3816 no_debug_pim_packetdump_recv_cmd,
3817 "no debug pim packet-dump receive",
3818 NO_STR
3819 DEBUG_STR
3820 DEBUG_PIM_STR
3821 DEBUG_PIM_PACKETDUMP_STR
3822 DEBUG_PIM_PACKETDUMP_RECV_STR)
3823{
3824 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
3825 return CMD_SUCCESS;
3826}
3827
3828ALIAS (no_debug_pim_packetdump_recv,
3829 undebug_pim_packetdump_recv_cmd,
3830 "undebug pim packet-dump receive",
3831 UNDEBUG_STR
3832 DEBUG_PIM_STR
3833 DEBUG_PIM_PACKETDUMP_STR
3834 DEBUG_PIM_PACKETDUMP_RECV_STR)
3835
3836DEFUN (debug_pim_trace,
3837 debug_pim_trace_cmd,
3838 "debug pim trace",
3839 DEBUG_STR
3840 DEBUG_PIM_STR
3841 DEBUG_PIM_TRACE_STR)
3842{
3843 PIM_DO_DEBUG_PIM_TRACE;
3844 return CMD_SUCCESS;
3845}
3846
3847DEFUN (no_debug_pim_trace,
3848 no_debug_pim_trace_cmd,
3849 "no debug pim trace",
3850 NO_STR
3851 DEBUG_STR
3852 DEBUG_PIM_STR
3853 DEBUG_PIM_TRACE_STR)
3854{
3855 PIM_DONT_DEBUG_PIM_TRACE;
3856 return CMD_SUCCESS;
3857}
3858
3859ALIAS (no_debug_pim_trace,
3860 undebug_pim_trace_cmd,
3861 "undebug pim trace",
3862 UNDEBUG_STR
3863 DEBUG_PIM_STR
3864 DEBUG_PIM_TRACE_STR)
3865
3866DEFUN (debug_ssmpingd,
3867 debug_ssmpingd_cmd,
3868 "debug ssmpingd",
3869 DEBUG_STR
3870 DEBUG_PIM_STR
3871 DEBUG_SSMPINGD_STR)
3872{
3873 PIM_DO_DEBUG_SSMPINGD;
3874 return CMD_SUCCESS;
3875}
3876
3877DEFUN (no_debug_ssmpingd,
3878 no_debug_ssmpingd_cmd,
3879 "no debug ssmpingd",
3880 NO_STR
3881 DEBUG_STR
3882 DEBUG_PIM_STR
3883 DEBUG_SSMPINGD_STR)
3884{
3885 PIM_DONT_DEBUG_SSMPINGD;
3886 return CMD_SUCCESS;
3887}
3888
3889ALIAS (no_debug_ssmpingd,
3890 undebug_ssmpingd_cmd,
3891 "undebug ssmpingd",
3892 UNDEBUG_STR
3893 DEBUG_PIM_STR
3894 DEBUG_SSMPINGD_STR)
3895
3896DEFUN (debug_pim_zebra,
3897 debug_pim_zebra_cmd,
3898 "debug pim zebra",
3899 DEBUG_STR
3900 DEBUG_PIM_STR
3901 DEBUG_PIM_ZEBRA_STR)
3902{
3903 PIM_DO_DEBUG_ZEBRA;
3904 return CMD_SUCCESS;
3905}
3906
3907DEFUN (no_debug_pim_zebra,
3908 no_debug_pim_zebra_cmd,
3909 "no debug pim zebra",
3910 NO_STR
3911 DEBUG_STR
3912 DEBUG_PIM_STR
3913 DEBUG_PIM_ZEBRA_STR)
3914{
3915 PIM_DONT_DEBUG_ZEBRA;
3916 return CMD_SUCCESS;
3917}
3918
3919ALIAS (no_debug_pim_zebra,
3920 undebug_pim_zebra_cmd,
3921 "undebug pim zebra",
3922 UNDEBUG_STR
3923 DEBUG_PIM_STR
3924 DEBUG_PIM_ZEBRA_STR)
3925
7a1d58ce
DS
3926DEFUN (show_debugging_pim,
3927 show_debugging_pim_cmd,
3928 "show debugging pim",
12e41d03 3929 SHOW_STR
7a1d58ce
DS
3930 DEBUG_STR
3931 PIM_STR)
12e41d03
DL
3932{
3933 pim_debug_config_write(vty);
3934 return CMD_SUCCESS;
3935}
3936
3937static struct igmp_sock *find_igmp_sock_by_fd(int fd)
3938{
3939 struct listnode *ifnode;
3940 struct interface *ifp;
3941
3942 /* scan all interfaces */
469351b3 3943 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
3944 struct pim_interface *pim_ifp;
3945 struct igmp_sock *igmp;
3946
3947 if (!ifp->info)
3948 continue;
3949
3950 pim_ifp = ifp->info;
3951
3952 /* lookup igmp socket under current interface */
3953 igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
3954 if (igmp)
3955 return igmp;
3956 }
3957
3958 return 0;
3959}
3960
3961DEFUN (test_igmp_receive_report,
3962 test_igmp_receive_report_cmd,
3963 "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
3964 "Test\n"
3965 "Test IGMP protocol\n"
3966 "Test IGMP message\n"
3967 "Test IGMP report\n"
3968 "Socket\n"
3969 "IGMP group address\n"
3970 "Record type\n"
3971 "Sources\n")
3972{
3973 char buf[1000];
3974 char *igmp_msg;
3975 struct ip *ip_hdr;
3976 size_t ip_hlen; /* ip header length in bytes */
3977 int ip_msg_len;
3978 int igmp_msg_len;
3979 const char *socket;
3980 int socket_fd;
3981 const char *grp_str;
3982 struct in_addr grp_addr;
3983 const char *record_type_str;
3984 int record_type;
3985 const char *src_str;
3986 int result;
3987 struct igmp_sock *igmp;
3988 char *group_record;
3989 int num_sources;
3990 struct in_addr *sources;
3991 struct in_addr *src_addr;
3992 int argi;
3993
3994 socket = argv[0];
3995 socket_fd = atoi(socket);
3996 igmp = find_igmp_sock_by_fd(socket_fd);
3997 if (!igmp) {
3998 vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
3999 socket, socket_fd, VTY_NEWLINE);
4000 return CMD_WARNING;
4001 }
4002
4003 grp_str = argv[1];
4004 result = inet_pton(AF_INET, grp_str, &grp_addr);
4005 if (result <= 0) {
4006 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4007 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4008 return CMD_WARNING;
4009 }
4010
4011 record_type_str = argv[2];
4012 record_type = atoi(record_type_str);
4013
4014 /*
4015 Tweak IP header
4016 */
4017 ip_hdr = (struct ip *) buf;
4018 ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
4019 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4020 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4021 ip_hdr->ip_src = igmp->ifaddr;
4022 ip_hdr->ip_dst = igmp->ifaddr;
4023
4024 /*
4025 Build IGMP v3 report message
4026 */
4027 igmp_msg = buf + ip_hlen;
4028 group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
4029 *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
4030 *(uint16_t *) (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
4031 *(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
4032 *(uint8_t *) (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
4033 memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
4034
4035 /* Scan LINE sources */
4036 sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
4037 src_addr = sources;
4038 for (argi = 3; argi < argc; ++argi,++src_addr) {
4039 src_str = argv[argi];
4040 result = inet_pton(AF_INET, src_str, src_addr);
4041 if (result <= 0) {
4042 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4043 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4044 return CMD_WARNING;
4045 }
4046 }
4047 num_sources = src_addr - sources;
4048
4049 *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
4050
4051 igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4); /* v3 report for one single group record */
4052
4053 /* compute checksum */
4054 *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
4055
4056 /* "receive" message */
4057
4058 ip_msg_len = ip_hlen + igmp_msg_len;
4059 result = pim_igmp_packet(igmp, buf, ip_msg_len);
4060 if (result) {
4061 vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
4062 ip_msg_len, result, VTY_NEWLINE);
4063 return CMD_WARNING;
4064 }
4065
4066 return CMD_SUCCESS;
4067}
4068
4069static int hexval(uint8_t ch)
4070{
4071 return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
4072}
4073
4074DEFUN (test_pim_receive_dump,
4075 test_pim_receive_dump_cmd,
4076 "test pim receive dump INTERFACE A.B.C.D .LINE",
4077 "Test\n"
4078 "Test PIM protocol\n"
4079 "Test PIM message reception\n"
4080 "Test PIM packet dump reception from neighbor\n"
4081 "Interface\n"
4082 "Neighbor address\n"
4083 "Packet dump\n")
4084{
4085 uint8_t buf[1000];
4086 uint8_t *pim_msg;
4087 struct ip *ip_hdr;
4088 size_t ip_hlen; /* ip header length in bytes */
4089 int ip_msg_len;
4090 int pim_msg_size;
4091 const char *neigh_str;
4092 struct in_addr neigh_addr;
4093 const char *ifname;
4094 struct interface *ifp;
4095 int argi;
4096 int result;
4097
4098 /* Find interface */
4099 ifname = argv[0];
4100 ifp = if_lookup_by_name(ifname);
4101 if (!ifp) {
4102 vty_out(vty, "No such interface name %s%s",
4103 ifname, VTY_NEWLINE);
4104 return CMD_WARNING;
4105 }
4106
4107 /* Neighbor address */
4108 neigh_str = argv[1];
4109 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4110 if (result <= 0) {
4111 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4112 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4113 return CMD_WARNING;
4114 }
4115
4116 /*
4117 Tweak IP header
4118 */
4119 ip_hdr = (struct ip *) buf;
4120 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4121 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4122 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4123 ip_hdr->ip_src = neigh_addr;
4124 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4125
4126 /*
4127 Build PIM hello message
4128 */
4129 pim_msg = buf + ip_hlen;
4130 pim_msg_size = 0;
4131
4132 /* Scan LINE dump into buffer */
4133 for (argi = 2; argi < argc; ++argi) {
4134 const char *str = argv[argi];
4135 int str_len = strlen(str);
4136 int str_last = str_len - 1;
4137 int i;
4138
4139 if (str_len % 2) {
4140 vty_out(vty, "%% Uneven hex array arg %d=%s%s",
4141 argi, str, VTY_NEWLINE);
4142 return CMD_WARNING;
4143 }
4144
4145 for (i = 0; i < str_last; i += 2) {
4146 uint8_t octet;
4147 int left;
4148 uint8_t h1 = str[i];
4149 uint8_t h2 = str[i + 1];
4150
4151 if (!isxdigit(h1) || !isxdigit(h2)) {
4152 vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
4153 h1, h2, argi, str, VTY_NEWLINE);
4154 return CMD_WARNING;
4155 }
4156 octet = (hexval(h1) << 4) + hexval(h2);
4157
4158 left = sizeof(buf) - ip_hlen - pim_msg_size;
4159 if (left < 1) {
4160 vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
4161 sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
4162 return CMD_WARNING;
4163 }
4164
4165 pim_msg[pim_msg_size++] = octet;
4166 }
4167 }
4168
4169 ip_msg_len = ip_hlen + pim_msg_size;
4170
4171 vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
4172 sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
4173
4174 /* "receive" message */
4175
4176 result = pim_pim_packet(ifp, buf, ip_msg_len);
4177 if (result) {
4178 vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
4179 ip_msg_len, result, VTY_NEWLINE);
4180 return CMD_WARNING;
4181 }
4182
4183 return CMD_SUCCESS;
4184}
4185
4186DEFUN (test_pim_receive_hello,
4187 test_pim_receive_hello_cmd,
4188 "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
4189 "Test\n"
4190 "Test PIM protocol\n"
4191 "Test PIM message reception\n"
4192 "Test PIM hello reception from neighbor\n"
4193 "Interface\n"
4194 "Neighbor address\n"
4195 "Neighbor holdtime\n"
4196 "Neighbor DR priority\n"
4197 "Neighbor generation ID\n"
4198 "Neighbor propagation delay (msec)\n"
4199 "Neighbor override interval (msec)\n"
4200 "Neighbor LAN prune delay T-bit\n"
4201 "Neighbor secondary addresses\n")
4202{
4203 uint8_t buf[1000];
4204 uint8_t *pim_msg;
4205 struct ip *ip_hdr;
4206 size_t ip_hlen; /* ip header length in bytes */
4207 int ip_msg_len;
4208 int pim_tlv_size;
4209 int pim_msg_size;
4210 const char *neigh_str;
4211 struct in_addr neigh_addr;
4212 const char *ifname;
4213 struct interface *ifp;
4214 uint16_t neigh_holdtime;
4215 uint16_t neigh_propagation_delay;
4216 uint16_t neigh_override_interval;
4217 int neigh_can_disable_join_suppression;
4218 uint32_t neigh_dr_priority;
4219 uint32_t neigh_generation_id;
4220 int argi;
4221 int result;
4222
4223 /* Find interface */
4224 ifname = argv[0];
4225 ifp = if_lookup_by_name(ifname);
4226 if (!ifp) {
4227 vty_out(vty, "No such interface name %s%s",
4228 ifname, VTY_NEWLINE);
4229 return CMD_WARNING;
4230 }
4231
4232 /* Neighbor address */
4233 neigh_str = argv[1];
4234 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4235 if (result <= 0) {
4236 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4237 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4238 return CMD_WARNING;
4239 }
4240
4241 neigh_holdtime = atoi(argv[2]);
4242 neigh_dr_priority = atoi(argv[3]);
4243 neigh_generation_id = atoi(argv[4]);
4244 neigh_propagation_delay = atoi(argv[5]);
4245 neigh_override_interval = atoi(argv[6]);
4246 neigh_can_disable_join_suppression = atoi(argv[7]);
4247
4248 /*
4249 Tweak IP header
4250 */
4251 ip_hdr = (struct ip *) buf;
4252 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4253 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4254 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4255 ip_hdr->ip_src = neigh_addr;
4256 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4257
4258 /*
4259 Build PIM hello message
4260 */
4261 pim_msg = buf + ip_hlen;
4262
4263 /* Scan LINE addresses */
4264 for (argi = 8; argi < argc; ++argi) {
4265 const char *sec_str = argv[argi];
4266 struct in_addr sec_addr;
4267 result = inet_pton(AF_INET, sec_str, &sec_addr);
4268 if (result <= 0) {
4269 vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
4270 sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
4271 return CMD_WARNING;
4272 }
4273
4274 vty_out(vty,
4275 "FIXME WRITEME consider neighbor secondary address %s%s",
4276 sec_str, VTY_NEWLINE);
4277 }
4278
4279 pim_tlv_size = pim_hello_build_tlv(ifp->name,
4280 pim_msg + PIM_PIM_MIN_LEN,
4281 sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
4282 neigh_holdtime,
4283 neigh_dr_priority,
4284 neigh_generation_id,
4285 neigh_propagation_delay,
4286 neigh_override_interval,
4287 neigh_can_disable_join_suppression,
4288 0 /* FIXME secondary address list */);
4289 if (pim_tlv_size < 0) {
4290 vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
4291 pim_tlv_size, VTY_NEWLINE);
4292 return CMD_WARNING;
4293 }
4294
4295 pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
4296
4297 pim_msg_build_header(pim_msg, pim_msg_size,
4298 PIM_MSG_TYPE_HELLO);
4299
4300 /* "receive" message */
4301
4302 ip_msg_len = ip_hlen + pim_msg_size;
4303 result = pim_pim_packet(ifp, buf, ip_msg_len);
4304 if (result) {
4305 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4306 ip_msg_len, result, VTY_NEWLINE);
4307 return CMD_WARNING;
4308 }
4309
4310 return CMD_SUCCESS;
4311}
4312
4313DEFUN (test_pim_receive_assert,
4314 test_pim_receive_assert_cmd,
4315 "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
4316 "Test\n"
4317 "Test PIM protocol\n"
4318 "Test PIM message reception\n"
4319 "Test reception of PIM assert\n"
4320 "Interface\n"
4321 "Neighbor address\n"
4322 "Assert multicast group address\n"
4323 "Assert unicast source address\n"
4324 "Assert metric preference\n"
4325 "Assert route metric\n"
4326 "Assert RPT bit flag\n")
4327{
4328 uint8_t buf[1000];
4329 uint8_t *buf_pastend = buf + sizeof(buf);
4330 uint8_t *pim_msg;
4331 struct ip *ip_hdr;
4332 size_t ip_hlen; /* ip header length in bytes */
4333 int ip_msg_len;
4334 int pim_msg_size;
4335 const char *neigh_str;
4336 struct in_addr neigh_addr;
4337 const char *group_str;
4338 struct in_addr group_addr;
4339 const char *source_str;
4340 struct in_addr source_addr;
4341 const char *ifname;
4342 struct interface *ifp;
4343 uint32_t assert_metric_preference;
4344 uint32_t assert_route_metric;
4345 uint32_t assert_rpt_bit_flag;
4346 int remain;
4347 int result;
4348
4349 /* Find interface */
4350 ifname = argv[0];
4351 ifp = if_lookup_by_name(ifname);
4352 if (!ifp) {
4353 vty_out(vty, "No such interface name %s%s",
4354 ifname, VTY_NEWLINE);
4355 return CMD_WARNING;
4356 }
4357
4358 /* Neighbor address */
4359 neigh_str = argv[1];
4360 result = inet_pton(AF_INET, neigh_str, &neigh_addr);
4361 if (result <= 0) {
4362 vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
4363 neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
4364 return CMD_WARNING;
4365 }
4366
4367 /* Group address */
4368 group_str = argv[2];
4369 result = inet_pton(AF_INET, group_str, &group_addr);
4370 if (result <= 0) {
4371 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4372 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4373 return CMD_WARNING;
4374 }
4375
4376 /* Source address */
4377 source_str = argv[3];
4378 result = inet_pton(AF_INET, source_str, &source_addr);
4379 if (result <= 0) {
4380 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4381 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4382 return CMD_WARNING;
4383 }
4384
4385 assert_metric_preference = atoi(argv[4]);
4386 assert_route_metric = atoi(argv[5]);
4387 assert_rpt_bit_flag = atoi(argv[6]);
4388
4389 remain = buf_pastend - buf;
4390 if (remain < (int) sizeof(struct ip)) {
4391 vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
4392 remain, sizeof(struct ip), VTY_NEWLINE);
4393 return CMD_WARNING;
4394 }
4395
4396 /*
4397 Tweak IP header
4398 */
4399 ip_hdr = (struct ip *) buf;
4400 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4401 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4402 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4403 ip_hdr->ip_src = neigh_addr;
4404 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4405
4406 /*
4407 Build PIM assert message
4408 */
4409 pim_msg = buf + ip_hlen; /* skip ip header */
4410
4411 pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
4412 group_addr, source_addr,
4413 assert_metric_preference,
4414 assert_route_metric,
4415 assert_rpt_bit_flag);
4416 if (pim_msg_size < 0) {
4417 vty_out(vty, "Failure building PIM assert message: size=%d%s",
4418 pim_msg_size, VTY_NEWLINE);
4419 return CMD_WARNING;
4420 }
4421
4422 /* "receive" message */
4423
4424 ip_msg_len = ip_hlen + pim_msg_size;
4425 result = pim_pim_packet(ifp, buf, ip_msg_len);
4426 if (result) {
4427 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4428 ip_msg_len, result, VTY_NEWLINE);
4429 return CMD_WARNING;
4430 }
4431
4432 return CMD_SUCCESS;
4433}
4434
4435static int recv_joinprune(struct vty *vty,
4436 const char *argv[],
4437 int src_is_join)
4438{
4439 uint8_t buf[1000];
4440 const uint8_t *buf_pastend = buf + sizeof(buf);
4441 uint8_t *pim_msg;
4442 uint8_t *pim_msg_curr;
4443 int pim_msg_size;
4444 struct ip *ip_hdr;
4445 size_t ip_hlen; /* ip header length in bytes */
4446 int ip_msg_len;
4447 uint16_t neigh_holdtime;
4448 const char *neigh_dst_str;
4449 struct in_addr neigh_dst_addr;
4450 const char *neigh_src_str;
4451 struct in_addr neigh_src_addr;
4452 const char *group_str;
4453 struct in_addr group_addr;
4454 const char *source_str;
4455 struct in_addr source_addr;
4456 const char *ifname;
4457 struct interface *ifp;
4458 int result;
4459 int remain;
4460 uint16_t num_joined;
4461 uint16_t num_pruned;
4462
4463 /* Find interface */
4464 ifname = argv[0];
4465 ifp = if_lookup_by_name(ifname);
4466 if (!ifp) {
4467 vty_out(vty, "No such interface name %s%s",
4468 ifname, VTY_NEWLINE);
4469 return CMD_WARNING;
4470 }
4471
4472 neigh_holdtime = atoi(argv[1]);
4473
4474 /* Neighbor destination address */
4475 neigh_dst_str = argv[2];
4476 result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
4477 if (result <= 0) {
4478 vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
4479 neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
4480 return CMD_WARNING;
4481 }
4482
4483 /* Neighbor source address */
4484 neigh_src_str = argv[3];
4485 result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
4486 if (result <= 0) {
4487 vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
4488 neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4489 return CMD_WARNING;
4490 }
4491
4492 /* Multicast group address */
4493 group_str = argv[4];
4494 result = inet_pton(AF_INET, group_str, &group_addr);
4495 if (result <= 0) {
4496 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4497 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4498 return CMD_WARNING;
4499 }
4500
4501 /* Multicast source address */
4502 source_str = argv[5];
4503 result = inet_pton(AF_INET, source_str, &source_addr);
4504 if (result <= 0) {
4505 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4506 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4507 return CMD_WARNING;
4508 }
4509
4510 /*
4511 Tweak IP header
4512 */
4513 ip_hdr = (struct ip *) buf;
4514 ip_hdr->ip_p = PIM_IP_PROTO_PIM;
4515 ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
4516 ip_hdr->ip_hl = ip_hlen >> 2; /* ip header length in 4-byte words */
4517 ip_hdr->ip_src = neigh_src_addr;
4518 ip_hdr->ip_dst = qpim_all_pim_routers_addr;
4519
4520 /*
4521 Build PIM message
4522 */
4523 pim_msg = buf + ip_hlen;
4524
4525 /* skip room for pim header */
4526 pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
4527
4528 remain = buf_pastend - pim_msg_curr;
4529 pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
4530 remain,
4531 neigh_dst_addr);
4532 if (!pim_msg_curr) {
4533 vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
4534 neigh_dst_str, remain, VTY_NEWLINE);
4535 return CMD_WARNING;
4536 }
4537
4538 remain = buf_pastend - pim_msg_curr;
4539 if (remain < 4) {
4540 vty_out(vty, "Group will not fit: space left=%d%s",
4541 remain, VTY_NEWLINE);
4542 return CMD_WARNING;
4543 }
4544
4545 *pim_msg_curr = 0; /* reserved */
4546 ++pim_msg_curr;
4547 *pim_msg_curr = 1; /* number of groups */
4548 ++pim_msg_curr;
4549 *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
4550 ++pim_msg_curr;
4551 ++pim_msg_curr;
4552
4553 remain = buf_pastend - pim_msg_curr;
4554 pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
4555 remain,
4556 group_addr);
4557 if (!pim_msg_curr) {
4558 vty_out(vty, "Failure encoding group address %s: space left=%d%s",
4559 group_str, remain, VTY_NEWLINE);
4560 return CMD_WARNING;
4561 }
4562
4563 remain = buf_pastend - pim_msg_curr;
4564 if (remain < 4) {
4565 vty_out(vty, "Sources will not fit: space left=%d%s",
4566 remain, VTY_NEWLINE);
4567 return CMD_WARNING;
4568 }
4569
4570 if (src_is_join) {
4571 num_joined = 1;
4572 num_pruned = 0;
4573 }
4574 else {
4575 num_joined = 0;
4576 num_pruned = 1;
4577 }
4578
4579 /* number of joined sources */
4580 *((uint16_t *) pim_msg_curr) = htons(num_joined);
4581 ++pim_msg_curr;
4582 ++pim_msg_curr;
4583
4584 /* number of pruned sources */
4585 *((uint16_t *) pim_msg_curr) = htons(num_pruned);
4586 ++pim_msg_curr;
4587 ++pim_msg_curr;
4588
4589 remain = buf_pastend - pim_msg_curr;
4590 pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
4591 remain,
4592 source_addr);
4593 if (!pim_msg_curr) {
4594 vty_out(vty, "Failure encoding source address %s: space left=%d%s",
4595 source_str, remain, VTY_NEWLINE);
4596 return CMD_WARNING;
4597 }
4598
4599 /* Add PIM header */
4600
4601 pim_msg_size = pim_msg_curr - pim_msg;
4602
4603 pim_msg_build_header(pim_msg, pim_msg_size,
4604 PIM_MSG_TYPE_JOIN_PRUNE);
4605
4606 /*
4607 "Receive" message
4608 */
4609
4610 ip_msg_len = ip_hlen + pim_msg_size;
4611 result = pim_pim_packet(ifp, buf, ip_msg_len);
4612 if (result) {
4613 vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
4614 ip_msg_len, result, VTY_NEWLINE);
4615 return CMD_WARNING;
4616 }
4617
4618 return CMD_SUCCESS;
4619}
4620
4621DEFUN (test_pim_receive_join,
4622 test_pim_receive_join_cmd,
4623 "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4624 "Test\n"
4625 "Test PIM protocol\n"
4626 "Test PIM message reception\n"
4627 "Test PIM join reception from neighbor\n"
4628 "Interface\n"
4629 "Neighbor holdtime\n"
4630 "Upstream neighbor unicast destination address\n"
4631 "Downstream neighbor unicast source address\n"
4632 "Multicast group address\n"
4633 "Unicast source address\n")
4634{
4635 return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
4636}
4637
4638DEFUN (test_pim_receive_prune,
4639 test_pim_receive_prune_cmd,
4640 "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
4641 "Test\n"
4642 "Test PIM protocol\n"
4643 "Test PIM message reception\n"
4644 "Test PIM prune reception from neighbor\n"
4645 "Interface\n"
4646 "Neighbor holdtime\n"
4647 "Upstream neighbor unicast destination address\n"
4648 "Downstream neighbor unicast source address\n"
4649 "Multicast group address\n"
4650 "Unicast source address\n")
4651{
4652 return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
4653}
4654
4655DEFUN (test_pim_receive_upcall,
4656 test_pim_receive_upcall_cmd,
4657 "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
4658 "Test\n"
4659 "Test PIM protocol\n"
4660 "Test PIM message reception\n"
4661 "Test reception of kernel upcall\n"
4662 "NOCACHE kernel upcall\n"
4663 "WRONGVIF kernel upcall\n"
4664 "WHOLEPKT kernel upcall\n"
4665 "Input interface vif index\n"
4666 "Multicast group address\n"
4667 "Multicast source address\n")
4668{
4669 struct igmpmsg msg;
4670 const char *upcall_type;
4671 const char *group_str;
4672 const char *source_str;
4673 int result;
4674
4675 upcall_type = argv[0];
4676
4677 if (upcall_type[0] == 'n')
4678 msg.im_msgtype = IGMPMSG_NOCACHE;
4679 else if (upcall_type[1] == 'r')
4680 msg.im_msgtype = IGMPMSG_WRONGVIF;
4681 else if (upcall_type[1] == 'h')
4682 msg.im_msgtype = IGMPMSG_WHOLEPKT;
4683 else {
4684 vty_out(vty, "Unknown kernel upcall type: %s%s",
4685 upcall_type, VTY_NEWLINE);
4686 return CMD_WARNING;
4687 }
4688
4689 msg.im_vif = atoi(argv[1]);
4690
4691 /* Group address */
4692 group_str = argv[2];
4693 result = inet_pton(AF_INET, group_str, &msg.im_dst);
4694 if (result <= 0) {
4695 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4696 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
4697 return CMD_WARNING;
4698 }
4699
4700 /* Source address */
4701 source_str = argv[3];
4702 result = inet_pton(AF_INET, source_str, &msg.im_src);
4703 if (result <= 0) {
4704 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4705 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
4706 return CMD_WARNING;
4707 }
4708
4709 msg.im_mbz = 0; /* Must be zero */
4710
4711 result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
4712 if (result) {
4713 vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
4714 sizeof(msg), result, VTY_NEWLINE);
4715 return CMD_WARNING;
4716 }
4717
4718 return CMD_SUCCESS;
4719}
4720
4721void pim_cmd_init()
4722{
4723 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
4724 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
4725
4726 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
4727 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
4728 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
4729 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
4730#if 0
4731 install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
4732#else
4733 install_element (CONFIG_NODE, &pim_interface_cmd);
4734#endif
4735 install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
4736
4737 install_default (INTERFACE_NODE);
4738 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
4739 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
4740 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
4741 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
4742 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
4743 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
4744 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
4745 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
4746 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
4747 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
4748 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
dedccda6
DS
4749 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
4750 install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
4751 install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
12e41d03 4752
6250610a
JAG
4753 // Static mroutes NEB
4754 install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
4755 install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
4756 install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
4757 install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
4758
12e41d03
DL
4759 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
4760 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
4761 install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
4762 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
4763 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4764 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
4765 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4766 install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
4767 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
4768 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
4769 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
4770 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
4771 install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
4772 install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
4773 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
4774 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
4775 install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
4776 install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
4777 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
4778 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
4779 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
4780 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
4781 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
4782 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
4783 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
4784 install_element (VIEW_NODE, &show_ip_multicast_cmd);
4785 install_element (VIEW_NODE, &show_ip_mroute_cmd);
4786 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
4787 install_element (VIEW_NODE, &show_ip_rib_cmd);
4788 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 4789 install_element (VIEW_NODE, &show_debugging_pim_cmd);
12e41d03
DL
4790
4791 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
4792 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
4793 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
4794 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
4795 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
4796
4797 install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
4798 install_element (ENABLE_NODE, &show_ip_igmp_join_cmd);
4799 install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
4800 install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
4801 install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
4802 install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
4803 install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
4804 install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
4805 install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
4806 install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
4807 install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
4808 install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
4809 install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
4810 install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
4811 install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
4812 install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
4813 install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
4814 install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
4815 install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
4816 install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
4817 install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
4818 install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
4819 install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
4820 install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
4821 install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
4822 install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
4823 install_element (ENABLE_NODE, &show_ip_multicast_cmd);
4824 install_element (ENABLE_NODE, &show_ip_mroute_cmd);
4825 install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
4826 install_element (ENABLE_NODE, &show_ip_rib_cmd);
4827 install_element (ENABLE_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 4828 install_element (ENABLE_NODE, &show_debugging_pim_cmd);
12e41d03
DL
4829
4830 install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
4831 install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
4832 install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
4833 install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
4834 install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
4835 install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
4836 install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
4837
4838 install_element (ENABLE_NODE, &debug_igmp_cmd);
4839 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
4840 install_element (ENABLE_NODE, &undebug_igmp_cmd);
4841 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
4842 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
4843 install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
4844 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
4845 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
4846 install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
4847 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
4848 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
4849 install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
4850 install_element (ENABLE_NODE, &debug_mroute_cmd);
4851 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
6250610a
JAG
4852 install_element (ENABLE_NODE, &debug_static_cmd);
4853 install_element (ENABLE_NODE, &no_debug_static_cmd);
12e41d03
DL
4854 install_element (ENABLE_NODE, &debug_pim_cmd);
4855 install_element (ENABLE_NODE, &no_debug_pim_cmd);
4856 install_element (ENABLE_NODE, &undebug_pim_cmd);
4857 install_element (ENABLE_NODE, &debug_pim_events_cmd);
4858 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
4859 install_element (ENABLE_NODE, &undebug_pim_events_cmd);
4860 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
4861 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
4862 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
4863 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
4864 install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
4865 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
4866 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
4867 install_element (ENABLE_NODE, &undebug_pim_packetdump_send_cmd);
4868 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
4869 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
4870 install_element (ENABLE_NODE, &undebug_pim_packetdump_recv_cmd);
4871 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
4872 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
4873 install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
4874 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
4875 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
4876 install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
4877 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
4878 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
4879 install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
4880
4881 install_element (CONFIG_NODE, &debug_igmp_cmd);
4882 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
4883 install_element (CONFIG_NODE, &undebug_igmp_cmd);
4884 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
4885 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
4886 install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
4887 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
4888 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
4889 install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
4890 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
4891 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
4892 install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
4893 install_element (CONFIG_NODE, &debug_mroute_cmd);
4894 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
6250610a
JAG
4895 install_element (CONFIG_NODE, &debug_static_cmd);
4896 install_element (CONFIG_NODE, &no_debug_static_cmd);
12e41d03
DL
4897 install_element (CONFIG_NODE, &debug_pim_cmd);
4898 install_element (CONFIG_NODE, &no_debug_pim_cmd);
4899 install_element (CONFIG_NODE, &undebug_pim_cmd);
4900 install_element (CONFIG_NODE, &debug_pim_events_cmd);
4901 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
4902 install_element (CONFIG_NODE, &undebug_pim_events_cmd);
4903 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
4904 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
4905 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
4906 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
4907 install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
4908 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
4909 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
4910 install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
4911 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
4912 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
4913 install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
4914 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
4915 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
4916 install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
4917}