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