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