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