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