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