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