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