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