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