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