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