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