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