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