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