]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_cmd.c
pimd: Add ability to select upstream on S,G for `show ip pim upstream`
[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 along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <zebra.h>
21
22 #include "lib/json.h"
23 #include "command.h"
24 #include "if.h"
25 #include "prefix.h"
26 #include "zclient.h"
27 #include "plist.h"
28 #include "hash.h"
29 #include "nexthop.h"
30 #include "vrf.h"
31 #include "ferr.h"
32
33 #include "pimd.h"
34 #include "pim_mroute.h"
35 #include "pim_cmd.h"
36 #include "pim_iface.h"
37 #include "pim_vty.h"
38 #include "pim_mroute.h"
39 #include "pim_str.h"
40 #include "pim_igmp.h"
41 #include "pim_igmpv3.h"
42 #include "pim_sock.h"
43 #include "pim_time.h"
44 #include "pim_util.h"
45 #include "pim_oil.h"
46 #include "pim_neighbor.h"
47 #include "pim_pim.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
50 #include "pim_msg.h"
51 #include "pim_upstream.h"
52 #include "pim_rpf.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
57 #include "pim_rp.h"
58 #include "pim_zlookup.h"
59 #include "pim_msdp.h"
60 #include "pim_ssm.h"
61 #include "pim_nht.h"
62 #include "pim_bfd.h"
63 #include "bfd.h"
64
65 #ifndef VTYSH_EXTRACT_PL
66 #include "pimd/pim_cmd_clippy.c"
67 #endif
68
69 static struct cmd_node interface_node = {
70 INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
71 };
72
73 static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
74
75 static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
76 const int argc, int *idx)
77 {
78 struct vrf *vrf;
79
80 if (argv_find(argv, argc, "NAME", idx))
81 vrf = vrf_lookup_by_name(argv[*idx]->arg);
82 else
83 vrf = vrf_lookup_by_id(VRF_DEFAULT);
84
85 if (!vrf)
86 vty_out(vty, "Specified VRF: %s does not exist\n",
87 argv[*idx]->arg);
88
89 return vrf;
90 }
91
92 static void pim_if_membership_clear(struct interface *ifp)
93 {
94 struct pim_interface *pim_ifp;
95
96 pim_ifp = ifp->info;
97 zassert(pim_ifp);
98
99 if (PIM_IF_TEST_PIM(pim_ifp->options)
100 && PIM_IF_TEST_IGMP(pim_ifp->options)) {
101 return;
102 }
103
104 pim_ifchannel_membership_clear(ifp);
105 }
106
107 /*
108 When PIM is disabled on interface, IGMPv3 local membership
109 information is not injected into PIM interface state.
110
111 The function pim_if_membership_refresh() fetches all IGMPv3 local
112 membership information into PIM. It is intented to be called
113 whenever PIM is enabled on the interface in order to collect missed
114 local membership information.
115 */
116 static void pim_if_membership_refresh(struct interface *ifp)
117 {
118 struct pim_interface *pim_ifp;
119 struct listnode *sock_node;
120 struct igmp_sock *igmp;
121
122 pim_ifp = ifp->info;
123 zassert(pim_ifp);
124
125 if (!PIM_IF_TEST_PIM(pim_ifp->options))
126 return;
127 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
128 return;
129
130 /*
131 First clear off membership from all PIM (S,G) entries on the
132 interface
133 */
134
135 pim_ifchannel_membership_clear(ifp);
136
137 /*
138 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
139 the interface
140 */
141
142 /* scan igmp sockets */
143 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
144 struct listnode *grpnode;
145 struct igmp_group *grp;
146
147 /* scan igmp groups */
148 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
149 grp)) {
150 struct listnode *srcnode;
151 struct igmp_source *src;
152
153 /* scan group sources */
154 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
155 srcnode, src)) {
156
157 if (IGMP_SOURCE_TEST_FORWARDING(
158 src->source_flags)) {
159 struct prefix_sg sg;
160
161 memset(&sg, 0,
162 sizeof(struct prefix_sg));
163 sg.src = src->source_addr;
164 sg.grp = grp->group_addr;
165 pim_ifchannel_local_membership_add(ifp,
166 &sg);
167 }
168
169 } /* scan group sources */
170 } /* scan igmp groups */
171 } /* scan igmp sockets */
172
173 /*
174 Finally delete every PIM (S,G) entry lacking all state info
175 */
176
177 pim_ifchannel_delete_on_noinfo(ifp);
178 }
179
180 static void pim_show_assert_helper(struct vty *vty,
181 struct pim_interface *pim_ifp,
182 struct pim_ifchannel *ch, time_t now)
183 {
184 char ch_src_str[INET_ADDRSTRLEN];
185 char ch_grp_str[INET_ADDRSTRLEN];
186 char winner_str[INET_ADDRSTRLEN];
187 struct in_addr ifaddr;
188 char uptime[10];
189 char timer[10];
190
191 ifaddr = pim_ifp->primary_address;
192
193 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
194 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
195 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
196 sizeof(winner_str));
197
198 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
199 pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
200
201 vty_out(vty, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
202 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
203 pim_ifchannel_ifassert_name(ch->ifassert_state), winner_str,
204 uptime, timer);
205 }
206
207 static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
208 {
209 struct pim_interface *pim_ifp;
210 struct pim_ifchannel *ch;
211 struct interface *ifp;
212 time_t now;
213
214 now = pim_time_monotonic_sec();
215
216 vty_out(vty,
217 "Interface Address Source Group State Winner Uptime Timer\n");
218
219 FOR_ALL_INTERFACES (pim->vrf, ifp) {
220 pim_ifp = ifp->info;
221 if (!pim_ifp)
222 continue;
223
224 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
225 pim_show_assert_helper(vty, pim_ifp, ch, now);
226 } /* scan interface channels */
227 }
228 }
229
230 static void pim_show_assert_internal_helper(struct vty *vty,
231 struct pim_interface *pim_ifp,
232 struct pim_ifchannel *ch)
233 {
234 char ch_src_str[INET_ADDRSTRLEN];
235 char ch_grp_str[INET_ADDRSTRLEN];
236 struct in_addr ifaddr;
237
238 ifaddr = pim_ifp->primary_address;
239
240 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
241 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
242 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
243 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
244 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
245 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
246 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
247 : "no",
248 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
249 }
250
251 static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
252 {
253 struct pim_interface *pim_ifp;
254 struct pim_ifchannel *ch;
255 struct interface *ifp;
256
257 vty_out(vty,
258 "CA: CouldAssert\n"
259 "ECA: Evaluate CouldAssert\n"
260 "ATD: AssertTrackingDesired\n"
261 "eATD: Evaluate AssertTrackingDesired\n\n");
262
263 vty_out(vty,
264 "Interface Address Source Group CA eCA ATD eATD\n");
265 FOR_ALL_INTERFACES (pim->vrf, ifp) {
266 pim_ifp = ifp->info;
267 if (!pim_ifp)
268 continue;
269
270 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
271 pim_show_assert_internal_helper(vty, pim_ifp, ch);
272 } /* scan interface channels */
273 }
274 }
275
276 static void pim_show_assert_metric_helper(struct vty *vty,
277 struct pim_interface *pim_ifp,
278 struct pim_ifchannel *ch)
279 {
280 char ch_src_str[INET_ADDRSTRLEN];
281 char ch_grp_str[INET_ADDRSTRLEN];
282 char addr_str[INET_ADDRSTRLEN];
283 struct pim_assert_metric am;
284 struct in_addr ifaddr;
285
286 ifaddr = pim_ifp->primary_address;
287
288 am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
289 pim_ifp->primary_address);
290
291 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
292 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
293 pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
294
295 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
296 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
297 am.rpt_bit_flag ? "yes" : "no", am.metric_preference,
298 am.route_metric, addr_str);
299 }
300
301 static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
302 {
303 struct pim_interface *pim_ifp;
304 struct pim_ifchannel *ch;
305 struct interface *ifp;
306
307 vty_out(vty,
308 "Interface Address Source Group RPT Pref Metric Address \n");
309
310 FOR_ALL_INTERFACES (pim->vrf, ifp) {
311 pim_ifp = ifp->info;
312 if (!pim_ifp)
313 continue;
314
315 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
316 pim_show_assert_metric_helper(vty, pim_ifp, ch);
317 } /* scan interface channels */
318 }
319 }
320
321 static void pim_show_assert_winner_metric_helper(struct vty *vty,
322 struct pim_interface *pim_ifp,
323 struct pim_ifchannel *ch)
324 {
325 char ch_src_str[INET_ADDRSTRLEN];
326 char ch_grp_str[INET_ADDRSTRLEN];
327 char addr_str[INET_ADDRSTRLEN];
328 struct pim_assert_metric *am;
329 struct in_addr ifaddr;
330 char pref_str[16];
331 char metr_str[16];
332
333 ifaddr = pim_ifp->primary_address;
334
335 am = &ch->ifassert_winner_metric;
336
337 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
338 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
339 pim_inet4_dump("<addr?>", am->ip_address, addr_str, sizeof(addr_str));
340
341 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
342 snprintf(pref_str, sizeof(pref_str), "INFI");
343 else
344 snprintf(pref_str, sizeof(pref_str), "%4u",
345 am->metric_preference);
346
347 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
348 snprintf(metr_str, sizeof(metr_str), "INFI");
349 else
350 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
351
352 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
353 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
354 am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, addr_str);
355 }
356
357 static void pim_show_assert_winner_metric(struct pim_instance *pim,
358 struct vty *vty)
359 {
360 struct pim_interface *pim_ifp;
361 struct pim_ifchannel *ch;
362 struct interface *ifp;
363
364 vty_out(vty,
365 "Interface Address Source Group RPT Pref Metric Address \n");
366
367 FOR_ALL_INTERFACES (pim->vrf, ifp) {
368 pim_ifp = ifp->info;
369 if (!pim_ifp)
370 continue;
371
372 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
373 pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
374 } /* scan interface channels */
375 }
376 }
377
378 static void json_object_pim_ifp_add(struct json_object *json,
379 struct interface *ifp)
380 {
381 struct pim_interface *pim_ifp;
382
383 pim_ifp = ifp->info;
384 json_object_string_add(json, "name", ifp->name);
385 json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
386 json_object_string_add(json, "address",
387 inet_ntoa(pim_ifp->primary_address));
388 json_object_int_add(json, "index", ifp->ifindex);
389
390 if (if_is_multicast(ifp))
391 json_object_boolean_true_add(json, "flagMulticast");
392
393 if (if_is_broadcast(ifp))
394 json_object_boolean_true_add(json, "flagBroadcast");
395
396 if (ifp->flags & IFF_ALLMULTI)
397 json_object_boolean_true_add(json, "flagAllMulticast");
398
399 if (ifp->flags & IFF_PROMISC)
400 json_object_boolean_true_add(json, "flagPromiscuous");
401
402 if (PIM_IF_IS_DELETED(ifp))
403 json_object_boolean_true_add(json, "flagDeleted");
404
405 if (pim_if_lan_delay_enabled(ifp))
406 json_object_boolean_true_add(json, "lanDelayEnabled");
407 }
408
409 static void pim_show_membership_helper(struct vty *vty,
410 struct pim_interface *pim_ifp,
411 struct pim_ifchannel *ch,
412 struct json_object *json)
413 {
414 char ch_src_str[INET_ADDRSTRLEN];
415 char ch_grp_str[INET_ADDRSTRLEN];
416 json_object *json_iface = NULL;
417 json_object *json_row = NULL;
418
419 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
420 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
421
422 json_object_object_get_ex(json, ch->interface->name, &json_iface);
423 if (!json_iface) {
424 json_iface = json_object_new_object();
425 json_object_pim_ifp_add(json_iface, ch->interface);
426 json_object_object_add(json, ch->interface->name, json_iface);
427 }
428
429 json_row = json_object_new_object();
430 json_object_string_add(json_row, "source", ch_src_str);
431 json_object_string_add(json_row, "group", ch_grp_str);
432 json_object_string_add(json_row, "localMembership",
433 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
434 ? "NOINFO"
435 : "INCLUDE");
436 json_object_object_add(json_iface, ch_grp_str, json_row);
437 }
438 static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
439 bool uj)
440 {
441 struct pim_interface *pim_ifp;
442 struct pim_ifchannel *ch;
443 struct interface *ifp;
444 enum json_type type;
445 json_object *json = NULL;
446 json_object *json_tmp = NULL;
447
448 json = json_object_new_object();
449
450 FOR_ALL_INTERFACES (pim->vrf, ifp) {
451 pim_ifp = ifp->info;
452 if (!pim_ifp)
453 continue;
454
455 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
456 pim_show_membership_helper(vty, pim_ifp, ch, json);
457 } /* scan interface channels */
458 }
459
460 if (uj) {
461 vty_out(vty, "%s\n", json_object_to_json_string_ext(
462 json, JSON_C_TO_STRING_PRETTY));
463 } else {
464 vty_out(vty,
465 "Interface Address Source Group Membership\n");
466
467 /*
468 * Example of the json data we are traversing
469 *
470 * {
471 * "swp3":{
472 * "name":"swp3",
473 * "state":"up",
474 * "address":"10.1.20.1",
475 * "index":5,
476 * "flagMulticast":true,
477 * "flagBroadcast":true,
478 * "lanDelayEnabled":true,
479 * "226.10.10.10":{
480 * "source":"*",
481 * "group":"226.10.10.10",
482 * "localMembership":"INCLUDE"
483 * }
484 * }
485 * }
486 */
487
488 /* foreach interface */
489 json_object_object_foreach(json, key, val)
490 {
491
492 /* Find all of the keys where the val is an object. In
493 * the example
494 * above the only one is 226.10.10.10
495 */
496 json_object_object_foreach(val, if_field_key,
497 if_field_val)
498 {
499 type = json_object_get_type(if_field_val);
500
501 if (type == json_type_object) {
502 vty_out(vty, "%-16s ", key);
503
504 json_object_object_get_ex(
505 val, "address", &json_tmp);
506 vty_out(vty, "%-15s ",
507 json_object_get_string(
508 json_tmp));
509
510 json_object_object_get_ex(if_field_val,
511 "source",
512 &json_tmp);
513 vty_out(vty, "%-15s ",
514 json_object_get_string(
515 json_tmp));
516
517 /* Group */
518 vty_out(vty, "%-15s ", if_field_key);
519
520 json_object_object_get_ex(
521 if_field_val, "localMembership",
522 &json_tmp);
523 vty_out(vty, "%-10s\n",
524 json_object_get_string(
525 json_tmp));
526 }
527 }
528 }
529 }
530
531 json_object_free(json);
532 }
533
534 static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp,
535 int mloop)
536 {
537 vty_out(vty, "Flags\n");
538 vty_out(vty, "-----\n");
539 vty_out(vty, "All Multicast : %s\n",
540 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
541 vty_out(vty, "Broadcast : %s\n",
542 if_is_broadcast(ifp) ? "yes" : "no");
543 vty_out(vty, "Deleted : %s\n",
544 PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
545 vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
546 vty_out(vty, "Multicast : %s\n",
547 if_is_multicast(ifp) ? "yes" : "no");
548 vty_out(vty, "Multicast Loop : %d\n", mloop);
549 vty_out(vty, "Promiscuous : %s\n",
550 (ifp->flags & IFF_PROMISC) ? "yes" : "no");
551 vty_out(vty, "\n");
552 vty_out(vty, "\n");
553 }
554
555 static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
556 bool uj)
557 {
558 struct interface *ifp;
559 time_t now;
560 json_object *json = NULL;
561 json_object *json_row = NULL;
562
563 now = pim_time_monotonic_sec();
564
565 if (uj)
566 json = json_object_new_object();
567 else
568 vty_out(vty,
569 "Interface State Address V Querier Query Timer Uptime\n");
570
571 FOR_ALL_INTERFACES (pim->vrf, ifp) {
572 struct pim_interface *pim_ifp;
573 struct listnode *sock_node;
574 struct igmp_sock *igmp;
575
576 pim_ifp = ifp->info;
577
578 if (!pim_ifp)
579 continue;
580
581 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
582 igmp)) {
583 char uptime[10];
584 char query_hhmmss[10];
585
586 pim_time_uptime(uptime, sizeof(uptime),
587 now - igmp->sock_creation);
588 pim_time_timer_to_hhmmss(query_hhmmss,
589 sizeof(query_hhmmss),
590 igmp->t_igmp_query_timer);
591
592 if (uj) {
593 json_row = json_object_new_object();
594 json_object_pim_ifp_add(json_row, ifp);
595 json_object_string_add(json_row, "upTime",
596 uptime);
597 json_object_int_add(json_row, "version",
598 pim_ifp->igmp_version);
599
600 if (igmp->t_igmp_query_timer) {
601 json_object_boolean_true_add(json_row,
602 "querier");
603 json_object_string_add(json_row,
604 "queryTimer",
605 query_hhmmss);
606 }
607
608 json_object_object_add(json, ifp->name,
609 json_row);
610
611 if (igmp->mtrace_only) {
612 json_object_boolean_true_add(
613 json_row, "mtraceOnly");
614 }
615 } else {
616 vty_out(vty,
617 "%-16s %5s %15s %d %7s %11s %8s\n",
618 ifp->name,
619 if_is_up(ifp)
620 ? (igmp->mtrace_only ? "mtrc"
621 : "up")
622 : "down",
623 inet_ntoa(igmp->ifaddr),
624 pim_ifp->igmp_version,
625 igmp->t_igmp_query_timer ? "local"
626 : "other",
627 query_hhmmss, uptime);
628 }
629 }
630 }
631
632 if (uj) {
633 vty_out(vty, "%s\n", json_object_to_json_string_ext(
634 json, JSON_C_TO_STRING_PRETTY));
635 json_object_free(json);
636 }
637 }
638
639 static void igmp_show_interfaces_single(struct pim_instance *pim,
640 struct vty *vty, const char *ifname,
641 bool uj)
642 {
643 struct igmp_sock *igmp;
644 struct interface *ifp;
645 struct listnode *sock_node;
646 struct pim_interface *pim_ifp;
647 char uptime[10];
648 char query_hhmmss[10];
649 char other_hhmmss[10];
650 int found_ifname = 0;
651 int sqi;
652 int mloop = 0;
653 long gmi_msec; /* Group Membership Interval */
654 long lmqt_msec;
655 long ohpi_msec;
656 long oqpi_msec; /* Other Querier Present Interval */
657 long qri_msec;
658 time_t now;
659
660 json_object *json = NULL;
661 json_object *json_row = NULL;
662
663 if (uj)
664 json = json_object_new_object();
665
666 now = pim_time_monotonic_sec();
667
668 FOR_ALL_INTERFACES (pim->vrf, ifp) {
669 pim_ifp = ifp->info;
670
671 if (!pim_ifp)
672 continue;
673
674 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
675 continue;
676
677 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
678 igmp)) {
679 found_ifname = 1;
680 pim_time_uptime(uptime, sizeof(uptime),
681 now - igmp->sock_creation);
682 pim_time_timer_to_hhmmss(query_hhmmss,
683 sizeof(query_hhmmss),
684 igmp->t_igmp_query_timer);
685 pim_time_timer_to_hhmmss(other_hhmmss,
686 sizeof(other_hhmmss),
687 igmp->t_other_querier_timer);
688
689 gmi_msec = PIM_IGMP_GMI_MSEC(
690 igmp->querier_robustness_variable,
691 igmp->querier_query_interval,
692 pim_ifp->igmp_query_max_response_time_dsec);
693
694 sqi = PIM_IGMP_SQI(
695 pim_ifp->igmp_default_query_interval);
696
697 oqpi_msec = PIM_IGMP_OQPI_MSEC(
698 igmp->querier_robustness_variable,
699 igmp->querier_query_interval,
700 pim_ifp->igmp_query_max_response_time_dsec);
701
702 lmqt_msec = PIM_IGMP_LMQT_MSEC(
703 pim_ifp->igmp_query_max_response_time_dsec,
704 igmp->querier_robustness_variable);
705
706 ohpi_msec =
707 PIM_IGMP_OHPI_DSEC(
708 igmp->querier_robustness_variable,
709 igmp->querier_query_interval,
710 pim_ifp->igmp_query_max_response_time_dsec)
711 * 100;
712
713 qri_msec = pim_ifp->igmp_query_max_response_time_dsec
714 * 100;
715 if (pim_ifp->pim_sock_fd >= 0)
716 mloop = pim_socket_mcastloop_get(
717 pim_ifp->pim_sock_fd);
718 else
719 mloop = 0;
720
721 if (uj) {
722 json_row = json_object_new_object();
723 json_object_pim_ifp_add(json_row, ifp);
724 json_object_string_add(json_row, "upTime",
725 uptime);
726 json_object_string_add(json_row, "querier",
727 igmp->t_igmp_query_timer
728 ? "local"
729 : "other");
730 json_object_int_add(json_row, "queryStartCount",
731 igmp->startup_query_count);
732 json_object_string_add(json_row,
733 "queryQueryTimer",
734 query_hhmmss);
735 json_object_string_add(json_row,
736 "queryOtherTimer",
737 other_hhmmss);
738 json_object_int_add(json_row, "version",
739 pim_ifp->igmp_version);
740 json_object_int_add(
741 json_row,
742 "timerGroupMembershipIntervalMsec",
743 gmi_msec);
744 json_object_int_add(json_row,
745 "timerLastMemberQueryMsec",
746 lmqt_msec);
747 json_object_int_add(
748 json_row,
749 "timerOlderHostPresentIntervalMsec",
750 ohpi_msec);
751 json_object_int_add(
752 json_row,
753 "timerOtherQuerierPresentIntervalMsec",
754 oqpi_msec);
755 json_object_int_add(
756 json_row, "timerQueryInterval",
757 igmp->querier_query_interval);
758 json_object_int_add(
759 json_row,
760 "timerQueryResponseIntervalMsec",
761 qri_msec);
762 json_object_int_add(
763 json_row, "timerRobustnessVariable",
764 igmp->querier_robustness_variable);
765 json_object_int_add(json_row,
766 "timerStartupQueryInterval",
767 sqi);
768
769 json_object_object_add(json, ifp->name,
770 json_row);
771
772 if (igmp->mtrace_only) {
773 json_object_boolean_true_add(
774 json_row, "mtraceOnly");
775 }
776 } else {
777 vty_out(vty, "Interface : %s\n", ifp->name);
778 vty_out(vty, "State : %s\n",
779 if_is_up(ifp)
780 ? (igmp->mtrace_only ? "mtrace"
781 : "up")
782 : "down");
783 vty_out(vty, "Address : %s\n",
784 inet_ntoa(pim_ifp->primary_address));
785 vty_out(vty, "Uptime : %s\n", uptime);
786 vty_out(vty, "Version : %d\n",
787 pim_ifp->igmp_version);
788 vty_out(vty, "\n");
789 vty_out(vty, "\n");
790
791 vty_out(vty, "Querier\n");
792 vty_out(vty, "-------\n");
793 vty_out(vty, "Querier : %s\n",
794 igmp->t_igmp_query_timer ? "local"
795 : "other");
796 vty_out(vty, "Start Count : %d\n",
797 igmp->startup_query_count);
798 vty_out(vty, "Query Timer : %s\n",
799 query_hhmmss);
800 vty_out(vty, "Other Timer : %s\n",
801 other_hhmmss);
802 vty_out(vty, "\n");
803 vty_out(vty, "\n");
804
805 vty_out(vty, "Timers\n");
806 vty_out(vty, "------\n");
807 vty_out(vty,
808 "Group Membership Interval : %lis\n",
809 gmi_msec / 1000);
810 vty_out(vty,
811 "Last Member Query Time : %lis\n",
812 lmqt_msec / 1000);
813 vty_out(vty,
814 "Older Host Present Interval : %lis\n",
815 ohpi_msec / 1000);
816 vty_out(vty,
817 "Other Querier Present Interval : %lis\n",
818 oqpi_msec / 1000);
819 vty_out(vty,
820 "Query Interval : %ds\n",
821 igmp->querier_query_interval);
822 vty_out(vty,
823 "Query Response Interval : %lis\n",
824 qri_msec / 1000);
825 vty_out(vty,
826 "Robustness Variable : %d\n",
827 igmp->querier_robustness_variable);
828 vty_out(vty,
829 "Startup Query Interval : %ds\n",
830 sqi);
831 vty_out(vty, "\n");
832 vty_out(vty, "\n");
833
834 pim_print_ifp_flags(vty, ifp, mloop);
835 }
836 }
837 }
838
839 if (uj) {
840 vty_out(vty, "%s\n", json_object_to_json_string_ext(
841 json, JSON_C_TO_STRING_PRETTY));
842 json_object_free(json);
843 } else {
844 if (!found_ifname)
845 vty_out(vty, "%% No such interface\n");
846 }
847 }
848
849 static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
850 {
851 struct interface *ifp;
852 time_t now;
853
854 now = pim_time_monotonic_sec();
855
856 vty_out(vty,
857 "Interface Address Source Group Socket Uptime \n");
858
859 FOR_ALL_INTERFACES (pim->vrf, ifp) {
860 struct pim_interface *pim_ifp;
861 struct listnode *join_node;
862 struct igmp_join *ij;
863 struct in_addr pri_addr;
864 char pri_addr_str[INET_ADDRSTRLEN];
865
866 pim_ifp = ifp->info;
867
868 if (!pim_ifp)
869 continue;
870
871 if (!pim_ifp->igmp_join_list)
872 continue;
873
874 pri_addr = pim_find_primary_addr(ifp);
875 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
876 sizeof(pri_addr_str));
877
878 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node,
879 ij)) {
880 char group_str[INET_ADDRSTRLEN];
881 char source_str[INET_ADDRSTRLEN];
882 char uptime[10];
883
884 pim_time_uptime(uptime, sizeof(uptime),
885 now - ij->sock_creation);
886 pim_inet4_dump("<grp?>", ij->group_addr, group_str,
887 sizeof(group_str));
888 pim_inet4_dump("<src?>", ij->source_addr, source_str,
889 sizeof(source_str));
890
891 vty_out(vty, "%-16s %-15s %-15s %-15s %6d %8s\n",
892 ifp->name, pri_addr_str, source_str, group_str,
893 ij->sock_fd, uptime);
894 } /* for (pim_ifp->igmp_join_list) */
895
896 } /* for (iflist) */
897 }
898
899 static void pim_show_interfaces_single(struct pim_instance *pim,
900 struct vty *vty, const char *ifname,
901 bool uj)
902 {
903 struct in_addr ifaddr;
904 struct interface *ifp;
905 struct listnode *neighnode;
906 struct listnode *upnode;
907 struct pim_interface *pim_ifp;
908 struct pim_neighbor *neigh;
909 struct pim_upstream *up;
910 time_t now;
911 char dr_str[INET_ADDRSTRLEN];
912 char dr_uptime[10];
913 char expire[10];
914 char grp_str[INET_ADDRSTRLEN];
915 char hello_period[10];
916 char hello_timer[10];
917 char neigh_src_str[INET_ADDRSTRLEN];
918 char src_str[INET_ADDRSTRLEN];
919 char stat_uptime[10];
920 char uptime[10];
921 int mloop = 0;
922 int found_ifname = 0;
923 int print_header;
924 json_object *json = NULL;
925 json_object *json_row = NULL;
926 json_object *json_pim_neighbor = NULL;
927 json_object *json_pim_neighbors = NULL;
928 json_object *json_group = NULL;
929 json_object *json_group_source = NULL;
930 json_object *json_fhr_sources = NULL;
931 struct pim_secondary_addr *sec_addr;
932 struct listnode *sec_node;
933
934 now = pim_time_monotonic_sec();
935
936 if (uj)
937 json = json_object_new_object();
938
939 FOR_ALL_INTERFACES (pim->vrf, ifp) {
940 pim_ifp = ifp->info;
941
942 if (!pim_ifp)
943 continue;
944
945 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
946 continue;
947
948 found_ifname = 1;
949 ifaddr = pim_ifp->primary_address;
950 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
951 sizeof(dr_str));
952 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
953 pim_ifp->pim_dr_election_last);
954 pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
955 pim_ifp->t_pim_hello_timer);
956 pim_time_mmss(hello_period, sizeof(hello_period),
957 pim_ifp->pim_hello_period);
958 pim_time_uptime(stat_uptime, sizeof(stat_uptime),
959 now - pim_ifp->pim_ifstat_start);
960 if (pim_ifp->pim_sock_fd >= 0)
961 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
962 else
963 mloop = 0;
964
965 if (uj) {
966 char pbuf[PREFIX2STR_BUFFER];
967 json_row = json_object_new_object();
968 json_object_pim_ifp_add(json_row, ifp);
969
970 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
971 json_object_string_add(
972 json_row, "useSource",
973 inet_ntoa(pim_ifp->update_source));
974 }
975 if (pim_ifp->sec_addr_list) {
976 json_object *sec_list = NULL;
977
978 sec_list = json_object_new_array();
979 for (ALL_LIST_ELEMENTS_RO(
980 pim_ifp->sec_addr_list, sec_node,
981 sec_addr)) {
982 json_object_array_add(
983 sec_list,
984 json_object_new_string(
985 prefix2str(
986 &sec_addr->addr,
987 pbuf,
988 sizeof(pbuf))));
989 }
990 json_object_object_add(json_row,
991 "secondaryAddressList",
992 sec_list);
993 }
994
995 // PIM neighbors
996 if (pim_ifp->pim_neighbor_list->count) {
997 json_pim_neighbors = json_object_new_object();
998
999 for (ALL_LIST_ELEMENTS_RO(
1000 pim_ifp->pim_neighbor_list,
1001 neighnode, neigh)) {
1002 json_pim_neighbor =
1003 json_object_new_object();
1004 pim_inet4_dump("<src?>",
1005 neigh->source_addr,
1006 neigh_src_str,
1007 sizeof(neigh_src_str));
1008 pim_time_uptime(uptime, sizeof(uptime),
1009 now - neigh->creation);
1010 pim_time_timer_to_hhmmss(
1011 expire, sizeof(expire),
1012 neigh->t_expire_timer);
1013
1014 json_object_string_add(
1015 json_pim_neighbor, "address",
1016 neigh_src_str);
1017 json_object_string_add(
1018 json_pim_neighbor, "upTime",
1019 uptime);
1020 json_object_string_add(
1021 json_pim_neighbor, "holdtime",
1022 expire);
1023
1024 json_object_object_add(
1025 json_pim_neighbors,
1026 neigh_src_str,
1027 json_pim_neighbor);
1028 }
1029
1030 json_object_object_add(json_row, "neighbors",
1031 json_pim_neighbors);
1032 }
1033
1034 json_object_string_add(json_row, "drAddress", dr_str);
1035 json_object_int_add(json_row, "drPriority",
1036 pim_ifp->pim_dr_priority);
1037 json_object_string_add(json_row, "drUptime", dr_uptime);
1038 json_object_int_add(json_row, "drElections",
1039 pim_ifp->pim_dr_election_count);
1040 json_object_int_add(json_row, "drChanges",
1041 pim_ifp->pim_dr_election_changes);
1042
1043 // FHR
1044 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
1045 up)) {
1046 if (ifp != up->rpf.source_nexthop.interface)
1047 continue;
1048
1049 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1050 continue;
1051
1052 if (!json_fhr_sources)
1053 json_fhr_sources =
1054 json_object_new_object();
1055
1056 pim_inet4_dump("<src?>", up->sg.src, src_str,
1057 sizeof(src_str));
1058 pim_inet4_dump("<grp?>", up->sg.grp, grp_str,
1059 sizeof(grp_str));
1060 pim_time_uptime(uptime, sizeof(uptime),
1061 now - up->state_transition);
1062
1063 /*
1064 * Does this group live in json_fhr_sources?
1065 * If not create it.
1066 */
1067 json_object_object_get_ex(json_fhr_sources,
1068 grp_str, &json_group);
1069
1070 if (!json_group) {
1071 json_group = json_object_new_object();
1072 json_object_object_add(json_fhr_sources,
1073 grp_str,
1074 json_group);
1075 }
1076
1077 json_group_source = json_object_new_object();
1078 json_object_string_add(json_group_source,
1079 "source", src_str);
1080 json_object_string_add(json_group_source,
1081 "group", grp_str);
1082 json_object_string_add(json_group_source,
1083 "upTime", uptime);
1084 json_object_object_add(json_group, src_str,
1085 json_group_source);
1086 }
1087
1088 if (json_fhr_sources) {
1089 json_object_object_add(json_row,
1090 "firstHopRouter",
1091 json_fhr_sources);
1092 }
1093
1094 json_object_int_add(json_row, "helloPeriod",
1095 pim_ifp->pim_hello_period);
1096 json_object_string_add(json_row, "helloTimer",
1097 hello_timer);
1098 json_object_string_add(json_row, "helloStatStart",
1099 stat_uptime);
1100 json_object_int_add(json_row, "helloReceived",
1101 pim_ifp->pim_ifstat_hello_recv);
1102 json_object_int_add(json_row, "helloReceivedFailed",
1103 pim_ifp->pim_ifstat_hello_recvfail);
1104 json_object_int_add(json_row, "helloSend",
1105 pim_ifp->pim_ifstat_hello_sent);
1106 json_object_int_add(json_row, "hellosendFailed",
1107 pim_ifp->pim_ifstat_hello_sendfail);
1108 json_object_int_add(json_row, "helloGenerationId",
1109 pim_ifp->pim_generation_id);
1110 json_object_int_add(json_row, "flagMulticastLoop",
1111 mloop);
1112
1113 json_object_int_add(
1114 json_row, "effectivePropagationDelay",
1115 pim_if_effective_propagation_delay_msec(ifp));
1116 json_object_int_add(
1117 json_row, "effectiveOverrideInterval",
1118 pim_if_effective_override_interval_msec(ifp));
1119 json_object_int_add(
1120 json_row, "joinPruneOverrideInterval",
1121 pim_if_jp_override_interval_msec(ifp));
1122
1123 json_object_int_add(
1124 json_row, "propagationDelay",
1125 pim_ifp->pim_propagation_delay_msec);
1126 json_object_int_add(
1127 json_row, "propagationDelayHighest",
1128 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1129 json_object_int_add(
1130 json_row, "overrideInterval",
1131 pim_ifp->pim_override_interval_msec);
1132 json_object_int_add(
1133 json_row, "overrideIntervalHighest",
1134 pim_ifp->pim_neighbors_highest_override_interval_msec);
1135 json_object_object_add(json, ifp->name, json_row);
1136
1137 } else {
1138 vty_out(vty, "Interface : %s\n", ifp->name);
1139 vty_out(vty, "State : %s\n",
1140 if_is_up(ifp) ? "up" : "down");
1141 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
1142 vty_out(vty, "Use Source : %s\n",
1143 inet_ntoa(pim_ifp->update_source));
1144 }
1145 if (pim_ifp->sec_addr_list) {
1146 char pbuf[PREFIX2STR_BUFFER];
1147 vty_out(vty, "Address : %s (primary)\n",
1148 inet_ntoa(ifaddr));
1149 for (ALL_LIST_ELEMENTS_RO(
1150 pim_ifp->sec_addr_list, sec_node,
1151 sec_addr)) {
1152 vty_out(vty, " %s\n",
1153 prefix2str(&sec_addr->addr,
1154 pbuf, sizeof(pbuf)));
1155 }
1156 } else {
1157 vty_out(vty, "Address : %s\n",
1158 inet_ntoa(ifaddr));
1159 }
1160 vty_out(vty, "\n");
1161
1162 // PIM neighbors
1163 print_header = 1;
1164
1165 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
1166 neighnode, neigh)) {
1167
1168 if (print_header) {
1169 vty_out(vty, "PIM Neighbors\n");
1170 vty_out(vty, "-------------\n");
1171 print_header = 0;
1172 }
1173
1174 pim_inet4_dump("<src?>", neigh->source_addr,
1175 neigh_src_str,
1176 sizeof(neigh_src_str));
1177 pim_time_uptime(uptime, sizeof(uptime),
1178 now - neigh->creation);
1179 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1180 neigh->t_expire_timer);
1181 vty_out(vty,
1182 "%-15s : up for %s, holdtime expires in %s\n",
1183 neigh_src_str, uptime, expire);
1184 }
1185
1186 if (!print_header) {
1187 vty_out(vty, "\n");
1188 vty_out(vty, "\n");
1189 }
1190
1191 vty_out(vty, "Designated Router\n");
1192 vty_out(vty, "-----------------\n");
1193 vty_out(vty, "Address : %s\n", dr_str);
1194 vty_out(vty, "Priority : %u(%d)\n",
1195 pim_ifp->pim_dr_priority,
1196 pim_ifp->pim_dr_num_nondrpri_neighbors);
1197 vty_out(vty, "Uptime : %s\n", dr_uptime);
1198 vty_out(vty, "Elections : %d\n",
1199 pim_ifp->pim_dr_election_count);
1200 vty_out(vty, "Changes : %d\n",
1201 pim_ifp->pim_dr_election_changes);
1202 vty_out(vty, "\n");
1203 vty_out(vty, "\n");
1204
1205 // FHR
1206 print_header = 1;
1207 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
1208 up)) {
1209
1210 if (strcmp(ifp->name,
1211 up->rpf.source_nexthop
1212 .interface->name)
1213 != 0)
1214 continue;
1215
1216 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1217 continue;
1218
1219 if (print_header) {
1220 vty_out(vty,
1221 "FHR - First Hop Router\n");
1222 vty_out(vty,
1223 "----------------------\n");
1224 print_header = 0;
1225 }
1226
1227 pim_inet4_dump("<src?>", up->sg.src, src_str,
1228 sizeof(src_str));
1229 pim_inet4_dump("<grp?>", up->sg.grp, grp_str,
1230 sizeof(grp_str));
1231 pim_time_uptime(uptime, sizeof(uptime),
1232 now - up->state_transition);
1233 vty_out(vty,
1234 "%s : %s is a source, uptime is %s\n",
1235 grp_str, src_str, uptime);
1236 }
1237
1238 if (!print_header) {
1239 vty_out(vty, "\n");
1240 vty_out(vty, "\n");
1241 }
1242
1243 vty_out(vty, "Hellos\n");
1244 vty_out(vty, "------\n");
1245 vty_out(vty, "Period : %d\n",
1246 pim_ifp->pim_hello_period);
1247 vty_out(vty, "Timer : %s\n", hello_timer);
1248 vty_out(vty, "StatStart : %s\n", stat_uptime);
1249 vty_out(vty, "Receive : %d\n",
1250 pim_ifp->pim_ifstat_hello_recv);
1251 vty_out(vty, "Receive Failed : %d\n",
1252 pim_ifp->pim_ifstat_hello_recvfail);
1253 vty_out(vty, "Send : %d\n",
1254 pim_ifp->pim_ifstat_hello_sent);
1255 vty_out(vty, "Send Failed : %d\n",
1256 pim_ifp->pim_ifstat_hello_sendfail);
1257 vty_out(vty, "Generation ID : %08x\n",
1258 pim_ifp->pim_generation_id);
1259 vty_out(vty, "\n");
1260 vty_out(vty, "\n");
1261
1262 pim_print_ifp_flags(vty, ifp, mloop);
1263
1264 vty_out(vty, "Join Prune Interval\n");
1265 vty_out(vty, "-------------------\n");
1266 vty_out(vty, "LAN Delay : %s\n",
1267 pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
1268 vty_out(vty, "Effective Propagation Delay : %d msec\n",
1269 pim_if_effective_propagation_delay_msec(ifp));
1270 vty_out(vty, "Effective Override Interval : %d msec\n",
1271 pim_if_effective_override_interval_msec(ifp));
1272 vty_out(vty, "Join Prune Override Interval : %d msec\n",
1273 pim_if_jp_override_interval_msec(ifp));
1274 vty_out(vty, "\n");
1275 vty_out(vty, "\n");
1276
1277 vty_out(vty, "LAN Prune Delay\n");
1278 vty_out(vty, "---------------\n");
1279 vty_out(vty, "Propagation Delay : %d msec\n",
1280 pim_ifp->pim_propagation_delay_msec);
1281 vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
1282 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1283 vty_out(vty, "Override Interval : %d msec\n",
1284 pim_ifp->pim_override_interval_msec);
1285 vty_out(vty, "Override Interval (Highest) : %d msec\n",
1286 pim_ifp->pim_neighbors_highest_override_interval_msec);
1287 vty_out(vty, "\n");
1288 vty_out(vty, "\n");
1289 }
1290 }
1291
1292 if (uj) {
1293 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1294 json, JSON_C_TO_STRING_PRETTY));
1295 json_object_free(json);
1296 } else {
1297 if (!found_ifname)
1298 vty_out(vty, "%% No such interface\n");
1299 }
1300 }
1301
1302 static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
1303 const char *ifname, bool uj)
1304 {
1305 struct interface *ifp;
1306 struct igmp_stats rx_stats;
1307
1308 igmp_stats_init(&rx_stats);
1309
1310 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1311 struct pim_interface *pim_ifp;
1312 struct listnode *sock_node;
1313 struct igmp_sock *igmp;
1314
1315 pim_ifp = ifp->info;
1316
1317 if (!pim_ifp)
1318 continue;
1319
1320 if (ifname && strcmp(ifname, ifp->name))
1321 continue;
1322
1323 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
1324 igmp)) {
1325 igmp_stats_add(&rx_stats, &igmp->rx_stats);
1326 }
1327 }
1328 if (uj) {
1329 json_object *json = NULL;
1330 json_object *json_row = NULL;
1331
1332 json = json_object_new_object();
1333 json_row = json_object_new_object();
1334
1335 json_object_string_add(json_row, "name", ifname ? ifname :
1336 "global");
1337 json_object_int_add(json_row, "queryV1", rx_stats.query_v1);
1338 json_object_int_add(json_row, "queryV2", rx_stats.query_v2);
1339 json_object_int_add(json_row, "queryV3", rx_stats.query_v3);
1340 json_object_int_add(json_row, "leaveV3", rx_stats.leave_v2);
1341 json_object_int_add(json_row, "reportV1", rx_stats.report_v1);
1342 json_object_int_add(json_row, "reportV2", rx_stats.report_v2);
1343 json_object_int_add(json_row, "reportV3", rx_stats.report_v3);
1344 json_object_int_add(json_row, "mtraceResponse",
1345 rx_stats.mtrace_rsp);
1346 json_object_int_add(json_row, "mtraceRequest",
1347 rx_stats.mtrace_req);
1348 json_object_int_add(json_row, "unsupported",
1349 rx_stats.unsupported);
1350 json_object_object_add(json, ifname ? ifname : "global",
1351 json_row);
1352 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1353 json, JSON_C_TO_STRING_PRETTY));
1354 json_object_free(json);
1355 } else {
1356 vty_out(vty, "IGMP RX statistics\n");
1357 vty_out(vty, "Interface : %s\n",
1358 ifname ? ifname : "global");
1359 vty_out(vty, "V1 query : %u\n", rx_stats.query_v1);
1360 vty_out(vty, "V2 query : %u\n", rx_stats.query_v2);
1361 vty_out(vty, "V3 query : %u\n", rx_stats.query_v3);
1362 vty_out(vty, "V2 leave : %u\n", rx_stats.leave_v2);
1363 vty_out(vty, "V1 report : %u\n", rx_stats.report_v1);
1364 vty_out(vty, "V2 report : %u\n", rx_stats.report_v2);
1365 vty_out(vty, "V3 report : %u\n", rx_stats.report_v3);
1366 vty_out(vty, "mtrace response : %u\n", rx_stats.mtrace_rsp);
1367 vty_out(vty, "mtrace request : %u\n", rx_stats.mtrace_req);
1368 vty_out(vty, "unsupported : %u\n", rx_stats.unsupported);
1369 }
1370 }
1371
1372 static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
1373 bool uj)
1374 {
1375 struct interface *ifp;
1376 struct listnode *upnode;
1377 struct pim_interface *pim_ifp;
1378 struct pim_upstream *up;
1379 int fhr = 0;
1380 int pim_nbrs = 0;
1381 int pim_ifchannels = 0;
1382 json_object *json = NULL;
1383 json_object *json_row = NULL;
1384 json_object *json_tmp;
1385
1386 json = json_object_new_object();
1387
1388 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1389 pim_ifp = ifp->info;
1390
1391 if (!pim_ifp)
1392 continue;
1393
1394 pim_nbrs = pim_ifp->pim_neighbor_list->count;
1395 pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
1396 fhr = 0;
1397
1398 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up))
1399 if (ifp == up->rpf.source_nexthop.interface)
1400 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
1401 fhr++;
1402
1403 json_row = json_object_new_object();
1404 json_object_pim_ifp_add(json_row, ifp);
1405 json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
1406 json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
1407 json_object_int_add(json_row, "firstHopRouterCount", fhr);
1408 json_object_string_add(json_row, "pimDesignatedRouter",
1409 inet_ntoa(pim_ifp->pim_dr_addr));
1410
1411 if (pim_ifp->pim_dr_addr.s_addr
1412 == pim_ifp->primary_address.s_addr)
1413 json_object_boolean_true_add(
1414 json_row, "pimDesignatedRouterLocal");
1415
1416 json_object_object_add(json, ifp->name, json_row);
1417 }
1418
1419 if (uj) {
1420 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1421 json, JSON_C_TO_STRING_PRETTY));
1422 } else {
1423 vty_out(vty,
1424 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1425
1426 json_object_object_foreach(json, key, val)
1427 {
1428 vty_out(vty, "%-16s ", key);
1429
1430 json_object_object_get_ex(val, "state", &json_tmp);
1431 vty_out(vty, "%5s ", json_object_get_string(json_tmp));
1432
1433 json_object_object_get_ex(val, "address", &json_tmp);
1434 vty_out(vty, "%15s ",
1435 json_object_get_string(json_tmp));
1436
1437 json_object_object_get_ex(val, "pimNeighbors",
1438 &json_tmp);
1439 vty_out(vty, "%8d ", json_object_get_int(json_tmp));
1440
1441 if (json_object_object_get_ex(
1442 val, "pimDesignatedRouterLocal",
1443 &json_tmp)) {
1444 vty_out(vty, "%15s ", "local");
1445 } else {
1446 json_object_object_get_ex(
1447 val, "pimDesignatedRouter", &json_tmp);
1448 vty_out(vty, "%15s ",
1449 json_object_get_string(json_tmp));
1450 }
1451
1452 json_object_object_get_ex(val, "firstHopRouter",
1453 &json_tmp);
1454 vty_out(vty, "%3d ", json_object_get_int(json_tmp));
1455
1456 json_object_object_get_ex(val, "pimIfChannels",
1457 &json_tmp);
1458 vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
1459 }
1460 }
1461
1462 json_object_free(json);
1463 }
1464
1465 static void pim_show_interface_traffic(struct pim_instance *pim,
1466 struct vty *vty, bool uj)
1467 {
1468 struct interface *ifp = NULL;
1469 struct pim_interface *pim_ifp = NULL;
1470 json_object *json = NULL;
1471 json_object *json_row = NULL;
1472
1473 if (uj)
1474 json = json_object_new_object();
1475 else {
1476 vty_out(vty, "\n");
1477 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1478 "Interface", " HELLO", " JOIN",
1479 " PRUNE", " REGISTER", "REGISTER-STOP",
1480 " ASSERT");
1481 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1482 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1483 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1484 vty_out(vty,
1485 "---------------------------------------------------------------------------------------------------------------\n");
1486 }
1487
1488 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1489 pim_ifp = ifp->info;
1490
1491 if (!pim_ifp)
1492 continue;
1493
1494 if (pim_ifp->pim_sock_fd < 0)
1495 continue;
1496 if (uj) {
1497 json_row = json_object_new_object();
1498 json_object_pim_ifp_add(json_row, ifp);
1499 json_object_int_add(json_row, "helloRx",
1500 pim_ifp->pim_ifstat_hello_recv);
1501 json_object_int_add(json_row, "helloTx",
1502 pim_ifp->pim_ifstat_hello_sent);
1503 json_object_int_add(json_row, "joinRx",
1504 pim_ifp->pim_ifstat_join_recv);
1505 json_object_int_add(json_row, "joinTx",
1506 pim_ifp->pim_ifstat_join_send);
1507 json_object_int_add(json_row, "registerRx",
1508 pim_ifp->pim_ifstat_reg_recv);
1509 json_object_int_add(json_row, "registerTx",
1510 pim_ifp->pim_ifstat_reg_recv);
1511 json_object_int_add(json_row, "registerStopRx",
1512 pim_ifp->pim_ifstat_reg_stop_recv);
1513 json_object_int_add(json_row, "registerStopTx",
1514 pim_ifp->pim_ifstat_reg_stop_send);
1515 json_object_int_add(json_row, "assertRx",
1516 pim_ifp->pim_ifstat_assert_recv);
1517 json_object_int_add(json_row, "assertTx",
1518 pim_ifp->pim_ifstat_assert_send);
1519
1520 json_object_object_add(json, ifp->name, json_row);
1521 } else {
1522 vty_out(vty,
1523 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1524 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1525 pim_ifp->pim_ifstat_hello_sent,
1526 pim_ifp->pim_ifstat_join_recv,
1527 pim_ifp->pim_ifstat_join_send,
1528 pim_ifp->pim_ifstat_prune_recv,
1529 pim_ifp->pim_ifstat_prune_send,
1530 pim_ifp->pim_ifstat_reg_recv,
1531 pim_ifp->pim_ifstat_reg_send,
1532 pim_ifp->pim_ifstat_reg_stop_recv,
1533 pim_ifp->pim_ifstat_reg_stop_send,
1534 pim_ifp->pim_ifstat_assert_recv,
1535 pim_ifp->pim_ifstat_assert_send);
1536 }
1537 }
1538 if (uj) {
1539 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1540 json, JSON_C_TO_STRING_PRETTY));
1541 json_object_free(json);
1542 }
1543 }
1544
1545 static void pim_show_interface_traffic_single(struct pim_instance *pim,
1546 struct vty *vty,
1547 const char *ifname, bool uj)
1548 {
1549 struct interface *ifp = NULL;
1550 struct pim_interface *pim_ifp = NULL;
1551 json_object *json = NULL;
1552 json_object *json_row = NULL;
1553 uint8_t found_ifname = 0;
1554
1555 if (uj)
1556 json = json_object_new_object();
1557 else {
1558 vty_out(vty, "\n");
1559 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1560 "Interface", " HELLO", " JOIN", " PRUNE",
1561 " REGISTER", " REGISTER-STOP", " ASSERT");
1562 vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
1563 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1564 " Rx/Tx", " Rx/Tx");
1565 vty_out(vty,
1566 "---------------------------------------------------------------------------------------------------------------------\n");
1567 }
1568
1569 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1570 if (strcmp(ifname, ifp->name))
1571 continue;
1572
1573 pim_ifp = ifp->info;
1574
1575 if (!pim_ifp)
1576 continue;
1577
1578 if (pim_ifp->pim_sock_fd < 0)
1579 continue;
1580
1581 found_ifname = 1;
1582 if (uj) {
1583 json_row = json_object_new_object();
1584 json_object_pim_ifp_add(json_row, ifp);
1585 json_object_int_add(json_row, "helloRx",
1586 pim_ifp->pim_ifstat_hello_recv);
1587 json_object_int_add(json_row, "helloTx",
1588 pim_ifp->pim_ifstat_hello_sent);
1589 json_object_int_add(json_row, "joinRx",
1590 pim_ifp->pim_ifstat_join_recv);
1591 json_object_int_add(json_row, "joinTx",
1592 pim_ifp->pim_ifstat_join_send);
1593 json_object_int_add(json_row, "registerRx",
1594 pim_ifp->pim_ifstat_reg_recv);
1595 json_object_int_add(json_row, "registerTx",
1596 pim_ifp->pim_ifstat_reg_recv);
1597 json_object_int_add(json_row, "registerStopRx",
1598 pim_ifp->pim_ifstat_reg_stop_recv);
1599 json_object_int_add(json_row, "registerStopTx",
1600 pim_ifp->pim_ifstat_reg_stop_send);
1601 json_object_int_add(json_row, "assertRx",
1602 pim_ifp->pim_ifstat_assert_recv);
1603 json_object_int_add(json_row, "assertTx",
1604 pim_ifp->pim_ifstat_assert_send);
1605
1606 json_object_object_add(json, ifp->name, json_row);
1607 } else {
1608 vty_out(vty,
1609 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
1610 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1611 pim_ifp->pim_ifstat_hello_sent,
1612 pim_ifp->pim_ifstat_join_recv,
1613 pim_ifp->pim_ifstat_join_send,
1614 pim_ifp->pim_ifstat_prune_recv,
1615 pim_ifp->pim_ifstat_prune_send,
1616 pim_ifp->pim_ifstat_reg_recv,
1617 pim_ifp->pim_ifstat_reg_send,
1618 pim_ifp->pim_ifstat_reg_stop_recv,
1619 pim_ifp->pim_ifstat_reg_stop_send,
1620 pim_ifp->pim_ifstat_assert_recv,
1621 pim_ifp->pim_ifstat_assert_send);
1622 }
1623 }
1624 if (uj) {
1625 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1626 json, JSON_C_TO_STRING_PRETTY));
1627 json_object_free(json);
1628 } else {
1629 if (!found_ifname)
1630 vty_out(vty, "%% No such interface\n");
1631 }
1632 }
1633
1634 static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
1635 struct pim_ifchannel *ch, json_object *json,
1636 time_t now, bool uj)
1637 {
1638 char ch_src_str[INET_ADDRSTRLEN];
1639 char ch_grp_str[INET_ADDRSTRLEN];
1640 json_object *json_iface = NULL;
1641 json_object *json_row = NULL;
1642 json_object *json_grp = NULL;
1643 struct in_addr ifaddr;
1644 char uptime[10];
1645 char expire[10];
1646 char prune[10];
1647
1648 ifaddr = pim_ifp->primary_address;
1649
1650 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
1651 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
1652
1653 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
1654 pim_time_timer_to_mmss(expire, sizeof(expire),
1655 ch->t_ifjoin_expiry_timer);
1656 pim_time_timer_to_mmss(prune, sizeof(prune),
1657 ch->t_ifjoin_prune_pending_timer);
1658
1659 if (uj) {
1660 json_object_object_get_ex(json, ch->interface->name,
1661 &json_iface);
1662
1663 if (!json_iface) {
1664 json_iface = json_object_new_object();
1665 json_object_pim_ifp_add(json_iface, ch->interface);
1666 json_object_object_add(json, ch->interface->name,
1667 json_iface);
1668 }
1669
1670 json_row = json_object_new_object();
1671 json_object_string_add(json_row, "source", ch_src_str);
1672 json_object_string_add(json_row, "group", ch_grp_str);
1673 json_object_string_add(json_row, "upTime", uptime);
1674 json_object_string_add(json_row, "expire", expire);
1675 json_object_string_add(json_row, "prune", prune);
1676 json_object_string_add(
1677 json_row, "channelJoinName",
1678 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
1679 if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
1680 json_object_int_add(json_row, "SGRpt", 1);
1681
1682 json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
1683 if (!json_grp) {
1684 json_grp = json_object_new_object();
1685 json_object_object_add(json_grp, ch_src_str, json_row);
1686 json_object_object_add(json_iface, ch_grp_str,
1687 json_grp);
1688 } else
1689 json_object_object_add(json_grp, ch_src_str, json_row);
1690 } else {
1691 vty_out(vty, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1692 ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
1693 ch_grp_str,
1694 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
1695 uptime, expire, prune);
1696 }
1697 }
1698
1699 static void pim_show_join(struct pim_instance *pim, struct vty *vty, bool uj)
1700 {
1701 struct pim_interface *pim_ifp;
1702 struct pim_ifchannel *ch;
1703 struct interface *ifp;
1704 time_t now;
1705 json_object *json = NULL;
1706
1707 now = pim_time_monotonic_sec();
1708
1709 if (uj)
1710 json = json_object_new_object();
1711 else
1712 vty_out(vty,
1713 "Interface Address Source Group State Uptime Expire Prune\n");
1714
1715 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1716 pim_ifp = ifp->info;
1717 if (!pim_ifp)
1718 continue;
1719
1720 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1721 pim_show_join_helper(vty, pim_ifp, ch, json, now, uj);
1722 } /* scan interface channels */
1723 }
1724
1725 if (uj) {
1726 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1727 json, JSON_C_TO_STRING_PRETTY));
1728 json_object_free(json);
1729 }
1730 }
1731
1732 static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
1733 const char *neighbor, bool uj)
1734 {
1735 struct listnode *neighnode;
1736 struct interface *ifp;
1737 struct pim_interface *pim_ifp;
1738 struct pim_neighbor *neigh;
1739 time_t now;
1740 int found_neighbor = 0;
1741 int option_address_list;
1742 int option_dr_priority;
1743 int option_generation_id;
1744 int option_holdtime;
1745 int option_lan_prune_delay;
1746 int option_t_bit;
1747 char uptime[10];
1748 char expire[10];
1749 char neigh_src_str[INET_ADDRSTRLEN];
1750
1751 json_object *json = NULL;
1752 json_object *json_ifp = NULL;
1753 json_object *json_row = NULL;
1754
1755 now = pim_time_monotonic_sec();
1756
1757 if (uj)
1758 json = json_object_new_object();
1759
1760 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1761 pim_ifp = ifp->info;
1762
1763 if (!pim_ifp)
1764 continue;
1765
1766 if (pim_ifp->pim_sock_fd < 0)
1767 continue;
1768
1769 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
1770 neigh)) {
1771 pim_inet4_dump("<src?>", neigh->source_addr,
1772 neigh_src_str, sizeof(neigh_src_str));
1773
1774 /*
1775 * The user can specify either the interface name or the
1776 * PIM neighbor IP.
1777 * If this pim_ifp matches neither then skip.
1778 */
1779 if (strcmp(neighbor, "detail")
1780 && strcmp(neighbor, ifp->name)
1781 && strcmp(neighbor, neigh_src_str))
1782 continue;
1783
1784 found_neighbor = 1;
1785 pim_time_uptime(uptime, sizeof(uptime),
1786 now - neigh->creation);
1787 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1788 neigh->t_expire_timer);
1789
1790 option_address_list = 0;
1791 option_dr_priority = 0;
1792 option_generation_id = 0;
1793 option_holdtime = 0;
1794 option_lan_prune_delay = 0;
1795 option_t_bit = 0;
1796
1797 if (PIM_OPTION_IS_SET(neigh->hello_options,
1798 PIM_OPTION_MASK_ADDRESS_LIST))
1799 option_address_list = 1;
1800
1801 if (PIM_OPTION_IS_SET(neigh->hello_options,
1802 PIM_OPTION_MASK_DR_PRIORITY))
1803 option_dr_priority = 1;
1804
1805 if (PIM_OPTION_IS_SET(neigh->hello_options,
1806 PIM_OPTION_MASK_GENERATION_ID))
1807 option_generation_id = 1;
1808
1809 if (PIM_OPTION_IS_SET(neigh->hello_options,
1810 PIM_OPTION_MASK_HOLDTIME))
1811 option_holdtime = 1;
1812
1813 if (PIM_OPTION_IS_SET(neigh->hello_options,
1814 PIM_OPTION_MASK_LAN_PRUNE_DELAY))
1815 option_lan_prune_delay = 1;
1816
1817 if (PIM_OPTION_IS_SET(
1818 neigh->hello_options,
1819 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
1820 option_t_bit = 1;
1821
1822 if (uj) {
1823
1824 /* Does this ifp live in json? If not create
1825 * it. */
1826 json_object_object_get_ex(json, ifp->name,
1827 &json_ifp);
1828
1829 if (!json_ifp) {
1830 json_ifp = json_object_new_object();
1831 json_object_pim_ifp_add(json_ifp, ifp);
1832 json_object_object_add(json, ifp->name,
1833 json_ifp);
1834 }
1835
1836 json_row = json_object_new_object();
1837 json_object_string_add(json_row, "interface",
1838 ifp->name);
1839 json_object_string_add(json_row, "address",
1840 neigh_src_str);
1841 json_object_string_add(json_row, "upTime",
1842 uptime);
1843 json_object_string_add(json_row, "holdtime",
1844 expire);
1845 json_object_int_add(json_row, "drPriority",
1846 neigh->dr_priority);
1847 json_object_int_add(json_row, "generationId",
1848 neigh->generation_id);
1849
1850 if (option_address_list)
1851 json_object_boolean_true_add(
1852 json_row,
1853 "helloOptionAddressList");
1854
1855 if (option_dr_priority)
1856 json_object_boolean_true_add(
1857 json_row,
1858 "helloOptionDrPriority");
1859
1860 if (option_generation_id)
1861 json_object_boolean_true_add(
1862 json_row,
1863 "helloOptionGenerationId");
1864
1865 if (option_holdtime)
1866 json_object_boolean_true_add(
1867 json_row,
1868 "helloOptionHoldtime");
1869
1870 if (option_lan_prune_delay)
1871 json_object_boolean_true_add(
1872 json_row,
1873 "helloOptionLanPruneDelay");
1874
1875 if (option_t_bit)
1876 json_object_boolean_true_add(
1877 json_row, "helloOptionTBit");
1878
1879 json_object_object_add(json_ifp, neigh_src_str,
1880 json_row);
1881
1882 } else {
1883 vty_out(vty, "Interface : %s\n", ifp->name);
1884 vty_out(vty, "Neighbor : %s\n", neigh_src_str);
1885 vty_out(vty,
1886 " Uptime : %s\n",
1887 uptime);
1888 vty_out(vty,
1889 " Holdtime : %s\n",
1890 expire);
1891 vty_out(vty,
1892 " DR Priority : %d\n",
1893 neigh->dr_priority);
1894 vty_out(vty,
1895 " Generation ID : %08x\n",
1896 neigh->generation_id);
1897 vty_out(vty,
1898 " Override Interval (msec) : %d\n",
1899 neigh->override_interval_msec);
1900 vty_out(vty,
1901 " Propagation Delay (msec) : %d\n",
1902 neigh->propagation_delay_msec);
1903 vty_out(vty,
1904 " Hello Option - Address List : %s\n",
1905 option_address_list ? "yes" : "no");
1906 vty_out(vty,
1907 " Hello Option - DR Priority : %s\n",
1908 option_dr_priority ? "yes" : "no");
1909 vty_out(vty,
1910 " Hello Option - Generation ID : %s\n",
1911 option_generation_id ? "yes" : "no");
1912 vty_out(vty,
1913 " Hello Option - Holdtime : %s\n",
1914 option_holdtime ? "yes" : "no");
1915 vty_out(vty,
1916 " Hello Option - LAN Prune Delay : %s\n",
1917 option_lan_prune_delay ? "yes" : "no");
1918 vty_out(vty,
1919 " Hello Option - T-bit : %s\n",
1920 option_t_bit ? "yes" : "no");
1921 pim_bfd_show_info(vty, neigh->bfd_info,
1922 json_ifp, uj, 0);
1923 vty_out(vty, "\n");
1924 }
1925 }
1926 }
1927
1928 if (uj) {
1929 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1930 json, JSON_C_TO_STRING_PRETTY));
1931 json_object_free(json);
1932 } else {
1933 {
1934 if (!found_neighbor)
1935 vty_out(vty,
1936 "%% No such interface or neighbor\n");
1937 }
1938 }
1939 }
1940
1941 static void pim_show_state(struct pim_instance *pim, struct vty *vty,
1942 const char *src_or_group, const char *group, bool uj)
1943 {
1944 struct channel_oil *c_oil;
1945 struct listnode *node;
1946 json_object *json = NULL;
1947 json_object *json_group = NULL;
1948 json_object *json_ifp_in = NULL;
1949 json_object *json_ifp_out = NULL;
1950 json_object *json_source = NULL;
1951 time_t now;
1952 int first_oif;
1953 now = pim_time_monotonic_sec();
1954
1955 if (uj) {
1956 json = json_object_new_object();
1957 } else {
1958 vty_out(vty,
1959 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
1960 vty_out(vty,
1961 "\nInstalled Source Group IIF OIL\n");
1962 }
1963
1964 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
1965 char grp_str[INET_ADDRSTRLEN];
1966 char src_str[INET_ADDRSTRLEN];
1967 char in_ifname[INTERFACE_NAMSIZ + 1];
1968 char out_ifname[INTERFACE_NAMSIZ + 1];
1969 int oif_vif_index;
1970 struct interface *ifp_in;
1971 first_oif = 1;
1972
1973 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
1974 sizeof(grp_str));
1975 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
1976 sizeof(src_str));
1977 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
1978
1979 if (ifp_in)
1980 strcpy(in_ifname, ifp_in->name);
1981 else
1982 strcpy(in_ifname, "<iif?>");
1983
1984 if (src_or_group) {
1985 if (strcmp(src_or_group, src_str)
1986 && strcmp(src_or_group, grp_str))
1987 continue;
1988
1989 if (group && strcmp(group, grp_str))
1990 continue;
1991 }
1992
1993 if (uj) {
1994
1995 /* Find the group, create it if it doesn't exist */
1996 json_object_object_get_ex(json, grp_str, &json_group);
1997
1998 if (!json_group) {
1999 json_group = json_object_new_object();
2000 json_object_object_add(json, grp_str,
2001 json_group);
2002 }
2003
2004 /* Find the source nested under the group, create it if
2005 * it doesn't exist */
2006 json_object_object_get_ex(json_group, src_str,
2007 &json_source);
2008
2009 if (!json_source) {
2010 json_source = json_object_new_object();
2011 json_object_object_add(json_group, src_str,
2012 json_source);
2013 }
2014
2015 /* Find the inbound interface nested under the source,
2016 * create it if it doesn't exist */
2017 json_object_object_get_ex(json_source, in_ifname,
2018 &json_ifp_in);
2019
2020 if (!json_ifp_in) {
2021 json_ifp_in = json_object_new_object();
2022 json_object_object_add(json_source, in_ifname,
2023 json_ifp_in);
2024 json_object_int_add(json_source, "Installed",
2025 c_oil->installed);
2026 json_object_int_add(json_source, "RefCount",
2027 c_oil->oil_ref_count);
2028 json_object_int_add(json_source, "OilListSize",
2029 c_oil->oil_size);
2030 json_object_int_add(
2031 json_source, "OilRescan",
2032 c_oil->oil_inherited_rescan);
2033 json_object_int_add(json_source, "LastUsed",
2034 c_oil->cc.lastused);
2035 json_object_int_add(json_source, "PacketCount",
2036 c_oil->cc.pktcnt);
2037 json_object_int_add(json_source, "ByteCount",
2038 c_oil->cc.bytecnt);
2039 json_object_int_add(json_source,
2040 "WrongInterface",
2041 c_oil->cc.wrong_if);
2042 }
2043 } else {
2044 vty_out(vty, "%-9d %-15s %-15s %-16s ",
2045 c_oil->installed, src_str, grp_str, in_ifname);
2046 }
2047
2048 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
2049 ++oif_vif_index) {
2050 struct interface *ifp_out;
2051 char oif_uptime[10];
2052 int ttl;
2053
2054 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2055 if (ttl < 1)
2056 continue;
2057
2058 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
2059 pim_time_uptime(
2060 oif_uptime, sizeof(oif_uptime),
2061 now - c_oil->oif_creation[oif_vif_index]);
2062
2063 if (ifp_out)
2064 strcpy(out_ifname, ifp_out->name);
2065 else
2066 strcpy(out_ifname, "<oif?>");
2067
2068 if (uj) {
2069 json_ifp_out = json_object_new_object();
2070 json_object_string_add(json_ifp_out, "source",
2071 src_str);
2072 json_object_string_add(json_ifp_out, "group",
2073 grp_str);
2074 json_object_string_add(json_ifp_out,
2075 "inboundInterface",
2076 in_ifname);
2077 json_object_string_add(json_ifp_out,
2078 "outboundInterface",
2079 out_ifname);
2080 json_object_int_add(json_ifp_out, "installed",
2081 c_oil->installed);
2082
2083 json_object_object_add(json_ifp_in, out_ifname,
2084 json_ifp_out);
2085 } else {
2086 if (first_oif) {
2087 first_oif = 0;
2088 vty_out(vty, "%s(%c%c%c%c)", out_ifname,
2089 (c_oil->oif_flags[oif_vif_index]
2090 & PIM_OIF_FLAG_PROTO_IGMP)
2091 ? 'I'
2092 : ' ',
2093 (c_oil->oif_flags[oif_vif_index]
2094 & PIM_OIF_FLAG_PROTO_PIM)
2095 ? 'J'
2096 : ' ',
2097 (c_oil->oif_flags[oif_vif_index]
2098 & PIM_OIF_FLAG_PROTO_SOURCE)
2099 ? 'S'
2100 : ' ',
2101 (c_oil->oif_flags[oif_vif_index]
2102 & PIM_OIF_FLAG_PROTO_STAR)
2103 ? '*'
2104 : ' ');
2105 } else
2106 vty_out(vty, ", %s(%c%c%c%c)",
2107 out_ifname,
2108 (c_oil->oif_flags[oif_vif_index]
2109 & PIM_OIF_FLAG_PROTO_IGMP)
2110 ? 'I'
2111 : ' ',
2112 (c_oil->oif_flags[oif_vif_index]
2113 & PIM_OIF_FLAG_PROTO_PIM)
2114 ? 'J'
2115 : ' ',
2116 (c_oil->oif_flags[oif_vif_index]
2117 & PIM_OIF_FLAG_PROTO_SOURCE)
2118 ? 'S'
2119 : ' ',
2120 (c_oil->oif_flags[oif_vif_index]
2121 & PIM_OIF_FLAG_PROTO_STAR)
2122 ? '*'
2123 : ' ');
2124 }
2125 }
2126
2127 if (!uj)
2128 vty_out(vty, "\n");
2129 }
2130
2131
2132 if (uj) {
2133 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2134 json, JSON_C_TO_STRING_PRETTY));
2135 json_object_free(json);
2136 } else {
2137 vty_out(vty, "\n");
2138 }
2139 }
2140
2141 static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
2142 bool uj)
2143 {
2144 struct listnode *neighnode;
2145 struct interface *ifp;
2146 struct pim_interface *pim_ifp;
2147 struct pim_neighbor *neigh;
2148 time_t now;
2149 char uptime[10];
2150 char expire[10];
2151 char neigh_src_str[INET_ADDRSTRLEN];
2152 json_object *json = NULL;
2153 json_object *json_ifp_rows = NULL;
2154 json_object *json_row = NULL;
2155
2156 now = pim_time_monotonic_sec();
2157
2158 if (uj) {
2159 json = json_object_new_object();
2160 } else {
2161 vty_out(vty,
2162 "Interface Neighbor Uptime Holdtime DR Pri\n");
2163 }
2164
2165 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2166 pim_ifp = ifp->info;
2167
2168 if (!pim_ifp)
2169 continue;
2170
2171 if (pim_ifp->pim_sock_fd < 0)
2172 continue;
2173
2174 if (uj)
2175 json_ifp_rows = json_object_new_object();
2176
2177 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2178 neigh)) {
2179 pim_inet4_dump("<src?>", neigh->source_addr,
2180 neigh_src_str, sizeof(neigh_src_str));
2181 pim_time_uptime(uptime, sizeof(uptime),
2182 now - neigh->creation);
2183 pim_time_timer_to_hhmmss(expire, sizeof(expire),
2184 neigh->t_expire_timer);
2185
2186 if (uj) {
2187 json_row = json_object_new_object();
2188 json_object_string_add(json_row, "interface",
2189 ifp->name);
2190 json_object_string_add(json_row, "neighbor",
2191 neigh_src_str);
2192 json_object_string_add(json_row, "upTime",
2193 uptime);
2194 json_object_string_add(json_row, "holdTime",
2195 expire);
2196 json_object_int_add(json_row, "holdTimeMax",
2197 neigh->holdtime);
2198 json_object_int_add(json_row, "drPriority",
2199 neigh->dr_priority);
2200 json_object_object_add(json_ifp_rows,
2201 neigh_src_str, json_row);
2202
2203 } else {
2204 vty_out(vty, "%-16s %15s %8s %8s %6d\n",
2205 ifp->name, neigh_src_str, uptime,
2206 expire, neigh->dr_priority);
2207 }
2208 }
2209
2210 if (uj) {
2211 json_object_object_add(json, ifp->name, json_ifp_rows);
2212 json_ifp_rows = NULL;
2213 }
2214 }
2215
2216 if (uj) {
2217 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2218 json, JSON_C_TO_STRING_PRETTY));
2219 json_object_free(json);
2220 }
2221 }
2222
2223 static void pim_show_neighbors_secondary(struct pim_instance *pim,
2224 struct vty *vty)
2225 {
2226 struct interface *ifp;
2227
2228 vty_out(vty,
2229 "Interface Address Neighbor Secondary \n");
2230
2231 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2232 struct pim_interface *pim_ifp;
2233 struct in_addr ifaddr;
2234 struct listnode *neighnode;
2235 struct pim_neighbor *neigh;
2236
2237 pim_ifp = ifp->info;
2238
2239 if (!pim_ifp)
2240 continue;
2241
2242 if (pim_ifp->pim_sock_fd < 0)
2243 continue;
2244
2245 ifaddr = pim_ifp->primary_address;
2246
2247 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2248 neigh)) {
2249 char neigh_src_str[INET_ADDRSTRLEN];
2250 struct listnode *prefix_node;
2251 struct prefix *p;
2252
2253 if (!neigh->prefix_list)
2254 continue;
2255
2256 pim_inet4_dump("<src?>", neigh->source_addr,
2257 neigh_src_str, sizeof(neigh_src_str));
2258
2259 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
2260 prefix_node, p)) {
2261 char neigh_sec_str[PREFIX2STR_BUFFER];
2262
2263 prefix2str(p, neigh_sec_str,
2264 sizeof(neigh_sec_str));
2265
2266 vty_out(vty, "%-16s %-15s %-15s %-15s\n",
2267 ifp->name, inet_ntoa(ifaddr),
2268 neigh_src_str, neigh_sec_str);
2269 }
2270 }
2271 }
2272 }
2273
2274 static void json_object_pim_upstream_add(json_object *json,
2275 struct pim_upstream *up)
2276 {
2277 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
2278 json_object_boolean_true_add(json, "drJoinDesired");
2279
2280 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
2281 json_object_boolean_true_add(json, "drJoinDesiredUpdated");
2282
2283 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
2284 json_object_boolean_true_add(json, "firstHopRouter");
2285
2286 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
2287 json_object_boolean_true_add(json, "sourceIgmp");
2288
2289 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
2290 json_object_boolean_true_add(json, "sourcePim");
2291
2292 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
2293 json_object_boolean_true_add(json, "sourceStream");
2294
2295 /* XXX: need to print ths flag in the plain text display as well */
2296 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
2297 json_object_boolean_true_add(json, "sourceMsdp");
2298 }
2299
2300 static const char *
2301 pim_upstream_state2brief_str(enum pim_upstream_state join_state,
2302 char *state_str)
2303 {
2304 switch (join_state) {
2305 case PIM_UPSTREAM_NOTJOINED:
2306 strcpy(state_str, "NotJ");
2307 break;
2308 case PIM_UPSTREAM_JOINED:
2309 strcpy(state_str, "J");
2310 break;
2311 default:
2312 strcpy(state_str, "Unk");
2313 }
2314 return state_str;
2315 }
2316
2317 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
2318 char *state_str)
2319 {
2320 switch (reg_state) {
2321 case PIM_REG_NOINFO:
2322 strcpy(state_str, "RegNI");
2323 break;
2324 case PIM_REG_JOIN:
2325 strcpy(state_str, "RegJ");
2326 break;
2327 case PIM_REG_JOIN_PENDING:
2328 case PIM_REG_PRUNE:
2329 strcpy(state_str, "RegP");
2330 break;
2331 default:
2332 strcpy(state_str, "Unk");
2333 }
2334 return state_str;
2335 }
2336
2337 static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
2338 struct prefix_sg *sg, bool uj)
2339 {
2340 struct listnode *upnode;
2341 struct pim_upstream *up;
2342 time_t now;
2343 json_object *json = NULL;
2344 json_object *json_group = NULL;
2345 json_object *json_row = NULL;
2346
2347 now = pim_time_monotonic_sec();
2348
2349 if (uj)
2350 json = json_object_new_object();
2351 else
2352 vty_out(vty,
2353 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2354
2355 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
2356 char src_str[INET_ADDRSTRLEN];
2357 char grp_str[INET_ADDRSTRLEN];
2358 char uptime[10];
2359 char join_timer[10];
2360 char rs_timer[10];
2361 char ka_timer[10];
2362 char msdp_reg_timer[10];
2363 char state_str[PIM_REG_STATE_STR_LEN];
2364
2365 if (sg->grp.s_addr != 0 && sg->grp.s_addr != up->sg.grp.s_addr)
2366 continue;
2367 if (sg->src.s_addr != 0 && sg->src.s_addr != up->sg.src.s_addr)
2368 continue;
2369
2370 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2371 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2372 pim_time_uptime(uptime, sizeof(uptime),
2373 now - up->state_transition);
2374 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
2375 up->t_join_timer);
2376
2377 /*
2378 * If the upstream is not dummy and it has a J/P timer for the
2379 * neighbor display that
2380 */
2381 if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
2382 struct pim_neighbor *nbr;
2383
2384 nbr = pim_neighbor_find(
2385 up->rpf.source_nexthop.interface,
2386 up->rpf.rpf_addr.u.prefix4);
2387 if (nbr)
2388 pim_time_timer_to_hhmmss(join_timer,
2389 sizeof(join_timer),
2390 nbr->jp_timer);
2391 }
2392
2393 pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
2394 up->t_rs_timer);
2395 pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
2396 up->t_ka_timer);
2397 pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
2398 up->t_msdp_reg_timer);
2399
2400 pim_upstream_state2brief_str(up->join_state, state_str);
2401 if (up->reg_state != PIM_REG_NOINFO) {
2402 char tmp_str[PIM_REG_STATE_STR_LEN];
2403
2404 sprintf(state_str + strlen(state_str), ",%s",
2405 pim_reg_state2brief_str(up->reg_state,
2406 tmp_str));
2407 }
2408
2409 if (uj) {
2410 json_object_object_get_ex(json, grp_str, &json_group);
2411
2412 if (!json_group) {
2413 json_group = json_object_new_object();
2414 json_object_object_add(json, grp_str,
2415 json_group);
2416 }
2417
2418 json_row = json_object_new_object();
2419 json_object_pim_upstream_add(json_row, up);
2420 json_object_string_add(
2421 json_row, "inboundInterface",
2422 up->rpf.source_nexthop.interface
2423 ? up->rpf.source_nexthop.interface->name
2424 : "Unknown");
2425
2426 /*
2427 * The RPF address we use is slightly different
2428 * based upon what we are looking up.
2429 * If we have a S, list that unless
2430 * we are the FHR, else we just put
2431 * the RP as the rpfAddress
2432 */
2433 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR
2434 || up->sg.src.s_addr == INADDR_ANY) {
2435 char rpf[PREFIX_STRLEN];
2436 struct pim_rpf *rpg;
2437
2438 rpg = RP(pim, up->sg.grp);
2439 pim_inet4_dump("<rpf?>",
2440 rpg->rpf_addr.u.prefix4, rpf,
2441 sizeof(rpf));
2442 json_object_string_add(json_row, "rpfAddress",
2443 rpf);
2444 } else {
2445 json_object_string_add(json_row, "rpfAddress",
2446 src_str);
2447 }
2448
2449 json_object_string_add(json_row, "source", src_str);
2450 json_object_string_add(json_row, "group", grp_str);
2451 json_object_string_add(json_row, "state", state_str);
2452 json_object_string_add(
2453 json_row, "joinState",
2454 pim_upstream_state2str(up->join_state));
2455 json_object_string_add(
2456 json_row, "regState",
2457 pim_reg_state2str(up->reg_state, state_str));
2458 json_object_string_add(json_row, "upTime", uptime);
2459 json_object_string_add(json_row, "joinTimer",
2460 join_timer);
2461 json_object_string_add(json_row, "resetTimer",
2462 rs_timer);
2463 json_object_string_add(json_row, "keepaliveTimer",
2464 ka_timer);
2465 json_object_string_add(json_row, "msdpRegTimer",
2466 msdp_reg_timer);
2467 json_object_int_add(json_row, "refCount",
2468 up->ref_count);
2469 json_object_int_add(json_row, "sptBit", up->sptbit);
2470 json_object_object_add(json_group, src_str, json_row);
2471 } else {
2472 vty_out(vty,
2473 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2474 up->rpf.source_nexthop.interface
2475 ? up->rpf.source_nexthop.interface->name
2476 : "Unknown",
2477 src_str, grp_str, state_str, uptime, join_timer,
2478 rs_timer, ka_timer, up->ref_count);
2479 }
2480 }
2481
2482 if (uj) {
2483 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2484 json, JSON_C_TO_STRING_PRETTY));
2485 json_object_free(json);
2486 }
2487 }
2488
2489 static void pim_show_join_desired_helper(struct pim_instance *pim,
2490 struct vty *vty,
2491 struct pim_interface *pim_ifp,
2492 struct pim_ifchannel *ch,
2493 json_object *json, bool uj)
2494 {
2495 struct pim_upstream *up = ch->upstream;
2496 json_object *json_group = NULL;
2497 char src_str[INET_ADDRSTRLEN];
2498 char grp_str[INET_ADDRSTRLEN];
2499 json_object *json_row = NULL;
2500
2501 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2502 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2503
2504 if (uj) {
2505 json_object_object_get_ex(json, grp_str, &json_group);
2506
2507 if (!json_group) {
2508 json_group = json_object_new_object();
2509 json_object_object_add(json, grp_str, json_group);
2510 }
2511
2512 json_row = json_object_new_object();
2513 json_object_pim_upstream_add(json_row, up);
2514 json_object_string_add(json_row, "interface",
2515 ch->interface->name);
2516 json_object_string_add(json_row, "source", src_str);
2517 json_object_string_add(json_row, "group", grp_str);
2518
2519 if (pim_macro_ch_lost_assert(ch))
2520 json_object_boolean_true_add(json_row, "lostAssert");
2521
2522 if (pim_macro_chisin_joins(ch))
2523 json_object_boolean_true_add(json_row, "joins");
2524
2525 if (pim_macro_chisin_pim_include(ch))
2526 json_object_boolean_true_add(json_row, "pimInclude");
2527
2528 if (pim_upstream_evaluate_join_desired(pim, up))
2529 json_object_boolean_true_add(json_row,
2530 "evaluateJoinDesired");
2531
2532 json_object_object_add(json_group, src_str, json_row);
2533
2534 } else {
2535 vty_out(vty, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2536 ch->interface->name, src_str, grp_str,
2537 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2538 pim_macro_chisin_joins(ch) ? "yes" : "no",
2539 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
2540 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
2541 ? "yes"
2542 : "no",
2543 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2544 : "no");
2545 }
2546 }
2547
2548 static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
2549 bool uj)
2550 {
2551 struct pim_interface *pim_ifp;
2552 struct pim_ifchannel *ch;
2553 struct interface *ifp;
2554
2555 json_object *json = NULL;
2556
2557 if (uj)
2558 json = json_object_new_object();
2559 else
2560 vty_out(vty,
2561 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2562
2563 /* scan per-interface (S,G) state */
2564 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2565 pim_ifp = ifp->info;
2566 if (!pim_ifp)
2567 continue;
2568
2569
2570 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
2571 /* scan all interfaces */
2572 pim_show_join_desired_helper(pim, vty, pim_ifp, ch,
2573 json, uj);
2574 }
2575 }
2576
2577 if (uj) {
2578 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2579 json, JSON_C_TO_STRING_PRETTY));
2580 json_object_free(json);
2581 }
2582 }
2583
2584 static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
2585 bool uj)
2586 {
2587 struct listnode *upnode;
2588 struct pim_upstream *up;
2589 json_object *json = NULL;
2590 json_object *json_group = NULL;
2591 json_object *json_row = NULL;
2592
2593 if (uj)
2594 json = json_object_new_object();
2595 else
2596 vty_out(vty,
2597 "Source Group RpfIface RibNextHop RpfAddress \n");
2598
2599 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
2600 char src_str[INET_ADDRSTRLEN];
2601 char grp_str[INET_ADDRSTRLEN];
2602 char rpf_nexthop_str[PREFIX_STRLEN];
2603 char rpf_addr_str[PREFIX_STRLEN];
2604 struct pim_rpf *rpf;
2605 const char *rpf_ifname;
2606
2607 rpf = &up->rpf;
2608
2609 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2610 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2611 pim_addr_dump("<nexthop?>",
2612 &rpf->source_nexthop.mrib_nexthop_addr,
2613 rpf_nexthop_str, sizeof(rpf_nexthop_str));
2614 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2615 sizeof(rpf_addr_str));
2616
2617 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
2618
2619 if (uj) {
2620 json_object_object_get_ex(json, grp_str, &json_group);
2621
2622 if (!json_group) {
2623 json_group = json_object_new_object();
2624 json_object_object_add(json, grp_str,
2625 json_group);
2626 }
2627
2628 json_row = json_object_new_object();
2629 json_object_pim_upstream_add(json_row, up);
2630 json_object_string_add(json_row, "source", src_str);
2631 json_object_string_add(json_row, "group", grp_str);
2632 json_object_string_add(json_row, "rpfInterface",
2633 rpf_ifname);
2634 json_object_string_add(json_row, "ribNexthop",
2635 rpf_nexthop_str);
2636 json_object_string_add(json_row, "rpfAddress",
2637 rpf_addr_str);
2638 json_object_object_add(json_group, src_str, json_row);
2639 } else {
2640 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s\n", src_str,
2641 grp_str, rpf_ifname, rpf_nexthop_str,
2642 rpf_addr_str);
2643 }
2644 }
2645
2646 if (uj) {
2647 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2648 json, JSON_C_TO_STRING_PRETTY));
2649 json_object_free(json);
2650 }
2651 }
2652
2653 static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
2654 time_t now, json_object *json)
2655 {
2656 char refresh_uptime[10];
2657
2658 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
2659 pim->rpf_cache_refresh_last);
2660
2661 if (json) {
2662 json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
2663 router->rpf_cache_refresh_delay_msec);
2664 json_object_int_add(
2665 json, "rpfCacheRefreshTimer",
2666 pim_time_timer_remain_msec(pim->rpf_cache_refresher));
2667 json_object_int_add(json, "rpfCacheRefreshRequests",
2668 pim->rpf_cache_refresh_requests);
2669 json_object_int_add(json, "rpfCacheRefreshEvents",
2670 pim->rpf_cache_refresh_events);
2671 json_object_string_add(json, "rpfCacheRefreshLast",
2672 refresh_uptime);
2673 json_object_int_add(json, "nexthopLookups",
2674 pim->nexthop_lookups);
2675 json_object_int_add(json, "nexthopLookupsAvoided",
2676 pim->nexthop_lookups_avoided);
2677 } else {
2678 vty_out(vty,
2679 "RPF Cache Refresh Delay: %ld msecs\n"
2680 "RPF Cache Refresh Timer: %ld msecs\n"
2681 "RPF Cache Refresh Requests: %lld\n"
2682 "RPF Cache Refresh Events: %lld\n"
2683 "RPF Cache Refresh Last: %s\n"
2684 "Nexthop Lookups: %lld\n"
2685 "Nexthop Lookups Avoided: %lld\n",
2686 router->rpf_cache_refresh_delay_msec,
2687 pim_time_timer_remain_msec(pim->rpf_cache_refresher),
2688 (long long)pim->rpf_cache_refresh_requests,
2689 (long long)pim->rpf_cache_refresh_events,
2690 refresh_uptime, (long long)pim->nexthop_lookups,
2691 (long long)pim->nexthop_lookups_avoided);
2692 }
2693 }
2694
2695 static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
2696 time_t now)
2697 {
2698 char uptime_scan_oil[10];
2699 char uptime_mroute_add[10];
2700 char uptime_mroute_del[10];
2701
2702 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
2703 pim->scan_oil_last);
2704 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
2705 pim->mroute_add_last);
2706 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
2707 pim->mroute_del_last);
2708
2709 vty_out(vty,
2710 "Scan OIL - Last: %s Events: %lld\n"
2711 "MFC Add - Last: %s Events: %lld\n"
2712 "MFC Del - Last: %s Events: %lld\n",
2713 uptime_scan_oil, (long long)pim->scan_oil_events,
2714 uptime_mroute_add, (long long)pim->mroute_add_events,
2715 uptime_mroute_del, (long long)pim->mroute_del_events);
2716 }
2717
2718 static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
2719 {
2720 struct listnode *up_node;
2721 struct pim_upstream *up;
2722 time_t now = pim_time_monotonic_sec();
2723 json_object *json = NULL;
2724 json_object *json_group = NULL;
2725 json_object *json_row = NULL;
2726
2727 if (uj) {
2728 json = json_object_new_object();
2729 show_rpf_refresh_stats(vty, pim, now, json);
2730 } else {
2731 show_rpf_refresh_stats(vty, pim, now, json);
2732 vty_out(vty, "\n");
2733 vty_out(vty,
2734 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2735 }
2736
2737 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
2738 char src_str[INET_ADDRSTRLEN];
2739 char grp_str[INET_ADDRSTRLEN];
2740 char rpf_addr_str[PREFIX_STRLEN];
2741 char rib_nexthop_str[PREFIX_STRLEN];
2742 const char *rpf_ifname;
2743 struct pim_rpf *rpf = &up->rpf;
2744
2745 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2746 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2747 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2748 sizeof(rpf_addr_str));
2749 pim_addr_dump("<nexthop?>",
2750 &rpf->source_nexthop.mrib_nexthop_addr,
2751 rib_nexthop_str, sizeof(rib_nexthop_str));
2752
2753 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
2754
2755 if (uj) {
2756 json_object_object_get_ex(json, grp_str, &json_group);
2757
2758 if (!json_group) {
2759 json_group = json_object_new_object();
2760 json_object_object_add(json, grp_str,
2761 json_group);
2762 }
2763
2764 json_row = json_object_new_object();
2765 json_object_string_add(json_row, "source", src_str);
2766 json_object_string_add(json_row, "group", grp_str);
2767 json_object_string_add(json_row, "rpfInterface",
2768 rpf_ifname);
2769 json_object_string_add(json_row, "rpfAddress",
2770 rpf_addr_str);
2771 json_object_string_add(json_row, "ribNexthop",
2772 rib_nexthop_str);
2773 json_object_int_add(
2774 json_row, "routeMetric",
2775 rpf->source_nexthop.mrib_route_metric);
2776 json_object_int_add(
2777 json_row, "routePreference",
2778 rpf->source_nexthop.mrib_metric_preference);
2779 json_object_object_add(json_group, src_str, json_row);
2780
2781 } else {
2782 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2783 src_str, grp_str, rpf_ifname, rpf_addr_str,
2784 rib_nexthop_str,
2785 rpf->source_nexthop.mrib_route_metric,
2786 rpf->source_nexthop.mrib_metric_preference);
2787 }
2788 }
2789
2790 if (uj) {
2791 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2792 json, JSON_C_TO_STRING_PRETTY));
2793 json_object_free(json);
2794 }
2795 }
2796
2797 struct pnc_cache_walk_data {
2798 struct vty *vty;
2799 struct pim_instance *pim;
2800 };
2801
2802 static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
2803 {
2804 struct pim_nexthop_cache *pnc = bucket->data;
2805 struct pnc_cache_walk_data *cwd = arg;
2806 struct vty *vty = cwd->vty;
2807 struct pim_instance *pim = cwd->pim;
2808 struct nexthop *nh_node = NULL;
2809 ifindex_t first_ifindex;
2810 struct interface *ifp = NULL;
2811
2812 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
2813 first_ifindex = nh_node->ifindex;
2814 ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
2815
2816 vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
2817 vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
2818 vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
2819 vty_out(vty, "\n");
2820 }
2821 return CMD_SUCCESS;
2822 }
2823
2824 static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
2825 {
2826 struct pnc_cache_walk_data cwd;
2827
2828 cwd.vty = vty;
2829 cwd.pim = pim;
2830 vty_out(vty, "Number of registered addresses: %lu\n",
2831 pim->rpf_hash->count);
2832 vty_out(vty, "Address Interface Nexthop\n");
2833 vty_out(vty, "---------------------------------------------\n");
2834
2835 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
2836 }
2837
2838 static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
2839 {
2840 struct interface *ifp;
2841 time_t now;
2842 json_object *json = NULL;
2843 json_object *json_iface = NULL;
2844 json_object *json_row = NULL;
2845
2846 now = pim_time_monotonic_sec();
2847
2848 if (uj)
2849 json = json_object_new_object();
2850 else
2851 vty_out(vty,
2852 "Interface Address Group Mode Timer Srcs V Uptime \n");
2853
2854 /* scan interfaces */
2855 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2856 struct pim_interface *pim_ifp = ifp->info;
2857 struct listnode *sock_node;
2858 struct igmp_sock *igmp;
2859
2860 if (!pim_ifp)
2861 continue;
2862
2863 /* scan igmp sockets */
2864 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
2865 igmp)) {
2866 char ifaddr_str[INET_ADDRSTRLEN];
2867 struct listnode *grpnode;
2868 struct igmp_group *grp;
2869
2870 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
2871 sizeof(ifaddr_str));
2872
2873 /* scan igmp groups */
2874 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
2875 grpnode, grp)) {
2876 char group_str[INET_ADDRSTRLEN];
2877 char hhmmss[10];
2878 char uptime[10];
2879
2880 pim_inet4_dump("<group?>", grp->group_addr,
2881 group_str, sizeof(group_str));
2882 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
2883 grp->t_group_timer);
2884 pim_time_uptime(uptime, sizeof(uptime),
2885 now - grp->group_creation);
2886
2887 if (uj) {
2888 json_object_object_get_ex(
2889 json, ifp->name, &json_iface);
2890
2891 if (!json_iface) {
2892 json_iface =
2893 json_object_new_object();
2894 json_object_pim_ifp_add(
2895 json_iface, ifp);
2896 json_object_object_add(
2897 json, ifp->name,
2898 json_iface);
2899 }
2900
2901 json_row = json_object_new_object();
2902 json_object_string_add(
2903 json_row, "source", ifaddr_str);
2904 json_object_string_add(
2905 json_row, "group", group_str);
2906
2907 if (grp->igmp_version == 3)
2908 json_object_string_add(
2909 json_row, "mode",
2910 grp->group_filtermode_isexcl
2911 ? "EXCLUDE"
2912 : "INCLUDE");
2913
2914 json_object_string_add(json_row,
2915 "timer", hhmmss);
2916 json_object_int_add(
2917 json_row, "sourcesCount",
2918 grp->group_source_list
2919 ? listcount(
2920 grp->group_source_list)
2921 : 0);
2922 json_object_int_add(json_row, "version",
2923 grp->igmp_version);
2924 json_object_string_add(
2925 json_row, "uptime", uptime);
2926 json_object_object_add(json_iface,
2927 group_str,
2928 json_row);
2929
2930 } else {
2931 vty_out(vty,
2932 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
2933 ifp->name, ifaddr_str,
2934 group_str,
2935 grp->igmp_version == 3
2936 ? (grp->group_filtermode_isexcl
2937 ? "EXCL"
2938 : "INCL")
2939 : "----",
2940 hhmmss,
2941 grp->group_source_list
2942 ? listcount(
2943 grp->group_source_list)
2944 : 0,
2945 grp->igmp_version, uptime);
2946 }
2947 } /* scan igmp groups */
2948 } /* scan igmp sockets */
2949 } /* scan interfaces */
2950
2951 if (uj) {
2952 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2953 json, JSON_C_TO_STRING_PRETTY));
2954 json_object_free(json);
2955 }
2956 }
2957
2958 static void igmp_show_group_retransmission(struct pim_instance *pim,
2959 struct vty *vty)
2960 {
2961 struct interface *ifp;
2962
2963 vty_out(vty,
2964 "Interface Address Group RetTimer Counter RetSrcs\n");
2965
2966 /* scan interfaces */
2967 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2968 struct pim_interface *pim_ifp = ifp->info;
2969 struct listnode *sock_node;
2970 struct igmp_sock *igmp;
2971
2972 if (!pim_ifp)
2973 continue;
2974
2975 /* scan igmp sockets */
2976 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
2977 igmp)) {
2978 char ifaddr_str[INET_ADDRSTRLEN];
2979 struct listnode *grpnode;
2980 struct igmp_group *grp;
2981
2982 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
2983 sizeof(ifaddr_str));
2984
2985 /* scan igmp groups */
2986 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
2987 grpnode, grp)) {
2988 char group_str[INET_ADDRSTRLEN];
2989 char grp_retr_mmss[10];
2990 struct listnode *src_node;
2991 struct igmp_source *src;
2992 int grp_retr_sources = 0;
2993
2994 pim_inet4_dump("<group?>", grp->group_addr,
2995 group_str, sizeof(group_str));
2996 pim_time_timer_to_mmss(
2997 grp_retr_mmss, sizeof(grp_retr_mmss),
2998 grp->t_group_query_retransmit_timer);
2999
3000
3001 /* count group sources with retransmission state
3002 */
3003 for (ALL_LIST_ELEMENTS_RO(
3004 grp->group_source_list, src_node,
3005 src)) {
3006 if (src->source_query_retransmit_count
3007 > 0) {
3008 ++grp_retr_sources;
3009 }
3010 }
3011
3012 vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
3013 ifp->name, ifaddr_str, group_str,
3014 grp_retr_mmss,
3015 grp->group_specific_query_retransmit_count,
3016 grp_retr_sources);
3017
3018 } /* scan igmp groups */
3019 } /* scan igmp sockets */
3020 } /* scan interfaces */
3021 }
3022
3023 static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
3024 {
3025 struct interface *ifp;
3026 time_t now;
3027
3028 now = pim_time_monotonic_sec();
3029
3030 vty_out(vty,
3031 "Interface Address Group Source Timer Fwd Uptime \n");
3032
3033 /* scan interfaces */
3034 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3035 struct pim_interface *pim_ifp = ifp->info;
3036 struct listnode *sock_node;
3037 struct igmp_sock *igmp;
3038
3039 if (!pim_ifp)
3040 continue;
3041
3042 /* scan igmp sockets */
3043 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3044 igmp)) {
3045 char ifaddr_str[INET_ADDRSTRLEN];
3046 struct listnode *grpnode;
3047 struct igmp_group *grp;
3048
3049 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3050 sizeof(ifaddr_str));
3051
3052 /* scan igmp groups */
3053 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3054 grpnode, grp)) {
3055 char group_str[INET_ADDRSTRLEN];
3056 struct listnode *srcnode;
3057 struct igmp_source *src;
3058
3059 pim_inet4_dump("<group?>", grp->group_addr,
3060 group_str, sizeof(group_str));
3061
3062 /* scan group sources */
3063 for (ALL_LIST_ELEMENTS_RO(
3064 grp->group_source_list, srcnode,
3065 src)) {
3066 char source_str[INET_ADDRSTRLEN];
3067 char mmss[10];
3068 char uptime[10];
3069
3070 pim_inet4_dump(
3071 "<source?>", src->source_addr,
3072 source_str, sizeof(source_str));
3073
3074 pim_time_timer_to_mmss(
3075 mmss, sizeof(mmss),
3076 src->t_source_timer);
3077
3078 pim_time_uptime(
3079 uptime, sizeof(uptime),
3080 now - src->source_creation);
3081
3082 vty_out(vty,
3083 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3084 ifp->name, ifaddr_str,
3085 group_str, source_str, mmss,
3086 IGMP_SOURCE_TEST_FORWARDING(
3087 src->source_flags)
3088 ? "Y"
3089 : "N",
3090 uptime);
3091
3092 } /* scan group sources */
3093 } /* scan igmp groups */
3094 } /* scan igmp sockets */
3095 } /* scan interfaces */
3096 }
3097
3098 static void igmp_show_source_retransmission(struct pim_instance *pim,
3099 struct vty *vty)
3100 {
3101 struct interface *ifp;
3102
3103 vty_out(vty,
3104 "Interface Address Group Source Counter\n");
3105
3106 /* scan interfaces */
3107 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3108 struct pim_interface *pim_ifp = ifp->info;
3109 struct listnode *sock_node;
3110 struct igmp_sock *igmp;
3111
3112 if (!pim_ifp)
3113 continue;
3114
3115 /* scan igmp sockets */
3116 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3117 igmp)) {
3118 char ifaddr_str[INET_ADDRSTRLEN];
3119 struct listnode *grpnode;
3120 struct igmp_group *grp;
3121
3122 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3123 sizeof(ifaddr_str));
3124
3125 /* scan igmp groups */
3126 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3127 grpnode, grp)) {
3128 char group_str[INET_ADDRSTRLEN];
3129 struct listnode *srcnode;
3130 struct igmp_source *src;
3131
3132 pim_inet4_dump("<group?>", grp->group_addr,
3133 group_str, sizeof(group_str));
3134
3135 /* scan group sources */
3136 for (ALL_LIST_ELEMENTS_RO(
3137 grp->group_source_list, srcnode,
3138 src)) {
3139 char source_str[INET_ADDRSTRLEN];
3140
3141 pim_inet4_dump(
3142 "<source?>", src->source_addr,
3143 source_str, sizeof(source_str));
3144
3145 vty_out(vty,
3146 "%-16s %-15s %-15s %-15s %7d\n",
3147 ifp->name, ifaddr_str,
3148 group_str, source_str,
3149 src->source_query_retransmit_count);
3150
3151 } /* scan group sources */
3152 } /* scan igmp groups */
3153 } /* scan igmp sockets */
3154 } /* scan interfaces */
3155 }
3156
3157 static void clear_igmp_interfaces(struct pim_instance *pim)
3158 {
3159 struct interface *ifp;
3160
3161 FOR_ALL_INTERFACES (pim->vrf, ifp)
3162 pim_if_addr_del_all_igmp(ifp);
3163
3164 FOR_ALL_INTERFACES (pim->vrf, ifp)
3165 pim_if_addr_add_all(ifp);
3166 }
3167
3168 static void clear_pim_interfaces(struct pim_instance *pim)
3169 {
3170 struct interface *ifp;
3171
3172 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3173 if (ifp->info) {
3174 pim_neighbor_delete_all(ifp, "interface cleared");
3175 }
3176 }
3177 }
3178
3179 static void clear_interfaces(struct pim_instance *pim)
3180 {
3181 clear_igmp_interfaces(pim);
3182 clear_pim_interfaces(pim);
3183 }
3184
3185 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3186 pim_ifp = ifp->info; \
3187 if (!pim_ifp) { \
3188 vty_out(vty, \
3189 "%% Enable PIM and/or IGMP on this interface first\n"); \
3190 return CMD_WARNING_CONFIG_FAILED; \
3191 }
3192
3193 DEFUN (clear_ip_interfaces,
3194 clear_ip_interfaces_cmd,
3195 "clear ip interfaces [vrf NAME]",
3196 CLEAR_STR
3197 IP_STR
3198 "Reset interfaces\n"
3199 VRF_CMD_HELP_STR)
3200 {
3201 int idx = 2;
3202 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3203
3204 if (!vrf)
3205 return CMD_WARNING;
3206
3207 clear_interfaces(vrf->info);
3208
3209 return CMD_SUCCESS;
3210 }
3211
3212 DEFUN (clear_ip_igmp_interfaces,
3213 clear_ip_igmp_interfaces_cmd,
3214 "clear ip igmp [vrf NAME] interfaces",
3215 CLEAR_STR
3216 IP_STR
3217 CLEAR_IP_IGMP_STR
3218 VRF_CMD_HELP_STR
3219 "Reset IGMP interfaces\n")
3220 {
3221 int idx = 2;
3222 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3223
3224 if (!vrf)
3225 return CMD_WARNING;
3226
3227 clear_igmp_interfaces(vrf->info);
3228
3229 return CMD_SUCCESS;
3230 }
3231
3232 static void mroute_add_all(struct pim_instance *pim)
3233 {
3234 struct listnode *node;
3235 struct channel_oil *c_oil;
3236
3237 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
3238 if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
3239 /* just log warning */
3240 char source_str[INET_ADDRSTRLEN];
3241 char group_str[INET_ADDRSTRLEN];
3242 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
3243 source_str, sizeof(source_str));
3244 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
3245 group_str, sizeof(group_str));
3246 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
3247 __FILE__, __PRETTY_FUNCTION__, source_str,
3248 group_str);
3249 }
3250 }
3251 }
3252
3253 static void mroute_del_all(struct pim_instance *pim)
3254 {
3255 struct listnode *node;
3256 struct channel_oil *c_oil;
3257
3258 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
3259 if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
3260 /* just log warning */
3261 char source_str[INET_ADDRSTRLEN];
3262 char group_str[INET_ADDRSTRLEN];
3263 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
3264 source_str, sizeof(source_str));
3265 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
3266 group_str, sizeof(group_str));
3267 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
3268 __FILE__, __PRETTY_FUNCTION__, source_str,
3269 group_str);
3270 }
3271 }
3272 }
3273
3274 DEFUN (clear_ip_mroute,
3275 clear_ip_mroute_cmd,
3276 "clear ip mroute [vrf NAME]",
3277 CLEAR_STR
3278 IP_STR
3279 "Reset multicast routes\n"
3280 VRF_CMD_HELP_STR)
3281 {
3282 int idx = 2;
3283 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3284
3285 if (!vrf)
3286 return CMD_WARNING;
3287
3288 mroute_del_all(vrf->info);
3289 mroute_add_all(vrf->info);
3290
3291 return CMD_SUCCESS;
3292 }
3293
3294 DEFUN (clear_ip_pim_interfaces,
3295 clear_ip_pim_interfaces_cmd,
3296 "clear ip pim [vrf NAME] interfaces",
3297 CLEAR_STR
3298 IP_STR
3299 CLEAR_IP_PIM_STR
3300 VRF_CMD_HELP_STR
3301 "Reset PIM interfaces\n")
3302 {
3303 int idx = 2;
3304 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3305
3306 if (!vrf)
3307 return CMD_WARNING;
3308
3309 clear_pim_interfaces(vrf->info);
3310
3311 return CMD_SUCCESS;
3312 }
3313
3314 DEFUN (clear_ip_pim_interface_traffic,
3315 clear_ip_pim_interface_traffic_cmd,
3316 "clear ip pim [vrf NAME] interface traffic",
3317 "Reset functions\n"
3318 "IP information\n"
3319 "PIM clear commands\n"
3320 VRF_CMD_HELP_STR
3321 "Reset PIM interfaces\n"
3322 "Reset Protocol Packet counters\n")
3323 {
3324 int idx = 2;
3325 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3326 struct interface *ifp = NULL;
3327 struct pim_interface *pim_ifp = NULL;
3328
3329 if (!vrf)
3330 return CMD_WARNING;
3331
3332 FOR_ALL_INTERFACES (vrf, ifp) {
3333 pim_ifp = ifp->info;
3334
3335 if (!pim_ifp)
3336 continue;
3337
3338 pim_ifp->pim_ifstat_hello_recv = 0;
3339 pim_ifp->pim_ifstat_hello_sent = 0;
3340 pim_ifp->pim_ifstat_join_recv = 0;
3341 pim_ifp->pim_ifstat_join_send = 0;
3342 pim_ifp->pim_ifstat_prune_recv = 0;
3343 pim_ifp->pim_ifstat_prune_send = 0;
3344 pim_ifp->pim_ifstat_reg_recv = 0;
3345 pim_ifp->pim_ifstat_reg_send = 0;
3346 pim_ifp->pim_ifstat_reg_stop_recv = 0;
3347 pim_ifp->pim_ifstat_reg_stop_send = 0;
3348 pim_ifp->pim_ifstat_assert_recv = 0;
3349 pim_ifp->pim_ifstat_assert_send = 0;
3350 }
3351
3352 return CMD_SUCCESS;
3353 }
3354
3355 DEFUN (clear_ip_pim_oil,
3356 clear_ip_pim_oil_cmd,
3357 "clear ip pim [vrf NAME] oil",
3358 CLEAR_STR
3359 IP_STR
3360 CLEAR_IP_PIM_STR
3361 VRF_CMD_HELP_STR
3362 "Rescan PIM OIL (output interface list)\n")
3363 {
3364 int idx = 2;
3365 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3366
3367 if (!vrf)
3368 return CMD_WARNING;
3369
3370 pim_scan_oil(vrf->info);
3371
3372 return CMD_SUCCESS;
3373 }
3374
3375 DEFUN (show_ip_igmp_interface,
3376 show_ip_igmp_interface_cmd,
3377 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
3378 SHOW_STR
3379 IP_STR
3380 IGMP_STR
3381 VRF_CMD_HELP_STR
3382 "IGMP interface information\n"
3383 "Detailed output\n"
3384 "interface name\n"
3385 JSON_STR)
3386 {
3387 int idx = 2;
3388 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3389 bool uj = use_json(argc, argv);
3390
3391 if (!vrf)
3392 return CMD_WARNING;
3393
3394 if (argv_find(argv, argc, "detail", &idx)
3395 || argv_find(argv, argc, "WORD", &idx))
3396 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
3397 else
3398 igmp_show_interfaces(vrf->info, vty, uj);
3399
3400 return CMD_SUCCESS;
3401 }
3402
3403 DEFUN (show_ip_igmp_interface_vrf_all,
3404 show_ip_igmp_interface_vrf_all_cmd,
3405 "show ip igmp vrf all interface [detail|WORD] [json]",
3406 SHOW_STR
3407 IP_STR
3408 IGMP_STR
3409 VRF_CMD_HELP_STR
3410 "IGMP interface information\n"
3411 "Detailed output\n"
3412 "interface name\n"
3413 JSON_STR)
3414 {
3415 int idx = 2;
3416 bool uj = use_json(argc, argv);
3417 struct vrf *vrf;
3418 bool first = true;
3419
3420 if (uj)
3421 vty_out(vty, "{ ");
3422 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
3423 if (uj) {
3424 if (!first)
3425 vty_out(vty, ", ");
3426 vty_out(vty, " \"%s\": ", vrf->name);
3427 first = false;
3428 } else
3429 vty_out(vty, "VRF: %s\n", vrf->name);
3430 if (argv_find(argv, argc, "detail", &idx)
3431 || argv_find(argv, argc, "WORD", &idx))
3432 igmp_show_interfaces_single(vrf->info, vty,
3433 argv[idx]->arg, uj);
3434 else
3435 igmp_show_interfaces(vrf->info, vty, uj);
3436 }
3437 if (uj)
3438 vty_out(vty, "}\n");
3439
3440 return CMD_SUCCESS;
3441 }
3442
3443 DEFUN (show_ip_igmp_join,
3444 show_ip_igmp_join_cmd,
3445 "show ip igmp [vrf NAME] join",
3446 SHOW_STR
3447 IP_STR
3448 IGMP_STR
3449 VRF_CMD_HELP_STR
3450 "IGMP static join information\n")
3451 {
3452 int idx = 2;
3453 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3454
3455 if (!vrf)
3456 return CMD_WARNING;
3457
3458 igmp_show_interface_join(vrf->info, vty);
3459
3460 return CMD_SUCCESS;
3461 }
3462
3463 DEFUN (show_ip_igmp_join_vrf_all,
3464 show_ip_igmp_join_vrf_all_cmd,
3465 "show ip igmp vrf all join",
3466 SHOW_STR
3467 IP_STR
3468 IGMP_STR
3469 VRF_CMD_HELP_STR
3470 "IGMP static join information\n")
3471 {
3472 bool uj = use_json(argc, argv);
3473 struct vrf *vrf;
3474 bool first = true;
3475
3476 if (uj)
3477 vty_out(vty, "{ ");
3478 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
3479 if (uj) {
3480 if (!first)
3481 vty_out(vty, ", ");
3482 vty_out(vty, " \"%s\": ", vrf->name);
3483 first = false;
3484 } else
3485 vty_out(vty, "VRF: %s\n", vrf->name);
3486 igmp_show_interface_join(vrf->info, vty);
3487 }
3488 if (uj)
3489 vty_out(vty, "}\n");
3490
3491 return CMD_SUCCESS;
3492 }
3493
3494 DEFUN (show_ip_igmp_groups,
3495 show_ip_igmp_groups_cmd,
3496 "show ip igmp [vrf NAME] groups [json]",
3497 SHOW_STR
3498 IP_STR
3499 IGMP_STR
3500 VRF_CMD_HELP_STR
3501 IGMP_GROUP_STR
3502 JSON_STR)
3503 {
3504 int idx = 2;
3505 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3506 bool uj = use_json(argc, argv);
3507
3508 if (!vrf)
3509 return CMD_WARNING;
3510
3511 igmp_show_groups(vrf->info, vty, uj);
3512
3513 return CMD_SUCCESS;
3514 }
3515
3516 DEFUN (show_ip_igmp_groups_vrf_all,
3517 show_ip_igmp_groups_vrf_all_cmd,
3518 "show ip igmp vrf all groups [json]",
3519 SHOW_STR
3520 IP_STR
3521 IGMP_STR
3522 VRF_CMD_HELP_STR
3523 IGMP_GROUP_STR
3524 JSON_STR)
3525 {
3526 bool uj = use_json(argc, argv);
3527 struct vrf *vrf;
3528 bool first = true;
3529
3530 if (uj)
3531 vty_out(vty, "{ ");
3532 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
3533 if (uj) {
3534 if (!first)
3535 vty_out(vty, ", ");
3536 vty_out(vty, " \"%s\": ", vrf->name);
3537 first = false;
3538 } else
3539 vty_out(vty, "VRF: %s\n", vrf->name);
3540 igmp_show_groups(vrf->info, vty, uj);
3541 }
3542 if (uj)
3543 vty_out(vty, "}\n");
3544
3545 return CMD_SUCCESS;
3546 }
3547
3548 DEFUN (show_ip_igmp_groups_retransmissions,
3549 show_ip_igmp_groups_retransmissions_cmd,
3550 "show ip igmp [vrf NAME] groups retransmissions",
3551 SHOW_STR
3552 IP_STR
3553 IGMP_STR
3554 VRF_CMD_HELP_STR
3555 IGMP_GROUP_STR
3556 "IGMP group retransmissions\n")
3557 {
3558 int idx = 2;
3559 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3560
3561 if (!vrf)
3562 return CMD_WARNING;
3563
3564 igmp_show_group_retransmission(vrf->info, vty);
3565
3566 return CMD_SUCCESS;
3567 }
3568
3569 DEFUN (show_ip_igmp_sources,
3570 show_ip_igmp_sources_cmd,
3571 "show ip igmp [vrf NAME] sources",
3572 SHOW_STR
3573 IP_STR
3574 IGMP_STR
3575 VRF_CMD_HELP_STR
3576 IGMP_SOURCE_STR)
3577 {
3578 int idx = 2;
3579 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3580
3581 if (!vrf)
3582 return CMD_WARNING;
3583
3584 igmp_show_sources(vrf->info, vty);
3585
3586 return CMD_SUCCESS;
3587 }
3588
3589 DEFUN (show_ip_igmp_sources_retransmissions,
3590 show_ip_igmp_sources_retransmissions_cmd,
3591 "show ip igmp [vrf NAME] sources retransmissions",
3592 SHOW_STR
3593 IP_STR
3594 IGMP_STR
3595 VRF_CMD_HELP_STR
3596 IGMP_SOURCE_STR
3597 "IGMP source retransmissions\n")
3598 {
3599 int idx = 2;
3600 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3601
3602 if (!vrf)
3603 return CMD_WARNING;
3604
3605 igmp_show_source_retransmission(vrf->info, vty);
3606
3607 return CMD_SUCCESS;
3608 }
3609
3610 DEFUN (show_ip_igmp_statistics,
3611 show_ip_igmp_statistics_cmd,
3612 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
3613 SHOW_STR
3614 IP_STR
3615 IGMP_STR
3616 VRF_CMD_HELP_STR
3617 "IGMP statistics\n"
3618 "interface\n"
3619 "IGMP interface\n"
3620 JSON_STR)
3621 {
3622 int idx = 2;
3623 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3624 bool uj = use_json(argc, argv);
3625
3626 if (!vrf)
3627 return CMD_WARNING;
3628
3629 if (argv_find(argv, argc, "WORD", &idx))
3630 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
3631 else
3632 igmp_show_statistics(vrf->info, vty, NULL, uj);
3633
3634 return CMD_SUCCESS;
3635 }
3636
3637 DEFUN (show_ip_pim_assert,
3638 show_ip_pim_assert_cmd,
3639 "show ip pim [vrf NAME] assert",
3640 SHOW_STR
3641 IP_STR
3642 PIM_STR
3643 VRF_CMD_HELP_STR
3644 "PIM interface assert\n")
3645 {
3646 int idx = 2;
3647 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3648
3649 if (!vrf)
3650 return CMD_WARNING;
3651
3652 pim_show_assert(vrf->info, vty);
3653
3654 return CMD_SUCCESS;
3655 }
3656
3657 DEFUN (show_ip_pim_assert_internal,
3658 show_ip_pim_assert_internal_cmd,
3659 "show ip pim [vrf NAME] assert-internal",
3660 SHOW_STR
3661 IP_STR
3662 PIM_STR
3663 VRF_CMD_HELP_STR
3664 "PIM interface internal assert state\n")
3665 {
3666 int idx = 2;
3667 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3668
3669 if (!vrf)
3670 return CMD_WARNING;
3671
3672 pim_show_assert_internal(vrf->info, vty);
3673
3674 return CMD_SUCCESS;
3675 }
3676
3677 DEFUN (show_ip_pim_assert_metric,
3678 show_ip_pim_assert_metric_cmd,
3679 "show ip pim [vrf NAME] assert-metric",
3680 SHOW_STR
3681 IP_STR
3682 PIM_STR
3683 VRF_CMD_HELP_STR
3684 "PIM interface assert metric\n")
3685 {
3686 int idx = 2;
3687 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3688
3689 if (!vrf)
3690 return CMD_WARNING;
3691
3692 pim_show_assert_metric(vrf->info, vty);
3693
3694 return CMD_SUCCESS;
3695 }
3696
3697 DEFUN (show_ip_pim_assert_winner_metric,
3698 show_ip_pim_assert_winner_metric_cmd,
3699 "show ip pim [vrf NAME] assert-winner-metric",
3700 SHOW_STR
3701 IP_STR
3702 PIM_STR
3703 VRF_CMD_HELP_STR
3704 "PIM interface assert winner metric\n")
3705 {
3706 int idx = 2;
3707 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3708
3709 if (!vrf)
3710 return CMD_WARNING;
3711
3712 pim_show_assert_winner_metric(vrf->info, vty);
3713
3714 return CMD_SUCCESS;
3715 }
3716
3717 DEFUN (show_ip_pim_interface,
3718 show_ip_pim_interface_cmd,
3719 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
3720 SHOW_STR
3721 IP_STR
3722 PIM_STR
3723 VRF_CMD_HELP_STR
3724 "PIM interface information\n"
3725 "Detailed output\n"
3726 "interface name\n"
3727 JSON_STR)
3728 {
3729 int idx = 2;
3730 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3731 bool uj = use_json(argc, argv);
3732
3733 if (!vrf)
3734 return CMD_WARNING;
3735
3736 if (argv_find(argv, argc, "WORD", &idx)
3737 || argv_find(argv, argc, "detail", &idx))
3738 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
3739 else
3740 pim_show_interfaces(vrf->info, vty, uj);
3741
3742 return CMD_SUCCESS;
3743 }
3744
3745 DEFUN (show_ip_pim_interface_vrf_all,
3746 show_ip_pim_interface_vrf_all_cmd,
3747 "show ip pim vrf all interface [detail|WORD] [json]",
3748 SHOW_STR
3749 IP_STR
3750 PIM_STR
3751 VRF_CMD_HELP_STR
3752 "PIM interface information\n"
3753 "Detailed output\n"
3754 "interface name\n"
3755 JSON_STR)
3756 {
3757 int idx = 6;
3758 bool uj = use_json(argc, argv);
3759 struct vrf *vrf;
3760 bool first = true;
3761
3762 if (uj)
3763 vty_out(vty, "{ ");
3764 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
3765 if (uj) {
3766 if (!first)
3767 vty_out(vty, ", ");
3768 vty_out(vty, " \"%s\": ", vrf->name);
3769 first = false;
3770 } else
3771 vty_out(vty, "VRF: %s\n", vrf->name);
3772 if (argv_find(argv, argc, "WORD", &idx)
3773 || argv_find(argv, argc, "detail", &idx))
3774 pim_show_interfaces_single(vrf->info, vty,
3775 argv[idx]->arg, uj);
3776 else
3777 pim_show_interfaces(vrf->info, vty, uj);
3778 }
3779 if (uj)
3780 vty_out(vty, "}\n");
3781
3782 return CMD_SUCCESS;
3783 }
3784
3785 DEFUN (show_ip_pim_join,
3786 show_ip_pim_join_cmd,
3787 "show ip pim [vrf NAME] join [json]",
3788 SHOW_STR
3789 IP_STR
3790 PIM_STR
3791 VRF_CMD_HELP_STR
3792 "PIM interface join information\n"
3793 JSON_STR)
3794 {
3795 int idx = 2;
3796 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3797 bool uj = use_json(argc, argv);
3798
3799 if (!vrf)
3800 return CMD_WARNING;
3801
3802 pim_show_join(vrf->info, vty, uj);
3803
3804 return CMD_SUCCESS;
3805 }
3806
3807 DEFUN (show_ip_pim_join_vrf_all,
3808 show_ip_pim_join_vrf_all_cmd,
3809 "show ip pim vrf all join [json]",
3810 SHOW_STR
3811 IP_STR
3812 PIM_STR
3813 VRF_CMD_HELP_STR
3814 "PIM interface join information\n"
3815 JSON_STR)
3816 {
3817 bool uj = use_json(argc, argv);
3818 struct vrf *vrf;
3819 bool first = true;
3820
3821 if (uj)
3822 vty_out(vty, "{ ");
3823 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
3824 if (uj) {
3825 if (!first)
3826 vty_out(vty, ", ");
3827 vty_out(vty, " \"%s\": ", vrf->name);
3828 first = false;
3829 } else
3830 vty_out(vty, "VRF: %s\n", vrf->name);
3831 pim_show_join(vrf->info, vty, uj);
3832 }
3833 if (uj)
3834 vty_out(vty, "}\n");
3835
3836 return CMD_WARNING;
3837 }
3838
3839 DEFUN (show_ip_pim_local_membership,
3840 show_ip_pim_local_membership_cmd,
3841 "show ip pim [vrf NAME] local-membership [json]",
3842 SHOW_STR
3843 IP_STR
3844 PIM_STR
3845 VRF_CMD_HELP_STR
3846 "PIM interface local-membership\n"
3847 JSON_STR)
3848 {
3849 int idx = 2;
3850 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3851 bool uj = use_json(argc, argv);
3852
3853 if (!vrf)
3854 return CMD_WARNING;
3855
3856 pim_show_membership(vrf->info, vty, uj);
3857
3858 return CMD_SUCCESS;
3859 }
3860
3861 DEFUN (show_ip_pim_neighbor,
3862 show_ip_pim_neighbor_cmd,
3863 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
3864 SHOW_STR
3865 IP_STR
3866 PIM_STR
3867 VRF_CMD_HELP_STR
3868 "PIM neighbor information\n"
3869 "Detailed output\n"
3870 "Name of interface or neighbor\n"
3871 JSON_STR)
3872 {
3873 int idx = 2;
3874 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3875 bool uj = use_json(argc, argv);
3876
3877 if (!vrf)
3878 return CMD_WARNING;
3879
3880 if (argv_find(argv, argc, "detail", &idx)
3881 || argv_find(argv, argc, "WORD", &idx))
3882 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
3883 else
3884 pim_show_neighbors(vrf->info, vty, uj);
3885
3886 return CMD_SUCCESS;
3887 }
3888
3889 DEFUN (show_ip_pim_neighbor_vrf_all,
3890 show_ip_pim_neighbor_vrf_all_cmd,
3891 "show ip pim vrf all neighbor [detail|WORD] [json]",
3892 SHOW_STR
3893 IP_STR
3894 PIM_STR
3895 VRF_CMD_HELP_STR
3896 "PIM neighbor information\n"
3897 "Detailed output\n"
3898 "Name of interface or neighbor\n"
3899 JSON_STR)
3900 {
3901 int idx = 2;
3902 bool uj = use_json(argc, argv);
3903 struct vrf *vrf;
3904 bool first = true;
3905
3906 if (uj)
3907 vty_out(vty, "{ ");
3908 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
3909 if (uj) {
3910 if (!first)
3911 vty_out(vty, ", ");
3912 vty_out(vty, " \"%s\": ", vrf->name);
3913 first = false;
3914 } else
3915 vty_out(vty, "VRF: %s\n", vrf->name);
3916 if (argv_find(argv, argc, "detail", &idx)
3917 || argv_find(argv, argc, "WORD", &idx))
3918 pim_show_neighbors_single(vrf->info, vty,
3919 argv[idx]->arg, uj);
3920 else
3921 pim_show_neighbors(vrf->info, vty, uj);
3922 }
3923 if (uj)
3924 vty_out(vty, "}\n");
3925
3926 return CMD_SUCCESS;
3927 }
3928
3929 DEFUN (show_ip_pim_secondary,
3930 show_ip_pim_secondary_cmd,
3931 "show ip pim [vrf NAME] secondary",
3932 SHOW_STR
3933 IP_STR
3934 PIM_STR
3935 VRF_CMD_HELP_STR
3936 "PIM neighbor addresses\n")
3937 {
3938 int idx = 2;
3939 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3940
3941 if (!vrf)
3942 return CMD_WARNING;
3943
3944 pim_show_neighbors_secondary(vrf->info, vty);
3945
3946 return CMD_SUCCESS;
3947 }
3948
3949 DEFUN (show_ip_pim_state,
3950 show_ip_pim_state_cmd,
3951 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
3952 SHOW_STR
3953 IP_STR
3954 PIM_STR
3955 VRF_CMD_HELP_STR
3956 "PIM state information\n"
3957 "Unicast or Multicast address\n"
3958 "Multicast address\n"
3959 JSON_STR)
3960 {
3961 const char *src_or_group = NULL;
3962 const char *group = NULL;
3963 int idx = 2;
3964 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3965 bool uj = use_json(argc, argv);
3966
3967 if (!vrf)
3968 return CMD_WARNING;
3969
3970 if (uj)
3971 argc--;
3972
3973 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
3974 src_or_group = argv[idx]->arg;
3975 if (idx + 1 < argc)
3976 group = argv[idx + 1]->arg;
3977 }
3978
3979 pim_show_state(vrf->info, vty, src_or_group, group, uj);
3980
3981 return CMD_SUCCESS;
3982 }
3983
3984 DEFUN (show_ip_pim_state_vrf_all,
3985 show_ip_pim_state_vrf_all_cmd,
3986 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
3987 SHOW_STR
3988 IP_STR
3989 PIM_STR
3990 VRF_CMD_HELP_STR
3991 "PIM state information\n"
3992 "Unicast or Multicast address\n"
3993 "Multicast address\n"
3994 JSON_STR)
3995 {
3996 const char *src_or_group = NULL;
3997 const char *group = NULL;
3998 int idx = 2;
3999 bool uj = use_json(argc, argv);
4000 struct vrf *vrf;
4001 bool first = true;
4002
4003 if (uj) {
4004 vty_out(vty, "{ ");
4005 argc--;
4006 }
4007
4008 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4009 src_or_group = argv[idx]->arg;
4010 if (idx + 1 < argc)
4011 group = argv[idx + 1]->arg;
4012 }
4013
4014 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4015 if (uj) {
4016 if (!first)
4017 vty_out(vty, ", ");
4018 vty_out(vty, " \"%s\": ", vrf->name);
4019 first = false;
4020 } else
4021 vty_out(vty, "VRF: %s\n", vrf->name);
4022 pim_show_state(vrf->info, vty, src_or_group, group, uj);
4023 }
4024 if (uj)
4025 vty_out(vty, "}\n");
4026
4027 return CMD_SUCCESS;
4028 }
4029
4030 DEFPY (show_ip_pim_upstream,
4031 show_ip_pim_upstream_cmd,
4032 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4033 SHOW_STR
4034 IP_STR
4035 PIM_STR
4036 VRF_CMD_HELP_STR
4037 "PIM upstream information\n"
4038 "The Source or Group\n"
4039 "The Group\n"
4040 JSON_STR)
4041 {
4042 struct prefix_sg sg = {0};
4043 struct vrf *v;
4044 bool uj = !!json;
4045 struct pim_instance *pim;
4046
4047 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4048
4049 if (!v) {
4050 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4051 return CMD_WARNING;
4052 }
4053 pim = pim_get_pim_instance(v->vrf_id);
4054
4055 if (!pim) {
4056 vty_out(vty, "%% Unable to find pim instance\n");
4057 return CMD_WARNING;
4058 }
4059
4060 if (s_or_g.s_addr != 0) {
4061 if (g.s_addr != 0) {
4062 sg.src = s_or_g;
4063 sg.grp = g;
4064 } else
4065 sg.grp = s_or_g;
4066 }
4067 pim_show_upstream(pim, vty, &sg, uj);
4068
4069 return CMD_SUCCESS;
4070 }
4071
4072 DEFUN (show_ip_pim_upstream_vrf_all,
4073 show_ip_pim_upstream_vrf_all_cmd,
4074 "show ip pim vrf all upstream [json]",
4075 SHOW_STR
4076 IP_STR
4077 PIM_STR
4078 VRF_CMD_HELP_STR
4079 "PIM upstream information\n"
4080 JSON_STR)
4081 {
4082 struct prefix_sg sg = {0};
4083 bool uj = use_json(argc, argv);
4084 struct vrf *vrf;
4085 bool first = true;
4086
4087 if (uj)
4088 vty_out(vty, "{ ");
4089 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4090 if (uj) {
4091 if (!first)
4092 vty_out(vty, ", ");
4093 vty_out(vty, " \"%s\": ", vrf->name);
4094 first = false;
4095 } else
4096 vty_out(vty, "VRF: %s\n", vrf->name);
4097 pim_show_upstream(vrf->info, vty, &sg, uj);
4098 }
4099
4100 return CMD_SUCCESS;
4101 }
4102
4103 DEFUN (show_ip_pim_upstream_join_desired,
4104 show_ip_pim_upstream_join_desired_cmd,
4105 "show ip pim [vrf NAME] upstream-join-desired [json]",
4106 SHOW_STR
4107 IP_STR
4108 PIM_STR
4109 VRF_CMD_HELP_STR
4110 "PIM upstream join-desired\n"
4111 JSON_STR)
4112 {
4113 int idx = 2;
4114 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4115 bool uj = use_json(argc, argv);
4116
4117 if (!vrf)
4118 return CMD_WARNING;
4119
4120 pim_show_join_desired(vrf->info, vty, uj);
4121
4122 return CMD_SUCCESS;
4123 }
4124
4125 DEFUN (show_ip_pim_upstream_rpf,
4126 show_ip_pim_upstream_rpf_cmd,
4127 "show ip pim [vrf NAME] upstream-rpf [json]",
4128 SHOW_STR
4129 IP_STR
4130 PIM_STR
4131 VRF_CMD_HELP_STR
4132 "PIM upstream source rpf\n"
4133 JSON_STR)
4134 {
4135 int idx = 2;
4136 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4137 bool uj = use_json(argc, argv);
4138
4139 if (!vrf)
4140 return CMD_WARNING;
4141
4142 pim_show_upstream_rpf(vrf->info, vty, uj);
4143
4144 return CMD_SUCCESS;
4145 }
4146
4147 DEFUN (show_ip_pim_rp,
4148 show_ip_pim_rp_cmd,
4149 "show ip pim [vrf NAME] rp-info [json]",
4150 SHOW_STR
4151 IP_STR
4152 PIM_STR
4153 VRF_CMD_HELP_STR
4154 "PIM RP information\n"
4155 JSON_STR)
4156 {
4157 int idx = 2;
4158 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4159 bool uj = use_json(argc, argv);
4160
4161 if (!vrf)
4162 return CMD_WARNING;
4163
4164 pim_rp_show_information(vrf->info, vty, uj);
4165
4166 return CMD_SUCCESS;
4167 }
4168
4169 DEFUN (show_ip_pim_rp_vrf_all,
4170 show_ip_pim_rp_vrf_all_cmd,
4171 "show ip pim vrf all rp-info [json]",
4172 SHOW_STR
4173 IP_STR
4174 PIM_STR
4175 VRF_CMD_HELP_STR
4176 "PIM RP information\n"
4177 JSON_STR)
4178 {
4179 bool uj = use_json(argc, argv);
4180 struct vrf *vrf;
4181 bool first = true;
4182
4183 if (uj)
4184 vty_out(vty, "{ ");
4185 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4186 if (uj) {
4187 if (!first)
4188 vty_out(vty, ", ");
4189 vty_out(vty, " \"%s\": ", vrf->name);
4190 first = false;
4191 } else
4192 vty_out(vty, "VRF: %s\n", vrf->name);
4193 pim_rp_show_information(vrf->info, vty, uj);
4194 }
4195 if (uj)
4196 vty_out(vty, "}\n");
4197
4198 return CMD_SUCCESS;
4199 }
4200
4201 DEFUN (show_ip_pim_rpf,
4202 show_ip_pim_rpf_cmd,
4203 "show ip pim [vrf NAME] rpf [json]",
4204 SHOW_STR
4205 IP_STR
4206 PIM_STR
4207 VRF_CMD_HELP_STR
4208 "PIM cached source rpf information\n"
4209 JSON_STR)
4210 {
4211 int idx = 2;
4212 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4213 bool uj = use_json(argc, argv);
4214
4215 if (!vrf)
4216 return CMD_WARNING;
4217
4218 pim_show_rpf(vrf->info, vty, uj);
4219
4220 return CMD_SUCCESS;
4221 }
4222
4223 DEFUN (show_ip_pim_rpf_vrf_all,
4224 show_ip_pim_rpf_vrf_all_cmd,
4225 "show ip pim vrf all rpf [json]",
4226 SHOW_STR
4227 IP_STR
4228 PIM_STR
4229 VRF_CMD_HELP_STR
4230 "PIM cached source rpf information\n"
4231 JSON_STR)
4232 {
4233 bool uj = use_json(argc, argv);
4234 struct vrf *vrf;
4235 bool first = true;
4236
4237 if (uj)
4238 vty_out(vty, "{ ");
4239 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4240 if (uj) {
4241 if (!first)
4242 vty_out(vty, ", ");
4243 vty_out(vty, " \"%s\": ", vrf->name);
4244 first = false;
4245 } else
4246 vty_out(vty, "VRF: %s\n", vrf->name);
4247 pim_show_rpf(vrf->info, vty, uj);
4248 }
4249 if (uj)
4250 vty_out(vty, "}\n");
4251
4252 return CMD_SUCCESS;
4253 }
4254
4255 DEFUN (show_ip_pim_nexthop,
4256 show_ip_pim_nexthop_cmd,
4257 "show ip pim [vrf NAME] nexthop",
4258 SHOW_STR
4259 IP_STR
4260 PIM_STR
4261 VRF_CMD_HELP_STR
4262 "PIM cached nexthop rpf information\n")
4263 {
4264 int idx = 2;
4265 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4266
4267 if (!vrf)
4268 return CMD_WARNING;
4269
4270 pim_show_nexthop(vrf->info, vty);
4271
4272 return CMD_SUCCESS;
4273 }
4274
4275 DEFUN (show_ip_pim_nexthop_lookup,
4276 show_ip_pim_nexthop_lookup_cmd,
4277 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
4278 SHOW_STR
4279 IP_STR
4280 PIM_STR
4281 VRF_CMD_HELP_STR
4282 "PIM cached nexthop rpf lookup\n"
4283 "Source/RP address\n"
4284 "Multicast Group address\n")
4285 {
4286 struct prefix nht_p;
4287 int result = 0;
4288 struct in_addr src_addr, grp_addr;
4289 struct in_addr vif_source;
4290 const char *addr_str, *addr_str1;
4291 struct prefix grp;
4292 struct pim_nexthop nexthop;
4293 char nexthop_addr_str[PREFIX_STRLEN];
4294 char grp_str[PREFIX_STRLEN];
4295 int idx = 2;
4296 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4297
4298 if (!vrf)
4299 return CMD_WARNING;
4300
4301 argv_find(argv, argc, "A.B.C.D", &idx);
4302 addr_str = argv[idx]->arg;
4303 result = inet_pton(AF_INET, addr_str, &src_addr);
4304 if (result <= 0) {
4305 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
4306 errno, safe_strerror(errno));
4307 return CMD_WARNING;
4308 }
4309
4310 if (pim_is_group_224_4(src_addr)) {
4311 vty_out(vty,
4312 "Invalid argument. Expected Valid Source Address.\n");
4313 return CMD_WARNING;
4314 }
4315
4316 addr_str1 = argv[idx + 1]->arg;
4317 result = inet_pton(AF_INET, addr_str1, &grp_addr);
4318 if (result <= 0) {
4319 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
4320 errno, safe_strerror(errno));
4321 return CMD_WARNING;
4322 }
4323
4324 if (!pim_is_group_224_4(grp_addr)) {
4325 vty_out(vty,
4326 "Invalid argument. Expected Valid Multicast Group Address.\n");
4327 return CMD_WARNING;
4328 }
4329
4330 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
4331 grp_addr))
4332 return CMD_SUCCESS;
4333
4334 nht_p.family = AF_INET;
4335 nht_p.prefixlen = IPV4_MAX_BITLEN;
4336 nht_p.u.prefix4 = vif_source;
4337 grp.family = AF_INET;
4338 grp.prefixlen = IPV4_MAX_BITLEN;
4339 grp.u.prefix4 = grp_addr;
4340 memset(&nexthop, 0, sizeof(nexthop));
4341
4342 result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
4343
4344 if (!result) {
4345 vty_out(vty,
4346 "Nexthop Lookup failed, no usable routes returned.\n");
4347 return CMD_SUCCESS;
4348 }
4349
4350 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
4351 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
4352 nexthop_addr_str, sizeof(nexthop_addr_str));
4353 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
4354 nexthop_addr_str, nexthop.interface->name);
4355
4356 return CMD_SUCCESS;
4357 }
4358
4359 DEFUN (show_ip_pim_interface_traffic,
4360 show_ip_pim_interface_traffic_cmd,
4361 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
4362 SHOW_STR
4363 IP_STR
4364 PIM_STR
4365 VRF_CMD_HELP_STR
4366 "PIM interface information\n"
4367 "Protocol Packet counters\n"
4368 "Interface name\n"
4369 JSON_STR)
4370 {
4371 int idx = 2;
4372 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4373 bool uj = use_json(argc, argv);
4374
4375 if (!vrf)
4376 return CMD_WARNING;
4377
4378 if (argv_find(argv, argc, "WORD", &idx))
4379 pim_show_interface_traffic_single(vrf->info, vty,
4380 argv[idx]->arg, uj);
4381 else
4382 pim_show_interface_traffic(vrf->info, vty, uj);
4383
4384 return CMD_SUCCESS;
4385 }
4386
4387 static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
4388 {
4389 struct interface *ifp;
4390
4391 vty_out(vty, "\n");
4392
4393 vty_out(vty,
4394 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
4395
4396 FOR_ALL_INTERFACES (pim->vrf, ifp) {
4397 struct pim_interface *pim_ifp;
4398 struct in_addr ifaddr;
4399 struct sioc_vif_req vreq;
4400
4401 pim_ifp = ifp->info;
4402
4403 if (!pim_ifp)
4404 continue;
4405
4406 memset(&vreq, 0, sizeof(vreq));
4407 vreq.vifi = pim_ifp->mroute_vif_index;
4408
4409 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
4410 zlog_warn(
4411 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
4412 (unsigned long)SIOCGETVIFCNT, ifp->name,
4413 pim_ifp->mroute_vif_index, errno,
4414 safe_strerror(errno));
4415 }
4416
4417 ifaddr = pim_ifp->primary_address;
4418
4419 vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
4420 ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
4421 pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
4422 (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
4423 (unsigned long)vreq.obytes);
4424 }
4425 }
4426
4427 static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
4428 struct vty *vty)
4429 {
4430 struct vrf *vrf = pim->vrf;
4431 time_t now = pim_time_monotonic_sec();
4432 char uptime[10];
4433 char mlag_role[80];
4434
4435 pim = vrf->info;
4436
4437 vty_out(vty, "Router MLAG Role: %s\n",
4438 mlag_role2str(router->role, mlag_role, sizeof(mlag_role)));
4439 vty_out(vty, "Mroute socket descriptor:");
4440
4441 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
4442
4443 pim_time_uptime(uptime, sizeof(uptime),
4444 now - pim->mroute_socket_creation);
4445 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
4446
4447 vty_out(vty, "\n");
4448
4449 pim_zebra_zclient_update(vty);
4450 pim_zlookup_show_ip_multicast(vty);
4451
4452 vty_out(vty, "\n");
4453 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
4454
4455 vty_out(vty, "\n");
4456 vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
4457 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
4458 vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
4459 vty_out(vty, "PIM ECMP Rebalance: %s\n",
4460 pim->ecmp_rebalance_enable ? "Enable" : "Disable");
4461
4462 vty_out(vty, "\n");
4463
4464 show_rpf_refresh_stats(vty, pim, now, NULL);
4465
4466 vty_out(vty, "\n");
4467
4468 show_scan_oil_stats(pim, vty, now);
4469
4470 show_multicast_interfaces(pim, vty);
4471 }
4472
4473 DEFUN (show_ip_multicast,
4474 show_ip_multicast_cmd,
4475 "show ip multicast [vrf NAME]",
4476 SHOW_STR
4477 IP_STR
4478 VRF_CMD_HELP_STR
4479 "Multicast global information\n")
4480 {
4481 int idx = 2;
4482 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4483
4484 if (!vrf)
4485 return CMD_WARNING;
4486
4487 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
4488
4489 return CMD_SUCCESS;
4490 }
4491
4492 DEFUN (show_ip_multicast_vrf_all,
4493 show_ip_multicast_vrf_all_cmd,
4494 "show ip multicast vrf all",
4495 SHOW_STR
4496 IP_STR
4497 VRF_CMD_HELP_STR
4498 "Multicast global information\n")
4499 {
4500 bool uj = use_json(argc, argv);
4501 struct vrf *vrf;
4502 bool first = true;
4503
4504 if (uj)
4505 vty_out(vty, "{ ");
4506 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4507 if (uj) {
4508 if (!first)
4509 vty_out(vty, ", ");
4510 vty_out(vty, " \"%s\": ", vrf->name);
4511 first = false;
4512 } else
4513 vty_out(vty, "VRF: %s\n", vrf->name);
4514 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
4515 }
4516 if (uj)
4517 vty_out(vty, "}\n");
4518
4519 return CMD_SUCCESS;
4520 }
4521
4522 static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill,
4523 bool uj)
4524 {
4525 struct listnode *node;
4526 struct channel_oil *c_oil;
4527 struct static_route *s_route;
4528 time_t now;
4529 json_object *json = NULL;
4530 json_object *json_group = NULL;
4531 json_object *json_source = NULL;
4532 json_object *json_oil = NULL;
4533 json_object *json_ifp_out = NULL;
4534 int found_oif;
4535 int first;
4536 char grp_str[INET_ADDRSTRLEN];
4537 char src_str[INET_ADDRSTRLEN];
4538 char in_ifname[INTERFACE_NAMSIZ + 1];
4539 char out_ifname[INTERFACE_NAMSIZ + 1];
4540 int oif_vif_index;
4541 struct interface *ifp_in;
4542 char proto[100];
4543
4544 if (uj) {
4545 json = json_object_new_object();
4546 } else {
4547 vty_out(vty,
4548 "Source Group Proto Input Output TTL Uptime\n");
4549 }
4550
4551 now = pim_time_monotonic_sec();
4552
4553 /* print list of PIM and IGMP routes */
4554 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
4555 found_oif = 0;
4556 first = 1;
4557 if (!c_oil->installed && !uj)
4558 continue;
4559
4560 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
4561 sizeof(grp_str));
4562 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
4563 sizeof(src_str));
4564 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
4565
4566 if (ifp_in)
4567 strcpy(in_ifname, ifp_in->name);
4568 else
4569 strcpy(in_ifname, "<iif?>");
4570
4571 if (uj) {
4572
4573 /* Find the group, create it if it doesn't exist */
4574 json_object_object_get_ex(json, grp_str, &json_group);
4575
4576 if (!json_group) {
4577 json_group = json_object_new_object();
4578 json_object_object_add(json, grp_str,
4579 json_group);
4580 }
4581
4582 /* Find the source nested under the group, create it if
4583 * it doesn't exist */
4584 json_object_object_get_ex(json_group, src_str,
4585 &json_source);
4586
4587 if (!json_source) {
4588 json_source = json_object_new_object();
4589 json_object_object_add(json_group, src_str,
4590 json_source);
4591 }
4592
4593 /* Find the inbound interface nested under the source,
4594 * create it if it doesn't exist */
4595 json_object_int_add(json_source, "installed",
4596 c_oil->installed);
4597 json_object_int_add(json_source, "refCount",
4598 c_oil->oil_ref_count);
4599 json_object_int_add(json_source, "oilSize",
4600 c_oil->oil_size);
4601 json_object_int_add(json_source, "OilInheritedRescan",
4602 c_oil->oil_inherited_rescan);
4603 json_object_string_add(json_source, "iif", in_ifname);
4604 json_oil = NULL;
4605 }
4606
4607 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
4608 ++oif_vif_index) {
4609 struct interface *ifp_out;
4610 char mroute_uptime[10];
4611 int ttl;
4612
4613 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
4614 if (ttl < 1)
4615 continue;
4616
4617 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
4618 pim_time_uptime(
4619 mroute_uptime, sizeof(mroute_uptime),
4620 now - c_oil->mroute_creation);
4621 found_oif = 1;
4622
4623 if (ifp_out)
4624 strcpy(out_ifname, ifp_out->name);
4625 else
4626 strcpy(out_ifname, "<oif?>");
4627
4628 if (uj) {
4629 json_ifp_out = json_object_new_object();
4630 json_object_string_add(json_ifp_out, "source",
4631 src_str);
4632 json_object_string_add(json_ifp_out, "group",
4633 grp_str);
4634
4635 if (c_oil->oif_flags[oif_vif_index]
4636 & PIM_OIF_FLAG_PROTO_PIM)
4637 json_object_boolean_true_add(
4638 json_ifp_out, "protocolPim");
4639
4640 if (c_oil->oif_flags[oif_vif_index]
4641 & PIM_OIF_FLAG_PROTO_IGMP)
4642 json_object_boolean_true_add(
4643 json_ifp_out, "protocolIgmp");
4644
4645 if (c_oil->oif_flags[oif_vif_index]
4646 & PIM_OIF_FLAG_PROTO_SOURCE)
4647 json_object_boolean_true_add(
4648 json_ifp_out, "protocolSource");
4649
4650 if (c_oil->oif_flags[oif_vif_index]
4651 & PIM_OIF_FLAG_PROTO_STAR)
4652 json_object_boolean_true_add(
4653 json_ifp_out,
4654 "protocolInherited");
4655
4656 json_object_string_add(json_ifp_out,
4657 "inboundInterface",
4658 in_ifname);
4659 json_object_int_add(json_ifp_out, "iVifI",
4660 c_oil->oil.mfcc_parent);
4661 json_object_string_add(json_ifp_out,
4662 "outboundInterface",
4663 out_ifname);
4664 json_object_int_add(json_ifp_out, "oVifI",
4665 oif_vif_index);
4666 json_object_int_add(json_ifp_out, "ttl", ttl);
4667 json_object_string_add(json_ifp_out, "upTime",
4668 mroute_uptime);
4669 if (!json_oil) {
4670 json_oil = json_object_new_object();
4671 json_object_object_add(json_source,
4672 "oil", json_oil);
4673 }
4674 json_object_object_add(json_oil, out_ifname,
4675 json_ifp_out);
4676 } else {
4677 if (c_oil->oif_flags[oif_vif_index]
4678 & PIM_OIF_FLAG_PROTO_PIM) {
4679 strcpy(proto, "PIM");
4680 }
4681
4682 if (c_oil->oif_flags[oif_vif_index]
4683 & PIM_OIF_FLAG_PROTO_IGMP) {
4684 strcpy(proto, "IGMP");
4685 }
4686
4687 if (c_oil->oif_flags[oif_vif_index]
4688 & PIM_OIF_FLAG_PROTO_SOURCE) {
4689 strcpy(proto, "SRC");
4690 }
4691
4692 if (c_oil->oif_flags[oif_vif_index]
4693 & PIM_OIF_FLAG_PROTO_STAR) {
4694 strcpy(proto, "STAR");
4695 }
4696
4697 vty_out(vty,
4698 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4699 src_str, grp_str, proto, in_ifname,
4700 out_ifname, ttl, mroute_uptime);
4701
4702 if (first) {
4703 src_str[0] = '\0';
4704 grp_str[0] = '\0';
4705 in_ifname[0] = '\0';
4706 first = 0;
4707 }
4708 }
4709 }
4710
4711 if (!uj && !found_oif) {
4712 vty_out(vty, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
4713 src_str, grp_str, "none", in_ifname, "none", 0,
4714 "--:--:--");
4715 }
4716 }
4717
4718 /* Print list of static routes */
4719 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
4720 first = 1;
4721
4722 if (!s_route->c_oil.installed)
4723 continue;
4724
4725 pim_inet4_dump("<group?>", s_route->group, grp_str,
4726 sizeof(grp_str));
4727 pim_inet4_dump("<source?>", s_route->source, src_str,
4728 sizeof(src_str));
4729 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
4730 found_oif = 0;
4731
4732 if (ifp_in)
4733 strcpy(in_ifname, ifp_in->name);
4734 else
4735 strcpy(in_ifname, "<iif?>");
4736
4737 if (uj) {
4738
4739 /* Find the group, create it if it doesn't exist */
4740 json_object_object_get_ex(json, grp_str, &json_group);
4741
4742 if (!json_group) {
4743 json_group = json_object_new_object();
4744 json_object_object_add(json, grp_str,
4745 json_group);
4746 }
4747
4748 /* Find the source nested under the group, create it if
4749 * it doesn't exist */
4750 json_object_object_get_ex(json_group, src_str,
4751 &json_source);
4752
4753 if (!json_source) {
4754 json_source = json_object_new_object();
4755 json_object_object_add(json_group, src_str,
4756 json_source);
4757 }
4758
4759 json_object_string_add(json_source, "iif", in_ifname);
4760 json_oil = NULL;
4761 } else {
4762 strcpy(proto, "STATIC");
4763 }
4764
4765 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
4766 ++oif_vif_index) {
4767 struct interface *ifp_out;
4768 char oif_uptime[10];
4769 int ttl;
4770
4771 ttl = s_route->oif_ttls[oif_vif_index];
4772 if (ttl < 1)
4773 continue;
4774
4775 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
4776 pim_time_uptime(
4777 oif_uptime, sizeof(oif_uptime),
4778 now
4779 - s_route->c_oil
4780 .oif_creation[oif_vif_index]);
4781 found_oif = 1;
4782
4783 if (ifp_out)
4784 strcpy(out_ifname, ifp_out->name);
4785 else
4786 strcpy(out_ifname, "<oif?>");
4787
4788 if (uj) {
4789 json_ifp_out = json_object_new_object();
4790 json_object_string_add(json_ifp_out, "source",
4791 src_str);
4792 json_object_string_add(json_ifp_out, "group",
4793 grp_str);
4794 json_object_boolean_true_add(json_ifp_out,
4795 "protocolStatic");
4796 json_object_string_add(json_ifp_out,
4797 "inboundInterface",
4798 in_ifname);
4799 json_object_int_add(
4800 json_ifp_out, "iVifI",
4801 s_route->c_oil.oil.mfcc_parent);
4802 json_object_string_add(json_ifp_out,
4803 "outboundInterface",
4804 out_ifname);
4805 json_object_int_add(json_ifp_out, "oVifI",
4806 oif_vif_index);
4807 json_object_int_add(json_ifp_out, "ttl", ttl);
4808 json_object_string_add(json_ifp_out, "upTime",
4809 oif_uptime);
4810 if (!json_oil) {
4811 json_oil = json_object_new_object();
4812 json_object_object_add(json_source,
4813 "oil", json_oil);
4814 }
4815 json_object_object_add(json_oil, out_ifname,
4816 json_ifp_out);
4817 } else {
4818 vty_out(vty,
4819 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4820 src_str, grp_str, proto, in_ifname,
4821 out_ifname, ttl, oif_uptime,
4822 pim->vrf->name);
4823 if (first && !fill) {
4824 src_str[0] = '\0';
4825 grp_str[0] = '\0';
4826 in_ifname[0] = '\0';
4827 first = 0;
4828 }
4829 }
4830 }
4831
4832 if (!uj && !found_oif) {
4833 vty_out(vty,
4834 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
4835 src_str, grp_str, proto, in_ifname, "none", 0,
4836 "--:--:--", pim->vrf->name);
4837 }
4838 }
4839
4840 if (uj) {
4841 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4842 json, JSON_C_TO_STRING_PRETTY));
4843 json_object_free(json);
4844 }
4845 }
4846
4847 DEFUN (show_ip_mroute,
4848 show_ip_mroute_cmd,
4849 "show ip mroute [vrf NAME] [fill] [json]",
4850 SHOW_STR
4851 IP_STR
4852 MROUTE_STR
4853 VRF_CMD_HELP_STR
4854 "Fill in Assumed data\n"
4855 JSON_STR)
4856 {
4857 bool uj = use_json(argc, argv);
4858 bool fill = false;
4859 int idx = 2;
4860 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4861
4862 if (!vrf)
4863 return CMD_WARNING;
4864
4865 if (argv_find(argv, argc, "fill", &idx))
4866 fill = true;
4867
4868 show_mroute(vrf->info, vty, fill, uj);
4869 return CMD_SUCCESS;
4870 }
4871
4872 DEFUN (show_ip_mroute_vrf_all,
4873 show_ip_mroute_vrf_all_cmd,
4874 "show ip mroute vrf all [fill] [json]",
4875 SHOW_STR
4876 IP_STR
4877 MROUTE_STR
4878 VRF_CMD_HELP_STR
4879 "Fill in Assumed data\n"
4880 JSON_STR)
4881 {
4882 bool uj = use_json(argc, argv);
4883 int idx = 4;
4884 struct vrf *vrf;
4885 bool first = true;
4886 bool fill = false;
4887
4888 if (argv_find(argv, argc, "fill", &idx))
4889 fill = true;
4890
4891 if (uj)
4892 vty_out(vty, "{ ");
4893 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4894 if (uj) {
4895 if (!first)
4896 vty_out(vty, ", ");
4897 vty_out(vty, " \"%s\": ", vrf->name);
4898 first = false;
4899 } else
4900 vty_out(vty, "VRF: %s\n", vrf->name);
4901 show_mroute(vrf->info, vty, fill, uj);
4902 }
4903 if (uj)
4904 vty_out(vty, "}\n");
4905
4906 return CMD_SUCCESS;
4907 }
4908
4909 static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
4910 {
4911 struct listnode *node;
4912 struct channel_oil *c_oil;
4913 struct static_route *s_route;
4914
4915 vty_out(vty, "\n");
4916
4917 vty_out(vty,
4918 "Source Group LastUsed Packets Bytes WrongIf \n");
4919
4920 /* Print PIM and IGMP route counts */
4921 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
4922 char group_str[INET_ADDRSTRLEN];
4923 char source_str[INET_ADDRSTRLEN];
4924
4925 if (!c_oil->installed)
4926 continue;
4927
4928 pim_mroute_update_counters(c_oil);
4929
4930 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
4931 sizeof(group_str));
4932 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
4933 sizeof(source_str));
4934
4935 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4936 source_str, group_str, c_oil->cc.lastused / 100,
4937 c_oil->cc.pktcnt, c_oil->cc.bytecnt,
4938 c_oil->cc.wrong_if);
4939 }
4940
4941 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
4942 char group_str[INET_ADDRSTRLEN];
4943 char source_str[INET_ADDRSTRLEN];
4944
4945 if (!s_route->c_oil.installed)
4946 continue;
4947
4948 pim_mroute_update_counters(&s_route->c_oil);
4949
4950 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp,
4951 group_str, sizeof(group_str));
4952 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin,
4953 source_str, sizeof(source_str));
4954
4955 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
4956 source_str, group_str, s_route->c_oil.cc.lastused,
4957 s_route->c_oil.cc.pktcnt, s_route->c_oil.cc.bytecnt,
4958 s_route->c_oil.cc.wrong_if);
4959 }
4960 }
4961
4962 DEFUN (show_ip_mroute_count,
4963 show_ip_mroute_count_cmd,
4964 "show ip mroute [vrf NAME] count",
4965 SHOW_STR
4966 IP_STR
4967 MROUTE_STR
4968 VRF_CMD_HELP_STR
4969 "Route and packet count data\n")
4970 {
4971 int idx = 2;
4972 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4973
4974 if (!vrf)
4975 return CMD_WARNING;
4976
4977 show_mroute_count(vrf->info, vty);
4978 return CMD_SUCCESS;
4979 }
4980
4981 DEFUN (show_ip_mroute_count_vrf_all,
4982 show_ip_mroute_count_vrf_all_cmd,
4983 "show ip mroute vrf all count",
4984 SHOW_STR
4985 IP_STR
4986 MROUTE_STR
4987 VRF_CMD_HELP_STR
4988 "Route and packet count data\n")
4989 {
4990 bool uj = use_json(argc, argv);
4991 struct vrf *vrf;
4992 bool first = true;
4993
4994 if (uj)
4995 vty_out(vty, "{ ");
4996 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4997 if (uj) {
4998 if (!first)
4999 vty_out(vty, ", ");
5000 vty_out(vty, " \"%s\": ", vrf->name);
5001 first = false;
5002 } else
5003 vty_out(vty, "VRF: %s\n", vrf->name);
5004 show_mroute_count(vrf->info, vty);
5005 }
5006 if (uj)
5007 vty_out(vty, "}\n");
5008
5009 return CMD_SUCCESS;
5010 }
5011
5012 DEFUN (show_ip_rib,
5013 show_ip_rib_cmd,
5014 "show ip rib [vrf NAME] A.B.C.D",
5015 SHOW_STR
5016 IP_STR
5017 RIB_STR
5018 VRF_CMD_HELP_STR
5019 "Unicast address\n")
5020 {
5021 int idx = 2;
5022 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5023 struct in_addr addr;
5024 const char *addr_str;
5025 struct pim_nexthop nexthop;
5026 char nexthop_addr_str[PREFIX_STRLEN];
5027 int result;
5028
5029 if (!vrf)
5030 return CMD_WARNING;
5031
5032 memset(&nexthop, 0, sizeof(nexthop));
5033 argv_find(argv, argc, "A.B.C.D", &idx);
5034 addr_str = argv[idx]->arg;
5035 result = inet_pton(AF_INET, addr_str, &addr);
5036 if (result <= 0) {
5037 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5038 errno, safe_strerror(errno));
5039 return CMD_WARNING;
5040 }
5041
5042 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
5043 vty_out(vty,
5044 "Failure querying RIB nexthop for unicast address %s\n",
5045 addr_str);
5046 return CMD_WARNING;
5047 }
5048
5049 vty_out(vty,
5050 "Address NextHop Interface Metric Preference\n");
5051
5052 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
5053 nexthop_addr_str, sizeof(nexthop_addr_str));
5054
5055 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
5056 nexthop.interface ? nexthop.interface->name : "<ifname?>",
5057 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
5058
5059 return CMD_SUCCESS;
5060 }
5061
5062 static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
5063 {
5064 struct listnode *node;
5065 struct ssmpingd_sock *ss;
5066 time_t now;
5067
5068 vty_out(vty,
5069 "Source Socket Address Port Uptime Requests\n");
5070
5071 if (!pim->ssmpingd_list)
5072 return;
5073
5074 now = pim_time_monotonic_sec();
5075
5076 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
5077 char source_str[INET_ADDRSTRLEN];
5078 char ss_uptime[10];
5079 struct sockaddr_in bind_addr;
5080 socklen_t len = sizeof(bind_addr);
5081 char bind_addr_str[INET_ADDRSTRLEN];
5082
5083 pim_inet4_dump("<src?>", ss->source_addr, source_str,
5084 sizeof(source_str));
5085
5086 if (pim_socket_getsockname(
5087 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
5088 vty_out(vty,
5089 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
5090 source_str, ss->sock_fd);
5091 }
5092
5093 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
5094 sizeof(bind_addr_str));
5095 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
5096 now - ss->creation);
5097
5098 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
5099 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
5100 ss_uptime, (long long)ss->requests);
5101 }
5102 }
5103
5104 DEFUN (show_ip_ssmpingd,
5105 show_ip_ssmpingd_cmd,
5106 "show ip ssmpingd [vrf NAME]",
5107 SHOW_STR
5108 IP_STR
5109 SHOW_SSMPINGD_STR
5110 VRF_CMD_HELP_STR)
5111 {
5112 int idx = 2;
5113 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5114
5115 if (!vrf)
5116 return CMD_WARNING;
5117
5118 show_ssmpingd(vrf->info, vty);
5119 return CMD_SUCCESS;
5120 }
5121
5122 static int pim_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
5123 const char *rp, const char *group,
5124 const char *plist)
5125 {
5126 int result;
5127
5128 result = pim_rp_new(pim, rp, group, plist);
5129
5130 if (result == PIM_GROUP_BAD_ADDRESS) {
5131 vty_out(vty, "%% Bad group address specified: %s\n", group);
5132 return CMD_WARNING_CONFIG_FAILED;
5133 }
5134
5135 if (result == PIM_RP_BAD_ADDRESS) {
5136 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
5137 return CMD_WARNING_CONFIG_FAILED;
5138 }
5139
5140 if (result == PIM_RP_NO_PATH) {
5141 vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
5142 return CMD_WARNING;
5143 }
5144
5145 if (result == PIM_GROUP_OVERLAP) {
5146 vty_out(vty,
5147 "%% Group range specified cannot exact match another\n");
5148 return CMD_WARNING_CONFIG_FAILED;
5149 }
5150
5151 if (result == PIM_GROUP_PFXLIST_OVERLAP) {
5152 vty_out(vty,
5153 "%% This group is already covered by a RP prefix-list\n");
5154 return CMD_WARNING_CONFIG_FAILED;
5155 }
5156
5157 if (result == PIM_RP_PFXLIST_IN_USE) {
5158 vty_out(vty,
5159 "%% The same prefix-list cannot be applied to multiple RPs\n");
5160 return CMD_WARNING_CONFIG_FAILED;
5161 }
5162
5163 if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
5164 vty_out(vty, "%% Inconsistent address and mask: %s\n",
5165 group);
5166 return CMD_WARNING_CONFIG_FAILED;
5167 }
5168
5169 return CMD_SUCCESS;
5170 }
5171
5172 static int pim_cmd_spt_switchover(struct pim_instance *pim,
5173 enum pim_spt_switchover spt,
5174 const char *plist)
5175 {
5176 pim->spt.switchover = spt;
5177
5178 switch (pim->spt.switchover) {
5179 case PIM_SPT_IMMEDIATE:
5180 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
5181
5182 pim_upstream_add_lhr_star_pimreg(pim);
5183 break;
5184 case PIM_SPT_INFINITY:
5185 pim_upstream_remove_lhr_star_pimreg(pim, plist);
5186
5187 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
5188
5189 if (plist)
5190 pim->spt.plist =
5191 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
5192 break;
5193 }
5194
5195 return CMD_SUCCESS;
5196 }
5197
5198 DEFUN (ip_pim_spt_switchover_infinity,
5199 ip_pim_spt_switchover_infinity_cmd,
5200 "ip pim spt-switchover infinity-and-beyond",
5201 IP_STR
5202 PIM_STR
5203 "SPT-Switchover\n"
5204 "Never switch to SPT Tree\n")
5205 {
5206 PIM_DECLVAR_CONTEXT(vrf, pim);
5207 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, NULL);
5208 }
5209
5210 DEFUN (ip_pim_spt_switchover_infinity_plist,
5211 ip_pim_spt_switchover_infinity_plist_cmd,
5212 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5213 IP_STR
5214 PIM_STR
5215 "SPT-Switchover\n"
5216 "Never switch to SPT Tree\n"
5217 "Prefix-List to control which groups to switch\n"
5218 "Prefix-List name\n")
5219 {
5220 PIM_DECLVAR_CONTEXT(vrf, pim);
5221 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, argv[5]->arg);
5222 }
5223
5224 DEFUN (no_ip_pim_spt_switchover_infinity,
5225 no_ip_pim_spt_switchover_infinity_cmd,
5226 "no ip pim spt-switchover infinity-and-beyond",
5227 NO_STR
5228 IP_STR
5229 PIM_STR
5230 "SPT_Switchover\n"
5231 "Never switch to SPT Tree\n")
5232 {
5233 PIM_DECLVAR_CONTEXT(vrf, pim);
5234 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
5235 }
5236
5237 DEFUN (no_ip_pim_spt_switchover_infinity_plist,
5238 no_ip_pim_spt_switchover_infinity_plist_cmd,
5239 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
5240 NO_STR
5241 IP_STR
5242 PIM_STR
5243 "SPT_Switchover\n"
5244 "Never switch to SPT Tree\n"
5245 "Prefix-List to control which groups to switch\n"
5246 "Prefix-List name\n")
5247 {
5248 PIM_DECLVAR_CONTEXT(vrf, pim);
5249 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
5250 }
5251
5252 DEFUN (ip_pim_joinprune_time,
5253 ip_pim_joinprune_time_cmd,
5254 "ip pim join-prune-interval (60-600)",
5255 IP_STR
5256 "pim multicast routing\n"
5257 "Join Prune Send Interval\n"
5258 "Seconds\n")
5259 {
5260 PIM_DECLVAR_CONTEXT(vrf, pim);
5261 router->t_periodic = atoi(argv[3]->arg);
5262 return CMD_SUCCESS;
5263 }
5264
5265 DEFUN (no_ip_pim_joinprune_time,
5266 no_ip_pim_joinprune_time_cmd,
5267 "no ip pim join-prune-interval (60-600)",
5268 NO_STR
5269 IP_STR
5270 "pim multicast routing\n"
5271 "Join Prune Send Interval\n"
5272 "Seconds\n")
5273 {
5274 PIM_DECLVAR_CONTEXT(vrf, pim);
5275 router->t_periodic = PIM_DEFAULT_T_PERIODIC;
5276 return CMD_SUCCESS;
5277 }
5278
5279 DEFUN (ip_pim_register_suppress,
5280 ip_pim_register_suppress_cmd,
5281 "ip pim register-suppress-time (5-60000)",
5282 IP_STR
5283 "pim multicast routing\n"
5284 "Register Suppress Timer\n"
5285 "Seconds\n")
5286 {
5287 PIM_DECLVAR_CONTEXT(vrf, pim);
5288 router->register_suppress_time = atoi(argv[3]->arg);
5289 return CMD_SUCCESS;
5290 }
5291
5292 DEFUN (no_ip_pim_register_suppress,
5293 no_ip_pim_register_suppress_cmd,
5294 "no ip pim register-suppress-time (5-60000)",
5295 NO_STR
5296 IP_STR
5297 "pim multicast routing\n"
5298 "Register Suppress Timer\n"
5299 "Seconds\n")
5300 {
5301 PIM_DECLVAR_CONTEXT(vrf, pim);
5302 router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
5303 return CMD_SUCCESS;
5304 }
5305
5306 DEFUN (ip_pim_rp_keep_alive,
5307 ip_pim_rp_keep_alive_cmd,
5308 "ip pim rp keep-alive-timer (31-60000)",
5309 IP_STR
5310 "pim multicast routing\n"
5311 "Rendevous Point\n"
5312 "Keep alive Timer\n"
5313 "Seconds\n")
5314 {
5315 PIM_DECLVAR_CONTEXT(vrf, pim);
5316 pim->rp_keep_alive_time = atoi(argv[4]->arg);
5317 return CMD_SUCCESS;
5318 }
5319
5320 DEFUN (no_ip_pim_rp_keep_alive,
5321 no_ip_pim_rp_keep_alive_cmd,
5322 "no ip pim rp keep-alive-timer (31-60000)",
5323 NO_STR
5324 IP_STR
5325 "pim multicast routing\n"
5326 "Rendevous Point\n"
5327 "Keep alive Timer\n"
5328 "Seconds\n")
5329 {
5330 PIM_DECLVAR_CONTEXT(vrf, pim);
5331 pim->rp_keep_alive_time = PIM_KEEPALIVE_PERIOD;
5332 return CMD_SUCCESS;
5333 }
5334
5335 DEFUN (ip_pim_keep_alive,
5336 ip_pim_keep_alive_cmd,
5337 "ip pim keep-alive-timer (31-60000)",
5338 IP_STR
5339 "pim multicast routing\n"
5340 "Keep alive Timer\n"
5341 "Seconds\n")
5342 {
5343 PIM_DECLVAR_CONTEXT(vrf, pim);
5344 pim->keep_alive_time = atoi(argv[3]->arg);
5345 return CMD_SUCCESS;
5346 }
5347
5348 DEFUN (no_ip_pim_keep_alive,
5349 no_ip_pim_keep_alive_cmd,
5350 "no ip pim keep-alive-timer (31-60000)",
5351 NO_STR
5352 IP_STR
5353 "pim multicast routing\n"
5354 "Keep alive Timer\n"
5355 "Seconds\n")
5356 {
5357 PIM_DECLVAR_CONTEXT(vrf, pim);
5358 pim->keep_alive_time = PIM_KEEPALIVE_PERIOD;
5359 return CMD_SUCCESS;
5360 }
5361
5362 DEFUN (ip_pim_packets,
5363 ip_pim_packets_cmd,
5364 "ip pim packets (1-100)",
5365 IP_STR
5366 "pim multicast routing\n"
5367 "packets to process at one time per fd\n"
5368 "Number of packets\n")
5369 {
5370 PIM_DECLVAR_CONTEXT(vrf, pim);
5371 router->packet_process = atoi(argv[3]->arg);
5372 return CMD_SUCCESS;
5373 }
5374
5375 DEFUN (no_ip_pim_packets,
5376 no_ip_pim_packets_cmd,
5377 "no ip pim packets (1-100)",
5378 NO_STR
5379 IP_STR
5380 "pim multicast routing\n"
5381 "packets to process at one time per fd\n"
5382 "Number of packets\n")
5383 {
5384 PIM_DECLVAR_CONTEXT(vrf, pim);
5385 router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
5386 return CMD_SUCCESS;
5387 }
5388
5389 DEFUN (ip_pim_v6_secondary,
5390 ip_pim_v6_secondary_cmd,
5391 "ip pim send-v6-secondary",
5392 IP_STR
5393 "pim multicast routing\n"
5394 "Send v6 secondary addresses\n")
5395 {
5396 PIM_DECLVAR_CONTEXT(vrf, pim);
5397 pim->send_v6_secondary = 1;
5398
5399 return CMD_SUCCESS;
5400 }
5401
5402 DEFUN (no_ip_pim_v6_secondary,
5403 no_ip_pim_v6_secondary_cmd,
5404 "no ip pim send-v6-secondary",
5405 NO_STR
5406 IP_STR
5407 "pim multicast routing\n"
5408 "Send v6 secondary addresses\n")
5409 {
5410 PIM_DECLVAR_CONTEXT(vrf, pim);
5411 pim->send_v6_secondary = 0;
5412
5413 return CMD_SUCCESS;
5414 }
5415
5416 DEFUN (ip_pim_rp,
5417 ip_pim_rp_cmd,
5418 "ip pim rp A.B.C.D [A.B.C.D/M]",
5419 IP_STR
5420 "pim multicast routing\n"
5421 "Rendevous Point\n"
5422 "ip address of RP\n"
5423 "Group Address range to cover\n")
5424 {
5425 PIM_DECLVAR_CONTEXT(vrf, pim);
5426 int idx_ipv4 = 3;
5427
5428 if (argc == (idx_ipv4 + 1))
5429 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
5430 NULL);
5431 else
5432 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
5433 argv[idx_ipv4 + 1]->arg, NULL);
5434 }
5435
5436 DEFUN (ip_pim_rp_prefix_list,
5437 ip_pim_rp_prefix_list_cmd,
5438 "ip pim rp A.B.C.D prefix-list WORD",
5439 IP_STR
5440 "pim multicast routing\n"
5441 "Rendevous Point\n"
5442 "ip address of RP\n"
5443 "group prefix-list filter\n"
5444 "Name of a prefix-list\n")
5445 {
5446 PIM_DECLVAR_CONTEXT(vrf, pim);
5447 return pim_rp_cmd_worker(pim, vty, argv[3]->arg, NULL, argv[5]->arg);
5448 }
5449
5450 static int pim_no_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
5451 const char *rp, const char *group,
5452 const char *plist)
5453 {
5454 int result = pim_rp_del(pim, rp, group, plist);
5455
5456 if (result == PIM_GROUP_BAD_ADDRESS) {
5457 vty_out(vty, "%% Bad group address specified: %s\n", group);
5458 return CMD_WARNING_CONFIG_FAILED;
5459 }
5460
5461 if (result == PIM_RP_BAD_ADDRESS) {
5462 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
5463 return CMD_WARNING_CONFIG_FAILED;
5464 }
5465
5466 if (result == PIM_RP_NOT_FOUND) {
5467 vty_out(vty, "%% Unable to find specified RP\n");
5468 return CMD_WARNING_CONFIG_FAILED;
5469 }
5470
5471 return CMD_SUCCESS;
5472 }
5473
5474 DEFUN (no_ip_pim_rp,
5475 no_ip_pim_rp_cmd,
5476 "no ip pim rp A.B.C.D [A.B.C.D/M]",
5477 NO_STR
5478 IP_STR
5479 "pim multicast routing\n"
5480 "Rendevous Point\n"
5481 "ip address of RP\n"
5482 "Group Address range to cover\n")
5483 {
5484 PIM_DECLVAR_CONTEXT(vrf, pim);
5485 int idx_ipv4 = 4, idx_group = 0;
5486
5487 if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
5488 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
5489 argv[idx_group]->arg, NULL);
5490 else
5491 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
5492 NULL);
5493 }
5494
5495 DEFUN (no_ip_pim_rp_prefix_list,
5496 no_ip_pim_rp_prefix_list_cmd,
5497 "no ip pim rp A.B.C.D prefix-list WORD",
5498 NO_STR
5499 IP_STR
5500 "pim multicast routing\n"
5501 "Rendevous Point\n"
5502 "ip address of RP\n"
5503 "group prefix-list filter\n"
5504 "Name of a prefix-list\n")
5505 {
5506 PIM_DECLVAR_CONTEXT(vrf, pim);
5507 return pim_no_rp_cmd_worker(pim, vty, argv[4]->arg, NULL, argv[6]->arg);
5508 }
5509
5510 static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
5511 const char *plist)
5512 {
5513 int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
5514
5515 if (result == PIM_SSM_ERR_NONE)
5516 return CMD_SUCCESS;
5517
5518 switch (result) {
5519 case PIM_SSM_ERR_NO_VRF:
5520 vty_out(vty, "%% VRF doesn't exist\n");
5521 break;
5522 case PIM_SSM_ERR_DUP:
5523 vty_out(vty, "%% duplicate config\n");
5524 break;
5525 default:
5526 vty_out(vty, "%% ssm range config failed\n");
5527 }
5528
5529 return CMD_WARNING_CONFIG_FAILED;
5530 }
5531
5532 DEFUN (ip_pim_ssm_prefix_list,
5533 ip_pim_ssm_prefix_list_cmd,
5534 "ip pim ssm prefix-list WORD",
5535 IP_STR
5536 "pim multicast routing\n"
5537 "Source Specific Multicast\n"
5538 "group range prefix-list filter\n"
5539 "Name of a prefix-list\n")
5540 {
5541 PIM_DECLVAR_CONTEXT(vrf, pim);
5542 return pim_ssm_cmd_worker(pim, vty, argv[4]->arg);
5543 }
5544
5545 DEFUN (no_ip_pim_ssm_prefix_list,
5546 no_ip_pim_ssm_prefix_list_cmd,
5547 "no ip pim ssm prefix-list",
5548 NO_STR
5549 IP_STR
5550 "pim multicast routing\n"
5551 "Source Specific Multicast\n"
5552 "group range prefix-list filter\n")
5553 {
5554 PIM_DECLVAR_CONTEXT(vrf, pim);
5555 return pim_ssm_cmd_worker(pim, vty, NULL);
5556 }
5557
5558 DEFUN (no_ip_pim_ssm_prefix_list_name,
5559 no_ip_pim_ssm_prefix_list_name_cmd,
5560 "no ip pim ssm prefix-list WORD",
5561 NO_STR
5562 IP_STR
5563 "pim multicast routing\n"
5564 "Source Specific Multicast\n"
5565 "group range prefix-list filter\n"
5566 "Name of a prefix-list\n")
5567 {
5568 PIM_DECLVAR_CONTEXT(vrf, pim);
5569 struct pim_ssm *ssm = pim->ssm_info;
5570
5571 if (ssm->plist_name && !strcmp(ssm->plist_name, argv[5]->arg))
5572 return pim_ssm_cmd_worker(pim, vty, NULL);
5573
5574 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
5575
5576 return CMD_WARNING_CONFIG_FAILED;
5577 }
5578
5579 static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
5580 struct vty *vty, bool uj)
5581 {
5582 struct pim_ssm *ssm = pim->ssm_info;
5583 const char *range_str =
5584 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
5585
5586 if (uj) {
5587 json_object *json;
5588 json = json_object_new_object();
5589 json_object_string_add(json, "ssmGroups", range_str);
5590 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5591 json, JSON_C_TO_STRING_PRETTY));
5592 json_object_free(json);
5593 } else
5594 vty_out(vty, "SSM group range : %s\n", range_str);
5595 }
5596
5597 DEFUN (show_ip_pim_ssm_range,
5598 show_ip_pim_ssm_range_cmd,
5599 "show ip pim [vrf NAME] group-type [json]",
5600 SHOW_STR
5601 IP_STR
5602 PIM_STR
5603 VRF_CMD_HELP_STR
5604 "PIM group type\n"
5605 JSON_STR)
5606 {
5607 int idx = 2;
5608 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5609 bool uj = use_json(argc, argv);
5610
5611 if (!vrf)
5612 return CMD_WARNING;
5613
5614 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
5615
5616 return CMD_SUCCESS;
5617 }
5618
5619 static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
5620 struct vty *vty, bool uj,
5621 const char *group)
5622 {
5623 struct in_addr group_addr;
5624 const char *type_str;
5625 int result;
5626
5627 result = inet_pton(AF_INET, group, &group_addr);
5628 if (result <= 0)
5629 type_str = "invalid";
5630 else {
5631 if (pim_is_group_224_4(group_addr))
5632 type_str =
5633 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
5634 else
5635 type_str = "not-multicast";
5636 }
5637
5638 if (uj) {
5639 json_object *json;
5640 json = json_object_new_object();
5641 json_object_string_add(json, "groupType", type_str);
5642 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5643 json, JSON_C_TO_STRING_PRETTY));
5644 json_object_free(json);
5645 } else
5646 vty_out(vty, "Group type : %s\n", type_str);
5647 }
5648
5649 DEFUN (show_ip_pim_group_type,
5650 show_ip_pim_group_type_cmd,
5651 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
5652 SHOW_STR
5653 IP_STR
5654 PIM_STR
5655 VRF_CMD_HELP_STR
5656 "multicast group type\n"
5657 "group address\n"
5658 JSON_STR)
5659 {
5660 int idx = 2;
5661 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5662 bool uj = use_json(argc, argv);
5663
5664 if (!vrf)
5665 return CMD_WARNING;
5666
5667 argv_find(argv, argc, "A.B.C.D", &idx);
5668 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
5669
5670 return CMD_SUCCESS;
5671 }
5672
5673 DEFUN (ip_ssmpingd,
5674 ip_ssmpingd_cmd,
5675 "ip ssmpingd [A.B.C.D]",
5676 IP_STR
5677 CONF_SSMPINGD_STR
5678 "Source address\n")
5679 {
5680 PIM_DECLVAR_CONTEXT(vrf, pim);
5681 int idx_ipv4 = 2;
5682 int result;
5683 struct in_addr source_addr;
5684 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
5685
5686 result = inet_pton(AF_INET, source_str, &source_addr);
5687 if (result <= 0) {
5688 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
5689 source_str, errno, safe_strerror(errno));
5690 return CMD_WARNING_CONFIG_FAILED;
5691 }
5692
5693 result = pim_ssmpingd_start(pim, source_addr);
5694 if (result) {
5695 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
5696 source_str, result);
5697 return CMD_WARNING_CONFIG_FAILED;
5698 }
5699
5700 return CMD_SUCCESS;
5701 }
5702
5703 DEFUN (no_ip_ssmpingd,
5704 no_ip_ssmpingd_cmd,
5705 "no ip ssmpingd [A.B.C.D]",
5706 NO_STR
5707 IP_STR
5708 CONF_SSMPINGD_STR
5709 "Source address\n")
5710 {
5711 PIM_DECLVAR_CONTEXT(vrf, pim);
5712 int idx_ipv4 = 3;
5713 int result;
5714 struct in_addr source_addr;
5715 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
5716
5717 result = inet_pton(AF_INET, source_str, &source_addr);
5718 if (result <= 0) {
5719 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
5720 source_str, errno, safe_strerror(errno));
5721 return CMD_WARNING_CONFIG_FAILED;
5722 }
5723
5724 result = pim_ssmpingd_stop(pim, source_addr);
5725 if (result) {
5726 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
5727 source_str, result);
5728 return CMD_WARNING_CONFIG_FAILED;
5729 }
5730
5731 return CMD_SUCCESS;
5732 }
5733
5734 DEFUN (ip_pim_ecmp,
5735 ip_pim_ecmp_cmd,
5736 "ip pim ecmp",
5737 IP_STR
5738 "pim multicast routing\n"
5739 "Enable PIM ECMP \n")
5740 {
5741 PIM_DECLVAR_CONTEXT(vrf, pim);
5742 pim->ecmp_enable = true;
5743
5744 return CMD_SUCCESS;
5745 }
5746
5747 DEFUN (no_ip_pim_ecmp,
5748 no_ip_pim_ecmp_cmd,
5749 "no ip pim ecmp",
5750 NO_STR
5751 IP_STR
5752 "pim multicast routing\n"
5753 "Disable PIM ECMP \n")
5754 {
5755 PIM_DECLVAR_CONTEXT(vrf, pim);
5756 pim->ecmp_enable = false;
5757
5758 return CMD_SUCCESS;
5759 }
5760
5761 DEFUN (ip_pim_ecmp_rebalance,
5762 ip_pim_ecmp_rebalance_cmd,
5763 "ip pim ecmp rebalance",
5764 IP_STR
5765 "pim multicast routing\n"
5766 "Enable PIM ECMP \n"
5767 "Enable PIM ECMP Rebalance\n")
5768 {
5769 PIM_DECLVAR_CONTEXT(vrf, pim);
5770 pim->ecmp_enable = true;
5771 pim->ecmp_rebalance_enable = true;
5772
5773 return CMD_SUCCESS;
5774 }
5775
5776 DEFUN (no_ip_pim_ecmp_rebalance,
5777 no_ip_pim_ecmp_rebalance_cmd,
5778 "no ip pim ecmp rebalance",
5779 NO_STR
5780 IP_STR
5781 "pim multicast routing\n"
5782 "Disable PIM ECMP \n"
5783 "Disable PIM ECMP Rebalance\n")
5784 {
5785 PIM_DECLVAR_CONTEXT(vrf, pim);
5786 pim->ecmp_rebalance_enable = false;
5787
5788 return CMD_SUCCESS;
5789 }
5790
5791 static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
5792 {
5793 struct pim_interface *pim_ifp;
5794 uint8_t need_startup = 0;
5795
5796 pim_ifp = ifp->info;
5797
5798 if (!pim_ifp) {
5799 pim_ifp = pim_if_new(ifp, true, false, false);
5800 if (!pim_ifp) {
5801 vty_out(vty, "Could not enable IGMP on interface %s\n",
5802 ifp->name);
5803 return CMD_WARNING_CONFIG_FAILED;
5804 }
5805 need_startup = 1;
5806 } else {
5807 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
5808 PIM_IF_DO_IGMP(pim_ifp->options);
5809 need_startup = 1;
5810 }
5811 }
5812
5813 /* 'ip igmp' executed multiple times, with need_startup
5814 avoid multiple if add all and membership refresh */
5815 if (need_startup) {
5816 pim_if_addr_add_all(ifp);
5817 pim_if_membership_refresh(ifp);
5818 }
5819
5820 return CMD_SUCCESS;
5821 }
5822
5823 DEFUN (interface_ip_igmp,
5824 interface_ip_igmp_cmd,
5825 "ip igmp",
5826 IP_STR
5827 IFACE_IGMP_STR)
5828 {
5829 VTY_DECLVAR_CONTEXT(interface, ifp);
5830
5831 return pim_cmd_igmp_start(vty, ifp);
5832 }
5833
5834 DEFUN (interface_no_ip_igmp,
5835 interface_no_ip_igmp_cmd,
5836 "no ip igmp",
5837 NO_STR
5838 IP_STR
5839 IFACE_IGMP_STR)
5840 {
5841 VTY_DECLVAR_CONTEXT(interface, ifp);
5842 struct pim_interface *pim_ifp = ifp->info;
5843
5844 if (!pim_ifp)
5845 return CMD_SUCCESS;
5846
5847 PIM_IF_DONT_IGMP(pim_ifp->options);
5848
5849 pim_if_membership_clear(ifp);
5850
5851 pim_if_addr_del_all_igmp(ifp);
5852
5853 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
5854 pim_if_delete(ifp);
5855 }
5856
5857 return CMD_SUCCESS;
5858 }
5859
5860 DEFUN (interface_ip_igmp_join,
5861 interface_ip_igmp_join_cmd,
5862 "ip igmp join A.B.C.D A.B.C.D",
5863 IP_STR
5864 IFACE_IGMP_STR
5865 "IGMP join multicast group\n"
5866 "Multicast group address\n"
5867 "Source address\n")
5868 {
5869 VTY_DECLVAR_CONTEXT(interface, ifp);
5870 int idx_ipv4 = 3;
5871 int idx_ipv4_2 = 4;
5872 const char *group_str;
5873 const char *source_str;
5874 struct in_addr group_addr;
5875 struct in_addr source_addr;
5876 int result;
5877
5878 /* Group address */
5879 group_str = argv[idx_ipv4]->arg;
5880 result = inet_pton(AF_INET, group_str, &group_addr);
5881 if (result <= 0) {
5882 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
5883 errno, safe_strerror(errno));
5884 return CMD_WARNING_CONFIG_FAILED;
5885 }
5886
5887 /* Source address */
5888 source_str = argv[idx_ipv4_2]->arg;
5889 result = inet_pton(AF_INET, source_str, &source_addr);
5890 if (result <= 0) {
5891 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
5892 source_str, errno, safe_strerror(errno));
5893 return CMD_WARNING_CONFIG_FAILED;
5894 }
5895
5896 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp, group_addr, source_addr),
5897 "Failure joining IGMP group: $ERR");
5898
5899 return CMD_SUCCESS;
5900 }
5901
5902 DEFUN (interface_no_ip_igmp_join,
5903 interface_no_ip_igmp_join_cmd,
5904 "no ip igmp join A.B.C.D A.B.C.D",
5905 NO_STR
5906 IP_STR
5907 IFACE_IGMP_STR
5908 "IGMP join multicast group\n"
5909 "Multicast group address\n"
5910 "Source address\n")
5911 {
5912 VTY_DECLVAR_CONTEXT(interface, ifp);
5913 int idx_ipv4 = 4;
5914 int idx_ipv4_2 = 5;
5915 const char *group_str;
5916 const char *source_str;
5917 struct in_addr group_addr;
5918 struct in_addr source_addr;
5919 int result;
5920
5921 /* Group address */
5922 group_str = argv[idx_ipv4]->arg;
5923 result = inet_pton(AF_INET, group_str, &group_addr);
5924 if (result <= 0) {
5925 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
5926 errno, safe_strerror(errno));
5927 return CMD_WARNING_CONFIG_FAILED;
5928 }
5929
5930 /* Source address */
5931 source_str = argv[idx_ipv4_2]->arg;
5932 result = inet_pton(AF_INET, source_str, &source_addr);
5933 if (result <= 0) {
5934 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
5935 source_str, errno, safe_strerror(errno));
5936 return CMD_WARNING_CONFIG_FAILED;
5937 }
5938
5939 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
5940 if (result) {
5941 vty_out(vty,
5942 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
5943 group_str, source_str, ifp->name, result);
5944 return CMD_WARNING_CONFIG_FAILED;
5945 }
5946
5947 return CMD_SUCCESS;
5948 }
5949
5950 /*
5951 CLI reconfiguration affects the interface level (struct pim_interface).
5952 This function propagates the reconfiguration to every active socket
5953 for that interface.
5954 */
5955 static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
5956 {
5957 struct interface *ifp;
5958 struct pim_interface *pim_ifp;
5959
5960 zassert(igmp);
5961
5962 /* other querier present? */
5963
5964 if (igmp->t_other_querier_timer)
5965 return;
5966
5967 /* this is the querier */
5968
5969 zassert(igmp->interface);
5970 zassert(igmp->interface->info);
5971
5972 ifp = igmp->interface;
5973 pim_ifp = ifp->info;
5974
5975 if (PIM_DEBUG_IGMP_TRACE) {
5976 char ifaddr_str[INET_ADDRSTRLEN];
5977 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
5978 sizeof(ifaddr_str));
5979 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
5980 __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
5981 pim_ifp->igmp_default_query_interval);
5982 }
5983
5984 /*
5985 igmp_startup_mode_on() will reset QQI:
5986
5987 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
5988 */
5989 igmp_startup_mode_on(igmp);
5990 }
5991
5992 static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
5993 {
5994 if (igmp->t_igmp_query_timer) {
5995 /* other querier present */
5996 zassert(igmp->t_igmp_query_timer);
5997 zassert(!igmp->t_other_querier_timer);
5998
5999 pim_igmp_general_query_off(igmp);
6000 pim_igmp_general_query_on(igmp);
6001
6002 zassert(igmp->t_igmp_query_timer);
6003 zassert(!igmp->t_other_querier_timer);
6004 } else {
6005 /* this is the querier */
6006
6007 zassert(!igmp->t_igmp_query_timer);
6008 zassert(igmp->t_other_querier_timer);
6009
6010 pim_igmp_other_querier_timer_off(igmp);
6011 pim_igmp_other_querier_timer_on(igmp);
6012
6013 zassert(!igmp->t_igmp_query_timer);
6014 zassert(igmp->t_other_querier_timer);
6015 }
6016 }
6017
6018 static void change_query_interval(struct pim_interface *pim_ifp,
6019 int query_interval)
6020 {
6021 struct listnode *sock_node;
6022 struct igmp_sock *igmp;
6023
6024 pim_ifp->igmp_default_query_interval = query_interval;
6025
6026 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
6027 igmp_sock_query_interval_reconfig(igmp);
6028 igmp_sock_query_reschedule(igmp);
6029 }
6030 }
6031
6032 static void change_query_max_response_time(struct pim_interface *pim_ifp,
6033 int query_max_response_time_dsec)
6034 {
6035 struct listnode *sock_node;
6036 struct igmp_sock *igmp;
6037
6038 pim_ifp->igmp_query_max_response_time_dsec =
6039 query_max_response_time_dsec;
6040
6041 /*
6042 Below we modify socket/group/source timers in order to quickly
6043 reflect the change. Otherwise, those timers would eventually catch
6044 up.
6045 */
6046
6047 /* scan all sockets */
6048 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
6049 struct listnode *grp_node;
6050 struct igmp_group *grp;
6051
6052 /* reschedule socket general query */
6053 igmp_sock_query_reschedule(igmp);
6054
6055 /* scan socket groups */
6056 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
6057 grp)) {
6058 struct listnode *src_node;
6059 struct igmp_source *src;
6060
6061 /* reset group timers for groups in EXCLUDE mode */
6062 if (grp->group_filtermode_isexcl) {
6063 igmp_group_reset_gmi(grp);
6064 }
6065
6066 /* scan group sources */
6067 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
6068 src_node, src)) {
6069
6070 /* reset source timers for sources with running
6071 * timers */
6072 if (src->t_source_timer) {
6073 igmp_source_reset_gmi(igmp, grp, src);
6074 }
6075 }
6076 }
6077 }
6078 }
6079
6080 #define IGMP_QUERY_INTERVAL_MIN (1)
6081 #define IGMP_QUERY_INTERVAL_MAX (1800)
6082
6083 DEFUN (interface_ip_igmp_query_interval,
6084 interface_ip_igmp_query_interval_cmd,
6085 "ip igmp query-interval (1-1800)",
6086 IP_STR
6087 IFACE_IGMP_STR
6088 IFACE_IGMP_QUERY_INTERVAL_STR
6089 "Query interval in seconds\n")
6090 {
6091 VTY_DECLVAR_CONTEXT(interface, ifp);
6092 struct pim_interface *pim_ifp = ifp->info;
6093 int query_interval;
6094 int query_interval_dsec;
6095 int ret;
6096
6097 if (!pim_ifp) {
6098 ret = pim_cmd_igmp_start(vty, ifp);
6099 if (ret != CMD_SUCCESS)
6100 return ret;
6101 pim_ifp = ifp->info;
6102 }
6103
6104 query_interval = atoi(argv[3]->arg);
6105 query_interval_dsec = 10 * query_interval;
6106
6107 /*
6108 It seems we don't need to check bounds since command.c does it
6109 already, but we verify them anyway for extra safety.
6110 */
6111 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
6112 vty_out(vty,
6113 "General query interval %d lower than minimum %d\n",
6114 query_interval, IGMP_QUERY_INTERVAL_MIN);
6115 return CMD_WARNING_CONFIG_FAILED;
6116 }
6117 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
6118 vty_out(vty,
6119 "General query interval %d higher than maximum %d\n",
6120 query_interval, IGMP_QUERY_INTERVAL_MAX);
6121 return CMD_WARNING_CONFIG_FAILED;
6122 }
6123
6124 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
6125 vty_out(vty,
6126 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
6127 query_interval_dsec,
6128 pim_ifp->igmp_query_max_response_time_dsec);
6129 return CMD_WARNING_CONFIG_FAILED;
6130 }
6131
6132 change_query_interval(pim_ifp, query_interval);
6133
6134 return CMD_SUCCESS;
6135 }
6136
6137 DEFUN (interface_no_ip_igmp_query_interval,
6138 interface_no_ip_igmp_query_interval_cmd,
6139 "no ip igmp query-interval",
6140 NO_STR
6141 IP_STR
6142 IFACE_IGMP_STR
6143 IFACE_IGMP_QUERY_INTERVAL_STR)
6144 {
6145 VTY_DECLVAR_CONTEXT(interface, ifp);
6146 struct pim_interface *pim_ifp = ifp->info;
6147 int default_query_interval_dsec;
6148
6149 if (!pim_ifp)
6150 return CMD_SUCCESS;
6151
6152 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
6153
6154 if (default_query_interval_dsec
6155 <= pim_ifp->igmp_query_max_response_time_dsec) {
6156 vty_out(vty,
6157 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
6158 default_query_interval_dsec,
6159 pim_ifp->igmp_query_max_response_time_dsec);
6160 return CMD_WARNING_CONFIG_FAILED;
6161 }
6162
6163 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
6164
6165 return CMD_SUCCESS;
6166 }
6167
6168 DEFUN (interface_ip_igmp_version,
6169 interface_ip_igmp_version_cmd,
6170 "ip igmp version (2-3)",
6171 IP_STR
6172 IFACE_IGMP_STR
6173 "IGMP version\n"
6174 "IGMP version number\n")
6175 {
6176 VTY_DECLVAR_CONTEXT(interface, ifp);
6177 struct pim_interface *pim_ifp = ifp->info;
6178 int igmp_version, old_version = 0;
6179 int ret;
6180
6181 if (!pim_ifp) {
6182 ret = pim_cmd_igmp_start(vty, ifp);
6183 if (ret != CMD_SUCCESS)
6184 return ret;
6185 pim_ifp = ifp->info;
6186 }
6187
6188 igmp_version = atoi(argv[3]->arg);
6189 old_version = pim_ifp->igmp_version;
6190 pim_ifp->igmp_version = igmp_version;
6191
6192 // Check if IGMP is Enabled otherwise, enable on interface
6193 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
6194 PIM_IF_DO_IGMP(pim_ifp->options);
6195 pim_if_addr_add_all(ifp);
6196 pim_if_membership_refresh(ifp);
6197 old_version = igmp_version;
6198 // avoid refreshing membership again.
6199 }
6200 /* Current and new version is different refresh existing
6201 membership. Going from 3 -> 2 or 2 -> 3. */
6202 if (old_version != igmp_version)
6203 pim_if_membership_refresh(ifp);
6204
6205 return CMD_SUCCESS;
6206 }
6207
6208 DEFUN (interface_no_ip_igmp_version,
6209 interface_no_ip_igmp_version_cmd,
6210 "no ip igmp version (2-3)",
6211 NO_STR
6212 IP_STR
6213 IFACE_IGMP_STR
6214 "IGMP version\n"
6215 "IGMP version number\n")
6216 {
6217 VTY_DECLVAR_CONTEXT(interface, ifp);
6218 struct pim_interface *pim_ifp = ifp->info;
6219
6220 if (!pim_ifp)
6221 return CMD_SUCCESS;
6222
6223 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
6224
6225 return CMD_SUCCESS;
6226 }
6227
6228 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6229 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6230
6231 DEFUN (interface_ip_igmp_query_max_response_time,
6232 interface_ip_igmp_query_max_response_time_cmd,
6233 "ip igmp query-max-response-time (10-250)",
6234 IP_STR
6235 IFACE_IGMP_STR
6236 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6237 "Query response value in deci-seconds\n")
6238 {
6239 VTY_DECLVAR_CONTEXT(interface, ifp);
6240 struct pim_interface *pim_ifp = ifp->info;
6241 int query_max_response_time;
6242 int ret;
6243
6244 if (!pim_ifp) {
6245 ret = pim_cmd_igmp_start(vty, ifp);
6246 if (ret != CMD_SUCCESS)
6247 return ret;
6248 pim_ifp = ifp->info;
6249 }
6250
6251 query_max_response_time = atoi(argv[3]->arg);
6252
6253 if (query_max_response_time
6254 >= pim_ifp->igmp_default_query_interval * 10) {
6255 vty_out(vty,
6256 "Can't set query max response time %d sec >= general query interval %d sec\n",
6257 query_max_response_time,
6258 pim_ifp->igmp_default_query_interval);
6259 return CMD_WARNING_CONFIG_FAILED;
6260 }
6261
6262 change_query_max_response_time(pim_ifp, query_max_response_time);
6263
6264 return CMD_SUCCESS;
6265 }
6266
6267 DEFUN (interface_no_ip_igmp_query_max_response_time,
6268 interface_no_ip_igmp_query_max_response_time_cmd,
6269 "no ip igmp query-max-response-time (10-250)",
6270 NO_STR
6271 IP_STR
6272 IFACE_IGMP_STR
6273 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
6274 "Time for response in deci-seconds\n")
6275 {
6276 VTY_DECLVAR_CONTEXT(interface, ifp);
6277 struct pim_interface *pim_ifp = ifp->info;
6278
6279 if (!pim_ifp)
6280 return CMD_SUCCESS;
6281
6282 change_query_max_response_time(pim_ifp,
6283 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
6284
6285 return CMD_SUCCESS;
6286 }
6287
6288 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
6289 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
6290
6291 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
6292 interface_ip_igmp_query_max_response_time_dsec_cmd,
6293 "ip igmp query-max-response-time-dsec (10-250)",
6294 IP_STR
6295 IFACE_IGMP_STR
6296 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
6297 "Query response value in deciseconds\n")
6298 {
6299 VTY_DECLVAR_CONTEXT(interface, ifp);
6300 struct pim_interface *pim_ifp = ifp->info;
6301 int query_max_response_time_dsec;
6302 int default_query_interval_dsec;
6303 int ret;
6304
6305 if (!pim_ifp) {
6306 ret = pim_cmd_igmp_start(vty, ifp);
6307 if (ret != CMD_SUCCESS)
6308 return ret;
6309 pim_ifp = ifp->info;
6310 }
6311
6312 query_max_response_time_dsec = atoi(argv[4]->arg);
6313
6314 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
6315
6316 if (query_max_response_time_dsec >= default_query_interval_dsec) {
6317 vty_out(vty,
6318 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
6319 query_max_response_time_dsec,
6320 default_query_interval_dsec);
6321 return CMD_WARNING_CONFIG_FAILED;
6322 }
6323
6324 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
6325
6326 return CMD_SUCCESS;
6327 }
6328
6329 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
6330 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
6331 "no ip igmp query-max-response-time-dsec",
6332 NO_STR
6333 IP_STR
6334 IFACE_IGMP_STR
6335 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
6336 {
6337 VTY_DECLVAR_CONTEXT(interface, ifp);
6338 struct pim_interface *pim_ifp = ifp->info;
6339
6340 if (!pim_ifp)
6341 return CMD_SUCCESS;
6342
6343 change_query_max_response_time(pim_ifp,
6344 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
6345
6346 return CMD_SUCCESS;
6347 }
6348
6349 DEFUN (interface_ip_pim_drprio,
6350 interface_ip_pim_drprio_cmd,
6351 "ip pim drpriority (1-4294967295)",
6352 IP_STR
6353 PIM_STR
6354 "Set the Designated Router Election Priority\n"
6355 "Value of the new DR Priority\n")
6356 {
6357 VTY_DECLVAR_CONTEXT(interface, ifp);
6358 int idx_number = 3;
6359 struct pim_interface *pim_ifp = ifp->info;
6360 uint32_t old_dr_prio;
6361
6362 if (!pim_ifp) {
6363 vty_out(vty, "Please enable PIM on interface, first\n");
6364 return CMD_WARNING_CONFIG_FAILED;
6365 }
6366
6367 old_dr_prio = pim_ifp->pim_dr_priority;
6368
6369 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
6370
6371 if (old_dr_prio != pim_ifp->pim_dr_priority) {
6372 pim_if_dr_election(ifp);
6373 pim_hello_restart_now(ifp);
6374 }
6375
6376 return CMD_SUCCESS;
6377 }
6378
6379 DEFUN (interface_no_ip_pim_drprio,
6380 interface_no_ip_pim_drprio_cmd,
6381 "no ip pim drpriority [(1-4294967295)]",
6382 NO_STR
6383 IP_STR
6384 PIM_STR
6385 "Revert the Designated Router Priority to default\n"
6386 "Old Value of the Priority\n")
6387 {
6388 VTY_DECLVAR_CONTEXT(interface, ifp);
6389 struct pim_interface *pim_ifp = ifp->info;
6390
6391 if (!pim_ifp) {
6392 vty_out(vty, "Pim not enabled on this interface\n");
6393 return CMD_WARNING_CONFIG_FAILED;
6394 }
6395
6396 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
6397 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
6398 pim_if_dr_election(ifp);
6399 pim_hello_restart_now(ifp);
6400 }
6401
6402 return CMD_SUCCESS;
6403 }
6404
6405 static int pim_cmd_interface_add(struct interface *ifp)
6406 {
6407 struct pim_interface *pim_ifp = ifp->info;
6408
6409 if (!pim_ifp) {
6410 pim_ifp = pim_if_new(ifp, false, true, false);
6411 if (!pim_ifp) {
6412 return 0;
6413 }
6414 } else {
6415 PIM_IF_DO_PIM(pim_ifp->options);
6416 }
6417
6418 pim_if_addr_add_all(ifp);
6419 pim_if_membership_refresh(ifp);
6420 return 1;
6421 }
6422
6423 DEFPY_HIDDEN (pim_test_sg_keepalive,
6424 pim_test_sg_keepalive_cmd,
6425 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
6426 "Test code\n"
6427 PIM_STR
6428 VRF_CMD_HELP_STR
6429 "Reset the Keepalive Timer\n"
6430 "The Source we are resetting\n"
6431 "The Group we are resetting\n")
6432 {
6433 struct pim_upstream *up;
6434 struct pim_instance *pim;
6435 struct prefix_sg sg;
6436
6437 sg.src = source;
6438 sg.grp = group;
6439
6440 if (!name)
6441 pim = pim_get_pim_instance(VRF_DEFAULT);
6442 else {
6443 struct vrf *vrf = vrf_lookup_by_name(name);
6444
6445 if (!vrf) {
6446 vty_out(vty, "%% Vrf specified: %s does not exist\n",
6447 name);
6448 return CMD_WARNING;
6449 }
6450
6451 pim = pim_get_pim_instance(vrf->vrf_id);
6452 }
6453
6454 if (!pim) {
6455 vty_out(vty, "%% Unable to find pim instance\n");
6456 return CMD_WARNING;
6457 }
6458
6459 up = pim_upstream_find(pim, &sg);
6460 if (!up) {
6461 vty_out(vty, "%% Unable to find %s specified\n",
6462 pim_str_sg_dump(&sg));
6463 return CMD_WARNING;
6464 }
6465
6466 vty_out(vty, "Setting %s to current keep alive time: %d\n",
6467 pim_str_sg_dump(&sg), pim->keep_alive_time);
6468 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
6469
6470 return CMD_SUCCESS;
6471 }
6472
6473 DEFPY_HIDDEN (interface_ip_pim_activeactive,
6474 interface_ip_pim_activeactive_cmd,
6475 "[no$no] ip pim active-active",
6476 NO_STR
6477 IP_STR
6478 PIM_STR
6479 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
6480 {
6481 VTY_DECLVAR_CONTEXT(interface, ifp);
6482 struct pim_interface *pim_ifp;
6483
6484 if (!no && !pim_cmd_interface_add(ifp)) {
6485 vty_out(vty, "Could not enable PIM SM active-active on interface\n");
6486 return CMD_WARNING_CONFIG_FAILED;
6487 }
6488
6489 pim_ifp = ifp->info;
6490 if (no)
6491 pim_ifp->activeactive = false;
6492 else
6493 pim_ifp->activeactive = true;
6494
6495 return CMD_SUCCESS;
6496 }
6497
6498 DEFUN_HIDDEN (interface_ip_pim_ssm,
6499 interface_ip_pim_ssm_cmd,
6500 "ip pim ssm",
6501 IP_STR
6502 PIM_STR
6503 IFACE_PIM_STR)
6504 {
6505 VTY_DECLVAR_CONTEXT(interface, ifp);
6506
6507 if (!pim_cmd_interface_add(ifp)) {
6508 vty_out(vty, "Could not enable PIM SM on interface\n");
6509 return CMD_WARNING_CONFIG_FAILED;
6510 }
6511
6512 vty_out(vty,
6513 "WARN: Enabled PIM SM on interface; configure PIM SSM "
6514 "range if needed\n");
6515 return CMD_SUCCESS;
6516 }
6517
6518 static int interface_ip_pim_helper(struct vty *vty)
6519 {
6520 struct pim_interface *pim_ifp;
6521
6522 VTY_DECLVAR_CONTEXT(interface, ifp);
6523
6524 if (!pim_cmd_interface_add(ifp)) {
6525 vty_out(vty, "Could not enable PIM SM on interface\n");
6526 return CMD_WARNING_CONFIG_FAILED;
6527 }
6528
6529 pim_ifp = ifp->info;
6530
6531 pim_if_create_pimreg(pim_ifp->pim);
6532
6533 return CMD_SUCCESS;
6534 }
6535
6536 DEFUN_HIDDEN (interface_ip_pim_sm,
6537 interface_ip_pim_sm_cmd,
6538 "ip pim sm",
6539 IP_STR
6540 PIM_STR
6541 IFACE_PIM_SM_STR)
6542 {
6543 return interface_ip_pim_helper(vty);
6544 }
6545
6546 DEFUN (interface_ip_pim,
6547 interface_ip_pim_cmd,
6548 "ip pim",
6549 IP_STR
6550 PIM_STR)
6551 {
6552 return interface_ip_pim_helper(vty);
6553 }
6554
6555 static int pim_cmd_interface_delete(struct interface *ifp)
6556 {
6557 struct pim_interface *pim_ifp = ifp->info;
6558
6559 if (!pim_ifp)
6560 return 1;
6561
6562 PIM_IF_DONT_PIM(pim_ifp->options);
6563
6564 pim_if_membership_clear(ifp);
6565
6566 /*
6567 pim_sock_delete() removes all neighbors from
6568 pim_ifp->pim_neighbor_list.
6569 */
6570 pim_sock_delete(ifp, "pim unconfigured on interface");
6571
6572 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
6573 pim_if_addr_del_all(ifp);
6574 pim_if_delete(ifp);
6575 }
6576
6577 return 1;
6578 }
6579
6580 static int interface_no_ip_pim_helper(struct vty *vty)
6581 {
6582 VTY_DECLVAR_CONTEXT(interface, ifp);
6583 if (!pim_cmd_interface_delete(ifp)) {
6584 vty_out(vty, "Unable to delete interface information\n");
6585 return CMD_WARNING_CONFIG_FAILED;
6586 }
6587
6588 return CMD_SUCCESS;
6589 }
6590
6591 DEFUN_HIDDEN (interface_no_ip_pim_ssm,
6592 interface_no_ip_pim_ssm_cmd,
6593 "no ip pim ssm",
6594 NO_STR
6595 IP_STR
6596 PIM_STR
6597 IFACE_PIM_STR)
6598 {
6599 return interface_no_ip_pim_helper(vty);
6600 }
6601
6602 DEFUN_HIDDEN (interface_no_ip_pim_sm,
6603 interface_no_ip_pim_sm_cmd,
6604 "no ip pim sm",
6605 NO_STR
6606 IP_STR
6607 PIM_STR
6608 IFACE_PIM_SM_STR)
6609 {
6610 return interface_no_ip_pim_helper(vty);
6611 }
6612
6613 DEFUN (interface_no_ip_pim,
6614 interface_no_ip_pim_cmd,
6615 "no ip pim",
6616 NO_STR
6617 IP_STR
6618 PIM_STR)
6619 {
6620 return interface_no_ip_pim_helper(vty);
6621 }
6622
6623 /* boundaries */
6624 DEFUN(interface_ip_pim_boundary_oil,
6625 interface_ip_pim_boundary_oil_cmd,
6626 "ip multicast boundary oil WORD",
6627 IP_STR
6628 "Generic multicast configuration options\n"
6629 "Define multicast boundary\n"
6630 "Filter OIL by group using prefix list\n"
6631 "Prefix list to filter OIL with\n")
6632 {
6633 VTY_DECLVAR_CONTEXT(interface, iif);
6634 struct pim_interface *pim_ifp;
6635 int idx = 0;
6636
6637 argv_find(argv, argc, "WORD", &idx);
6638
6639 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
6640
6641 if (pim_ifp->boundary_oil_plist)
6642 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
6643
6644 pim_ifp->boundary_oil_plist =
6645 XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
6646
6647 /* Interface will be pruned from OIL on next Join */
6648 return CMD_SUCCESS;
6649 }
6650
6651 DEFUN(interface_no_ip_pim_boundary_oil,
6652 interface_no_ip_pim_boundary_oil_cmd,
6653 "no ip multicast boundary oil [WORD]",
6654 NO_STR
6655 IP_STR
6656 "Generic multicast configuration options\n"
6657 "Define multicast boundary\n"
6658 "Filter OIL by group using prefix list\n"
6659 "Prefix list to filter OIL with\n")
6660 {
6661 VTY_DECLVAR_CONTEXT(interface, iif);
6662 struct pim_interface *pim_ifp;
6663 int idx = 0;
6664
6665 argv_find(argv, argc, "WORD", &idx);
6666
6667 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
6668
6669 if (pim_ifp->boundary_oil_plist)
6670 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
6671
6672 return CMD_SUCCESS;
6673 }
6674
6675 DEFUN (interface_ip_mroute,
6676 interface_ip_mroute_cmd,
6677 "ip mroute INTERFACE A.B.C.D",
6678 IP_STR
6679 "Add multicast route\n"
6680 "Outgoing interface name\n"
6681 "Group address\n")
6682 {
6683 VTY_DECLVAR_CONTEXT(interface, iif);
6684 struct pim_interface *pim_ifp;
6685 struct pim_instance *pim;
6686 int idx_interface = 2;
6687 int idx_ipv4 = 3;
6688 struct interface *oif;
6689 const char *oifname;
6690 const char *grp_str;
6691 struct in_addr grp_addr;
6692 struct in_addr src_addr;
6693 int result;
6694
6695 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
6696 pim = pim_ifp->pim;
6697
6698 oifname = argv[idx_interface]->arg;
6699 oif = if_lookup_by_name(oifname, pim->vrf_id);
6700 if (!oif) {
6701 vty_out(vty, "No such interface name %s\n", oifname);
6702 return CMD_WARNING;
6703 }
6704
6705 grp_str = argv[idx_ipv4]->arg;
6706 result = inet_pton(AF_INET, grp_str, &grp_addr);
6707 if (result <= 0) {
6708 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
6709 errno, safe_strerror(errno));
6710 return CMD_WARNING;
6711 }
6712
6713 src_addr.s_addr = INADDR_ANY;
6714
6715 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
6716 vty_out(vty, "Failed to add route\n");
6717 return CMD_WARNING;
6718 }
6719
6720 return CMD_SUCCESS;
6721 }
6722
6723 DEFUN (interface_ip_mroute_source,
6724 interface_ip_mroute_source_cmd,
6725 "ip mroute INTERFACE A.B.C.D A.B.C.D",
6726 IP_STR
6727 "Add multicast route\n"
6728 "Outgoing interface name\n"
6729 "Group address\n"
6730 "Source address\n")
6731 {
6732 VTY_DECLVAR_CONTEXT(interface, iif);
6733 struct pim_interface *pim_ifp;
6734 struct pim_instance *pim;
6735 int idx_interface = 2;
6736 int idx_ipv4 = 3;
6737 int idx_ipv4_2 = 4;
6738 struct interface *oif;
6739 const char *oifname;
6740 const char *grp_str;
6741 struct in_addr grp_addr;
6742 const char *src_str;
6743 struct in_addr src_addr;
6744 int result;
6745
6746 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
6747 pim = pim_ifp->pim;
6748
6749 oifname = argv[idx_interface]->arg;
6750 oif = if_lookup_by_name(oifname, pim->vrf_id);
6751 if (!oif) {
6752 vty_out(vty, "No such interface name %s\n", oifname);
6753 return CMD_WARNING;
6754 }
6755
6756 grp_str = argv[idx_ipv4]->arg;
6757 result = inet_pton(AF_INET, grp_str, &grp_addr);
6758 if (result <= 0) {
6759 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
6760 errno, safe_strerror(errno));
6761 return CMD_WARNING;
6762 }
6763
6764 src_str = argv[idx_ipv4_2]->arg;
6765 result = inet_pton(AF_INET, src_str, &src_addr);
6766 if (result <= 0) {
6767 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
6768 errno, safe_strerror(errno));
6769 return CMD_WARNING;
6770 }
6771
6772 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
6773 vty_out(vty, "Failed to add route\n");
6774 return CMD_WARNING;
6775 }
6776
6777 return CMD_SUCCESS;
6778 }
6779
6780 DEFUN (interface_no_ip_mroute,
6781 interface_no_ip_mroute_cmd,
6782 "no ip mroute INTERFACE A.B.C.D",
6783 NO_STR
6784 IP_STR
6785 "Add multicast route\n"
6786 "Outgoing interface name\n"
6787 "Group Address\n")
6788 {
6789 VTY_DECLVAR_CONTEXT(interface, iif);
6790 struct pim_interface *pim_ifp;
6791 struct pim_instance *pim;
6792 int idx_interface = 3;
6793 int idx_ipv4 = 4;
6794 struct interface *oif;
6795 const char *oifname;
6796 const char *grp_str;
6797 struct in_addr grp_addr;
6798 struct in_addr src_addr;
6799 int result;
6800
6801 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
6802 pim = pim_ifp->pim;
6803
6804 oifname = argv[idx_interface]->arg;
6805 oif = if_lookup_by_name(oifname, pim->vrf_id);
6806 if (!oif) {
6807 vty_out(vty, "No such interface name %s\n", oifname);
6808 return CMD_WARNING;
6809 }
6810
6811 grp_str = argv[idx_ipv4]->arg;
6812 result = inet_pton(AF_INET, grp_str, &grp_addr);
6813 if (result <= 0) {
6814 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
6815 errno, safe_strerror(errno));
6816 return CMD_WARNING;
6817 }
6818
6819 src_addr.s_addr = INADDR_ANY;
6820
6821 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
6822 vty_out(vty, "Failed to remove route\n");
6823 return CMD_WARNING;
6824 }
6825
6826 return CMD_SUCCESS;
6827 }
6828
6829 DEFUN (interface_no_ip_mroute_source,
6830 interface_no_ip_mroute_source_cmd,
6831 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
6832 NO_STR
6833 IP_STR
6834 "Add multicast route\n"
6835 "Outgoing interface name\n"
6836 "Group Address\n"
6837 "Source Address\n")
6838 {
6839 VTY_DECLVAR_CONTEXT(interface, iif);
6840 struct pim_interface *pim_ifp;
6841 struct pim_instance *pim;
6842 int idx_interface = 3;
6843 int idx_ipv4 = 4;
6844 int idx_ipv4_2 = 5;
6845 struct interface *oif;
6846 const char *oifname;
6847 const char *grp_str;
6848 struct in_addr grp_addr;
6849 const char *src_str;
6850 struct in_addr src_addr;
6851 int result;
6852
6853 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
6854 pim = pim_ifp->pim;
6855
6856 oifname = argv[idx_interface]->arg;
6857 oif = if_lookup_by_name(oifname, pim->vrf_id);
6858 if (!oif) {
6859 vty_out(vty, "No such interface name %s\n", oifname);
6860 return CMD_WARNING;
6861 }
6862
6863 grp_str = argv[idx_ipv4]->arg;
6864 result = inet_pton(AF_INET, grp_str, &grp_addr);
6865 if (result <= 0) {
6866 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
6867 errno, safe_strerror(errno));
6868 return CMD_WARNING;
6869 }
6870
6871 src_str = argv[idx_ipv4_2]->arg;
6872 result = inet_pton(AF_INET, src_str, &src_addr);
6873 if (result <= 0) {
6874 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
6875 errno, safe_strerror(errno));
6876 return CMD_WARNING;
6877 }
6878
6879 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
6880 vty_out(vty, "Failed to remove route\n");
6881 return CMD_WARNING;
6882 }
6883
6884 return CMD_SUCCESS;
6885 }
6886
6887 DEFUN (interface_ip_pim_hello,
6888 interface_ip_pim_hello_cmd,
6889 "ip pim hello (1-180) [(1-180)]",
6890 IP_STR
6891 PIM_STR
6892 IFACE_PIM_HELLO_STR
6893 IFACE_PIM_HELLO_TIME_STR
6894 IFACE_PIM_HELLO_HOLD_STR)
6895 {
6896 VTY_DECLVAR_CONTEXT(interface, ifp);
6897 int idx_time = 3;
6898 int idx_hold = 4;
6899 struct pim_interface *pim_ifp = ifp->info;
6900
6901 if (!pim_ifp) {
6902 if (!pim_cmd_interface_add(ifp)) {
6903 vty_out(vty, "Could not enable PIM SM on interface\n");
6904 return CMD_WARNING_CONFIG_FAILED;
6905 }
6906 }
6907
6908 pim_ifp = ifp->info;
6909 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
6910
6911 if (argc == idx_hold + 1)
6912 pim_ifp->pim_default_holdtime =
6913 strtol(argv[idx_hold]->arg, NULL, 10);
6914
6915 return CMD_SUCCESS;
6916 }
6917
6918 DEFUN (interface_no_ip_pim_hello,
6919 interface_no_ip_pim_hello_cmd,
6920 "no ip pim hello [(1-180) (1-180)]",
6921 NO_STR
6922 IP_STR
6923 PIM_STR
6924 IFACE_PIM_HELLO_STR
6925 IFACE_PIM_HELLO_TIME_STR
6926 IFACE_PIM_HELLO_HOLD_STR)
6927 {
6928 VTY_DECLVAR_CONTEXT(interface, ifp);
6929 struct pim_interface *pim_ifp = ifp->info;
6930
6931 if (!pim_ifp) {
6932 vty_out(vty, "Pim not enabled on this interface\n");
6933 return CMD_WARNING_CONFIG_FAILED;
6934 }
6935
6936 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
6937 pim_ifp->pim_default_holdtime = -1;
6938
6939 return CMD_SUCCESS;
6940 }
6941
6942 DEFUN (debug_igmp,
6943 debug_igmp_cmd,
6944 "debug igmp",
6945 DEBUG_STR
6946 DEBUG_IGMP_STR)
6947 {
6948 PIM_DO_DEBUG_IGMP_EVENTS;
6949 PIM_DO_DEBUG_IGMP_PACKETS;
6950 PIM_DO_DEBUG_IGMP_TRACE;
6951 return CMD_SUCCESS;
6952 }
6953
6954 DEFUN (no_debug_igmp,
6955 no_debug_igmp_cmd,
6956 "no debug igmp",
6957 NO_STR
6958 DEBUG_STR
6959 DEBUG_IGMP_STR)
6960 {
6961 PIM_DONT_DEBUG_IGMP_EVENTS;
6962 PIM_DONT_DEBUG_IGMP_PACKETS;
6963 PIM_DONT_DEBUG_IGMP_TRACE;
6964 return CMD_SUCCESS;
6965 }
6966
6967
6968 DEFUN (debug_igmp_events,
6969 debug_igmp_events_cmd,
6970 "debug igmp events",
6971 DEBUG_STR
6972 DEBUG_IGMP_STR
6973 DEBUG_IGMP_EVENTS_STR)
6974 {
6975 PIM_DO_DEBUG_IGMP_EVENTS;
6976 return CMD_SUCCESS;
6977 }
6978
6979 DEFUN (no_debug_igmp_events,
6980 no_debug_igmp_events_cmd,
6981 "no debug igmp events",
6982 NO_STR
6983 DEBUG_STR
6984 DEBUG_IGMP_STR
6985 DEBUG_IGMP_EVENTS_STR)
6986 {
6987 PIM_DONT_DEBUG_IGMP_EVENTS;
6988 return CMD_SUCCESS;
6989 }
6990
6991
6992 DEFUN (debug_igmp_packets,
6993 debug_igmp_packets_cmd,
6994 "debug igmp packets",
6995 DEBUG_STR
6996 DEBUG_IGMP_STR
6997 DEBUG_IGMP_PACKETS_STR)
6998 {
6999 PIM_DO_DEBUG_IGMP_PACKETS;
7000 return CMD_SUCCESS;
7001 }
7002
7003 DEFUN (no_debug_igmp_packets,
7004 no_debug_igmp_packets_cmd,
7005 "no debug igmp packets",
7006 NO_STR
7007 DEBUG_STR
7008 DEBUG_IGMP_STR
7009 DEBUG_IGMP_PACKETS_STR)
7010 {
7011 PIM_DONT_DEBUG_IGMP_PACKETS;
7012 return CMD_SUCCESS;
7013 }
7014
7015
7016 DEFUN (debug_igmp_trace,
7017 debug_igmp_trace_cmd,
7018 "debug igmp trace",
7019 DEBUG_STR
7020 DEBUG_IGMP_STR
7021 DEBUG_IGMP_TRACE_STR)
7022 {
7023 PIM_DO_DEBUG_IGMP_TRACE;
7024 return CMD_SUCCESS;
7025 }
7026
7027 DEFUN (no_debug_igmp_trace,
7028 no_debug_igmp_trace_cmd,
7029 "no debug igmp trace",
7030 NO_STR
7031 DEBUG_STR
7032 DEBUG_IGMP_STR
7033 DEBUG_IGMP_TRACE_STR)
7034 {
7035 PIM_DONT_DEBUG_IGMP_TRACE;
7036 return CMD_SUCCESS;
7037 }
7038
7039
7040 DEFUN (debug_mroute,
7041 debug_mroute_cmd,
7042 "debug mroute",
7043 DEBUG_STR
7044 DEBUG_MROUTE_STR)
7045 {
7046 PIM_DO_DEBUG_MROUTE;
7047 return CMD_SUCCESS;
7048 }
7049
7050 DEFUN (debug_mroute_detail,
7051 debug_mroute_detail_cmd,
7052 "debug mroute detail",
7053 DEBUG_STR
7054 DEBUG_MROUTE_STR
7055 "detailed\n")
7056 {
7057 PIM_DO_DEBUG_MROUTE_DETAIL;
7058 return CMD_SUCCESS;
7059 }
7060
7061 DEFUN (no_debug_mroute,
7062 no_debug_mroute_cmd,
7063 "no debug mroute",
7064 NO_STR
7065 DEBUG_STR
7066 DEBUG_MROUTE_STR)
7067 {
7068 PIM_DONT_DEBUG_MROUTE;
7069 return CMD_SUCCESS;
7070 }
7071
7072 DEFUN (no_debug_mroute_detail,
7073 no_debug_mroute_detail_cmd,
7074 "no debug mroute detail",
7075 NO_STR
7076 DEBUG_STR
7077 DEBUG_MROUTE_STR
7078 "detailed\n")
7079 {
7080 PIM_DONT_DEBUG_MROUTE_DETAIL;
7081 return CMD_SUCCESS;
7082 }
7083
7084 DEFUN (debug_pim_static,
7085 debug_pim_static_cmd,
7086 "debug pim static",
7087 DEBUG_STR
7088 DEBUG_PIM_STR
7089 DEBUG_STATIC_STR)
7090 {
7091 PIM_DO_DEBUG_STATIC;
7092 return CMD_SUCCESS;
7093 }
7094
7095 DEFUN (no_debug_pim_static,
7096 no_debug_pim_static_cmd,
7097 "no debug pim static",
7098 NO_STR
7099 DEBUG_STR
7100 DEBUG_PIM_STR
7101 DEBUG_STATIC_STR)
7102 {
7103 PIM_DONT_DEBUG_STATIC;
7104 return CMD_SUCCESS;
7105 }
7106
7107
7108 DEFUN (debug_pim,
7109 debug_pim_cmd,
7110 "debug pim",
7111 DEBUG_STR
7112 DEBUG_PIM_STR)
7113 {
7114 PIM_DO_DEBUG_PIM_EVENTS;
7115 PIM_DO_DEBUG_PIM_PACKETS;
7116 PIM_DO_DEBUG_PIM_TRACE;
7117 PIM_DO_DEBUG_MSDP_EVENTS;
7118 PIM_DO_DEBUG_MSDP_PACKETS;
7119 return CMD_SUCCESS;
7120 }
7121
7122 DEFUN (no_debug_pim,
7123 no_debug_pim_cmd,
7124 "no debug pim",
7125 NO_STR
7126 DEBUG_STR
7127 DEBUG_PIM_STR)
7128 {
7129 PIM_DONT_DEBUG_PIM_EVENTS;
7130 PIM_DONT_DEBUG_PIM_PACKETS;
7131 PIM_DONT_DEBUG_PIM_TRACE;
7132 PIM_DONT_DEBUG_MSDP_EVENTS;
7133 PIM_DONT_DEBUG_MSDP_PACKETS;
7134
7135 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
7136 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
7137
7138 return CMD_SUCCESS;
7139 }
7140
7141 DEFUN (debug_pim_nht,
7142 debug_pim_nht_cmd,
7143 "debug pim nht",
7144 DEBUG_STR
7145 DEBUG_PIM_STR
7146 "Nexthop Tracking\n")
7147 {
7148 PIM_DO_DEBUG_PIM_NHT;
7149 return CMD_SUCCESS;
7150 }
7151
7152 DEFUN (no_debug_pim_nht,
7153 no_debug_pim_nht_cmd,
7154 "no debug pim nht",
7155 NO_STR
7156 DEBUG_STR
7157 DEBUG_PIM_STR
7158 "Nexthop Tracking\n")
7159 {
7160 PIM_DONT_DEBUG_PIM_NHT;
7161 return CMD_SUCCESS;
7162 }
7163
7164 DEFUN (debug_pim_nht_rp,
7165 debug_pim_nht_rp_cmd,
7166 "debug pim nht rp",
7167 DEBUG_STR
7168 DEBUG_PIM_STR
7169 "Nexthop Tracking\n"
7170 "RP Nexthop Tracking\n")
7171 {
7172 PIM_DO_DEBUG_PIM_NHT_RP;
7173 return CMD_SUCCESS;
7174 }
7175
7176 DEFUN (no_debug_pim_nht_rp,
7177 no_debug_pim_nht_rp_cmd,
7178 "no debug pim nht rp",
7179 NO_STR
7180 DEBUG_STR
7181 DEBUG_PIM_STR
7182 "Nexthop Tracking\n"
7183 "RP Nexthop Tracking\n")
7184 {
7185 PIM_DONT_DEBUG_PIM_NHT_RP;
7186 return CMD_SUCCESS;
7187 }
7188
7189 DEFUN (debug_pim_events,
7190 debug_pim_events_cmd,
7191 "debug pim events",
7192 DEBUG_STR
7193 DEBUG_PIM_STR
7194 DEBUG_PIM_EVENTS_STR)
7195 {
7196 PIM_DO_DEBUG_PIM_EVENTS;
7197 return CMD_SUCCESS;
7198 }
7199
7200 DEFUN (no_debug_pim_events,
7201 no_debug_pim_events_cmd,
7202 "no debug pim events",
7203 NO_STR
7204 DEBUG_STR
7205 DEBUG_PIM_STR
7206 DEBUG_PIM_EVENTS_STR)
7207 {
7208 PIM_DONT_DEBUG_PIM_EVENTS;
7209 return CMD_SUCCESS;
7210 }
7211
7212 DEFUN (debug_pim_packets,
7213 debug_pim_packets_cmd,
7214 "debug pim packets [<hello|joins|register>]",
7215 DEBUG_STR
7216 DEBUG_PIM_STR
7217 DEBUG_PIM_PACKETS_STR
7218 DEBUG_PIM_HELLO_PACKETS_STR
7219 DEBUG_PIM_J_P_PACKETS_STR
7220 DEBUG_PIM_PIM_REG_PACKETS_STR)
7221 {
7222 int idx = 0;
7223 if (argv_find(argv, argc, "hello", &idx)) {
7224 PIM_DO_DEBUG_PIM_HELLO;
7225 vty_out(vty, "PIM Hello debugging is on\n");
7226 } else if (argv_find(argv, argc, "joins", &idx)) {
7227 PIM_DO_DEBUG_PIM_J_P;
7228 vty_out(vty, "PIM Join/Prune debugging is on\n");
7229 } else if (argv_find(argv, argc, "register", &idx)) {
7230 PIM_DO_DEBUG_PIM_REG;
7231 vty_out(vty, "PIM Register debugging is on\n");
7232 } else {
7233 PIM_DO_DEBUG_PIM_PACKETS;
7234 vty_out(vty, "PIM Packet debugging is on \n");
7235 }
7236 return CMD_SUCCESS;
7237 }
7238
7239 DEFUN (no_debug_pim_packets,
7240 no_debug_pim_packets_cmd,
7241 "no debug pim packets [<hello|joins|register>]",
7242 NO_STR
7243 DEBUG_STR
7244 DEBUG_PIM_STR
7245 DEBUG_PIM_PACKETS_STR
7246 DEBUG_PIM_HELLO_PACKETS_STR
7247 DEBUG_PIM_J_P_PACKETS_STR
7248 DEBUG_PIM_PIM_REG_PACKETS_STR)
7249 {
7250 int idx = 0;
7251 if (argv_find(argv, argc, "hello", &idx)) {
7252 PIM_DONT_DEBUG_PIM_HELLO;
7253 vty_out(vty, "PIM Hello debugging is off \n");
7254 } else if (argv_find(argv, argc, "joins", &idx)) {
7255 PIM_DONT_DEBUG_PIM_J_P;
7256 vty_out(vty, "PIM Join/Prune debugging is off \n");
7257 } else if (argv_find(argv, argc, "register", &idx)) {
7258 PIM_DONT_DEBUG_PIM_REG;
7259 vty_out(vty, "PIM Register debugging is off\n");
7260 } else
7261 PIM_DONT_DEBUG_PIM_PACKETS;
7262
7263 return CMD_SUCCESS;
7264 }
7265
7266
7267 DEFUN (debug_pim_packetdump_send,
7268 debug_pim_packetdump_send_cmd,
7269 "debug pim packet-dump send",
7270 DEBUG_STR
7271 DEBUG_PIM_STR
7272 DEBUG_PIM_PACKETDUMP_STR
7273 DEBUG_PIM_PACKETDUMP_SEND_STR)
7274 {
7275 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
7276 return CMD_SUCCESS;
7277 }
7278
7279 DEFUN (no_debug_pim_packetdump_send,
7280 no_debug_pim_packetdump_send_cmd,
7281 "no debug pim packet-dump send",
7282 NO_STR
7283 DEBUG_STR
7284 DEBUG_PIM_STR
7285 DEBUG_PIM_PACKETDUMP_STR
7286 DEBUG_PIM_PACKETDUMP_SEND_STR)
7287 {
7288 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
7289 return CMD_SUCCESS;
7290 }
7291
7292 DEFUN (debug_pim_packetdump_recv,
7293 debug_pim_packetdump_recv_cmd,
7294 "debug pim packet-dump receive",
7295 DEBUG_STR
7296 DEBUG_PIM_STR
7297 DEBUG_PIM_PACKETDUMP_STR
7298 DEBUG_PIM_PACKETDUMP_RECV_STR)
7299 {
7300 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
7301 return CMD_SUCCESS;
7302 }
7303
7304 DEFUN (no_debug_pim_packetdump_recv,
7305 no_debug_pim_packetdump_recv_cmd,
7306 "no debug pim packet-dump receive",
7307 NO_STR
7308 DEBUG_STR
7309 DEBUG_PIM_STR
7310 DEBUG_PIM_PACKETDUMP_STR
7311 DEBUG_PIM_PACKETDUMP_RECV_STR)
7312 {
7313 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
7314 return CMD_SUCCESS;
7315 }
7316
7317 DEFUN (debug_pim_trace,
7318 debug_pim_trace_cmd,
7319 "debug pim trace",
7320 DEBUG_STR
7321 DEBUG_PIM_STR
7322 DEBUG_PIM_TRACE_STR)
7323 {
7324 PIM_DO_DEBUG_PIM_TRACE;
7325 return CMD_SUCCESS;
7326 }
7327
7328 DEFUN (debug_pim_trace_detail,
7329 debug_pim_trace_detail_cmd,
7330 "debug pim trace detail",
7331 DEBUG_STR
7332 DEBUG_PIM_STR
7333 DEBUG_PIM_TRACE_STR
7334 "Detailed Information\n")
7335 {
7336 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
7337 return CMD_SUCCESS;
7338 }
7339
7340 DEFUN (no_debug_pim_trace,
7341 no_debug_pim_trace_cmd,
7342 "no debug pim trace",
7343 NO_STR
7344 DEBUG_STR
7345 DEBUG_PIM_STR
7346 DEBUG_PIM_TRACE_STR)
7347 {
7348 PIM_DONT_DEBUG_PIM_TRACE;
7349 return CMD_SUCCESS;
7350 }
7351
7352 DEFUN (no_debug_pim_trace_detail,
7353 no_debug_pim_trace_detail_cmd,
7354 "no debug pim trace detail",
7355 NO_STR
7356 DEBUG_STR
7357 DEBUG_PIM_STR
7358 DEBUG_PIM_TRACE_STR
7359 "Detailed Information\n")
7360 {
7361 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
7362 return CMD_SUCCESS;
7363 }
7364
7365 DEFUN (debug_ssmpingd,
7366 debug_ssmpingd_cmd,
7367 "debug ssmpingd",
7368 DEBUG_STR
7369 DEBUG_SSMPINGD_STR)
7370 {
7371 PIM_DO_DEBUG_SSMPINGD;
7372 return CMD_SUCCESS;
7373 }
7374
7375 DEFUN (no_debug_ssmpingd,
7376 no_debug_ssmpingd_cmd,
7377 "no debug ssmpingd",
7378 NO_STR
7379 DEBUG_STR
7380 DEBUG_SSMPINGD_STR)
7381 {
7382 PIM_DONT_DEBUG_SSMPINGD;
7383 return CMD_SUCCESS;
7384 }
7385
7386 DEFUN (debug_pim_zebra,
7387 debug_pim_zebra_cmd,
7388 "debug pim zebra",
7389 DEBUG_STR
7390 DEBUG_PIM_STR
7391 DEBUG_PIM_ZEBRA_STR)
7392 {
7393 PIM_DO_DEBUG_ZEBRA;
7394 return CMD_SUCCESS;
7395 }
7396
7397 DEFUN (no_debug_pim_zebra,
7398 no_debug_pim_zebra_cmd,
7399 "no debug pim zebra",
7400 NO_STR
7401 DEBUG_STR
7402 DEBUG_PIM_STR
7403 DEBUG_PIM_ZEBRA_STR)
7404 {
7405 PIM_DONT_DEBUG_ZEBRA;
7406 return CMD_SUCCESS;
7407 }
7408
7409 DEFUN (debug_msdp,
7410 debug_msdp_cmd,
7411 "debug msdp",
7412 DEBUG_STR
7413 DEBUG_MSDP_STR)
7414 {
7415 PIM_DO_DEBUG_MSDP_EVENTS;
7416 PIM_DO_DEBUG_MSDP_PACKETS;
7417 return CMD_SUCCESS;
7418 }
7419
7420 DEFUN (no_debug_msdp,
7421 no_debug_msdp_cmd,
7422 "no debug msdp",
7423 NO_STR
7424 DEBUG_STR
7425 DEBUG_MSDP_STR)
7426 {
7427 PIM_DONT_DEBUG_MSDP_EVENTS;
7428 PIM_DONT_DEBUG_MSDP_PACKETS;
7429 return CMD_SUCCESS;
7430 }
7431
7432 DEFUN (debug_msdp_events,
7433 debug_msdp_events_cmd,
7434 "debug msdp events",
7435 DEBUG_STR
7436 DEBUG_MSDP_STR
7437 DEBUG_MSDP_EVENTS_STR)
7438 {
7439 PIM_DO_DEBUG_MSDP_EVENTS;
7440 return CMD_SUCCESS;
7441 }
7442
7443 DEFUN (no_debug_msdp_events,
7444 no_debug_msdp_events_cmd,
7445 "no debug msdp events",
7446 NO_STR
7447 DEBUG_STR
7448 DEBUG_MSDP_STR
7449 DEBUG_MSDP_EVENTS_STR)
7450 {
7451 PIM_DONT_DEBUG_MSDP_EVENTS;
7452 return CMD_SUCCESS;
7453 }
7454
7455 DEFUN (debug_msdp_packets,
7456 debug_msdp_packets_cmd,
7457 "debug msdp packets",
7458 DEBUG_STR
7459 DEBUG_MSDP_STR
7460 DEBUG_MSDP_PACKETS_STR)
7461 {
7462 PIM_DO_DEBUG_MSDP_PACKETS;
7463 return CMD_SUCCESS;
7464 }
7465
7466 DEFUN (no_debug_msdp_packets,
7467 no_debug_msdp_packets_cmd,
7468 "no debug msdp packets",
7469 NO_STR
7470 DEBUG_STR
7471 DEBUG_MSDP_STR
7472 DEBUG_MSDP_PACKETS_STR)
7473 {
7474 PIM_DONT_DEBUG_MSDP_PACKETS;
7475 return CMD_SUCCESS;
7476 }
7477
7478 DEFUN (debug_mtrace,
7479 debug_mtrace_cmd,
7480 "debug mtrace",
7481 DEBUG_STR
7482 DEBUG_MTRACE_STR)
7483 {
7484 PIM_DO_DEBUG_MTRACE;
7485 return CMD_SUCCESS;
7486 }
7487
7488 DEFUN (no_debug_mtrace,
7489 no_debug_mtrace_cmd,
7490 "no debug mtrace",
7491 NO_STR
7492 DEBUG_STR
7493 DEBUG_MTRACE_STR)
7494 {
7495 PIM_DONT_DEBUG_MTRACE;
7496 return CMD_SUCCESS;
7497 }
7498
7499 DEFUN_NOSH (show_debugging_pim,
7500 show_debugging_pim_cmd,
7501 "show debugging [pim]",
7502 SHOW_STR
7503 DEBUG_STR
7504 PIM_STR)
7505 {
7506 vty_out(vty, "PIM debugging status\n");
7507
7508 pim_debug_config_write(vty);
7509
7510 return CMD_SUCCESS;
7511 }
7512
7513 static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
7514 {
7515 int result;
7516 struct in_addr source_addr;
7517 int ret = CMD_SUCCESS;
7518 VTY_DECLVAR_CONTEXT(interface, ifp);
7519
7520 result = inet_pton(AF_INET, source, &source_addr);
7521 if (result <= 0) {
7522 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
7523 errno, safe_strerror(errno));
7524 return CMD_WARNING_CONFIG_FAILED;
7525 }
7526
7527 result = pim_update_source_set(ifp, source_addr);
7528 switch (result) {
7529 case PIM_SUCCESS:
7530 break;
7531 case PIM_IFACE_NOT_FOUND:
7532 ret = CMD_WARNING_CONFIG_FAILED;
7533 vty_out(vty, "Pim not enabled on this interface\n");
7534 break;
7535 case PIM_UPDATE_SOURCE_DUP:
7536 ret = CMD_WARNING;
7537 vty_out(vty, "%% Source already set to %s\n", source);
7538 break;
7539 default:
7540 ret = CMD_WARNING_CONFIG_FAILED;
7541 vty_out(vty, "%% Source set failed\n");
7542 }
7543
7544 return ret;
7545 }
7546
7547 DEFUN (interface_pim_use_source,
7548 interface_pim_use_source_cmd,
7549 "ip pim use-source A.B.C.D",
7550 IP_STR
7551 PIM_STR
7552 "Configure primary IP address\n"
7553 "source ip address\n")
7554 {
7555 return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
7556 }
7557
7558 DEFUN (interface_no_pim_use_source,
7559 interface_no_pim_use_source_cmd,
7560 "no ip pim use-source [A.B.C.D]",
7561 NO_STR
7562 IP_STR
7563 PIM_STR
7564 "Delete source IP address\n"
7565 "source ip address\n")
7566 {
7567 return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
7568 }
7569
7570 DEFUN (ip_pim_bfd,
7571 ip_pim_bfd_cmd,
7572 "ip pim bfd",
7573 IP_STR
7574 PIM_STR
7575 "Enables BFD support\n")
7576 {
7577 VTY_DECLVAR_CONTEXT(interface, ifp);
7578 struct pim_interface *pim_ifp = ifp->info;
7579 struct bfd_info *bfd_info = NULL;
7580
7581 if (!pim_ifp) {
7582 if (!pim_cmd_interface_add(ifp)) {
7583 vty_out(vty, "Could not enable PIM SM on interface\n");
7584 return CMD_WARNING;
7585 }
7586 }
7587 pim_ifp = ifp->info;
7588
7589 bfd_info = pim_ifp->bfd_info;
7590
7591 if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
7592 pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
7593 BFD_DEF_DETECT_MULT, 1);
7594
7595 return CMD_SUCCESS;
7596 }
7597
7598 DEFUN (no_ip_pim_bfd,
7599 no_ip_pim_bfd_cmd,
7600 "no ip pim bfd",
7601 NO_STR
7602 IP_STR
7603 PIM_STR
7604 "Disables BFD support\n")
7605 {
7606 VTY_DECLVAR_CONTEXT(interface, ifp);
7607 struct pim_interface *pim_ifp = ifp->info;
7608
7609 if (!pim_ifp) {
7610 vty_out(vty, "Pim not enabled on this interface\n");
7611 return CMD_WARNING;
7612 }
7613
7614 if (pim_ifp->bfd_info) {
7615 pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
7616 bfd_info_free(&(pim_ifp->bfd_info));
7617 }
7618
7619 return CMD_SUCCESS;
7620 }
7621
7622 #if HAVE_BFDD > 0
7623 DEFUN_HIDDEN(
7624 #else
7625 DEFUN(
7626 #endif /* HAVE_BFDD */
7627 ip_pim_bfd_param,
7628 ip_pim_bfd_param_cmd,
7629 "ip pim bfd (2-255) (50-60000) (50-60000)",
7630 IP_STR
7631 PIM_STR
7632 "Enables BFD support\n"
7633 "Detect Multiplier\n"
7634 "Required min receive interval\n"
7635 "Desired min transmit interval\n")
7636 {
7637 VTY_DECLVAR_CONTEXT(interface, ifp);
7638 int idx_number = 3;
7639 int idx_number_2 = 4;
7640 int idx_number_3 = 5;
7641 uint32_t rx_val;
7642 uint32_t tx_val;
7643 uint8_t dm_val;
7644 int ret;
7645 struct pim_interface *pim_ifp = ifp->info;
7646
7647 if (!pim_ifp) {
7648 if (!pim_cmd_interface_add(ifp)) {
7649 vty_out(vty, "Could not enable PIM SM on interface\n");
7650 return CMD_WARNING;
7651 }
7652 }
7653
7654 if ((ret = bfd_validate_param(
7655 vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
7656 argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
7657 != CMD_SUCCESS)
7658 return ret;
7659
7660 pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
7661
7662 return CMD_SUCCESS;
7663 }
7664
7665 #if HAVE_BFDD == 0
7666 ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
7667 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
7668 "Enables BFD support\n"
7669 "Detect Multiplier\n"
7670 "Required min receive interval\n"
7671 "Desired min transmit interval\n")
7672 #endif /* !HAVE_BFDD */
7673
7674 static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
7675 const char *peer, const char *local)
7676 {
7677 enum pim_msdp_err result;
7678 struct in_addr peer_addr;
7679 struct in_addr local_addr;
7680 int ret = CMD_SUCCESS;
7681
7682 result = inet_pton(AF_INET, peer, &peer_addr);
7683 if (result <= 0) {
7684 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
7685 errno, safe_strerror(errno));
7686 return CMD_WARNING_CONFIG_FAILED;
7687 }
7688
7689 result = inet_pton(AF_INET, local, &local_addr);
7690 if (result <= 0) {
7691 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
7692 errno, safe_strerror(errno));
7693 return CMD_WARNING_CONFIG_FAILED;
7694 }
7695
7696 result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
7697 NULL /* mp_p */);
7698 switch (result) {
7699 case PIM_MSDP_ERR_NONE:
7700 break;
7701 case PIM_MSDP_ERR_OOM:
7702 ret = CMD_WARNING_CONFIG_FAILED;
7703 vty_out(vty, "%% Out of memory\n");
7704 break;
7705 case PIM_MSDP_ERR_PEER_EXISTS:
7706 ret = CMD_WARNING;
7707 vty_out(vty, "%% Peer exists\n");
7708 break;
7709 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
7710 ret = CMD_WARNING_CONFIG_FAILED;
7711 vty_out(vty, "%% Only one mesh-group allowed currently\n");
7712 break;
7713 default:
7714 ret = CMD_WARNING_CONFIG_FAILED;
7715 vty_out(vty, "%% peer add failed\n");
7716 }
7717
7718 return ret;
7719 }
7720
7721 DEFUN_HIDDEN (ip_msdp_peer,
7722 ip_msdp_peer_cmd,
7723 "ip msdp peer A.B.C.D source A.B.C.D",
7724 IP_STR
7725 CFG_MSDP_STR
7726 "Configure MSDP peer\n"
7727 "peer ip address\n"
7728 "Source address for TCP connection\n"
7729 "local ip address\n")
7730 {
7731 PIM_DECLVAR_CONTEXT(vrf, pim);
7732 return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg);
7733 }
7734
7735 static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
7736 const char *peer)
7737 {
7738 enum pim_msdp_err result;
7739 struct in_addr peer_addr;
7740
7741 result = inet_pton(AF_INET, peer, &peer_addr);
7742 if (result <= 0) {
7743 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
7744 errno, safe_strerror(errno));
7745 return CMD_WARNING_CONFIG_FAILED;
7746 }
7747
7748 result = pim_msdp_peer_del(pim, peer_addr);
7749 switch (result) {
7750 case PIM_MSDP_ERR_NONE:
7751 break;
7752 case PIM_MSDP_ERR_NO_PEER:
7753 vty_out(vty, "%% Peer does not exist\n");
7754 break;
7755 default:
7756 vty_out(vty, "%% peer del failed\n");
7757 }
7758
7759 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
7760 }
7761
7762 DEFUN_HIDDEN (no_ip_msdp_peer,
7763 no_ip_msdp_peer_cmd,
7764 "no ip msdp peer A.B.C.D",
7765 NO_STR
7766 IP_STR
7767 CFG_MSDP_STR
7768 "Delete MSDP peer\n"
7769 "peer ip address\n")
7770 {
7771 PIM_DECLVAR_CONTEXT(vrf, pim);
7772 return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg);
7773 }
7774
7775 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
7776 struct vty *vty, const char *mg,
7777 const char *mbr)
7778 {
7779 enum pim_msdp_err result;
7780 struct in_addr mbr_ip;
7781 int ret = CMD_SUCCESS;
7782
7783 result = inet_pton(AF_INET, mbr, &mbr_ip);
7784 if (result <= 0) {
7785 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
7786 errno, safe_strerror(errno));
7787 return CMD_WARNING_CONFIG_FAILED;
7788 }
7789
7790 result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
7791 switch (result) {
7792 case PIM_MSDP_ERR_NONE:
7793 break;
7794 case PIM_MSDP_ERR_OOM:
7795 ret = CMD_WARNING_CONFIG_FAILED;
7796 vty_out(vty, "%% Out of memory\n");
7797 break;
7798 case PIM_MSDP_ERR_MG_MBR_EXISTS:
7799 ret = CMD_WARNING;
7800 vty_out(vty, "%% mesh-group member exists\n");
7801 break;
7802 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
7803 ret = CMD_WARNING_CONFIG_FAILED;
7804 vty_out(vty, "%% Only one mesh-group allowed currently\n");
7805 break;
7806 default:
7807 ret = CMD_WARNING_CONFIG_FAILED;
7808 vty_out(vty, "%% member add failed\n");
7809 }
7810
7811 return ret;
7812 }
7813
7814 DEFUN (ip_msdp_mesh_group_member,
7815 ip_msdp_mesh_group_member_cmd,
7816 "ip msdp mesh-group WORD member A.B.C.D",
7817 IP_STR
7818 CFG_MSDP_STR
7819 "Configure MSDP mesh-group\n"
7820 "mesh group name\n"
7821 "mesh group member\n"
7822 "peer ip address\n")
7823 {
7824 PIM_DECLVAR_CONTEXT(vrf, pim);
7825 return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg,
7826 argv[5]->arg);
7827 }
7828
7829 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
7830 struct vty *vty,
7831 const char *mg,
7832 const char *mbr)
7833 {
7834 enum pim_msdp_err result;
7835 struct in_addr mbr_ip;
7836
7837 result = inet_pton(AF_INET, mbr, &mbr_ip);
7838 if (result <= 0) {
7839 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
7840 errno, safe_strerror(errno));
7841 return CMD_WARNING_CONFIG_FAILED;
7842 }
7843
7844 result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
7845 switch (result) {
7846 case PIM_MSDP_ERR_NONE:
7847 break;
7848 case PIM_MSDP_ERR_NO_MG:
7849 vty_out(vty, "%% mesh-group does not exist\n");
7850 break;
7851 case PIM_MSDP_ERR_NO_MG_MBR:
7852 vty_out(vty, "%% mesh-group member does not exist\n");
7853 break;
7854 default:
7855 vty_out(vty, "%% mesh-group member del failed\n");
7856 }
7857
7858 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
7859 }
7860 DEFUN (no_ip_msdp_mesh_group_member,
7861 no_ip_msdp_mesh_group_member_cmd,
7862 "no ip msdp mesh-group WORD member A.B.C.D",
7863 NO_STR
7864 IP_STR
7865 CFG_MSDP_STR
7866 "Delete MSDP mesh-group member\n"
7867 "mesh group name\n"
7868 "mesh group member\n"
7869 "peer ip address\n")
7870 {
7871 PIM_DECLVAR_CONTEXT(vrf, pim);
7872 return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg,
7873 argv[6]->arg);
7874 }
7875
7876 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
7877 struct vty *vty, const char *mg,
7878 const char *src)
7879 {
7880 enum pim_msdp_err result;
7881 struct in_addr src_ip;
7882
7883 result = inet_pton(AF_INET, src, &src_ip);
7884 if (result <= 0) {
7885 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
7886 errno, safe_strerror(errno));
7887 return CMD_WARNING_CONFIG_FAILED;
7888 }
7889
7890 result = pim_msdp_mg_src_add(pim, mg, src_ip);
7891 switch (result) {
7892 case PIM_MSDP_ERR_NONE:
7893 break;
7894 case PIM_MSDP_ERR_OOM:
7895 vty_out(vty, "%% Out of memory\n");
7896 break;
7897 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
7898 vty_out(vty, "%% Only one mesh-group allowed currently\n");
7899 break;
7900 default:
7901 vty_out(vty, "%% source add failed\n");
7902 }
7903
7904 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
7905 }
7906
7907
7908 DEFUN (ip_msdp_mesh_group_source,
7909 ip_msdp_mesh_group_source_cmd,
7910 "ip msdp mesh-group WORD source A.B.C.D",
7911 IP_STR
7912 CFG_MSDP_STR
7913 "Configure MSDP mesh-group\n"
7914 "mesh group name\n"
7915 "mesh group local address\n"
7916 "source ip address for the TCP connection\n")
7917 {
7918 PIM_DECLVAR_CONTEXT(vrf, pim);
7919 return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg,
7920 argv[5]->arg);
7921 }
7922
7923 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
7924 struct vty *vty,
7925 const char *mg)
7926 {
7927 enum pim_msdp_err result;
7928
7929 result = pim_msdp_mg_src_del(pim, mg);
7930 switch (result) {
7931 case PIM_MSDP_ERR_NONE:
7932 break;
7933 case PIM_MSDP_ERR_NO_MG:
7934 vty_out(vty, "%% mesh-group does not exist\n");
7935 break;
7936 default:
7937 vty_out(vty, "%% mesh-group source del failed\n");
7938 }
7939
7940 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
7941 }
7942
7943 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
7944 struct vty *vty, const char *mg)
7945 {
7946 enum pim_msdp_err result;
7947
7948 result = pim_msdp_mg_del(pim, mg);
7949 switch (result) {
7950 case PIM_MSDP_ERR_NONE:
7951 break;
7952 case PIM_MSDP_ERR_NO_MG:
7953 vty_out(vty, "%% mesh-group does not exist\n");
7954 break;
7955 default:
7956 vty_out(vty, "%% mesh-group source del failed\n");
7957 }
7958
7959 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
7960 }
7961
7962 DEFUN (no_ip_msdp_mesh_group_source,
7963 no_ip_msdp_mesh_group_source_cmd,
7964 "no ip msdp mesh-group WORD source [A.B.C.D]",
7965 NO_STR
7966 IP_STR
7967 CFG_MSDP_STR
7968 "Delete MSDP mesh-group source\n"
7969 "mesh group name\n"
7970 "mesh group source\n"
7971 "mesh group local address\n")
7972 {
7973 PIM_DECLVAR_CONTEXT(vrf, pim);
7974 if (argc == 7)
7975 return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[6]->arg);
7976 else
7977 return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty,
7978 argv[4]->arg);
7979 }
7980
7981 static void print_empty_json_obj(struct vty *vty)
7982 {
7983 json_object *json;
7984 json = json_object_new_object();
7985 vty_out(vty, "%s\n",
7986 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
7987 json_object_free(json);
7988 }
7989
7990 static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
7991 bool uj)
7992 {
7993 struct listnode *mbrnode;
7994 struct pim_msdp_mg_mbr *mbr;
7995 struct pim_msdp_mg *mg = pim->msdp.mg;
7996 char mbr_str[INET_ADDRSTRLEN];
7997 char src_str[INET_ADDRSTRLEN];
7998 char state_str[PIM_MSDP_STATE_STRLEN];
7999 enum pim_msdp_peer_state state;
8000 json_object *json = NULL;
8001 json_object *json_mg_row = NULL;
8002 json_object *json_members = NULL;
8003 json_object *json_row = NULL;
8004
8005 if (!mg) {
8006 if (uj)
8007 print_empty_json_obj(vty);
8008 return;
8009 }
8010
8011 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
8012 if (uj) {
8013 json = json_object_new_object();
8014 /* currently there is only one mesh group but we should still
8015 * make
8016 * it a dict with mg-name as key */
8017 json_mg_row = json_object_new_object();
8018 json_object_string_add(json_mg_row, "name",
8019 mg->mesh_group_name);
8020 json_object_string_add(json_mg_row, "source", src_str);
8021 } else {
8022 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
8023 vty_out(vty, " Source : %s\n", src_str);
8024 vty_out(vty, " Member State\n");
8025 }
8026
8027 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
8028 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
8029 if (mbr->mp) {
8030 state = mbr->mp->state;
8031 } else {
8032 state = PIM_MSDP_DISABLED;
8033 }
8034 pim_msdp_state_dump(state, state_str, sizeof(state_str));
8035 if (uj) {
8036 json_row = json_object_new_object();
8037 json_object_string_add(json_row, "member", mbr_str);
8038 json_object_string_add(json_row, "state", state_str);
8039 if (!json_members) {
8040 json_members = json_object_new_object();
8041 json_object_object_add(json_mg_row, "members",
8042 json_members);
8043 }
8044 json_object_object_add(json_members, mbr_str, json_row);
8045 } else {
8046 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
8047 }
8048 }
8049
8050 if (uj) {
8051 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
8052 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8053 json, JSON_C_TO_STRING_PRETTY));
8054 json_object_free(json);
8055 }
8056 }
8057
8058 DEFUN (show_ip_msdp_mesh_group,
8059 show_ip_msdp_mesh_group_cmd,
8060 "show ip msdp [vrf NAME] mesh-group [json]",
8061 SHOW_STR
8062 IP_STR
8063 MSDP_STR
8064 VRF_CMD_HELP_STR
8065 "MSDP mesh-group information\n"
8066 JSON_STR)
8067 {
8068 bool uj = use_json(argc, argv);
8069 int idx = 2;
8070 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
8071
8072 if (!vrf)
8073 return CMD_WARNING;
8074
8075 ip_msdp_show_mesh_group(vrf->info, vty, uj);
8076
8077 return CMD_SUCCESS;
8078 }
8079
8080 DEFUN (show_ip_msdp_mesh_group_vrf_all,
8081 show_ip_msdp_mesh_group_vrf_all_cmd,
8082 "show ip msdp vrf all mesh-group [json]",
8083 SHOW_STR
8084 IP_STR
8085 MSDP_STR
8086 VRF_CMD_HELP_STR
8087 "MSDP mesh-group information\n"
8088 JSON_STR)
8089 {
8090 bool uj = use_json(argc, argv);
8091 struct vrf *vrf;
8092 bool first = true;
8093
8094 if (uj)
8095 vty_out(vty, "{ ");
8096 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
8097 if (uj) {
8098 if (!first)
8099 vty_out(vty, ", ");
8100 vty_out(vty, " \"%s\": ", vrf->name);
8101 first = false;
8102 } else
8103 vty_out(vty, "VRF: %s\n", vrf->name);
8104 ip_msdp_show_mesh_group(vrf->info, vty, uj);
8105 }
8106 if (uj)
8107 vty_out(vty, "}\n");
8108
8109 return CMD_SUCCESS;
8110 }
8111
8112 static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
8113 bool uj)
8114 {
8115 struct listnode *mpnode;
8116 struct pim_msdp_peer *mp;
8117 char peer_str[INET_ADDRSTRLEN];
8118 char local_str[INET_ADDRSTRLEN];
8119 char state_str[PIM_MSDP_STATE_STRLEN];
8120 char timebuf[PIM_MSDP_UPTIME_STRLEN];
8121 int64_t now;
8122 json_object *json = NULL;
8123 json_object *json_row = NULL;
8124
8125
8126 if (uj) {
8127 json = json_object_new_object();
8128 } else {
8129 vty_out(vty,
8130 "Peer Local State Uptime SaCnt\n");
8131 }
8132
8133 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
8134 if (mp->state == PIM_MSDP_ESTABLISHED) {
8135 now = pim_time_monotonic_sec();
8136 pim_time_uptime(timebuf, sizeof(timebuf),
8137 now - mp->uptime);
8138 } else {
8139 strcpy(timebuf, "-");
8140 }
8141 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
8142 pim_inet4_dump("<local?>", mp->local, local_str,
8143 sizeof(local_str));
8144 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
8145 if (uj) {
8146 json_row = json_object_new_object();
8147 json_object_string_add(json_row, "peer", peer_str);
8148 json_object_string_add(json_row, "local", local_str);
8149 json_object_string_add(json_row, "state", state_str);
8150 json_object_string_add(json_row, "upTime", timebuf);
8151 json_object_int_add(json_row, "saCount", mp->sa_cnt);
8152 json_object_object_add(json, peer_str, json_row);
8153 } else {
8154 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
8155 local_str, state_str, timebuf, mp->sa_cnt);
8156 }
8157 }
8158
8159 if (uj) {
8160 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8161 json, JSON_C_TO_STRING_PRETTY));
8162 json_object_free(json);
8163 }
8164 }
8165
8166 static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
8167 const char *peer, bool uj)
8168 {
8169 struct listnode *mpnode;
8170 struct pim_msdp_peer *mp;
8171 char peer_str[INET_ADDRSTRLEN];
8172 char local_str[INET_ADDRSTRLEN];
8173 char state_str[PIM_MSDP_STATE_STRLEN];
8174 char timebuf[PIM_MSDP_UPTIME_STRLEN];
8175 char katimer[PIM_MSDP_TIMER_STRLEN];
8176 char crtimer[PIM_MSDP_TIMER_STRLEN];
8177 char holdtimer[PIM_MSDP_TIMER_STRLEN];
8178 int64_t now;
8179 json_object *json = NULL;
8180 json_object *json_row = NULL;
8181
8182 if (uj) {
8183 json = json_object_new_object();
8184 }
8185
8186 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
8187 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
8188 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
8189 continue;
8190
8191 if (mp->state == PIM_MSDP_ESTABLISHED) {
8192 now = pim_time_monotonic_sec();
8193 pim_time_uptime(timebuf, sizeof(timebuf),
8194 now - mp->uptime);
8195 } else {
8196 strcpy(timebuf, "-");
8197 }
8198 pim_inet4_dump("<local?>", mp->local, local_str,
8199 sizeof(local_str));
8200 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
8201 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
8202 mp->ka_timer);
8203 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
8204 mp->cr_timer);
8205 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
8206 mp->hold_timer);
8207
8208 if (uj) {
8209 json_row = json_object_new_object();
8210 json_object_string_add(json_row, "peer", peer_str);
8211 json_object_string_add(json_row, "local", local_str);
8212 json_object_string_add(json_row, "meshGroupName",
8213 mp->mesh_group_name);
8214 json_object_string_add(json_row, "state", state_str);
8215 json_object_string_add(json_row, "upTime", timebuf);
8216 json_object_string_add(json_row, "keepAliveTimer",
8217 katimer);
8218 json_object_string_add(json_row, "connRetryTimer",
8219 crtimer);
8220 json_object_string_add(json_row, "holdTimer",
8221 holdtimer);
8222 json_object_string_add(json_row, "lastReset",
8223 mp->last_reset);
8224 json_object_int_add(json_row, "connAttempts",
8225 mp->conn_attempts);
8226 json_object_int_add(json_row, "establishedChanges",
8227 mp->est_flaps);
8228 json_object_int_add(json_row, "saCount", mp->sa_cnt);
8229 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
8230 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
8231 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
8232 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
8233 json_object_object_add(json, peer_str, json_row);
8234 } else {
8235 vty_out(vty, "Peer : %s\n", peer_str);
8236 vty_out(vty, " Local : %s\n", local_str);
8237 vty_out(vty, " Mesh Group : %s\n",
8238 mp->mesh_group_name);
8239 vty_out(vty, " State : %s\n", state_str);
8240 vty_out(vty, " Uptime : %s\n", timebuf);
8241
8242 vty_out(vty, " Keepalive Timer : %s\n", katimer);
8243 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
8244 vty_out(vty, " Hold Timer : %s\n", holdtimer);
8245 vty_out(vty, " Last Reset : %s\n",
8246 mp->last_reset);
8247 vty_out(vty, " Conn Attempts : %d\n",
8248 mp->conn_attempts);
8249 vty_out(vty, " Established Changes : %d\n",
8250 mp->est_flaps);
8251 vty_out(vty, " SA Count : %d\n",
8252 mp->sa_cnt);
8253 vty_out(vty, " Statistics :\n");
8254 vty_out(vty,
8255 " Sent Rcvd\n");
8256 vty_out(vty, " Keepalives : %10d %10d\n",
8257 mp->ka_tx_cnt, mp->ka_rx_cnt);
8258 vty_out(vty, " SAs : %10d %10d\n",
8259 mp->sa_tx_cnt, mp->sa_rx_cnt);
8260 vty_out(vty, "\n");
8261 }
8262 }
8263
8264 if (uj) {
8265 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8266 json, JSON_C_TO_STRING_PRETTY));
8267 json_object_free(json);
8268 }
8269 }
8270
8271 DEFUN (show_ip_msdp_peer_detail,
8272 show_ip_msdp_peer_detail_cmd,
8273 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
8274 SHOW_STR
8275 IP_STR
8276 MSDP_STR
8277 VRF_CMD_HELP_STR
8278 "MSDP peer information\n"
8279 "Detailed output\n"
8280 "peer ip address\n"
8281 JSON_STR)
8282 {
8283 bool uj = use_json(argc, argv);
8284 int idx = 2;
8285 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
8286
8287 if (!vrf)
8288 return CMD_WARNING;
8289
8290 char *arg = NULL;
8291
8292 if (argv_find(argv, argc, "detail", &idx))
8293 arg = argv[idx]->text;
8294 else if (argv_find(argv, argc, "A.B.C.D", &idx))
8295 arg = argv[idx]->arg;
8296
8297 if (arg)
8298 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
8299 else
8300 ip_msdp_show_peers(vrf->info, vty, uj);
8301
8302 return CMD_SUCCESS;
8303 }
8304
8305 DEFUN (show_ip_msdp_peer_detail_vrf_all,
8306 show_ip_msdp_peer_detail_vrf_all_cmd,
8307 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
8308 SHOW_STR
8309 IP_STR
8310 MSDP_STR
8311 VRF_CMD_HELP_STR
8312 "MSDP peer information\n"
8313 "Detailed output\n"
8314 "peer ip address\n"
8315 JSON_STR)
8316 {
8317 int idx = 2;
8318 bool uj = use_json(argc, argv);
8319 struct vrf *vrf;
8320 bool first = true;
8321
8322 if (uj)
8323 vty_out(vty, "{ ");
8324 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
8325 if (uj) {
8326 if (!first)
8327 vty_out(vty, ", ");
8328 vty_out(vty, " \"%s\": ", vrf->name);
8329 first = false;
8330 } else
8331 vty_out(vty, "VRF: %s\n", vrf->name);
8332 if (argv_find(argv, argc, "detail", &idx)
8333 || argv_find(argv, argc, "A.B.C.D", &idx))
8334 ip_msdp_show_peers_detail(vrf->info, vty,
8335 argv[idx]->arg, uj);
8336 else
8337 ip_msdp_show_peers(vrf->info, vty, uj);
8338 }
8339 if (uj)
8340 vty_out(vty, "}\n");
8341
8342 return CMD_SUCCESS;
8343 }
8344
8345 static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
8346 {
8347 struct listnode *sanode;
8348 struct pim_msdp_sa *sa;
8349 char src_str[INET_ADDRSTRLEN];
8350 char grp_str[INET_ADDRSTRLEN];
8351 char rp_str[INET_ADDRSTRLEN];
8352 char timebuf[PIM_MSDP_UPTIME_STRLEN];
8353 char spt_str[8];
8354 char local_str[8];
8355 int64_t now;
8356 json_object *json = NULL;
8357 json_object *json_group = NULL;
8358 json_object *json_row = NULL;
8359
8360 if (uj) {
8361 json = json_object_new_object();
8362 } else {
8363 vty_out(vty,
8364 "Source Group RP Local SPT Uptime\n");
8365 }
8366
8367 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8368 now = pim_time_monotonic_sec();
8369 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
8370 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
8371 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
8372 if (sa->flags & PIM_MSDP_SAF_PEER) {
8373 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
8374 if (sa->up) {
8375 strcpy(spt_str, "yes");
8376 } else {
8377 strcpy(spt_str, "no");
8378 }
8379 } else {
8380 strcpy(rp_str, "-");
8381 strcpy(spt_str, "-");
8382 }
8383 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
8384 strcpy(local_str, "yes");
8385 } else {
8386 strcpy(local_str, "no");
8387 }
8388 if (uj) {
8389 json_object_object_get_ex(json, grp_str, &json_group);
8390
8391 if (!json_group) {
8392 json_group = json_object_new_object();
8393 json_object_object_add(json, grp_str,
8394 json_group);
8395 }
8396
8397 json_row = json_object_new_object();
8398 json_object_string_add(json_row, "source", src_str);
8399 json_object_string_add(json_row, "group", grp_str);
8400 json_object_string_add(json_row, "rp", rp_str);
8401 json_object_string_add(json_row, "local", local_str);
8402 json_object_string_add(json_row, "sptSetup", spt_str);
8403 json_object_string_add(json_row, "upTime", timebuf);
8404 json_object_object_add(json_group, src_str, json_row);
8405 } else {
8406 vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
8407 src_str, grp_str, rp_str, local_str[0],
8408 spt_str[0], timebuf);
8409 }
8410 }
8411
8412 if (uj) {
8413 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8414 json, JSON_C_TO_STRING_PRETTY));
8415 json_object_free(json);
8416 }
8417 }
8418
8419 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
8420 const char *src_str,
8421 const char *grp_str, struct vty *vty,
8422 bool uj, json_object *json)
8423 {
8424 char rp_str[INET_ADDRSTRLEN];
8425 char peer_str[INET_ADDRSTRLEN];
8426 char timebuf[PIM_MSDP_UPTIME_STRLEN];
8427 char spt_str[8];
8428 char local_str[8];
8429 char statetimer[PIM_MSDP_TIMER_STRLEN];
8430 int64_t now;
8431 json_object *json_group = NULL;
8432 json_object *json_row = NULL;
8433
8434 now = pim_time_monotonic_sec();
8435 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
8436 if (sa->flags & PIM_MSDP_SAF_PEER) {
8437 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
8438 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
8439 if (sa->up) {
8440 strcpy(spt_str, "yes");
8441 } else {
8442 strcpy(spt_str, "no");
8443 }
8444 } else {
8445 strcpy(rp_str, "-");
8446 strcpy(peer_str, "-");
8447 strcpy(spt_str, "-");
8448 }
8449 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
8450 strcpy(local_str, "yes");
8451 } else {
8452 strcpy(local_str, "no");
8453 }
8454 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
8455 sa->sa_state_timer);
8456 if (uj) {
8457 json_object_object_get_ex(json, grp_str, &json_group);
8458
8459 if (!json_group) {
8460 json_group = json_object_new_object();
8461 json_object_object_add(json, grp_str, json_group);
8462 }
8463
8464 json_row = json_object_new_object();
8465 json_object_string_add(json_row, "source", src_str);
8466 json_object_string_add(json_row, "group", grp_str);
8467 json_object_string_add(json_row, "rp", rp_str);
8468 json_object_string_add(json_row, "local", local_str);
8469 json_object_string_add(json_row, "sptSetup", spt_str);
8470 json_object_string_add(json_row, "upTime", timebuf);
8471 json_object_string_add(json_row, "stateTimer", statetimer);
8472 json_object_object_add(json_group, src_str, json_row);
8473 } else {
8474 vty_out(vty, "SA : %s\n", sa->sg_str);
8475 vty_out(vty, " RP : %s\n", rp_str);
8476 vty_out(vty, " Peer : %s\n", peer_str);
8477 vty_out(vty, " Local : %s\n", local_str);
8478 vty_out(vty, " SPT Setup : %s\n", spt_str);
8479 vty_out(vty, " Uptime : %s\n", timebuf);
8480 vty_out(vty, " State Timer : %s\n", statetimer);
8481 vty_out(vty, "\n");
8482 }
8483 }
8484
8485 static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
8486 bool uj)
8487 {
8488 struct listnode *sanode;
8489 struct pim_msdp_sa *sa;
8490 char src_str[INET_ADDRSTRLEN];
8491 char grp_str[INET_ADDRSTRLEN];
8492 json_object *json = NULL;
8493
8494 if (uj) {
8495 json = json_object_new_object();
8496 }
8497
8498 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8499 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
8500 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
8501 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
8502 json);
8503 }
8504
8505 if (uj) {
8506 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8507 json, JSON_C_TO_STRING_PRETTY));
8508 json_object_free(json);
8509 }
8510 }
8511
8512 DEFUN (show_ip_msdp_sa_detail,
8513 show_ip_msdp_sa_detail_cmd,
8514 "show ip msdp [vrf NAME] sa detail [json]",
8515 SHOW_STR
8516 IP_STR
8517 MSDP_STR
8518 VRF_CMD_HELP_STR
8519 "MSDP active-source information\n"
8520 "Detailed output\n"
8521 JSON_STR)
8522 {
8523 bool uj = use_json(argc, argv);
8524 int idx = 2;
8525 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
8526
8527 if (!vrf)
8528 return CMD_WARNING;
8529
8530 ip_msdp_show_sa_detail(vrf->info, vty, uj);
8531
8532 return CMD_SUCCESS;
8533 }
8534
8535 DEFUN (show_ip_msdp_sa_detail_vrf_all,
8536 show_ip_msdp_sa_detail_vrf_all_cmd,
8537 "show ip msdp vrf all sa detail [json]",
8538 SHOW_STR
8539 IP_STR
8540 MSDP_STR
8541 VRF_CMD_HELP_STR
8542 "MSDP active-source information\n"
8543 "Detailed output\n"
8544 JSON_STR)
8545 {
8546 bool uj = use_json(argc, argv);
8547 struct vrf *vrf;
8548 bool first = true;
8549
8550 if (uj)
8551 vty_out(vty, "{ ");
8552 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
8553 if (uj) {
8554 if (!first)
8555 vty_out(vty, ", ");
8556 vty_out(vty, " \"%s\": ", vrf->name);
8557 first = false;
8558 } else
8559 vty_out(vty, "VRF: %s\n", vrf->name);
8560 ip_msdp_show_sa_detail(vrf->info, vty, uj);
8561 }
8562 if (uj)
8563 vty_out(vty, "}\n");
8564
8565 return CMD_SUCCESS;
8566 }
8567
8568 static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
8569 const char *addr, bool uj)
8570 {
8571 struct listnode *sanode;
8572 struct pim_msdp_sa *sa;
8573 char src_str[INET_ADDRSTRLEN];
8574 char grp_str[INET_ADDRSTRLEN];
8575 json_object *json = NULL;
8576
8577 if (uj) {
8578 json = json_object_new_object();
8579 }
8580
8581 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8582 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
8583 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
8584 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
8585 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
8586 uj, json);
8587 }
8588 }
8589
8590 if (uj) {
8591 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8592 json, JSON_C_TO_STRING_PRETTY));
8593 json_object_free(json);
8594 }
8595 }
8596
8597 static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
8598 const char *src, const char *grp, bool uj)
8599 {
8600 struct listnode *sanode;
8601 struct pim_msdp_sa *sa;
8602 char src_str[INET_ADDRSTRLEN];
8603 char grp_str[INET_ADDRSTRLEN];
8604 json_object *json = NULL;
8605
8606 if (uj) {
8607 json = json_object_new_object();
8608 }
8609
8610 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
8611 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
8612 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
8613 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
8614 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
8615 uj, json);
8616 }
8617 }
8618
8619 if (uj) {
8620 vty_out(vty, "%s\n", json_object_to_json_string_ext(
8621 json, JSON_C_TO_STRING_PRETTY));
8622 json_object_free(json);
8623 }
8624 }
8625
8626 DEFUN (show_ip_msdp_sa_sg,
8627 show_ip_msdp_sa_sg_cmd,
8628 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
8629 SHOW_STR
8630 IP_STR
8631 MSDP_STR
8632 VRF_CMD_HELP_STR
8633 "MSDP active-source information\n"
8634 "source or group ip\n"
8635 "group ip\n"
8636 JSON_STR)
8637 {
8638 bool uj = use_json(argc, argv);
8639 struct vrf *vrf;
8640 int idx = 2;
8641
8642 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
8643
8644 if (!vrf)
8645 return CMD_WARNING;
8646
8647 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
8648 : NULL;
8649 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
8650 ? argv[idx]->arg
8651 : NULL;
8652
8653 if (src_ip && grp_ip)
8654 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
8655 else if (src_ip)
8656 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
8657 else
8658 ip_msdp_show_sa(vrf->info, vty, uj);
8659
8660 return CMD_SUCCESS;
8661 }
8662
8663 DEFUN (show_ip_msdp_sa_sg_vrf_all,
8664 show_ip_msdp_sa_sg_vrf_all_cmd,
8665 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
8666 SHOW_STR
8667 IP_STR
8668 MSDP_STR
8669 VRF_CMD_HELP_STR
8670 "MSDP active-source information\n"
8671 "source or group ip\n"
8672 "group ip\n"
8673 JSON_STR)
8674 {
8675 bool uj = use_json(argc, argv);
8676 struct vrf *vrf;
8677 bool first = true;
8678 int idx = 2;
8679
8680 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
8681 : NULL;
8682 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
8683 ? argv[idx]->arg
8684 : NULL;
8685
8686 if (uj)
8687 vty_out(vty, "{ ");
8688 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
8689 if (uj) {
8690 if (!first)
8691 vty_out(vty, ", ");
8692 vty_out(vty, " \"%s\": ", vrf->name);
8693 first = false;
8694 } else
8695 vty_out(vty, "VRF: %s\n", vrf->name);
8696
8697 if (src_ip && grp_ip)
8698 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
8699 else if (src_ip)
8700 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
8701 else
8702 ip_msdp_show_sa(vrf->info, vty, uj);
8703 }
8704 if (uj)
8705 vty_out(vty, "}\n");
8706
8707 return CMD_SUCCESS;
8708 }
8709
8710 void pim_cmd_init(void)
8711 {
8712 install_node(&interface_node,
8713 pim_interface_config_write); /* INTERFACE_NODE */
8714 if_cmd_init();
8715
8716 install_node(&debug_node, pim_debug_config_write);
8717
8718 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
8719
8720 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
8721 install_element(VRF_NODE, &ip_pim_rp_cmd);
8722 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
8723 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
8724 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
8725 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
8726 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
8727 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
8728 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
8729 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
8730 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
8731 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
8732 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
8733 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
8734 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
8735 install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
8736 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
8737 install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
8738 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
8739 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
8740 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
8741 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
8742 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
8743 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
8744 install_element(CONFIG_NODE,
8745 &no_ip_pim_spt_switchover_infinity_plist_cmd);
8746 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
8747 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
8748 install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
8749 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
8750 install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
8751 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
8752 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
8753 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
8754 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
8755 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
8756 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
8757 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
8758 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
8759 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
8760 install_element(VRF_NODE, &ip_pim_packets_cmd);
8761 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
8762 install_element(VRF_NODE, &no_ip_pim_packets_cmd);
8763 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
8764 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
8765 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
8766 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
8767 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
8768 install_element(VRF_NODE, &ip_ssmpingd_cmd);
8769 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
8770 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
8771 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
8772 install_element(VRF_NODE, &ip_msdp_peer_cmd);
8773 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
8774 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
8775 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
8776 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
8777 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
8778 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
8779 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
8780 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
8781 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
8782 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
8783
8784 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
8785 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
8786 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
8787 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
8788 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
8789 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
8790 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
8791 install_element(INTERFACE_NODE,
8792 &interface_no_ip_igmp_query_interval_cmd);
8793 install_element(INTERFACE_NODE,
8794 &interface_ip_igmp_query_max_response_time_cmd);
8795 install_element(INTERFACE_NODE,
8796 &interface_no_ip_igmp_query_max_response_time_cmd);
8797 install_element(INTERFACE_NODE,
8798 &interface_ip_igmp_query_max_response_time_dsec_cmd);
8799 install_element(INTERFACE_NODE,
8800 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
8801 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
8802 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
8803 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
8804 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
8805 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
8806 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
8807 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
8808 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
8809 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
8810 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
8811 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
8812 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
8813 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
8814
8815 // Static mroutes NEB
8816 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
8817 install_element(INTERFACE_NODE, &interface_ip_mroute_source_cmd);
8818 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
8819 install_element(INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
8820
8821 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
8822 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
8823 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
8824 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
8825 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
8826 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
8827 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
8828 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
8829 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
8830 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
8831 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
8832 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
8833 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
8834 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
8835 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
8836 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
8837 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
8838 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
8839 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
8840 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
8841 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
8842 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
8843 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
8844 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
8845 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
8846 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
8847 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
8848 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
8849 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
8850 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
8851 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
8852 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
8853 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
8854 install_element(VIEW_NODE, &show_ip_multicast_cmd);
8855 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
8856 install_element(VIEW_NODE, &show_ip_mroute_cmd);
8857 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
8858 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
8859 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
8860 install_element(VIEW_NODE, &show_ip_rib_cmd);
8861 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
8862 install_element(VIEW_NODE, &show_debugging_pim_cmd);
8863 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
8864 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
8865
8866 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
8867 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
8868 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
8869 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
8870 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
8871 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
8872
8873 install_element(ENABLE_NODE, &debug_igmp_cmd);
8874 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
8875 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
8876 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
8877 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
8878 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
8879 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
8880 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
8881 install_element(ENABLE_NODE, &debug_mroute_cmd);
8882 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
8883 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
8884 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
8885 install_element(ENABLE_NODE, &debug_pim_static_cmd);
8886 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
8887 install_element(ENABLE_NODE, &debug_pim_cmd);
8888 install_element(ENABLE_NODE, &no_debug_pim_cmd);
8889 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
8890 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
8891 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
8892 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
8893 install_element(ENABLE_NODE, &debug_pim_events_cmd);
8894 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
8895 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
8896 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
8897 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
8898 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
8899 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
8900 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
8901 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
8902 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
8903 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
8904 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
8905 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
8906 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
8907 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
8908 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
8909 install_element(ENABLE_NODE, &debug_msdp_cmd);
8910 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
8911 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
8912 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
8913 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
8914 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
8915 install_element(ENABLE_NODE, &debug_mtrace_cmd);
8916 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
8917
8918 install_element(CONFIG_NODE, &debug_igmp_cmd);
8919 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
8920 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
8921 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
8922 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
8923 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
8924 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
8925 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
8926 install_element(CONFIG_NODE, &debug_mroute_cmd);
8927 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
8928 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
8929 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
8930 install_element(CONFIG_NODE, &debug_pim_static_cmd);
8931 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
8932 install_element(CONFIG_NODE, &debug_pim_cmd);
8933 install_element(CONFIG_NODE, &no_debug_pim_cmd);
8934 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
8935 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
8936 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
8937 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
8938 install_element(CONFIG_NODE, &debug_pim_events_cmd);
8939 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
8940 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
8941 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
8942 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
8943 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
8944 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
8945 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
8946 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
8947 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
8948 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
8949 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
8950 install_element(CONFIG_NODE, &debug_msdp_cmd);
8951 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
8952 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
8953 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
8954 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
8955 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
8956 install_element(CONFIG_NODE, &debug_mtrace_cmd);
8957 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
8958
8959 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
8960 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
8961 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
8962 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
8963 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
8964 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
8965 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
8966 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
8967 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
8968 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
8969 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
8970 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
8971 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
8972 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
8973 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
8974 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
8975 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
8976 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
8977 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
8978 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
8979 /* Install BFD command */
8980 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
8981 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
8982 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
8983 #if HAVE_BFDD == 0
8984 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
8985 #endif /* !HAVE_BFDD */
8986 }