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