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