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