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