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