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