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