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