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