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