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