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