3 * Copyright (C) 2008 Everton da Silva Marques
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.
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.
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
34 #include "pim_mroute.h"
36 #include "pim_iface.h"
38 #include "pim_mroute.h"
41 #include "pim_igmpv3.h"
46 #include "pim_neighbor.h"
48 #include "pim_ifchannel.h"
49 #include "pim_hello.h"
51 #include "pim_upstream.h"
53 #include "pim_macro.h"
54 #include "pim_ssmpingd.h"
55 #include "pim_zebra.h"
56 #include "pim_static.h"
58 #include "pim_zlookup.h"
63 #include "pim_vxlan.h"
67 #include "lib/northbound_cli.h"
68 #include "pim_errors.h"
71 #ifndef VTYSH_EXTRACT_PL
72 #include "pimd/pim_cmd_clippy.c"
75 static struct cmd_node interface_node
= {
77 .node
= INTERFACE_NODE
,
78 .parent_node
= CONFIG_NODE
,
79 .prompt
= "%s(config-if)# ",
80 .config_write
= pim_interface_config_write
,
83 static struct cmd_node debug_node
= {
87 .config_write
= pim_debug_config_write
,
90 static struct vrf
*pim_cmd_lookup_vrf(struct vty
*vty
, struct cmd_token
*argv
[],
91 const int argc
, int *idx
)
95 if (argv_find(argv
, argc
, "NAME", idx
))
96 vrf
= vrf_lookup_by_name(argv
[*idx
]->arg
);
98 vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
101 vty_out(vty
, "Specified VRF: %s does not exist\n",
107 static void pim_show_assert_helper(struct vty
*vty
,
108 struct pim_interface
*pim_ifp
,
109 struct pim_ifchannel
*ch
, time_t now
)
111 char ch_src_str
[INET_ADDRSTRLEN
];
112 char ch_grp_str
[INET_ADDRSTRLEN
];
113 char winner_str
[INET_ADDRSTRLEN
];
114 struct in_addr ifaddr
;
117 char buf
[PREFIX_STRLEN
];
119 ifaddr
= pim_ifp
->primary_address
;
121 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
122 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
123 pim_inet4_dump("<assrt_win?>", ch
->ifassert_winner
, winner_str
,
126 pim_time_uptime(uptime
, sizeof(uptime
), now
- ch
->ifassert_creation
);
127 pim_time_timer_to_mmss(timer
, sizeof(timer
), ch
->t_ifassert_timer
);
129 vty_out(vty
, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
131 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)), ch_src_str
,
132 ch_grp_str
, pim_ifchannel_ifassert_name(ch
->ifassert_state
),
133 winner_str
, uptime
, timer
);
136 static void pim_show_assert(struct pim_instance
*pim
, struct vty
*vty
)
138 struct pim_interface
*pim_ifp
;
139 struct pim_ifchannel
*ch
;
140 struct interface
*ifp
;
143 now
= pim_time_monotonic_sec();
146 "Interface Address Source Group State Winner Uptime Timer\n");
148 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
153 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
154 pim_show_assert_helper(vty
, pim_ifp
, ch
, now
);
155 } /* scan interface channels */
159 static void pim_show_assert_internal_helper(struct vty
*vty
,
160 struct pim_interface
*pim_ifp
,
161 struct pim_ifchannel
*ch
)
163 char ch_src_str
[INET_ADDRSTRLEN
];
164 char ch_grp_str
[INET_ADDRSTRLEN
];
165 struct in_addr ifaddr
;
166 char buf
[PREFIX_STRLEN
];
168 ifaddr
= pim_ifp
->primary_address
;
170 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
171 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
172 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
174 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
175 ch_src_str
, ch_grp_str
,
176 PIM_IF_FLAG_TEST_COULD_ASSERT(ch
->flags
) ? "yes" : "no",
177 pim_macro_ch_could_assert_eval(ch
) ? "yes" : "no",
178 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch
->flags
) ? "yes"
180 pim_macro_assert_tracking_desired_eval(ch
) ? "yes" : "no");
183 static void pim_show_assert_internal(struct pim_instance
*pim
, struct vty
*vty
)
185 struct pim_interface
*pim_ifp
;
186 struct pim_ifchannel
*ch
;
187 struct interface
*ifp
;
191 "ECA: Evaluate CouldAssert\n"
192 "ATD: AssertTrackingDesired\n"
193 "eATD: Evaluate AssertTrackingDesired\n\n");
196 "Interface Address Source Group CA eCA ATD eATD\n");
197 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
202 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
203 pim_show_assert_internal_helper(vty
, pim_ifp
, ch
);
204 } /* scan interface channels */
208 static void pim_show_assert_metric_helper(struct vty
*vty
,
209 struct pim_interface
*pim_ifp
,
210 struct pim_ifchannel
*ch
)
212 char ch_src_str
[INET_ADDRSTRLEN
];
213 char ch_grp_str
[INET_ADDRSTRLEN
];
214 char addr_str
[INET_ADDRSTRLEN
];
215 struct pim_assert_metric am
;
216 struct in_addr ifaddr
;
217 char buf
[PREFIX_STRLEN
];
219 ifaddr
= pim_ifp
->primary_address
;
221 am
= pim_macro_spt_assert_metric(&ch
->upstream
->rpf
,
222 pim_ifp
->primary_address
);
224 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
225 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
226 pim_inet4_dump("<addr?>", am
.ip_address
, addr_str
, sizeof(addr_str
));
228 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
230 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
231 ch_src_str
, ch_grp_str
, am
.rpt_bit_flag
? "yes" : "no",
232 am
.metric_preference
, am
.route_metric
, addr_str
);
235 static void pim_show_assert_metric(struct pim_instance
*pim
, struct vty
*vty
)
237 struct pim_interface
*pim_ifp
;
238 struct pim_ifchannel
*ch
;
239 struct interface
*ifp
;
242 "Interface Address Source Group RPT Pref Metric Address \n");
244 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
249 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
250 pim_show_assert_metric_helper(vty
, pim_ifp
, ch
);
251 } /* scan interface channels */
255 static void pim_show_assert_winner_metric_helper(struct vty
*vty
,
256 struct pim_interface
*pim_ifp
,
257 struct pim_ifchannel
*ch
)
259 char ch_src_str
[INET_ADDRSTRLEN
];
260 char ch_grp_str
[INET_ADDRSTRLEN
];
261 char addr_str
[INET_ADDRSTRLEN
];
262 struct pim_assert_metric
*am
;
263 struct in_addr ifaddr
;
266 char buf
[PREFIX_STRLEN
];
268 ifaddr
= pim_ifp
->primary_address
;
270 am
= &ch
->ifassert_winner_metric
;
272 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
273 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
274 pim_inet4_dump("<addr?>", am
->ip_address
, addr_str
, sizeof(addr_str
));
276 if (am
->metric_preference
== PIM_ASSERT_METRIC_PREFERENCE_MAX
)
277 snprintf(pref_str
, sizeof(pref_str
), "INFI");
279 snprintf(pref_str
, sizeof(pref_str
), "%4u",
280 am
->metric_preference
);
282 if (am
->route_metric
== PIM_ASSERT_ROUTE_METRIC_MAX
)
283 snprintf(metr_str
, sizeof(metr_str
), "INFI");
285 snprintf(metr_str
, sizeof(metr_str
), "%6u", am
->route_metric
);
287 vty_out(vty
, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
289 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)), ch_src_str
,
290 ch_grp_str
, am
->rpt_bit_flag
? "yes" : "no", pref_str
, metr_str
,
294 static void pim_show_assert_winner_metric(struct pim_instance
*pim
,
297 struct pim_interface
*pim_ifp
;
298 struct pim_ifchannel
*ch
;
299 struct interface
*ifp
;
302 "Interface Address Source Group RPT Pref Metric Address \n");
304 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
309 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
310 pim_show_assert_winner_metric_helper(vty
, pim_ifp
, ch
);
311 } /* scan interface channels */
315 static void json_object_pim_ifp_add(struct json_object
*json
,
316 struct interface
*ifp
)
318 struct pim_interface
*pim_ifp
;
319 char buf
[PREFIX_STRLEN
];
322 json_object_string_add(json
, "name", ifp
->name
);
323 json_object_string_add(json
, "state", if_is_up(ifp
) ? "up" : "down");
324 json_object_string_add(json
, "address",
325 inet_ntop(AF_INET
, &pim_ifp
->primary_address
,
327 json_object_int_add(json
, "index", ifp
->ifindex
);
329 if (if_is_multicast(ifp
))
330 json_object_boolean_true_add(json
, "flagMulticast");
332 if (if_is_broadcast(ifp
))
333 json_object_boolean_true_add(json
, "flagBroadcast");
335 if (ifp
->flags
& IFF_ALLMULTI
)
336 json_object_boolean_true_add(json
, "flagAllMulticast");
338 if (ifp
->flags
& IFF_PROMISC
)
339 json_object_boolean_true_add(json
, "flagPromiscuous");
341 if (PIM_IF_IS_DELETED(ifp
))
342 json_object_boolean_true_add(json
, "flagDeleted");
344 if (pim_if_lan_delay_enabled(ifp
))
345 json_object_boolean_true_add(json
, "lanDelayEnabled");
348 static void pim_show_membership_helper(struct vty
*vty
,
349 struct pim_interface
*pim_ifp
,
350 struct pim_ifchannel
*ch
,
351 struct json_object
*json
)
353 char ch_src_str
[INET_ADDRSTRLEN
];
354 char ch_grp_str
[INET_ADDRSTRLEN
];
355 json_object
*json_iface
= NULL
;
356 json_object
*json_row
= NULL
;
358 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
359 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
361 json_object_object_get_ex(json
, ch
->interface
->name
, &json_iface
);
363 json_iface
= json_object_new_object();
364 json_object_pim_ifp_add(json_iface
, ch
->interface
);
365 json_object_object_add(json
, ch
->interface
->name
, json_iface
);
368 json_row
= json_object_new_object();
369 json_object_string_add(json_row
, "source", ch_src_str
);
370 json_object_string_add(json_row
, "group", ch_grp_str
);
371 json_object_string_add(json_row
, "localMembership",
372 ch
->local_ifmembership
== PIM_IFMEMBERSHIP_NOINFO
375 json_object_object_add(json_iface
, ch_grp_str
, json_row
);
377 static void pim_show_membership(struct pim_instance
*pim
, struct vty
*vty
,
380 struct pim_interface
*pim_ifp
;
381 struct pim_ifchannel
*ch
;
382 struct interface
*ifp
;
384 json_object
*json
= NULL
;
385 json_object
*json_tmp
= NULL
;
387 json
= json_object_new_object();
389 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
394 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
395 pim_show_membership_helper(vty
, pim_ifp
, ch
, json
);
396 } /* scan interface channels */
400 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
401 json
, JSON_C_TO_STRING_PRETTY
));
404 "Interface Address Source Group Membership\n");
407 * Example of the json data we are traversing
413 * "address":"10.1.20.1",
415 * "flagMulticast":true,
416 * "flagBroadcast":true,
417 * "lanDelayEnabled":true,
420 * "group":"226.10.10.10",
421 * "localMembership":"INCLUDE"
427 /* foreach interface */
428 json_object_object_foreach(json
, key
, val
)
431 /* Find all of the keys where the val is an object. In
433 * above the only one is 226.10.10.10
435 json_object_object_foreach(val
, if_field_key
,
438 type
= json_object_get_type(if_field_val
);
440 if (type
== json_type_object
) {
441 vty_out(vty
, "%-16s ", key
);
443 json_object_object_get_ex(
444 val
, "address", &json_tmp
);
445 vty_out(vty
, "%-15s ",
446 json_object_get_string(
449 json_object_object_get_ex(if_field_val
,
452 vty_out(vty
, "%-15s ",
453 json_object_get_string(
457 vty_out(vty
, "%-15s ", if_field_key
);
459 json_object_object_get_ex(
460 if_field_val
, "localMembership",
462 vty_out(vty
, "%-10s\n",
463 json_object_get_string(
470 json_object_free(json
);
473 static void pim_print_ifp_flags(struct vty
*vty
, struct interface
*ifp
,
476 vty_out(vty
, "Flags\n");
477 vty_out(vty
, "-----\n");
478 vty_out(vty
, "All Multicast : %s\n",
479 (ifp
->flags
& IFF_ALLMULTI
) ? "yes" : "no");
480 vty_out(vty
, "Broadcast : %s\n",
481 if_is_broadcast(ifp
) ? "yes" : "no");
482 vty_out(vty
, "Deleted : %s\n",
483 PIM_IF_IS_DELETED(ifp
) ? "yes" : "no");
484 vty_out(vty
, "Interface Index : %d\n", ifp
->ifindex
);
485 vty_out(vty
, "Multicast : %s\n",
486 if_is_multicast(ifp
) ? "yes" : "no");
487 vty_out(vty
, "Multicast Loop : %d\n", mloop
);
488 vty_out(vty
, "Promiscuous : %s\n",
489 (ifp
->flags
& IFF_PROMISC
) ? "yes" : "no");
494 static void igmp_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
497 struct interface
*ifp
;
499 char buf
[PREFIX_STRLEN
];
500 char quer_buf
[PREFIX_STRLEN
];
501 json_object
*json
= NULL
;
502 json_object
*json_row
= NULL
;
504 now
= pim_time_monotonic_sec();
507 json
= json_object_new_object();
510 "Interface State Address V Querier QuerierIp Query Timer Uptime\n");
512 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
513 struct pim_interface
*pim_ifp
;
514 struct listnode
*sock_node
;
515 struct igmp_sock
*igmp
;
522 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
525 char query_hhmmss
[10];
527 pim_time_uptime(uptime
, sizeof(uptime
),
528 now
- igmp
->sock_creation
);
529 pim_time_timer_to_hhmmss(query_hhmmss
,
530 sizeof(query_hhmmss
),
531 igmp
->t_igmp_query_timer
);
534 json_row
= json_object_new_object();
535 json_object_pim_ifp_add(json_row
, ifp
);
536 json_object_string_add(json_row
, "upTime",
538 json_object_int_add(json_row
, "version",
539 pim_ifp
->igmp_version
);
541 if (igmp
->t_igmp_query_timer
) {
542 json_object_boolean_true_add(json_row
,
544 json_object_string_add(json_row
,
548 json_object_string_add(
549 json_row
, "querierIp",
550 inet_ntop(AF_INET
, &igmp
->querier_addr
,
551 quer_buf
, sizeof(quer_buf
)));
553 json_object_object_add(json
, ifp
->name
,
556 if (igmp
->mtrace_only
) {
557 json_object_boolean_true_add(
558 json_row
, "mtraceOnly");
562 "%-16s %5s %15s %d %7s %17pI4 %11s %8s\n",
565 ? (igmp
->mtrace_only
? "mtrc"
568 inet_ntop(AF_INET
, &igmp
->ifaddr
, buf
,
570 pim_ifp
->igmp_version
,
571 igmp
->t_igmp_query_timer
? "local"
573 &igmp
->querier_addr
, query_hhmmss
,
580 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
581 json
, JSON_C_TO_STRING_PRETTY
));
582 json_object_free(json
);
586 static void igmp_show_interfaces_single(struct pim_instance
*pim
,
587 struct vty
*vty
, const char *ifname
,
590 struct igmp_sock
*igmp
;
591 struct interface
*ifp
;
592 struct listnode
*sock_node
;
593 struct pim_interface
*pim_ifp
;
595 char quer_buf
[PREFIX_STRLEN
];
596 char query_hhmmss
[10];
597 char other_hhmmss
[10];
598 int found_ifname
= 0;
601 long gmi_msec
; /* Group Membership Interval */
604 long oqpi_msec
; /* Other Querier Present Interval */
609 json_object
*json
= NULL
;
610 json_object
*json_row
= NULL
;
613 json
= json_object_new_object();
615 now
= pim_time_monotonic_sec();
617 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
623 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
626 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
629 pim_time_uptime(uptime
, sizeof(uptime
),
630 now
- igmp
->sock_creation
);
631 pim_time_timer_to_hhmmss(query_hhmmss
,
632 sizeof(query_hhmmss
),
633 igmp
->t_igmp_query_timer
);
634 pim_time_timer_to_hhmmss(other_hhmmss
,
635 sizeof(other_hhmmss
),
636 igmp
->t_other_querier_timer
);
638 gmi_msec
= PIM_IGMP_GMI_MSEC(
639 igmp
->querier_robustness_variable
,
640 igmp
->querier_query_interval
,
641 pim_ifp
->igmp_query_max_response_time_dsec
);
644 pim_ifp
->igmp_default_query_interval
);
646 oqpi_msec
= PIM_IGMP_OQPI_MSEC(
647 igmp
->querier_robustness_variable
,
648 igmp
->querier_query_interval
,
649 pim_ifp
->igmp_query_max_response_time_dsec
);
651 lmqt_msec
= PIM_IGMP_LMQT_MSEC(
652 pim_ifp
->igmp_specific_query_max_response_time_dsec
,
653 pim_ifp
->igmp_last_member_query_count
);
657 igmp
->querier_robustness_variable
,
658 igmp
->querier_query_interval
,
659 pim_ifp
->igmp_query_max_response_time_dsec
)
662 qri_msec
= pim_ifp
->igmp_query_max_response_time_dsec
664 if (pim_ifp
->pim_sock_fd
>= 0)
665 mloop
= pim_socket_mcastloop_get(
666 pim_ifp
->pim_sock_fd
);
669 lmqc
= pim_ifp
->igmp_last_member_query_count
;
672 json_row
= json_object_new_object();
673 json_object_pim_ifp_add(json_row
, ifp
);
674 json_object_string_add(json_row
, "upTime",
676 json_object_string_add(json_row
, "querier",
677 igmp
->t_igmp_query_timer
680 json_object_string_add(
681 json_row
, "querierIp",
682 inet_ntop(AF_INET
, &igmp
->querier_addr
,
683 quer_buf
, sizeof(quer_buf
)));
684 json_object_int_add(json_row
, "queryStartCount",
685 igmp
->startup_query_count
);
686 json_object_string_add(json_row
,
689 json_object_string_add(json_row
,
692 json_object_int_add(json_row
, "version",
693 pim_ifp
->igmp_version
);
696 "timerGroupMembershipIntervalMsec",
698 json_object_int_add(json_row
,
699 "lastMemberQueryCount",
701 json_object_int_add(json_row
,
702 "timerLastMemberQueryMsec",
706 "timerOlderHostPresentIntervalMsec",
710 "timerOtherQuerierPresentIntervalMsec",
713 json_row
, "timerQueryInterval",
714 igmp
->querier_query_interval
);
717 "timerQueryResponseIntervalMsec",
720 json_row
, "timerRobustnessVariable",
721 igmp
->querier_robustness_variable
);
722 json_object_int_add(json_row
,
723 "timerStartupQueryInterval",
726 json_object_object_add(json
, ifp
->name
,
729 if (igmp
->mtrace_only
) {
730 json_object_boolean_true_add(
731 json_row
, "mtraceOnly");
734 vty_out(vty
, "Interface : %s\n", ifp
->name
);
735 vty_out(vty
, "State : %s\n",
736 if_is_up(ifp
) ? (igmp
->mtrace_only
?
740 vty_out(vty
, "Address : %pI4\n",
741 &pim_ifp
->primary_address
);
742 vty_out(vty
, "Uptime : %s\n", uptime
);
743 vty_out(vty
, "Version : %d\n",
744 pim_ifp
->igmp_version
);
748 vty_out(vty
, "Querier\n");
749 vty_out(vty
, "-------\n");
750 vty_out(vty
, "Querier : %s\n",
751 igmp
->t_igmp_query_timer
? "local"
753 vty_out(vty
, "QuerierIp : %pI4",
754 &igmp
->querier_addr
);
755 if (pim_ifp
->primary_address
.s_addr
756 == igmp
->querier_addr
.s_addr
)
757 vty_out(vty
, " (this router)\n");
761 vty_out(vty
, "Start Count : %d\n",
762 igmp
->startup_query_count
);
763 vty_out(vty
, "Query Timer : %s\n",
765 vty_out(vty
, "Other Timer : %s\n",
770 vty_out(vty
, "Timers\n");
771 vty_out(vty
, "------\n");
773 "Group Membership Interval : %lis\n",
776 "Last Member Query Count : %d\n",
779 "Last Member Query Time : %lis\n",
782 "Older Host Present Interval : %lis\n",
785 "Other Querier Present Interval : %lis\n",
788 "Query Interval : %ds\n",
789 igmp
->querier_query_interval
);
791 "Query Response Interval : %lis\n",
794 "Robustness Variable : %d\n",
795 igmp
->querier_robustness_variable
);
797 "Startup Query Interval : %ds\n",
802 pim_print_ifp_flags(vty
, ifp
, mloop
);
808 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
809 json
, JSON_C_TO_STRING_PRETTY
));
810 json_object_free(json
);
813 vty_out(vty
, "%% No such interface\n");
817 static void igmp_show_interface_join(struct pim_instance
*pim
, struct vty
*vty
,
820 struct interface
*ifp
;
822 json_object
*json
= NULL
;
823 json_object
*json_iface
= NULL
;
824 json_object
*json_grp
= NULL
;
825 json_object
*json_grp_arr
= NULL
;
827 now
= pim_time_monotonic_sec();
830 json
= json_object_new_object();
831 json_object_string_add(json
, "vrf",
832 vrf_id_to_name(pim
->vrf
->vrf_id
));
835 "Interface Address Source Group Socket Uptime \n");
838 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
839 struct pim_interface
*pim_ifp
;
840 struct listnode
*join_node
;
841 struct igmp_join
*ij
;
842 struct in_addr pri_addr
;
843 char pri_addr_str
[INET_ADDRSTRLEN
];
850 if (!pim_ifp
->igmp_join_list
)
853 pri_addr
= pim_find_primary_addr(ifp
);
854 pim_inet4_dump("<pri?>", pri_addr
, pri_addr_str
,
855 sizeof(pri_addr_str
));
857 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_join_list
, join_node
,
859 char group_str
[INET_ADDRSTRLEN
];
860 char source_str
[INET_ADDRSTRLEN
];
863 pim_time_uptime(uptime
, sizeof(uptime
),
864 now
- ij
->sock_creation
);
865 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
867 pim_inet4_dump("<src?>", ij
->source_addr
, source_str
,
871 json_object_object_get_ex(json
, ifp
->name
,
875 json_iface
= json_object_new_object();
876 json_object_string_add(
877 json_iface
, "name", ifp
->name
);
878 json_object_object_add(json
, ifp
->name
,
880 json_grp_arr
= json_object_new_array();
881 json_object_object_add(json_iface
,
886 json_grp
= json_object_new_object();
887 json_object_string_add(json_grp
, "source",
889 json_object_string_add(json_grp
, "group",
891 json_object_string_add(json_grp
, "primaryAddr",
893 json_object_int_add(json_grp
, "sockFd",
895 json_object_string_add(json_grp
, "upTime",
897 json_object_array_add(json_grp_arr
, json_grp
);
900 "%-16s %-15s %-15s %-15s %6d %8s\n",
901 ifp
->name
, pri_addr_str
, source_str
,
902 group_str
, ij
->sock_fd
, uptime
);
904 } /* for (pim_ifp->igmp_join_list) */
909 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
910 json
, JSON_C_TO_STRING_PRETTY
));
911 json_object_free(json
);
915 static void pim_show_interfaces_single(struct pim_instance
*pim
,
916 struct vty
*vty
, const char *ifname
,
919 struct in_addr ifaddr
;
920 struct interface
*ifp
;
921 struct listnode
*neighnode
;
922 struct pim_interface
*pim_ifp
;
923 struct pim_neighbor
*neigh
;
924 struct pim_upstream
*up
;
926 char dr_str
[INET_ADDRSTRLEN
];
929 char grp_str
[INET_ADDRSTRLEN
];
930 char hello_period
[10];
931 char hello_timer
[10];
932 char neigh_src_str
[INET_ADDRSTRLEN
];
933 char src_str
[INET_ADDRSTRLEN
];
934 char stat_uptime
[10];
937 int found_ifname
= 0;
939 char buf
[PREFIX_STRLEN
];
940 json_object
*json
= NULL
;
941 json_object
*json_row
= NULL
;
942 json_object
*json_pim_neighbor
= NULL
;
943 json_object
*json_pim_neighbors
= NULL
;
944 json_object
*json_group
= NULL
;
945 json_object
*json_group_source
= NULL
;
946 json_object
*json_fhr_sources
= NULL
;
947 struct pim_secondary_addr
*sec_addr
;
948 struct listnode
*sec_node
;
950 now
= pim_time_monotonic_sec();
953 json
= json_object_new_object();
955 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
961 if (mlag
== true && pim_ifp
->activeactive
== false)
964 if (strcmp(ifname
, "detail") && strcmp(ifname
, ifp
->name
))
968 ifaddr
= pim_ifp
->primary_address
;
969 pim_inet4_dump("<dr?>", pim_ifp
->pim_dr_addr
, dr_str
,
971 pim_time_uptime_begin(dr_uptime
, sizeof(dr_uptime
), now
,
972 pim_ifp
->pim_dr_election_last
);
973 pim_time_timer_to_hhmmss(hello_timer
, sizeof(hello_timer
),
974 pim_ifp
->t_pim_hello_timer
);
975 pim_time_mmss(hello_period
, sizeof(hello_period
),
976 pim_ifp
->pim_hello_period
);
977 pim_time_uptime(stat_uptime
, sizeof(stat_uptime
),
978 now
- pim_ifp
->pim_ifstat_start
);
979 if (pim_ifp
->pim_sock_fd
>= 0)
980 mloop
= pim_socket_mcastloop_get(pim_ifp
->pim_sock_fd
);
985 char pbuf
[PREFIX2STR_BUFFER
];
986 json_row
= json_object_new_object();
987 json_object_pim_ifp_add(json_row
, ifp
);
989 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
990 json_object_string_add(
991 json_row
, "useSource",
993 &pim_ifp
->update_source
,
996 if (pim_ifp
->sec_addr_list
) {
997 json_object
*sec_list
= NULL
;
999 sec_list
= json_object_new_array();
1000 for (ALL_LIST_ELEMENTS_RO(
1001 pim_ifp
->sec_addr_list
, sec_node
,
1003 json_object_array_add(
1005 json_object_new_string(
1011 json_object_object_add(json_row
,
1012 "secondaryAddressList",
1017 if (pim_ifp
->pim_neighbor_list
->count
) {
1018 json_pim_neighbors
= json_object_new_object();
1020 for (ALL_LIST_ELEMENTS_RO(
1021 pim_ifp
->pim_neighbor_list
,
1022 neighnode
, neigh
)) {
1024 json_object_new_object();
1025 pim_inet4_dump("<src?>",
1028 sizeof(neigh_src_str
));
1029 pim_time_uptime(uptime
, sizeof(uptime
),
1030 now
- neigh
->creation
);
1031 pim_time_timer_to_hhmmss(
1032 expire
, sizeof(expire
),
1033 neigh
->t_expire_timer
);
1035 json_object_string_add(
1036 json_pim_neighbor
, "address",
1038 json_object_string_add(
1039 json_pim_neighbor
, "upTime",
1041 json_object_string_add(
1042 json_pim_neighbor
, "holdtime",
1045 json_object_object_add(
1051 json_object_object_add(json_row
, "neighbors",
1052 json_pim_neighbors
);
1055 json_object_string_add(json_row
, "drAddress", dr_str
);
1056 json_object_int_add(json_row
, "drPriority",
1057 pim_ifp
->pim_dr_priority
);
1058 json_object_string_add(json_row
, "drUptime", dr_uptime
);
1059 json_object_int_add(json_row
, "drElections",
1060 pim_ifp
->pim_dr_election_count
);
1061 json_object_int_add(json_row
, "drChanges",
1062 pim_ifp
->pim_dr_election_changes
);
1065 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1066 if (ifp
!= up
->rpf
.source_nexthop
.interface
)
1069 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1072 if (!json_fhr_sources
)
1074 json_object_new_object();
1076 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1078 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1080 pim_time_uptime(uptime
, sizeof(uptime
),
1081 now
- up
->state_transition
);
1084 * Does this group live in json_fhr_sources?
1087 json_object_object_get_ex(json_fhr_sources
,
1088 grp_str
, &json_group
);
1091 json_group
= json_object_new_object();
1092 json_object_object_add(json_fhr_sources
,
1097 json_group_source
= json_object_new_object();
1098 json_object_string_add(json_group_source
,
1100 json_object_string_add(json_group_source
,
1102 json_object_string_add(json_group_source
,
1104 json_object_object_add(json_group
, src_str
,
1108 if (json_fhr_sources
) {
1109 json_object_object_add(json_row
,
1114 json_object_int_add(json_row
, "helloPeriod",
1115 pim_ifp
->pim_hello_period
);
1116 json_object_int_add(json_row
, "holdTime",
1117 PIM_IF_DEFAULT_HOLDTIME(pim_ifp
));
1118 json_object_string_add(json_row
, "helloTimer",
1120 json_object_string_add(json_row
, "helloStatStart",
1122 json_object_int_add(json_row
, "helloReceived",
1123 pim_ifp
->pim_ifstat_hello_recv
);
1124 json_object_int_add(json_row
, "helloReceivedFailed",
1125 pim_ifp
->pim_ifstat_hello_recvfail
);
1126 json_object_int_add(json_row
, "helloSend",
1127 pim_ifp
->pim_ifstat_hello_sent
);
1128 json_object_int_add(json_row
, "hellosendFailed",
1129 pim_ifp
->pim_ifstat_hello_sendfail
);
1130 json_object_int_add(json_row
, "helloGenerationId",
1131 pim_ifp
->pim_generation_id
);
1132 json_object_int_add(json_row
, "flagMulticastLoop",
1135 json_object_int_add(
1136 json_row
, "effectivePropagationDelay",
1137 pim_if_effective_propagation_delay_msec(ifp
));
1138 json_object_int_add(
1139 json_row
, "effectiveOverrideInterval",
1140 pim_if_effective_override_interval_msec(ifp
));
1141 json_object_int_add(
1142 json_row
, "joinPruneOverrideInterval",
1143 pim_if_jp_override_interval_msec(ifp
));
1145 json_object_int_add(
1146 json_row
, "propagationDelay",
1147 pim_ifp
->pim_propagation_delay_msec
);
1148 json_object_int_add(
1149 json_row
, "propagationDelayHighest",
1150 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1151 json_object_int_add(
1152 json_row
, "overrideInterval",
1153 pim_ifp
->pim_override_interval_msec
);
1154 json_object_int_add(
1155 json_row
, "overrideIntervalHighest",
1156 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1157 if (pim_ifp
->bsm_enable
)
1158 json_object_boolean_true_add(json_row
,
1160 if (pim_ifp
->ucast_bsm_accept
)
1161 json_object_boolean_true_add(json_row
,
1163 json_object_object_add(json
, ifp
->name
, json_row
);
1166 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1167 vty_out(vty
, "State : %s\n",
1168 if_is_up(ifp
) ? "up" : "down");
1169 if (pim_ifp
->update_source
.s_addr
!= INADDR_ANY
) {
1170 vty_out(vty
, "Use Source : %pI4\n",
1171 &pim_ifp
->update_source
);
1173 if (pim_ifp
->sec_addr_list
) {
1174 vty_out(vty
, "Address : %pI4 (primary)\n",
1176 for (ALL_LIST_ELEMENTS_RO(
1177 pim_ifp
->sec_addr_list
, sec_node
,
1179 vty_out(vty
, " %pFX\n",
1182 vty_out(vty
, "Address : %pI4\n",
1190 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
1191 neighnode
, neigh
)) {
1194 vty_out(vty
, "PIM Neighbors\n");
1195 vty_out(vty
, "-------------\n");
1199 pim_inet4_dump("<src?>", neigh
->source_addr
,
1201 sizeof(neigh_src_str
));
1202 pim_time_uptime(uptime
, sizeof(uptime
),
1203 now
- neigh
->creation
);
1204 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1205 neigh
->t_expire_timer
);
1207 "%-15s : up for %s, holdtime expires in %s\n",
1208 neigh_src_str
, uptime
, expire
);
1211 if (!print_header
) {
1216 vty_out(vty
, "Designated Router\n");
1217 vty_out(vty
, "-----------------\n");
1218 vty_out(vty
, "Address : %s\n", dr_str
);
1219 vty_out(vty
, "Priority : %u(%d)\n",
1220 pim_ifp
->pim_dr_priority
,
1221 pim_ifp
->pim_dr_num_nondrpri_neighbors
);
1222 vty_out(vty
, "Uptime : %s\n", dr_uptime
);
1223 vty_out(vty
, "Elections : %d\n",
1224 pim_ifp
->pim_dr_election_count
);
1225 vty_out(vty
, "Changes : %d\n",
1226 pim_ifp
->pim_dr_election_changes
);
1232 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
1233 if (!up
->rpf
.source_nexthop
.interface
)
1236 if (strcmp(ifp
->name
,
1237 up
->rpf
.source_nexthop
1242 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
))
1247 "FHR - First Hop Router\n");
1249 "----------------------\n");
1253 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
,
1255 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
,
1257 pim_time_uptime(uptime
, sizeof(uptime
),
1258 now
- up
->state_transition
);
1260 "%s : %s is a source, uptime is %s\n",
1261 grp_str
, src_str
, uptime
);
1264 if (!print_header
) {
1269 vty_out(vty
, "Hellos\n");
1270 vty_out(vty
, "------\n");
1271 vty_out(vty
, "Period : %d\n",
1272 pim_ifp
->pim_hello_period
);
1273 vty_out(vty
, "HoldTime : %d\n",
1274 PIM_IF_DEFAULT_HOLDTIME(pim_ifp
));
1275 vty_out(vty
, "Timer : %s\n", hello_timer
);
1276 vty_out(vty
, "StatStart : %s\n", stat_uptime
);
1277 vty_out(vty
, "Receive : %d\n",
1278 pim_ifp
->pim_ifstat_hello_recv
);
1279 vty_out(vty
, "Receive Failed : %d\n",
1280 pim_ifp
->pim_ifstat_hello_recvfail
);
1281 vty_out(vty
, "Send : %d\n",
1282 pim_ifp
->pim_ifstat_hello_sent
);
1283 vty_out(vty
, "Send Failed : %d\n",
1284 pim_ifp
->pim_ifstat_hello_sendfail
);
1285 vty_out(vty
, "Generation ID : %08x\n",
1286 pim_ifp
->pim_generation_id
);
1290 pim_print_ifp_flags(vty
, ifp
, mloop
);
1292 vty_out(vty
, "Join Prune Interval\n");
1293 vty_out(vty
, "-------------------\n");
1294 vty_out(vty
, "LAN Delay : %s\n",
1295 pim_if_lan_delay_enabled(ifp
) ? "yes" : "no");
1296 vty_out(vty
, "Effective Propagation Delay : %d msec\n",
1297 pim_if_effective_propagation_delay_msec(ifp
));
1298 vty_out(vty
, "Effective Override Interval : %d msec\n",
1299 pim_if_effective_override_interval_msec(ifp
));
1300 vty_out(vty
, "Join Prune Override Interval : %d msec\n",
1301 pim_if_jp_override_interval_msec(ifp
));
1305 vty_out(vty
, "LAN Prune Delay\n");
1306 vty_out(vty
, "---------------\n");
1307 vty_out(vty
, "Propagation Delay : %d msec\n",
1308 pim_ifp
->pim_propagation_delay_msec
);
1309 vty_out(vty
, "Propagation Delay (Highest) : %d msec\n",
1310 pim_ifp
->pim_neighbors_highest_propagation_delay_msec
);
1311 vty_out(vty
, "Override Interval : %d msec\n",
1312 pim_ifp
->pim_override_interval_msec
);
1313 vty_out(vty
, "Override Interval (Highest) : %d msec\n",
1314 pim_ifp
->pim_neighbors_highest_override_interval_msec
);
1318 vty_out(vty
, "BSM Status\n");
1319 vty_out(vty
, "----------\n");
1320 vty_out(vty
, "Bsm Enabled : %s\n",
1321 pim_ifp
->bsm_enable
? "yes" : "no");
1322 vty_out(vty
, "Unicast Bsm Enabled : %s\n",
1323 pim_ifp
->ucast_bsm_accept
? "yes" : "no");
1330 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1331 json
, JSON_C_TO_STRING_PRETTY
));
1332 json_object_free(json
);
1335 vty_out(vty
, "%% No such interface\n");
1339 static void igmp_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
1340 const char *ifname
, bool uj
)
1342 struct interface
*ifp
;
1343 struct igmp_stats rx_stats
;
1345 igmp_stats_init(&rx_stats
);
1347 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1348 struct pim_interface
*pim_ifp
;
1349 struct listnode
*sock_node
;
1350 struct igmp_sock
*igmp
;
1352 pim_ifp
= ifp
->info
;
1357 if (ifname
&& strcmp(ifname
, ifp
->name
))
1360 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
1362 igmp_stats_add(&rx_stats
, &igmp
->rx_stats
);
1366 json_object
*json
= NULL
;
1367 json_object
*json_row
= NULL
;
1369 json
= json_object_new_object();
1370 json_row
= json_object_new_object();
1372 json_object_string_add(json_row
, "name", ifname
? ifname
:
1374 json_object_int_add(json_row
, "queryV1", rx_stats
.query_v1
);
1375 json_object_int_add(json_row
, "queryV2", rx_stats
.query_v2
);
1376 json_object_int_add(json_row
, "queryV3", rx_stats
.query_v3
);
1377 json_object_int_add(json_row
, "leaveV3", rx_stats
.leave_v2
);
1378 json_object_int_add(json_row
, "reportV1", rx_stats
.report_v1
);
1379 json_object_int_add(json_row
, "reportV2", rx_stats
.report_v2
);
1380 json_object_int_add(json_row
, "reportV3", rx_stats
.report_v3
);
1381 json_object_int_add(json_row
, "mtraceResponse",
1382 rx_stats
.mtrace_rsp
);
1383 json_object_int_add(json_row
, "mtraceRequest",
1384 rx_stats
.mtrace_req
);
1385 json_object_int_add(json_row
, "unsupported",
1386 rx_stats
.unsupported
);
1387 json_object_object_add(json
, ifname
? ifname
: "global",
1389 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1390 json
, JSON_C_TO_STRING_PRETTY
));
1391 json_object_free(json
);
1393 vty_out(vty
, "IGMP RX statistics\n");
1394 vty_out(vty
, "Interface : %s\n",
1395 ifname
? ifname
: "global");
1396 vty_out(vty
, "V1 query : %u\n", rx_stats
.query_v1
);
1397 vty_out(vty
, "V2 query : %u\n", rx_stats
.query_v2
);
1398 vty_out(vty
, "V3 query : %u\n", rx_stats
.query_v3
);
1399 vty_out(vty
, "V2 leave : %u\n", rx_stats
.leave_v2
);
1400 vty_out(vty
, "V1 report : %u\n", rx_stats
.report_v1
);
1401 vty_out(vty
, "V2 report : %u\n", rx_stats
.report_v2
);
1402 vty_out(vty
, "V3 report : %u\n", rx_stats
.report_v3
);
1403 vty_out(vty
, "mtrace response : %u\n", rx_stats
.mtrace_rsp
);
1404 vty_out(vty
, "mtrace request : %u\n", rx_stats
.mtrace_req
);
1405 vty_out(vty
, "unsupported : %u\n", rx_stats
.unsupported
);
1409 static void pim_show_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
1412 struct interface
*ifp
;
1413 struct pim_interface
*pim_ifp
;
1414 struct pim_upstream
*up
;
1417 int pim_ifchannels
= 0;
1418 char buf
[PREFIX_STRLEN
];
1419 json_object
*json
= NULL
;
1420 json_object
*json_row
= NULL
;
1421 json_object
*json_tmp
;
1423 json
= json_object_new_object();
1425 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1426 pim_ifp
= ifp
->info
;
1431 if (mlag
== true && pim_ifp
->activeactive
== false)
1434 pim_nbrs
= pim_ifp
->pim_neighbor_list
->count
;
1435 pim_ifchannels
= pim_if_ifchannel_count(pim_ifp
);
1438 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
)
1439 if (ifp
== up
->rpf
.source_nexthop
.interface
)
1440 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
1443 json_row
= json_object_new_object();
1444 json_object_pim_ifp_add(json_row
, ifp
);
1445 json_object_int_add(json_row
, "pimNeighbors", pim_nbrs
);
1446 json_object_int_add(json_row
, "pimIfChannels", pim_ifchannels
);
1447 json_object_int_add(json_row
, "firstHopRouterCount", fhr
);
1448 json_object_string_add(json_row
, "pimDesignatedRouter",
1450 &pim_ifp
->pim_dr_addr
, buf
,
1453 if (pim_ifp
->pim_dr_addr
.s_addr
1454 == pim_ifp
->primary_address
.s_addr
)
1455 json_object_boolean_true_add(
1456 json_row
, "pimDesignatedRouterLocal");
1458 json_object_object_add(json
, ifp
->name
, json_row
);
1462 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1463 json
, JSON_C_TO_STRING_PRETTY
));
1466 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1468 json_object_object_foreach(json
, key
, val
)
1470 vty_out(vty
, "%-16s ", key
);
1472 json_object_object_get_ex(val
, "state", &json_tmp
);
1473 vty_out(vty
, "%5s ", json_object_get_string(json_tmp
));
1475 json_object_object_get_ex(val
, "address", &json_tmp
);
1476 vty_out(vty
, "%15s ",
1477 json_object_get_string(json_tmp
));
1479 json_object_object_get_ex(val
, "pimNeighbors",
1481 vty_out(vty
, "%8d ", json_object_get_int(json_tmp
));
1483 if (json_object_object_get_ex(
1484 val
, "pimDesignatedRouterLocal",
1486 vty_out(vty
, "%15s ", "local");
1488 json_object_object_get_ex(
1489 val
, "pimDesignatedRouter", &json_tmp
);
1490 vty_out(vty
, "%15s ",
1491 json_object_get_string(json_tmp
));
1494 json_object_object_get_ex(val
, "firstHopRouter",
1496 vty_out(vty
, "%3d ", json_object_get_int(json_tmp
));
1498 json_object_object_get_ex(val
, "pimIfChannels",
1500 vty_out(vty
, "%9d\n", json_object_get_int(json_tmp
));
1504 json_object_free(json
);
1507 static void pim_show_interface_traffic(struct pim_instance
*pim
,
1508 struct vty
*vty
, bool uj
)
1510 struct interface
*ifp
= NULL
;
1511 struct pim_interface
*pim_ifp
= NULL
;
1512 json_object
*json
= NULL
;
1513 json_object
*json_row
= NULL
;
1516 json
= json_object_new_object();
1519 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1520 "Interface", " HELLO", " JOIN",
1521 " PRUNE", " REGISTER", "REGISTER-STOP",
1523 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1524 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1525 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1528 "---------------------------------------------------------------------------------------------------------------\n");
1531 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1532 pim_ifp
= ifp
->info
;
1537 if (pim_ifp
->pim_sock_fd
< 0)
1540 json_row
= json_object_new_object();
1541 json_object_pim_ifp_add(json_row
, ifp
);
1542 json_object_int_add(json_row
, "helloRx",
1543 pim_ifp
->pim_ifstat_hello_recv
);
1544 json_object_int_add(json_row
, "helloTx",
1545 pim_ifp
->pim_ifstat_hello_sent
);
1546 json_object_int_add(json_row
, "joinRx",
1547 pim_ifp
->pim_ifstat_join_recv
);
1548 json_object_int_add(json_row
, "joinTx",
1549 pim_ifp
->pim_ifstat_join_send
);
1550 json_object_int_add(json_row
, "pruneTx",
1551 pim_ifp
->pim_ifstat_prune_send
);
1552 json_object_int_add(json_row
, "pruneRx",
1553 pim_ifp
->pim_ifstat_prune_recv
);
1554 json_object_int_add(json_row
, "registerRx",
1555 pim_ifp
->pim_ifstat_reg_recv
);
1556 json_object_int_add(json_row
, "registerTx",
1557 pim_ifp
->pim_ifstat_reg_recv
);
1558 json_object_int_add(json_row
, "registerStopRx",
1559 pim_ifp
->pim_ifstat_reg_stop_recv
);
1560 json_object_int_add(json_row
, "registerStopTx",
1561 pim_ifp
->pim_ifstat_reg_stop_send
);
1562 json_object_int_add(json_row
, "assertRx",
1563 pim_ifp
->pim_ifstat_assert_recv
);
1564 json_object_int_add(json_row
, "assertTx",
1565 pim_ifp
->pim_ifstat_assert_send
);
1566 json_object_int_add(json_row
, "bsmRx",
1567 pim_ifp
->pim_ifstat_bsm_rx
);
1568 json_object_int_add(json_row
, "bsmTx",
1569 pim_ifp
->pim_ifstat_bsm_tx
);
1570 json_object_object_add(json
, ifp
->name
, json_row
);
1573 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1574 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1575 pim_ifp
->pim_ifstat_hello_sent
,
1576 pim_ifp
->pim_ifstat_join_recv
,
1577 pim_ifp
->pim_ifstat_join_send
,
1578 pim_ifp
->pim_ifstat_prune_recv
,
1579 pim_ifp
->pim_ifstat_prune_send
,
1580 pim_ifp
->pim_ifstat_reg_recv
,
1581 pim_ifp
->pim_ifstat_reg_send
,
1582 pim_ifp
->pim_ifstat_reg_stop_recv
,
1583 pim_ifp
->pim_ifstat_reg_stop_send
,
1584 pim_ifp
->pim_ifstat_assert_recv
,
1585 pim_ifp
->pim_ifstat_assert_send
,
1586 pim_ifp
->pim_ifstat_bsm_rx
,
1587 pim_ifp
->pim_ifstat_bsm_tx
);
1591 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1592 json
, JSON_C_TO_STRING_PRETTY
));
1593 json_object_free(json
);
1597 static void pim_show_interface_traffic_single(struct pim_instance
*pim
,
1599 const char *ifname
, bool uj
)
1601 struct interface
*ifp
= NULL
;
1602 struct pim_interface
*pim_ifp
= NULL
;
1603 json_object
*json
= NULL
;
1604 json_object
*json_row
= NULL
;
1605 uint8_t found_ifname
= 0;
1608 json
= json_object_new_object();
1611 vty_out(vty
, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1612 "Interface", " HELLO", " JOIN", " PRUNE",
1613 " REGISTER", " REGISTER-STOP", " ASSERT",
1615 vty_out(vty
, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1616 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1617 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1619 "-------------------------------------------------------------------------------------------------------------------------------\n");
1622 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1623 if (strcmp(ifname
, ifp
->name
))
1626 pim_ifp
= ifp
->info
;
1631 if (pim_ifp
->pim_sock_fd
< 0)
1636 json_row
= json_object_new_object();
1637 json_object_pim_ifp_add(json_row
, ifp
);
1638 json_object_int_add(json_row
, "helloRx",
1639 pim_ifp
->pim_ifstat_hello_recv
);
1640 json_object_int_add(json_row
, "helloTx",
1641 pim_ifp
->pim_ifstat_hello_sent
);
1642 json_object_int_add(json_row
, "joinRx",
1643 pim_ifp
->pim_ifstat_join_recv
);
1644 json_object_int_add(json_row
, "joinTx",
1645 pim_ifp
->pim_ifstat_join_send
);
1646 json_object_int_add(json_row
, "registerRx",
1647 pim_ifp
->pim_ifstat_reg_recv
);
1648 json_object_int_add(json_row
, "registerTx",
1649 pim_ifp
->pim_ifstat_reg_recv
);
1650 json_object_int_add(json_row
, "registerStopRx",
1651 pim_ifp
->pim_ifstat_reg_stop_recv
);
1652 json_object_int_add(json_row
, "registerStopTx",
1653 pim_ifp
->pim_ifstat_reg_stop_send
);
1654 json_object_int_add(json_row
, "assertRx",
1655 pim_ifp
->pim_ifstat_assert_recv
);
1656 json_object_int_add(json_row
, "assertTx",
1657 pim_ifp
->pim_ifstat_assert_send
);
1658 json_object_int_add(json_row
, "bsmRx",
1659 pim_ifp
->pim_ifstat_bsm_rx
);
1660 json_object_int_add(json_row
, "bsmTx",
1661 pim_ifp
->pim_ifstat_bsm_tx
);
1663 json_object_object_add(json
, ifp
->name
, json_row
);
1666 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64
"/%-7" PRIu64
"\n",
1667 ifp
->name
, pim_ifp
->pim_ifstat_hello_recv
,
1668 pim_ifp
->pim_ifstat_hello_sent
,
1669 pim_ifp
->pim_ifstat_join_recv
,
1670 pim_ifp
->pim_ifstat_join_send
,
1671 pim_ifp
->pim_ifstat_prune_recv
,
1672 pim_ifp
->pim_ifstat_prune_send
,
1673 pim_ifp
->pim_ifstat_reg_recv
,
1674 pim_ifp
->pim_ifstat_reg_send
,
1675 pim_ifp
->pim_ifstat_reg_stop_recv
,
1676 pim_ifp
->pim_ifstat_reg_stop_send
,
1677 pim_ifp
->pim_ifstat_assert_recv
,
1678 pim_ifp
->pim_ifstat_assert_send
,
1679 pim_ifp
->pim_ifstat_bsm_rx
,
1680 pim_ifp
->pim_ifstat_bsm_tx
);
1684 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1685 json
, JSON_C_TO_STRING_PRETTY
));
1686 json_object_free(json
);
1689 vty_out(vty
, "%% No such interface\n");
1693 static void pim_show_join_helper(struct vty
*vty
, struct pim_interface
*pim_ifp
,
1694 struct pim_ifchannel
*ch
, json_object
*json
,
1695 time_t now
, bool uj
)
1697 char ch_src_str
[INET_ADDRSTRLEN
];
1698 char ch_grp_str
[INET_ADDRSTRLEN
];
1699 json_object
*json_iface
= NULL
;
1700 json_object
*json_row
= NULL
;
1701 json_object
*json_grp
= NULL
;
1702 struct in_addr ifaddr
;
1706 char buf
[PREFIX_STRLEN
];
1708 ifaddr
= pim_ifp
->primary_address
;
1710 pim_inet4_dump("<ch_src?>", ch
->sg
.src
, ch_src_str
, sizeof(ch_src_str
));
1711 pim_inet4_dump("<ch_grp?>", ch
->sg
.grp
, ch_grp_str
, sizeof(ch_grp_str
));
1713 pim_time_uptime_begin(uptime
, sizeof(uptime
), now
, ch
->ifjoin_creation
);
1714 pim_time_timer_to_mmss(expire
, sizeof(expire
),
1715 ch
->t_ifjoin_expiry_timer
);
1716 pim_time_timer_to_mmss(prune
, sizeof(prune
),
1717 ch
->t_ifjoin_prune_pending_timer
);
1720 json_object_object_get_ex(json
, ch
->interface
->name
,
1724 json_iface
= json_object_new_object();
1725 json_object_pim_ifp_add(json_iface
, ch
->interface
);
1726 json_object_object_add(json
, ch
->interface
->name
,
1730 json_row
= json_object_new_object();
1731 json_object_string_add(json_row
, "source", ch_src_str
);
1732 json_object_string_add(json_row
, "group", ch_grp_str
);
1733 json_object_string_add(json_row
, "upTime", uptime
);
1734 json_object_string_add(json_row
, "expire", expire
);
1735 json_object_string_add(json_row
, "prune", prune
);
1736 json_object_string_add(
1737 json_row
, "channelJoinName",
1738 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
));
1739 if (PIM_IF_FLAG_TEST_S_G_RPT(ch
->flags
))
1740 json_object_int_add(json_row
, "SGRpt", 1);
1741 if (PIM_IF_FLAG_TEST_PROTO_PIM(ch
->flags
))
1742 json_object_int_add(json_row
, "protocolPim", 1);
1743 if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch
->flags
))
1744 json_object_int_add(json_row
, "protocolIgmp", 1);
1745 json_object_object_get_ex(json_iface
, ch_grp_str
, &json_grp
);
1747 json_grp
= json_object_new_object();
1748 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1749 json_object_object_add(json_iface
, ch_grp_str
,
1752 json_object_object_add(json_grp
, ch_src_str
, json_row
);
1754 vty_out(vty
, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1755 ch
->interface
->name
,
1756 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
1757 ch_src_str
, ch_grp_str
,
1758 pim_ifchannel_ifjoin_name(ch
->ifjoin_state
, ch
->flags
),
1759 uptime
, expire
, prune
);
1763 static void pim_show_join(struct pim_instance
*pim
, struct vty
*vty
,
1764 struct prefix_sg
*sg
, bool uj
)
1766 struct pim_interface
*pim_ifp
;
1767 struct pim_ifchannel
*ch
;
1768 struct interface
*ifp
;
1770 json_object
*json
= NULL
;
1772 now
= pim_time_monotonic_sec();
1775 json
= json_object_new_object();
1778 "Interface Address Source Group State Uptime Expire Prune\n");
1780 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1781 pim_ifp
= ifp
->info
;
1785 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
1786 if (sg
->grp
.s_addr
!= INADDR_ANY
1787 && sg
->grp
.s_addr
!= ch
->sg
.grp
.s_addr
)
1789 if (sg
->src
.s_addr
!= INADDR_ANY
1790 && sg
->src
.s_addr
!= ch
->sg
.src
.s_addr
)
1792 pim_show_join_helper(vty
, pim_ifp
, ch
, json
, now
, uj
);
1793 } /* scan interface channels */
1797 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1798 json
, JSON_C_TO_STRING_PRETTY
));
1799 json_object_free(json
);
1803 static void pim_show_neighbors_single(struct pim_instance
*pim
, struct vty
*vty
,
1804 const char *neighbor
, bool uj
)
1806 struct listnode
*neighnode
;
1807 struct interface
*ifp
;
1808 struct pim_interface
*pim_ifp
;
1809 struct pim_neighbor
*neigh
;
1811 int found_neighbor
= 0;
1812 int option_address_list
;
1813 int option_dr_priority
;
1814 int option_generation_id
;
1815 int option_holdtime
;
1816 int option_lan_prune_delay
;
1820 char neigh_src_str
[INET_ADDRSTRLEN
];
1822 json_object
*json
= NULL
;
1823 json_object
*json_ifp
= NULL
;
1824 json_object
*json_row
= NULL
;
1826 now
= pim_time_monotonic_sec();
1829 json
= json_object_new_object();
1831 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
1832 pim_ifp
= ifp
->info
;
1837 if (pim_ifp
->pim_sock_fd
< 0)
1840 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
1842 pim_inet4_dump("<src?>", neigh
->source_addr
,
1843 neigh_src_str
, sizeof(neigh_src_str
));
1846 * The user can specify either the interface name or the
1848 * If this pim_ifp matches neither then skip.
1850 if (strcmp(neighbor
, "detail")
1851 && strcmp(neighbor
, ifp
->name
)
1852 && strcmp(neighbor
, neigh_src_str
))
1856 pim_time_uptime(uptime
, sizeof(uptime
),
1857 now
- neigh
->creation
);
1858 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
1859 neigh
->t_expire_timer
);
1861 option_address_list
= 0;
1862 option_dr_priority
= 0;
1863 option_generation_id
= 0;
1864 option_holdtime
= 0;
1865 option_lan_prune_delay
= 0;
1868 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1869 PIM_OPTION_MASK_ADDRESS_LIST
))
1870 option_address_list
= 1;
1872 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1873 PIM_OPTION_MASK_DR_PRIORITY
))
1874 option_dr_priority
= 1;
1876 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1877 PIM_OPTION_MASK_GENERATION_ID
))
1878 option_generation_id
= 1;
1880 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1881 PIM_OPTION_MASK_HOLDTIME
))
1882 option_holdtime
= 1;
1884 if (PIM_OPTION_IS_SET(neigh
->hello_options
,
1885 PIM_OPTION_MASK_LAN_PRUNE_DELAY
))
1886 option_lan_prune_delay
= 1;
1888 if (PIM_OPTION_IS_SET(
1889 neigh
->hello_options
,
1890 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION
))
1895 /* Does this ifp live in json? If not create
1897 json_object_object_get_ex(json
, ifp
->name
,
1901 json_ifp
= json_object_new_object();
1902 json_object_pim_ifp_add(json_ifp
, ifp
);
1903 json_object_object_add(json
, ifp
->name
,
1907 json_row
= json_object_new_object();
1908 json_object_string_add(json_row
, "interface",
1910 json_object_string_add(json_row
, "address",
1912 json_object_string_add(json_row
, "upTime",
1914 json_object_string_add(json_row
, "holdtime",
1916 json_object_int_add(json_row
, "drPriority",
1917 neigh
->dr_priority
);
1918 json_object_int_add(json_row
, "generationId",
1919 neigh
->generation_id
);
1921 if (option_address_list
)
1922 json_object_boolean_true_add(
1924 "helloOptionAddressList");
1926 if (option_dr_priority
)
1927 json_object_boolean_true_add(
1929 "helloOptionDrPriority");
1931 if (option_generation_id
)
1932 json_object_boolean_true_add(
1934 "helloOptionGenerationId");
1936 if (option_holdtime
)
1937 json_object_boolean_true_add(
1939 "helloOptionHoldtime");
1941 if (option_lan_prune_delay
)
1942 json_object_boolean_true_add(
1944 "helloOptionLanPruneDelay");
1947 json_object_boolean_true_add(
1948 json_row
, "helloOptionTBit");
1950 json_object_object_add(json_ifp
, neigh_src_str
,
1954 vty_out(vty
, "Interface : %s\n", ifp
->name
);
1955 vty_out(vty
, "Neighbor : %s\n", neigh_src_str
);
1963 " DR Priority : %d\n",
1964 neigh
->dr_priority
);
1966 " Generation ID : %08x\n",
1967 neigh
->generation_id
);
1969 " Override Interval (msec) : %d\n",
1970 neigh
->override_interval_msec
);
1972 " Propagation Delay (msec) : %d\n",
1973 neigh
->propagation_delay_msec
);
1975 " Hello Option - Address List : %s\n",
1976 option_address_list
? "yes" : "no");
1978 " Hello Option - DR Priority : %s\n",
1979 option_dr_priority
? "yes" : "no");
1981 " Hello Option - Generation ID : %s\n",
1982 option_generation_id
? "yes" : "no");
1984 " Hello Option - Holdtime : %s\n",
1985 option_holdtime
? "yes" : "no");
1987 " Hello Option - LAN Prune Delay : %s\n",
1988 option_lan_prune_delay
? "yes" : "no");
1990 " Hello Option - T-bit : %s\n",
1991 option_t_bit
? "yes" : "no");
1992 bfd_sess_show(vty
, json_ifp
,
1993 neigh
->bfd_session
);
2000 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2001 json
, JSON_C_TO_STRING_PRETTY
));
2002 json_object_free(json
);
2005 if (!found_neighbor
)
2007 "%% No such interface or neighbor\n");
2012 static void pim_show_state(struct pim_instance
*pim
, struct vty
*vty
,
2013 const char *src_or_group
, const char *group
, bool uj
)
2015 struct channel_oil
*c_oil
;
2016 json_object
*json
= NULL
;
2017 json_object
*json_group
= NULL
;
2018 json_object
*json_ifp_in
= NULL
;
2019 json_object
*json_ifp_out
= NULL
;
2020 json_object
*json_source
= NULL
;
2023 now
= pim_time_monotonic_sec();
2026 json
= json_object_new_object();
2029 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
2031 "\nActive Source Group RPT IIF OIL\n");
2034 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
2035 char grp_str
[INET_ADDRSTRLEN
];
2036 char src_str
[INET_ADDRSTRLEN
];
2037 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
2038 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
2040 struct interface
*ifp_in
;
2045 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil
->up
->flags
)) ||
2046 c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
2051 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
2053 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
2055 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
2058 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
2060 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
2063 if (strcmp(src_or_group
, src_str
)
2064 && strcmp(src_or_group
, grp_str
))
2067 if (group
&& strcmp(group
, grp_str
))
2073 /* Find the group, create it if it doesn't exist */
2074 json_object_object_get_ex(json
, grp_str
, &json_group
);
2077 json_group
= json_object_new_object();
2078 json_object_object_add(json
, grp_str
,
2082 /* Find the source nested under the group, create it if
2083 * it doesn't exist */
2084 json_object_object_get_ex(json_group
, src_str
,
2088 json_source
= json_object_new_object();
2089 json_object_object_add(json_group
, src_str
,
2093 /* Find the inbound interface nested under the source,
2094 * create it if it doesn't exist */
2095 json_object_object_get_ex(json_source
, in_ifname
,
2099 json_ifp_in
= json_object_new_object();
2100 json_object_object_add(json_source
, in_ifname
,
2102 json_object_int_add(json_source
, "Installed",
2105 json_object_boolean_true_add(
2106 json_source
, "isRpt");
2108 json_object_boolean_false_add(
2109 json_source
, "isRpt");
2110 json_object_int_add(json_source
, "RefCount",
2111 c_oil
->oil_ref_count
);
2112 json_object_int_add(json_source
, "OilListSize",
2114 json_object_int_add(
2115 json_source
, "OilRescan",
2116 c_oil
->oil_inherited_rescan
);
2117 json_object_int_add(json_source
, "LastUsed",
2118 c_oil
->cc
.lastused
);
2119 json_object_int_add(json_source
, "PacketCount",
2121 json_object_int_add(json_source
, "ByteCount",
2123 json_object_int_add(json_source
,
2125 c_oil
->cc
.wrong_if
);
2128 vty_out(vty
, "%-6d %-15s %-15s %-3s %-16s ",
2129 c_oil
->installed
, src_str
, grp_str
,
2130 isRpt
? "y" : "n", in_ifname
);
2133 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
2135 struct interface
*ifp_out
;
2136 char oif_uptime
[10];
2139 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
2143 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
2145 oif_uptime
, sizeof(oif_uptime
),
2146 now
- c_oil
->oif_creation
[oif_vif_index
]);
2149 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
2151 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
2154 json_ifp_out
= json_object_new_object();
2155 json_object_string_add(json_ifp_out
, "source",
2157 json_object_string_add(json_ifp_out
, "group",
2159 json_object_string_add(json_ifp_out
,
2162 json_object_string_add(json_ifp_out
,
2163 "outboundInterface",
2165 json_object_int_add(json_ifp_out
, "installed",
2168 json_object_object_add(json_ifp_in
, out_ifname
,
2173 vty_out(vty
, "%s(%c%c%c%c%c)",
2175 (c_oil
->oif_flags
[oif_vif_index
]
2176 & PIM_OIF_FLAG_PROTO_IGMP
)
2179 (c_oil
->oif_flags
[oif_vif_index
]
2180 & PIM_OIF_FLAG_PROTO_PIM
)
2183 (c_oil
->oif_flags
[oif_vif_index
]
2184 & PIM_OIF_FLAG_PROTO_VXLAN
)
2187 (c_oil
->oif_flags
[oif_vif_index
]
2188 & PIM_OIF_FLAG_PROTO_STAR
)
2191 (c_oil
->oif_flags
[oif_vif_index
]
2192 & PIM_OIF_FLAG_MUTE
)
2196 vty_out(vty
, ", %s(%c%c%c%c%c)",
2198 (c_oil
->oif_flags
[oif_vif_index
]
2199 & PIM_OIF_FLAG_PROTO_IGMP
)
2202 (c_oil
->oif_flags
[oif_vif_index
]
2203 & PIM_OIF_FLAG_PROTO_PIM
)
2206 (c_oil
->oif_flags
[oif_vif_index
]
2207 & PIM_OIF_FLAG_PROTO_VXLAN
)
2210 (c_oil
->oif_flags
[oif_vif_index
]
2211 & PIM_OIF_FLAG_PROTO_STAR
)
2214 (c_oil
->oif_flags
[oif_vif_index
]
2215 & PIM_OIF_FLAG_MUTE
)
2227 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2228 json
, JSON_C_TO_STRING_PRETTY
));
2229 json_object_free(json
);
2235 static void pim_show_neighbors(struct pim_instance
*pim
, struct vty
*vty
,
2238 struct listnode
*neighnode
;
2239 struct interface
*ifp
;
2240 struct pim_interface
*pim_ifp
;
2241 struct pim_neighbor
*neigh
;
2245 char neigh_src_str
[INET_ADDRSTRLEN
];
2246 json_object
*json
= NULL
;
2247 json_object
*json_ifp_rows
= NULL
;
2248 json_object
*json_row
= NULL
;
2250 now
= pim_time_monotonic_sec();
2253 json
= json_object_new_object();
2256 "Interface Neighbor Uptime Holdtime DR Pri\n");
2259 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2260 pim_ifp
= ifp
->info
;
2265 if (pim_ifp
->pim_sock_fd
< 0)
2269 json_ifp_rows
= json_object_new_object();
2271 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2273 pim_inet4_dump("<src?>", neigh
->source_addr
,
2274 neigh_src_str
, sizeof(neigh_src_str
));
2275 pim_time_uptime(uptime
, sizeof(uptime
),
2276 now
- neigh
->creation
);
2277 pim_time_timer_to_hhmmss(expire
, sizeof(expire
),
2278 neigh
->t_expire_timer
);
2281 json_row
= json_object_new_object();
2282 json_object_string_add(json_row
, "interface",
2284 json_object_string_add(json_row
, "neighbor",
2286 json_object_string_add(json_row
, "upTime",
2288 json_object_string_add(json_row
, "holdTime",
2290 json_object_int_add(json_row
, "holdTimeMax",
2292 json_object_int_add(json_row
, "drPriority",
2293 neigh
->dr_priority
);
2294 json_object_object_add(json_ifp_rows
,
2295 neigh_src_str
, json_row
);
2298 vty_out(vty
, "%-16s %15s %8s %8s %6d\n",
2299 ifp
->name
, neigh_src_str
, uptime
,
2300 expire
, neigh
->dr_priority
);
2305 json_object_object_add(json
, ifp
->name
, json_ifp_rows
);
2306 json_ifp_rows
= NULL
;
2311 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2312 json
, JSON_C_TO_STRING_PRETTY
));
2313 json_object_free(json
);
2317 static void pim_show_neighbors_secondary(struct pim_instance
*pim
,
2320 struct interface
*ifp
;
2323 "Interface Address Neighbor Secondary \n");
2325 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2326 struct pim_interface
*pim_ifp
;
2327 struct in_addr ifaddr
;
2328 struct listnode
*neighnode
;
2329 struct pim_neighbor
*neigh
;
2330 char buf
[PREFIX_STRLEN
];
2332 pim_ifp
= ifp
->info
;
2337 if (pim_ifp
->pim_sock_fd
< 0)
2340 ifaddr
= pim_ifp
->primary_address
;
2342 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
, neighnode
,
2344 char neigh_src_str
[INET_ADDRSTRLEN
];
2345 struct listnode
*prefix_node
;
2348 if (!neigh
->prefix_list
)
2351 pim_inet4_dump("<src?>", neigh
->source_addr
,
2352 neigh_src_str
, sizeof(neigh_src_str
));
2354 for (ALL_LIST_ELEMENTS_RO(neigh
->prefix_list
,
2356 vty_out(vty
, "%-16s %-15s %-15s %-15pFX\n",
2358 inet_ntop(AF_INET
, &ifaddr
,
2365 static void json_object_pim_upstream_add(json_object
*json
,
2366 struct pim_upstream
*up
)
2368 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED
)
2369 json_object_boolean_true_add(json
, "drJoinDesired");
2371 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED
)
2372 json_object_boolean_true_add(json
, "drJoinDesiredUpdated");
2374 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
)
2375 json_object_boolean_true_add(json
, "firstHopRouter");
2377 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_IGMP
)
2378 json_object_boolean_true_add(json
, "sourceIgmp");
2380 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_PIM
)
2381 json_object_boolean_true_add(json
, "sourcePim");
2383 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_STREAM
)
2384 json_object_boolean_true_add(json
, "sourceStream");
2386 /* XXX: need to print ths flag in the plain text display as well */
2387 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_MSDP
)
2388 json_object_boolean_true_add(json
, "sourceMsdp");
2390 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE
)
2391 json_object_boolean_true_add(json
, "sendSGRptPrune");
2393 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_LHR
)
2394 json_object_boolean_true_add(json
, "lastHopRouter");
2396 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY
)
2397 json_object_boolean_true_add(json
, "disableKATExpiry");
2399 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_STATIC_IIF
)
2400 json_object_boolean_true_add(json
, "staticIncomingInterface");
2402 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL
)
2403 json_object_boolean_true_add(json
,
2404 "allowIncomingInterfaceinOil");
2406 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA
)
2407 json_object_boolean_true_add(json
, "noPimRegistrationData");
2409 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG
)
2410 json_object_boolean_true_add(json
, "forcePimRegistration");
2412 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG
)
2413 json_object_boolean_true_add(json
, "sourceVxlanOrigination");
2415 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM
)
2416 json_object_boolean_true_add(json
, "sourceVxlanTermination");
2418 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN
)
2419 json_object_boolean_true_add(json
, "mlagVxlan");
2421 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF
)
2422 json_object_boolean_true_add(json
,
2423 "mlagNonDesignatedForwarder");
2427 pim_upstream_state2brief_str(enum pim_upstream_state join_state
,
2428 char *state_str
, size_t state_str_len
)
2430 switch (join_state
) {
2431 case PIM_UPSTREAM_NOTJOINED
:
2432 strlcpy(state_str
, "NotJ", state_str_len
);
2434 case PIM_UPSTREAM_JOINED
:
2435 strlcpy(state_str
, "J", state_str_len
);
2438 strlcpy(state_str
, "Unk", state_str_len
);
2443 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state
,
2444 char *state_str
, size_t state_str_len
)
2446 switch (reg_state
) {
2447 case PIM_REG_NOINFO
:
2448 strlcpy(state_str
, "RegNI", state_str_len
);
2451 strlcpy(state_str
, "RegJ", state_str_len
);
2453 case PIM_REG_JOIN_PENDING
:
2455 strlcpy(state_str
, "RegP", state_str_len
);
2458 strlcpy(state_str
, "Unk", state_str_len
);
2463 static void pim_show_upstream(struct pim_instance
*pim
, struct vty
*vty
,
2464 struct prefix_sg
*sg
, bool uj
)
2466 struct pim_upstream
*up
;
2468 json_object
*json
= NULL
;
2469 json_object
*json_group
= NULL
;
2470 json_object
*json_row
= NULL
;
2472 now
= pim_time_monotonic_sec();
2475 json
= json_object_new_object();
2478 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2480 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2481 char src_str
[INET_ADDRSTRLEN
];
2482 char grp_str
[INET_ADDRSTRLEN
];
2484 char join_timer
[10];
2487 char msdp_reg_timer
[10];
2488 char state_str
[PIM_REG_STATE_STR_LEN
];
2490 if (sg
->grp
.s_addr
!= INADDR_ANY
2491 && sg
->grp
.s_addr
!= up
->sg
.grp
.s_addr
)
2493 if (sg
->src
.s_addr
!= INADDR_ANY
2494 && sg
->src
.s_addr
!= up
->sg
.src
.s_addr
)
2497 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2498 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2499 pim_time_uptime(uptime
, sizeof(uptime
),
2500 now
- up
->state_transition
);
2501 pim_time_timer_to_hhmmss(join_timer
, sizeof(join_timer
),
2505 * If the upstream is not dummy and it has a J/P timer for the
2506 * neighbor display that
2508 if (!up
->t_join_timer
&& up
->rpf
.source_nexthop
.interface
) {
2509 struct pim_neighbor
*nbr
;
2511 nbr
= pim_neighbor_find(
2512 up
->rpf
.source_nexthop
.interface
,
2513 up
->rpf
.rpf_addr
.u
.prefix4
);
2515 pim_time_timer_to_hhmmss(join_timer
,
2520 pim_time_timer_to_hhmmss(rs_timer
, sizeof(rs_timer
),
2522 pim_time_timer_to_hhmmss(ka_timer
, sizeof(ka_timer
),
2524 pim_time_timer_to_hhmmss(msdp_reg_timer
, sizeof(msdp_reg_timer
),
2525 up
->t_msdp_reg_timer
);
2527 pim_upstream_state2brief_str(up
->join_state
, state_str
, sizeof(state_str
));
2528 if (up
->reg_state
!= PIM_REG_NOINFO
) {
2529 char tmp_str
[PIM_REG_STATE_STR_LEN
];
2530 char tmp
[sizeof(state_str
) + 1];
2532 snprintf(tmp
, sizeof(tmp
), ",%s",
2533 pim_reg_state2brief_str(up
->reg_state
, tmp_str
,
2535 strlcat(state_str
, tmp
, sizeof(state_str
));
2539 json_object_object_get_ex(json
, grp_str
, &json_group
);
2542 json_group
= json_object_new_object();
2543 json_object_object_add(json
, grp_str
,
2547 json_row
= json_object_new_object();
2548 json_object_pim_upstream_add(json_row
, up
);
2549 json_object_string_add(
2550 json_row
, "inboundInterface",
2551 up
->rpf
.source_nexthop
.interface
2552 ? up
->rpf
.source_nexthop
.interface
->name
2556 * The RPF address we use is slightly different
2557 * based upon what we are looking up.
2558 * If we have a S, list that unless
2559 * we are the FHR, else we just put
2560 * the RP as the rpfAddress
2562 if (up
->flags
& PIM_UPSTREAM_FLAG_MASK_FHR
2563 || up
->sg
.src
.s_addr
== INADDR_ANY
) {
2564 char rpf
[PREFIX_STRLEN
];
2565 struct pim_rpf
*rpg
;
2567 rpg
= RP(pim
, up
->sg
.grp
);
2568 pim_inet4_dump("<rpf?>",
2569 rpg
->rpf_addr
.u
.prefix4
, rpf
,
2571 json_object_string_add(json_row
, "rpfAddress",
2574 json_object_string_add(json_row
, "rpfAddress",
2578 json_object_string_add(json_row
, "source", src_str
);
2579 json_object_string_add(json_row
, "group", grp_str
);
2580 json_object_string_add(json_row
, "state", state_str
);
2581 json_object_string_add(
2582 json_row
, "joinState",
2583 pim_upstream_state2str(up
->join_state
));
2584 json_object_string_add(
2585 json_row
, "regState",
2586 pim_reg_state2str(up
->reg_state
, state_str
, sizeof(state_str
)));
2587 json_object_string_add(json_row
, "upTime", uptime
);
2588 json_object_string_add(json_row
, "joinTimer",
2590 json_object_string_add(json_row
, "resetTimer",
2592 json_object_string_add(json_row
, "keepaliveTimer",
2594 json_object_string_add(json_row
, "msdpRegTimer",
2596 json_object_int_add(json_row
, "refCount",
2598 json_object_int_add(json_row
, "sptBit", up
->sptbit
);
2599 json_object_object_add(json_group
, src_str
, json_row
);
2602 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2603 up
->rpf
.source_nexthop
.interface
2604 ? up
->rpf
.source_nexthop
.interface
->name
2606 src_str
, grp_str
, state_str
, uptime
, join_timer
,
2607 rs_timer
, ka_timer
, up
->ref_count
);
2612 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2613 json
, JSON_C_TO_STRING_PRETTY
));
2614 json_object_free(json
);
2618 static void pim_show_channel_helper(struct pim_instance
*pim
,
2620 struct pim_interface
*pim_ifp
,
2621 struct pim_ifchannel
*ch
,
2622 json_object
*json
, bool uj
)
2624 struct pim_upstream
*up
= ch
->upstream
;
2625 json_object
*json_group
= NULL
;
2626 char src_str
[INET_ADDRSTRLEN
];
2627 char grp_str
[INET_ADDRSTRLEN
];
2628 json_object
*json_row
= NULL
;
2630 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2631 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2634 json_object_object_get_ex(json
, grp_str
, &json_group
);
2637 json_group
= json_object_new_object();
2638 json_object_object_add(json
, grp_str
, json_group
);
2641 json_row
= json_object_new_object();
2642 json_object_pim_upstream_add(json_row
, up
);
2643 json_object_string_add(json_row
, "interface",
2644 ch
->interface
->name
);
2645 json_object_string_add(json_row
, "source", src_str
);
2646 json_object_string_add(json_row
, "group", grp_str
);
2648 if (pim_macro_ch_lost_assert(ch
))
2649 json_object_boolean_true_add(json_row
, "lostAssert");
2651 if (pim_macro_chisin_joins(ch
))
2652 json_object_boolean_true_add(json_row
, "joins");
2654 if (pim_macro_chisin_pim_include(ch
))
2655 json_object_boolean_true_add(json_row
, "pimInclude");
2657 if (pim_upstream_evaluate_join_desired(pim
, up
))
2658 json_object_boolean_true_add(json_row
,
2659 "evaluateJoinDesired");
2661 json_object_object_add(json_group
, src_str
, json_row
);
2664 vty_out(vty
, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2665 ch
->interface
->name
, src_str
, grp_str
,
2666 pim_macro_ch_lost_assert(ch
) ? "yes" : "no",
2667 pim_macro_chisin_joins(ch
) ? "yes" : "no",
2668 pim_macro_chisin_pim_include(ch
) ? "yes" : "no",
2669 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up
->flags
)
2672 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2677 static void pim_show_channel(struct pim_instance
*pim
, struct vty
*vty
,
2680 struct pim_interface
*pim_ifp
;
2681 struct pim_ifchannel
*ch
;
2682 struct interface
*ifp
;
2684 json_object
*json
= NULL
;
2687 json
= json_object_new_object();
2690 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2692 /* scan per-interface (S,G) state */
2693 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
2694 pim_ifp
= ifp
->info
;
2699 RB_FOREACH (ch
, pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
) {
2700 /* scan all interfaces */
2701 pim_show_channel_helper(pim
, vty
, pim_ifp
, ch
,
2707 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2708 json
, JSON_C_TO_STRING_PRETTY
));
2709 json_object_free(json
);
2713 static void pim_show_join_desired_helper(struct pim_instance
*pim
,
2715 struct pim_upstream
*up
,
2716 json_object
*json
, bool uj
)
2718 json_object
*json_group
= NULL
;
2719 char src_str
[INET_ADDRSTRLEN
];
2720 char grp_str
[INET_ADDRSTRLEN
];
2721 json_object
*json_row
= NULL
;
2723 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2724 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2727 json_object_object_get_ex(json
, grp_str
, &json_group
);
2730 json_group
= json_object_new_object();
2731 json_object_object_add(json
, grp_str
, json_group
);
2734 json_row
= json_object_new_object();
2735 json_object_pim_upstream_add(json_row
, up
);
2736 json_object_string_add(json_row
, "source", src_str
);
2737 json_object_string_add(json_row
, "group", grp_str
);
2739 if (pim_upstream_evaluate_join_desired(pim
, up
))
2740 json_object_boolean_true_add(json_row
,
2741 "evaluateJoinDesired");
2743 json_object_object_add(json_group
, src_str
, json_row
);
2746 vty_out(vty
, "%-15s %-15s %-6s\n",
2748 pim_upstream_evaluate_join_desired(pim
, up
) ? "yes"
2753 static void pim_show_join_desired(struct pim_instance
*pim
, struct vty
*vty
,
2756 struct pim_upstream
*up
;
2758 json_object
*json
= NULL
;
2761 json
= json_object_new_object();
2764 "Source Group EvalJD\n");
2766 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2767 /* scan all interfaces */
2768 pim_show_join_desired_helper(pim
, vty
, up
,
2773 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2774 json
, JSON_C_TO_STRING_PRETTY
));
2775 json_object_free(json
);
2779 static void pim_show_upstream_rpf(struct pim_instance
*pim
, struct vty
*vty
,
2782 struct pim_upstream
*up
;
2783 json_object
*json
= NULL
;
2784 json_object
*json_group
= NULL
;
2785 json_object
*json_row
= NULL
;
2788 json
= json_object_new_object();
2791 "Source Group RpfIface RibNextHop RpfAddress \n");
2793 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2794 char src_str
[INET_ADDRSTRLEN
];
2795 char grp_str
[INET_ADDRSTRLEN
];
2796 char rpf_nexthop_str
[PREFIX_STRLEN
];
2797 char rpf_addr_str
[PREFIX_STRLEN
];
2798 struct pim_rpf
*rpf
;
2799 const char *rpf_ifname
;
2803 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2804 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2805 pim_addr_dump("<nexthop?>",
2806 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2807 rpf_nexthop_str
, sizeof(rpf_nexthop_str
));
2808 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2809 sizeof(rpf_addr_str
));
2811 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2814 json_object_object_get_ex(json
, grp_str
, &json_group
);
2817 json_group
= json_object_new_object();
2818 json_object_object_add(json
, grp_str
,
2822 json_row
= json_object_new_object();
2823 json_object_pim_upstream_add(json_row
, up
);
2824 json_object_string_add(json_row
, "source", src_str
);
2825 json_object_string_add(json_row
, "group", grp_str
);
2826 json_object_string_add(json_row
, "rpfInterface",
2828 json_object_string_add(json_row
, "ribNexthop",
2830 json_object_string_add(json_row
, "rpfAddress",
2832 json_object_object_add(json_group
, src_str
, json_row
);
2834 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s\n", src_str
,
2835 grp_str
, rpf_ifname
, rpf_nexthop_str
,
2841 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2842 json
, JSON_C_TO_STRING_PRETTY
));
2843 json_object_free(json
);
2847 static void show_rpf_refresh_stats(struct vty
*vty
, struct pim_instance
*pim
,
2848 time_t now
, json_object
*json
)
2850 char refresh_uptime
[10];
2852 pim_time_uptime_begin(refresh_uptime
, sizeof(refresh_uptime
), now
,
2853 pim
->rpf_cache_refresh_last
);
2856 json_object_int_add(json
, "rpfCacheRefreshDelayMsecs",
2857 router
->rpf_cache_refresh_delay_msec
);
2858 json_object_int_add(
2859 json
, "rpfCacheRefreshTimer",
2860 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
));
2861 json_object_int_add(json
, "rpfCacheRefreshRequests",
2862 pim
->rpf_cache_refresh_requests
);
2863 json_object_int_add(json
, "rpfCacheRefreshEvents",
2864 pim
->rpf_cache_refresh_events
);
2865 json_object_string_add(json
, "rpfCacheRefreshLast",
2867 json_object_int_add(json
, "nexthopLookups",
2868 pim
->nexthop_lookups
);
2869 json_object_int_add(json
, "nexthopLookupsAvoided",
2870 pim
->nexthop_lookups_avoided
);
2873 "RPF Cache Refresh Delay: %ld msecs\n"
2874 "RPF Cache Refresh Timer: %ld msecs\n"
2875 "RPF Cache Refresh Requests: %lld\n"
2876 "RPF Cache Refresh Events: %lld\n"
2877 "RPF Cache Refresh Last: %s\n"
2878 "Nexthop Lookups: %lld\n"
2879 "Nexthop Lookups Avoided: %lld\n",
2880 router
->rpf_cache_refresh_delay_msec
,
2881 pim_time_timer_remain_msec(pim
->rpf_cache_refresher
),
2882 (long long)pim
->rpf_cache_refresh_requests
,
2883 (long long)pim
->rpf_cache_refresh_events
,
2884 refresh_uptime
, (long long)pim
->nexthop_lookups
,
2885 (long long)pim
->nexthop_lookups_avoided
);
2889 static void show_scan_oil_stats(struct pim_instance
*pim
, struct vty
*vty
,
2892 char uptime_scan_oil
[10];
2893 char uptime_mroute_add
[10];
2894 char uptime_mroute_del
[10];
2896 pim_time_uptime_begin(uptime_scan_oil
, sizeof(uptime_scan_oil
), now
,
2897 pim
->scan_oil_last
);
2898 pim_time_uptime_begin(uptime_mroute_add
, sizeof(uptime_mroute_add
), now
,
2899 pim
->mroute_add_last
);
2900 pim_time_uptime_begin(uptime_mroute_del
, sizeof(uptime_mroute_del
), now
,
2901 pim
->mroute_del_last
);
2904 "Scan OIL - Last: %s Events: %lld\n"
2905 "MFC Add - Last: %s Events: %lld\n"
2906 "MFC Del - Last: %s Events: %lld\n",
2907 uptime_scan_oil
, (long long)pim
->scan_oil_events
,
2908 uptime_mroute_add
, (long long)pim
->mroute_add_events
,
2909 uptime_mroute_del
, (long long)pim
->mroute_del_events
);
2912 static void pim_show_rpf(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
2914 struct pim_upstream
*up
;
2915 time_t now
= pim_time_monotonic_sec();
2916 json_object
*json
= NULL
;
2917 json_object
*json_group
= NULL
;
2918 json_object
*json_row
= NULL
;
2921 json
= json_object_new_object();
2922 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2924 show_rpf_refresh_stats(vty
, pim
, now
, json
);
2927 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2930 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
2931 char src_str
[INET_ADDRSTRLEN
];
2932 char grp_str
[INET_ADDRSTRLEN
];
2933 char rpf_addr_str
[PREFIX_STRLEN
];
2934 char rib_nexthop_str
[PREFIX_STRLEN
];
2935 const char *rpf_ifname
;
2936 struct pim_rpf
*rpf
= &up
->rpf
;
2938 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
2939 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
2940 pim_addr_dump("<rpf?>", &rpf
->rpf_addr
, rpf_addr_str
,
2941 sizeof(rpf_addr_str
));
2942 pim_addr_dump("<nexthop?>",
2943 &rpf
->source_nexthop
.mrib_nexthop_addr
,
2944 rib_nexthop_str
, sizeof(rib_nexthop_str
));
2946 rpf_ifname
= rpf
->source_nexthop
.interface
? rpf
->source_nexthop
.interface
->name
: "<ifname?>";
2949 json_object_object_get_ex(json
, grp_str
, &json_group
);
2952 json_group
= json_object_new_object();
2953 json_object_object_add(json
, grp_str
,
2957 json_row
= json_object_new_object();
2958 json_object_string_add(json_row
, "source", src_str
);
2959 json_object_string_add(json_row
, "group", grp_str
);
2960 json_object_string_add(json_row
, "rpfInterface",
2962 json_object_string_add(json_row
, "rpfAddress",
2964 json_object_string_add(json_row
, "ribNexthop",
2966 json_object_int_add(
2967 json_row
, "routeMetric",
2968 rpf
->source_nexthop
.mrib_route_metric
);
2969 json_object_int_add(
2970 json_row
, "routePreference",
2971 rpf
->source_nexthop
.mrib_metric_preference
);
2972 json_object_object_add(json_group
, src_str
, json_row
);
2975 vty_out(vty
, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2976 src_str
, grp_str
, rpf_ifname
, rpf_addr_str
,
2978 rpf
->source_nexthop
.mrib_route_metric
,
2979 rpf
->source_nexthop
.mrib_metric_preference
);
2984 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2985 json
, JSON_C_TO_STRING_PRETTY
));
2986 json_object_free(json
);
2990 struct pnc_cache_walk_data
{
2992 struct pim_instance
*pim
;
2995 static int pim_print_pnc_cache_walkcb(struct hash_bucket
*bucket
, void *arg
)
2997 struct pim_nexthop_cache
*pnc
= bucket
->data
;
2998 struct pnc_cache_walk_data
*cwd
= arg
;
2999 struct vty
*vty
= cwd
->vty
;
3000 struct pim_instance
*pim
= cwd
->pim
;
3001 struct nexthop
*nh_node
= NULL
;
3002 ifindex_t first_ifindex
;
3003 struct interface
*ifp
= NULL
;
3004 char buf
[PREFIX_STRLEN
];
3006 for (nh_node
= pnc
->nexthop
; nh_node
; nh_node
= nh_node
->next
) {
3007 first_ifindex
= nh_node
->ifindex
;
3008 ifp
= if_lookup_by_index(first_ifindex
, pim
->vrf
->vrf_id
);
3010 vty_out(vty
, "%-15s ", inet_ntop(AF_INET
,
3011 &pnc
->rpf
.rpf_addr
.u
.prefix4
,
3013 vty_out(vty
, "%-16s ", ifp
? ifp
->name
: "NULL");
3014 vty_out(vty
, "%pI4 ", &nh_node
->gate
.ipv4
);
3020 static void pim_show_nexthop(struct pim_instance
*pim
, struct vty
*vty
)
3022 struct pnc_cache_walk_data cwd
;
3026 vty_out(vty
, "Number of registered addresses: %lu\n",
3027 pim
->rpf_hash
->count
);
3028 vty_out(vty
, "Address Interface Nexthop\n");
3029 vty_out(vty
, "---------------------------------------------\n");
3031 hash_walk(pim
->rpf_hash
, pim_print_pnc_cache_walkcb
, &cwd
);
3034 /* Display the bsm database details */
3035 static void pim_show_bsm_db(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3039 struct bsm_frag
*bsfrag
;
3040 json_object
*json
= NULL
;
3041 json_object
*json_group
= NULL
;
3042 json_object
*json_row
= NULL
;
3044 count
= bsm_frags_count(pim
->global_scope
.bsm_frags
);
3047 json
= json_object_new_object();
3048 json_object_int_add(json
, "Number of the fragments", count
);
3050 vty_out(vty
, "Scope Zone: Global\n");
3051 vty_out(vty
, "Number of the fragments: %d\n", count
);
3055 frr_each (bsm_frags
, pim
->global_scope
.bsm_frags
, bsfrag
) {
3056 char grp_str
[PREFIX_STRLEN
];
3057 char rp_str
[INET_ADDRSTRLEN
];
3058 char bsr_str
[INET_ADDRSTRLEN
];
3059 struct bsmmsg_grpinfo
*group
;
3060 struct bsmmsg_rpinfo
*rpaddr
;
3062 struct bsm_hdr
*hdr
;
3063 uint32_t offset
= 0;
3066 uint32_t frag_rp_cnt
= 0;
3071 /* skip pim header */
3072 buf
+= PIM_MSG_HEADER_LEN
;
3073 len
-= PIM_MSG_HEADER_LEN
;
3075 hdr
= (struct bsm_hdr
*)buf
;
3077 /* BSM starts with bsr header */
3078 buf
+= sizeof(struct bsm_hdr
);
3079 len
-= sizeof(struct bsm_hdr
);
3081 pim_inet4_dump("<BSR Address?>", hdr
->bsr_addr
.addr
, bsr_str
,
3086 json_object_string_add(json
, "BSR address", bsr_str
);
3087 json_object_int_add(json
, "BSR priority",
3089 json_object_int_add(json
, "Hashmask Length",
3091 json_object_int_add(json
, "Fragment Tag",
3092 ntohs(hdr
->frag_tag
));
3094 vty_out(vty
, "BSM Fragment : %d\n", fragment
);
3095 vty_out(vty
, "------------------\n");
3096 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3097 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3098 vty_out(vty
, "%-15s %-15d %-15d %-15d\n", bsr_str
,
3099 hdr
->bsr_prio
, hdr
->hm_len
,
3100 ntohs(hdr
->frag_tag
));
3105 while (offset
< len
) {
3106 group
= (struct bsmmsg_grpinfo
*)buf
;
3108 if (group
->group
.family
== PIM_MSG_ADDRESS_FAMILY_IPV4
)
3109 grp
.family
= AF_INET
;
3111 grp
.prefixlen
= group
->group
.mask
;
3112 grp
.u
.prefix4
.s_addr
= group
->group
.addr
.s_addr
;
3114 prefix2str(&grp
, grp_str
, sizeof(grp_str
));
3116 buf
+= sizeof(struct bsmmsg_grpinfo
);
3117 offset
+= sizeof(struct bsmmsg_grpinfo
);
3120 json_object_object_get_ex(json
, grp_str
,
3123 json_group
= json_object_new_object();
3124 json_object_int_add(json_group
,
3127 json_object_int_add(
3128 json_group
, "Fragment Rp count",
3129 group
->frag_rp_count
);
3130 json_object_object_add(json
, grp_str
,
3134 vty_out(vty
, "Group : %s\n", grp_str
);
3135 vty_out(vty
, "-------------------\n");
3136 vty_out(vty
, "Rp Count:%d\n", group
->rp_count
);
3137 vty_out(vty
, "Fragment Rp Count : %d\n",
3138 group
->frag_rp_count
);
3141 frag_rp_cnt
= group
->frag_rp_count
;
3148 "RpAddress HoldTime Priority\n");
3150 while (frag_rp_cnt
--) {
3151 rpaddr
= (struct bsmmsg_rpinfo
*)buf
;
3153 buf
+= sizeof(struct bsmmsg_rpinfo
);
3154 offset
+= sizeof(struct bsmmsg_rpinfo
);
3156 pim_inet4_dump("<Rp addr?>",
3157 rpaddr
->rpaddr
.addr
, rp_str
,
3161 json_row
= json_object_new_object();
3162 json_object_string_add(
3163 json_row
, "Rp Address", rp_str
);
3164 json_object_int_add(
3165 json_row
, "Rp HoldTime",
3166 ntohs(rpaddr
->rp_holdtime
));
3167 json_object_int_add(json_row
,
3170 json_object_object_add(
3171 json_group
, rp_str
, json_row
);
3173 vty_out(vty
, "%-15s %-12d %d\n", rp_str
,
3174 ntohs(rpaddr
->rp_holdtime
),
3185 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3186 json
, JSON_C_TO_STRING_PRETTY
));
3187 json_object_free(json
);
3191 /*Display the group-rp mappings */
3192 static void pim_show_group_rp_mappings_info(struct pim_instance
*pim
,
3193 struct vty
*vty
, bool uj
)
3195 struct bsgrp_node
*bsgrp
;
3196 struct bsm_rpinfo
*bsm_rp
;
3197 struct route_node
*rn
;
3198 char bsr_str
[INET_ADDRSTRLEN
];
3199 json_object
*json
= NULL
;
3200 json_object
*json_group
= NULL
;
3201 json_object
*json_row
= NULL
;
3203 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
)
3204 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3207 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
, bsr_str
,
3211 json
= json_object_new_object();
3212 json_object_string_add(json
, "BSR Address", bsr_str
);
3214 vty_out(vty
, "BSR Address %s\n", bsr_str
);
3217 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
3218 rn
= route_next(rn
)) {
3219 bsgrp
= (struct bsgrp_node
*)rn
->info
;
3224 char grp_str
[PREFIX_STRLEN
];
3226 prefix2str(&bsgrp
->group
, grp_str
, sizeof(grp_str
));
3229 json_object_object_get_ex(json
, grp_str
, &json_group
);
3231 json_group
= json_object_new_object();
3232 json_object_object_add(json
, grp_str
,
3236 vty_out(vty
, "Group Address %pFX\n", &bsgrp
->group
);
3237 vty_out(vty
, "--------------------------\n");
3238 vty_out(vty
, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3239 "priority", "Holdtime", "Hash");
3241 vty_out(vty
, "(ACTIVE)\n");
3244 frr_each (bsm_rpinfos
, bsgrp
->bsrp_list
, bsm_rp
) {
3245 char rp_str
[INET_ADDRSTRLEN
];
3247 pim_inet4_dump("<Rp Address?>", bsm_rp
->rp_address
,
3248 rp_str
, sizeof(rp_str
));
3251 json_row
= json_object_new_object();
3252 json_object_string_add(json_row
, "Rp Address",
3254 json_object_int_add(json_row
, "Rp HoldTime",
3255 bsm_rp
->rp_holdtime
);
3256 json_object_int_add(json_row
, "Rp Priority",
3258 json_object_int_add(json_row
, "Hash Val",
3260 json_object_object_add(json_group
, rp_str
,
3264 vty_out(vty
, "%-15s %-15u %-15u %-15u\n",
3265 rp_str
, bsm_rp
->rp_prio
,
3266 bsm_rp
->rp_holdtime
, bsm_rp
->hash
);
3269 if (!bsm_rpinfos_count(bsgrp
->bsrp_list
) && !uj
)
3270 vty_out(vty
, "Active List is empty.\n");
3273 json_object_int_add(json_group
, "Pending RP count",
3274 bsgrp
->pend_rp_cnt
);
3276 vty_out(vty
, "(PENDING)\n");
3277 vty_out(vty
, "Pending RP count :%d\n",
3278 bsgrp
->pend_rp_cnt
);
3279 if (bsgrp
->pend_rp_cnt
)
3280 vty_out(vty
, "%-15s %-15s %-15s %-15s\n",
3281 "Rp Address", "priority", "Holdtime",
3285 frr_each (bsm_rpinfos
, bsgrp
->partial_bsrp_list
, bsm_rp
) {
3286 char rp_str
[INET_ADDRSTRLEN
];
3288 pim_inet4_dump("<Rp Addr?>", bsm_rp
->rp_address
, rp_str
,
3292 json_row
= json_object_new_object();
3293 json_object_string_add(json_row
, "Rp Address",
3295 json_object_int_add(json_row
, "Rp HoldTime",
3296 bsm_rp
->rp_holdtime
);
3297 json_object_int_add(json_row
, "Rp Priority",
3299 json_object_int_add(json_row
, "Hash Val",
3301 json_object_object_add(json_group
, rp_str
,
3304 vty_out(vty
, "%-15s %-15u %-15u %-15u\n",
3305 rp_str
, bsm_rp
->rp_prio
,
3306 bsm_rp
->rp_holdtime
, bsm_rp
->hash
);
3309 if (!bsm_rpinfos_count(bsgrp
->partial_bsrp_list
) && !uj
)
3310 vty_out(vty
, "Partial List is empty\n");
3317 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3318 json
, JSON_C_TO_STRING_PRETTY
));
3319 json_object_free(json
);
3323 /* pim statistics - just adding only bsm related now.
3324 * We can continue to add all pim related stats here.
3326 static void pim_show_statistics(struct pim_instance
*pim
, struct vty
*vty
,
3327 const char *ifname
, bool uj
)
3329 json_object
*json
= NULL
;
3330 struct interface
*ifp
;
3333 json
= json_object_new_object();
3334 json_object_int_add(json
, "bsmRx", pim
->bsm_rcvd
);
3335 json_object_int_add(json
, "bsmTx", pim
->bsm_sent
);
3336 json_object_int_add(json
, "bsmDropped", pim
->bsm_dropped
);
3338 vty_out(vty
, "BSM Statistics :\n");
3339 vty_out(vty
, "----------------\n");
3340 vty_out(vty
, "Number of Received BSMs : %" PRIu64
"\n",
3342 vty_out(vty
, "Number of Forwared BSMs : %" PRIu64
"\n",
3344 vty_out(vty
, "Number of Dropped BSMs : %" PRIu64
"\n",
3350 /* scan interfaces */
3351 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3352 struct pim_interface
*pim_ifp
= ifp
->info
;
3354 if (ifname
&& strcmp(ifname
, ifp
->name
))
3361 vty_out(vty
, "Interface : %s\n", ifp
->name
);
3362 vty_out(vty
, "-------------------\n");
3364 "Number of BSMs dropped due to config miss : %u\n",
3365 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3366 vty_out(vty
, "Number of unicast BSMs dropped : %u\n",
3367 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3369 "Number of BSMs dropped due to invalid scope zone : %u\n",
3370 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3373 json_object
*json_row
= NULL
;
3375 json_row
= json_object_new_object();
3377 json_object_string_add(json_row
, "If Name", ifp
->name
);
3378 json_object_int_add(json_row
, "bsmDroppedConfig",
3379 pim_ifp
->pim_ifstat_bsm_cfg_miss
);
3380 json_object_int_add(
3381 json_row
, "bsmDroppedUnicast",
3382 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
);
3383 json_object_int_add(json_row
,
3384 "bsmDroppedInvalidScopeZone",
3385 pim_ifp
->pim_ifstat_bsm_invalid_sz
);
3386 json_object_object_add(json
, ifp
->name
, json_row
);
3392 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3393 json
, JSON_C_TO_STRING_PRETTY
));
3394 json_object_free(json
);
3398 static void clear_pim_statistics(struct pim_instance
*pim
)
3400 struct interface
*ifp
;
3404 pim
->bsm_dropped
= 0;
3406 /* scan interfaces */
3407 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3408 struct pim_interface
*pim_ifp
= ifp
->info
;
3413 pim_ifp
->pim_ifstat_bsm_cfg_miss
= 0;
3414 pim_ifp
->pim_ifstat_ucast_bsm_cfg_miss
= 0;
3415 pim_ifp
->pim_ifstat_bsm_invalid_sz
= 0;
3419 static void igmp_show_groups(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
3421 struct interface
*ifp
;
3423 json_object
*json
= NULL
;
3424 json_object
*json_iface
= NULL
;
3425 json_object
*json_group
= NULL
;
3426 json_object
*json_groups
= NULL
;
3428 now
= pim_time_monotonic_sec();
3431 json
= json_object_new_object();
3432 json_object_int_add(json
, "totalGroups", pim
->igmp_group_count
);
3433 json_object_int_add(json
, "watermarkLimit",
3434 pim
->igmp_watermark_limit
);
3436 vty_out(vty
, "Total IGMP groups: %u\n", pim
->igmp_group_count
);
3437 vty_out(vty
, "Watermark warn limit(%s): %u\n",
3438 pim
->igmp_watermark_limit
? "Set" : "Not Set",
3439 pim
->igmp_watermark_limit
);
3441 "Interface Address Group Mode Timer Srcs V Uptime \n");
3444 /* scan interfaces */
3445 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3446 struct pim_interface
*pim_ifp
= ifp
->info
;
3447 struct listnode
*sock_node
;
3448 struct igmp_sock
*igmp
;
3453 /* scan igmp sockets */
3454 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3456 char ifaddr_str
[INET_ADDRSTRLEN
];
3457 struct listnode
*grpnode
;
3458 struct igmp_group
*grp
;
3460 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3461 sizeof(ifaddr_str
));
3463 /* scan igmp groups */
3464 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3466 char group_str
[INET_ADDRSTRLEN
];
3470 pim_inet4_dump("<group?>", grp
->group_addr
,
3471 group_str
, sizeof(group_str
));
3472 pim_time_timer_to_hhmmss(hhmmss
, sizeof(hhmmss
),
3473 grp
->t_group_timer
);
3474 pim_time_uptime(uptime
, sizeof(uptime
),
3475 now
- grp
->group_creation
);
3478 json_object_object_get_ex(
3479 json
, ifp
->name
, &json_iface
);
3483 json_object_new_object();
3484 json_object_pim_ifp_add(
3486 json_object_object_add(
3490 json_object_new_array();
3491 json_object_object_add(
3497 json_group
= json_object_new_object();
3498 json_object_string_add(json_group
,
3501 json_object_string_add(json_group
,
3505 if (grp
->igmp_version
== 3)
3506 json_object_string_add(
3508 grp
->group_filtermode_isexcl
3512 json_object_string_add(json_group
,
3514 json_object_int_add(
3515 json_group
, "sourcesCount",
3516 grp
->group_source_list
3518 grp
->group_source_list
)
3520 json_object_int_add(
3521 json_group
, "version",
3523 json_object_string_add(
3524 json_group
, "uptime", uptime
);
3525 json_object_array_add(json_groups
,
3529 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3530 ifp
->name
, ifaddr_str
,
3532 grp
->igmp_version
== 3
3533 ? (grp
->group_filtermode_isexcl
3538 grp
->group_source_list
3540 grp
->group_source_list
)
3542 grp
->igmp_version
, uptime
);
3544 } /* scan igmp groups */
3545 } /* scan igmp sockets */
3546 } /* scan interfaces */
3549 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3550 json
, JSON_C_TO_STRING_PRETTY
));
3551 json_object_free(json
);
3555 static void igmp_show_group_retransmission(struct pim_instance
*pim
,
3558 struct interface
*ifp
;
3561 "Interface Address Group RetTimer Counter RetSrcs\n");
3563 /* scan interfaces */
3564 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3565 struct pim_interface
*pim_ifp
= ifp
->info
;
3566 struct listnode
*sock_node
;
3567 struct igmp_sock
*igmp
;
3572 /* scan igmp sockets */
3573 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3575 char ifaddr_str
[INET_ADDRSTRLEN
];
3576 struct listnode
*grpnode
;
3577 struct igmp_group
*grp
;
3579 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3580 sizeof(ifaddr_str
));
3582 /* scan igmp groups */
3583 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3585 char group_str
[INET_ADDRSTRLEN
];
3586 char grp_retr_mmss
[10];
3587 struct listnode
*src_node
;
3588 struct igmp_source
*src
;
3589 int grp_retr_sources
= 0;
3591 pim_inet4_dump("<group?>", grp
->group_addr
,
3592 group_str
, sizeof(group_str
));
3593 pim_time_timer_to_mmss(
3594 grp_retr_mmss
, sizeof(grp_retr_mmss
),
3595 grp
->t_group_query_retransmit_timer
);
3598 /* count group sources with retransmission state
3600 for (ALL_LIST_ELEMENTS_RO(
3601 grp
->group_source_list
, src_node
,
3603 if (src
->source_query_retransmit_count
3609 vty_out(vty
, "%-16s %-15s %-15s %-8s %7d %7d\n",
3610 ifp
->name
, ifaddr_str
, group_str
,
3612 grp
->group_specific_query_retransmit_count
,
3615 } /* scan igmp groups */
3616 } /* scan igmp sockets */
3617 } /* scan interfaces */
3620 static void igmp_show_sources(struct pim_instance
*pim
, struct vty
*vty
)
3622 struct interface
*ifp
;
3625 now
= pim_time_monotonic_sec();
3628 "Interface Address Group Source Timer Fwd Uptime \n");
3630 /* scan interfaces */
3631 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3632 struct pim_interface
*pim_ifp
= ifp
->info
;
3633 struct listnode
*sock_node
;
3634 struct igmp_sock
*igmp
;
3639 /* scan igmp sockets */
3640 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3642 char ifaddr_str
[INET_ADDRSTRLEN
];
3643 struct listnode
*grpnode
;
3644 struct igmp_group
*grp
;
3646 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3647 sizeof(ifaddr_str
));
3649 /* scan igmp groups */
3650 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3652 char group_str
[INET_ADDRSTRLEN
];
3653 struct listnode
*srcnode
;
3654 struct igmp_source
*src
;
3656 pim_inet4_dump("<group?>", grp
->group_addr
,
3657 group_str
, sizeof(group_str
));
3659 /* scan group sources */
3660 for (ALL_LIST_ELEMENTS_RO(
3661 grp
->group_source_list
, srcnode
,
3663 char source_str
[INET_ADDRSTRLEN
];
3668 "<source?>", src
->source_addr
,
3669 source_str
, sizeof(source_str
));
3671 pim_time_timer_to_mmss(
3673 src
->t_source_timer
);
3676 uptime
, sizeof(uptime
),
3677 now
- src
->source_creation
);
3680 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3681 ifp
->name
, ifaddr_str
,
3682 group_str
, source_str
, mmss
,
3683 IGMP_SOURCE_TEST_FORWARDING(
3689 } /* scan group sources */
3690 } /* scan igmp groups */
3691 } /* scan igmp sockets */
3692 } /* scan interfaces */
3695 static void igmp_show_source_retransmission(struct pim_instance
*pim
,
3698 struct interface
*ifp
;
3701 "Interface Address Group Source Counter\n");
3703 /* scan interfaces */
3704 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3705 struct pim_interface
*pim_ifp
= ifp
->info
;
3706 struct listnode
*sock_node
;
3707 struct igmp_sock
*igmp
;
3712 /* scan igmp sockets */
3713 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
3715 char ifaddr_str
[INET_ADDRSTRLEN
];
3716 struct listnode
*grpnode
;
3717 struct igmp_group
*grp
;
3719 pim_inet4_dump("<ifaddr?>", igmp
->ifaddr
, ifaddr_str
,
3720 sizeof(ifaddr_str
));
3722 /* scan igmp groups */
3723 for (ALL_LIST_ELEMENTS_RO(igmp
->igmp_group_list
,
3725 char group_str
[INET_ADDRSTRLEN
];
3726 struct listnode
*srcnode
;
3727 struct igmp_source
*src
;
3729 pim_inet4_dump("<group?>", grp
->group_addr
,
3730 group_str
, sizeof(group_str
));
3732 /* scan group sources */
3733 for (ALL_LIST_ELEMENTS_RO(
3734 grp
->group_source_list
, srcnode
,
3736 char source_str
[INET_ADDRSTRLEN
];
3739 "<source?>", src
->source_addr
,
3740 source_str
, sizeof(source_str
));
3743 "%-16s %-15s %-15s %-15s %7d\n",
3744 ifp
->name
, ifaddr_str
,
3745 group_str
, source_str
,
3746 src
->source_query_retransmit_count
);
3748 } /* scan group sources */
3749 } /* scan igmp groups */
3750 } /* scan igmp sockets */
3751 } /* scan interfaces */
3754 static void pim_show_bsr(struct pim_instance
*pim
,
3759 char last_bsm_seen
[10];
3762 char bsr_str
[PREFIX_STRLEN
];
3763 json_object
*json
= NULL
;
3765 if (pim
->global_scope
.current_bsr
.s_addr
== INADDR_ANY
) {
3766 strlcpy(bsr_str
, "0.0.0.0", sizeof(bsr_str
));
3767 pim_time_uptime(uptime
, sizeof(uptime
),
3768 pim
->global_scope
.current_bsr_first_ts
);
3769 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3770 pim
->global_scope
.current_bsr_last_ts
);
3774 pim_inet4_dump("<bsr?>", pim
->global_scope
.current_bsr
,
3775 bsr_str
, sizeof(bsr_str
));
3776 now
= pim_time_monotonic_sec();
3777 pim_time_uptime(uptime
, sizeof(uptime
),
3778 (now
- pim
->global_scope
.current_bsr_first_ts
));
3779 pim_time_uptime(last_bsm_seen
, sizeof(last_bsm_seen
),
3780 now
- pim
->global_scope
.current_bsr_last_ts
);
3783 switch (pim
->global_scope
.state
) {
3785 strlcpy(bsr_state
, "NO_INFO", sizeof(bsr_state
));
3788 strlcpy(bsr_state
, "ACCEPT_ANY", sizeof(bsr_state
));
3790 case ACCEPT_PREFERRED
:
3791 strlcpy(bsr_state
, "ACCEPT_PREFERRED", sizeof(bsr_state
));
3794 strlcpy(bsr_state
, "", sizeof(bsr_state
));
3798 json
= json_object_new_object();
3799 json_object_string_add(json
, "bsr", bsr_str
);
3800 json_object_int_add(json
, "priority",
3801 pim
->global_scope
.current_bsr_prio
);
3802 json_object_int_add(json
, "fragmentTag",
3803 pim
->global_scope
.bsm_frag_tag
);
3804 json_object_string_add(json
, "state", bsr_state
);
3805 json_object_string_add(json
, "upTime", uptime
);
3806 json_object_string_add(json
, "lastBsmSeen", last_bsm_seen
);
3810 vty_out(vty
, "PIMv2 Bootstrap information\n");
3811 vty_out(vty
, "Current preferred BSR address: %s\n", bsr_str
);
3813 "Priority Fragment-Tag State UpTime\n");
3814 vty_out(vty
, " %-12d %-12d %-13s %7s\n",
3815 pim
->global_scope
.current_bsr_prio
,
3816 pim
->global_scope
.bsm_frag_tag
,
3819 vty_out(vty
, "Last BSM seen: %s\n", last_bsm_seen
);
3823 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3824 json
, JSON_C_TO_STRING_PRETTY
));
3825 json_object_free(json
);
3829 static void clear_igmp_interfaces(struct pim_instance
*pim
)
3831 struct interface
*ifp
;
3833 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3834 pim_if_addr_del_all_igmp(ifp
);
3836 FOR_ALL_INTERFACES (pim
->vrf
, ifp
)
3837 pim_if_addr_add_all(ifp
);
3840 static void clear_pim_interfaces(struct pim_instance
*pim
)
3842 struct interface
*ifp
;
3844 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
3846 pim_neighbor_delete_all(ifp
, "interface cleared");
3851 static void clear_interfaces(struct pim_instance
*pim
)
3853 clear_igmp_interfaces(pim
);
3854 clear_pim_interfaces(pim
);
3857 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3858 pim_ifp = ifp->info; \
3861 "%% Enable PIM and/or IGMP on this interface first\n"); \
3862 return CMD_WARNING_CONFIG_FAILED; \
3866 * Get current node VRF name.
3869 * In case of failure it will print error message to user.
3871 * \returns name or NULL if failed to get VRF.
3873 static const char *pim_cli_get_vrf_name(struct vty
*vty
)
3875 const struct lyd_node
*vrf_node
;
3877 /* Not inside any VRF context. */
3878 if (vty
->xpath_index
== 0)
3879 return VRF_DEFAULT_NAME
;
3881 vrf_node
= yang_dnode_get(vty
->candidate_config
->dnode
, VTY_CURR_XPATH
);
3882 if (vrf_node
== NULL
) {
3883 vty_out(vty
, "%% Failed to get vrf dnode in configuration\n");
3887 return yang_dnode_get_string(vrf_node
, "./name");
3891 * Compatibility function to keep the legacy mesh group CLI behavior:
3892 * Delete group when there are no more configurations in it.
3895 * Don't forget to call `nb_cli_apply_changes` after this.
3897 static void pim_cli_legacy_mesh_group_behavior(struct vty
*vty
,
3900 const char *vrfname
;
3901 char xpath_value
[XPATH_MAXLEN
];
3902 char xpath_member_value
[XPATH_MAXLEN
];
3903 const struct lyd_node
*member_dnode
;
3905 vrfname
= pim_cli_get_vrf_name(vty
);
3906 if (vrfname
== NULL
)
3909 /* Get mesh group base XPath. */
3910 snprintf(xpath_value
, sizeof(xpath_value
),
3911 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
3912 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
3913 /* Group must exists, otherwise just quit. */
3914 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
))
3917 /* Group members check: */
3918 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
3919 strlcat(xpath_member_value
, "/members", sizeof(xpath_member_value
));
3920 if (yang_dnode_exists(vty
->candidate_config
->dnode
,
3921 xpath_member_value
)) {
3922 member_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
,
3923 xpath_member_value
);
3924 if (!yang_is_last_list_dnode(member_dnode
))
3928 /* Source address check: */
3929 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
3930 strlcat(xpath_member_value
, "/source", sizeof(xpath_member_value
));
3931 if (yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_member_value
))
3934 /* No configurations found: delete it. */
3935 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
3938 DEFUN (clear_ip_interfaces
,
3939 clear_ip_interfaces_cmd
,
3940 "clear ip interfaces [vrf NAME]",
3943 "Reset interfaces\n"
3947 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3952 clear_interfaces(vrf
->info
);
3957 DEFUN (clear_ip_igmp_interfaces
,
3958 clear_ip_igmp_interfaces_cmd
,
3959 "clear ip igmp [vrf NAME] interfaces",
3964 "Reset IGMP interfaces\n")
3967 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3972 clear_igmp_interfaces(vrf
->info
);
3977 DEFUN (clear_ip_pim_statistics
,
3978 clear_ip_pim_statistics_cmd
,
3979 "clear ip pim statistics [vrf NAME]",
3984 "Reset PIM statistics\n")
3987 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
3992 clear_pim_statistics(vrf
->info
);
3996 static void clear_mroute(struct pim_instance
*pim
)
3998 struct pim_upstream
*up
;
3999 struct interface
*ifp
;
4001 /* scan interfaces */
4002 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4003 struct pim_interface
*pim_ifp
= ifp
->info
;
4004 struct listnode
*sock_node
;
4005 struct igmp_sock
*igmp
;
4006 struct pim_ifchannel
*ch
;
4011 /* deleting all ifchannels */
4012 while (!RB_EMPTY(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
)) {
4013 ch
= RB_ROOT(pim_ifchannel_rb
, &pim_ifp
->ifchannel_rb
);
4015 pim_ifchannel_delete(ch
);
4018 /* clean up all igmp groups */
4019 /* scan igmp sockets */
4020 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->igmp_socket_list
, sock_node
,
4023 struct igmp_group
*grp
;
4025 if (igmp
->igmp_group_list
) {
4026 while (igmp
->igmp_group_list
->count
) {
4027 grp
= listnode_head(
4028 igmp
->igmp_group_list
);
4029 igmp_group_delete(grp
);
4036 /* clean up all upstreams*/
4037 while ((up
= rb_pim_upstream_first(&pim
->upstream_head
)))
4038 pim_upstream_del(pim
, up
, __func__
);
4042 DEFUN (clear_ip_mroute
,
4043 clear_ip_mroute_cmd
,
4044 "clear ip mroute [vrf NAME]",
4047 "Reset multicast routes\n"
4051 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4056 clear_mroute(vrf
->info
);
4061 DEFUN (clear_ip_pim_interfaces
,
4062 clear_ip_pim_interfaces_cmd
,
4063 "clear ip pim [vrf NAME] interfaces",
4068 "Reset PIM interfaces\n")
4071 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4076 clear_pim_interfaces(vrf
->info
);
4081 DEFUN (clear_ip_pim_interface_traffic
,
4082 clear_ip_pim_interface_traffic_cmd
,
4083 "clear ip pim [vrf NAME] interface traffic",
4086 "PIM clear commands\n"
4088 "Reset PIM interfaces\n"
4089 "Reset Protocol Packet counters\n")
4092 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4093 struct interface
*ifp
= NULL
;
4094 struct pim_interface
*pim_ifp
= NULL
;
4099 FOR_ALL_INTERFACES (vrf
, ifp
) {
4100 pim_ifp
= ifp
->info
;
4105 pim_ifp
->pim_ifstat_hello_recv
= 0;
4106 pim_ifp
->pim_ifstat_hello_sent
= 0;
4107 pim_ifp
->pim_ifstat_join_recv
= 0;
4108 pim_ifp
->pim_ifstat_join_send
= 0;
4109 pim_ifp
->pim_ifstat_prune_recv
= 0;
4110 pim_ifp
->pim_ifstat_prune_send
= 0;
4111 pim_ifp
->pim_ifstat_reg_recv
= 0;
4112 pim_ifp
->pim_ifstat_reg_send
= 0;
4113 pim_ifp
->pim_ifstat_reg_stop_recv
= 0;
4114 pim_ifp
->pim_ifstat_reg_stop_send
= 0;
4115 pim_ifp
->pim_ifstat_assert_recv
= 0;
4116 pim_ifp
->pim_ifstat_assert_send
= 0;
4117 pim_ifp
->pim_ifstat_bsm_rx
= 0;
4118 pim_ifp
->pim_ifstat_bsm_tx
= 0;
4124 DEFUN (clear_ip_pim_oil
,
4125 clear_ip_pim_oil_cmd
,
4126 "clear ip pim [vrf NAME] oil",
4131 "Rescan PIM OIL (output interface list)\n")
4134 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4139 pim_scan_oil(vrf
->info
);
4144 static void clear_pim_bsr_db(struct pim_instance
*pim
)
4146 struct route_node
*rn
;
4147 struct route_node
*rpnode
;
4148 struct bsgrp_node
*bsgrp
;
4149 struct prefix nht_p
;
4150 struct prefix g_all
;
4151 struct rp_info
*rp_all
;
4152 struct pim_upstream
*up
;
4153 struct rp_info
*rp_info
;
4154 bool is_bsr_tracking
= true;
4156 /* Remove next hop tracking for the bsr */
4157 nht_p
.family
= AF_INET
;
4158 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4159 nht_p
.u
.prefix4
= pim
->global_scope
.current_bsr
;
4160 if (PIM_DEBUG_BSM
) {
4161 zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT",
4164 pim_delete_tracked_nexthop(pim
, &nht_p
, NULL
, NULL
, is_bsr_tracking
);
4166 /* Reset scope zone data */
4167 pim
->global_scope
.accept_nofwd_bsm
= false;
4168 pim
->global_scope
.state
= ACCEPT_ANY
;
4169 pim
->global_scope
.current_bsr
.s_addr
= INADDR_ANY
;
4170 pim
->global_scope
.current_bsr_prio
= 0;
4171 pim
->global_scope
.current_bsr_first_ts
= 0;
4172 pim
->global_scope
.current_bsr_last_ts
= 0;
4173 pim
->global_scope
.bsm_frag_tag
= 0;
4174 pim_bsm_frags_free(&pim
->global_scope
);
4176 pim_bs_timer_stop(&pim
->global_scope
);
4178 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
4179 rn
= route_next(rn
)) {
4184 rpnode
= route_node_lookup(pim
->rp_table
, &bsgrp
->group
);
4187 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
,
4189 pim_free_bsgrp_data(bsgrp
);
4193 rp_info
= (struct rp_info
*)rpnode
->info
;
4195 if ((!rp_info
) || (rp_info
->rp_src
!= RP_SRC_BSR
)) {
4196 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
,
4198 pim_free_bsgrp_data(bsgrp
);
4202 /* Deregister addr with Zebra NHT */
4203 nht_p
.family
= AF_INET
;
4204 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
4205 nht_p
.u
.prefix4
= rp_info
->rp
.rpf_addr
.u
.prefix4
;
4207 if (PIM_DEBUG_PIM_NHT_RP
) {
4208 zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
4212 pim_delete_tracked_nexthop(pim
, &nht_p
, NULL
, rp_info
, false);
4214 if (!str2prefix("224.0.0.0/4", &g_all
))
4217 rp_all
= pim_rp_find_match_group(pim
, &g_all
);
4219 if (rp_all
== rp_info
) {
4220 rp_all
->rp
.rpf_addr
.family
= AF_INET
;
4221 rp_all
->rp
.rpf_addr
.u
.prefix4
.s_addr
= INADDR_NONE
;
4222 rp_all
->i_am_rp
= 0;
4224 /* Delete the rp_info from rp-list */
4225 listnode_delete(pim
->rp_list
, rp_info
);
4227 /* Delete the rp node from rp_table */
4228 rpnode
->info
= NULL
;
4229 route_unlock_node(rpnode
);
4230 route_unlock_node(rpnode
);
4233 XFREE(MTYPE_PIM_RP
, rp_info
);
4235 pim_free_bsgrp_node(bsgrp
->scope
->bsrp_table
, &bsgrp
->group
);
4236 pim_free_bsgrp_data(bsgrp
);
4238 pim_rp_refresh_group_to_rp_mapping(pim
);
4241 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
4242 /* Find the upstream (*, G) whose upstream address is same as
4245 if (up
->sg
.src
.s_addr
!= INADDR_ANY
)
4249 struct rp_info
*trp_info
;
4251 grp
.family
= AF_INET
;
4252 grp
.prefixlen
= IPV4_MAX_BITLEN
;
4253 grp
.u
.prefix4
= up
->sg
.grp
;
4255 trp_info
= pim_rp_find_match_group(pim
, &grp
);
4257 /* RP not found for the group grp */
4258 if (pim_rpf_addr_is_inaddr_none(&trp_info
->rp
)) {
4259 pim_upstream_rpf_clear(pim
, up
);
4260 pim_rp_set_upstream_addr(pim
, &up
->upstream_addr
,
4261 up
->sg
.src
, up
->sg
.grp
);
4263 /* RP found for the group grp */
4264 pim_upstream_update(pim
, up
);
4270 DEFUN (clear_ip_pim_bsr_db
,
4271 clear_ip_pim_bsr_db_cmd
,
4272 "clear ip pim [vrf NAME] bsr-data",
4277 "Reset pim bsr data\n")
4280 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4285 clear_pim_bsr_db(vrf
->info
);
4290 DEFUN (show_ip_igmp_interface
,
4291 show_ip_igmp_interface_cmd
,
4292 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4297 "IGMP interface information\n"
4303 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4304 bool uj
= use_json(argc
, argv
);
4309 if (argv_find(argv
, argc
, "detail", &idx
)
4310 || argv_find(argv
, argc
, "WORD", &idx
))
4311 igmp_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4313 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4318 DEFUN (show_ip_igmp_interface_vrf_all
,
4319 show_ip_igmp_interface_vrf_all_cmd
,
4320 "show ip igmp vrf all interface [detail|WORD] [json]",
4325 "IGMP interface information\n"
4331 bool uj
= use_json(argc
, argv
);
4337 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4341 vty_out(vty
, " \"%s\": ", vrf
->name
);
4344 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4345 if (argv_find(argv
, argc
, "detail", &idx
)
4346 || argv_find(argv
, argc
, "WORD", &idx
))
4347 igmp_show_interfaces_single(vrf
->info
, vty
,
4348 argv
[idx
]->arg
, uj
);
4350 igmp_show_interfaces(vrf
->info
, vty
, uj
);
4353 vty_out(vty
, "}\n");
4358 DEFUN (show_ip_igmp_join
,
4359 show_ip_igmp_join_cmd
,
4360 "show ip igmp [vrf NAME] join [json]",
4365 "IGMP static join information\n"
4369 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4370 bool uj
= use_json(argc
, argv
);
4375 igmp_show_interface_join(vrf
->info
, vty
, uj
);
4380 DEFUN (show_ip_igmp_join_vrf_all
,
4381 show_ip_igmp_join_vrf_all_cmd
,
4382 "show ip igmp vrf all join [json]",
4387 "IGMP static join information\n"
4390 bool uj
= use_json(argc
, argv
);
4396 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4400 vty_out(vty
, " \"%s\": ", vrf
->name
);
4403 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4404 igmp_show_interface_join(vrf
->info
, vty
, uj
);
4407 vty_out(vty
, "}\n");
4412 DEFUN (show_ip_igmp_groups
,
4413 show_ip_igmp_groups_cmd
,
4414 "show ip igmp [vrf NAME] groups [json]",
4423 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4424 bool uj
= use_json(argc
, argv
);
4429 igmp_show_groups(vrf
->info
, vty
, uj
);
4434 DEFUN (show_ip_igmp_groups_vrf_all
,
4435 show_ip_igmp_groups_vrf_all_cmd
,
4436 "show ip igmp vrf all groups [json]",
4444 bool uj
= use_json(argc
, argv
);
4450 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4454 vty_out(vty
, " \"%s\": ", vrf
->name
);
4457 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4458 igmp_show_groups(vrf
->info
, vty
, uj
);
4461 vty_out(vty
, "}\n");
4466 DEFUN (show_ip_igmp_groups_retransmissions
,
4467 show_ip_igmp_groups_retransmissions_cmd
,
4468 "show ip igmp [vrf NAME] groups retransmissions",
4474 "IGMP group retransmissions\n")
4477 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4482 igmp_show_group_retransmission(vrf
->info
, vty
);
4487 DEFUN (show_ip_igmp_sources
,
4488 show_ip_igmp_sources_cmd
,
4489 "show ip igmp [vrf NAME] sources",
4497 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4502 igmp_show_sources(vrf
->info
, vty
);
4507 DEFUN (show_ip_igmp_sources_retransmissions
,
4508 show_ip_igmp_sources_retransmissions_cmd
,
4509 "show ip igmp [vrf NAME] sources retransmissions",
4515 "IGMP source retransmissions\n")
4518 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4523 igmp_show_source_retransmission(vrf
->info
, vty
);
4528 DEFUN (show_ip_igmp_statistics
,
4529 show_ip_igmp_statistics_cmd
,
4530 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4541 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4542 bool uj
= use_json(argc
, argv
);
4547 if (argv_find(argv
, argc
, "WORD", &idx
))
4548 igmp_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
4550 igmp_show_statistics(vrf
->info
, vty
, NULL
, uj
);
4555 DEFUN (show_ip_pim_mlag_summary
,
4556 show_ip_pim_mlag_summary_cmd
,
4557 "show ip pim mlag summary [json]",
4562 "status and stats\n"
4565 bool uj
= use_json(argc
, argv
);
4566 char role_buf
[MLAG_ROLE_STRSIZE
];
4567 char addr_buf
[INET_ADDRSTRLEN
];
4570 json_object
*json
= NULL
;
4571 json_object
*json_stat
= NULL
;
4573 json
= json_object_new_object();
4574 if (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4575 json_object_boolean_true_add(json
, "mlagConnUp");
4576 if (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4577 json_object_boolean_true_add(json
, "mlagPeerConnUp");
4578 if (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4579 json_object_boolean_true_add(json
, "mlagPeerZebraUp");
4580 json_object_string_add(json
, "mlagRole",
4581 mlag_role2str(router
->mlag_role
,
4582 role_buf
, sizeof(role_buf
)));
4583 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4584 addr_buf
, INET_ADDRSTRLEN
);
4585 json_object_string_add(json
, "localVtepIp", addr_buf
);
4586 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4587 addr_buf
, INET_ADDRSTRLEN
);
4588 json_object_string_add(json
, "anycastVtepIp", addr_buf
);
4589 json_object_string_add(json
, "peerlinkRif",
4590 router
->peerlink_rif
);
4592 json_stat
= json_object_new_object();
4593 json_object_int_add(json_stat
, "mlagConnFlaps",
4594 router
->mlag_stats
.mlagd_session_downs
);
4595 json_object_int_add(json_stat
, "mlagPeerConnFlaps",
4596 router
->mlag_stats
.peer_session_downs
);
4597 json_object_int_add(json_stat
, "mlagPeerZebraFlaps",
4598 router
->mlag_stats
.peer_zebra_downs
);
4599 json_object_int_add(json_stat
, "mrouteAddRx",
4600 router
->mlag_stats
.msg
.mroute_add_rx
);
4601 json_object_int_add(json_stat
, "mrouteAddTx",
4602 router
->mlag_stats
.msg
.mroute_add_tx
);
4603 json_object_int_add(json_stat
, "mrouteDelRx",
4604 router
->mlag_stats
.msg
.mroute_del_rx
);
4605 json_object_int_add(json_stat
, "mrouteDelTx",
4606 router
->mlag_stats
.msg
.mroute_del_tx
);
4607 json_object_int_add(json_stat
, "mlagStatusUpdates",
4608 router
->mlag_stats
.msg
.mlag_status_updates
);
4609 json_object_int_add(json_stat
, "peerZebraStatusUpdates",
4610 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4611 json_object_int_add(json_stat
, "pimStatusUpdates",
4612 router
->mlag_stats
.msg
.pim_status_updates
);
4613 json_object_int_add(json_stat
, "vxlanUpdates",
4614 router
->mlag_stats
.msg
.vxlan_updates
);
4615 json_object_object_add(json
, "connStats", json_stat
);
4617 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4618 json
, JSON_C_TO_STRING_PRETTY
));
4619 json_object_free(json
);
4623 vty_out(vty
, "MLAG daemon connection: %s\n",
4624 (router
->mlag_flags
& PIM_MLAGF_LOCAL_CONN_UP
)
4626 vty_out(vty
, "MLAG peer state: %s\n",
4627 (router
->mlag_flags
& PIM_MLAGF_PEER_CONN_UP
)
4629 vty_out(vty
, "Zebra peer state: %s\n",
4630 (router
->mlag_flags
& PIM_MLAGF_PEER_ZEBRA_UP
)
4632 vty_out(vty
, "MLAG role: %s\n",
4633 mlag_role2str(router
->mlag_role
, role_buf
, sizeof(role_buf
)));
4634 inet_ntop(AF_INET
, &router
->local_vtep_ip
,
4635 addr_buf
, INET_ADDRSTRLEN
);
4636 vty_out(vty
, "Local VTEP IP: %s\n", addr_buf
);
4637 inet_ntop(AF_INET
, &router
->anycast_vtep_ip
,
4638 addr_buf
, INET_ADDRSTRLEN
);
4639 vty_out(vty
, "Anycast VTEP IP: %s\n", addr_buf
);
4640 vty_out(vty
, "Peerlink: %s\n", router
->peerlink_rif
);
4641 vty_out(vty
, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4642 router
->mlag_stats
.mlagd_session_downs
,
4643 router
->mlag_stats
.peer_session_downs
,
4644 router
->mlag_stats
.peer_zebra_downs
);
4645 vty_out(vty
, "Message Statistics:\n");
4646 vty_out(vty
, " mroute adds: rx: %d, tx: %d\n",
4647 router
->mlag_stats
.msg
.mroute_add_rx
,
4648 router
->mlag_stats
.msg
.mroute_add_tx
);
4649 vty_out(vty
, " mroute dels: rx: %d, tx: %d\n",
4650 router
->mlag_stats
.msg
.mroute_del_rx
,
4651 router
->mlag_stats
.msg
.mroute_del_tx
);
4652 vty_out(vty
, " peer zebra status updates: %d\n",
4653 router
->mlag_stats
.msg
.peer_zebra_status_updates
);
4654 vty_out(vty
, " PIM status updates: %d\n",
4655 router
->mlag_stats
.msg
.pim_status_updates
);
4656 vty_out(vty
, " VxLAN updates: %d\n",
4657 router
->mlag_stats
.msg
.vxlan_updates
);
4662 DEFUN (show_ip_pim_assert
,
4663 show_ip_pim_assert_cmd
,
4664 "show ip pim [vrf NAME] assert",
4669 "PIM interface assert\n")
4672 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4677 pim_show_assert(vrf
->info
, vty
);
4682 DEFUN (show_ip_pim_assert_internal
,
4683 show_ip_pim_assert_internal_cmd
,
4684 "show ip pim [vrf NAME] assert-internal",
4689 "PIM interface internal assert state\n")
4692 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4697 pim_show_assert_internal(vrf
->info
, vty
);
4702 DEFUN (show_ip_pim_assert_metric
,
4703 show_ip_pim_assert_metric_cmd
,
4704 "show ip pim [vrf NAME] assert-metric",
4709 "PIM interface assert metric\n")
4712 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4717 pim_show_assert_metric(vrf
->info
, vty
);
4722 DEFUN (show_ip_pim_assert_winner_metric
,
4723 show_ip_pim_assert_winner_metric_cmd
,
4724 "show ip pim [vrf NAME] assert-winner-metric",
4729 "PIM interface assert winner metric\n")
4732 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4737 pim_show_assert_winner_metric(vrf
->info
, vty
);
4742 DEFUN (show_ip_pim_interface
,
4743 show_ip_pim_interface_cmd
,
4744 "show ip pim [mlag] [vrf NAME] interface [detail|WORD] [json]",
4750 "PIM interface information\n"
4756 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4757 bool uj
= use_json(argc
, argv
);
4763 if (argv_find(argv
, argc
, "mlag", &idx
))
4766 if (argv_find(argv
, argc
, "WORD", &idx
)
4767 || argv_find(argv
, argc
, "detail", &idx
))
4768 pim_show_interfaces_single(vrf
->info
, vty
, argv
[idx
]->arg
, mlag
,
4771 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4776 DEFUN (show_ip_pim_interface_vrf_all
,
4777 show_ip_pim_interface_vrf_all_cmd
,
4778 "show ip pim [mlag] vrf all interface [detail|WORD] [json]",
4784 "PIM interface information\n"
4790 bool uj
= use_json(argc
, argv
);
4795 if (argv_find(argv
, argc
, "mlag", &idx
))
4801 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4805 vty_out(vty
, " \"%s\": ", vrf
->name
);
4808 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4809 if (argv_find(argv
, argc
, "WORD", &idx
)
4810 || argv_find(argv
, argc
, "detail", &idx
))
4811 pim_show_interfaces_single(vrf
->info
, vty
,
4812 argv
[idx
]->arg
, mlag
, uj
);
4814 pim_show_interfaces(vrf
->info
, vty
, mlag
, uj
);
4817 vty_out(vty
, "}\n");
4822 DEFPY (show_ip_pim_join
,
4823 show_ip_pim_join_cmd
,
4824 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4829 "PIM interface join information\n"
4830 "The Source or Group\n"
4834 struct prefix_sg sg
= {0};
4837 struct pim_instance
*pim
;
4839 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4842 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4845 pim
= pim_get_pim_instance(v
->vrf_id
);
4848 vty_out(vty
, "%% Unable to find pim instance\n");
4852 if (s_or_g
.s_addr
!= INADDR_ANY
) {
4853 if (g
.s_addr
!= INADDR_ANY
) {
4860 pim_show_join(pim
, vty
, &sg
, uj
);
4865 DEFUN (show_ip_pim_join_vrf_all
,
4866 show_ip_pim_join_vrf_all_cmd
,
4867 "show ip pim vrf all join [json]",
4872 "PIM interface join information\n"
4875 struct prefix_sg sg
= {0};
4876 bool uj
= use_json(argc
, argv
);
4882 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4886 vty_out(vty
, " \"%s\": ", vrf
->name
);
4889 vty_out(vty
, "VRF: %s\n", vrf
->name
);
4890 pim_show_join(vrf
->info
, vty
, &sg
, uj
);
4893 vty_out(vty
, "}\n");
4898 static void pim_show_jp_agg_helper(struct vty
*vty
,
4899 struct interface
*ifp
,
4900 struct pim_neighbor
*neigh
,
4901 struct pim_upstream
*up
,
4904 char src_str
[INET_ADDRSTRLEN
];
4905 char grp_str
[INET_ADDRSTRLEN
];
4906 char rpf_str
[INET_ADDRSTRLEN
];
4908 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
4909 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
4910 /* pius->address.s_addr */
4911 pim_inet4_dump("<rpf?>", neigh
->source_addr
, rpf_str
, sizeof(rpf_str
));
4913 vty_out(vty
, "%-16s %-15s %-15s %-15s %5s\n",
4914 ifp
->name
, rpf_str
, src_str
,
4915 grp_str
, is_join
?"J":"P");
4918 static void pim_show_jp_agg_list(struct pim_instance
*pim
, struct vty
*vty
)
4920 struct interface
*ifp
;
4921 struct pim_interface
*pim_ifp
;
4922 struct listnode
*n_node
;
4923 struct pim_neighbor
*neigh
;
4924 struct listnode
*jag_node
;
4925 struct pim_jp_agg_group
*jag
;
4926 struct listnode
*js_node
;
4927 struct pim_jp_sources
*js
;
4930 "Interface RPF Nbr Source Group State\n");
4932 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
4933 pim_ifp
= ifp
->info
;
4937 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->pim_neighbor_list
,
4939 for (ALL_LIST_ELEMENTS_RO(neigh
->upstream_jp_agg
,
4941 for (ALL_LIST_ELEMENTS_RO(jag
->sources
,
4943 pim_show_jp_agg_helper(vty
,
4952 DEFPY (show_ip_pim_jp_agg
,
4953 show_ip_pim_jp_agg_cmd
,
4954 "show ip pim [vrf NAME] jp-agg",
4959 "join prune aggregation list\n")
4962 struct pim_instance
*pim
;
4964 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
4967 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
4970 pim
= pim_get_pim_instance(v
->vrf_id
);
4973 vty_out(vty
, "%% Unable to find pim instance\n");
4977 pim_show_jp_agg_list(pim
, vty
);
4982 DEFUN (show_ip_pim_local_membership
,
4983 show_ip_pim_local_membership_cmd
,
4984 "show ip pim [vrf NAME] local-membership [json]",
4989 "PIM interface local-membership\n"
4993 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
4994 bool uj
= use_json(argc
, argv
);
4999 pim_show_membership(vrf
->info
, vty
, uj
);
5004 static void pim_show_mlag_up_entry_detail(struct vrf
*vrf
,
5006 struct pim_upstream
*up
,
5007 char *src_str
, char *grp_str
,
5011 json_object
*json_row
= NULL
;
5012 json_object
*own_list
= NULL
;
5013 json_object
*json_group
= NULL
;
5016 json_object_object_get_ex(json
, grp_str
, &json_group
);
5018 json_group
= json_object_new_object();
5019 json_object_object_add(json
, grp_str
,
5023 json_row
= json_object_new_object();
5024 json_object_string_add(json_row
, "source", src_str
);
5025 json_object_string_add(json_row
, "group", grp_str
);
5027 own_list
= json_object_new_array();
5028 if (pim_up_mlag_is_local(up
))
5029 json_object_array_add(own_list
,
5030 json_object_new_string("local"));
5031 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
5032 json_object_array_add(own_list
,
5033 json_object_new_string("peer"));
5034 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
5035 json_object_array_add(
5036 own_list
, json_object_new_string("Interface"));
5037 json_object_object_add(json_row
, "owners", own_list
);
5039 json_object_int_add(json_row
, "localCost",
5040 pim_up_mlag_local_cost(up
));
5041 json_object_int_add(json_row
, "peerCost",
5042 pim_up_mlag_peer_cost(up
));
5043 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
5044 json_object_boolean_false_add(json_row
, "df");
5046 json_object_boolean_true_add(json_row
, "df");
5047 json_object_object_add(json_group
, src_str
, json_row
);
5052 if (pim_up_mlag_is_local(up
))
5053 strlcat(own_str
, "L", sizeof(own_str
));
5054 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
5055 strlcat(own_str
, "P", sizeof(own_str
));
5056 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
5057 strlcat(own_str
, "I", sizeof(own_str
));
5058 /* XXX - fixup, print paragraph output */
5060 "%-15s %-15s %-6s %-11u %-10d %2s\n",
5061 src_str
, grp_str
, own_str
,
5062 pim_up_mlag_local_cost(up
),
5063 pim_up_mlag_peer_cost(up
),
5064 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
5069 static void pim_show_mlag_up_detail(struct vrf
*vrf
,
5070 struct vty
*vty
, const char *src_or_group
,
5071 const char *group
, bool uj
)
5073 char src_str
[INET_ADDRSTRLEN
];
5074 char grp_str
[INET_ADDRSTRLEN
];
5075 struct pim_upstream
*up
;
5076 struct pim_instance
*pim
= vrf
->info
;
5077 json_object
*json
= NULL
;
5080 json
= json_object_new_object();
5083 "Source Group Owner Local-cost Peer-cost DF\n");
5085 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
5086 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
5087 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
5088 && !pim_up_mlag_is_local(up
))
5091 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
5092 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
5093 /* XXX: strcmps are clearly inefficient. we should do uint comps
5097 if (strcmp(src_str
, src_or_group
) ||
5098 strcmp(grp_str
, group
))
5101 if (strcmp(src_str
, src_or_group
) &&
5102 strcmp(grp_str
, src_or_group
))
5105 pim_show_mlag_up_entry_detail(vrf
, vty
, up
,
5106 src_str
, grp_str
, json
);
5110 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5111 json
, JSON_C_TO_STRING_PRETTY
));
5112 json_object_free(json
);
5116 static void pim_show_mlag_up_vrf(struct vrf
*vrf
, struct vty
*vty
, bool uj
)
5118 json_object
*json
= NULL
;
5119 json_object
*json_row
;
5120 struct pim_upstream
*up
;
5121 char src_str
[INET_ADDRSTRLEN
];
5122 char grp_str
[INET_ADDRSTRLEN
];
5123 struct pim_instance
*pim
= vrf
->info
;
5124 json_object
*json_group
= NULL
;
5127 json
= json_object_new_object();
5130 "Source Group Owner Local-cost Peer-cost DF\n");
5133 frr_each (rb_pim_upstream
, &pim
->upstream_head
, up
) {
5134 if (!(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)
5135 && !(up
->flags
& PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
)
5136 && !pim_up_mlag_is_local(up
))
5138 pim_inet4_dump("<src?>", up
->sg
.src
, src_str
, sizeof(src_str
));
5139 pim_inet4_dump("<grp?>", up
->sg
.grp
, grp_str
, sizeof(grp_str
));
5141 json_object
*own_list
= NULL
;
5143 json_object_object_get_ex(json
, grp_str
, &json_group
);
5145 json_group
= json_object_new_object();
5146 json_object_object_add(json
, grp_str
,
5150 json_row
= json_object_new_object();
5151 json_object_string_add(json_row
, "vrf", vrf
->name
);
5152 json_object_string_add(json_row
, "source", src_str
);
5153 json_object_string_add(json_row
, "group", grp_str
);
5155 own_list
= json_object_new_array();
5156 if (pim_up_mlag_is_local(up
)) {
5158 json_object_array_add(own_list
,
5159 json_object_new_string(
5162 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
)) {
5163 json_object_array_add(own_list
,
5164 json_object_new_string(
5167 json_object_object_add(json_row
, "owners", own_list
);
5169 json_object_int_add(json_row
, "localCost",
5170 pim_up_mlag_local_cost(up
));
5171 json_object_int_add(json_row
, "peerCost",
5172 pim_up_mlag_peer_cost(up
));
5173 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
))
5174 json_object_boolean_false_add(json_row
, "df");
5176 json_object_boolean_true_add(json_row
, "df");
5177 json_object_object_add(json_group
, src_str
, json_row
);
5182 if (pim_up_mlag_is_local(up
))
5183 strlcat(own_str
, "L", sizeof(own_str
));
5184 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER
))
5185 strlcat(own_str
, "P", sizeof(own_str
));
5186 if (up
->flags
& (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE
))
5187 strlcat(own_str
, "I", sizeof(own_str
));
5189 "%-15s %-15s %-6s %-11u %-10u %2s\n",
5190 src_str
, grp_str
, own_str
,
5191 pim_up_mlag_local_cost(up
),
5192 pim_up_mlag_peer_cost(up
),
5193 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up
->flags
)
5198 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5199 json
, JSON_C_TO_STRING_PRETTY
));
5200 json_object_free(json
);
5204 static void pim_show_mlag_help_string(struct vty
*vty
, bool uj
)
5207 vty_out(vty
, "Owner codes:\n");
5209 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
5214 DEFUN(show_ip_pim_mlag_up
, show_ip_pim_mlag_up_cmd
,
5215 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
5222 "Unicast or Multicast address\n"
5223 "Multicast address\n" JSON_STR
)
5225 const char *src_or_group
= NULL
;
5226 const char *group
= NULL
;
5228 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5229 bool uj
= use_json(argc
, argv
);
5231 if (!vrf
|| !vrf
->info
) {
5232 vty_out(vty
, "%s: VRF or Info missing\n", __func__
);
5239 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5240 src_or_group
= argv
[idx
]->arg
;
5242 group
= argv
[idx
+ 1]->arg
;
5245 pim_show_mlag_help_string(vty
, uj
);
5248 pim_show_mlag_up_detail(vrf
, vty
, src_or_group
, group
, uj
);
5250 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5256 DEFUN(show_ip_pim_mlag_up_vrf_all
, show_ip_pim_mlag_up_vrf_all_cmd
,
5257 "show ip pim vrf all mlag upstream [json]",
5258 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
5260 "upstream\n" JSON_STR
)
5263 bool uj
= use_json(argc
, argv
);
5265 pim_show_mlag_help_string(vty
, uj
);
5266 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5267 pim_show_mlag_up_vrf(vrf
, vty
, uj
);
5273 DEFUN (show_ip_pim_neighbor
,
5274 show_ip_pim_neighbor_cmd
,
5275 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5280 "PIM neighbor information\n"
5282 "Name of interface or neighbor\n"
5286 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5287 bool uj
= use_json(argc
, argv
);
5292 if (argv_find(argv
, argc
, "detail", &idx
)
5293 || argv_find(argv
, argc
, "WORD", &idx
))
5294 pim_show_neighbors_single(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5296 pim_show_neighbors(vrf
->info
, vty
, uj
);
5301 DEFUN (show_ip_pim_neighbor_vrf_all
,
5302 show_ip_pim_neighbor_vrf_all_cmd
,
5303 "show ip pim vrf all neighbor [detail|WORD] [json]",
5308 "PIM neighbor information\n"
5310 "Name of interface or neighbor\n"
5314 bool uj
= use_json(argc
, argv
);
5320 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5324 vty_out(vty
, " \"%s\": ", vrf
->name
);
5327 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5328 if (argv_find(argv
, argc
, "detail", &idx
)
5329 || argv_find(argv
, argc
, "WORD", &idx
))
5330 pim_show_neighbors_single(vrf
->info
, vty
,
5331 argv
[idx
]->arg
, uj
);
5333 pim_show_neighbors(vrf
->info
, vty
, uj
);
5336 vty_out(vty
, "}\n");
5341 DEFUN (show_ip_pim_secondary
,
5342 show_ip_pim_secondary_cmd
,
5343 "show ip pim [vrf NAME] secondary",
5348 "PIM neighbor addresses\n")
5351 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5356 pim_show_neighbors_secondary(vrf
->info
, vty
);
5361 DEFUN (show_ip_pim_state
,
5362 show_ip_pim_state_cmd
,
5363 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5368 "PIM state information\n"
5369 "Unicast or Multicast address\n"
5370 "Multicast address\n"
5373 const char *src_or_group
= NULL
;
5374 const char *group
= NULL
;
5376 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5377 bool uj
= use_json(argc
, argv
);
5385 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5386 src_or_group
= argv
[idx
]->arg
;
5388 group
= argv
[idx
+ 1]->arg
;
5391 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5396 DEFUN (show_ip_pim_state_vrf_all
,
5397 show_ip_pim_state_vrf_all_cmd
,
5398 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5403 "PIM state information\n"
5404 "Unicast or Multicast address\n"
5405 "Multicast address\n"
5408 const char *src_or_group
= NULL
;
5409 const char *group
= NULL
;
5411 bool uj
= use_json(argc
, argv
);
5420 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)) {
5421 src_or_group
= argv
[idx
]->arg
;
5423 group
= argv
[idx
+ 1]->arg
;
5426 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5430 vty_out(vty
, " \"%s\": ", vrf
->name
);
5433 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5434 pim_show_state(vrf
->info
, vty
, src_or_group
, group
, uj
);
5437 vty_out(vty
, "}\n");
5442 DEFPY (show_ip_pim_upstream
,
5443 show_ip_pim_upstream_cmd
,
5444 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5449 "PIM upstream information\n"
5450 "The Source or Group\n"
5454 struct prefix_sg sg
= {0};
5457 struct pim_instance
*pim
;
5459 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
5462 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
5465 pim
= pim_get_pim_instance(v
->vrf_id
);
5468 vty_out(vty
, "%% Unable to find pim instance\n");
5472 if (s_or_g
.s_addr
!= INADDR_ANY
) {
5473 if (g
.s_addr
!= INADDR_ANY
) {
5479 pim_show_upstream(pim
, vty
, &sg
, uj
);
5484 DEFUN (show_ip_pim_upstream_vrf_all
,
5485 show_ip_pim_upstream_vrf_all_cmd
,
5486 "show ip pim vrf all upstream [json]",
5491 "PIM upstream information\n"
5494 struct prefix_sg sg
= {0};
5495 bool uj
= use_json(argc
, argv
);
5501 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5505 vty_out(vty
, " \"%s\": ", vrf
->name
);
5508 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5509 pim_show_upstream(vrf
->info
, vty
, &sg
, uj
);
5515 DEFUN (show_ip_pim_channel
,
5516 show_ip_pim_channel_cmd
,
5517 "show ip pim [vrf NAME] channel [json]",
5522 "PIM downstream channel info\n"
5526 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5527 bool uj
= use_json(argc
, argv
);
5532 pim_show_channel(vrf
->info
, vty
, uj
);
5537 DEFUN (show_ip_pim_upstream_join_desired
,
5538 show_ip_pim_upstream_join_desired_cmd
,
5539 "show ip pim [vrf NAME] upstream-join-desired [json]",
5544 "PIM upstream join-desired\n"
5548 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5549 bool uj
= use_json(argc
, argv
);
5554 pim_show_join_desired(vrf
->info
, vty
, uj
);
5559 DEFUN (show_ip_pim_upstream_rpf
,
5560 show_ip_pim_upstream_rpf_cmd
,
5561 "show ip pim [vrf NAME] upstream-rpf [json]",
5566 "PIM upstream source rpf\n"
5570 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5571 bool uj
= use_json(argc
, argv
);
5576 pim_show_upstream_rpf(vrf
->info
, vty
, uj
);
5581 DEFUN (show_ip_pim_rp
,
5583 "show ip pim [vrf NAME] rp-info [json]",
5588 "PIM RP information\n"
5592 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5593 bool uj
= use_json(argc
, argv
);
5598 pim_rp_show_information(vrf
->info
, vty
, uj
);
5603 DEFUN (show_ip_pim_rp_vrf_all
,
5604 show_ip_pim_rp_vrf_all_cmd
,
5605 "show ip pim vrf all rp-info [json]",
5610 "PIM RP information\n"
5613 bool uj
= use_json(argc
, argv
);
5619 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5623 vty_out(vty
, " \"%s\": ", vrf
->name
);
5626 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5627 pim_rp_show_information(vrf
->info
, vty
, uj
);
5630 vty_out(vty
, "}\n");
5635 DEFUN (show_ip_pim_rpf
,
5636 show_ip_pim_rpf_cmd
,
5637 "show ip pim [vrf NAME] rpf [json]",
5642 "PIM cached source rpf information\n"
5646 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5647 bool uj
= use_json(argc
, argv
);
5652 pim_show_rpf(vrf
->info
, vty
, uj
);
5657 DEFUN (show_ip_pim_rpf_vrf_all
,
5658 show_ip_pim_rpf_vrf_all_cmd
,
5659 "show ip pim vrf all rpf [json]",
5664 "PIM cached source rpf information\n"
5667 bool uj
= use_json(argc
, argv
);
5673 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
5677 vty_out(vty
, " \"%s\": ", vrf
->name
);
5680 vty_out(vty
, "VRF: %s\n", vrf
->name
);
5681 pim_show_rpf(vrf
->info
, vty
, uj
);
5684 vty_out(vty
, "}\n");
5689 DEFUN (show_ip_pim_nexthop
,
5690 show_ip_pim_nexthop_cmd
,
5691 "show ip pim [vrf NAME] nexthop",
5696 "PIM cached nexthop rpf information\n")
5699 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5704 pim_show_nexthop(vrf
->info
, vty
);
5709 DEFUN (show_ip_pim_nexthop_lookup
,
5710 show_ip_pim_nexthop_lookup_cmd
,
5711 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5716 "PIM cached nexthop rpf lookup\n"
5717 "Source/RP address\n"
5718 "Multicast Group address\n")
5720 struct prefix nht_p
;
5722 struct in_addr src_addr
, grp_addr
;
5723 struct in_addr vif_source
;
5724 const char *addr_str
, *addr_str1
;
5726 struct pim_nexthop nexthop
;
5727 char nexthop_addr_str
[PREFIX_STRLEN
];
5728 char grp_str
[PREFIX_STRLEN
];
5730 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5735 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5736 addr_str
= argv
[idx
]->arg
;
5737 result
= inet_pton(AF_INET
, addr_str
, &src_addr
);
5739 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5740 errno
, safe_strerror(errno
));
5744 if (pim_is_group_224_4(src_addr
)) {
5746 "Invalid argument. Expected Valid Source Address.\n");
5750 addr_str1
= argv
[idx
+ 1]->arg
;
5751 result
= inet_pton(AF_INET
, addr_str1
, &grp_addr
);
5753 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
5754 errno
, safe_strerror(errno
));
5758 if (!pim_is_group_224_4(grp_addr
)) {
5760 "Invalid argument. Expected Valid Multicast Group Address.\n");
5764 if (!pim_rp_set_upstream_addr(vrf
->info
, &vif_source
, src_addr
,
5768 nht_p
.family
= AF_INET
;
5769 nht_p
.prefixlen
= IPV4_MAX_BITLEN
;
5770 nht_p
.u
.prefix4
= vif_source
;
5771 grp
.family
= AF_INET
;
5772 grp
.prefixlen
= IPV4_MAX_BITLEN
;
5773 grp
.u
.prefix4
= grp_addr
;
5774 memset(&nexthop
, 0, sizeof(nexthop
));
5776 result
= pim_ecmp_nexthop_lookup(vrf
->info
, &nexthop
, &nht_p
, &grp
, 0);
5780 "Nexthop Lookup failed, no usable routes returned.\n");
5784 pim_addr_dump("<grp?>", &grp
, grp_str
, sizeof(grp_str
));
5785 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
5786 nexthop_addr_str
, sizeof(nexthop_addr_str
));
5787 vty_out(vty
, "Group %s --- Nexthop %s Interface %s \n", grp_str
,
5788 nexthop_addr_str
, nexthop
.interface
->name
);
5793 DEFUN (show_ip_pim_interface_traffic
,
5794 show_ip_pim_interface_traffic_cmd
,
5795 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5800 "PIM interface information\n"
5801 "Protocol Packet counters\n"
5806 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5807 bool uj
= use_json(argc
, argv
);
5812 if (argv_find(argv
, argc
, "WORD", &idx
))
5813 pim_show_interface_traffic_single(vrf
->info
, vty
,
5814 argv
[idx
]->arg
, uj
);
5816 pim_show_interface_traffic(vrf
->info
, vty
, uj
);
5821 DEFUN (show_ip_pim_bsm_db
,
5822 show_ip_pim_bsm_db_cmd
,
5823 "show ip pim bsm-database [vrf NAME] [json]",
5827 "PIM cached bsm packets information\n"
5832 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5833 bool uj
= use_json(argc
, argv
);
5838 pim_show_bsm_db(vrf
->info
, vty
, uj
);
5842 DEFUN (show_ip_pim_bsrp
,
5843 show_ip_pim_bsrp_cmd
,
5844 "show ip pim bsrp-info [vrf NAME] [json]",
5848 "PIM cached group-rp mappings information\n"
5853 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5854 bool uj
= use_json(argc
, argv
);
5859 pim_show_group_rp_mappings_info(vrf
->info
, vty
, uj
);
5864 DEFUN (show_ip_pim_statistics
,
5865 show_ip_pim_statistics_cmd
,
5866 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5877 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
5878 bool uj
= use_json(argc
, argv
);
5883 if (argv_find(argv
, argc
, "WORD", &idx
))
5884 pim_show_statistics(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
5886 pim_show_statistics(vrf
->info
, vty
, NULL
, uj
);
5891 static void show_multicast_interfaces(struct pim_instance
*pim
, struct vty
*vty
,
5894 struct interface
*ifp
;
5895 char buf
[PREFIX_STRLEN
];
5896 json_object
*json
= NULL
;
5897 json_object
*json_row
= NULL
;
5902 json
= json_object_new_object();
5905 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5907 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
5908 struct pim_interface
*pim_ifp
;
5909 struct in_addr ifaddr
;
5910 struct sioc_vif_req vreq
;
5912 pim_ifp
= ifp
->info
;
5917 memset(&vreq
, 0, sizeof(vreq
));
5918 vreq
.vifi
= pim_ifp
->mroute_vif_index
;
5920 if (ioctl(pim
->mroute_socket
, SIOCGETVIFCNT
, &vreq
)) {
5922 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5923 (unsigned long)SIOCGETVIFCNT
, ifp
->name
,
5924 pim_ifp
->mroute_vif_index
, errno
,
5925 safe_strerror(errno
));
5928 ifaddr
= pim_ifp
->primary_address
;
5930 json_row
= json_object_new_object();
5931 json_object_string_add(json_row
, "name", ifp
->name
);
5932 json_object_string_add(json_row
, "state",
5933 if_is_up(ifp
) ? "up" : "down");
5934 json_object_string_add(
5935 json_row
, "address",
5936 inet_ntop(AF_INET
, &pim_ifp
->primary_address
,
5938 json_object_int_add(json_row
, "ifIndex", ifp
->ifindex
);
5939 json_object_int_add(json_row
, "vif",
5940 pim_ifp
->mroute_vif_index
);
5941 json_object_int_add(json_row
, "pktsIn",
5942 (unsigned long)vreq
.icount
);
5943 json_object_int_add(json_row
, "pktsOut",
5944 (unsigned long)vreq
.ocount
);
5945 json_object_int_add(json_row
, "bytesIn",
5946 (unsigned long)vreq
.ibytes
);
5947 json_object_int_add(json_row
, "bytesOut",
5948 (unsigned long)vreq
.obytes
);
5949 json_object_object_add(json
, ifp
->name
, json_row
);
5952 "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5954 inet_ntop(AF_INET
, &ifaddr
, buf
, sizeof(buf
)),
5955 ifp
->ifindex
, pim_ifp
->mroute_vif_index
,
5956 (unsigned long)vreq
.icount
,
5957 (unsigned long)vreq
.ocount
,
5958 (unsigned long)vreq
.ibytes
,
5959 (unsigned long)vreq
.obytes
);
5964 vty_out(vty
, "%s\n",
5965 json_object_to_json_string_ext(
5966 json
, JSON_C_TO_STRING_PRETTY
));
5967 json_object_free(json
);
5971 static void pim_cmd_show_ip_multicast_helper(struct pim_instance
*pim
,
5974 struct vrf
*vrf
= pim
->vrf
;
5975 time_t now
= pim_time_monotonic_sec();
5981 vty_out(vty
, "Router MLAG Role: %s\n",
5982 mlag_role2str(router
->mlag_role
, mlag_role
, sizeof(mlag_role
)));
5983 vty_out(vty
, "Mroute socket descriptor:");
5985 vty_out(vty
, " %d(%s)\n", pim
->mroute_socket
, vrf
->name
);
5987 pim_time_uptime(uptime
, sizeof(uptime
),
5988 now
- pim
->mroute_socket_creation
);
5989 vty_out(vty
, "Mroute socket uptime: %s\n", uptime
);
5993 pim_zebra_zclient_update(vty
);
5994 pim_zlookup_show_ip_multicast(vty
);
5997 vty_out(vty
, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS
);
6000 vty_out(vty
, "Upstream Join Timer: %d secs\n", router
->t_periodic
);
6001 vty_out(vty
, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME
);
6002 vty_out(vty
, "PIM ECMP: %s\n", pim
->ecmp_enable
? "Enable" : "Disable");
6003 vty_out(vty
, "PIM ECMP Rebalance: %s\n",
6004 pim
->ecmp_rebalance_enable
? "Enable" : "Disable");
6008 show_rpf_refresh_stats(vty
, pim
, now
, NULL
);
6012 show_scan_oil_stats(pim
, vty
, now
);
6014 show_multicast_interfaces(pim
, vty
, false);
6017 DEFUN (show_ip_multicast
,
6018 show_ip_multicast_cmd
,
6019 "show ip multicast [vrf NAME]",
6023 "Multicast global information\n")
6026 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6031 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
6036 DEFUN (show_ip_multicast_vrf_all
,
6037 show_ip_multicast_vrf_all_cmd
,
6038 "show ip multicast vrf all",
6042 "Multicast global information\n")
6044 bool uj
= use_json(argc
, argv
);
6050 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6054 vty_out(vty
, " \"%s\": ", vrf
->name
);
6057 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6058 pim_cmd_show_ip_multicast_helper(vrf
->info
, vty
);
6061 vty_out(vty
, "}\n");
6066 DEFUN(show_ip_multicast_count
,
6067 show_ip_multicast_count_cmd
,
6068 "show ip multicast count [vrf NAME] [json]",
6070 "Multicast global information\n"
6071 "Data packet count\n"
6072 VRF_CMD_HELP_STR JSON_STR
)
6075 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6076 bool uj
= use_json(argc
, argv
);
6081 show_multicast_interfaces(vrf
->info
, vty
, uj
);
6086 DEFUN(show_ip_multicast_count_vrf_all
,
6087 show_ip_multicast_count_vrf_all_cmd
,
6088 "show ip multicast count vrf all [json]",
6090 "Multicast global information\n"
6091 "Data packet count\n"
6092 VRF_CMD_HELP_STR JSON_STR
)
6094 bool uj
= use_json(argc
, argv
);
6101 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6106 vty_out(vty
, " \"%s\": ", vrf
->name
);
6109 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6111 show_multicast_interfaces(vrf
->info
, vty
, uj
);
6115 vty_out(vty
, "}\n");
6120 static void show_mroute(struct pim_instance
*pim
, struct vty
*vty
,
6121 struct prefix_sg
*sg
, bool fill
, bool uj
)
6123 struct listnode
*node
;
6124 struct channel_oil
*c_oil
;
6125 struct static_route
*s_route
;
6127 json_object
*json
= NULL
;
6128 json_object
*json_group
= NULL
;
6129 json_object
*json_source
= NULL
;
6130 json_object
*json_oil
= NULL
;
6131 json_object
*json_ifp_out
= NULL
;
6134 char grp_str
[INET_ADDRSTRLEN
];
6135 char src_str
[INET_ADDRSTRLEN
];
6136 char in_ifname
[INTERFACE_NAMSIZ
+ 1];
6137 char out_ifname
[INTERFACE_NAMSIZ
+ 1];
6139 struct interface
*ifp_in
;
6141 char state_str
[PIM_REG_STATE_STR_LEN
];
6142 char mroute_uptime
[10];
6145 json
= json_object_new_object();
6147 vty_out(vty
, "IP Multicast Routing Table\n");
6148 vty_out(vty
, "Flags: S - Sparse, C - Connected, P - Pruned\n");
6150 " R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n");
6152 "\nSource Group Flags Proto Input Output TTL Uptime\n");
6155 now
= pim_time_monotonic_sec();
6157 /* print list of PIM and IGMP routes */
6158 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6161 if (!c_oil
->installed
)
6164 if (sg
->grp
.s_addr
!= INADDR_ANY
6165 && sg
->grp
.s_addr
!= c_oil
->oil
.mfcc_mcastgrp
.s_addr
)
6167 if (sg
->src
.s_addr
!= INADDR_ANY
6168 && sg
->src
.s_addr
!= c_oil
->oil
.mfcc_origin
.s_addr
)
6171 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, grp_str
,
6173 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, src_str
,
6176 strlcpy(state_str
, "S", sizeof(state_str
));
6177 /* When a non DR receives a igmp join, it creates a (*,G)
6178 * channel_oil without any upstream creation */
6180 if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil
->up
->flags
))
6181 strlcat(state_str
, "C", sizeof(state_str
));
6182 if (pim_upstream_is_sg_rpt(c_oil
->up
))
6183 strlcat(state_str
, "R", sizeof(state_str
));
6184 if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil
->up
->flags
))
6185 strlcat(state_str
, "F", sizeof(state_str
));
6186 if (c_oil
->up
->sptbit
== PIM_UPSTREAM_SPTBIT_TRUE
)
6187 strlcat(state_str
, "T", sizeof(state_str
));
6189 if (pim_channel_oil_empty(c_oil
))
6190 strlcat(state_str
, "P", sizeof(state_str
));
6192 ifp_in
= pim_if_find_by_vif_index(pim
, c_oil
->oil
.mfcc_parent
);
6195 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6197 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6200 pim_time_uptime(mroute_uptime
, sizeof(mroute_uptime
),
6201 now
- c_oil
->mroute_creation
);
6205 /* Find the group, create it if it doesn't exist */
6206 json_object_object_get_ex(json
, grp_str
, &json_group
);
6209 json_group
= json_object_new_object();
6210 json_object_object_add(json
, grp_str
,
6214 /* Find the source nested under the group, create it if
6217 json_object_object_get_ex(json_group
, src_str
,
6221 json_source
= json_object_new_object();
6222 json_object_object_add(json_group
, src_str
,
6226 /* Find the inbound interface nested under the source,
6227 * create it if it doesn't exist */
6228 json_object_int_add(json_source
, "installed",
6230 json_object_int_add(json_source
, "refCount",
6231 c_oil
->oil_ref_count
);
6232 json_object_int_add(json_source
, "oilSize",
6234 json_object_int_add(json_source
, "OilInheritedRescan",
6235 c_oil
->oil_inherited_rescan
);
6236 json_object_string_add(json_source
, "iif", in_ifname
);
6237 json_object_string_add(json_source
, "upTime",
6242 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6244 struct interface
*ifp_out
;
6247 ttl
= c_oil
->oil
.mfcc_ttls
[oif_vif_index
];
6251 /* do not display muted OIFs */
6252 if (c_oil
->oif_flags
[oif_vif_index
]
6253 & PIM_OIF_FLAG_MUTE
)
6256 if (c_oil
->oil
.mfcc_parent
== oif_vif_index
&&
6257 !pim_mroute_allow_iif_in_oil(c_oil
,
6261 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6265 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6267 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6270 json_ifp_out
= json_object_new_object();
6271 json_object_string_add(json_ifp_out
, "source",
6273 json_object_string_add(json_ifp_out
, "group",
6276 if (c_oil
->oif_flags
[oif_vif_index
]
6277 & PIM_OIF_FLAG_PROTO_PIM
)
6278 json_object_boolean_true_add(
6279 json_ifp_out
, "protocolPim");
6281 if (c_oil
->oif_flags
[oif_vif_index
]
6282 & PIM_OIF_FLAG_PROTO_IGMP
)
6283 json_object_boolean_true_add(
6284 json_ifp_out
, "protocolIgmp");
6286 if (c_oil
->oif_flags
[oif_vif_index
]
6287 & PIM_OIF_FLAG_PROTO_VXLAN
)
6288 json_object_boolean_true_add(
6289 json_ifp_out
, "protocolVxlan");
6291 if (c_oil
->oif_flags
[oif_vif_index
]
6292 & PIM_OIF_FLAG_PROTO_STAR
)
6293 json_object_boolean_true_add(
6295 "protocolInherited");
6297 json_object_string_add(json_ifp_out
,
6300 json_object_int_add(json_ifp_out
, "iVifI",
6301 c_oil
->oil
.mfcc_parent
);
6302 json_object_string_add(json_ifp_out
,
6303 "outboundInterface",
6305 json_object_int_add(json_ifp_out
, "oVifI",
6307 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6308 json_object_string_add(json_ifp_out
, "upTime",
6310 json_object_string_add(json_source
, "flags",
6313 json_oil
= json_object_new_object();
6314 json_object_object_add(json_source
,
6317 json_object_object_add(json_oil
, out_ifname
,
6321 if (c_oil
->oif_flags
[oif_vif_index
]
6322 & PIM_OIF_FLAG_PROTO_PIM
) {
6323 strlcpy(proto
, "PIM", sizeof(proto
));
6326 if (c_oil
->oif_flags
[oif_vif_index
]
6327 & PIM_OIF_FLAG_PROTO_IGMP
) {
6328 strlcpy(proto
, "IGMP", sizeof(proto
));
6331 if (c_oil
->oif_flags
[oif_vif_index
]
6332 & PIM_OIF_FLAG_PROTO_VXLAN
) {
6333 strlcpy(proto
, "VxLAN", sizeof(proto
));
6336 if (c_oil
->oif_flags
[oif_vif_index
]
6337 & PIM_OIF_FLAG_PROTO_STAR
) {
6338 strlcpy(proto
, "STAR", sizeof(proto
));
6342 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6343 src_str
, grp_str
, state_str
, proto
,
6344 in_ifname
, out_ifname
, ttl
,
6350 in_ifname
[0] = '\0';
6351 state_str
[0] = '\0';
6352 mroute_uptime
[0] = '\0';
6358 if (!uj
&& !found_oif
) {
6360 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6361 src_str
, grp_str
, state_str
, "none", in_ifname
,
6362 "none", 0, "--:--:--");
6366 /* Print list of static routes */
6367 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6370 if (!s_route
->c_oil
.installed
)
6373 pim_inet4_dump("<group?>", s_route
->group
, grp_str
,
6375 pim_inet4_dump("<source?>", s_route
->source
, src_str
,
6377 ifp_in
= pim_if_find_by_vif_index(pim
, s_route
->iif
);
6381 strlcpy(in_ifname
, ifp_in
->name
, sizeof(in_ifname
));
6383 strlcpy(in_ifname
, "<iif?>", sizeof(in_ifname
));
6387 /* Find the group, create it if it doesn't exist */
6388 json_object_object_get_ex(json
, grp_str
, &json_group
);
6391 json_group
= json_object_new_object();
6392 json_object_object_add(json
, grp_str
,
6396 /* Find the source nested under the group, create it if
6397 * it doesn't exist */
6398 json_object_object_get_ex(json_group
, src_str
,
6402 json_source
= json_object_new_object();
6403 json_object_object_add(json_group
, src_str
,
6407 json_object_string_add(json_source
, "iif", in_ifname
);
6410 strlcpy(proto
, "STATIC", sizeof(proto
));
6413 for (oif_vif_index
= 0; oif_vif_index
< MAXVIFS
;
6415 struct interface
*ifp_out
;
6416 char oif_uptime
[10];
6419 ttl
= s_route
->oif_ttls
[oif_vif_index
];
6423 ifp_out
= pim_if_find_by_vif_index(pim
, oif_vif_index
);
6425 oif_uptime
, sizeof(oif_uptime
),
6428 .oif_creation
[oif_vif_index
]);
6432 strlcpy(out_ifname
, ifp_out
->name
, sizeof(out_ifname
));
6434 strlcpy(out_ifname
, "<oif?>", sizeof(out_ifname
));
6437 json_ifp_out
= json_object_new_object();
6438 json_object_string_add(json_ifp_out
, "source",
6440 json_object_string_add(json_ifp_out
, "group",
6442 json_object_boolean_true_add(json_ifp_out
,
6444 json_object_string_add(json_ifp_out
,
6447 json_object_int_add(
6448 json_ifp_out
, "iVifI",
6449 s_route
->c_oil
.oil
.mfcc_parent
);
6450 json_object_string_add(json_ifp_out
,
6451 "outboundInterface",
6453 json_object_int_add(json_ifp_out
, "oVifI",
6455 json_object_int_add(json_ifp_out
, "ttl", ttl
);
6456 json_object_string_add(json_ifp_out
, "upTime",
6459 json_oil
= json_object_new_object();
6460 json_object_object_add(json_source
,
6463 json_object_object_add(json_oil
, out_ifname
,
6467 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6468 src_str
, grp_str
, "-", proto
, in_ifname
,
6469 out_ifname
, ttl
, oif_uptime
);
6470 if (first
&& !fill
) {
6473 in_ifname
[0] = '\0';
6479 if (!uj
&& !found_oif
) {
6481 "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
6482 src_str
, grp_str
, "-", proto
, in_ifname
, "none",
6488 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
6489 json
, JSON_C_TO_STRING_PRETTY
));
6490 json_object_free(json
);
6494 DEFPY (show_ip_mroute
,
6496 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6501 "The Source or Group\n"
6503 "Fill in Assumed data\n"
6506 struct prefix_sg sg
= {0};
6507 struct pim_instance
*pim
;
6510 v
= vrf_lookup_by_name(vrf
? vrf
: VRF_DEFAULT_NAME
);
6513 vty_out(vty
, "%% Vrf specified: %s does not exist\n", vrf
);
6516 pim
= pim_get_pim_instance(v
->vrf_id
);
6519 vty_out(vty
, "%% Unable to find pim instance\n");
6523 if (s_or_g
.s_addr
!= INADDR_ANY
) {
6524 if (g
.s_addr
!= INADDR_ANY
) {
6530 show_mroute(pim
, vty
, &sg
, !!fill
, !!json
);
6534 DEFUN (show_ip_mroute_vrf_all
,
6535 show_ip_mroute_vrf_all_cmd
,
6536 "show ip mroute vrf all [fill] [json]",
6541 "Fill in Assumed data\n"
6544 struct prefix_sg sg
= {0};
6545 bool uj
= use_json(argc
, argv
);
6551 if (argv_find(argv
, argc
, "fill", &idx
))
6556 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6560 vty_out(vty
, " \"%s\": ", vrf
->name
);
6563 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6564 show_mroute(vrf
->info
, vty
, &sg
, fill
, uj
);
6567 vty_out(vty
, "}\n");
6572 DEFUN (clear_ip_mroute_count
,
6573 clear_ip_mroute_count_cmd
,
6574 "clear ip mroute [vrf NAME] count",
6579 "Route and packet count data\n")
6582 struct listnode
*node
;
6583 struct channel_oil
*c_oil
;
6584 struct static_route
*sr
;
6585 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6586 struct pim_instance
*pim
;
6592 frr_each(rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6593 if (!c_oil
->installed
)
6596 pim_mroute_update_counters(c_oil
);
6597 c_oil
->cc
.origpktcnt
= c_oil
->cc
.pktcnt
;
6598 c_oil
->cc
.origbytecnt
= c_oil
->cc
.bytecnt
;
6599 c_oil
->cc
.origwrong_if
= c_oil
->cc
.wrong_if
;
6602 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
)) {
6603 if (!sr
->c_oil
.installed
)
6606 pim_mroute_update_counters(&sr
->c_oil
);
6608 sr
->c_oil
.cc
.origpktcnt
= sr
->c_oil
.cc
.pktcnt
;
6609 sr
->c_oil
.cc
.origbytecnt
= sr
->c_oil
.cc
.bytecnt
;
6610 sr
->c_oil
.cc
.origwrong_if
= sr
->c_oil
.cc
.wrong_if
;
6615 static void show_mroute_count_per_channel_oil(struct channel_oil
*c_oil
,
6619 char group_str
[INET_ADDRSTRLEN
];
6620 char source_str
[INET_ADDRSTRLEN
];
6621 json_object
*json_group
= NULL
;
6622 json_object
*json_source
= NULL
;
6624 if (!c_oil
->installed
)
6627 pim_mroute_update_counters(c_oil
);
6629 pim_inet4_dump("<group?>", c_oil
->oil
.mfcc_mcastgrp
, group_str
,
6631 pim_inet4_dump("<source?>", c_oil
->oil
.mfcc_origin
, source_str
,
6632 sizeof(source_str
));
6635 json_object_object_get_ex(json
, group_str
, &json_group
);
6638 json_group
= json_object_new_object();
6639 json_object_object_add(json
, group_str
, json_group
);
6642 json_source
= json_object_new_object();
6643 json_object_object_add(json_group
, source_str
, json_source
);
6644 json_object_int_add(json_source
, "lastUsed",
6645 c_oil
->cc
.lastused
/ 100);
6646 json_object_int_add(json_source
, "packets", c_oil
->cc
.pktcnt
);
6647 json_object_int_add(json_source
, "bytes", c_oil
->cc
.bytecnt
);
6648 json_object_int_add(json_source
, "wrongIf", c_oil
->cc
.wrong_if
);
6651 vty_out(vty
, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6652 source_str
, group_str
, c_oil
->cc
.lastused
/ 100,
6653 c_oil
->cc
.pktcnt
- c_oil
->cc
.origpktcnt
,
6654 c_oil
->cc
.bytecnt
- c_oil
->cc
.origbytecnt
,
6655 c_oil
->cc
.wrong_if
- c_oil
->cc
.origwrong_if
);
6659 static void show_mroute_count(struct pim_instance
*pim
, struct vty
*vty
,
6662 struct listnode
*node
;
6663 struct channel_oil
*c_oil
;
6664 struct static_route
*sr
;
6665 json_object
*json
= NULL
;
6668 json
= json_object_new_object();
6673 "Source Group LastUsed Packets Bytes WrongIf \n");
6676 /* Print PIM and IGMP route counts */
6677 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
)
6678 show_mroute_count_per_channel_oil(c_oil
, json
, vty
);
6680 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, sr
))
6681 show_mroute_count_per_channel_oil(&sr
->c_oil
, json
, vty
);
6684 vty_out(vty
, "%s\n",
6685 json_object_to_json_string_ext(
6686 json
, JSON_C_TO_STRING_PRETTY
));
6687 json_object_free(json
);
6691 DEFUN (show_ip_mroute_count
,
6692 show_ip_mroute_count_cmd
,
6693 "show ip mroute [vrf NAME] count [json]",
6698 "Route and packet count data\n"
6702 bool uj
= use_json(argc
, argv
);
6703 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6708 show_mroute_count(vrf
->info
, vty
, uj
);
6712 DEFUN (show_ip_mroute_count_vrf_all
,
6713 show_ip_mroute_count_vrf_all_cmd
,
6714 "show ip mroute vrf all count [json]",
6719 "Route and packet count data\n"
6722 bool uj
= use_json(argc
, argv
);
6728 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6732 vty_out(vty
, " \"%s\": ", vrf
->name
);
6735 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6736 show_mroute_count(vrf
->info
, vty
, uj
);
6739 vty_out(vty
, "}\n");
6744 static void show_mroute_summary(struct pim_instance
*pim
, struct vty
*vty
,
6747 struct listnode
*node
;
6748 struct channel_oil
*c_oil
;
6749 struct static_route
*s_route
;
6750 uint32_t starg_sw_mroute_cnt
= 0;
6751 uint32_t sg_sw_mroute_cnt
= 0;
6752 uint32_t starg_hw_mroute_cnt
= 0;
6753 uint32_t sg_hw_mroute_cnt
= 0;
6754 json_object
*json_starg
= NULL
;
6755 json_object
*json_sg
= NULL
;
6758 vty_out(vty
, "Mroute Type Installed/Total\n");
6760 frr_each (rb_pim_oil
, &pim
->channel_oil_head
, c_oil
) {
6761 if (!c_oil
->installed
) {
6762 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6763 starg_sw_mroute_cnt
++;
6767 if (c_oil
->oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6768 starg_hw_mroute_cnt
++;
6774 for (ALL_LIST_ELEMENTS_RO(pim
->static_routes
, node
, s_route
)) {
6775 if (!s_route
->c_oil
.installed
) {
6776 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6777 starg_sw_mroute_cnt
++;
6781 if (s_route
->c_oil
.oil
.mfcc_origin
.s_addr
== INADDR_ANY
)
6782 starg_hw_mroute_cnt
++;
6789 vty_out(vty
, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt
,
6790 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6791 vty_out(vty
, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt
,
6792 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6793 vty_out(vty
, "------\n");
6794 vty_out(vty
, "%-20s %u/%u\n", "Total",
6795 (starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
),
6796 (starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6797 + sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
));
6799 /* (*,G) route details */
6800 json_starg
= json_object_new_object();
6801 json_object_object_add(json
, "wildcardGroup", json_starg
);
6803 json_object_int_add(json_starg
, "installed",
6804 starg_hw_mroute_cnt
);
6805 json_object_int_add(json_starg
, "total",
6806 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
);
6808 /* (S, G) route details */
6809 json_sg
= json_object_new_object();
6810 json_object_object_add(json
, "sourceGroup", json_sg
);
6812 json_object_int_add(json_sg
, "installed", sg_hw_mroute_cnt
);
6813 json_object_int_add(json_sg
, "total",
6814 sg_sw_mroute_cnt
+ sg_hw_mroute_cnt
);
6816 json_object_int_add(json
, "totalNumOfInstalledMroutes",
6817 starg_hw_mroute_cnt
+ sg_hw_mroute_cnt
);
6818 json_object_int_add(json
, "totalNumOfMroutes",
6819 starg_sw_mroute_cnt
+ starg_hw_mroute_cnt
6821 + sg_hw_mroute_cnt
);
6825 DEFUN (show_ip_mroute_summary
,
6826 show_ip_mroute_summary_cmd
,
6827 "show ip mroute [vrf NAME] summary [json]",
6832 "Summary of all mroutes\n"
6836 bool uj
= use_json(argc
, argv
);
6837 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6838 json_object
*json
= NULL
;
6841 json
= json_object_new_object();
6846 show_mroute_summary(vrf
->info
, vty
, json
);
6849 vty_out(vty
, "%s\n",
6850 json_object_to_json_string_ext(
6851 json
, JSON_C_TO_STRING_PRETTY
));
6852 json_object_free(json
);
6857 DEFUN (show_ip_mroute_summary_vrf_all
,
6858 show_ip_mroute_summary_vrf_all_cmd
,
6859 "show ip mroute vrf all summary [json]",
6864 "Summary of all mroutes\n"
6868 bool uj
= use_json(argc
, argv
);
6869 json_object
*json
= NULL
;
6870 json_object
*json_vrf
= NULL
;
6873 json
= json_object_new_object();
6875 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
6877 json_vrf
= json_object_new_object();
6879 vty_out(vty
, "VRF: %s\n", vrf
->name
);
6881 show_mroute_summary(vrf
->info
, vty
, json_vrf
);
6884 json_object_object_add(json
, vrf
->name
, json_vrf
);
6888 vty_out(vty
, "%s\n",
6889 json_object_to_json_string_ext(
6890 json
, JSON_C_TO_STRING_PRETTY
));
6891 json_object_free(json
);
6899 "show ip rib [vrf NAME] A.B.C.D",
6904 "Unicast address\n")
6907 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
6908 struct in_addr addr
;
6909 const char *addr_str
;
6910 struct pim_nexthop nexthop
;
6911 char nexthop_addr_str
[PREFIX_STRLEN
];
6917 memset(&nexthop
, 0, sizeof(nexthop
));
6918 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6919 addr_str
= argv
[idx
]->arg
;
6920 result
= inet_pton(AF_INET
, addr_str
, &addr
);
6922 vty_out(vty
, "Bad unicast address %s: errno=%d: %s\n", addr_str
,
6923 errno
, safe_strerror(errno
));
6927 if (!pim_nexthop_lookup(vrf
->info
, &nexthop
, addr
, 0)) {
6929 "Failure querying RIB nexthop for unicast address %s\n",
6935 "Address NextHop Interface Metric Preference\n");
6937 pim_addr_dump("<nexthop?>", &nexthop
.mrib_nexthop_addr
,
6938 nexthop_addr_str
, sizeof(nexthop_addr_str
));
6940 vty_out(vty
, "%-15s %-15s %-9s %6d %10d\n", addr_str
, nexthop_addr_str
,
6941 nexthop
.interface
? nexthop
.interface
->name
: "<ifname?>",
6942 nexthop
.mrib_route_metric
, nexthop
.mrib_metric_preference
);
6947 static void show_ssmpingd(struct pim_instance
*pim
, struct vty
*vty
)
6949 struct listnode
*node
;
6950 struct ssmpingd_sock
*ss
;
6954 "Source Socket Address Port Uptime Requests\n");
6956 if (!pim
->ssmpingd_list
)
6959 now
= pim_time_monotonic_sec();
6961 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
6962 char source_str
[INET_ADDRSTRLEN
];
6964 struct sockaddr_in bind_addr
;
6965 socklen_t len
= sizeof(bind_addr
);
6966 char bind_addr_str
[INET_ADDRSTRLEN
];
6968 pim_inet4_dump("<src?>", ss
->source_addr
, source_str
,
6969 sizeof(source_str
));
6971 if (pim_socket_getsockname(
6972 ss
->sock_fd
, (struct sockaddr
*)&bind_addr
, &len
)) {
6974 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6975 source_str
, ss
->sock_fd
);
6978 pim_inet4_dump("<addr?>", bind_addr
.sin_addr
, bind_addr_str
,
6979 sizeof(bind_addr_str
));
6980 pim_time_uptime(ss_uptime
, sizeof(ss_uptime
),
6981 now
- ss
->creation
);
6983 vty_out(vty
, "%-15s %6d %-15s %5d %8s %8lld\n", source_str
,
6984 ss
->sock_fd
, bind_addr_str
, ntohs(bind_addr
.sin_port
),
6985 ss_uptime
, (long long)ss
->requests
);
6989 DEFUN (show_ip_ssmpingd
,
6990 show_ip_ssmpingd_cmd
,
6991 "show ip ssmpingd [vrf NAME]",
6998 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7003 show_ssmpingd(vrf
->info
, vty
);
7007 DEFUN (ip_pim_spt_switchover_infinity
,
7008 ip_pim_spt_switchover_infinity_cmd
,
7009 "ip pim spt-switchover infinity-and-beyond",
7013 "Never switch to SPT Tree\n")
7015 const char *vrfname
;
7016 char spt_plist_xpath
[XPATH_MAXLEN
];
7017 char spt_action_xpath
[XPATH_MAXLEN
];
7019 vrfname
= pim_cli_get_vrf_name(vty
);
7020 if (vrfname
== NULL
)
7021 return CMD_WARNING_CONFIG_FAILED
;
7023 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7024 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7025 "frr-routing:ipv4");
7026 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7027 sizeof(spt_plist_xpath
));
7029 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7030 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7031 "frr-routing:ipv4");
7032 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7033 sizeof(spt_action_xpath
));
7035 if (yang_dnode_exists(vty
->candidate_config
->dnode
, spt_plist_xpath
))
7036 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
,
7038 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7039 "PIM_SPT_INFINITY");
7041 return nb_cli_apply_changes(vty
, NULL
);
7044 DEFUN (ip_pim_spt_switchover_infinity_plist
,
7045 ip_pim_spt_switchover_infinity_plist_cmd
,
7046 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
7050 "Never switch to SPT Tree\n"
7051 "Prefix-List to control which groups to switch\n"
7052 "Prefix-List name\n")
7054 const char *vrfname
;
7055 char spt_plist_xpath
[XPATH_MAXLEN
];
7056 char spt_action_xpath
[XPATH_MAXLEN
];
7058 vrfname
= pim_cli_get_vrf_name(vty
);
7059 if (vrfname
== NULL
)
7060 return CMD_WARNING_CONFIG_FAILED
;
7062 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7063 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7064 "frr-routing:ipv4");
7065 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7066 sizeof(spt_plist_xpath
));
7068 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7069 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7070 "frr-routing:ipv4");
7071 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7072 sizeof(spt_action_xpath
));
7074 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7075 "PIM_SPT_INFINITY");
7076 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_MODIFY
,
7079 return nb_cli_apply_changes(vty
, NULL
);
7082 DEFUN (no_ip_pim_spt_switchover_infinity
,
7083 no_ip_pim_spt_switchover_infinity_cmd
,
7084 "no ip pim spt-switchover infinity-and-beyond",
7089 "Never switch to SPT Tree\n")
7091 const char *vrfname
;
7092 char spt_plist_xpath
[XPATH_MAXLEN
];
7093 char spt_action_xpath
[XPATH_MAXLEN
];
7095 vrfname
= pim_cli_get_vrf_name(vty
);
7096 if (vrfname
== NULL
)
7097 return CMD_WARNING_CONFIG_FAILED
;
7099 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7100 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7101 "frr-routing:ipv4");
7102 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7103 sizeof(spt_plist_xpath
));
7105 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7106 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7107 "frr-routing:ipv4");
7108 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7109 sizeof(spt_action_xpath
));
7111 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
, NULL
);
7112 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7113 "PIM_SPT_IMMEDIATE");
7115 return nb_cli_apply_changes(vty
, NULL
);
7118 DEFUN (no_ip_pim_spt_switchover_infinity_plist
,
7119 no_ip_pim_spt_switchover_infinity_plist_cmd
,
7120 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
7125 "Never switch to SPT Tree\n"
7126 "Prefix-List to control which groups to switch\n"
7127 "Prefix-List name\n")
7129 const char *vrfname
;
7130 char spt_plist_xpath
[XPATH_MAXLEN
];
7131 char spt_action_xpath
[XPATH_MAXLEN
];
7133 vrfname
= pim_cli_get_vrf_name(vty
);
7134 if (vrfname
== NULL
)
7135 return CMD_WARNING_CONFIG_FAILED
;
7137 snprintf(spt_plist_xpath
, sizeof(spt_plist_xpath
),
7138 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7139 "frr-routing:ipv4");
7140 strlcat(spt_plist_xpath
, "/spt-switchover/spt-infinity-prefix-list",
7141 sizeof(spt_plist_xpath
));
7143 snprintf(spt_action_xpath
, sizeof(spt_action_xpath
),
7144 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7145 "frr-routing:ipv4");
7146 strlcat(spt_action_xpath
, "/spt-switchover/spt-action",
7147 sizeof(spt_action_xpath
));
7149 nb_cli_enqueue_change(vty
, spt_plist_xpath
, NB_OP_DESTROY
, NULL
);
7150 nb_cli_enqueue_change(vty
, spt_action_xpath
, NB_OP_MODIFY
,
7151 "PIM_SPT_IMMEDIATE");
7153 return nb_cli_apply_changes(vty
, NULL
);
7156 DEFPY (pim_register_accept_list
,
7157 pim_register_accept_list_cmd
,
7158 "[no] ip pim register-accept-list WORD$word",
7162 "Only accept registers from a specific source prefix list\n"
7163 "Prefix-List name\n")
7165 const char *vrfname
;
7166 char reg_alist_xpath
[XPATH_MAXLEN
];
7168 vrfname
= pim_cli_get_vrf_name(vty
);
7169 if (vrfname
== NULL
)
7170 return CMD_WARNING_CONFIG_FAILED
;
7172 snprintf(reg_alist_xpath
, sizeof(reg_alist_xpath
),
7173 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
7174 "frr-routing:ipv4");
7175 strlcat(reg_alist_xpath
, "/register-accept-list",
7176 sizeof(reg_alist_xpath
));
7179 nb_cli_enqueue_change(vty
, reg_alist_xpath
,
7180 NB_OP_DESTROY
, NULL
);
7182 nb_cli_enqueue_change(vty
, reg_alist_xpath
,
7183 NB_OP_MODIFY
, word
);
7185 return nb_cli_apply_changes(vty
, NULL
);
7188 DEFUN (ip_pim_joinprune_time
,
7189 ip_pim_joinprune_time_cmd
,
7190 "ip pim join-prune-interval (5-600)",
7192 "pim multicast routing\n"
7193 "Join Prune Send Interval\n"
7196 nb_cli_enqueue_change(vty
, "/frr-pim:pim/join-prune-interval",
7197 NB_OP_MODIFY
, argv
[3]->arg
);
7199 return nb_cli_apply_changes(vty
, NULL
);
7202 DEFUN (no_ip_pim_joinprune_time
,
7203 no_ip_pim_joinprune_time_cmd
,
7204 "no ip pim join-prune-interval (5-600)",
7207 "pim multicast routing\n"
7208 "Join Prune Send Interval\n"
7211 char jp_default_timer
[5];
7213 snprintf(jp_default_timer
, sizeof(jp_default_timer
), "%d",
7214 PIM_DEFAULT_T_PERIODIC
);
7216 nb_cli_enqueue_change(vty
, "/frr-pim:pim/join-prune-interval",
7217 NB_OP_MODIFY
, jp_default_timer
);
7219 return nb_cli_apply_changes(vty
, NULL
);
7222 DEFUN (ip_pim_register_suppress
,
7223 ip_pim_register_suppress_cmd
,
7224 "ip pim register-suppress-time (5-60000)",
7226 "pim multicast routing\n"
7227 "Register Suppress Timer\n"
7230 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7231 NB_OP_MODIFY
, argv
[3]->arg
);
7233 return nb_cli_apply_changes(vty
, NULL
);
7236 DEFUN (no_ip_pim_register_suppress
,
7237 no_ip_pim_register_suppress_cmd
,
7238 "no ip pim register-suppress-time (5-60000)",
7241 "pim multicast routing\n"
7242 "Register Suppress Timer\n"
7245 char rs_default_timer
[5];
7247 snprintf(rs_default_timer
, sizeof(rs_default_timer
), "%d",
7248 PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
);
7250 nb_cli_enqueue_change(vty
, "/frr-pim:pim/register-suppress-time",
7251 NB_OP_MODIFY
, rs_default_timer
);
7253 return nb_cli_apply_changes(vty
, NULL
);
7256 DEFUN (ip_pim_rp_keep_alive
,
7257 ip_pim_rp_keep_alive_cmd
,
7258 "ip pim rp keep-alive-timer (31-60000)",
7260 "pim multicast routing\n"
7262 "Keep alive Timer\n"
7265 const char *vrfname
;
7266 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7268 vrfname
= pim_cli_get_vrf_name(vty
);
7269 if (vrfname
== NULL
)
7270 return CMD_WARNING_CONFIG_FAILED
;
7272 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7273 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7274 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7275 sizeof(rp_ka_timer_xpath
));
7277 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7280 return nb_cli_apply_changes(vty
, NULL
);
7283 DEFUN (no_ip_pim_rp_keep_alive
,
7284 no_ip_pim_rp_keep_alive_cmd
,
7285 "no ip pim rp keep-alive-timer (31-60000)",
7288 "pim multicast routing\n"
7290 "Keep alive Timer\n"
7293 const char *vrfname
;
7294 char rp_ka_timer
[5];
7295 char rp_ka_timer_xpath
[XPATH_MAXLEN
];
7297 snprintf(rp_ka_timer
, sizeof(rp_ka_timer
), "%d",
7298 PIM_RP_KEEPALIVE_PERIOD
);
7300 vrfname
= pim_cli_get_vrf_name(vty
);
7301 if (vrfname
== NULL
)
7302 return CMD_WARNING_CONFIG_FAILED
;
7304 snprintf(rp_ka_timer_xpath
, sizeof(rp_ka_timer_xpath
),
7305 FRR_PIM_XPATH
, "frr-pim:pimd", "pim", vrfname
);
7306 strlcat(rp_ka_timer_xpath
, "/rp-keep-alive-timer",
7307 sizeof(rp_ka_timer_xpath
));
7309 nb_cli_enqueue_change(vty
, rp_ka_timer_xpath
, NB_OP_MODIFY
,
7312 return nb_cli_apply_changes(vty
, NULL
);
7315 DEFUN (ip_pim_keep_alive
,
7316 ip_pim_keep_alive_cmd
,
7317 "ip pim keep-alive-timer (31-60000)",
7319 "pim multicast routing\n"
7320 "Keep alive Timer\n"
7323 const char *vrfname
;
7324 char ka_timer_xpath
[XPATH_MAXLEN
];
7326 vrfname
= pim_cli_get_vrf_name(vty
);
7327 if (vrfname
== NULL
)
7328 return CMD_WARNING_CONFIG_FAILED
;
7330 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7331 "frr-pim:pimd", "pim", vrfname
);
7332 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7334 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_MODIFY
,
7337 return nb_cli_apply_changes(vty
, NULL
);
7340 DEFUN (no_ip_pim_keep_alive
,
7341 no_ip_pim_keep_alive_cmd
,
7342 "no ip pim keep-alive-timer (31-60000)",
7345 "pim multicast routing\n"
7346 "Keep alive Timer\n"
7349 const char *vrfname
;
7351 char ka_timer_xpath
[XPATH_MAXLEN
];
7353 snprintf(ka_timer
, sizeof(ka_timer
), "%d", PIM_KEEPALIVE_PERIOD
);
7355 vrfname
= pim_cli_get_vrf_name(vty
);
7356 if (vrfname
== NULL
)
7357 return CMD_WARNING_CONFIG_FAILED
;
7359 snprintf(ka_timer_xpath
, sizeof(ka_timer_xpath
), FRR_PIM_XPATH
,
7360 "frr-pim:pimd", "pim", vrfname
);
7361 strlcat(ka_timer_xpath
, "/keep-alive-timer", sizeof(ka_timer_xpath
));
7363 nb_cli_enqueue_change(vty
, ka_timer_xpath
, NB_OP_MODIFY
,
7366 return nb_cli_apply_changes(vty
, NULL
);
7369 DEFUN (ip_pim_packets
,
7371 "ip pim packets (1-100)",
7373 "pim multicast routing\n"
7374 "packets to process at one time per fd\n"
7375 "Number of packets\n")
7377 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_MODIFY
,
7380 return nb_cli_apply_changes(vty
, NULL
);
7383 DEFUN (no_ip_pim_packets
,
7384 no_ip_pim_packets_cmd
,
7385 "no ip pim packets (1-100)",
7388 "pim multicast routing\n"
7389 "packets to process at one time per fd\n"
7390 "Number of packets\n")
7392 char default_packet
[3];
7394 snprintf(default_packet
, sizeof(default_packet
), "%d",
7395 PIM_DEFAULT_PACKET_PROCESS
);
7397 nb_cli_enqueue_change(vty
, "/frr-pim:pim/packets", NB_OP_MODIFY
,
7400 return nb_cli_apply_changes(vty
, NULL
);
7403 DEFPY (igmp_group_watermark
,
7404 igmp_group_watermark_cmd
,
7405 "ip igmp watermark-warn (10-60000)$limit",
7408 "Configure group limit for watermark warning\n"
7409 "Group count to generate watermark warning\n")
7411 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7412 pim
->igmp_watermark_limit
= limit
;
7417 DEFPY (no_igmp_group_watermark
,
7418 no_igmp_group_watermark_cmd
,
7419 "no ip igmp watermark-warn [(10-60000)$limit]",
7423 "Unconfigure group limit for watermark warning\n"
7424 "Group count to generate watermark warning\n")
7426 PIM_DECLVAR_CONTEXT(vrf
, pim
);
7427 pim
->igmp_watermark_limit
= 0;
7432 DEFUN (ip_pim_v6_secondary
,
7433 ip_pim_v6_secondary_cmd
,
7434 "ip pim send-v6-secondary",
7436 "pim multicast routing\n"
7437 "Send v6 secondary addresses\n")
7439 const char *vrfname
;
7440 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7442 vrfname
= pim_cli_get_vrf_name(vty
);
7443 if (vrfname
== NULL
)
7444 return CMD_WARNING_CONFIG_FAILED
;
7446 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7448 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7449 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7450 sizeof(send_v6_secondary_xpath
));
7452 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7455 return nb_cli_apply_changes(vty
, NULL
);
7458 DEFUN (no_ip_pim_v6_secondary
,
7459 no_ip_pim_v6_secondary_cmd
,
7460 "no ip pim send-v6-secondary",
7463 "pim multicast routing\n"
7464 "Send v6 secondary addresses\n")
7466 const char *vrfname
;
7467 char send_v6_secondary_xpath
[XPATH_MAXLEN
];
7469 vrfname
= pim_cli_get_vrf_name(vty
);
7470 if (vrfname
== NULL
)
7471 return CMD_WARNING_CONFIG_FAILED
;
7473 snprintf(send_v6_secondary_xpath
, sizeof(send_v6_secondary_xpath
),
7475 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7476 strlcat(send_v6_secondary_xpath
, "/send-v6-secondary",
7477 sizeof(send_v6_secondary_xpath
));
7479 nb_cli_enqueue_change(vty
, send_v6_secondary_xpath
, NB_OP_MODIFY
,
7482 return nb_cli_apply_changes(vty
, NULL
);
7487 "ip pim rp A.B.C.D [A.B.C.D/M]",
7489 "pim multicast routing\n"
7491 "ip address of RP\n"
7492 "Group Address range to cover\n")
7494 const char *vrfname
;
7495 int idx_rp
= 3, idx_group
= 4;
7496 char rp_group_xpath
[XPATH_MAXLEN
];
7498 struct prefix group
;
7499 struct in_addr rp_addr
;
7500 const char *group_str
=
7501 (argc
== 5) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7503 result
= str2prefix(group_str
, &group
);
7507 prefix_copy(&temp
, &group
);
7509 if (!prefix_same(&group
, &temp
)) {
7510 vty_out(vty
, "%% Inconsistent address and mask: %s\n",
7512 return CMD_WARNING_CONFIG_FAILED
;
7517 vty_out(vty
, "%% Bad group address specified: %s\n",
7519 return CMD_WARNING_CONFIG_FAILED
;
7522 result
= inet_pton(AF_INET
, argv
[idx_rp
]->arg
, &rp_addr
);
7524 vty_out(vty
, "%% Bad RP address specified: %s\n",
7526 return CMD_WARNING_CONFIG_FAILED
;
7529 vrfname
= pim_cli_get_vrf_name(vty
);
7530 if (vrfname
== NULL
)
7531 return CMD_WARNING_CONFIG_FAILED
;
7533 snprintf(rp_group_xpath
, sizeof(rp_group_xpath
),
7534 FRR_PIM_STATIC_RP_XPATH
,
7535 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7537 strlcat(rp_group_xpath
, "/group-list", sizeof(rp_group_xpath
));
7539 nb_cli_enqueue_change(vty
, rp_group_xpath
, NB_OP_CREATE
, group_str
);
7541 return nb_cli_apply_changes(vty
, NULL
);
7544 DEFUN (ip_pim_rp_prefix_list
,
7545 ip_pim_rp_prefix_list_cmd
,
7546 "ip pim rp A.B.C.D prefix-list WORD",
7548 "pim multicast routing\n"
7550 "ip address of RP\n"
7551 "group prefix-list filter\n"
7552 "Name of a prefix-list\n")
7554 int idx_rp
= 3, idx_plist
= 5;
7555 const char *vrfname
;
7556 char rp_plist_xpath
[XPATH_MAXLEN
];
7558 vrfname
= pim_cli_get_vrf_name(vty
);
7559 if (vrfname
== NULL
)
7560 return CMD_WARNING_CONFIG_FAILED
;
7562 snprintf(rp_plist_xpath
, sizeof(rp_plist_xpath
),
7563 FRR_PIM_STATIC_RP_XPATH
,
7564 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7566 strlcat(rp_plist_xpath
, "/prefix-list", sizeof(rp_plist_xpath
));
7568 nb_cli_enqueue_change(vty
, rp_plist_xpath
, NB_OP_MODIFY
,
7569 argv
[idx_plist
]->arg
);
7571 return nb_cli_apply_changes(vty
, NULL
);
7574 DEFUN (no_ip_pim_rp
,
7576 "no ip pim rp A.B.C.D [A.B.C.D/M]",
7579 "pim multicast routing\n"
7581 "ip address of RP\n"
7582 "Group Address range to cover\n")
7584 int idx_rp
= 4, idx_group
= 5;
7585 const char *group_str
=
7586 (argc
== 6) ? argv
[idx_group
]->arg
: "224.0.0.0/4";
7587 char group_list_xpath
[XPATH_MAXLEN
+ 32];
7588 char group_xpath
[XPATH_MAXLEN
+ 64];
7589 char rp_xpath
[XPATH_MAXLEN
];
7590 const char *vrfname
;
7591 const struct lyd_node
*group_dnode
;
7593 vrfname
= pim_cli_get_vrf_name(vty
);
7594 if (vrfname
== NULL
)
7595 return CMD_WARNING_CONFIG_FAILED
;
7597 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7598 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7601 snprintf(group_list_xpath
, sizeof(group_list_xpath
), "%s/group-list",
7604 snprintf(group_xpath
, sizeof(group_xpath
), "%s[.='%s']",
7605 group_list_xpath
, group_str
);
7607 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, group_xpath
)) {
7608 vty_out(vty
, "%% Unable to find specified RP\n");
7612 group_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, group_xpath
);
7614 if (yang_is_last_list_dnode(group_dnode
))
7615 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7617 nb_cli_enqueue_change(vty
, group_list_xpath
, NB_OP_DESTROY
,
7620 return nb_cli_apply_changes(vty
, NULL
);
7623 DEFUN (no_ip_pim_rp_prefix_list
,
7624 no_ip_pim_rp_prefix_list_cmd
,
7625 "no ip pim rp A.B.C.D prefix-list WORD",
7628 "pim multicast routing\n"
7630 "ip address of RP\n"
7631 "group prefix-list filter\n"
7632 "Name of a prefix-list\n")
7636 char rp_xpath
[XPATH_MAXLEN
];
7637 char plist_xpath
[XPATH_MAXLEN
];
7638 const char *vrfname
;
7639 const struct lyd_node
*plist_dnode
;
7642 vrfname
= pim_cli_get_vrf_name(vty
);
7643 if (vrfname
== NULL
)
7644 return CMD_WARNING_CONFIG_FAILED
;
7646 snprintf(rp_xpath
, sizeof(rp_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7647 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7650 snprintf(plist_xpath
, sizeof(plist_xpath
), FRR_PIM_STATIC_RP_XPATH
,
7651 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4",
7653 strlcat(plist_xpath
, "/prefix-list", sizeof(plist_xpath
));
7655 plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
, plist_xpath
);
7657 vty_out(vty
, "%% Unable to find specified RP\n");
7661 plist
= yang_dnode_get_string(plist_dnode
, plist_xpath
);
7662 if (strcmp(argv
[idx_plist
]->arg
, plist
)) {
7663 vty_out(vty
, "%% Unable to find specified RP\n");
7667 nb_cli_enqueue_change(vty
, rp_xpath
, NB_OP_DESTROY
, NULL
);
7669 return nb_cli_apply_changes(vty
, NULL
);
7672 DEFUN (ip_pim_ssm_prefix_list
,
7673 ip_pim_ssm_prefix_list_cmd
,
7674 "ip pim ssm prefix-list WORD",
7676 "pim multicast routing\n"
7677 "Source Specific Multicast\n"
7678 "group range prefix-list filter\n"
7679 "Name of a prefix-list\n")
7681 const char *vrfname
;
7682 char ssm_plist_xpath
[XPATH_MAXLEN
];
7684 vrfname
= pim_cli_get_vrf_name(vty
);
7685 if (vrfname
== NULL
)
7686 return CMD_WARNING_CONFIG_FAILED
;
7688 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
), FRR_PIM_AF_XPATH
,
7689 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7690 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7692 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_MODIFY
, argv
[4]->arg
);
7694 return nb_cli_apply_changes(vty
, NULL
);
7697 DEFUN (no_ip_pim_ssm_prefix_list
,
7698 no_ip_pim_ssm_prefix_list_cmd
,
7699 "no ip pim ssm prefix-list",
7702 "pim multicast routing\n"
7703 "Source Specific Multicast\n"
7704 "group range prefix-list filter\n")
7706 const char *vrfname
;
7707 char ssm_plist_xpath
[XPATH_MAXLEN
];
7709 vrfname
= pim_cli_get_vrf_name(vty
);
7710 if (vrfname
== NULL
)
7711 return CMD_WARNING_CONFIG_FAILED
;
7713 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7715 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7716 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7718 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
, NULL
);
7720 return nb_cli_apply_changes(vty
, NULL
);
7723 DEFUN (no_ip_pim_ssm_prefix_list_name
,
7724 no_ip_pim_ssm_prefix_list_name_cmd
,
7725 "no ip pim ssm prefix-list WORD",
7728 "pim multicast routing\n"
7729 "Source Specific Multicast\n"
7730 "group range prefix-list filter\n"
7731 "Name of a prefix-list\n")
7733 const char *vrfname
;
7734 const struct lyd_node
*ssm_plist_dnode
;
7735 char ssm_plist_xpath
[XPATH_MAXLEN
];
7736 const char *ssm_plist_name
;
7738 vrfname
= pim_cli_get_vrf_name(vty
);
7739 if (vrfname
== NULL
)
7740 return CMD_WARNING_CONFIG_FAILED
;
7742 snprintf(ssm_plist_xpath
, sizeof(ssm_plist_xpath
),
7744 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7745 strlcat(ssm_plist_xpath
, "/ssm-prefix-list", sizeof(ssm_plist_xpath
));
7746 ssm_plist_dnode
= yang_dnode_get(vty
->candidate_config
->dnode
,
7749 if (!ssm_plist_dnode
) {
7751 "%% pim ssm prefix-list %s doesn't exist\n",
7753 return CMD_WARNING_CONFIG_FAILED
;
7756 ssm_plist_name
= yang_dnode_get_string(ssm_plist_dnode
, ".");
7758 if (ssm_plist_name
&& !strcmp(ssm_plist_name
, argv
[5]->arg
)) {
7759 nb_cli_enqueue_change(vty
, ssm_plist_xpath
, NB_OP_DESTROY
,
7762 return nb_cli_apply_changes(vty
, NULL
);
7765 vty_out(vty
, "%% pim ssm prefix-list %s doesn't exist\n", argv
[5]->arg
);
7767 return CMD_WARNING_CONFIG_FAILED
;
7770 static void ip_pim_ssm_show_group_range(struct pim_instance
*pim
,
7771 struct vty
*vty
, bool uj
)
7773 struct pim_ssm
*ssm
= pim
->ssm_info
;
7774 const char *range_str
=
7775 ssm
->plist_name
? ssm
->plist_name
: PIM_SSM_STANDARD_RANGE
;
7779 json
= json_object_new_object();
7780 json_object_string_add(json
, "ssmGroups", range_str
);
7781 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7782 json
, JSON_C_TO_STRING_PRETTY
));
7783 json_object_free(json
);
7785 vty_out(vty
, "SSM group range : %s\n", range_str
);
7788 DEFUN (show_ip_pim_ssm_range
,
7789 show_ip_pim_ssm_range_cmd
,
7790 "show ip pim [vrf NAME] group-type [json]",
7799 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7800 bool uj
= use_json(argc
, argv
);
7805 ip_pim_ssm_show_group_range(vrf
->info
, vty
, uj
);
7810 static void ip_pim_ssm_show_group_type(struct pim_instance
*pim
,
7811 struct vty
*vty
, bool uj
,
7814 struct in_addr group_addr
;
7815 const char *type_str
;
7818 result
= inet_pton(AF_INET
, group
, &group_addr
);
7820 type_str
= "invalid";
7822 if (pim_is_group_224_4(group_addr
))
7824 pim_is_grp_ssm(pim
, group_addr
) ? "SSM" : "ASM";
7826 type_str
= "not-multicast";
7831 json
= json_object_new_object();
7832 json_object_string_add(json
, "groupType", type_str
);
7833 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
7834 json
, JSON_C_TO_STRING_PRETTY
));
7835 json_object_free(json
);
7837 vty_out(vty
, "Group type : %s\n", type_str
);
7840 DEFUN (show_ip_pim_group_type
,
7841 show_ip_pim_group_type_cmd
,
7842 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7847 "multicast group type\n"
7852 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7853 bool uj
= use_json(argc
, argv
);
7858 argv_find(argv
, argc
, "A.B.C.D", &idx
);
7859 ip_pim_ssm_show_group_type(vrf
->info
, vty
, uj
, argv
[idx
]->arg
);
7864 DEFUN (show_ip_pim_bsr
,
7865 show_ip_pim_bsr_cmd
,
7866 "show ip pim bsr [json]",
7870 "boot-strap router information\n"
7874 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
7875 bool uj
= use_json(argc
, argv
);
7880 pim_show_bsr(vrf
->info
, vty
, uj
);
7887 "ip ssmpingd [A.B.C.D]",
7893 const char *source_str
= (argc
== 3) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7894 const char *vrfname
;
7895 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7897 vrfname
= pim_cli_get_vrf_name(vty
);
7898 if (vrfname
== NULL
)
7899 return CMD_WARNING_CONFIG_FAILED
;
7901 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7903 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7904 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7905 sizeof(ssmpingd_ip_xpath
));
7907 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_CREATE
,
7910 return nb_cli_apply_changes(vty
, NULL
);
7913 DEFUN (no_ip_ssmpingd
,
7915 "no ip ssmpingd [A.B.C.D]",
7921 const char *vrfname
;
7923 const char *source_str
= (argc
== 4) ? argv
[idx_ipv4
]->arg
: "0.0.0.0";
7924 char ssmpingd_ip_xpath
[XPATH_MAXLEN
];
7926 vrfname
= pim_cli_get_vrf_name(vty
);
7927 if (vrfname
== NULL
)
7928 return CMD_WARNING_CONFIG_FAILED
;
7930 snprintf(ssmpingd_ip_xpath
, sizeof(ssmpingd_ip_xpath
),
7932 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
7933 strlcat(ssmpingd_ip_xpath
, "/ssm-pingd-source-ip",
7934 sizeof(ssmpingd_ip_xpath
));
7936 nb_cli_enqueue_change(vty
, ssmpingd_ip_xpath
, NB_OP_DESTROY
,
7939 return nb_cli_apply_changes(vty
, NULL
);
7946 "pim multicast routing\n"
7947 "Enable PIM ECMP \n")
7949 const char *vrfname
;
7950 char ecmp_xpath
[XPATH_MAXLEN
];
7952 vrfname
= pim_cli_get_vrf_name(vty
);
7953 if (vrfname
== NULL
)
7954 return CMD_WARNING_CONFIG_FAILED
;
7956 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7957 "frr-pim:pimd", "pim", vrfname
);
7958 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7960 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
7961 return nb_cli_apply_changes(vty
, NULL
);
7964 DEFUN (no_ip_pim_ecmp
,
7969 "pim multicast routing\n"
7970 "Disable PIM ECMP \n")
7972 const char *vrfname
;
7973 char ecmp_xpath
[XPATH_MAXLEN
];
7975 vrfname
= pim_cli_get_vrf_name(vty
);
7976 if (vrfname
== NULL
)
7977 return CMD_WARNING_CONFIG_FAILED
;
7979 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
7980 "frr-pim:pimd", "pim", vrfname
);
7981 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
7983 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "false");
7985 return nb_cli_apply_changes(vty
, NULL
);
7988 DEFUN (ip_pim_ecmp_rebalance
,
7989 ip_pim_ecmp_rebalance_cmd
,
7990 "ip pim ecmp rebalance",
7992 "pim multicast routing\n"
7993 "Enable PIM ECMP \n"
7994 "Enable PIM ECMP Rebalance\n")
7996 const char *vrfname
;
7997 char ecmp_xpath
[XPATH_MAXLEN
];
7998 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
8000 vrfname
= pim_cli_get_vrf_name(vty
);
8001 if (vrfname
== NULL
)
8002 return CMD_WARNING_CONFIG_FAILED
;
8004 snprintf(ecmp_xpath
, sizeof(ecmp_xpath
), FRR_PIM_XPATH
,
8005 "frr-pim:pimd", "pim", vrfname
);
8006 strlcat(ecmp_xpath
, "/ecmp", sizeof(ecmp_xpath
));
8007 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
8009 "frr-pim:pimd", "pim", vrfname
);
8010 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
8011 sizeof(ecmp_rebalance_xpath
));
8013 nb_cli_enqueue_change(vty
, ecmp_xpath
, NB_OP_MODIFY
, "true");
8014 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "true");
8016 return nb_cli_apply_changes(vty
, NULL
);
8019 DEFUN (no_ip_pim_ecmp_rebalance
,
8020 no_ip_pim_ecmp_rebalance_cmd
,
8021 "no ip pim ecmp rebalance",
8024 "pim multicast routing\n"
8025 "Disable PIM ECMP \n"
8026 "Disable PIM ECMP Rebalance\n")
8028 const char *vrfname
;
8029 char ecmp_rebalance_xpath
[XPATH_MAXLEN
];
8031 vrfname
= pim_cli_get_vrf_name(vty
);
8032 if (vrfname
== NULL
)
8033 return CMD_WARNING_CONFIG_FAILED
;
8035 snprintf(ecmp_rebalance_xpath
, sizeof(ecmp_rebalance_xpath
),
8037 "frr-pim:pimd", "pim", vrfname
);
8038 strlcat(ecmp_rebalance_xpath
, "/ecmp-rebalance",
8039 sizeof(ecmp_rebalance_xpath
));
8041 nb_cli_enqueue_change(vty
, ecmp_rebalance_xpath
, NB_OP_MODIFY
, "false");
8043 return nb_cli_apply_changes(vty
, NULL
);
8046 DEFUN (interface_ip_igmp
,
8047 interface_ip_igmp_cmd
,
8052 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
, "true");
8054 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8057 DEFUN (interface_no_ip_igmp
,
8058 interface_no_ip_igmp_cmd
,
8064 const struct lyd_node
*pim_enable_dnode
;
8065 char pim_if_xpath
[XPATH_MAXLEN
+ 20];
8067 snprintf(pim_if_xpath
, sizeof(pim_if_xpath
),
8068 "%s/frr-pim:pim", VTY_CURR_XPATH
);
8070 pim_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8071 "%s/pim-enable", pim_if_xpath
);
8072 if (!pim_enable_dnode
) {
8073 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
, NULL
);
8074 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8076 if (!yang_dnode_get_bool(pim_enable_dnode
, ".")) {
8077 nb_cli_enqueue_change(vty
, pim_if_xpath
, NB_OP_DESTROY
,
8079 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8081 nb_cli_enqueue_change(vty
, "./igmp-enable",
8082 NB_OP_MODIFY
, "false");
8085 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8088 DEFUN (interface_ip_igmp_join
,
8089 interface_ip_igmp_join_cmd
,
8090 "ip igmp join A.B.C.D [A.B.C.D]",
8093 "IGMP join multicast group\n"
8094 "Multicast group address\n"
8099 const char *source_str
;
8100 char xpath
[XPATH_MAXLEN
];
8103 source_str
= argv
[idx_source
]->arg
;
8105 if (strcmp(source_str
, "0.0.0.0") == 0) {
8106 vty_out(vty
, "Bad source address %s\n",
8107 argv
[idx_source
]->arg
);
8108 return CMD_WARNING_CONFIG_FAILED
;
8111 source_str
= "0.0.0.0";
8113 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8114 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8116 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
8118 return nb_cli_apply_changes(vty
, NULL
);
8121 DEFUN (interface_no_ip_igmp_join
,
8122 interface_no_ip_igmp_join_cmd
,
8123 "no ip igmp join A.B.C.D [A.B.C.D]",
8127 "IGMP join multicast group\n"
8128 "Multicast group address\n"
8133 const char *source_str
;
8134 char xpath
[XPATH_MAXLEN
];
8137 source_str
= argv
[idx_source
]->arg
;
8139 if (strcmp(source_str
, "0.0.0.0") == 0) {
8140 vty_out(vty
, "Bad source address %s\n",
8141 argv
[idx_source
]->arg
);
8142 return CMD_WARNING_CONFIG_FAILED
;
8145 source_str
= "0.0.0.0";
8147 snprintf(xpath
, sizeof(xpath
), FRR_IGMP_JOIN_XPATH
,
8148 "frr-routing:ipv4", argv
[idx_group
]->arg
, source_str
);
8150 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
8152 return nb_cli_apply_changes(vty
, NULL
);
8155 DEFUN (interface_ip_igmp_query_interval
,
8156 interface_ip_igmp_query_interval_cmd
,
8157 "ip igmp query-interval (1-1800)",
8160 IFACE_IGMP_QUERY_INTERVAL_STR
8161 "Query interval in seconds\n")
8163 const struct lyd_node
*pim_enable_dnode
;
8166 yang_dnode_getf(vty
->candidate_config
->dnode
,
8167 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8168 if (!pim_enable_dnode
) {
8169 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8172 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8173 nb_cli_enqueue_change(vty
, "./igmp-enable",
8174 NB_OP_MODIFY
, "true");
8177 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_MODIFY
,
8180 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8183 DEFUN (interface_no_ip_igmp_query_interval
,
8184 interface_no_ip_igmp_query_interval_cmd
,
8185 "no ip igmp query-interval",
8189 IFACE_IGMP_QUERY_INTERVAL_STR
)
8191 char default_query_interval
[5];
8193 snprintf(default_query_interval
, sizeof(default_query_interval
), "%d",
8194 IGMP_GENERAL_QUERY_INTERVAL
);
8196 nb_cli_enqueue_change(vty
, "./query-interval", NB_OP_MODIFY
,
8197 default_query_interval
);
8199 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8202 DEFUN (interface_ip_igmp_version
,
8203 interface_ip_igmp_version_cmd
,
8204 "ip igmp version (2-3)",
8208 "IGMP version number\n")
8210 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8212 nb_cli_enqueue_change(vty
, "./version", NB_OP_MODIFY
, argv
[3]->arg
);
8214 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8217 DEFUN (interface_no_ip_igmp_version
,
8218 interface_no_ip_igmp_version_cmd
,
8219 "no ip igmp version (2-3)",
8224 "IGMP version number\n")
8226 nb_cli_enqueue_change(vty
, "./version", NB_OP_DESTROY
, NULL
);
8228 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8231 DEFUN (interface_ip_igmp_query_max_response_time
,
8232 interface_ip_igmp_query_max_response_time_cmd
,
8233 "ip igmp query-max-response-time (10-250)",
8236 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8237 "Query response value in deci-seconds\n")
8239 const struct lyd_node
*pim_enable_dnode
;
8242 yang_dnode_getf(vty
->candidate_config
->dnode
,
8243 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8245 if (!pim_enable_dnode
) {
8246 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8249 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8250 nb_cli_enqueue_change(vty
, "./igmp-enable",
8251 NB_OP_MODIFY
, "true");
8254 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8257 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8260 DEFUN (interface_no_ip_igmp_query_max_response_time
,
8261 interface_no_ip_igmp_query_max_response_time_cmd
,
8262 "no ip igmp query-max-response-time (10-250)",
8266 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
8267 "Time for response in deci-seconds\n")
8269 char default_query_max_response_time
[4];
8271 snprintf(default_query_max_response_time
,
8272 sizeof(default_query_max_response_time
),
8273 "%d", IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8275 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8276 default_query_max_response_time
);
8277 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8280 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec
,
8281 interface_ip_igmp_query_max_response_time_dsec_cmd
,
8282 "ip igmp query-max-response-time-dsec (10-250)",
8285 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
8286 "Query response value in deciseconds\n")
8288 const struct lyd_node
*pim_enable_dnode
;
8291 yang_dnode_getf(vty
->candidate_config
->dnode
,
8292 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8293 if (!pim_enable_dnode
) {
8294 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8297 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8298 nb_cli_enqueue_change(vty
, "./igmp-enable",
8299 NB_OP_MODIFY
, "true");
8302 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8305 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8308 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec
,
8309 interface_no_ip_igmp_query_max_response_time_dsec_cmd
,
8310 "no ip igmp query-max-response-time-dsec",
8314 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
)
8316 char default_query_max_response_time
[4];
8318 snprintf(default_query_max_response_time
,
8319 sizeof(default_query_max_response_time
),
8320 "%d", IGMP_QUERY_MAX_RESPONSE_TIME_DSEC
);
8322 nb_cli_enqueue_change(vty
, "./query-max-response-time", NB_OP_MODIFY
,
8323 default_query_max_response_time
);
8325 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8328 DEFUN (interface_ip_igmp_last_member_query_count
,
8329 interface_ip_igmp_last_member_query_count_cmd
,
8330 "ip igmp last-member-query-count (1-7)",
8333 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
8334 "Last member query count\n")
8336 const struct lyd_node
*pim_enable_dnode
;
8339 yang_dnode_getf(vty
->candidate_config
->dnode
,
8340 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8341 if (!pim_enable_dnode
) {
8342 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8345 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8346 nb_cli_enqueue_change(vty
, "./igmp-enable",
8347 NB_OP_MODIFY
, "true");
8350 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_MODIFY
,
8353 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8356 DEFUN (interface_no_ip_igmp_last_member_query_count
,
8357 interface_no_ip_igmp_last_member_query_count_cmd
,
8358 "no ip igmp last-member-query-count",
8362 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
)
8364 char default_robustness
[2];
8366 snprintf(default_robustness
, sizeof(default_robustness
), "%d",
8367 IGMP_DEFAULT_ROBUSTNESS_VARIABLE
);
8369 nb_cli_enqueue_change(vty
, "./robustness-variable", NB_OP_MODIFY
,
8370 default_robustness
);
8372 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8375 DEFUN (interface_ip_igmp_last_member_query_interval
,
8376 interface_ip_igmp_last_member_query_interval_cmd
,
8377 "ip igmp last-member-query-interval (1-255)",
8380 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
8381 "Last member query interval in deciseconds\n")
8383 const struct lyd_node
*pim_enable_dnode
;
8386 yang_dnode_getf(vty
->candidate_config
->dnode
,
8387 "%s/frr-pim:pim/pim-enable", VTY_CURR_XPATH
);
8388 if (!pim_enable_dnode
) {
8389 nb_cli_enqueue_change(vty
, "./igmp-enable", NB_OP_MODIFY
,
8392 if (!yang_dnode_get_bool(pim_enable_dnode
, "."))
8393 nb_cli_enqueue_change(vty
, "./igmp-enable",
8394 NB_OP_MODIFY
, "true");
8397 nb_cli_enqueue_change(vty
, "./last-member-query-interval", NB_OP_MODIFY
,
8400 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8403 DEFUN (interface_no_ip_igmp_last_member_query_interval
,
8404 interface_no_ip_igmp_last_member_query_interval_cmd
,
8405 "no ip igmp last-member-query-interval",
8409 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
)
8411 char default_last_member_query_count
[4];
8413 snprintf(default_last_member_query_count
,
8414 sizeof(default_last_member_query_count
),
8415 "%d", IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
);
8417 nb_cli_enqueue_change(vty
, "./last-member-query-interval", NB_OP_MODIFY
,
8418 default_last_member_query_count
);
8420 return nb_cli_apply_changes(vty
, "./frr-igmp:igmp");
8423 DEFUN (interface_ip_pim_drprio
,
8424 interface_ip_pim_drprio_cmd
,
8425 "ip pim drpriority (1-4294967295)",
8428 "Set the Designated Router Election Priority\n"
8429 "Value of the new DR Priority\n")
8433 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_MODIFY
,
8434 argv
[idx_number
]->arg
);
8436 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8439 DEFUN (interface_no_ip_pim_drprio
,
8440 interface_no_ip_pim_drprio_cmd
,
8441 "no ip pim drpriority [(1-4294967295)]",
8445 "Revert the Designated Router Priority to default\n"
8446 "Old Value of the Priority\n")
8448 char default_priority
[10];
8450 snprintf(default_priority
, sizeof(default_priority
), "%d",
8451 PIM_DEFAULT_DR_PRIORITY
);
8453 nb_cli_enqueue_change(vty
, "./dr-priority", NB_OP_MODIFY
,
8456 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8459 DEFPY_HIDDEN (interface_ip_igmp_query_generate
,
8460 interface_ip_igmp_query_generate_cmd
,
8461 "ip igmp generate-query-once [version (2-3)]",
8464 "Generate igmp general query once\n"
8466 "IGMP version number\n")
8468 VTY_DECLVAR_CONTEXT(interface
, ifp
);
8469 int igmp_version
= 2;
8472 vty_out(vty
, "IGMP/PIM is not enabled on the interface %s\n",
8474 return CMD_WARNING_CONFIG_FAILED
;
8478 igmp_version
= atoi(argv
[4]->arg
);
8480 igmp_send_query_on_intf(ifp
, igmp_version
);
8485 DEFPY_HIDDEN (pim_test_sg_keepalive
,
8486 pim_test_sg_keepalive_cmd
,
8487 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
8491 "Reset the Keepalive Timer\n"
8492 "The Source we are resetting\n"
8493 "The Group we are resetting\n")
8495 struct pim_upstream
*up
;
8496 struct pim_instance
*pim
;
8497 struct prefix_sg sg
;
8503 pim
= pim_get_pim_instance(VRF_DEFAULT
);
8505 struct vrf
*vrf
= vrf_lookup_by_name(name
);
8508 vty_out(vty
, "%% Vrf specified: %s does not exist\n",
8513 pim
= pim_get_pim_instance(vrf
->vrf_id
);
8517 vty_out(vty
, "%% Unable to find pim instance\n");
8521 up
= pim_upstream_find(pim
, &sg
);
8523 vty_out(vty
, "%% Unable to find %s specified\n",
8524 pim_str_sg_dump(&sg
));
8528 vty_out(vty
, "Setting %s to current keep alive time: %d\n",
8529 pim_str_sg_dump(&sg
), pim
->keep_alive_time
);
8530 pim_upstream_keep_alive_timer_start(up
, pim
->keep_alive_time
);
8535 DEFPY (interface_ip_pim_activeactive
,
8536 interface_ip_pim_activeactive_cmd
,
8537 "[no$no] ip pim active-active",
8541 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8544 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8547 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8550 nb_cli_enqueue_change(vty
, "./active-active", NB_OP_MODIFY
,
8554 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8557 DEFUN_HIDDEN (interface_ip_pim_ssm
,
8558 interface_ip_pim_ssm_cmd
,
8566 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8568 ret
= nb_cli_apply_changes(vty
, "./frr-pim:pim");
8574 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
8579 DEFUN_HIDDEN (interface_ip_pim_sm
,
8580 interface_ip_pim_sm_cmd
,
8586 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8588 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8591 DEFUN (interface_ip_pim
,
8592 interface_ip_pim_cmd
,
8597 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
, "true");
8599 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8602 DEFUN_HIDDEN (interface_no_ip_pim_ssm
,
8603 interface_no_ip_pim_ssm_cmd
,
8610 const struct lyd_node
*igmp_enable_dnode
;
8611 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8613 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8614 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8615 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8616 "%s/igmp-enable", igmp_if_xpath
);
8618 if (!igmp_enable_dnode
) {
8619 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8620 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8622 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8623 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8625 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8627 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8631 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8634 DEFUN_HIDDEN (interface_no_ip_pim_sm
,
8635 interface_no_ip_pim_sm_cmd
,
8642 const struct lyd_node
*igmp_enable_dnode
;
8643 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8645 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8646 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8647 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8648 "%s/igmp-enable", igmp_if_xpath
);
8650 if (!igmp_enable_dnode
) {
8651 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8652 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8654 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8655 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8657 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8659 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8663 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8666 DEFUN (interface_no_ip_pim
,
8667 interface_no_ip_pim_cmd
,
8673 const struct lyd_node
*igmp_enable_dnode
;
8674 char igmp_if_xpath
[XPATH_MAXLEN
+ 20];
8676 snprintf(igmp_if_xpath
, sizeof(igmp_if_xpath
),
8677 "%s/frr-igmp:igmp", VTY_CURR_XPATH
);
8678 igmp_enable_dnode
= yang_dnode_getf(vty
->candidate_config
->dnode
,
8679 "%s/igmp-enable", igmp_if_xpath
);
8681 if (!igmp_enable_dnode
) {
8682 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
, NULL
);
8683 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8685 if (!yang_dnode_get_bool(igmp_enable_dnode
, ".")) {
8686 nb_cli_enqueue_change(vty
, igmp_if_xpath
, NB_OP_DESTROY
,
8688 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8690 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8694 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8698 DEFUN(interface_ip_pim_boundary_oil
,
8699 interface_ip_pim_boundary_oil_cmd
,
8700 "ip multicast boundary oil WORD",
8702 "Generic multicast configuration options\n"
8703 "Define multicast boundary\n"
8704 "Filter OIL by group using prefix list\n"
8705 "Prefix list to filter OIL with\n")
8707 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_MODIFY
,
8710 return nb_cli_apply_changes(vty
,
8711 "./frr-pim:pim/address-family[address-family='%s']",
8712 "frr-routing:ipv4");
8716 DEFUN(interface_no_ip_pim_boundary_oil
,
8717 interface_no_ip_pim_boundary_oil_cmd
,
8718 "no ip multicast boundary oil [WORD]",
8721 "Generic multicast configuration options\n"
8722 "Define multicast boundary\n"
8723 "Filter OIL by group using prefix list\n"
8724 "Prefix list to filter OIL with\n")
8726 nb_cli_enqueue_change(vty
, "./multicast-boundary-oil", NB_OP_DESTROY
,
8729 return nb_cli_apply_changes(vty
,
8730 "./frr-pim:pim/address-family[address-family='%s']",
8731 "frr-routing:ipv4");
8734 DEFUN (interface_ip_mroute
,
8735 interface_ip_mroute_cmd
,
8736 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8738 "Add multicast route\n"
8739 "Outgoing interface name\n"
8743 int idx_interface
= 2;
8745 const char *source_str
;
8747 if (argc
== (idx_ipv4
+ 1))
8748 source_str
= "0.0.0.0";
8750 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8752 nb_cli_enqueue_change(vty
, "./oif", NB_OP_MODIFY
,
8753 argv
[idx_interface
]->arg
);
8755 return nb_cli_apply_changes(vty
,
8756 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8757 "frr-routing:ipv4", source_str
,
8758 argv
[idx_ipv4
]->arg
);
8761 DEFUN (interface_no_ip_mroute
,
8762 interface_no_ip_mroute_cmd
,
8763 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8766 "Add multicast route\n"
8767 "Outgoing interface name\n"
8772 const char *source_str
;
8774 if (argc
== (idx_ipv4
+ 1))
8775 source_str
= "0.0.0.0";
8777 source_str
= argv
[idx_ipv4
+ 1]->arg
;
8779 nb_cli_enqueue_change(vty
, ".", NB_OP_DESTROY
, NULL
);
8781 return nb_cli_apply_changes(vty
,
8782 "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
8783 "frr-routing:ipv4", source_str
,
8784 argv
[idx_ipv4
]->arg
);
8787 DEFUN (interface_ip_pim_hello
,
8788 interface_ip_pim_hello_cmd
,
8789 "ip pim hello (1-180) [(1-630)]",
8793 IFACE_PIM_HELLO_TIME_STR
8794 IFACE_PIM_HELLO_HOLD_STR
)
8798 const struct lyd_node
*igmp_enable_dnode
;
8801 yang_dnode_getf(vty
->candidate_config
->dnode
,
8802 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
8803 if (!igmp_enable_dnode
) {
8804 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8807 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
8808 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
8812 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_MODIFY
,
8813 argv
[idx_time
]->arg
);
8815 if (argc
== idx_hold
+ 1)
8816 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_MODIFY
,
8817 argv
[idx_hold
]->arg
);
8819 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8822 DEFUN (interface_no_ip_pim_hello
,
8823 interface_no_ip_pim_hello_cmd
,
8824 "no ip pim hello [(1-180) [(1-630)]]",
8829 IFACE_PIM_HELLO_TIME_STR
8830 IFACE_PIM_HELLO_HOLD_STR
)
8832 char hello_default_timer
[3];
8834 snprintf(hello_default_timer
, sizeof(hello_default_timer
), "%d",
8835 PIM_DEFAULT_HELLO_PERIOD
);
8837 nb_cli_enqueue_change(vty
, "./hello-interval", NB_OP_MODIFY
,
8838 hello_default_timer
);
8839 nb_cli_enqueue_change(vty
, "./hello-holdtime", NB_OP_DESTROY
, NULL
);
8841 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
8850 PIM_DO_DEBUG_IGMP_EVENTS
;
8851 PIM_DO_DEBUG_IGMP_PACKETS
;
8852 PIM_DO_DEBUG_IGMP_TRACE
;
8856 DEFUN (no_debug_igmp
,
8863 PIM_DONT_DEBUG_IGMP_EVENTS
;
8864 PIM_DONT_DEBUG_IGMP_PACKETS
;
8865 PIM_DONT_DEBUG_IGMP_TRACE
;
8870 DEFUN (debug_igmp_events
,
8871 debug_igmp_events_cmd
,
8872 "debug igmp events",
8875 DEBUG_IGMP_EVENTS_STR
)
8877 PIM_DO_DEBUG_IGMP_EVENTS
;
8881 DEFUN (no_debug_igmp_events
,
8882 no_debug_igmp_events_cmd
,
8883 "no debug igmp events",
8887 DEBUG_IGMP_EVENTS_STR
)
8889 PIM_DONT_DEBUG_IGMP_EVENTS
;
8894 DEFUN (debug_igmp_packets
,
8895 debug_igmp_packets_cmd
,
8896 "debug igmp packets",
8899 DEBUG_IGMP_PACKETS_STR
)
8901 PIM_DO_DEBUG_IGMP_PACKETS
;
8905 DEFUN (no_debug_igmp_packets
,
8906 no_debug_igmp_packets_cmd
,
8907 "no debug igmp packets",
8911 DEBUG_IGMP_PACKETS_STR
)
8913 PIM_DONT_DEBUG_IGMP_PACKETS
;
8918 DEFUN (debug_igmp_trace
,
8919 debug_igmp_trace_cmd
,
8923 DEBUG_IGMP_TRACE_STR
)
8925 PIM_DO_DEBUG_IGMP_TRACE
;
8929 DEFUN (no_debug_igmp_trace
,
8930 no_debug_igmp_trace_cmd
,
8931 "no debug igmp trace",
8935 DEBUG_IGMP_TRACE_STR
)
8937 PIM_DONT_DEBUG_IGMP_TRACE
;
8942 DEFUN (debug_mroute
,
8948 PIM_DO_DEBUG_MROUTE
;
8952 DEFUN (debug_mroute_detail
,
8953 debug_mroute_detail_cmd
,
8954 "debug mroute detail",
8959 PIM_DO_DEBUG_MROUTE_DETAIL
;
8963 DEFUN (no_debug_mroute
,
8964 no_debug_mroute_cmd
,
8970 PIM_DONT_DEBUG_MROUTE
;
8974 DEFUN (no_debug_mroute_detail
,
8975 no_debug_mroute_detail_cmd
,
8976 "no debug mroute detail",
8982 PIM_DONT_DEBUG_MROUTE_DETAIL
;
8986 DEFUN (debug_pim_static
,
8987 debug_pim_static_cmd
,
8993 PIM_DO_DEBUG_STATIC
;
8997 DEFUN (no_debug_pim_static
,
8998 no_debug_pim_static_cmd
,
8999 "no debug pim static",
9005 PIM_DONT_DEBUG_STATIC
;
9016 PIM_DO_DEBUG_PIM_EVENTS
;
9017 PIM_DO_DEBUG_PIM_PACKETS
;
9018 PIM_DO_DEBUG_PIM_TRACE
;
9019 PIM_DO_DEBUG_MSDP_EVENTS
;
9020 PIM_DO_DEBUG_MSDP_PACKETS
;
9025 DEFUN (no_debug_pim
,
9032 PIM_DONT_DEBUG_PIM_EVENTS
;
9033 PIM_DONT_DEBUG_PIM_PACKETS
;
9034 PIM_DONT_DEBUG_PIM_TRACE
;
9035 PIM_DONT_DEBUG_MSDP_EVENTS
;
9036 PIM_DONT_DEBUG_MSDP_PACKETS
;
9038 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9039 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9045 DEFUN (debug_pim_nht
,
9050 "Nexthop Tracking\n")
9052 PIM_DO_DEBUG_PIM_NHT
;
9056 DEFUN (no_debug_pim_nht
,
9057 no_debug_pim_nht_cmd
,
9062 "Nexthop Tracking\n")
9064 PIM_DONT_DEBUG_PIM_NHT
;
9068 DEFUN (debug_pim_nht_rp
,
9069 debug_pim_nht_rp_cmd
,
9073 "Nexthop Tracking\n"
9074 "RP Nexthop Tracking\n")
9076 PIM_DO_DEBUG_PIM_NHT_RP
;
9080 DEFUN (no_debug_pim_nht_rp
,
9081 no_debug_pim_nht_rp_cmd
,
9082 "no debug pim nht rp",
9086 "Nexthop Tracking\n"
9087 "RP Nexthop Tracking\n")
9089 PIM_DONT_DEBUG_PIM_NHT_RP
;
9093 DEFUN (debug_pim_events
,
9094 debug_pim_events_cmd
,
9098 DEBUG_PIM_EVENTS_STR
)
9100 PIM_DO_DEBUG_PIM_EVENTS
;
9104 DEFUN (no_debug_pim_events
,
9105 no_debug_pim_events_cmd
,
9106 "no debug pim events",
9110 DEBUG_PIM_EVENTS_STR
)
9112 PIM_DONT_DEBUG_PIM_EVENTS
;
9116 DEFUN (debug_pim_packets
,
9117 debug_pim_packets_cmd
,
9118 "debug pim packets [<hello|joins|register>]",
9121 DEBUG_PIM_PACKETS_STR
9122 DEBUG_PIM_HELLO_PACKETS_STR
9123 DEBUG_PIM_J_P_PACKETS_STR
9124 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9127 if (argv_find(argv
, argc
, "hello", &idx
)) {
9128 PIM_DO_DEBUG_PIM_HELLO
;
9129 vty_out(vty
, "PIM Hello debugging is on\n");
9130 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9131 PIM_DO_DEBUG_PIM_J_P
;
9132 vty_out(vty
, "PIM Join/Prune debugging is on\n");
9133 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9134 PIM_DO_DEBUG_PIM_REG
;
9135 vty_out(vty
, "PIM Register debugging is on\n");
9137 PIM_DO_DEBUG_PIM_PACKETS
;
9138 vty_out(vty
, "PIM Packet debugging is on \n");
9143 DEFUN (no_debug_pim_packets
,
9144 no_debug_pim_packets_cmd
,
9145 "no debug pim packets [<hello|joins|register>]",
9149 DEBUG_PIM_PACKETS_STR
9150 DEBUG_PIM_HELLO_PACKETS_STR
9151 DEBUG_PIM_J_P_PACKETS_STR
9152 DEBUG_PIM_PIM_REG_PACKETS_STR
)
9155 if (argv_find(argv
, argc
, "hello", &idx
)) {
9156 PIM_DONT_DEBUG_PIM_HELLO
;
9157 vty_out(vty
, "PIM Hello debugging is off \n");
9158 } else if (argv_find(argv
, argc
, "joins", &idx
)) {
9159 PIM_DONT_DEBUG_PIM_J_P
;
9160 vty_out(vty
, "PIM Join/Prune debugging is off \n");
9161 } else if (argv_find(argv
, argc
, "register", &idx
)) {
9162 PIM_DONT_DEBUG_PIM_REG
;
9163 vty_out(vty
, "PIM Register debugging is off\n");
9165 PIM_DONT_DEBUG_PIM_PACKETS
;
9171 DEFUN (debug_pim_packetdump_send
,
9172 debug_pim_packetdump_send_cmd
,
9173 "debug pim packet-dump send",
9176 DEBUG_PIM_PACKETDUMP_STR
9177 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9179 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND
;
9183 DEFUN (no_debug_pim_packetdump_send
,
9184 no_debug_pim_packetdump_send_cmd
,
9185 "no debug pim packet-dump send",
9189 DEBUG_PIM_PACKETDUMP_STR
9190 DEBUG_PIM_PACKETDUMP_SEND_STR
)
9192 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND
;
9196 DEFUN (debug_pim_packetdump_recv
,
9197 debug_pim_packetdump_recv_cmd
,
9198 "debug pim packet-dump receive",
9201 DEBUG_PIM_PACKETDUMP_STR
9202 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9204 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV
;
9208 DEFUN (no_debug_pim_packetdump_recv
,
9209 no_debug_pim_packetdump_recv_cmd
,
9210 "no debug pim packet-dump receive",
9214 DEBUG_PIM_PACKETDUMP_STR
9215 DEBUG_PIM_PACKETDUMP_RECV_STR
)
9217 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV
;
9221 DEFUN (debug_pim_trace
,
9222 debug_pim_trace_cmd
,
9226 DEBUG_PIM_TRACE_STR
)
9228 PIM_DO_DEBUG_PIM_TRACE
;
9232 DEFUN (debug_pim_trace_detail
,
9233 debug_pim_trace_detail_cmd
,
9234 "debug pim trace detail",
9238 "Detailed Information\n")
9240 PIM_DO_DEBUG_PIM_TRACE_DETAIL
;
9244 DEFUN (no_debug_pim_trace
,
9245 no_debug_pim_trace_cmd
,
9246 "no debug pim trace",
9250 DEBUG_PIM_TRACE_STR
)
9252 PIM_DONT_DEBUG_PIM_TRACE
;
9256 DEFUN (no_debug_pim_trace_detail
,
9257 no_debug_pim_trace_detail_cmd
,
9258 "no debug pim trace detail",
9263 "Detailed Information\n")
9265 PIM_DONT_DEBUG_PIM_TRACE_DETAIL
;
9269 DEFUN (debug_ssmpingd
,
9275 PIM_DO_DEBUG_SSMPINGD
;
9279 DEFUN (no_debug_ssmpingd
,
9280 no_debug_ssmpingd_cmd
,
9281 "no debug ssmpingd",
9286 PIM_DONT_DEBUG_SSMPINGD
;
9290 DEFUN (debug_pim_zebra
,
9291 debug_pim_zebra_cmd
,
9295 DEBUG_PIM_ZEBRA_STR
)
9301 DEFUN (no_debug_pim_zebra
,
9302 no_debug_pim_zebra_cmd
,
9303 "no debug pim zebra",
9307 DEBUG_PIM_ZEBRA_STR
)
9309 PIM_DONT_DEBUG_ZEBRA
;
9313 DEFUN(debug_pim_mlag
, debug_pim_mlag_cmd
, "debug pim mlag",
9314 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9320 DEFUN(no_debug_pim_mlag
, no_debug_pim_mlag_cmd
, "no debug pim mlag",
9321 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR
)
9323 PIM_DONT_DEBUG_MLAG
;
9327 DEFUN (debug_pim_vxlan
,
9328 debug_pim_vxlan_cmd
,
9332 DEBUG_PIM_VXLAN_STR
)
9338 DEFUN (no_debug_pim_vxlan
,
9339 no_debug_pim_vxlan_cmd
,
9340 "no debug pim vxlan",
9344 DEBUG_PIM_VXLAN_STR
)
9346 PIM_DONT_DEBUG_VXLAN
;
9356 PIM_DO_DEBUG_MSDP_EVENTS
;
9357 PIM_DO_DEBUG_MSDP_PACKETS
;
9361 DEFUN (no_debug_msdp
,
9368 PIM_DONT_DEBUG_MSDP_EVENTS
;
9369 PIM_DONT_DEBUG_MSDP_PACKETS
;
9373 DEFUN (debug_msdp_events
,
9374 debug_msdp_events_cmd
,
9375 "debug msdp events",
9378 DEBUG_MSDP_EVENTS_STR
)
9380 PIM_DO_DEBUG_MSDP_EVENTS
;
9384 DEFUN (no_debug_msdp_events
,
9385 no_debug_msdp_events_cmd
,
9386 "no debug msdp events",
9390 DEBUG_MSDP_EVENTS_STR
)
9392 PIM_DONT_DEBUG_MSDP_EVENTS
;
9396 DEFUN (debug_msdp_packets
,
9397 debug_msdp_packets_cmd
,
9398 "debug msdp packets",
9401 DEBUG_MSDP_PACKETS_STR
)
9403 PIM_DO_DEBUG_MSDP_PACKETS
;
9407 DEFUN (no_debug_msdp_packets
,
9408 no_debug_msdp_packets_cmd
,
9409 "no debug msdp packets",
9413 DEBUG_MSDP_PACKETS_STR
)
9415 PIM_DONT_DEBUG_MSDP_PACKETS
;
9419 DEFUN (debug_mtrace
,
9425 PIM_DO_DEBUG_MTRACE
;
9429 DEFUN (no_debug_mtrace
,
9430 no_debug_mtrace_cmd
,
9436 PIM_DONT_DEBUG_MTRACE
;
9451 DEFUN (no_debug_bsm
,
9464 DEFUN_NOSH (show_debugging_pim
,
9465 show_debugging_pim_cmd
,
9466 "show debugging [pim]",
9471 vty_out(vty
, "PIM debugging status\n");
9473 pim_debug_config_write(vty
);
9478 DEFUN (interface_pim_use_source
,
9479 interface_pim_use_source_cmd
,
9480 "ip pim use-source A.B.C.D",
9483 "Configure primary IP address\n"
9484 "source ip address\n")
9486 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, argv
[3]->arg
);
9488 return nb_cli_apply_changes(vty
,
9489 "./frr-pim:pim/address-family[address-family='%s']",
9490 "frr-routing:ipv4");
9493 DEFUN (interface_no_pim_use_source
,
9494 interface_no_pim_use_source_cmd
,
9495 "no ip pim use-source [A.B.C.D]",
9499 "Delete source IP address\n"
9500 "source ip address\n")
9502 nb_cli_enqueue_change(vty
, "./use-source", NB_OP_MODIFY
, "0.0.0.0");
9504 return nb_cli_apply_changes(vty
,
9505 "./frr-pim:pim/address-family[address-family='%s']",
9506 "frr-routing:ipv4");
9511 "ip pim bfd [profile BFDPROF$prof]",
9514 "Enables BFD support\n"
9516 "Use BFD profile name\n")
9518 const struct lyd_node
*igmp_enable_dnode
;
9521 yang_dnode_getf(vty
->candidate_config
->dnode
,
9522 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9523 if (!igmp_enable_dnode
)
9524 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9527 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9528 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9532 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9534 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_MODIFY
, prof
);
9536 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9539 DEFPY(no_ip_pim_bfd_profile
, no_ip_pim_bfd_profile_cmd
,
9540 "no ip pim bfd profile [BFDPROF]",
9544 "Enables BFD support\n"
9545 "Disable BFD profile\n"
9546 "BFD Profile name\n")
9548 nb_cli_enqueue_change(vty
, "./bfd/profile", NB_OP_DESTROY
, NULL
);
9550 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9553 DEFUN (no_ip_pim_bfd
,
9559 "Disables BFD support\n")
9561 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_DESTROY
, NULL
);
9563 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9571 "Enables BSM support on the interface\n")
9573 const struct lyd_node
*igmp_enable_dnode
;
9576 yang_dnode_getf(vty
->candidate_config
->dnode
,
9577 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9578 if (!igmp_enable_dnode
)
9579 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9582 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9583 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9587 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "true");
9589 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9592 DEFUN (no_ip_pim_bsm
,
9598 "Disables BSM support\n")
9600 nb_cli_enqueue_change(vty
, "./bsm", NB_OP_MODIFY
, "false");
9602 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9605 DEFUN (ip_pim_ucast_bsm
,
9606 ip_pim_ucast_bsm_cmd
,
9607 "ip pim unicast-bsm",
9610 "Accept/Send unicast BSM on the interface\n")
9612 const struct lyd_node
*igmp_enable_dnode
;
9615 yang_dnode_getf(vty
->candidate_config
->dnode
,
9616 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9617 if (!igmp_enable_dnode
)
9618 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9621 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9622 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9626 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "true");
9628 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9631 DEFUN (no_ip_pim_ucast_bsm
,
9632 no_ip_pim_ucast_bsm_cmd
,
9633 "no ip pim unicast-bsm",
9637 "Block send/receive unicast BSM on this interface\n")
9639 nb_cli_enqueue_change(vty
, "./unicast-bsm", NB_OP_MODIFY
, "false");
9641 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9647 ip_pim_bfd_param_cmd
,
9648 "ip pim bfd (2-255) (50-60000) (50-60000)",
9651 "Enables BFD support\n"
9652 "Detect Multiplier\n"
9653 "Required min receive interval\n"
9654 "Desired min transmit interval\n")
9658 ip_pim_bfd_param_cmd
,
9659 "ip pim bfd (2-255) (50-60000) (50-60000)",
9662 "Enables BFD support\n"
9663 "Detect Multiplier\n"
9664 "Required min receive interval\n"
9665 "Desired min transmit interval\n")
9666 #endif /* HAVE_BFDD */
9669 int idx_number_2
= 4;
9670 int idx_number_3
= 5;
9671 const struct lyd_node
*igmp_enable_dnode
;
9674 yang_dnode_getf(vty
->candidate_config
->dnode
,
9675 "%s/frr-igmp:igmp/igmp-enable", VTY_CURR_XPATH
);
9676 if (!igmp_enable_dnode
)
9677 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9680 if (!yang_dnode_get_bool(igmp_enable_dnode
, "."))
9681 nb_cli_enqueue_change(vty
, "./pim-enable", NB_OP_MODIFY
,
9685 nb_cli_enqueue_change(vty
, "./bfd", NB_OP_CREATE
, NULL
);
9686 nb_cli_enqueue_change(vty
, "./bfd/min-rx-interval", NB_OP_MODIFY
,
9687 argv
[idx_number_2
]->arg
);
9688 nb_cli_enqueue_change(vty
, "./bfd/min-tx-interval", NB_OP_MODIFY
,
9689 argv
[idx_number_3
]->arg
);
9690 nb_cli_enqueue_change(vty
, "./bfd/detect_mult", NB_OP_MODIFY
,
9691 argv
[idx_number
]->arg
);
9693 return nb_cli_apply_changes(vty
, "./frr-pim:pim");
9697 ALIAS(no_ip_pim_bfd
, no_ip_pim_bfd_param_cmd
,
9698 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9699 "Enables BFD support\n"
9700 "Detect Multiplier\n"
9701 "Required min receive interval\n"
9702 "Desired min transmit interval\n")
9703 #endif /* !HAVE_BFDD */
9705 DEFPY(ip_msdp_peer
, ip_msdp_peer_cmd
,
9706 "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
9709 "Configure MSDP peer\n"
9711 "Source address for TCP connection\n"
9712 "Local IP address\n")
9714 const char *vrfname
;
9715 char temp_xpath
[XPATH_MAXLEN
];
9716 char msdp_peer_source_xpath
[XPATH_MAXLEN
];
9718 vrfname
= pim_cli_get_vrf_name(vty
);
9719 if (vrfname
== NULL
)
9720 return CMD_WARNING_CONFIG_FAILED
;
9722 snprintf(msdp_peer_source_xpath
, sizeof(msdp_peer_source_xpath
),
9723 FRR_PIM_AF_XPATH
, "frr-pim:pimd", "pim", vrfname
,
9724 "frr-routing:ipv4");
9725 snprintf(temp_xpath
, sizeof(temp_xpath
),
9726 "/msdp-peer[peer-ip='%s']/source-ip", peer_str
);
9727 strlcat(msdp_peer_source_xpath
, temp_xpath
,
9728 sizeof(msdp_peer_source_xpath
));
9730 nb_cli_enqueue_change(vty
, msdp_peer_source_xpath
, NB_OP_MODIFY
,
9733 return nb_cli_apply_changes(vty
, NULL
);
9736 DEFPY(ip_msdp_timers
, ip_msdp_timers_cmd
,
9737 "ip msdp timers (2-600)$keepalive (3-600)$holdtime [(1-600)$connretry]",
9740 "MSDP timers configuration\n"
9741 "Keep alive period (in seconds)\n"
9742 "Hold time period (in seconds)\n"
9743 "Connection retry period (in seconds)\n")
9745 const char *vrfname
;
9746 char xpath
[XPATH_MAXLEN
];
9748 vrfname
= pim_cli_get_vrf_name(vty
);
9749 if (vrfname
== NULL
)
9750 return CMD_WARNING_CONFIG_FAILED
;
9752 snprintf(xpath
, sizeof(xpath
), FRR_PIM_MSDP_XPATH
, "frr-pim:pimd",
9753 "pim", vrfname
, "frr-routing:ipv4");
9754 nb_cli_enqueue_change(vty
, "./hold-time", NB_OP_MODIFY
, holdtime_str
);
9755 nb_cli_enqueue_change(vty
, "./keep-alive", NB_OP_MODIFY
, keepalive_str
);
9757 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_MODIFY
,
9760 nb_cli_enqueue_change(vty
, "./connection-retry", NB_OP_DESTROY
,
9763 nb_cli_apply_changes(vty
, xpath
);
9768 DEFUN (no_ip_msdp_peer
,
9769 no_ip_msdp_peer_cmd
,
9770 "no ip msdp peer A.B.C.D",
9774 "Delete MSDP peer\n"
9775 "peer ip address\n")
9777 const char *vrfname
;
9778 char msdp_peer_xpath
[XPATH_MAXLEN
];
9779 char temp_xpath
[XPATH_MAXLEN
];
9781 vrfname
= pim_cli_get_vrf_name(vty
);
9782 if (vrfname
== NULL
)
9783 return CMD_WARNING_CONFIG_FAILED
;
9785 snprintf(msdp_peer_xpath
, sizeof(msdp_peer_xpath
),
9787 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4");
9788 snprintf(temp_xpath
, sizeof(temp_xpath
),
9789 "/msdp-peer[peer-ip='%s']",
9792 strlcat(msdp_peer_xpath
, temp_xpath
, sizeof(msdp_peer_xpath
));
9794 nb_cli_enqueue_change(vty
, msdp_peer_xpath
, NB_OP_DESTROY
, NULL
);
9796 return nb_cli_apply_changes(vty
, NULL
);
9799 DEFPY(ip_msdp_mesh_group_member
,
9800 ip_msdp_mesh_group_member_cmd
,
9801 "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9804 "Configure MSDP mesh-group\n"
9806 "Mesh group member\n"
9807 "Peer IP address\n")
9809 const char *vrfname
;
9810 char xpath_value
[XPATH_MAXLEN
];
9812 vrfname
= pim_cli_get_vrf_name(vty
);
9813 if (vrfname
== NULL
)
9814 return CMD_WARNING_CONFIG_FAILED
;
9816 /* Create mesh group. */
9817 snprintf(xpath_value
, sizeof(xpath_value
),
9818 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9819 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9820 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9822 /* Create mesh group member. */
9823 strlcat(xpath_value
, "/members[address='", sizeof(xpath_value
));
9824 strlcat(xpath_value
, maddr_str
, sizeof(xpath_value
));
9825 strlcat(xpath_value
, "']", sizeof(xpath_value
));
9826 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9828 return nb_cli_apply_changes(vty
, NULL
);
9831 DEFPY(no_ip_msdp_mesh_group_member
,
9832 no_ip_msdp_mesh_group_member_cmd
,
9833 "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
9837 "Delete MSDP mesh-group member\n"
9839 "Mesh group member\n"
9840 "Peer IP address\n")
9842 const char *vrfname
;
9843 char xpath_value
[XPATH_MAXLEN
];
9844 char xpath_member_value
[XPATH_MAXLEN
];
9846 vrfname
= pim_cli_get_vrf_name(vty
);
9847 if (vrfname
== NULL
)
9848 return CMD_WARNING_CONFIG_FAILED
;
9850 /* Get mesh group base XPath. */
9851 snprintf(xpath_value
, sizeof(xpath_value
),
9852 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9853 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9855 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
)) {
9856 vty_out(vty
, "%% mesh-group does not exist\n");
9857 return CMD_WARNING_CONFIG_FAILED
;
9860 /* Remove mesh group member. */
9861 strlcpy(xpath_member_value
, xpath_value
, sizeof(xpath_member_value
));
9862 strlcat(xpath_member_value
, "/members[address='",
9863 sizeof(xpath_member_value
));
9864 strlcat(xpath_member_value
, maddr_str
, sizeof(xpath_member_value
));
9865 strlcat(xpath_member_value
, "']", sizeof(xpath_member_value
));
9866 if (!yang_dnode_exists(vty
->candidate_config
->dnode
,
9867 xpath_member_value
)) {
9868 vty_out(vty
, "%% mesh-group member does not exist\n");
9869 return CMD_WARNING_CONFIG_FAILED
;
9872 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9875 * If this is the last member, then we must remove the group altogether
9876 * to not break legacy CLI behaviour.
9878 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9880 return nb_cli_apply_changes(vty
, NULL
);
9883 DEFPY(ip_msdp_mesh_group_source
,
9884 ip_msdp_mesh_group_source_cmd
,
9885 "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
9888 "Configure MSDP mesh-group\n"
9890 "Mesh group local address\n"
9891 "Source IP address for the TCP connection\n")
9893 const char *vrfname
;
9894 char xpath_value
[XPATH_MAXLEN
];
9896 vrfname
= pim_cli_get_vrf_name(vty
);
9897 if (vrfname
== NULL
)
9898 return CMD_WARNING_CONFIG_FAILED
;
9900 /* Create mesh group. */
9901 snprintf(xpath_value
, sizeof(xpath_value
),
9902 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9903 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9904 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9906 /* Create mesh group member. */
9907 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9908 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, saddr_str
);
9910 return nb_cli_apply_changes(vty
, NULL
);
9913 DEFPY(no_ip_msdp_mesh_group_source
,
9914 no_ip_msdp_mesh_group_source_cmd
,
9915 "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
9919 "Delete MSDP mesh-group source\n"
9921 "Mesh group source\n"
9922 "Mesh group local address\n")
9924 const char *vrfname
;
9925 char xpath_value
[XPATH_MAXLEN
];
9927 vrfname
= pim_cli_get_vrf_name(vty
);
9928 if (vrfname
== NULL
)
9929 return CMD_WARNING_CONFIG_FAILED
;
9931 /* Get mesh group base XPath. */
9932 snprintf(xpath_value
, sizeof(xpath_value
),
9933 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9934 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9935 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_CREATE
, NULL
);
9937 /* Create mesh group member. */
9938 strlcat(xpath_value
, "/source", sizeof(xpath_value
));
9939 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9942 * If this is the last member, then we must remove the group altogether
9943 * to not break legacy CLI behaviour.
9945 pim_cli_legacy_mesh_group_behavior(vty
, gname
);
9947 return nb_cli_apply_changes(vty
, NULL
);
9950 DEFPY(no_ip_msdp_mesh_group
,
9951 no_ip_msdp_mesh_group_cmd
,
9952 "no ip msdp mesh-group WORD$gname",
9956 "Delete MSDP mesh-group\n"
9959 const char *vrfname
;
9960 char xpath_value
[XPATH_MAXLEN
];
9962 vrfname
= pim_cli_get_vrf_name(vty
);
9963 if (vrfname
== NULL
)
9964 return CMD_WARNING_CONFIG_FAILED
;
9966 /* Get mesh group base XPath. */
9967 snprintf(xpath_value
, sizeof(xpath_value
),
9968 FRR_PIM_AF_XPATH
"/msdp-mesh-groups[name='%s']",
9969 "frr-pim:pimd", "pim", vrfname
, "frr-routing:ipv4", gname
);
9970 if (!yang_dnode_exists(vty
->candidate_config
->dnode
, xpath_value
))
9973 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_DESTROY
, NULL
);
9974 return nb_cli_apply_changes(vty
, NULL
);
9977 static void ip_msdp_show_mesh_group(struct vty
*vty
, struct pim_msdp_mg
*mg
,
9978 struct json_object
*json
)
9980 struct listnode
*mbrnode
;
9981 struct pim_msdp_mg_mbr
*mbr
;
9982 char mbr_str
[INET_ADDRSTRLEN
];
9983 char src_str
[INET_ADDRSTRLEN
];
9984 char state_str
[PIM_MSDP_STATE_STRLEN
];
9985 enum pim_msdp_peer_state state
;
9986 json_object
*json_mg_row
= NULL
;
9987 json_object
*json_members
= NULL
;
9988 json_object
*json_row
= NULL
;
9990 pim_inet4_dump("<source?>", mg
->src_ip
, src_str
, sizeof(src_str
));
9992 /* currently there is only one mesh group but we should still
9994 * it a dict with mg-name as key */
9995 json_mg_row
= json_object_new_object();
9996 json_object_string_add(json_mg_row
, "name",
9997 mg
->mesh_group_name
);
9998 json_object_string_add(json_mg_row
, "source", src_str
);
10000 vty_out(vty
, "Mesh group : %s\n", mg
->mesh_group_name
);
10001 vty_out(vty
, " Source : %s\n", src_str
);
10002 vty_out(vty
, " Member State\n");
10005 for (ALL_LIST_ELEMENTS_RO(mg
->mbr_list
, mbrnode
, mbr
)) {
10006 pim_inet4_dump("<mbr?>", mbr
->mbr_ip
, mbr_str
, sizeof(mbr_str
));
10008 state
= mbr
->mp
->state
;
10010 state
= PIM_MSDP_DISABLED
;
10012 pim_msdp_state_dump(state
, state_str
, sizeof(state_str
));
10014 json_row
= json_object_new_object();
10015 json_object_string_add(json_row
, "member", mbr_str
);
10016 json_object_string_add(json_row
, "state", state_str
);
10017 if (!json_members
) {
10018 json_members
= json_object_new_object();
10019 json_object_object_add(json_mg_row
, "members",
10022 json_object_object_add(json_members
, mbr_str
, json_row
);
10024 vty_out(vty
, " %-15s %11s\n", mbr_str
, state_str
);
10029 json_object_object_add(json
, mg
->mesh_group_name
, json_mg_row
);
10032 DEFUN (show_ip_msdp_mesh_group
,
10033 show_ip_msdp_mesh_group_cmd
,
10034 "show ip msdp [vrf NAME] mesh-group [json]",
10039 "MSDP mesh-group information\n"
10042 bool uj
= use_json(argc
, argv
);
10044 struct pim_msdp_mg
*mg
;
10045 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10046 struct pim_instance
*pim
= vrf
->info
;
10047 struct json_object
*json
= NULL
;
10050 return CMD_WARNING
;
10052 /* Quick case: list is empty. */
10053 if (SLIST_EMPTY(&pim
->msdp
.mglist
)) {
10055 vty_out(vty
, "{}\n");
10057 return CMD_SUCCESS
;
10061 json
= json_object_new_object();
10063 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
10064 ip_msdp_show_mesh_group(vty
, mg
, json
);
10067 vty_out(vty
, "%s\n",
10068 json_object_to_json_string_ext(
10069 json
, JSON_C_TO_STRING_PRETTY
));
10070 json_object_free(json
);
10073 return CMD_SUCCESS
;
10076 DEFUN (show_ip_msdp_mesh_group_vrf_all
,
10077 show_ip_msdp_mesh_group_vrf_all_cmd
,
10078 "show ip msdp vrf all mesh-group [json]",
10083 "MSDP mesh-group information\n"
10086 bool uj
= use_json(argc
, argv
);
10087 struct json_object
*json
= NULL
, *vrf_json
= NULL
;
10088 struct pim_instance
*pim
;
10089 struct pim_msdp_mg
*mg
;
10093 json
= json_object_new_object();
10095 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10097 vrf_json
= json_object_new_object();
10098 json_object_object_add(json
, vrf
->name
, vrf_json
);
10100 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10103 SLIST_FOREACH (mg
, &pim
->msdp
.mglist
, mg_entry
)
10104 ip_msdp_show_mesh_group(vty
, mg
, vrf_json
);
10108 vty_out(vty
, "%s\n",
10109 json_object_to_json_string_ext(
10110 json
, JSON_C_TO_STRING_PRETTY
));
10111 json_object_free(json
);
10114 return CMD_SUCCESS
;
10117 static void ip_msdp_show_peers(struct pim_instance
*pim
, struct vty
*vty
,
10120 struct listnode
*mpnode
;
10121 struct pim_msdp_peer
*mp
;
10122 char peer_str
[INET_ADDRSTRLEN
];
10123 char local_str
[INET_ADDRSTRLEN
];
10124 char state_str
[PIM_MSDP_STATE_STRLEN
];
10125 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10127 json_object
*json
= NULL
;
10128 json_object
*json_row
= NULL
;
10132 json
= json_object_new_object();
10135 "Peer Local State Uptime SaCnt\n");
10138 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10139 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10140 now
= pim_time_monotonic_sec();
10141 pim_time_uptime(timebuf
, sizeof(timebuf
),
10144 strlcpy(timebuf
, "-", sizeof(timebuf
));
10146 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10147 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10148 sizeof(local_str
));
10149 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10151 json_row
= json_object_new_object();
10152 json_object_string_add(json_row
, "peer", peer_str
);
10153 json_object_string_add(json_row
, "local", local_str
);
10154 json_object_string_add(json_row
, "state", state_str
);
10155 json_object_string_add(json_row
, "upTime", timebuf
);
10156 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10157 json_object_object_add(json
, peer_str
, json_row
);
10159 vty_out(vty
, "%-15s %15s %11s %8s %6d\n", peer_str
,
10160 local_str
, state_str
, timebuf
, mp
->sa_cnt
);
10165 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10166 json
, JSON_C_TO_STRING_PRETTY
));
10167 json_object_free(json
);
10171 static void ip_msdp_show_peers_detail(struct pim_instance
*pim
, struct vty
*vty
,
10172 const char *peer
, bool uj
)
10174 struct listnode
*mpnode
;
10175 struct pim_msdp_peer
*mp
;
10176 char peer_str
[INET_ADDRSTRLEN
];
10177 char local_str
[INET_ADDRSTRLEN
];
10178 char state_str
[PIM_MSDP_STATE_STRLEN
];
10179 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10180 char katimer
[PIM_MSDP_TIMER_STRLEN
];
10181 char crtimer
[PIM_MSDP_TIMER_STRLEN
];
10182 char holdtimer
[PIM_MSDP_TIMER_STRLEN
];
10184 json_object
*json
= NULL
;
10185 json_object
*json_row
= NULL
;
10188 json
= json_object_new_object();
10191 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.peer_list
, mpnode
, mp
)) {
10192 pim_inet4_dump("<peer?>", mp
->peer
, peer_str
, sizeof(peer_str
));
10193 if (strcmp(peer
, "detail") && strcmp(peer
, peer_str
))
10196 if (mp
->state
== PIM_MSDP_ESTABLISHED
) {
10197 now
= pim_time_monotonic_sec();
10198 pim_time_uptime(timebuf
, sizeof(timebuf
),
10201 strlcpy(timebuf
, "-", sizeof(timebuf
));
10203 pim_inet4_dump("<local?>", mp
->local
, local_str
,
10204 sizeof(local_str
));
10205 pim_msdp_state_dump(mp
->state
, state_str
, sizeof(state_str
));
10206 pim_time_timer_to_hhmmss(katimer
, sizeof(katimer
),
10208 pim_time_timer_to_hhmmss(crtimer
, sizeof(crtimer
),
10210 pim_time_timer_to_hhmmss(holdtimer
, sizeof(holdtimer
),
10214 json_row
= json_object_new_object();
10215 json_object_string_add(json_row
, "peer", peer_str
);
10216 json_object_string_add(json_row
, "local", local_str
);
10217 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10218 json_object_string_add(json_row
,
10220 mp
->mesh_group_name
);
10221 json_object_string_add(json_row
, "state", state_str
);
10222 json_object_string_add(json_row
, "upTime", timebuf
);
10223 json_object_string_add(json_row
, "keepAliveTimer",
10225 json_object_string_add(json_row
, "connRetryTimer",
10227 json_object_string_add(json_row
, "holdTimer",
10229 json_object_string_add(json_row
, "lastReset",
10231 json_object_int_add(json_row
, "connAttempts",
10232 mp
->conn_attempts
);
10233 json_object_int_add(json_row
, "establishedChanges",
10235 json_object_int_add(json_row
, "saCount", mp
->sa_cnt
);
10236 json_object_int_add(json_row
, "kaSent", mp
->ka_tx_cnt
);
10237 json_object_int_add(json_row
, "kaRcvd", mp
->ka_rx_cnt
);
10238 json_object_int_add(json_row
, "saSent", mp
->sa_tx_cnt
);
10239 json_object_int_add(json_row
, "saRcvd", mp
->sa_rx_cnt
);
10240 json_object_object_add(json
, peer_str
, json_row
);
10242 vty_out(vty
, "Peer : %s\n", peer_str
);
10243 vty_out(vty
, " Local : %s\n", local_str
);
10244 if (mp
->flags
& PIM_MSDP_PEERF_IN_GROUP
)
10245 vty_out(vty
, " Mesh Group : %s\n",
10246 mp
->mesh_group_name
);
10247 vty_out(vty
, " State : %s\n", state_str
);
10248 vty_out(vty
, " Uptime : %s\n", timebuf
);
10250 vty_out(vty
, " Keepalive Timer : %s\n", katimer
);
10251 vty_out(vty
, " Conn Retry Timer : %s\n", crtimer
);
10252 vty_out(vty
, " Hold Timer : %s\n", holdtimer
);
10253 vty_out(vty
, " Last Reset : %s\n",
10255 vty_out(vty
, " Conn Attempts : %d\n",
10256 mp
->conn_attempts
);
10257 vty_out(vty
, " Established Changes : %d\n",
10259 vty_out(vty
, " SA Count : %d\n",
10261 vty_out(vty
, " Statistics :\n");
10264 vty_out(vty
, " Keepalives : %10d %10d\n",
10265 mp
->ka_tx_cnt
, mp
->ka_rx_cnt
);
10266 vty_out(vty
, " SAs : %10d %10d\n",
10267 mp
->sa_tx_cnt
, mp
->sa_rx_cnt
);
10268 vty_out(vty
, "\n");
10273 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10274 json
, JSON_C_TO_STRING_PRETTY
));
10275 json_object_free(json
);
10279 DEFUN (show_ip_msdp_peer_detail
,
10280 show_ip_msdp_peer_detail_cmd
,
10281 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
10286 "MSDP peer information\n"
10287 "Detailed output\n"
10288 "peer ip address\n"
10291 bool uj
= use_json(argc
, argv
);
10293 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10296 return CMD_WARNING
;
10300 if (argv_find(argv
, argc
, "detail", &idx
))
10301 arg
= argv
[idx
]->text
;
10302 else if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10303 arg
= argv
[idx
]->arg
;
10306 ip_msdp_show_peers_detail(vrf
->info
, vty
, argv
[idx
]->arg
, uj
);
10308 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10310 return CMD_SUCCESS
;
10313 DEFUN (show_ip_msdp_peer_detail_vrf_all
,
10314 show_ip_msdp_peer_detail_vrf_all_cmd
,
10315 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
10320 "MSDP peer information\n"
10321 "Detailed output\n"
10322 "peer ip address\n"
10326 bool uj
= use_json(argc
, argv
);
10331 vty_out(vty
, "{ ");
10332 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10335 vty_out(vty
, ", ");
10336 vty_out(vty
, " \"%s\": ", vrf
->name
);
10339 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10340 if (argv_find(argv
, argc
, "detail", &idx
)
10341 || argv_find(argv
, argc
, "A.B.C.D", &idx
))
10342 ip_msdp_show_peers_detail(vrf
->info
, vty
,
10343 argv
[idx
]->arg
, uj
);
10345 ip_msdp_show_peers(vrf
->info
, vty
, uj
);
10348 vty_out(vty
, "}\n");
10350 return CMD_SUCCESS
;
10353 static void ip_msdp_show_sa(struct pim_instance
*pim
, struct vty
*vty
, bool uj
)
10355 struct listnode
*sanode
;
10356 struct pim_msdp_sa
*sa
;
10357 char src_str
[INET_ADDRSTRLEN
];
10358 char grp_str
[INET_ADDRSTRLEN
];
10359 char rp_str
[INET_ADDRSTRLEN
];
10360 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10364 json_object
*json
= NULL
;
10365 json_object
*json_group
= NULL
;
10366 json_object
*json_row
= NULL
;
10369 json
= json_object_new_object();
10372 "Source Group RP Local SPT Uptime\n");
10375 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10376 now
= pim_time_monotonic_sec();
10377 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10378 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10379 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10380 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10381 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10383 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10385 strlcpy(spt_str
, "no", sizeof(spt_str
));
10388 strlcpy(rp_str
, "-", sizeof(rp_str
));
10389 strlcpy(spt_str
, "-", sizeof(spt_str
));
10391 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10392 strlcpy(local_str
, "yes", sizeof(local_str
));
10394 strlcpy(local_str
, "no", sizeof(local_str
));
10397 json_object_object_get_ex(json
, grp_str
, &json_group
);
10400 json_group
= json_object_new_object();
10401 json_object_object_add(json
, grp_str
,
10405 json_row
= json_object_new_object();
10406 json_object_string_add(json_row
, "source", src_str
);
10407 json_object_string_add(json_row
, "group", grp_str
);
10408 json_object_string_add(json_row
, "rp", rp_str
);
10409 json_object_string_add(json_row
, "local", local_str
);
10410 json_object_string_add(json_row
, "sptSetup", spt_str
);
10411 json_object_string_add(json_row
, "upTime", timebuf
);
10412 json_object_object_add(json_group
, src_str
, json_row
);
10414 vty_out(vty
, "%-15s %15s %15s %5c %3c %8s\n",
10415 src_str
, grp_str
, rp_str
, local_str
[0],
10416 spt_str
[0], timebuf
);
10421 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10422 json
, JSON_C_TO_STRING_PRETTY
));
10423 json_object_free(json
);
10427 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa
*sa
,
10428 const char *src_str
,
10429 const char *grp_str
, struct vty
*vty
,
10430 bool uj
, json_object
*json
)
10432 char rp_str
[INET_ADDRSTRLEN
];
10433 char peer_str
[INET_ADDRSTRLEN
];
10434 char timebuf
[PIM_MSDP_UPTIME_STRLEN
];
10437 char statetimer
[PIM_MSDP_TIMER_STRLEN
];
10439 json_object
*json_group
= NULL
;
10440 json_object
*json_row
= NULL
;
10442 now
= pim_time_monotonic_sec();
10443 pim_time_uptime(timebuf
, sizeof(timebuf
), now
- sa
->uptime
);
10444 if (sa
->flags
& PIM_MSDP_SAF_PEER
) {
10445 pim_inet4_dump("<rp?>", sa
->rp
, rp_str
, sizeof(rp_str
));
10446 pim_inet4_dump("<peer?>", sa
->peer
, peer_str
, sizeof(peer_str
));
10448 strlcpy(spt_str
, "yes", sizeof(spt_str
));
10450 strlcpy(spt_str
, "no", sizeof(spt_str
));
10453 strlcpy(rp_str
, "-", sizeof(rp_str
));
10454 strlcpy(peer_str
, "-", sizeof(peer_str
));
10455 strlcpy(spt_str
, "-", sizeof(spt_str
));
10457 if (sa
->flags
& PIM_MSDP_SAF_LOCAL
) {
10458 strlcpy(local_str
, "yes", sizeof(local_str
));
10460 strlcpy(local_str
, "no", sizeof(local_str
));
10462 pim_time_timer_to_hhmmss(statetimer
, sizeof(statetimer
),
10463 sa
->sa_state_timer
);
10465 json_object_object_get_ex(json
, grp_str
, &json_group
);
10468 json_group
= json_object_new_object();
10469 json_object_object_add(json
, grp_str
, json_group
);
10472 json_row
= json_object_new_object();
10473 json_object_string_add(json_row
, "source", src_str
);
10474 json_object_string_add(json_row
, "group", grp_str
);
10475 json_object_string_add(json_row
, "rp", rp_str
);
10476 json_object_string_add(json_row
, "local", local_str
);
10477 json_object_string_add(json_row
, "sptSetup", spt_str
);
10478 json_object_string_add(json_row
, "upTime", timebuf
);
10479 json_object_string_add(json_row
, "stateTimer", statetimer
);
10480 json_object_object_add(json_group
, src_str
, json_row
);
10482 vty_out(vty
, "SA : %s\n", sa
->sg_str
);
10483 vty_out(vty
, " RP : %s\n", rp_str
);
10484 vty_out(vty
, " Peer : %s\n", peer_str
);
10485 vty_out(vty
, " Local : %s\n", local_str
);
10486 vty_out(vty
, " SPT Setup : %s\n", spt_str
);
10487 vty_out(vty
, " Uptime : %s\n", timebuf
);
10488 vty_out(vty
, " State Timer : %s\n", statetimer
);
10489 vty_out(vty
, "\n");
10493 static void ip_msdp_show_sa_detail(struct pim_instance
*pim
, struct vty
*vty
,
10496 struct listnode
*sanode
;
10497 struct pim_msdp_sa
*sa
;
10498 char src_str
[INET_ADDRSTRLEN
];
10499 char grp_str
[INET_ADDRSTRLEN
];
10500 json_object
*json
= NULL
;
10503 json
= json_object_new_object();
10506 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10507 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10508 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10509 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
, uj
,
10514 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10515 json
, JSON_C_TO_STRING_PRETTY
));
10516 json_object_free(json
);
10520 DEFUN (show_ip_msdp_sa_detail
,
10521 show_ip_msdp_sa_detail_cmd
,
10522 "show ip msdp [vrf NAME] sa detail [json]",
10527 "MSDP active-source information\n"
10528 "Detailed output\n"
10531 bool uj
= use_json(argc
, argv
);
10533 struct vrf
*vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10536 return CMD_WARNING
;
10538 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10540 return CMD_SUCCESS
;
10543 DEFUN (show_ip_msdp_sa_detail_vrf_all
,
10544 show_ip_msdp_sa_detail_vrf_all_cmd
,
10545 "show ip msdp vrf all sa detail [json]",
10550 "MSDP active-source information\n"
10551 "Detailed output\n"
10554 bool uj
= use_json(argc
, argv
);
10559 vty_out(vty
, "{ ");
10560 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10563 vty_out(vty
, ", ");
10564 vty_out(vty
, " \"%s\": ", vrf
->name
);
10567 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10568 ip_msdp_show_sa_detail(vrf
->info
, vty
, uj
);
10571 vty_out(vty
, "}\n");
10573 return CMD_SUCCESS
;
10576 static void ip_msdp_show_sa_addr(struct pim_instance
*pim
, struct vty
*vty
,
10577 const char *addr
, bool uj
)
10579 struct listnode
*sanode
;
10580 struct pim_msdp_sa
*sa
;
10581 char src_str
[INET_ADDRSTRLEN
];
10582 char grp_str
[INET_ADDRSTRLEN
];
10583 json_object
*json
= NULL
;
10586 json
= json_object_new_object();
10589 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10590 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10591 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10592 if (!strcmp(addr
, src_str
) || !strcmp(addr
, grp_str
)) {
10593 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10599 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10600 json
, JSON_C_TO_STRING_PRETTY
));
10601 json_object_free(json
);
10605 static void ip_msdp_show_sa_sg(struct pim_instance
*pim
, struct vty
*vty
,
10606 const char *src
, const char *grp
, bool uj
)
10608 struct listnode
*sanode
;
10609 struct pim_msdp_sa
*sa
;
10610 char src_str
[INET_ADDRSTRLEN
];
10611 char grp_str
[INET_ADDRSTRLEN
];
10612 json_object
*json
= NULL
;
10615 json
= json_object_new_object();
10618 for (ALL_LIST_ELEMENTS_RO(pim
->msdp
.sa_list
, sanode
, sa
)) {
10619 pim_inet4_dump("<src?>", sa
->sg
.src
, src_str
, sizeof(src_str
));
10620 pim_inet4_dump("<grp?>", sa
->sg
.grp
, grp_str
, sizeof(grp_str
));
10621 if (!strcmp(src
, src_str
) && !strcmp(grp
, grp_str
)) {
10622 ip_msdp_show_sa_entry_detail(sa
, src_str
, grp_str
, vty
,
10628 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10629 json
, JSON_C_TO_STRING_PRETTY
));
10630 json_object_free(json
);
10634 DEFUN (show_ip_msdp_sa_sg
,
10635 show_ip_msdp_sa_sg_cmd
,
10636 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10641 "MSDP active-source information\n"
10642 "source or group ip\n"
10646 bool uj
= use_json(argc
, argv
);
10650 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10653 return CMD_WARNING
;
10655 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10657 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10661 if (src_ip
&& grp_ip
)
10662 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10664 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10666 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10668 return CMD_SUCCESS
;
10671 DEFUN (show_ip_msdp_sa_sg_vrf_all
,
10672 show_ip_msdp_sa_sg_vrf_all_cmd
,
10673 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10678 "MSDP active-source information\n"
10679 "source or group ip\n"
10683 bool uj
= use_json(argc
, argv
);
10688 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
++]->arg
10690 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
)
10695 vty_out(vty
, "{ ");
10696 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
10699 vty_out(vty
, ", ");
10700 vty_out(vty
, " \"%s\": ", vrf
->name
);
10703 vty_out(vty
, "VRF: %s\n", vrf
->name
);
10705 if (src_ip
&& grp_ip
)
10706 ip_msdp_show_sa_sg(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10708 ip_msdp_show_sa_addr(vrf
->info
, vty
, src_ip
, uj
);
10710 ip_msdp_show_sa(vrf
->info
, vty
, uj
);
10713 vty_out(vty
, "}\n");
10715 return CMD_SUCCESS
;
10718 struct pim_sg_cache_walk_data
{
10721 json_object
*json_group
;
10722 struct in_addr addr
;
10726 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg
*vxlan_sg
,
10727 struct pim_sg_cache_walk_data
*cwd
)
10729 struct vty
*vty
= cwd
->vty
;
10730 json_object
*json
= cwd
->json
;
10731 char src_str
[INET_ADDRSTRLEN
];
10732 char grp_str
[INET_ADDRSTRLEN
];
10733 json_object
*json_row
;
10734 bool installed
= (vxlan_sg
->up
) ? true : false;
10735 const char *iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10736 const char *oif_name
;
10738 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10739 oif_name
= vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10741 oif_name
= vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10743 if (cwd
->addr_match
&& (vxlan_sg
->sg
.src
.s_addr
!= cwd
->addr
.s_addr
) &&
10744 (vxlan_sg
->sg
.grp
.s_addr
!= cwd
->addr
.s_addr
)) {
10747 pim_inet4_dump("<src?>", vxlan_sg
->sg
.src
, src_str
, sizeof(src_str
));
10748 pim_inet4_dump("<grp?>", vxlan_sg
->sg
.grp
, grp_str
, sizeof(grp_str
));
10750 json_object_object_get_ex(json
, grp_str
, &cwd
->json_group
);
10752 if (!cwd
->json_group
) {
10753 cwd
->json_group
= json_object_new_object();
10754 json_object_object_add(json
, grp_str
,
10758 json_row
= json_object_new_object();
10759 json_object_string_add(json_row
, "source", src_str
);
10760 json_object_string_add(json_row
, "group", grp_str
);
10761 json_object_string_add(json_row
, "input", iif_name
);
10762 json_object_string_add(json_row
, "output", oif_name
);
10764 json_object_boolean_true_add(json_row
, "installed");
10766 json_object_boolean_false_add(json_row
, "installed");
10767 json_object_object_add(cwd
->json_group
, src_str
, json_row
);
10769 vty_out(vty
, "%-15s %-15s %-15s %-15s %-5s\n",
10770 src_str
, grp_str
, iif_name
, oif_name
,
10775 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket
*bucket
, void *arg
)
10777 pim_show_vxlan_sg_entry((struct pim_vxlan_sg
*)bucket
->data
,
10778 (struct pim_sg_cache_walk_data
*)arg
);
10781 static void pim_show_vxlan_sg(struct pim_instance
*pim
,
10782 struct vty
*vty
, bool uj
)
10784 json_object
*json
= NULL
;
10785 struct pim_sg_cache_walk_data cwd
;
10788 json
= json_object_new_object();
10790 vty_out(vty
, "Codes: I -> installed\n");
10792 "Source Group Input Output Flags\n");
10795 memset(&cwd
, 0, sizeof(cwd
));
10798 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10801 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10802 json
, JSON_C_TO_STRING_PRETTY
));
10803 json_object_free(json
);
10807 static void pim_show_vxlan_sg_match_addr(struct pim_instance
*pim
,
10808 struct vty
*vty
, char *addr_str
,
10811 json_object
*json
= NULL
;
10812 struct pim_sg_cache_walk_data cwd
;
10815 memset(&cwd
, 0, sizeof(cwd
));
10816 result
= inet_pton(AF_INET
, addr_str
, &cwd
.addr
);
10818 vty_out(vty
, "Bad address %s: errno=%d: %s\n", addr_str
,
10819 errno
, safe_strerror(errno
));
10824 json
= json_object_new_object();
10826 vty_out(vty
, "Codes: I -> installed\n");
10828 "Source Group Input Output Flags\n");
10833 cwd
.addr_match
= true;
10834 hash_iterate(pim
->vxlan
.sg_hash
, pim_show_vxlan_sg_hash_entry
, &cwd
);
10837 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10838 json
, JSON_C_TO_STRING_PRETTY
));
10839 json_object_free(json
);
10843 static void pim_show_vxlan_sg_one(struct pim_instance
*pim
,
10844 struct vty
*vty
, char *src_str
, char *grp_str
,
10847 json_object
*json
= NULL
;
10848 struct prefix_sg sg
;
10850 struct pim_vxlan_sg
*vxlan_sg
;
10851 const char *iif_name
;
10853 const char *oif_name
;
10855 result
= inet_pton(AF_INET
, src_str
, &sg
.src
);
10857 vty_out(vty
, "Bad src address %s: errno=%d: %s\n", src_str
,
10858 errno
, safe_strerror(errno
));
10861 result
= inet_pton(AF_INET
, grp_str
, &sg
.grp
);
10863 vty_out(vty
, "Bad grp address %s: errno=%d: %s\n", grp_str
,
10864 errno
, safe_strerror(errno
));
10868 sg
.family
= AF_INET
;
10869 sg
.prefixlen
= IPV4_MAX_BITLEN
;
10871 json
= json_object_new_object();
10873 vxlan_sg
= pim_vxlan_sg_find(pim
, &sg
);
10875 installed
= (vxlan_sg
->up
) ? true : false;
10876 iif_name
= vxlan_sg
->iif
?vxlan_sg
->iif
->name
:"-";
10878 if (pim_vxlan_is_orig_mroute(vxlan_sg
))
10880 vxlan_sg
->orig_oif
?vxlan_sg
->orig_oif
->name
:"";
10883 vxlan_sg
->term_oif
?vxlan_sg
->term_oif
->name
:"";
10886 json_object_string_add(json
, "source", src_str
);
10887 json_object_string_add(json
, "group", grp_str
);
10888 json_object_string_add(json
, "input", iif_name
);
10889 json_object_string_add(json
, "output", oif_name
);
10891 json_object_boolean_true_add(json
, "installed");
10893 json_object_boolean_false_add(json
,
10896 vty_out(vty
, "SG : %s\n", vxlan_sg
->sg_str
);
10897 vty_out(vty
, " Input : %s\n", iif_name
);
10898 vty_out(vty
, " Output : %s\n", oif_name
);
10899 vty_out(vty
, " installed : %s\n",
10900 installed
?"yes":"no");
10905 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10906 json
, JSON_C_TO_STRING_PRETTY
));
10907 json_object_free(json
);
10911 DEFUN (show_ip_pim_vxlan_sg
,
10912 show_ip_pim_vxlan_sg_cmd
,
10913 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10918 "VxLAN BUM groups\n"
10919 "source or group ip\n"
10923 bool uj
= use_json(argc
, argv
);
10927 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10930 return CMD_WARNING
;
10932 char *src_ip
= argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10933 argv
[idx
++]->arg
:NULL
;
10934 char *grp_ip
= idx
< argc
&& argv_find(argv
, argc
, "A.B.C.D", &idx
) ?
10935 argv
[idx
]->arg
:NULL
;
10937 if (src_ip
&& grp_ip
)
10938 pim_show_vxlan_sg_one(vrf
->info
, vty
, src_ip
, grp_ip
, uj
);
10940 pim_show_vxlan_sg_match_addr(vrf
->info
, vty
, src_ip
, uj
);
10942 pim_show_vxlan_sg(vrf
->info
, vty
, uj
);
10944 return CMD_SUCCESS
;
10947 static void pim_show_vxlan_sg_work(struct pim_instance
*pim
,
10948 struct vty
*vty
, bool uj
)
10950 json_object
*json
= NULL
;
10951 struct pim_sg_cache_walk_data cwd
;
10952 struct listnode
*node
;
10953 struct pim_vxlan_sg
*vxlan_sg
;
10956 json
= json_object_new_object();
10958 vty_out(vty
, "Codes: I -> installed\n");
10960 "Source Group Input Flags\n");
10963 memset(&cwd
, 0, sizeof(cwd
));
10966 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p
->work_list
, node
, vxlan_sg
))
10967 pim_show_vxlan_sg_entry(vxlan_sg
, &cwd
);
10970 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10971 json
, JSON_C_TO_STRING_PRETTY
));
10972 json_object_free(json
);
10976 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work
,
10977 show_ip_pim_vxlan_sg_work_cmd
,
10978 "show ip pim [vrf NAME] vxlan-work [json]",
10983 "VxLAN work list\n"
10986 bool uj
= use_json(argc
, argv
);
10990 vrf
= pim_cmd_lookup_vrf(vty
, argv
, argc
, &idx
);
10993 return CMD_WARNING
;
10995 pim_show_vxlan_sg_work(vrf
->info
, vty
, uj
);
10997 return CMD_SUCCESS
;
11000 DEFUN_HIDDEN (no_ip_pim_mlag
,
11001 no_ip_pim_mlag_cmd
,
11008 char mlag_xpath
[XPATH_MAXLEN
];
11010 snprintf(mlag_xpath
, sizeof(mlag_xpath
), FRR_PIM_AF_XPATH
,
11011 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11012 strlcat(mlag_xpath
, "/mlag", sizeof(mlag_xpath
));
11014 nb_cli_enqueue_change(vty
, mlag_xpath
, NB_OP_DESTROY
, NULL
);
11017 return nb_cli_apply_changes(vty
, NULL
);
11020 DEFUN_HIDDEN (ip_pim_mlag
,
11022 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
11026 "peerlink sub interface\n"
11028 "MLAG role primary\n"
11029 "MLAG role secondary\n"
11030 "peer session state\n"
11031 "peer session state up\n"
11032 "peer session state down\n"
11034 "unique ip address\n")
11037 char mlag_peerlink_rif_xpath
[XPATH_MAXLEN
];
11038 char mlag_my_role_xpath
[XPATH_MAXLEN
];
11039 char mlag_peer_state_xpath
[XPATH_MAXLEN
];
11040 char mlag_reg_address_xpath
[XPATH_MAXLEN
];
11042 snprintf(mlag_peerlink_rif_xpath
, sizeof(mlag_peerlink_rif_xpath
),
11044 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11045 strlcat(mlag_peerlink_rif_xpath
, "/mlag/peerlink-rif",
11046 sizeof(mlag_peerlink_rif_xpath
));
11049 nb_cli_enqueue_change(vty
, mlag_peerlink_rif_xpath
, NB_OP_MODIFY
,
11052 snprintf(mlag_my_role_xpath
, sizeof(mlag_my_role_xpath
),
11054 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11055 strlcat(mlag_my_role_xpath
, "/mlag/my-role",
11056 sizeof(mlag_my_role_xpath
));
11059 if (!strcmp(argv
[idx
]->arg
, "primary")) {
11060 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
11061 "MLAG_ROLE_PRIMARY");
11063 } else if (!strcmp(argv
[idx
]->arg
, "secondary")) {
11064 nb_cli_enqueue_change(vty
, mlag_my_role_xpath
, NB_OP_MODIFY
,
11065 "MLAG_ROLE_SECONDARY");
11068 vty_out(vty
, "unknown MLAG role %s\n", argv
[idx
]->arg
);
11069 return CMD_WARNING
;
11072 snprintf(mlag_peer_state_xpath
, sizeof(mlag_peer_state_xpath
),
11074 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11075 strlcat(mlag_peer_state_xpath
, "/mlag/peer-state",
11076 sizeof(mlag_peer_state_xpath
));
11079 if (!strcmp(argv
[idx
]->arg
, "up")) {
11080 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
11083 } else if (strcmp(argv
[idx
]->arg
, "down")) {
11084 nb_cli_enqueue_change(vty
, mlag_peer_state_xpath
, NB_OP_MODIFY
,
11088 vty_out(vty
, "unknown MLAG state %s\n", argv
[idx
]->arg
);
11089 return CMD_WARNING
;
11092 snprintf(mlag_reg_address_xpath
, sizeof(mlag_reg_address_xpath
),
11094 "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
11095 strlcat(mlag_reg_address_xpath
, "/mlag/reg-address",
11096 sizeof(mlag_reg_address_xpath
));
11099 nb_cli_enqueue_change(vty
, mlag_reg_address_xpath
, NB_OP_MODIFY
,
11102 return nb_cli_apply_changes(vty
, NULL
);
11105 void pim_cmd_init(void)
11107 install_node(&interface_node
); /* INTERFACE_NODE */
11110 install_node(&debug_node
);
11112 install_element(ENABLE_NODE
, &pim_test_sg_keepalive_cmd
);
11114 install_element(CONFIG_NODE
, &ip_pim_rp_cmd
);
11115 install_element(VRF_NODE
, &ip_pim_rp_cmd
);
11116 install_element(CONFIG_NODE
, &no_ip_pim_rp_cmd
);
11117 install_element(VRF_NODE
, &no_ip_pim_rp_cmd
);
11118 install_element(CONFIG_NODE
, &ip_pim_rp_prefix_list_cmd
);
11119 install_element(VRF_NODE
, &ip_pim_rp_prefix_list_cmd
);
11120 install_element(CONFIG_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11121 install_element(VRF_NODE
, &no_ip_pim_rp_prefix_list_cmd
);
11122 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11123 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_cmd
);
11124 install_element(CONFIG_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11125 install_element(VRF_NODE
, &no_ip_pim_ssm_prefix_list_name_cmd
);
11126 install_element(CONFIG_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11127 install_element(VRF_NODE
, &ip_pim_ssm_prefix_list_cmd
);
11128 install_element(CONFIG_NODE
, &ip_pim_register_suppress_cmd
);
11129 install_element(CONFIG_NODE
, &no_ip_pim_register_suppress_cmd
);
11130 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11131 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_cmd
);
11132 install_element(CONFIG_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11133 install_element(VRF_NODE
, &ip_pim_spt_switchover_infinity_plist_cmd
);
11134 install_element(CONFIG_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11135 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_cmd
);
11136 install_element(CONFIG_NODE
,
11137 &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11138 install_element(VRF_NODE
, &no_ip_pim_spt_switchover_infinity_plist_cmd
);
11139 install_element(CONFIG_NODE
, &pim_register_accept_list_cmd
);
11140 install_element(VRF_NODE
, &pim_register_accept_list_cmd
);
11141 install_element(CONFIG_NODE
, &ip_pim_joinprune_time_cmd
);
11142 install_element(CONFIG_NODE
, &no_ip_pim_joinprune_time_cmd
);
11143 install_element(CONFIG_NODE
, &ip_pim_keep_alive_cmd
);
11144 install_element(VRF_NODE
, &ip_pim_keep_alive_cmd
);
11145 install_element(CONFIG_NODE
, &ip_pim_rp_keep_alive_cmd
);
11146 install_element(VRF_NODE
, &ip_pim_rp_keep_alive_cmd
);
11147 install_element(CONFIG_NODE
, &no_ip_pim_keep_alive_cmd
);
11148 install_element(VRF_NODE
, &no_ip_pim_keep_alive_cmd
);
11149 install_element(CONFIG_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11150 install_element(VRF_NODE
, &no_ip_pim_rp_keep_alive_cmd
);
11151 install_element(CONFIG_NODE
, &ip_pim_packets_cmd
);
11152 install_element(CONFIG_NODE
, &no_ip_pim_packets_cmd
);
11153 install_element(CONFIG_NODE
, &ip_pim_v6_secondary_cmd
);
11154 install_element(VRF_NODE
, &ip_pim_v6_secondary_cmd
);
11155 install_element(CONFIG_NODE
, &no_ip_pim_v6_secondary_cmd
);
11156 install_element(VRF_NODE
, &no_ip_pim_v6_secondary_cmd
);
11157 install_element(CONFIG_NODE
, &ip_ssmpingd_cmd
);
11158 install_element(VRF_NODE
, &ip_ssmpingd_cmd
);
11159 install_element(CONFIG_NODE
, &no_ip_ssmpingd_cmd
);
11160 install_element(VRF_NODE
, &no_ip_ssmpingd_cmd
);
11161 install_element(CONFIG_NODE
, &ip_msdp_peer_cmd
);
11162 install_element(VRF_NODE
, &ip_msdp_peer_cmd
);
11163 install_element(CONFIG_NODE
, &no_ip_msdp_peer_cmd
);
11164 install_element(VRF_NODE
, &no_ip_msdp_peer_cmd
);
11165 install_element(CONFIG_NODE
, &ip_pim_ecmp_cmd
);
11166 install_element(VRF_NODE
, &ip_pim_ecmp_cmd
);
11167 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_cmd
);
11168 install_element(VRF_NODE
, &no_ip_pim_ecmp_cmd
);
11169 install_element(CONFIG_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11170 install_element(VRF_NODE
, &ip_pim_ecmp_rebalance_cmd
);
11171 install_element(CONFIG_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11172 install_element(VRF_NODE
, &no_ip_pim_ecmp_rebalance_cmd
);
11173 install_element(CONFIG_NODE
, &ip_pim_mlag_cmd
);
11174 install_element(CONFIG_NODE
, &no_ip_pim_mlag_cmd
);
11175 install_element(CONFIG_NODE
, &igmp_group_watermark_cmd
);
11176 install_element(VRF_NODE
, &igmp_group_watermark_cmd
);
11177 install_element(CONFIG_NODE
, &no_igmp_group_watermark_cmd
);
11178 install_element(VRF_NODE
, &no_igmp_group_watermark_cmd
);
11180 install_element(INTERFACE_NODE
, &interface_ip_igmp_cmd
);
11181 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_cmd
);
11182 install_element(INTERFACE_NODE
, &interface_ip_igmp_join_cmd
);
11183 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_join_cmd
);
11184 install_element(INTERFACE_NODE
, &interface_ip_igmp_version_cmd
);
11185 install_element(INTERFACE_NODE
, &interface_no_ip_igmp_version_cmd
);
11186 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_interval_cmd
);
11187 install_element(INTERFACE_NODE
,
11188 &interface_no_ip_igmp_query_interval_cmd
);
11189 install_element(INTERFACE_NODE
,
11190 &interface_ip_igmp_query_max_response_time_cmd
);
11191 install_element(INTERFACE_NODE
,
11192 &interface_no_ip_igmp_query_max_response_time_cmd
);
11193 install_element(INTERFACE_NODE
,
11194 &interface_ip_igmp_query_max_response_time_dsec_cmd
);
11195 install_element(INTERFACE_NODE
,
11196 &interface_no_ip_igmp_query_max_response_time_dsec_cmd
);
11197 install_element(INTERFACE_NODE
,
11198 &interface_ip_igmp_last_member_query_count_cmd
);
11199 install_element(INTERFACE_NODE
,
11200 &interface_no_ip_igmp_last_member_query_count_cmd
);
11201 install_element(INTERFACE_NODE
,
11202 &interface_ip_igmp_last_member_query_interval_cmd
);
11203 install_element(INTERFACE_NODE
,
11204 &interface_no_ip_igmp_last_member_query_interval_cmd
);
11205 install_element(INTERFACE_NODE
, &interface_ip_pim_activeactive_cmd
);
11206 install_element(INTERFACE_NODE
, &interface_ip_pim_ssm_cmd
);
11207 install_element(INTERFACE_NODE
, &interface_no_ip_pim_ssm_cmd
);
11208 install_element(INTERFACE_NODE
, &interface_ip_pim_sm_cmd
);
11209 install_element(INTERFACE_NODE
, &interface_no_ip_pim_sm_cmd
);
11210 install_element(INTERFACE_NODE
, &interface_ip_pim_cmd
);
11211 install_element(INTERFACE_NODE
, &interface_no_ip_pim_cmd
);
11212 install_element(INTERFACE_NODE
, &interface_ip_pim_drprio_cmd
);
11213 install_element(INTERFACE_NODE
, &interface_no_ip_pim_drprio_cmd
);
11214 install_element(INTERFACE_NODE
, &interface_ip_pim_hello_cmd
);
11215 install_element(INTERFACE_NODE
, &interface_no_ip_pim_hello_cmd
);
11216 install_element(INTERFACE_NODE
, &interface_ip_pim_boundary_oil_cmd
);
11217 install_element(INTERFACE_NODE
, &interface_no_ip_pim_boundary_oil_cmd
);
11218 install_element(INTERFACE_NODE
, &interface_ip_igmp_query_generate_cmd
);
11220 // Static mroutes NEB
11221 install_element(INTERFACE_NODE
, &interface_ip_mroute_cmd
);
11222 install_element(INTERFACE_NODE
, &interface_no_ip_mroute_cmd
);
11224 install_element(VIEW_NODE
, &show_ip_igmp_interface_cmd
);
11225 install_element(VIEW_NODE
, &show_ip_igmp_interface_vrf_all_cmd
);
11226 install_element(VIEW_NODE
, &show_ip_igmp_join_cmd
);
11227 install_element(VIEW_NODE
, &show_ip_igmp_join_vrf_all_cmd
);
11228 install_element(VIEW_NODE
, &show_ip_igmp_groups_cmd
);
11229 install_element(VIEW_NODE
, &show_ip_igmp_groups_vrf_all_cmd
);
11230 install_element(VIEW_NODE
, &show_ip_igmp_groups_retransmissions_cmd
);
11231 install_element(VIEW_NODE
, &show_ip_igmp_sources_cmd
);
11232 install_element(VIEW_NODE
, &show_ip_igmp_sources_retransmissions_cmd
);
11233 install_element(VIEW_NODE
, &show_ip_igmp_statistics_cmd
);
11234 install_element(VIEW_NODE
, &show_ip_pim_assert_cmd
);
11235 install_element(VIEW_NODE
, &show_ip_pim_assert_internal_cmd
);
11236 install_element(VIEW_NODE
, &show_ip_pim_assert_metric_cmd
);
11237 install_element(VIEW_NODE
, &show_ip_pim_assert_winner_metric_cmd
);
11238 install_element(VIEW_NODE
, &show_ip_pim_interface_traffic_cmd
);
11239 install_element(VIEW_NODE
, &show_ip_pim_interface_cmd
);
11240 install_element(VIEW_NODE
, &show_ip_pim_interface_vrf_all_cmd
);
11241 install_element(VIEW_NODE
, &show_ip_pim_join_cmd
);
11242 install_element(VIEW_NODE
, &show_ip_pim_join_vrf_all_cmd
);
11243 install_element(VIEW_NODE
, &show_ip_pim_jp_agg_cmd
);
11244 install_element(VIEW_NODE
, &show_ip_pim_local_membership_cmd
);
11245 install_element(VIEW_NODE
, &show_ip_pim_mlag_summary_cmd
);
11246 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_cmd
);
11247 install_element(VIEW_NODE
, &show_ip_pim_mlag_up_vrf_all_cmd
);
11248 install_element(VIEW_NODE
, &show_ip_pim_neighbor_cmd
);
11249 install_element(VIEW_NODE
, &show_ip_pim_neighbor_vrf_all_cmd
);
11250 install_element(VIEW_NODE
, &show_ip_pim_rpf_cmd
);
11251 install_element(VIEW_NODE
, &show_ip_pim_rpf_vrf_all_cmd
);
11252 install_element(VIEW_NODE
, &show_ip_pim_secondary_cmd
);
11253 install_element(VIEW_NODE
, &show_ip_pim_state_cmd
);
11254 install_element(VIEW_NODE
, &show_ip_pim_state_vrf_all_cmd
);
11255 install_element(VIEW_NODE
, &show_ip_pim_upstream_cmd
);
11256 install_element(VIEW_NODE
, &show_ip_pim_upstream_vrf_all_cmd
);
11257 install_element(VIEW_NODE
, &show_ip_pim_channel_cmd
);
11258 install_element(VIEW_NODE
, &show_ip_pim_upstream_join_desired_cmd
);
11259 install_element(VIEW_NODE
, &show_ip_pim_upstream_rpf_cmd
);
11260 install_element(VIEW_NODE
, &show_ip_pim_rp_cmd
);
11261 install_element(VIEW_NODE
, &show_ip_pim_rp_vrf_all_cmd
);
11262 install_element(VIEW_NODE
, &show_ip_pim_bsr_cmd
);
11263 install_element(VIEW_NODE
, &show_ip_multicast_cmd
);
11264 install_element(VIEW_NODE
, &show_ip_multicast_vrf_all_cmd
);
11265 install_element(VIEW_NODE
, &show_ip_multicast_count_cmd
);
11266 install_element(VIEW_NODE
, &show_ip_multicast_count_vrf_all_cmd
);
11267 install_element(VIEW_NODE
, &show_ip_mroute_cmd
);
11268 install_element(VIEW_NODE
, &show_ip_mroute_vrf_all_cmd
);
11269 install_element(VIEW_NODE
, &show_ip_mroute_count_cmd
);
11270 install_element(VIEW_NODE
, &show_ip_mroute_count_vrf_all_cmd
);
11271 install_element(VIEW_NODE
, &show_ip_mroute_summary_cmd
);
11272 install_element(VIEW_NODE
, &show_ip_mroute_summary_vrf_all_cmd
);
11273 install_element(VIEW_NODE
, &show_ip_rib_cmd
);
11274 install_element(VIEW_NODE
, &show_ip_ssmpingd_cmd
);
11275 install_element(VIEW_NODE
, &show_ip_pim_nexthop_cmd
);
11276 install_element(VIEW_NODE
, &show_ip_pim_nexthop_lookup_cmd
);
11277 install_element(VIEW_NODE
, &show_ip_pim_bsrp_cmd
);
11278 install_element(VIEW_NODE
, &show_ip_pim_bsm_db_cmd
);
11279 install_element(VIEW_NODE
, &show_ip_pim_statistics_cmd
);
11281 install_element(ENABLE_NODE
, &clear_ip_mroute_count_cmd
);
11282 install_element(ENABLE_NODE
, &clear_ip_interfaces_cmd
);
11283 install_element(ENABLE_NODE
, &clear_ip_igmp_interfaces_cmd
);
11284 install_element(ENABLE_NODE
, &clear_ip_mroute_cmd
);
11285 install_element(ENABLE_NODE
, &clear_ip_pim_interfaces_cmd
);
11286 install_element(ENABLE_NODE
, &clear_ip_pim_interface_traffic_cmd
);
11287 install_element(ENABLE_NODE
, &clear_ip_pim_oil_cmd
);
11288 install_element(ENABLE_NODE
, &clear_ip_pim_statistics_cmd
);
11289 install_element(ENABLE_NODE
, &clear_ip_pim_bsr_db_cmd
);
11291 install_element(ENABLE_NODE
, &show_debugging_pim_cmd
);
11293 install_element(ENABLE_NODE
, &debug_igmp_cmd
);
11294 install_element(ENABLE_NODE
, &no_debug_igmp_cmd
);
11295 install_element(ENABLE_NODE
, &debug_igmp_events_cmd
);
11296 install_element(ENABLE_NODE
, &no_debug_igmp_events_cmd
);
11297 install_element(ENABLE_NODE
, &debug_igmp_packets_cmd
);
11298 install_element(ENABLE_NODE
, &no_debug_igmp_packets_cmd
);
11299 install_element(ENABLE_NODE
, &debug_igmp_trace_cmd
);
11300 install_element(ENABLE_NODE
, &no_debug_igmp_trace_cmd
);
11301 install_element(ENABLE_NODE
, &debug_mroute_cmd
);
11302 install_element(ENABLE_NODE
, &debug_mroute_detail_cmd
);
11303 install_element(ENABLE_NODE
, &no_debug_mroute_cmd
);
11304 install_element(ENABLE_NODE
, &no_debug_mroute_detail_cmd
);
11305 install_element(ENABLE_NODE
, &debug_pim_static_cmd
);
11306 install_element(ENABLE_NODE
, &no_debug_pim_static_cmd
);
11307 install_element(ENABLE_NODE
, &debug_pim_cmd
);
11308 install_element(ENABLE_NODE
, &no_debug_pim_cmd
);
11309 install_element(ENABLE_NODE
, &debug_pim_nht_cmd
);
11310 install_element(ENABLE_NODE
, &no_debug_pim_nht_cmd
);
11311 install_element(ENABLE_NODE
, &debug_pim_nht_rp_cmd
);
11312 install_element(ENABLE_NODE
, &no_debug_pim_nht_rp_cmd
);
11313 install_element(ENABLE_NODE
, &debug_pim_events_cmd
);
11314 install_element(ENABLE_NODE
, &no_debug_pim_events_cmd
);
11315 install_element(ENABLE_NODE
, &debug_pim_packets_cmd
);
11316 install_element(ENABLE_NODE
, &no_debug_pim_packets_cmd
);
11317 install_element(ENABLE_NODE
, &debug_pim_packetdump_send_cmd
);
11318 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_send_cmd
);
11319 install_element(ENABLE_NODE
, &debug_pim_packetdump_recv_cmd
);
11320 install_element(ENABLE_NODE
, &no_debug_pim_packetdump_recv_cmd
);
11321 install_element(ENABLE_NODE
, &debug_pim_trace_cmd
);
11322 install_element(ENABLE_NODE
, &no_debug_pim_trace_cmd
);
11323 install_element(ENABLE_NODE
, &debug_pim_trace_detail_cmd
);
11324 install_element(ENABLE_NODE
, &no_debug_pim_trace_detail_cmd
);
11325 install_element(ENABLE_NODE
, &debug_ssmpingd_cmd
);
11326 install_element(ENABLE_NODE
, &no_debug_ssmpingd_cmd
);
11327 install_element(ENABLE_NODE
, &debug_pim_zebra_cmd
);
11328 install_element(ENABLE_NODE
, &no_debug_pim_zebra_cmd
);
11329 install_element(ENABLE_NODE
, &debug_pim_mlag_cmd
);
11330 install_element(ENABLE_NODE
, &no_debug_pim_mlag_cmd
);
11331 install_element(ENABLE_NODE
, &debug_pim_vxlan_cmd
);
11332 install_element(ENABLE_NODE
, &no_debug_pim_vxlan_cmd
);
11333 install_element(ENABLE_NODE
, &debug_msdp_cmd
);
11334 install_element(ENABLE_NODE
, &no_debug_msdp_cmd
);
11335 install_element(ENABLE_NODE
, &debug_msdp_events_cmd
);
11336 install_element(ENABLE_NODE
, &no_debug_msdp_events_cmd
);
11337 install_element(ENABLE_NODE
, &debug_msdp_packets_cmd
);
11338 install_element(ENABLE_NODE
, &no_debug_msdp_packets_cmd
);
11339 install_element(ENABLE_NODE
, &debug_mtrace_cmd
);
11340 install_element(ENABLE_NODE
, &no_debug_mtrace_cmd
);
11341 install_element(ENABLE_NODE
, &debug_bsm_cmd
);
11342 install_element(ENABLE_NODE
, &no_debug_bsm_cmd
);
11344 install_element(CONFIG_NODE
, &debug_igmp_cmd
);
11345 install_element(CONFIG_NODE
, &no_debug_igmp_cmd
);
11346 install_element(CONFIG_NODE
, &debug_igmp_events_cmd
);
11347 install_element(CONFIG_NODE
, &no_debug_igmp_events_cmd
);
11348 install_element(CONFIG_NODE
, &debug_igmp_packets_cmd
);
11349 install_element(CONFIG_NODE
, &no_debug_igmp_packets_cmd
);
11350 install_element(CONFIG_NODE
, &debug_igmp_trace_cmd
);
11351 install_element(CONFIG_NODE
, &no_debug_igmp_trace_cmd
);
11352 install_element(CONFIG_NODE
, &debug_mroute_cmd
);
11353 install_element(CONFIG_NODE
, &debug_mroute_detail_cmd
);
11354 install_element(CONFIG_NODE
, &no_debug_mroute_cmd
);
11355 install_element(CONFIG_NODE
, &no_debug_mroute_detail_cmd
);
11356 install_element(CONFIG_NODE
, &debug_pim_static_cmd
);
11357 install_element(CONFIG_NODE
, &no_debug_pim_static_cmd
);
11358 install_element(CONFIG_NODE
, &debug_pim_cmd
);
11359 install_element(CONFIG_NODE
, &no_debug_pim_cmd
);
11360 install_element(CONFIG_NODE
, &debug_pim_nht_cmd
);
11361 install_element(CONFIG_NODE
, &no_debug_pim_nht_cmd
);
11362 install_element(CONFIG_NODE
, &debug_pim_nht_rp_cmd
);
11363 install_element(CONFIG_NODE
, &no_debug_pim_nht_rp_cmd
);
11364 install_element(CONFIG_NODE
, &debug_pim_events_cmd
);
11365 install_element(CONFIG_NODE
, &no_debug_pim_events_cmd
);
11366 install_element(CONFIG_NODE
, &debug_pim_packets_cmd
);
11367 install_element(CONFIG_NODE
, &no_debug_pim_packets_cmd
);
11368 install_element(CONFIG_NODE
, &debug_pim_trace_cmd
);
11369 install_element(CONFIG_NODE
, &no_debug_pim_trace_cmd
);
11370 install_element(CONFIG_NODE
, &debug_pim_trace_detail_cmd
);
11371 install_element(CONFIG_NODE
, &no_debug_pim_trace_detail_cmd
);
11372 install_element(CONFIG_NODE
, &debug_ssmpingd_cmd
);
11373 install_element(CONFIG_NODE
, &no_debug_ssmpingd_cmd
);
11374 install_element(CONFIG_NODE
, &debug_pim_zebra_cmd
);
11375 install_element(CONFIG_NODE
, &no_debug_pim_zebra_cmd
);
11376 install_element(CONFIG_NODE
, &debug_pim_mlag_cmd
);
11377 install_element(CONFIG_NODE
, &no_debug_pim_mlag_cmd
);
11378 install_element(CONFIG_NODE
, &debug_pim_vxlan_cmd
);
11379 install_element(CONFIG_NODE
, &no_debug_pim_vxlan_cmd
);
11380 install_element(CONFIG_NODE
, &debug_msdp_cmd
);
11381 install_element(CONFIG_NODE
, &no_debug_msdp_cmd
);
11382 install_element(CONFIG_NODE
, &debug_msdp_events_cmd
);
11383 install_element(CONFIG_NODE
, &no_debug_msdp_events_cmd
);
11384 install_element(CONFIG_NODE
, &debug_msdp_packets_cmd
);
11385 install_element(CONFIG_NODE
, &no_debug_msdp_packets_cmd
);
11386 install_element(CONFIG_NODE
, &debug_mtrace_cmd
);
11387 install_element(CONFIG_NODE
, &no_debug_mtrace_cmd
);
11388 install_element(CONFIG_NODE
, &debug_bsm_cmd
);
11389 install_element(CONFIG_NODE
, &no_debug_bsm_cmd
);
11391 install_element(CONFIG_NODE
, &ip_msdp_timers_cmd
);
11392 install_element(VRF_NODE
, &ip_msdp_timers_cmd
);
11393 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_member_cmd
);
11394 install_element(VRF_NODE
, &ip_msdp_mesh_group_member_cmd
);
11395 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11396 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_member_cmd
);
11397 install_element(CONFIG_NODE
, &ip_msdp_mesh_group_source_cmd
);
11398 install_element(VRF_NODE
, &ip_msdp_mesh_group_source_cmd
);
11399 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11400 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_source_cmd
);
11401 install_element(CONFIG_NODE
, &no_ip_msdp_mesh_group_cmd
);
11402 install_element(VRF_NODE
, &no_ip_msdp_mesh_group_cmd
);
11403 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_cmd
);
11404 install_element(VIEW_NODE
, &show_ip_msdp_peer_detail_vrf_all_cmd
);
11405 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_cmd
);
11406 install_element(VIEW_NODE
, &show_ip_msdp_sa_detail_vrf_all_cmd
);
11407 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_cmd
);
11408 install_element(VIEW_NODE
, &show_ip_msdp_sa_sg_vrf_all_cmd
);
11409 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_cmd
);
11410 install_element(VIEW_NODE
, &show_ip_msdp_mesh_group_vrf_all_cmd
);
11411 install_element(VIEW_NODE
, &show_ip_pim_ssm_range_cmd
);
11412 install_element(VIEW_NODE
, &show_ip_pim_group_type_cmd
);
11413 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_cmd
);
11414 install_element(VIEW_NODE
, &show_ip_pim_vxlan_sg_work_cmd
);
11415 install_element(INTERFACE_NODE
, &interface_pim_use_source_cmd
);
11416 install_element(INTERFACE_NODE
, &interface_no_pim_use_source_cmd
);
11417 /* Install BSM command */
11418 install_element(INTERFACE_NODE
, &ip_pim_bsm_cmd
);
11419 install_element(INTERFACE_NODE
, &no_ip_pim_bsm_cmd
);
11420 install_element(INTERFACE_NODE
, &ip_pim_ucast_bsm_cmd
);
11421 install_element(INTERFACE_NODE
, &no_ip_pim_ucast_bsm_cmd
);
11422 /* Install BFD command */
11423 install_element(INTERFACE_NODE
, &ip_pim_bfd_cmd
);
11424 install_element(INTERFACE_NODE
, &ip_pim_bfd_param_cmd
);
11425 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_profile_cmd
);
11426 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_cmd
);
11428 install_element(INTERFACE_NODE
, &no_ip_pim_bfd_param_cmd
);
11429 #endif /* !HAVE_BFDD */