]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_cmd.c
pimd: Add ability to tweak join/prune send time
[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_ifp_in = 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)
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_object_get_ex(json_source, in_ifname, &json_ifp_in);
2944
2945 if (!json_ifp_in) {
2946 json_ifp_in = json_object_new_object();
2947 json_object_object_add(json_source, in_ifname, json_ifp_in);
2948 }
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 json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
2990 } else {
2991 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
2992 strcpy(proto, "PIM");
2993 }
2994
2995 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
2996 strcpy(proto, "IGMP");
2997 }
2998
2999 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) {
3000 strcpy(proto, "SRC");
3001 }
3002
3003 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3004 src_str,
3005 grp_str,
3006 proto,
3007 in_ifname,
3008 out_ifname,
3009 ttl,
3010 oif_uptime,
3011 VTY_NEWLINE);
3012
3013 if (first)
3014 {
3015 src_str[0] = '\0';
3016 grp_str[0] = '\0';
3017 in_ifname[0] = '\0';
3018 first = 0;
3019 }
3020 }
3021 }
3022
3023 if (!uj && !found_oif) {
3024 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3025 src_str,
3026 grp_str,
3027 "none",
3028 in_ifname,
3029 "none",
3030 0,
3031 "--:--:--",
3032 VTY_NEWLINE);
3033 }
3034 }
3035
3036 /* Print list of static routes */
3037 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
3038 char grp_str[INET_ADDRSTRLEN];
3039 char src_str[INET_ADDRSTRLEN];
3040 char in_ifname[16];
3041 char out_ifname[16];
3042 int oif_vif_index;
3043 struct interface *ifp_in;
3044 char proto[100];
3045 first = 1;
3046
3047 if (!s_route->c_oil.installed)
3048 continue;
3049
3050 pim_inet4_dump("<group?>", s_route->group, grp_str, sizeof(grp_str));
3051 pim_inet4_dump("<source?>", s_route->source, src_str, sizeof(src_str));
3052 ifp_in = pim_if_find_by_vif_index(s_route->iif);
3053 found_oif = 0;
3054
3055 if (ifp_in)
3056 strcpy(in_ifname, ifp_in->name);
3057 else
3058 strcpy(in_ifname, "<iif?>");
3059
3060 if (uj) {
3061
3062 /* Find the group, create it if it doesn't exist */
3063 json_object_object_get_ex(json, grp_str, &json_group);
3064
3065 if (!json_group) {
3066 json_group = json_object_new_object();
3067 json_object_object_add(json, grp_str, json_group);
3068 }
3069
3070 /* Find the source nested under the group, create it if it doesn't exist */
3071 json_object_object_get_ex(json_group, src_str, &json_source);
3072
3073 if (!json_source) {
3074 json_source = json_object_new_object();
3075 json_object_object_add(json_group, src_str, json_source);
3076 }
3077
3078 /* Find the inbound interface nested under the source, create it if it doesn't exist */
3079 json_object_object_get_ex(json_source, in_ifname, &json_ifp_in);
3080
3081 if (!json_ifp_in) {
3082 json_ifp_in = json_object_new_object();
3083 json_object_object_add(json_source, in_ifname, json_ifp_in);
3084 }
3085
3086 } else {
3087 strcpy(proto, "STATIC");
3088 }
3089
3090 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
3091 struct interface *ifp_out;
3092 char oif_uptime[10];
3093 int ttl;
3094
3095 ttl = s_route->oif_ttls[oif_vif_index];
3096 if (ttl < 1)
3097 continue;
3098
3099 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
3100 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->c_oil.oif_creation[oif_vif_index]);
3101 found_oif = 1;
3102
3103 if (ifp_out)
3104 strcpy(out_ifname, ifp_out->name);
3105 else
3106 strcpy(out_ifname, "<oif?>");
3107
3108 if (uj) {
3109 json_ifp_out = json_object_new_object();
3110 json_object_string_add(json_ifp_out, "source", src_str);
3111 json_object_string_add(json_ifp_out, "group", grp_str);
3112 json_object_boolean_true_add(json_ifp_out, "protocolStatic");
3113 json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
3114 json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
3115 json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
3116 json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
3117 json_object_int_add(json_ifp_out, "ttl", ttl);
3118 json_object_string_add(json_ifp_out, "upTime", oif_uptime);
3119 json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
3120 } else {
3121 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3122 src_str,
3123 grp_str,
3124 proto,
3125 in_ifname,
3126 out_ifname,
3127 ttl,
3128 oif_uptime,
3129 VTY_NEWLINE);
3130 if (first)
3131 {
3132 src_str[0] = '\0';
3133 grp_str[0] = '\0';
3134 in_ifname[0] = '\0';
3135 first = 0;
3136 }
3137 }
3138 }
3139
3140 if (!uj && !found_oif) {
3141 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
3142 src_str,
3143 grp_str,
3144 proto,
3145 in_ifname,
3146 "none",
3147 0,
3148 "--:--:--",
3149 VTY_NEWLINE);
3150 }
3151 }
3152
3153 if (uj) {
3154 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
3155 json_object_free(json);
3156 }
3157 }
3158
3159 DEFUN (show_ip_mroute,
3160 show_ip_mroute_cmd,
3161 "show ip mroute [json]",
3162 SHOW_STR
3163 IP_STR
3164 MROUTE_STR)
3165 {
3166 u_char uj = use_json(argc, argv);
3167 show_mroute(vty, uj);
3168 return CMD_SUCCESS;
3169 }
3170
3171 static void show_mroute_count(struct vty *vty)
3172 {
3173 struct listnode *node;
3174 struct channel_oil *c_oil;
3175 struct static_route *s_route;
3176
3177 vty_out(vty, "%s", VTY_NEWLINE);
3178
3179 vty_out(vty, "Source Group LastUsed Packets Bytes WrongIf %s",
3180 VTY_NEWLINE);
3181
3182 /* Print PIM and IGMP route counts */
3183 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
3184 char group_str[INET_ADDRSTRLEN];
3185 char source_str[INET_ADDRSTRLEN];
3186
3187 if (!c_oil->installed)
3188 continue;
3189
3190 pim_mroute_update_counters (c_oil);
3191
3192 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
3193 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
3194
3195 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3196 source_str,
3197 group_str,
3198 c_oil->cc.lastused/100,
3199 c_oil->cc.pktcnt,
3200 c_oil->cc.bytecnt,
3201 c_oil->cc.wrong_if,
3202 VTY_NEWLINE);
3203 }
3204
3205 /* Print static route counts */
3206 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
3207 char group_str[INET_ADDRSTRLEN];
3208 char source_str[INET_ADDRSTRLEN];
3209
3210 if (!s_route->c_oil.installed)
3211 continue;
3212
3213 pim_mroute_update_counters (&s_route->c_oil);
3214
3215 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
3216 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
3217
3218 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
3219 source_str,
3220 group_str,
3221 s_route->c_oil.cc.lastused,
3222 s_route->c_oil.cc.pktcnt,
3223 s_route->c_oil.cc.bytecnt,
3224 s_route->c_oil.cc.wrong_if,
3225 VTY_NEWLINE);
3226 }
3227 }
3228
3229 DEFUN (show_ip_mroute_count,
3230 show_ip_mroute_count_cmd,
3231 "show ip mroute count",
3232 SHOW_STR
3233 IP_STR
3234 MROUTE_STR
3235 "Route and packet count data\n")
3236 {
3237 show_mroute_count(vty);
3238 return CMD_SUCCESS;
3239 }
3240
3241 DEFUN (show_ip_rib,
3242 show_ip_rib_cmd,
3243 "show ip rib A.B.C.D",
3244 SHOW_STR
3245 IP_STR
3246 RIB_STR
3247 "Unicast address\n")
3248 {
3249 int idx_ipv4 = 3;
3250 struct in_addr addr;
3251 const char *addr_str;
3252 struct pim_nexthop nexthop;
3253 char nexthop_addr_str[PREFIX_STRLEN];
3254 int result;
3255
3256 memset (&nexthop, 0, sizeof (nexthop));
3257 addr_str = argv[idx_ipv4]->arg;
3258 result = inet_pton(AF_INET, addr_str, &addr);
3259 if (result <= 0) {
3260 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
3261 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
3262 return CMD_WARNING;
3263 }
3264
3265 if (pim_nexthop_lookup(&nexthop, addr, 0)) {
3266 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
3267 addr_str, VTY_NEWLINE);
3268 return CMD_WARNING;
3269 }
3270
3271 vty_out(vty, "Address NextHop Interface Metric Preference%s",
3272 VTY_NEWLINE);
3273
3274 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
3275 nexthop_addr_str, sizeof(nexthop_addr_str));
3276
3277 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
3278 addr_str,
3279 nexthop_addr_str,
3280 nexthop.interface ? nexthop.interface->name : "<ifname?>",
3281 nexthop.mrib_route_metric,
3282 nexthop.mrib_metric_preference,
3283 VTY_NEWLINE);
3284
3285 return CMD_SUCCESS;
3286 }
3287
3288 static void show_ssmpingd(struct vty *vty)
3289 {
3290 struct listnode *node;
3291 struct ssmpingd_sock *ss;
3292 time_t now;
3293
3294 vty_out(vty, "Source Socket Address Port Uptime Requests%s",
3295 VTY_NEWLINE);
3296
3297 if (!qpim_ssmpingd_list)
3298 return;
3299
3300 now = pim_time_monotonic_sec();
3301
3302 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
3303 char source_str[INET_ADDRSTRLEN];
3304 char ss_uptime[10];
3305 struct sockaddr_in bind_addr;
3306 socklen_t len = sizeof(bind_addr);
3307 char bind_addr_str[INET_ADDRSTRLEN];
3308
3309 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
3310
3311 if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
3312 vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3313 source_str, ss->sock_fd, VTY_NEWLINE);
3314 }
3315
3316 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
3317 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
3318
3319 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
3320 source_str,
3321 ss->sock_fd,
3322 bind_addr_str,
3323 ntohs(bind_addr.sin_port),
3324 ss_uptime,
3325 (long long)ss->requests,
3326 VTY_NEWLINE);
3327 }
3328 }
3329
3330 DEFUN (show_ip_ssmpingd,
3331 show_ip_ssmpingd_cmd,
3332 "show ip ssmpingd",
3333 SHOW_STR
3334 IP_STR
3335 SHOW_SSMPINGD_STR)
3336 {
3337 show_ssmpingd(vty);
3338 return CMD_SUCCESS;
3339 }
3340
3341 static int
3342 pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const char *plist)
3343 {
3344 int result;
3345
3346 result = pim_rp_new (rp, group, plist);
3347
3348 if (result == PIM_MALLOC_FAIL)
3349 {
3350 vty_out (vty, "%% Out of memory%s", VTY_NEWLINE);
3351 return CMD_WARNING;
3352 }
3353
3354 if (result == PIM_GROUP_BAD_ADDRESS)
3355 {
3356 vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
3357 return CMD_WARNING;
3358 }
3359
3360 if (result == PIM_RP_BAD_ADDRESS)
3361 {
3362 vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
3363 return CMD_WARNING;
3364 }
3365
3366 if (result == PIM_RP_NO_PATH)
3367 {
3368 vty_out (vty, "%% No Path to RP address specified: %s%s", rp, VTY_NEWLINE);
3369 return CMD_WARNING;
3370 }
3371
3372 if (result == PIM_GROUP_OVERLAP)
3373 {
3374 vty_out (vty, "%% Group range specified cannot overlap%s", VTY_NEWLINE);
3375 return CMD_WARNING;
3376 }
3377
3378 if (result == PIM_GROUP_PFXLIST_OVERLAP)
3379 {
3380 vty_out (vty, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE);
3381 return CMD_WARNING;
3382 }
3383
3384 if (result == PIM_RP_PFXLIST_IN_USE)
3385 {
3386 vty_out (vty, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE);
3387 return CMD_WARNING;
3388 }
3389
3390 return CMD_SUCCESS;
3391 }
3392
3393 DEFUN (ip_pim_joinprune_time,
3394 ip_pim_joinprune_time_cmd,
3395 "ip pim join-prune-interval <60-600>",
3396 IP_STR
3397 "pim multicast routing\n"
3398 "Join Prune Send Interval\n"
3399 "Seconds\n")
3400 {
3401 qpim_t_periodic = atoi(argv[3]->arg);
3402 return CMD_SUCCESS;
3403 }
3404
3405 DEFUN (no_ip_pim_joinprune_time,
3406 no_ip_pim_joinprune_time_cmd,
3407 "no ip pim join-prune-interval <60-600>",
3408 NO_STR
3409 IP_STR
3410 "pim multicast routing\n"
3411 "Join Prune Send Interval\n"
3412 "Seconds\n")
3413 {
3414 qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
3415 return CMD_SUCCESS;
3416 }
3417
3418 DEFUN (ip_pim_register_suppress,
3419 ip_pim_register_suppress_cmd,
3420 "ip pim register-suppress-time <5-60000>",
3421 IP_STR
3422 "pim multicast routing\n"
3423 "Register Suppress Timer\n"
3424 "Seconds\n")
3425 {
3426 qpim_keep_alive_time = atoi (argv[3]->arg);
3427 return CMD_SUCCESS;
3428 }
3429
3430 DEFUN (no_ip_pim_register_suppress,
3431 no_ip_pim_register_suppress_cmd,
3432 "no ip pim register-suppress-time <5-60000>",
3433 NO_STR
3434 IP_STR
3435 "pim multicast routing\n"
3436 "Register Suppress Timer\n"
3437 "Seconds\n")
3438 {
3439 qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
3440 return CMD_SUCCESS;
3441 }
3442
3443 DEFUN (ip_pim_keep_alive,
3444 ip_pim_keep_alive_cmd,
3445 "ip pim keep-alive-timer <31-60000>",
3446 IP_STR
3447 "pim multicast routing\n"
3448 "Keep alive Timer\n"
3449 "Seconds\n")
3450 {
3451 qpim_rp_keep_alive_time = atoi (argv[4]->arg);
3452 return CMD_SUCCESS;
3453 }
3454
3455 DEFUN (no_ip_pim_keep_alive,
3456 no_ip_pim_keep_alive_cmd,
3457 "no ip pim keep-alive-timer <31-60000>",
3458 NO_STR
3459 IP_STR
3460 "pim multicast routing\n"
3461 "Keep alive Timer\n"
3462 "Seconds\n")
3463 {
3464 qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
3465 return CMD_SUCCESS;
3466 }
3467
3468 DEFUN (ip_pim_packets,
3469 ip_pim_packets_cmd,
3470 "ip pim packets <1-100>",
3471 IP_STR
3472 "pim multicast routing\n"
3473 "Number of packets to process at one time per fd\n")
3474 {
3475 qpim_packet_process = atoi (argv[3]->arg);
3476 return CMD_SUCCESS;
3477 }
3478
3479 DEFUN (no_ip_pim_packets,
3480 no_ip_pim_packets_cmd,
3481 "no ip pim packets <1-100>",
3482 NO_STR
3483 IP_STR
3484 "pim multicast routing\n"
3485 "Number of packets to process at one time per fd\n")
3486 {
3487 qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
3488 return CMD_SUCCESS;
3489 }
3490
3491 DEFUN (ip_pim_rp,
3492 ip_pim_rp_cmd,
3493 "ip pim rp A.B.C.D [A.B.C.D/M]",
3494 IP_STR
3495 "pim multicast routing\n"
3496 "Rendevous Point\n"
3497 "ip address of RP\n")
3498 {
3499 int idx_ipv4 = 3;
3500 return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
3501 }
3502
3503 DEFUN (ip_pim_rp_prefix_list,
3504 ip_pim_rp_prefix_list_cmd,
3505 "ip pim rp A.B.C.D prefix-list WORD",
3506 IP_STR
3507 "pim multicast routing\n"
3508 "Rendevous Point\n"
3509 "ip address of RP\n"
3510 "group prefix-list filter\n"
3511 "Name of a prefix-list\n")
3512 {
3513 return pim_rp_cmd_worker (vty, argv[3]->arg, NULL, argv[5]->arg);
3514 }
3515
3516 static int
3517 pim_no_rp_cmd_worker (struct vty *vty, const char *rp, const char *group,
3518 const char *plist)
3519 {
3520 int result = pim_rp_del (rp, group, plist);
3521
3522 if (result == PIM_GROUP_BAD_ADDRESS)
3523 {
3524 vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
3525 return CMD_WARNING;
3526 }
3527
3528 if (result == PIM_RP_BAD_ADDRESS)
3529 {
3530 vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
3531 return CMD_WARNING;
3532 }
3533
3534 if (result == PIM_RP_NOT_FOUND)
3535 {
3536 vty_out (vty, "%% Unable to find specified RP%s", VTY_NEWLINE);
3537 return CMD_WARNING;
3538 }
3539
3540 return CMD_SUCCESS;
3541 }
3542
3543 DEFUN (no_ip_pim_rp,
3544 no_ip_pim_rp_cmd,
3545 "no ip pim rp A.B.C.D [A.B.C.D/M]",
3546 NO_STR
3547 IP_STR
3548 "pim multicast routing\n"
3549 "Rendevous Point\n"
3550 "ip address of RP\n")
3551 {
3552 int idx_ipv4 = 4;
3553 return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
3554 }
3555
3556 DEFUN (no_ip_pim_rp_prefix_list,
3557 no_ip_pim_rp_prefix_list_cmd,
3558 "no ip pim rp A.B.C.D prefix-list WORD",
3559 NO_STR
3560 IP_STR
3561 "pim multicast routing\n"
3562 "Rendevous Point\n"
3563 "ip address of RP\n"
3564 "group prefix-list filter\n"
3565 "Name of a prefix-list\n")
3566 {
3567 return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
3568 }
3569
3570 DEFUN (ip_multicast_routing,
3571 ip_multicast_routing_cmd,
3572 "ip multicast-routing",
3573 IP_STR
3574 "Enable IP multicast forwarding\n")
3575 {
3576 pim_mroute_socket_enable();
3577 pim_if_add_vif_all();
3578 mroute_add_all();
3579 static_mroute_add_all();
3580 return CMD_SUCCESS;
3581 }
3582
3583 DEFUN (no_ip_multicast_routing,
3584 no_ip_multicast_routing_cmd,
3585 "no ip multicast-routing",
3586 NO_STR
3587 IP_STR
3588 "Global IP configuration subcommands\n"
3589 "Enable IP multicast forwarding\n")
3590 {
3591 mroute_del_all();
3592 static_mroute_del_all();
3593 pim_if_del_vif_all();
3594 pim_mroute_socket_disable();
3595 return CMD_SUCCESS;
3596 }
3597
3598 DEFUN (ip_ssmpingd,
3599 ip_ssmpingd_cmd,
3600 "ip ssmpingd [A.B.C.D]",
3601 IP_STR
3602 CONF_SSMPINGD_STR
3603 "Source address\n")
3604 {
3605 int idx_ipv4 = 2;
3606 int result;
3607 struct in_addr source_addr;
3608 const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
3609
3610 result = inet_pton(AF_INET, source_str, &source_addr);
3611 if (result <= 0) {
3612 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
3613 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3614 return CMD_WARNING;
3615 }
3616
3617 result = pim_ssmpingd_start(source_addr);
3618 if (result) {
3619 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
3620 source_str, result, VTY_NEWLINE);
3621 return CMD_WARNING;
3622 }
3623
3624 return CMD_SUCCESS;
3625 }
3626
3627 DEFUN (no_ip_ssmpingd,
3628 no_ip_ssmpingd_cmd,
3629 "no ip ssmpingd [A.B.C.D]",
3630 NO_STR
3631 IP_STR
3632 CONF_SSMPINGD_STR
3633 "Source address\n")
3634 {
3635 int idx_ipv4 = 3;
3636 int result;
3637 struct in_addr source_addr;
3638 const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
3639
3640 result = inet_pton(AF_INET, source_str, &source_addr);
3641 if (result <= 0) {
3642 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
3643 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3644 return CMD_WARNING;
3645 }
3646
3647 result = pim_ssmpingd_stop(source_addr);
3648 if (result) {
3649 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
3650 source_str, result, VTY_NEWLINE);
3651 return CMD_WARNING;
3652 }
3653
3654 return CMD_SUCCESS;
3655 }
3656
3657 DEFUN (interface_ip_igmp,
3658 interface_ip_igmp_cmd,
3659 "ip igmp",
3660 IP_STR
3661 IFACE_IGMP_STR)
3662 {
3663 VTY_DECLVAR_CONTEXT(interface, ifp);
3664 struct pim_interface *pim_ifp;
3665
3666 pim_ifp = ifp->info;
3667
3668 if (!pim_ifp) {
3669 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
3670 if (!pim_ifp) {
3671 vty_out(vty, "Could not enable IGMP on interface %s%s",
3672 ifp->name, VTY_NEWLINE);
3673 return CMD_WARNING;
3674 }
3675 }
3676 else {
3677 PIM_IF_DO_IGMP(pim_ifp->options);
3678 }
3679
3680 pim_if_addr_add_all(ifp);
3681 pim_if_membership_refresh(ifp);
3682
3683 return CMD_SUCCESS;
3684 }
3685
3686 DEFUN (interface_no_ip_igmp,
3687 interface_no_ip_igmp_cmd,
3688 "no ip igmp",
3689 NO_STR
3690 IP_STR
3691 IFACE_IGMP_STR)
3692 {
3693 VTY_DECLVAR_CONTEXT(interface, ifp);
3694 struct pim_interface *pim_ifp;
3695
3696 pim_ifp = ifp->info;
3697 if (!pim_ifp)
3698 return CMD_SUCCESS;
3699
3700 PIM_IF_DONT_IGMP(pim_ifp->options);
3701
3702 pim_if_membership_clear(ifp);
3703
3704 pim_if_addr_del_all_igmp(ifp);
3705
3706 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
3707 pim_if_delete(ifp);
3708 }
3709
3710 return CMD_SUCCESS;
3711 }
3712
3713 DEFUN (interface_ip_igmp_join,
3714 interface_ip_igmp_join_cmd,
3715 "ip igmp join A.B.C.D A.B.C.D",
3716 IP_STR
3717 IFACE_IGMP_STR
3718 "IGMP join multicast group\n"
3719 "Multicast group address\n"
3720 "Source address\n")
3721 {
3722 VTY_DECLVAR_CONTEXT(interface, ifp);
3723 int idx_ipv4 = 3;
3724 int idx_ipv4_2 = 4;
3725 const char *group_str;
3726 const char *source_str;
3727 struct in_addr group_addr;
3728 struct in_addr source_addr;
3729 int result;
3730
3731 /* Group address */
3732 group_str = argv[idx_ipv4]->arg;
3733 result = inet_pton(AF_INET, group_str, &group_addr);
3734 if (result <= 0) {
3735 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3736 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
3737 return CMD_WARNING;
3738 }
3739
3740 /* Source address */
3741 source_str = argv[idx_ipv4_2]->arg;
3742 result = inet_pton(AF_INET, source_str, &source_addr);
3743 if (result <= 0) {
3744 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3745 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3746 return CMD_WARNING;
3747 }
3748
3749 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
3750 if (result) {
3751 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
3752 group_str, source_str, ifp->name, result, VTY_NEWLINE);
3753 return CMD_WARNING;
3754 }
3755
3756 return CMD_SUCCESS;
3757 }
3758
3759 DEFUN (interface_no_ip_igmp_join,
3760 interface_no_ip_igmp_join_cmd,
3761 "no ip igmp join A.B.C.D A.B.C.D",
3762 NO_STR
3763 IP_STR
3764 IFACE_IGMP_STR
3765 "IGMP join multicast group\n"
3766 "Multicast group address\n"
3767 "Source address\n")
3768 {
3769 VTY_DECLVAR_CONTEXT(interface, ifp);
3770 int idx_ipv4 = 4;
3771 int idx_ipv4_2 = 5;
3772 const char *group_str;
3773 const char *source_str;
3774 struct in_addr group_addr;
3775 struct in_addr source_addr;
3776 int result;
3777
3778 /* Group address */
3779 group_str = argv[idx_ipv4]->arg;
3780 result = inet_pton(AF_INET, group_str, &group_addr);
3781 if (result <= 0) {
3782 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3783 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
3784 return CMD_WARNING;
3785 }
3786
3787 /* Source address */
3788 source_str = argv[idx_ipv4_2]->arg;
3789 result = inet_pton(AF_INET, source_str, &source_addr);
3790 if (result <= 0) {
3791 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3792 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3793 return CMD_WARNING;
3794 }
3795
3796 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
3797 if (result) {
3798 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
3799 group_str, source_str, ifp->name, result, VTY_NEWLINE);
3800 return CMD_WARNING;
3801 }
3802
3803 return CMD_SUCCESS;
3804 }
3805
3806 /*
3807 CLI reconfiguration affects the interface level (struct pim_interface).
3808 This function propagates the reconfiguration to every active socket
3809 for that interface.
3810 */
3811 static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
3812 {
3813 struct interface *ifp;
3814 struct pim_interface *pim_ifp;
3815
3816 zassert(igmp);
3817
3818 /* other querier present? */
3819
3820 if (igmp->t_other_querier_timer)
3821 return;
3822
3823 /* this is the querier */
3824
3825 zassert(igmp->interface);
3826 zassert(igmp->interface->info);
3827
3828 ifp = igmp->interface;
3829 pim_ifp = ifp->info;
3830
3831 if (PIM_DEBUG_IGMP_TRACE) {
3832 char ifaddr_str[INET_ADDRSTRLEN];
3833 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
3834 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
3835 __PRETTY_FUNCTION__,
3836 ifaddr_str,
3837 ifp->name,
3838 pim_ifp->igmp_default_query_interval);
3839 }
3840
3841 /*
3842 igmp_startup_mode_on() will reset QQI:
3843
3844 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
3845 */
3846 igmp_startup_mode_on(igmp);
3847 }
3848
3849 static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
3850 {
3851 if (igmp->t_igmp_query_timer) {
3852 /* other querier present */
3853 zassert(igmp->t_igmp_query_timer);
3854 zassert(!igmp->t_other_querier_timer);
3855
3856 pim_igmp_general_query_off(igmp);
3857 pim_igmp_general_query_on(igmp);
3858
3859 zassert(igmp->t_igmp_query_timer);
3860 zassert(!igmp->t_other_querier_timer);
3861 }
3862 else {
3863 /* this is the querier */
3864
3865 zassert(!igmp->t_igmp_query_timer);
3866 zassert(igmp->t_other_querier_timer);
3867
3868 pim_igmp_other_querier_timer_off(igmp);
3869 pim_igmp_other_querier_timer_on(igmp);
3870
3871 zassert(!igmp->t_igmp_query_timer);
3872 zassert(igmp->t_other_querier_timer);
3873 }
3874 }
3875
3876 static void change_query_interval(struct pim_interface *pim_ifp,
3877 int query_interval)
3878 {
3879 struct listnode *sock_node;
3880 struct igmp_sock *igmp;
3881
3882 pim_ifp->igmp_default_query_interval = query_interval;
3883
3884 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
3885 igmp_sock_query_interval_reconfig(igmp);
3886 igmp_sock_query_reschedule(igmp);
3887 }
3888 }
3889
3890 static void change_query_max_response_time(struct pim_interface *pim_ifp,
3891 int query_max_response_time_dsec)
3892 {
3893 struct listnode *sock_node;
3894 struct igmp_sock *igmp;
3895
3896 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
3897
3898 /*
3899 Below we modify socket/group/source timers in order to quickly
3900 reflect the change. Otherwise, those timers would eventually catch
3901 up.
3902 */
3903
3904 /* scan all sockets */
3905 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
3906 struct listnode *grp_node;
3907 struct igmp_group *grp;
3908
3909 /* reschedule socket general query */
3910 igmp_sock_query_reschedule(igmp);
3911
3912 /* scan socket groups */
3913 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
3914 struct listnode *src_node;
3915 struct igmp_source *src;
3916
3917 /* reset group timers for groups in EXCLUDE mode */
3918 if (grp->group_filtermode_isexcl) {
3919 igmp_group_reset_gmi(grp);
3920 }
3921
3922 /* scan group sources */
3923 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
3924
3925 /* reset source timers for sources with running timers */
3926 if (src->t_source_timer) {
3927 igmp_source_reset_gmi(igmp, grp, src);
3928 }
3929 }
3930 }
3931 }
3932 }
3933
3934 #define IGMP_QUERY_INTERVAL_MIN (1)
3935 #define IGMP_QUERY_INTERVAL_MAX (1800)
3936
3937 DEFUN (interface_ip_igmp_query_interval,
3938 interface_ip_igmp_query_interval_cmd,
3939 "ip igmp query-interval (1-1800)",
3940 IP_STR
3941 IFACE_IGMP_STR
3942 IFACE_IGMP_QUERY_INTERVAL_STR
3943 "Query interval in seconds\n")
3944 {
3945 VTY_DECLVAR_CONTEXT(interface, ifp);
3946 struct pim_interface *pim_ifp;
3947 int query_interval;
3948 int query_interval_dsec;
3949
3950 pim_ifp = ifp->info;
3951
3952 if (!pim_ifp) {
3953 vty_out(vty,
3954 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3955 ifp->name,
3956 VTY_NEWLINE);
3957 return CMD_WARNING;
3958 }
3959
3960 query_interval = atoi(argv[4]->arg);
3961 query_interval_dsec = 10 * query_interval;
3962
3963 /*
3964 It seems we don't need to check bounds since command.c does it
3965 already, but we verify them anyway for extra safety.
3966 */
3967 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
3968 vty_out(vty, "General query interval %d lower than minimum %d%s",
3969 query_interval,
3970 IGMP_QUERY_INTERVAL_MIN,
3971 VTY_NEWLINE);
3972 return CMD_WARNING;
3973 }
3974 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
3975 vty_out(vty, "General query interval %d higher than maximum %d%s",
3976 query_interval,
3977 IGMP_QUERY_INTERVAL_MAX,
3978 VTY_NEWLINE);
3979 return CMD_WARNING;
3980 }
3981
3982 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
3983 vty_out(vty,
3984 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
3985 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
3986 VTY_NEWLINE);
3987 return CMD_WARNING;
3988 }
3989
3990 change_query_interval(pim_ifp, query_interval);
3991
3992 return CMD_SUCCESS;
3993 }
3994
3995 DEFUN (interface_no_ip_igmp_query_interval,
3996 interface_no_ip_igmp_query_interval_cmd,
3997 "no ip igmp query-interval",
3998 NO_STR
3999 IP_STR
4000 IFACE_IGMP_STR
4001 IFACE_IGMP_QUERY_INTERVAL_STR)
4002 {
4003 VTY_DECLVAR_CONTEXT(interface, ifp);
4004 struct pim_interface *pim_ifp;
4005 int default_query_interval_dsec;
4006
4007 pim_ifp = ifp->info;
4008
4009 if (!pim_ifp)
4010 return CMD_SUCCESS;
4011
4012 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
4013
4014 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
4015 vty_out(vty,
4016 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
4017 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
4018 VTY_NEWLINE);
4019 return CMD_WARNING;
4020 }
4021
4022 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
4023
4024 return CMD_SUCCESS;
4025 }
4026
4027 DEFUN (interface_ip_igmp_version,
4028 interface_ip_igmp_version_cmd,
4029 "ip igmp version <2-3>",
4030 IP_STR
4031 IFACE_IGMP_STR
4032 "IGMP version\n"
4033 "IGMP version number\n")
4034 {
4035 VTY_DECLVAR_CONTEXT(interface,ifp);
4036 struct pim_interface *pim_ifp;
4037 int igmp_version;
4038
4039 pim_ifp = ifp->info;
4040
4041 if (!pim_ifp) {
4042 vty_out(vty,
4043 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4044 ifp->name,
4045 VTY_NEWLINE);
4046 return CMD_WARNING;
4047 }
4048
4049 igmp_version = atoi(argv[3]->arg);
4050 pim_ifp->igmp_version = igmp_version;
4051
4052 return CMD_SUCCESS;
4053 }
4054
4055 DEFUN (interface_no_ip_igmp_version,
4056 interface_no_ip_igmp_version_cmd,
4057 "no ip igmp version <2-3>",
4058 NO_STR
4059 IP_STR
4060 IFACE_IGMP_STR
4061 "IGMP version\n"
4062 "IGMP version number\n")
4063 {
4064 VTY_DECLVAR_CONTEXT(interface, ifp);
4065 struct pim_interface *pim_ifp;
4066
4067 pim_ifp = ifp->info;
4068
4069 if (!pim_ifp)
4070 return CMD_SUCCESS;
4071
4072 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
4073
4074 return CMD_SUCCESS;
4075 }
4076
4077 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4078 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4079
4080 DEFUN (interface_ip_igmp_query_max_response_time,
4081 interface_ip_igmp_query_max_response_time_cmd,
4082 "ip igmp query-max-response-time (10-250)",
4083 IP_STR
4084 IFACE_IGMP_STR
4085 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
4086 "Query response value in deci-seconds\n")
4087 {
4088 VTY_DECLVAR_CONTEXT(interface, ifp);
4089 struct pim_interface *pim_ifp;
4090 int query_max_response_time;
4091
4092 pim_ifp = ifp->info;
4093
4094 if (!pim_ifp) {
4095 vty_out(vty,
4096 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4097 ifp->name,
4098 VTY_NEWLINE);
4099 return CMD_WARNING;
4100 }
4101
4102 query_max_response_time = atoi(argv[4]->arg);
4103
4104 if (query_max_response_time >= pim_ifp->igmp_default_query_interval * 10) {
4105 vty_out(vty,
4106 "Can't set query max response time %d sec >= general query interval %d sec%s",
4107 query_max_response_time, pim_ifp->igmp_default_query_interval,
4108 VTY_NEWLINE);
4109 return CMD_WARNING;
4110 }
4111
4112 change_query_max_response_time(pim_ifp, query_max_response_time);
4113
4114 return CMD_SUCCESS;
4115 }
4116
4117 DEFUN (interface_no_ip_igmp_query_max_response_time,
4118 interface_no_ip_igmp_query_max_response_time_cmd,
4119 "no ip igmp query-max-response-time <10-250>",
4120 NO_STR
4121 IP_STR
4122 IFACE_IGMP_STR
4123 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
4124 {
4125 VTY_DECLVAR_CONTEXT(interface, ifp);
4126 struct pim_interface *pim_ifp;
4127
4128 pim_ifp = ifp->info;
4129
4130 if (!pim_ifp)
4131 return CMD_SUCCESS;
4132
4133 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
4134
4135 return CMD_SUCCESS;
4136 }
4137
4138 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4139 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4140
4141 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
4142 interface_ip_igmp_query_max_response_time_dsec_cmd,
4143 "ip igmp query-max-response-time-dsec (10-250)",
4144 IP_STR
4145 IFACE_IGMP_STR
4146 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4147 "Query response value in deciseconds\n")
4148 {
4149 VTY_DECLVAR_CONTEXT(interface, ifp);
4150 struct pim_interface *pim_ifp;
4151 int query_max_response_time_dsec;
4152 int default_query_interval_dsec;
4153
4154 pim_ifp = ifp->info;
4155
4156 if (!pim_ifp) {
4157 vty_out(vty,
4158 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4159 ifp->name,
4160 VTY_NEWLINE);
4161 return CMD_WARNING;
4162 }
4163
4164 query_max_response_time_dsec = atoi(argv[4]->arg);
4165
4166 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
4167
4168 if (query_max_response_time_dsec >= default_query_interval_dsec) {
4169 vty_out(vty,
4170 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4171 query_max_response_time_dsec, default_query_interval_dsec,
4172 VTY_NEWLINE);
4173 return CMD_WARNING;
4174 }
4175
4176 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
4177
4178 return CMD_SUCCESS;
4179 }
4180
4181 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
4182 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
4183 "no ip igmp query-max-response-time-dsec",
4184 NO_STR
4185 IP_STR
4186 IFACE_IGMP_STR
4187 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
4188 {
4189 VTY_DECLVAR_CONTEXT(interface, ifp);
4190 struct pim_interface *pim_ifp;
4191
4192 pim_ifp = ifp->info;
4193
4194 if (!pim_ifp)
4195 return CMD_SUCCESS;
4196
4197 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
4198
4199 return CMD_SUCCESS;
4200 }
4201
4202 DEFUN (interface_ip_pim_drprio,
4203 interface_ip_pim_drprio_cmd,
4204 "ip pim drpriority (1-4294967295)",
4205 IP_STR
4206 PIM_STR
4207 "Set the Designated Router Election Priority\n"
4208 "Value of the new DR Priority\n")
4209 {
4210 VTY_DECLVAR_CONTEXT(interface, ifp);
4211 int idx_number = 3;
4212 struct pim_interface *pim_ifp;
4213 uint32_t old_dr_prio;
4214
4215 pim_ifp = ifp->info;
4216
4217 if (!pim_ifp) {
4218 vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
4219 return CMD_WARNING;
4220 }
4221
4222 old_dr_prio = pim_ifp->pim_dr_priority;
4223
4224 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
4225
4226 if (old_dr_prio != pim_ifp->pim_dr_priority) {
4227 if (pim_if_dr_election(ifp))
4228 pim_hello_restart_now(ifp);
4229 }
4230
4231 return CMD_SUCCESS;
4232 }
4233
4234 DEFUN (interface_no_ip_pim_drprio,
4235 interface_no_ip_pim_drprio_cmd,
4236 "no ip pim drpriority [(1-4294967295)]",
4237 NO_STR
4238 IP_STR
4239 PIM_STR
4240 "Revert the Designated Router Priority to default\n"
4241 "Old Value of the Priority\n")
4242 {
4243 VTY_DECLVAR_CONTEXT(interface, ifp);
4244 struct pim_interface *pim_ifp;
4245
4246 pim_ifp = ifp->info;
4247
4248 if (!pim_ifp) {
4249 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
4250 return CMD_WARNING;
4251 }
4252
4253 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
4254 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
4255 if (pim_if_dr_election(ifp))
4256 pim_hello_restart_now(ifp);
4257 }
4258
4259 return CMD_SUCCESS;
4260 }
4261
4262 static int
4263 pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
4264 {
4265 struct pim_interface *pim_ifp = ifp->info;
4266
4267 if (!pim_ifp) {
4268 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
4269 if (!pim_ifp) {
4270 return 0;
4271 }
4272 }
4273 else {
4274 PIM_IF_DO_PIM(pim_ifp->options);
4275 }
4276
4277 pim_ifp->itype = itype;
4278 pim_if_addr_add_all(ifp);
4279 pim_if_membership_refresh(ifp);
4280 return 1;
4281 }
4282
4283
4284 DEFUN (interface_ip_pim_ssm,
4285 interface_ip_pim_ssm_cmd,
4286 "ip pim ssm",
4287 IP_STR
4288 PIM_STR
4289 IFACE_PIM_STR)
4290 {
4291 VTY_DECLVAR_CONTEXT(interface, ifp);
4292
4293 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) {
4294 vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE);
4295 return CMD_WARNING;
4296 }
4297
4298 return CMD_SUCCESS;
4299 }
4300
4301 DEFUN (interface_ip_pim_sm,
4302 interface_ip_pim_sm_cmd,
4303 "ip pim sm",
4304 IP_STR
4305 PIM_STR
4306 IFACE_PIM_SM_STR)
4307 {
4308 VTY_DECLVAR_CONTEXT(interface, ifp);
4309 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) {
4310 vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
4311 return CMD_WARNING;
4312 }
4313
4314 pim_if_create_pimreg();
4315
4316 return CMD_SUCCESS;
4317 }
4318
4319 static int
4320 pim_cmd_interface_delete (struct interface *ifp)
4321 {
4322 struct pim_interface *pim_ifp = ifp->info;
4323
4324 if (!pim_ifp)
4325 return 1;
4326
4327 PIM_IF_DONT_PIM(pim_ifp->options);
4328
4329 pim_if_membership_clear(ifp);
4330
4331 /*
4332 pim_sock_delete() removes all neighbors from
4333 pim_ifp->pim_neighbor_list.
4334 */
4335 pim_sock_delete(ifp, "pim unconfigured on interface");
4336
4337 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
4338 pim_if_addr_del_all(ifp);
4339 pim_if_delete(ifp);
4340 }
4341
4342 return 1;
4343 }
4344
4345 DEFUN (interface_no_ip_pim_ssm,
4346 interface_no_ip_pim_ssm_cmd,
4347 "no ip pim ssm",
4348 NO_STR
4349 IP_STR
4350 PIM_STR
4351 IFACE_PIM_STR)
4352 {
4353 VTY_DECLVAR_CONTEXT(interface, ifp);
4354 if (!pim_cmd_interface_delete(ifp)) {
4355 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
4356 return CMD_WARNING;
4357 }
4358
4359 return CMD_SUCCESS;
4360 }
4361
4362 DEFUN (interface_no_ip_pim_sm,
4363 interface_no_ip_pim_sm_cmd,
4364 "no ip pim sm",
4365 NO_STR
4366 IP_STR
4367 PIM_STR
4368 IFACE_PIM_SM_STR)
4369 {
4370 VTY_DECLVAR_CONTEXT(interface, ifp);
4371 if (!pim_cmd_interface_delete(ifp)) {
4372 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
4373 return CMD_WARNING;
4374 }
4375
4376 return CMD_SUCCESS;
4377 }
4378
4379 DEFUN (interface_ip_mroute,
4380 interface_ip_mroute_cmd,
4381 "ip mroute INTERFACE A.B.C.D",
4382 IP_STR
4383 "Add multicast route\n"
4384 "Outgoing interface name\n"
4385 "Group address\n")
4386 {
4387 VTY_DECLVAR_CONTEXT(interface, iif);
4388 int idx_interface = 2;
4389 int idx_ipv4 = 3;
4390 struct interface *oif;
4391 const char *oifname;
4392 const char *grp_str;
4393 struct in_addr grp_addr;
4394 struct in_addr src_addr;
4395 int result;
4396
4397 oifname = argv[idx_interface]->arg;
4398 oif = if_lookup_by_name(oifname);
4399 if (!oif) {
4400 vty_out(vty, "No such interface name %s%s",
4401 oifname, VTY_NEWLINE);
4402 return CMD_WARNING;
4403 }
4404
4405 grp_str = argv[idx_ipv4]->arg;
4406 result = inet_pton(AF_INET, grp_str, &grp_addr);
4407 if (result <= 0) {
4408 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4409 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4410 return CMD_WARNING;
4411 }
4412
4413 src_addr.s_addr = INADDR_ANY;
4414
4415 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
4416 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
4417 return CMD_WARNING;
4418 }
4419
4420 return CMD_SUCCESS;
4421 }
4422
4423 DEFUN (interface_ip_mroute_source,
4424 interface_ip_mroute_source_cmd,
4425 "ip mroute INTERFACE A.B.C.D A.B.C.D",
4426 IP_STR
4427 "Add multicast route\n"
4428 "Outgoing interface name\n"
4429 "Group address\n"
4430 "Source address\n")
4431 {
4432 VTY_DECLVAR_CONTEXT(interface, iif);
4433 int idx_interface = 2;
4434 int idx_ipv4 = 3;
4435 int idx_ipv4_2 = 4;
4436 struct interface *oif;
4437 const char *oifname;
4438 const char *grp_str;
4439 struct in_addr grp_addr;
4440 const char *src_str;
4441 struct in_addr src_addr;
4442 int result;
4443
4444 oifname = argv[idx_interface]->arg;
4445 oif = if_lookup_by_name(oifname);
4446 if (!oif) {
4447 vty_out(vty, "No such interface name %s%s",
4448 oifname, VTY_NEWLINE);
4449 return CMD_WARNING;
4450 }
4451
4452 grp_str = argv[idx_ipv4]->arg;
4453 result = inet_pton(AF_INET, grp_str, &grp_addr);
4454 if (result <= 0) {
4455 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4456 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4457 return CMD_WARNING;
4458 }
4459
4460 src_str = argv[idx_ipv4_2]->arg;
4461 result = inet_pton(AF_INET, src_str, &src_addr);
4462 if (result <= 0) {
4463 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4464 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4465 return CMD_WARNING;
4466 }
4467
4468 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
4469 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
4470 return CMD_WARNING;
4471 }
4472
4473 return CMD_SUCCESS;
4474 }
4475
4476 DEFUN (interface_no_ip_mroute,
4477 interface_no_ip_mroute_cmd,
4478 "no ip mroute INTERFACE A.B.C.D",
4479 NO_STR
4480 IP_STR
4481 "Add multicast route\n"
4482 "Outgoing interface name\n"
4483 "Group Address\n")
4484 {
4485 VTY_DECLVAR_CONTEXT(interface, iif);
4486 int idx_interface = 3;
4487 int idx_ipv4 = 4;
4488 struct interface *oif;
4489 const char *oifname;
4490 const char *grp_str;
4491 struct in_addr grp_addr;
4492 struct in_addr src_addr;
4493 int result;
4494
4495 oifname = argv[idx_interface]->arg;
4496 oif = if_lookup_by_name(oifname);
4497 if (!oif) {
4498 vty_out(vty, "No such interface name %s%s",
4499 oifname, VTY_NEWLINE);
4500 return CMD_WARNING;
4501 }
4502
4503 grp_str = argv[idx_ipv4]->arg;
4504 result = inet_pton(AF_INET, grp_str, &grp_addr);
4505 if (result <= 0) {
4506 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4507 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4508 return CMD_WARNING;
4509 }
4510
4511 src_addr.s_addr = INADDR_ANY;
4512
4513 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
4514 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
4515 return CMD_WARNING;
4516 }
4517
4518 return CMD_SUCCESS;
4519 }
4520
4521 DEFUN (interface_no_ip_mroute_source,
4522 interface_no_ip_mroute_source_cmd,
4523 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
4524 NO_STR
4525 IP_STR
4526 "Add multicast route\n"
4527 "Outgoing interface name\n"
4528 "Group Address\n"
4529 "Source Address\n")
4530 {
4531 VTY_DECLVAR_CONTEXT(interface, iif);
4532 int idx_interface = 3;
4533 int idx_ipv4 = 4;
4534 int idx_ipv4_2 = 5;
4535 struct interface *oif;
4536 const char *oifname;
4537 const char *grp_str;
4538 struct in_addr grp_addr;
4539 const char *src_str;
4540 struct in_addr src_addr;
4541 int result;
4542
4543 oifname = argv[idx_interface]->arg;
4544 oif = if_lookup_by_name(oifname);
4545 if (!oif) {
4546 vty_out(vty, "No such interface name %s%s",
4547 oifname, VTY_NEWLINE);
4548 return CMD_WARNING;
4549 }
4550
4551 grp_str = argv[idx_ipv4]->arg;
4552 result = inet_pton(AF_INET, grp_str, &grp_addr);
4553 if (result <= 0) {
4554 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4555 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4556 return CMD_WARNING;
4557 }
4558
4559 src_str = argv[idx_ipv4_2]->arg;
4560 result = inet_pton(AF_INET, src_str, &src_addr);
4561 if (result <= 0) {
4562 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4563 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4564 return CMD_WARNING;
4565 }
4566
4567 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
4568 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
4569 return CMD_WARNING;
4570 }
4571
4572 return CMD_SUCCESS;
4573 }
4574
4575 DEFUN (interface_ip_pim_hello,
4576 interface_ip_pim_hello_cmd,
4577 "ip pim hello (1-180) [(1-180)]",
4578 IP_STR
4579 PIM_STR
4580 IFACE_PIM_HELLO_STR
4581 IFACE_PIM_HELLO_TIME_STR
4582 IFACE_PIM_HELLO_HOLD_STR)
4583 {
4584 VTY_DECLVAR_CONTEXT(interface, ifp);
4585 int idx_time = 3;
4586 int idx_hold = 4;
4587 struct pim_interface *pim_ifp;
4588
4589 pim_ifp = ifp->info;
4590
4591 if (!pim_ifp) {
4592 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
4593 return CMD_WARNING;
4594 }
4595
4596 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
4597
4598 if (argc > idx_hold)
4599 pim_ifp->pim_default_holdtime = strtol(argv[idx_hold]->arg, NULL, 10);
4600
4601 return CMD_SUCCESS;
4602 }
4603
4604
4605
4606 DEFUN (interface_no_ip_pim_hello,
4607 interface_no_ip_pim_hello_cmd,
4608 "no ip pim hello [(1-180) (1-180)]",
4609 NO_STR
4610 IP_STR
4611 PIM_STR
4612 IFACE_PIM_HELLO_STR
4613 IFACE_PIM_HELLO_TIME_STR
4614 IFACE_PIM_HELLO_HOLD_STR)
4615 {
4616 VTY_DECLVAR_CONTEXT(interface, ifp);
4617 struct pim_interface *pim_ifp;
4618
4619 pim_ifp = ifp->info;
4620
4621 if (!pim_ifp) {
4622 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
4623 return CMD_WARNING;
4624 }
4625
4626 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
4627 pim_ifp->pim_default_holdtime = -1;
4628
4629 return CMD_SUCCESS;
4630 }
4631
4632 DEFUN (debug_igmp,
4633 debug_igmp_cmd,
4634 "debug igmp",
4635 DEBUG_STR
4636 DEBUG_IGMP_STR)
4637 {
4638 PIM_DO_DEBUG_IGMP_EVENTS;
4639 PIM_DO_DEBUG_IGMP_PACKETS;
4640 PIM_DO_DEBUG_IGMP_TRACE;
4641 return CMD_SUCCESS;
4642 }
4643
4644 DEFUN (no_debug_igmp,
4645 no_debug_igmp_cmd,
4646 "no debug igmp",
4647 NO_STR
4648 DEBUG_STR
4649 DEBUG_IGMP_STR)
4650 {
4651 PIM_DONT_DEBUG_IGMP_EVENTS;
4652 PIM_DONT_DEBUG_IGMP_PACKETS;
4653 PIM_DONT_DEBUG_IGMP_TRACE;
4654 return CMD_SUCCESS;
4655 }
4656
4657
4658 DEFUN (debug_igmp_events,
4659 debug_igmp_events_cmd,
4660 "debug igmp events",
4661 DEBUG_STR
4662 DEBUG_IGMP_STR
4663 DEBUG_IGMP_EVENTS_STR)
4664 {
4665 PIM_DO_DEBUG_IGMP_EVENTS;
4666 return CMD_SUCCESS;
4667 }
4668
4669 DEFUN (no_debug_igmp_events,
4670 no_debug_igmp_events_cmd,
4671 "no debug igmp events",
4672 NO_STR
4673 DEBUG_STR
4674 DEBUG_IGMP_STR
4675 DEBUG_IGMP_EVENTS_STR)
4676 {
4677 PIM_DONT_DEBUG_IGMP_EVENTS;
4678 return CMD_SUCCESS;
4679 }
4680
4681
4682 DEFUN (debug_igmp_packets,
4683 debug_igmp_packets_cmd,
4684 "debug igmp packets",
4685 DEBUG_STR
4686 DEBUG_IGMP_STR
4687 DEBUG_IGMP_PACKETS_STR)
4688 {
4689 PIM_DO_DEBUG_IGMP_PACKETS;
4690 return CMD_SUCCESS;
4691 }
4692
4693 DEFUN (no_debug_igmp_packets,
4694 no_debug_igmp_packets_cmd,
4695 "no debug igmp packets",
4696 NO_STR
4697 DEBUG_STR
4698 DEBUG_IGMP_STR
4699 DEBUG_IGMP_PACKETS_STR)
4700 {
4701 PIM_DONT_DEBUG_IGMP_PACKETS;
4702 return CMD_SUCCESS;
4703 }
4704
4705
4706 DEFUN (debug_igmp_trace,
4707 debug_igmp_trace_cmd,
4708 "debug igmp trace",
4709 DEBUG_STR
4710 DEBUG_IGMP_STR
4711 DEBUG_IGMP_TRACE_STR)
4712 {
4713 PIM_DO_DEBUG_IGMP_TRACE;
4714 return CMD_SUCCESS;
4715 }
4716
4717 DEFUN (no_debug_igmp_trace,
4718 no_debug_igmp_trace_cmd,
4719 "no debug igmp trace",
4720 NO_STR
4721 DEBUG_STR
4722 DEBUG_IGMP_STR
4723 DEBUG_IGMP_TRACE_STR)
4724 {
4725 PIM_DONT_DEBUG_IGMP_TRACE;
4726 return CMD_SUCCESS;
4727 }
4728
4729
4730 DEFUN (debug_mroute,
4731 debug_mroute_cmd,
4732 "debug mroute",
4733 DEBUG_STR
4734 DEBUG_MROUTE_STR)
4735 {
4736 PIM_DO_DEBUG_MROUTE;
4737 return CMD_SUCCESS;
4738 }
4739
4740 DEFUN (debug_mroute_detail,
4741 debug_mroute_detail_cmd,
4742 "debug mroute detail",
4743 DEBUG_STR
4744 DEBUG_MROUTE_STR
4745 "detailed\n")
4746 {
4747 PIM_DO_DEBUG_MROUTE_DETAIL;
4748 return CMD_SUCCESS;
4749 }
4750
4751 DEFUN (no_debug_mroute,
4752 no_debug_mroute_cmd,
4753 "no debug mroute",
4754 NO_STR
4755 DEBUG_STR
4756 DEBUG_MROUTE_STR)
4757 {
4758 PIM_DONT_DEBUG_MROUTE;
4759 return CMD_SUCCESS;
4760 }
4761
4762 DEFUN (no_debug_mroute_detail,
4763 no_debug_mroute_detail_cmd,
4764 "no debug mroute detail",
4765 NO_STR
4766 DEBUG_STR
4767 DEBUG_MROUTE_STR
4768 "detailed\n")
4769 {
4770 PIM_DONT_DEBUG_MROUTE_DETAIL;
4771 return CMD_SUCCESS;
4772 }
4773
4774 DEFUN (debug_static,
4775 debug_static_cmd,
4776 "debug static",
4777 DEBUG_STR
4778 DEBUG_STATIC_STR)
4779 {
4780 PIM_DO_DEBUG_STATIC;
4781 return CMD_SUCCESS;
4782 }
4783
4784 DEFUN (no_debug_static,
4785 no_debug_static_cmd,
4786 "no debug static",
4787 NO_STR
4788 DEBUG_STR
4789 DEBUG_STATIC_STR)
4790 {
4791 PIM_DONT_DEBUG_STATIC;
4792 return CMD_SUCCESS;
4793 }
4794
4795
4796 DEFUN (debug_pim,
4797 debug_pim_cmd,
4798 "debug pim",
4799 DEBUG_STR
4800 DEBUG_PIM_STR)
4801 {
4802 PIM_DO_DEBUG_PIM_EVENTS;
4803 PIM_DO_DEBUG_PIM_PACKETS;
4804 PIM_DO_DEBUG_PIM_TRACE;
4805 PIM_DO_DEBUG_MSDP_EVENTS;
4806 PIM_DO_DEBUG_MSDP_PACKETS;
4807 return CMD_SUCCESS;
4808 }
4809
4810 DEFUN (no_debug_pim,
4811 no_debug_pim_cmd,
4812 "no debug pim",
4813 NO_STR
4814 DEBUG_STR
4815 DEBUG_PIM_STR)
4816 {
4817 PIM_DONT_DEBUG_PIM_EVENTS;
4818 PIM_DONT_DEBUG_PIM_PACKETS;
4819 PIM_DONT_DEBUG_PIM_TRACE;
4820 PIM_DONT_DEBUG_MSDP_EVENTS;
4821 PIM_DONT_DEBUG_MSDP_PACKETS;
4822
4823 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
4824 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4825
4826 return CMD_SUCCESS;
4827 }
4828
4829
4830 DEFUN (debug_pim_events,
4831 debug_pim_events_cmd,
4832 "debug pim events",
4833 DEBUG_STR
4834 DEBUG_PIM_STR
4835 DEBUG_PIM_EVENTS_STR)
4836 {
4837 PIM_DO_DEBUG_PIM_EVENTS;
4838 return CMD_SUCCESS;
4839 }
4840
4841 DEFUN (no_debug_pim_events,
4842 no_debug_pim_events_cmd,
4843 "no debug pim events",
4844 NO_STR
4845 DEBUG_STR
4846 DEBUG_PIM_STR
4847 DEBUG_PIM_EVENTS_STR)
4848 {
4849 PIM_DONT_DEBUG_PIM_EVENTS;
4850 return CMD_SUCCESS;
4851 }
4852
4853
4854 DEFUN (debug_pim_packets,
4855 debug_pim_packets_cmd,
4856 "debug pim packets",
4857 DEBUG_STR
4858 DEBUG_PIM_STR
4859 DEBUG_PIM_PACKETS_STR)
4860 {
4861 PIM_DO_DEBUG_PIM_PACKETS;
4862 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
4863 return CMD_SUCCESS;
4864 }
4865
4866 DEFUN (debug_pim_packets_filter,
4867 debug_pim_packets_filter_cmd,
4868 "debug pim packets <hello|joins|register>",
4869 DEBUG_STR
4870 DEBUG_PIM_STR
4871 DEBUG_PIM_PACKETS_STR
4872 DEBUG_PIM_HELLO_PACKETS_STR
4873 DEBUG_PIM_J_P_PACKETS_STR
4874 DEBUG_PIM_PIM_REG_PACKETS_STR)
4875 {
4876 int idx_hello_join = 3;
4877 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
4878 {
4879 PIM_DO_DEBUG_PIM_HELLO;
4880 vty_out (vty, "PIM Hello debugging is on%s", VTY_NEWLINE);
4881 }
4882 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
4883 {
4884 PIM_DO_DEBUG_PIM_J_P;
4885 vty_out (vty, "PIM Join/Prune debugging is on%s", VTY_NEWLINE);
4886 }
4887 else if (strncmp(argv[idx_hello_join]->arg,"r",1) == 0)
4888 {
4889 PIM_DO_DEBUG_PIM_REG;
4890 vty_out (vty, "PIM Register debugging is on%s", VTY_NEWLINE);
4891 }
4892 return CMD_SUCCESS;
4893 }
4894
4895 DEFUN (no_debug_pim_packets,
4896 no_debug_pim_packets_cmd,
4897 "no debug pim packets",
4898 NO_STR
4899 DEBUG_STR
4900 DEBUG_PIM_STR
4901 DEBUG_PIM_PACKETS_STR
4902 DEBUG_PIM_HELLO_PACKETS_STR
4903 DEBUG_PIM_J_P_PACKETS_STR)
4904 {
4905 PIM_DONT_DEBUG_PIM_PACKETS;
4906 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
4907 return CMD_SUCCESS;
4908 }
4909
4910 DEFUN (no_debug_pim_packets_filter,
4911 no_debug_pim_packets_filter_cmd,
4912 "no debug pim packets <hello|joins|register>",
4913 NO_STR
4914 DEBUG_STR
4915 DEBUG_PIM_STR
4916 DEBUG_PIM_PACKETS_STR
4917 DEBUG_PIM_HELLO_PACKETS_STR
4918 DEBUG_PIM_J_P_PACKETS_STR)
4919 {
4920 int idx_hello_join = 4;
4921 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
4922 {
4923 PIM_DONT_DEBUG_PIM_HELLO;
4924 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
4925 }
4926 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
4927 {
4928 PIM_DONT_DEBUG_PIM_J_P;
4929 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
4930 }
4931 else if (strncmp (argv[idx_hello_join]->arg, "r", 1) == 0)
4932 {
4933 PIM_DONT_DEBUG_PIM_REG;
4934 vty_out (vty, "PIM Register debugging is off%s", VTY_NEWLINE);
4935 }
4936 return CMD_SUCCESS;
4937 }
4938
4939
4940 DEFUN (debug_pim_packetdump_send,
4941 debug_pim_packetdump_send_cmd,
4942 "debug pim packet-dump send",
4943 DEBUG_STR
4944 DEBUG_PIM_STR
4945 DEBUG_PIM_PACKETDUMP_STR
4946 DEBUG_PIM_PACKETDUMP_SEND_STR)
4947 {
4948 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
4949 return CMD_SUCCESS;
4950 }
4951
4952 DEFUN (no_debug_pim_packetdump_send,
4953 no_debug_pim_packetdump_send_cmd,
4954 "no debug pim packet-dump send",
4955 NO_STR
4956 DEBUG_STR
4957 DEBUG_PIM_STR
4958 DEBUG_PIM_PACKETDUMP_STR
4959 DEBUG_PIM_PACKETDUMP_SEND_STR)
4960 {
4961 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
4962 return CMD_SUCCESS;
4963 }
4964
4965
4966 DEFUN (debug_pim_packetdump_recv,
4967 debug_pim_packetdump_recv_cmd,
4968 "debug pim packet-dump receive",
4969 DEBUG_STR
4970 DEBUG_PIM_STR
4971 DEBUG_PIM_PACKETDUMP_STR
4972 DEBUG_PIM_PACKETDUMP_RECV_STR)
4973 {
4974 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
4975 return CMD_SUCCESS;
4976 }
4977
4978 DEFUN (no_debug_pim_packetdump_recv,
4979 no_debug_pim_packetdump_recv_cmd,
4980 "no debug pim packet-dump receive",
4981 NO_STR
4982 DEBUG_STR
4983 DEBUG_PIM_STR
4984 DEBUG_PIM_PACKETDUMP_STR
4985 DEBUG_PIM_PACKETDUMP_RECV_STR)
4986 {
4987 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4988 return CMD_SUCCESS;
4989 }
4990
4991
4992 DEFUN (debug_pim_trace,
4993 debug_pim_trace_cmd,
4994 "debug pim trace",
4995 DEBUG_STR
4996 DEBUG_PIM_STR
4997 DEBUG_PIM_TRACE_STR)
4998 {
4999 PIM_DO_DEBUG_PIM_TRACE;
5000 return CMD_SUCCESS;
5001 }
5002
5003 DEFUN (no_debug_pim_trace,
5004 no_debug_pim_trace_cmd,
5005 "no debug pim trace",
5006 NO_STR
5007 DEBUG_STR
5008 DEBUG_PIM_STR
5009 DEBUG_PIM_TRACE_STR)
5010 {
5011 PIM_DONT_DEBUG_PIM_TRACE;
5012 return CMD_SUCCESS;
5013 }
5014
5015
5016 DEFUN (debug_ssmpingd,
5017 debug_ssmpingd_cmd,
5018 "debug ssmpingd",
5019 DEBUG_STR
5020 DEBUG_PIM_STR
5021 DEBUG_SSMPINGD_STR)
5022 {
5023 PIM_DO_DEBUG_SSMPINGD;
5024 return CMD_SUCCESS;
5025 }
5026
5027 DEFUN (no_debug_ssmpingd,
5028 no_debug_ssmpingd_cmd,
5029 "no debug ssmpingd",
5030 NO_STR
5031 DEBUG_STR
5032 DEBUG_PIM_STR
5033 DEBUG_SSMPINGD_STR)
5034 {
5035 PIM_DONT_DEBUG_SSMPINGD;
5036 return CMD_SUCCESS;
5037 }
5038
5039
5040 DEFUN (debug_pim_zebra,
5041 debug_pim_zebra_cmd,
5042 "debug pim zebra",
5043 DEBUG_STR
5044 DEBUG_PIM_STR
5045 DEBUG_PIM_ZEBRA_STR)
5046 {
5047 PIM_DO_DEBUG_ZEBRA;
5048 return CMD_SUCCESS;
5049 }
5050
5051 DEFUN (no_debug_pim_zebra,
5052 no_debug_pim_zebra_cmd,
5053 "no debug pim zebra",
5054 NO_STR
5055 DEBUG_STR
5056 DEBUG_PIM_STR
5057 DEBUG_PIM_ZEBRA_STR)
5058 {
5059 PIM_DONT_DEBUG_ZEBRA;
5060 return CMD_SUCCESS;
5061 }
5062
5063
5064 DEFUN (debug_msdp,
5065 debug_msdp_cmd,
5066 "debug msdp",
5067 DEBUG_STR
5068 DEBUG_MSDP_STR)
5069 {
5070 PIM_DO_DEBUG_MSDP_EVENTS;
5071 PIM_DO_DEBUG_MSDP_PACKETS;
5072 return CMD_SUCCESS;
5073 }
5074
5075 DEFUN (no_debug_msdp,
5076 no_debug_msdp_cmd,
5077 "no debug msdp",
5078 NO_STR
5079 DEBUG_STR
5080 DEBUG_MSDP_STR)
5081 {
5082 PIM_DONT_DEBUG_MSDP_EVENTS;
5083 PIM_DONT_DEBUG_MSDP_PACKETS;
5084 return CMD_SUCCESS;
5085 }
5086
5087 ALIAS (no_debug_msdp,
5088 undebug_msdp_cmd,
5089 "undebug msdp",
5090 UNDEBUG_STR
5091 DEBUG_MSDP_STR)
5092
5093 DEFUN (debug_msdp_events,
5094 debug_msdp_events_cmd,
5095 "debug msdp events",
5096 DEBUG_STR
5097 DEBUG_MSDP_STR
5098 DEBUG_MSDP_EVENTS_STR)
5099 {
5100 PIM_DO_DEBUG_MSDP_EVENTS;
5101 return CMD_SUCCESS;
5102 }
5103
5104 DEFUN (no_debug_msdp_events,
5105 no_debug_msdp_events_cmd,
5106 "no debug msdp events",
5107 NO_STR
5108 DEBUG_STR
5109 DEBUG_MSDP_STR
5110 DEBUG_MSDP_EVENTS_STR)
5111 {
5112 PIM_DONT_DEBUG_MSDP_EVENTS;
5113 return CMD_SUCCESS;
5114 }
5115
5116 ALIAS (no_debug_msdp_events,
5117 undebug_msdp_events_cmd,
5118 "undebug msdp events",
5119 UNDEBUG_STR
5120 DEBUG_MSDP_STR
5121 DEBUG_MSDP_EVENTS_STR)
5122
5123 DEFUN (debug_msdp_packets,
5124 debug_msdp_packets_cmd,
5125 "debug msdp packets",
5126 DEBUG_STR
5127 DEBUG_MSDP_STR
5128 DEBUG_MSDP_PACKETS_STR)
5129 {
5130 PIM_DO_DEBUG_MSDP_PACKETS;
5131 return CMD_SUCCESS;
5132 }
5133
5134 DEFUN (no_debug_msdp_packets,
5135 no_debug_msdp_packets_cmd,
5136 "no debug msdp packets",
5137 NO_STR
5138 DEBUG_STR
5139 DEBUG_MSDP_STR
5140 DEBUG_MSDP_PACKETS_STR)
5141 {
5142 PIM_DONT_DEBUG_MSDP_PACKETS;
5143 return CMD_SUCCESS;
5144 }
5145
5146 ALIAS (no_debug_msdp_packets,
5147 undebug_msdp_packets_cmd,
5148 "undebug msdp packets",
5149 UNDEBUG_STR
5150 DEBUG_MSDP_STR
5151 DEBUG_MSDP_PACKETS_STR)
5152
5153 DEFUN (show_debugging_pim,
5154 show_debugging_pim_cmd,
5155 "show debugging pim",
5156 SHOW_STR
5157 DEBUG_STR
5158 PIM_STR)
5159 {
5160 pim_debug_config_write(vty);
5161 return CMD_SUCCESS;
5162 }
5163
5164 static int
5165 interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
5166 {
5167 int result;
5168 struct in_addr source_addr;
5169 VTY_DECLVAR_CONTEXT(interface, ifp);
5170
5171 result = inet_pton(AF_INET, source, &source_addr);
5172 if (result <= 0) {
5173 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
5174 source, errno, safe_strerror(errno), VTY_NEWLINE);
5175 return CMD_WARNING;
5176 }
5177
5178 result = pim_update_source_set(ifp, source_addr);
5179 switch (result) {
5180 case PIM_SUCCESS:
5181 break;
5182 case PIM_IFACE_NOT_FOUND:
5183 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
5184 break;
5185 case PIM_UPDATE_SOURCE_DUP:
5186 vty_out(vty, "%% Source already set to %s%s", source, VTY_NEWLINE);
5187 break;
5188 default:
5189 vty_out(vty, "%% Source set failed%s", VTY_NEWLINE);
5190 }
5191
5192 return result?CMD_WARNING:CMD_SUCCESS;
5193 }
5194
5195 DEFUN (interface_pim_use_source,
5196 interface_pim_use_source_cmd,
5197 "ip pim use-source A.B.C.D",
5198 IP_STR
5199 "pim multicast routing\n"
5200 "Configure primary IP address\n"
5201 "source ip address\n")
5202 {
5203 return interface_pim_use_src_cmd_worker (vty, argv[3]->arg);
5204 }
5205
5206 DEFUN (interface_no_pim_use_source,
5207 interface_no_pim_use_source_cmd,
5208 "no ip pim use-source",
5209 NO_STR
5210 IP_STR
5211 "pim multicast routing\n"
5212 "Delete source IP address\n")
5213 {
5214 return interface_pim_use_src_cmd_worker (vty, "0.0.0.0");
5215 }
5216
5217 static int
5218 ip_msdp_peer_cmd_worker (struct vty *vty, const char *peer, const char *local)
5219 {
5220 enum pim_msdp_err result;
5221 struct in_addr peer_addr;
5222 struct in_addr local_addr;
5223
5224 result = inet_pton(AF_INET, peer, &peer_addr);
5225 if (result <= 0) {
5226 vty_out(vty, "%% Bad peer address %s: errno=%d: %s%s",
5227 peer, errno, safe_strerror(errno), VTY_NEWLINE);
5228 return CMD_WARNING;
5229 }
5230
5231 result = inet_pton(AF_INET, local, &local_addr);
5232 if (result <= 0) {
5233 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
5234 local, errno, safe_strerror(errno), VTY_NEWLINE);
5235 return CMD_WARNING;
5236 }
5237
5238 result = pim_msdp_peer_add(peer_addr, local_addr, "default", NULL/* mp_p */);
5239 switch (result) {
5240 case PIM_MSDP_ERR_NONE:
5241 break;
5242 case PIM_MSDP_ERR_OOM:
5243 vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
5244 break;
5245 case PIM_MSDP_ERR_PEER_EXISTS:
5246 vty_out(vty, "%% Peer exists%s", VTY_NEWLINE);
5247 break;
5248 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
5249 vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
5250 break;
5251 default:
5252 vty_out(vty, "%% peer add failed%s", VTY_NEWLINE);
5253 }
5254
5255 return result?CMD_WARNING:CMD_SUCCESS;
5256 }
5257
5258 DEFUN_HIDDEN (ip_msdp_peer,
5259 ip_msdp_peer_cmd,
5260 "ip msdp peer A.B.C.D source A.B.C.D",
5261 IP_STR
5262 CFG_MSDP_STR
5263 "Configure MSDP peer\n"
5264 "peer ip address\n"
5265 "Source address for TCP connection\n"
5266 "local ip address\n")
5267 {
5268 return ip_msdp_peer_cmd_worker (vty, argv[3]->arg, argv[5]->arg);
5269 }
5270
5271 static int
5272 ip_no_msdp_peer_cmd_worker (struct vty *vty, const char *peer)
5273 {
5274 enum pim_msdp_err result;
5275 struct in_addr peer_addr;
5276
5277 result = inet_pton(AF_INET, peer, &peer_addr);
5278 if (result <= 0) {
5279 vty_out(vty, "%% Bad peer address %s: errno=%d: %s%s",
5280 peer, errno, safe_strerror(errno), VTY_NEWLINE);
5281 return CMD_WARNING;
5282 }
5283
5284 result = pim_msdp_peer_del(peer_addr);
5285 switch (result) {
5286 case PIM_MSDP_ERR_NONE:
5287 break;
5288 case PIM_MSDP_ERR_NO_PEER:
5289 vty_out(vty, "%% Peer does not exist%s", VTY_NEWLINE);
5290 break;
5291 default:
5292 vty_out(vty, "%% peer del failed%s", VTY_NEWLINE);
5293 }
5294
5295 return result?CMD_WARNING:CMD_SUCCESS;
5296 }
5297
5298 DEFUN_HIDDEN (no_ip_msdp_peer,
5299 no_ip_msdp_peer_cmd,
5300 "no ip msdp peer A.B.C.D",
5301 NO_STR
5302 IP_STR
5303 CFG_MSDP_STR
5304 "Delete MSDP peer\n"
5305 "peer ip address\n")
5306 {
5307 return ip_no_msdp_peer_cmd_worker (vty, argv[4]->arg);
5308 }
5309
5310 static int
5311 ip_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
5312 {
5313 enum pim_msdp_err result;
5314 struct in_addr mbr_ip;
5315
5316 result = inet_pton(AF_INET, mbr, &mbr_ip);
5317 if (result <= 0) {
5318 vty_out(vty, "%% Bad member address %s: errno=%d: %s%s",
5319 mbr, errno, safe_strerror(errno), VTY_NEWLINE);
5320 return CMD_WARNING;
5321 }
5322
5323 result = pim_msdp_mg_mbr_add(mg, mbr_ip);
5324 switch (result) {
5325 case PIM_MSDP_ERR_NONE:
5326 break;
5327 case PIM_MSDP_ERR_OOM:
5328 vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
5329 break;
5330 case PIM_MSDP_ERR_MG_MBR_EXISTS:
5331 vty_out(vty, "%% mesh-group member exists%s", VTY_NEWLINE);
5332 break;
5333 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
5334 vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
5335 break;
5336 default:
5337 vty_out(vty, "%% member add failed%s", VTY_NEWLINE);
5338 }
5339
5340 return result?CMD_WARNING:CMD_SUCCESS;
5341 }
5342
5343 DEFUN (ip_msdp_mesh_group_member,
5344 ip_msdp_mesh_group_member_cmd,
5345 "ip msdp mesh-group WORD member A.B.C.D",
5346 IP_STR
5347 CFG_MSDP_STR
5348 "Configure MSDP mesh-group\n"
5349 "mesh group name\n"
5350 "mesh group member\n"
5351 "peer ip address\n")
5352 {
5353 return ip_msdp_mesh_group_member_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
5354 }
5355
5356 static int
5357 ip_no_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
5358 {
5359 enum pim_msdp_err result;
5360 struct in_addr mbr_ip;
5361
5362 result = inet_pton(AF_INET, mbr, &mbr_ip);
5363 if (result <= 0) {
5364 vty_out(vty, "%% Bad member address %s: errno=%d: %s%s",
5365 mbr, errno, safe_strerror(errno), VTY_NEWLINE);
5366 return CMD_WARNING;
5367 }
5368
5369 result = pim_msdp_mg_mbr_del(mg, mbr_ip);
5370 switch (result) {
5371 case PIM_MSDP_ERR_NONE:
5372 break;
5373 case PIM_MSDP_ERR_NO_MG:
5374 vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
5375 break;
5376 case PIM_MSDP_ERR_NO_MG_MBR:
5377 vty_out(vty, "%% mesh-group member does not exist%s", VTY_NEWLINE);
5378 break;
5379 default:
5380 vty_out(vty, "%% mesh-group member del failed%s", VTY_NEWLINE);
5381 }
5382
5383 return result?CMD_WARNING:CMD_SUCCESS;
5384 }
5385 DEFUN (no_ip_msdp_mesh_group_member,
5386 no_ip_msdp_mesh_group_member_cmd,
5387 "no ip msdp mesh-group WORD member A.B.C.D",
5388 NO_STR
5389 IP_STR
5390 CFG_MSDP_STR
5391 "Delete MSDP mesh-group member\n"
5392 "mesh group name\n"
5393 "mesh group member\n"
5394 "peer ip address\n")
5395 {
5396 return ip_no_msdp_mesh_group_member_cmd_worker(vty, argv[4]->arg, argv[6]->arg);
5397 }
5398
5399 static int
5400 ip_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg, const char *src)
5401 {
5402 enum pim_msdp_err result;
5403 struct in_addr src_ip;
5404
5405 result = inet_pton(AF_INET, src, &src_ip);
5406 if (result <= 0) {
5407 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
5408 src, errno, safe_strerror(errno), VTY_NEWLINE);
5409 return CMD_WARNING;
5410 }
5411
5412 result = pim_msdp_mg_src_add(mg, src_ip);
5413 switch (result) {
5414 case PIM_MSDP_ERR_NONE:
5415 break;
5416 case PIM_MSDP_ERR_OOM:
5417 vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
5418 break;
5419 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
5420 vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
5421 break;
5422 default:
5423 vty_out(vty, "%% source add failed%s", VTY_NEWLINE);
5424 }
5425
5426 return result?CMD_WARNING:CMD_SUCCESS;
5427 }
5428
5429
5430 DEFUN (ip_msdp_mesh_group_source,
5431 ip_msdp_mesh_group_source_cmd,
5432 "ip msdp mesh-group WORD source A.B.C.D",
5433 IP_STR
5434 CFG_MSDP_STR
5435 "Configure MSDP mesh-group\n"
5436 "mesh group name\n"
5437 "mesh group local address\n"
5438 "source ip address for the TCP connection\n")
5439 {
5440 return ip_msdp_mesh_group_source_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
5441 }
5442
5443 static int
5444 ip_no_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg)
5445 {
5446 enum pim_msdp_err result;
5447
5448 result = pim_msdp_mg_src_del(mg);
5449 switch (result) {
5450 case PIM_MSDP_ERR_NONE:
5451 break;
5452 case PIM_MSDP_ERR_NO_MG:
5453 vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
5454 break;
5455 default:
5456 vty_out(vty, "%% mesh-group source del failed%s", VTY_NEWLINE);
5457 }
5458
5459 return result?CMD_WARNING:CMD_SUCCESS;
5460 }
5461
5462 static int
5463 ip_no_msdp_mesh_group_cmd_worker(struct vty *vty, const char *mg)
5464 {
5465 enum pim_msdp_err result;
5466
5467 result = pim_msdp_mg_del(mg);
5468 switch (result) {
5469 case PIM_MSDP_ERR_NONE:
5470 break;
5471 case PIM_MSDP_ERR_NO_MG:
5472 vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
5473 break;
5474 default:
5475 vty_out(vty, "%% mesh-group source del failed%s", VTY_NEWLINE);
5476 }
5477
5478 return result ? CMD_WARNING : CMD_SUCCESS;
5479 }
5480
5481 DEFUN (no_ip_msdp_mesh_group_source,
5482 no_ip_msdp_mesh_group_source_cmd,
5483 "no ip msdp mesh-group WORD source [A.B.C.D]",
5484 NO_STR
5485 IP_STR
5486 CFG_MSDP_STR
5487 "Delete MSDP mesh-group source\n"
5488 "mesh group name\n"
5489 "mesh group local address\n")
5490 {
5491 if (argv[6]->arg)
5492 return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
5493 else
5494 return ip_no_msdp_mesh_group_source_cmd_worker(vty, argv[4]->arg);
5495 }
5496
5497 static void
5498 print_empty_json_obj(struct vty *vty)
5499 {
5500 json_object *json;
5501 json = json_object_new_object();
5502 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5503 json_object_free(json);
5504 }
5505
5506 static void
5507 ip_msdp_show_mesh_group(struct vty *vty, u_char uj)
5508 {
5509 struct listnode *mbrnode;
5510 struct pim_msdp_mg_mbr *mbr;
5511 struct pim_msdp_mg *mg = msdp->mg;
5512 char mbr_str[INET_ADDRSTRLEN];
5513 char src_str[INET_ADDRSTRLEN];
5514 char state_str[PIM_MSDP_STATE_STRLEN];
5515 enum pim_msdp_peer_state state;
5516 json_object *json = NULL;
5517 json_object *json_mg_row = NULL;
5518 json_object *json_row = NULL;
5519
5520 if (!mg) {
5521 if (uj)
5522 print_empty_json_obj(vty);
5523 return;
5524 }
5525
5526 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
5527 if (uj) {
5528 json = json_object_new_object();
5529 /* currently there is only one mesh group but we should still make
5530 * it a dict with mg-name as key */
5531 json_mg_row = json_object_new_object();
5532 json_object_string_add(json_mg_row, "name", mg->mesh_group_name);
5533 json_object_string_add(json_mg_row, "source", src_str);
5534 } else {
5535 vty_out(vty, "Mesh group : %s%s", mg->mesh_group_name, VTY_NEWLINE);
5536 vty_out(vty, " Source : %s%s", src_str, VTY_NEWLINE);
5537 vty_out(vty, " Member State%s", VTY_NEWLINE);
5538 }
5539
5540 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
5541 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
5542 if (mbr->mp) {
5543 state = mbr->mp->state;
5544 } else {
5545 state = PIM_MSDP_DISABLED;
5546 }
5547 pim_msdp_state_dump(state, state_str, sizeof(state_str));
5548 if (uj) {
5549 json_row = json_object_new_object();
5550 json_object_string_add(json_row, "member", mbr_str);
5551 json_object_string_add(json_row, "state", state_str);
5552 json_object_object_add(json_mg_row, mbr_str, json_row);
5553 } else {
5554 vty_out(vty, " %-15s %11s%s",
5555 mbr_str, state_str, VTY_NEWLINE);
5556 }
5557 }
5558
5559 if (uj) {
5560 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
5561 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5562 json_object_free(json);
5563 }
5564 }
5565
5566 DEFUN (show_ip_msdp_mesh_group,
5567 show_ip_msdp_mesh_group_cmd,
5568 "show ip msdp mesh-group [json]",
5569 SHOW_STR
5570 IP_STR
5571 MSDP_STR
5572 "MSDP mesh-group information\n"
5573 "JavaScript Object Notation\n")
5574 {
5575 u_char uj = use_json(argc, argv);
5576 ip_msdp_show_mesh_group(vty, uj);
5577
5578 return CMD_SUCCESS;
5579 }
5580
5581 static void
5582 ip_msdp_show_peers(struct vty *vty, u_char uj)
5583 {
5584 struct listnode *mpnode;
5585 struct pim_msdp_peer *mp;
5586 char peer_str[INET_ADDRSTRLEN];
5587 char local_str[INET_ADDRSTRLEN];
5588 char state_str[PIM_MSDP_STATE_STRLEN];
5589 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5590 int64_t now;
5591 json_object *json = NULL;
5592 json_object *json_row = NULL;
5593
5594
5595 if (uj) {
5596 json = json_object_new_object();
5597 } else {
5598 vty_out(vty, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE);
5599 }
5600
5601 for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
5602 if (mp->state == PIM_MSDP_ESTABLISHED) {
5603 now = pim_time_monotonic_sec();
5604 pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
5605 } else {
5606 strcpy(timebuf, "-");
5607 }
5608 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5609 pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
5610 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5611 if (uj) {
5612 json_row = json_object_new_object();
5613 json_object_string_add(json_row, "peer", peer_str);
5614 json_object_string_add(json_row, "local", local_str);
5615 json_object_string_add(json_row, "state", state_str);
5616 json_object_string_add(json_row, "upTime", timebuf);
5617 json_object_int_add(json_row, "saCount", mp->sa_cnt);
5618 json_object_object_add(json, peer_str, json_row);
5619 } else {
5620 vty_out(vty, "%-15s %15s %11s %8s %6d%s",
5621 peer_str, local_str, state_str,
5622 timebuf, mp->sa_cnt, VTY_NEWLINE);
5623 }
5624 }
5625
5626 if (uj) {
5627 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5628 json_object_free(json);
5629 }
5630 }
5631
5632 static void
5633 ip_msdp_show_peers_detail(struct vty *vty, const char *peer, u_char uj)
5634 {
5635 struct listnode *mpnode;
5636 struct pim_msdp_peer *mp;
5637 char peer_str[INET_ADDRSTRLEN];
5638 char local_str[INET_ADDRSTRLEN];
5639 char state_str[PIM_MSDP_STATE_STRLEN];
5640 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5641 char katimer[PIM_MSDP_TIMER_STRLEN];
5642 char crtimer[PIM_MSDP_TIMER_STRLEN];
5643 char holdtimer[PIM_MSDP_TIMER_STRLEN];
5644 int64_t now;
5645 json_object *json = NULL;
5646 json_object *json_row = NULL;
5647
5648 if (uj) {
5649 json = json_object_new_object();
5650 }
5651
5652 for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
5653 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5654 if (strcmp(peer, "detail") &&
5655 strcmp(peer, peer_str))
5656 continue;
5657
5658 if (mp->state == PIM_MSDP_ESTABLISHED) {
5659 now = pim_time_monotonic_sec();
5660 pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
5661 } else {
5662 strcpy(timebuf, "-");
5663 }
5664 pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
5665 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5666 pim_time_timer_to_hhmmss(katimer, sizeof(katimer), mp->ka_timer);
5667 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer), mp->cr_timer);
5668 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer), mp->hold_timer);
5669
5670 if (uj) {
5671 json_row = json_object_new_object();
5672 json_object_string_add(json_row, "peer", peer_str);
5673 json_object_string_add(json_row, "local", local_str);
5674 json_object_string_add(json_row, "meshGroupName", mp->mesh_group_name);
5675 json_object_string_add(json_row, "state", state_str);
5676 json_object_string_add(json_row, "upTime", timebuf);
5677 json_object_string_add(json_row, "keepAliveTimer", katimer);
5678 json_object_string_add(json_row, "connRetryTimer", crtimer);
5679 json_object_string_add(json_row, "holdTimer", holdtimer);
5680 json_object_string_add(json_row, "lastReset", mp->last_reset);
5681 json_object_int_add(json_row, "connAttempts", mp->conn_attempts);
5682 json_object_int_add(json_row, "establishedChanges", mp->est_flaps);
5683 json_object_int_add(json_row, "saCount", mp->sa_cnt);
5684 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
5685 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
5686 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
5687 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
5688 json_object_object_add(json, peer_str, json_row);
5689 } else {
5690 vty_out(vty, "Peer : %s%s", peer_str, VTY_NEWLINE);
5691 vty_out(vty, " Local : %s%s", local_str, VTY_NEWLINE);
5692 vty_out(vty, " Mesh Group : %s%s", mp->mesh_group_name, VTY_NEWLINE);
5693 vty_out(vty, " State : %s%s", state_str, VTY_NEWLINE);
5694 vty_out(vty, " Uptime : %s%s", timebuf, VTY_NEWLINE);
5695
5696 vty_out(vty, " Keepalive Timer : %s%s", katimer, VTY_NEWLINE);
5697 vty_out(vty, " Conn Retry Timer : %s%s", crtimer, VTY_NEWLINE);
5698 vty_out(vty, " Hold Timer : %s%s", holdtimer, VTY_NEWLINE);
5699 vty_out(vty, " Last Reset : %s%s", mp->last_reset, VTY_NEWLINE);
5700 vty_out(vty, " Conn Attempts : %d%s", mp->conn_attempts, VTY_NEWLINE);
5701 vty_out(vty, " Established Changes : %d%s", mp->est_flaps, VTY_NEWLINE);
5702 vty_out(vty, " SA Count : %d%s", mp->sa_cnt, VTY_NEWLINE);
5703 vty_out(vty, " Statistics :%s", VTY_NEWLINE);
5704 vty_out(vty, " Sent Rcvd%s", VTY_NEWLINE);
5705 vty_out(vty, " Keepalives : %10d %10d%s",
5706 mp->ka_tx_cnt, mp->ka_rx_cnt, VTY_NEWLINE);
5707 vty_out(vty, " SAs : %10d %10d%s",
5708 mp->sa_tx_cnt, mp->sa_rx_cnt, VTY_NEWLINE);
5709 vty_out(vty, "%s", VTY_NEWLINE);
5710 }
5711 }
5712
5713 if (uj) {
5714 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5715 json_object_free(json);
5716 }
5717 }
5718
5719 DEFUN (show_ip_msdp_peer_detail,
5720 show_ip_msdp_peer_detail_cmd,
5721 "show ip msdp peer [detail|A.B.C.D] [json]",
5722 SHOW_STR
5723 IP_STR
5724 MSDP_STR
5725 "MSDP peer information\n"
5726 "Detailed output\n"
5727 "peer ip address\n"
5728 "JavaScript Object Notation\n")
5729 {
5730 u_char uj = use_json(argc, argv);
5731 if (argv[4]->arg)
5732 ip_msdp_show_peers_detail(vty, argv[4]->arg, uj);
5733 else
5734 ip_msdp_show_peers(vty, uj);
5735
5736 return CMD_SUCCESS;
5737 }
5738
5739 static void
5740 ip_msdp_show_sa(struct vty *vty, u_char uj)
5741 {
5742 struct listnode *sanode;
5743 struct pim_msdp_sa *sa;
5744 char src_str[INET_ADDRSTRLEN];
5745 char grp_str[INET_ADDRSTRLEN];
5746 char rp_str[INET_ADDRSTRLEN];
5747 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5748 char spt_str[8];
5749 char local_str[8];
5750 int64_t now;
5751 json_object *json = NULL;
5752 json_object *json_group = NULL;
5753 json_object *json_row = NULL;
5754
5755 if (uj) {
5756 json = json_object_new_object();
5757 } else {
5758 vty_out(vty, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE);
5759 }
5760
5761 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5762 now = pim_time_monotonic_sec();
5763 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
5764 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5765 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
5766 if (sa->flags & PIM_MSDP_SAF_PEER) {
5767 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
5768 if (sa->up) {
5769 strcpy(spt_str, "yes");
5770 } else {
5771 strcpy(spt_str, "no");
5772 }
5773 } else {
5774 strcpy(rp_str, "-");
5775 strcpy(spt_str, "-");
5776 }
5777 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5778 strcpy(local_str, "yes");
5779 } else {
5780 strcpy(local_str, "no");
5781 }
5782 if (uj) {
5783 json_object_object_get_ex(json, grp_str, &json_group);
5784
5785 if (!json_group) {
5786 json_group = json_object_new_object();
5787 json_object_object_add(json, grp_str, json_group);
5788 }
5789
5790 json_row = json_object_new_object();
5791 json_object_string_add(json_row, "source", src_str);
5792 json_object_string_add(json_row, "group", grp_str);
5793 json_object_string_add(json_row, "rp", rp_str);
5794 json_object_string_add(json_row, "local", local_str);
5795 json_object_string_add(json_row, "sptSetup", spt_str);
5796 json_object_string_add(json_row, "upTime", timebuf);
5797 json_object_object_add(json_group, src_str, json_row);
5798 } else {
5799 vty_out(vty, "%-15s %15s %15s %5c %3c %8s%s",
5800 src_str, grp_str, rp_str, local_str[0], spt_str[0], timebuf, VTY_NEWLINE);
5801 }
5802 }
5803
5804
5805 if (uj) {
5806 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5807 json_object_free(json);
5808 }
5809 }
5810
5811 static void
5812 ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, const char *src_str,
5813 const char *grp_str, struct vty *vty,
5814 u_char uj, json_object *json)
5815 {
5816 char rp_str[INET_ADDRSTRLEN];
5817 char peer_str[INET_ADDRSTRLEN];
5818 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5819 char spt_str[8];
5820 char local_str[8];
5821 char statetimer[PIM_MSDP_TIMER_STRLEN];
5822 int64_t now;
5823 json_object *json_group = NULL;
5824 json_object *json_row = NULL;
5825
5826 now = pim_time_monotonic_sec();
5827 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
5828 if (sa->flags & PIM_MSDP_SAF_PEER) {
5829 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
5830 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
5831 if (sa->up) {
5832 strcpy(spt_str, "yes");
5833 } else {
5834 strcpy(spt_str, "no");
5835 }
5836 } else {
5837 strcpy(rp_str, "-");
5838 strcpy(peer_str, "-");
5839 strcpy(spt_str, "-");
5840 }
5841 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5842 strcpy(local_str, "yes");
5843 } else {
5844 strcpy(local_str, "no");
5845 }
5846 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer), sa->sa_state_timer);
5847 if (uj) {
5848 json_object_object_get_ex(json, grp_str, &json_group);
5849
5850 if (!json_group) {
5851 json_group = json_object_new_object();
5852 json_object_object_add(json, grp_str, json_group);
5853 }
5854
5855 json_row = json_object_new_object();
5856 json_object_string_add(json_row, "source", src_str);
5857 json_object_string_add(json_row, "group", grp_str);
5858 json_object_string_add(json_row, "rp", rp_str);
5859 json_object_string_add(json_row, "local", local_str);
5860 json_object_string_add(json_row, "sptSetup", spt_str);
5861 json_object_string_add(json_row, "upTime", timebuf);
5862 json_object_string_add(json_row, "stateTimer", statetimer);
5863 json_object_object_add(json_group, src_str, json_row);
5864 } else {
5865 vty_out(vty, "SA : %s%s", sa->sg_str, VTY_NEWLINE);
5866 vty_out(vty, " RP : %s%s", rp_str, VTY_NEWLINE);
5867 vty_out(vty, " Peer : %s%s", peer_str, VTY_NEWLINE);
5868 vty_out(vty, " Local : %s%s", local_str, VTY_NEWLINE);
5869 vty_out(vty, " SPT Setup : %s%s", spt_str, VTY_NEWLINE);
5870 vty_out(vty, " Uptime : %s%s", timebuf, VTY_NEWLINE);
5871 vty_out(vty, " State Timer : %s%s", statetimer, VTY_NEWLINE);
5872 vty_out(vty, "%s", VTY_NEWLINE);
5873 }
5874 }
5875
5876 static void
5877 ip_msdp_show_sa_detail(struct vty *vty, u_char uj)
5878 {
5879 struct listnode *sanode;
5880 struct pim_msdp_sa *sa;
5881 char src_str[INET_ADDRSTRLEN];
5882 char grp_str[INET_ADDRSTRLEN];
5883 json_object *json = NULL;
5884
5885 if (uj) {
5886 json = json_object_new_object();
5887 }
5888
5889 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5890 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5891 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
5892 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
5893 }
5894
5895 if (uj) {
5896 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5897 json_object_free(json);
5898 }
5899 }
5900
5901 DEFUN (show_ip_msdp_sa_detail,
5902 show_ip_msdp_sa_detail_cmd,
5903 "show ip msdp sa detail [json]",
5904 SHOW_STR
5905 IP_STR
5906 MSDP_STR
5907 "MSDP active-source information\n"
5908 "Detailed output\n"
5909 "JavaScript Object Notation\n")
5910 {
5911 u_char uj = use_json(argc, argv);
5912 ip_msdp_show_sa_detail(vty, uj);
5913
5914 return CMD_SUCCESS;
5915 }
5916
5917 static void
5918 ip_msdp_show_sa_addr(struct vty *vty, const char *addr, u_char uj)
5919 {
5920 struct listnode *sanode;
5921 struct pim_msdp_sa *sa;
5922 char src_str[INET_ADDRSTRLEN];
5923 char grp_str[INET_ADDRSTRLEN];
5924 json_object *json = NULL;
5925
5926 if (uj) {
5927 json = json_object_new_object();
5928 }
5929
5930 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5931 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5932 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
5933 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
5934 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
5935 }
5936 }
5937
5938 if (uj) {
5939 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5940 json_object_free(json);
5941 }
5942 }
5943
5944 static void
5945 ip_msdp_show_sa_sg(struct vty *vty, const char *src, const char *grp, u_char uj)
5946 {
5947 struct listnode *sanode;
5948 struct pim_msdp_sa *sa;
5949 char src_str[INET_ADDRSTRLEN];
5950 char grp_str[INET_ADDRSTRLEN];
5951 json_object *json = NULL;
5952
5953 if (uj) {
5954 json = json_object_new_object();
5955 }
5956
5957 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5958 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5959 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
5960 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
5961 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
5962 }
5963 }
5964
5965 if (uj) {
5966 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5967 json_object_free(json);
5968 }
5969 }
5970
5971 DEFUN (show_ip_msdp_sa_sg,
5972 show_ip_msdp_sa_sg_cmd,
5973 "show ip msdp sa [A.B.C.D] [A.B.C.D] [json]",
5974 SHOW_STR
5975 IP_STR
5976 MSDP_STR
5977 "MSDP active-source information\n"
5978 "source or group ip\n"
5979 "JavaScript Object Notation\n")
5980 {
5981 u_char uj = use_json(argc, argv);
5982 if (argv[5]->arg)
5983 ip_msdp_show_sa_sg(vty, argv[4]->arg, argv[5]->arg, uj);
5984 else if (argv[4]->arg)
5985 ip_msdp_show_sa_addr(vty, argv[4]->arg, uj);
5986 else
5987 ip_msdp_show_sa(vty, uj);
5988
5989 return CMD_SUCCESS;
5990 }
5991
5992 void pim_cmd_init()
5993 {
5994 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
5995 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
5996 if_cmd_init ();
5997
5998 install_node (&debug_node, pim_debug_config_write);
5999
6000 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
6001 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
6002 install_element (CONFIG_NODE, &ip_pim_rp_cmd);
6003 install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
6004 install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
6005 install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
6006 install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd);
6007 install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
6008 install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd);
6009 install_element (CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
6010 install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
6011 install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
6012 install_element (CONFIG_NODE, &ip_pim_packets_cmd);
6013 install_element (CONFIG_NODE, &no_ip_pim_packets_cmd);
6014 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
6015 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
6016 install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
6017 install_element (CONFIG_NODE, &no_ip_msdp_peer_cmd);
6018
6019 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
6020 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
6021 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
6022 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
6023 install_element (INTERFACE_NODE, &interface_ip_igmp_version_cmd);
6024 install_element (INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
6025 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
6026 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
6027 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
6028 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
6029 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
6030 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
6031 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
6032 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
6033 install_element (INTERFACE_NODE, &interface_ip_pim_sm_cmd);
6034 install_element (INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
6035 install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
6036 install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
6037 install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
6038 install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
6039
6040 // Static mroutes NEB
6041 install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
6042 install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
6043 install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
6044 install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
6045
6046 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
6047 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
6048 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
6049 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
6050 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
6051 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
6052 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
6053 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
6054 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
6055 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
6056 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
6057 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
6058 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
6059 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
6060 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
6061 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
6062 install_element (VIEW_NODE, &show_ip_pim_state_cmd);
6063 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
6064 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
6065 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
6066 install_element (VIEW_NODE, &show_ip_pim_rp_cmd);
6067 install_element (VIEW_NODE, &show_ip_multicast_cmd);
6068 install_element (VIEW_NODE, &show_ip_mroute_cmd);
6069 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
6070 install_element (VIEW_NODE, &show_ip_rib_cmd);
6071 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
6072 install_element (VIEW_NODE, &show_debugging_pim_cmd);
6073
6074 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
6075 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
6076 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
6077 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
6078 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
6079
6080 install_element (ENABLE_NODE, &debug_igmp_cmd);
6081 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
6082 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
6083 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
6084 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
6085 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
6086 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
6087 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
6088 install_element (ENABLE_NODE, &debug_mroute_cmd);
6089 install_element (ENABLE_NODE, &debug_mroute_detail_cmd);
6090 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
6091 install_element (ENABLE_NODE, &no_debug_mroute_detail_cmd);
6092 install_element (ENABLE_NODE, &debug_static_cmd);
6093 install_element (ENABLE_NODE, &no_debug_static_cmd);
6094 install_element (ENABLE_NODE, &debug_pim_cmd);
6095 install_element (ENABLE_NODE, &no_debug_pim_cmd);
6096 install_element (ENABLE_NODE, &debug_pim_events_cmd);
6097 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
6098 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
6099 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
6100 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
6101 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
6102 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
6103 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
6104 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
6105 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
6106 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
6107 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
6108 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
6109 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
6110 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
6111 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
6112 install_element (ENABLE_NODE, &debug_msdp_cmd);
6113 install_element (ENABLE_NODE, &no_debug_msdp_cmd);
6114 install_element (ENABLE_NODE, &undebug_msdp_cmd);
6115 install_element (ENABLE_NODE, &debug_msdp_events_cmd);
6116 install_element (ENABLE_NODE, &no_debug_msdp_events_cmd);
6117 install_element (ENABLE_NODE, &undebug_msdp_events_cmd);
6118 install_element (ENABLE_NODE, &debug_msdp_packets_cmd);
6119 install_element (ENABLE_NODE, &no_debug_msdp_packets_cmd);
6120 install_element (ENABLE_NODE, &undebug_msdp_packets_cmd);
6121
6122 install_element (CONFIG_NODE, &debug_igmp_cmd);
6123 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
6124 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
6125 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
6126 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
6127 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
6128 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
6129 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
6130 install_element (CONFIG_NODE, &debug_mroute_cmd);
6131 install_element (CONFIG_NODE, &debug_mroute_detail_cmd);
6132 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
6133 install_element (CONFIG_NODE, &no_debug_mroute_detail_cmd);
6134 install_element (CONFIG_NODE, &debug_static_cmd);
6135 install_element (CONFIG_NODE, &no_debug_static_cmd);
6136 install_element (CONFIG_NODE, &debug_pim_cmd);
6137 install_element (CONFIG_NODE, &no_debug_pim_cmd);
6138 install_element (CONFIG_NODE, &debug_pim_events_cmd);
6139 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
6140 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
6141 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
6142 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
6143 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
6144 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
6145 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
6146 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
6147 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
6148 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
6149 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
6150 install_element (CONFIG_NODE, &debug_msdp_cmd);
6151 install_element (CONFIG_NODE, &no_debug_msdp_cmd);
6152 install_element (CONFIG_NODE, &undebug_msdp_cmd);
6153 install_element (CONFIG_NODE, &debug_msdp_events_cmd);
6154 install_element (CONFIG_NODE, &no_debug_msdp_events_cmd);
6155 install_element (CONFIG_NODE, &undebug_msdp_events_cmd);
6156 install_element (CONFIG_NODE, &debug_msdp_packets_cmd);
6157 install_element (CONFIG_NODE, &no_debug_msdp_packets_cmd);
6158 install_element (CONFIG_NODE, &undebug_msdp_packets_cmd);
6159 install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
6160 install_element (CONFIG_NODE, &no_ip_msdp_peer_cmd);
6161 install_element (CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
6162 install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
6163 install_element (CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
6164 install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
6165 install_element (VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
6166 install_element (VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
6167 install_element (VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
6168 install_element (VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
6169 install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
6170 install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
6171 }