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