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