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