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