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