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