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