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