]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_cmd.c
Merge pull request #42 from donaldsharp/pim_lib_work2
[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 {
1370 vty_out(vty, "%sSource Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE);
1371 }
1372
040d86ad 1373 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
eaa54bdb
DW
1374 char grp_str[INET_ADDRSTRLEN];
1375 char src_str[INET_ADDRSTRLEN];
31a21c9c
DW
1376 char in_ifname[16];
1377 char out_ifname[16];
1378 int oif_vif_index;
1379 struct interface *ifp_in;
1380 first_oif = 1;
1381
1382 if (!c_oil->installed)
1383 continue;
1384
1385 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
1386 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
1387 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
1388
1389 if (ifp_in)
1390 strcpy(in_ifname, ifp_in->name);
1391 else
1392 strcpy(in_ifname, "<iif?>");
1393
1394 if (src_or_group)
1395 {
1396 if (strcmp(src_or_group, src_str) && strcmp(src_or_group, grp_str))
1397 continue;
1398
1399 if (group && strcmp(group, grp_str))
1400 continue;
1401 }
1402
1403 if (uj) {
1404
1405 /* Find the group, create it if it doesn't exist */
1406 json_object_object_get_ex(json, grp_str, &json_group);
1407
1408 if (!json_group) {
1409 json_group = json_object_new_object();
1410 json_object_object_add(json, grp_str, json_group);
1411 }
1412
1413 /* Find the source nested under the group, create it if it doesn't exist */
1414 json_object_object_get_ex(json_group, src_str, &json_source);
1415
1416 if (!json_source) {
1417 json_source = json_object_new_object();
1418 json_object_object_add(json_group, src_str, json_source);
1419 }
1420
1421 /* Find the inbound interface nested under the source, create it if it doesn't exist */
1422 json_object_object_get_ex(json_source, in_ifname, &json_ifp_in);
1423
1424 if (!json_ifp_in) {
1425 json_ifp_in = json_object_new_object();
1426 json_object_object_add(json_source, in_ifname, json_ifp_in);
1427 }
1428 } else {
1429 vty_out(vty, "%-15s %-15s %-5s ",
1430 src_str,
1431 grp_str,
1432 ifp_in->name);
1433 }
1434
1435 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
1436 struct interface *ifp_out;
1437 char oif_uptime[10];
1438 int ttl;
1439
1440 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
1441 if (ttl < 1)
1442 continue;
1443
1444 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
1445 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
1446
1447 if (ifp_out)
1448 strcpy(out_ifname, ifp_out->name);
1449 else
1450 strcpy(out_ifname, "<oif?>");
1451
1452 if (uj) {
1453 json_ifp_out = json_object_new_object();
1454 json_object_string_add(json_ifp_out, "source", src_str);
1455 json_object_string_add(json_ifp_out, "group", grp_str);
1456 json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
1457 json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
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;
1464 vty_out(vty, "%s", out_ifname);
1465 }
1466 else
1467 vty_out(vty, ",%s", out_ifname);
1468 }
1469 }
1470
1471 if (!uj)
1472 vty_out(vty, "%s", VTY_NEWLINE);
1473 }
1474
1475
1476 if (uj) {
72b39b9e 1477 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
31a21c9c
DW
1478 json_object_free(json);
1479 } else {
1480 vty_out(vty, "%s", VTY_NEWLINE);
1481 }
1482}
1483
a268493f 1484static void pim_show_neighbors(struct vty *vty, u_char uj)
12e41d03 1485{
a268493f
DW
1486 struct listnode *node;
1487 struct listnode *neighnode;
12e41d03 1488 struct interface *ifp;
a268493f
DW
1489 struct pim_interface *pim_ifp;
1490 struct pim_neighbor *neigh;
1491 time_t now;
1492 char uptime[10];
1493 char expire[10];
eaa54bdb 1494 char neigh_src_str[INET_ADDRSTRLEN];
a268493f
DW
1495 json_object *json = NULL;
1496 json_object *json_ifp_rows = NULL;
1497 json_object *json_row = NULL;
12e41d03 1498
a268493f 1499 now = pim_time_monotonic_sec();
12e41d03 1500
a268493f
DW
1501 if (uj) {
1502 json = json_object_new_object();
1503 } else {
1504 vty_out(vty, "Interface Neighbor Uptime Holdtime DR Pri%s", VTY_NEWLINE);
1505 }
12e41d03 1506
469351b3 1507 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03 1508 pim_ifp = ifp->info;
a268493f 1509
12e41d03
DL
1510 if (!pim_ifp)
1511 continue;
1512
1513 if (pim_ifp->pim_sock_fd < 0)
1514 continue;
1515
a268493f
DW
1516 if (uj)
1517 json_ifp_rows = json_object_new_object();
12e41d03
DL
1518
1519 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
12e41d03
DL
1520 pim_inet4_dump("<src?>", neigh->source_addr,
1521 neigh_src_str, sizeof(neigh_src_str));
a268493f
DW
1522 pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
1523 pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
12e41d03 1524
a268493f
DW
1525 if (uj) {
1526 json_row = json_object_new_object();
1527 json_object_string_add(json_row, "interface", ifp->name);
1528 json_object_string_add(json_row, "neighbor", neigh_src_str);
1529 json_object_string_add(json_row, "upTime", uptime);
1530 json_object_string_add(json_row, "holdTime", expire);
1531 json_object_int_add(json_row, "holdTimeMax", neigh->holdtime);
1532 json_object_int_add(json_row, "drPriority", neigh->dr_priority);
1533 json_object_object_add(json_ifp_rows, neigh_src_str, json_row);
1534
1535 } else {
1536 vty_out(vty, "%-9s %15s %8s %8s %6d%s",
1537 ifp->name,
1538 neigh_src_str,
1539 uptime,
1540 expire,
1541 neigh->dr_priority,
1542 VTY_NEWLINE);
1543 }
12e41d03
DL
1544 }
1545
a268493f
DW
1546 if (uj) {
1547 json_object_object_add(json, ifp->name, json_ifp_rows);
1548 json_ifp_rows = NULL;
1549 }
12e41d03 1550 }
12e41d03 1551
a268493f 1552 if (uj) {
17b52be1 1553 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
a268493f 1554 json_object_free(json);
12e41d03
DL
1555 }
1556}
1557
1558static void pim_show_neighbors_secondary(struct vty *vty)
1559{
1560 struct listnode *node;
1561 struct interface *ifp;
1562
1563 vty_out(vty, "Interface Address Neighbor Secondary %s", VTY_NEWLINE);
1564
469351b3 1565 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
1566 struct pim_interface *pim_ifp;
1567 struct in_addr ifaddr;
1568 struct listnode *neighnode;
1569 struct pim_neighbor *neigh;
1570
1571 pim_ifp = ifp->info;
1572
1573 if (!pim_ifp)
1574 continue;
1575
1576 if (pim_ifp->pim_sock_fd < 0)
1577 continue;
1578
1579 ifaddr = pim_ifp->primary_address;
1580
1581 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
eaa54bdb 1582 char neigh_src_str[INET_ADDRSTRLEN];
12e41d03
DL
1583 struct listnode *prefix_node;
1584 struct prefix *p;
1585
1586 if (!neigh->prefix_list)
1587 continue;
1588
1589 pim_inet4_dump("<src?>", neigh->source_addr,
1590 neigh_src_str, sizeof(neigh_src_str));
1591
1592 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
eaa54bdb 1593 char neigh_sec_str[INET_ADDRSTRLEN];
12e41d03
DL
1594
1595 if (p->family != AF_INET)
1596 continue;
1597
1598 pim_inet4_dump("<src?>", p->u.prefix4,
1599 neigh_sec_str, sizeof(neigh_sec_str));
1600
1601 vty_out(vty, "%-9s %-15s %-15s %-15s%s",
1602 ifp->name,
1603 inet_ntoa(ifaddr),
1604 neigh_src_str,
1605 neigh_sec_str,
1606 VTY_NEWLINE);
1607 }
1608 }
1609 }
1610}
1611
9bf3c633 1612static void
e775c0a4 1613json_object_pim_upstream_add (json_object *json, struct pim_upstream *up)
9bf3c633
DW
1614{
1615 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
e775c0a4 1616 json_object_boolean_true_add(json, "drJoinDesired");
9bf3c633
DW
1617
1618 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
e775c0a4 1619 json_object_boolean_true_add(json, "drJoinDesiredUpdated");
9bf3c633
DW
1620
1621 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
e775c0a4 1622 json_object_boolean_true_add(json, "firstHopRouter");
9bf3c633
DW
1623
1624 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
e775c0a4 1625 json_object_boolean_true_add(json, "sourceIgmp");
9bf3c633
DW
1626
1627 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
e775c0a4 1628 json_object_boolean_true_add(json, "sourcePim");
9bf3c633
DW
1629
1630 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
e775c0a4 1631 json_object_boolean_true_add(json, "sourceStream");
7667c556 1632
1633 /* XXX: need to print ths flag in the plain text display as well */
1634 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
1635 json_object_boolean_true_add(json, "sourceMsdp");
9bf3c633
DW
1636}
1637
1638static void pim_show_upstream(struct vty *vty, u_char uj)
12e41d03
DL
1639{
1640 struct listnode *upnode;
1641 struct pim_upstream *up;
1642 time_t now;
9bf3c633 1643 json_object *json = NULL;
e775c0a4 1644 json_object *json_group = NULL;
9bf3c633 1645 json_object *json_row = NULL;
12e41d03
DL
1646
1647 now = pim_time_monotonic_sec();
1648
9bf3c633
DW
1649 if (uj)
1650 json = json_object_new_object();
1651 else
b3fb2c27 1652 vty_out(vty, "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt%s", VTY_NEWLINE);
12e41d03 1653
0f588989 1654 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
eaa54bdb
DW
1655 char src_str[INET_ADDRSTRLEN];
1656 char grp_str[INET_ADDRSTRLEN];
9bf3c633
DW
1657 char uptime[10];
1658 char join_timer[10];
1659 char rs_timer[10];
1660 char ka_timer[10];
1bf16443 1661 char msdp_reg_timer[10];
12e41d03 1662
9bf3c633
DW
1663 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
1664 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
1665 pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
1666 pim_time_timer_to_hhmmss (join_timer, sizeof(join_timer), up->t_join_timer);
1667 pim_time_timer_to_hhmmss (rs_timer, sizeof (rs_timer), up->t_rs_timer);
1668 pim_time_timer_to_hhmmss (ka_timer, sizeof (ka_timer), up->t_ka_timer);
1bf16443 1669 pim_time_timer_to_hhmmss (msdp_reg_timer, sizeof (msdp_reg_timer), up->t_msdp_reg_timer);
12e41d03 1670
9bf3c633 1671 if (uj) {
e775c0a4 1672 json_object_object_get_ex(json, grp_str, &json_group);
9bf3c633 1673
e775c0a4
DW
1674 if (!json_group) {
1675 json_group = json_object_new_object();
1676 json_object_object_add(json, grp_str, json_group);
9bf3c633
DW
1677 }
1678
9bf3c633 1679 json_row = json_object_new_object();
e775c0a4 1680 json_object_pim_upstream_add(json_row, up);
9bf3c633
DW
1681 json_object_string_add(json_row, "inboundInterface", up->rpf.source_nexthop.interface->name);
1682 json_object_string_add(json_row, "source", src_str);
1683 json_object_string_add(json_row, "group", grp_str);
1684 json_object_string_add(json_row, "state", pim_upstream_state2str (up->join_state));
1685 json_object_string_add(json_row, "upTime", uptime);
1686 json_object_string_add(json_row, "joinTimer", join_timer);
1687 json_object_string_add(json_row, "resetTimer", rs_timer);
1688 json_object_string_add(json_row, "keepaliveTimer", ka_timer);
1bf16443 1689 json_object_string_add(json_row, "msdpRegTimer", msdp_reg_timer);
9bf3c633 1690 json_object_int_add(json_row, "refCount", up->ref_count);
5d84a3bc 1691 json_object_int_add(json_row, "sptBit", up->sptbit);
e775c0a4 1692 json_object_object_add(json_group, src_str, json_row);
9bf3c633 1693 } else {
e775c0a4 1694 vty_out(vty, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d%s",
9bf3c633
DW
1695 up->rpf.source_nexthop.interface->name,
1696 src_str,
1697 grp_str,
1698 pim_upstream_state2str (up->join_state),
1699 uptime,
1700 join_timer,
1701 rs_timer,
2ecb76d3 1702 ka_timer,
9bf3c633
DW
1703 up->ref_count,
1704 VTY_NEWLINE);
1705 }
1706 }
1707
1708 if (uj) {
17b52be1 1709 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
9bf3c633 1710 json_object_free(json);
12e41d03
DL
1711 }
1712}
1713
9bf3c633 1714static void pim_show_join_desired(struct vty *vty, u_char uj)
12e41d03 1715{
12e41d03 1716 struct listnode *chnode;
12e41d03
DL
1717 struct pim_interface *pim_ifp;
1718 struct pim_ifchannel *ch;
eaa54bdb
DW
1719 char src_str[INET_ADDRSTRLEN];
1720 char grp_str[INET_ADDRSTRLEN];
9bf3c633 1721 json_object *json = NULL;
e775c0a4 1722 json_object *json_group = NULL;
9bf3c633
DW
1723 json_object *json_row = NULL;
1724
1725 if (uj)
1726 json = json_object_new_object();
1727 else
1728 vty_out(vty,
1729 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD%s",
1730 VTY_NEWLINE);
12e41d03 1731
ea4a71fc
DS
1732 /* scan per-interface (S,G) state */
1733 for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, chnode, ch)) {
1734 /* scan all interfaces */
1735 pim_ifp = ch->interface->info;
12e41d03
DL
1736 if (!pim_ifp)
1737 continue;
1738
ea4a71fc 1739 struct pim_upstream *up = ch->upstream;
12e41d03 1740
ea4a71fc
DS
1741 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
1742 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
12e41d03 1743
ea4a71fc
DS
1744 if (uj) {
1745 json_object_object_get_ex(json, grp_str, &json_group);
9bf3c633 1746
ea4a71fc
DS
1747 if (!json_group) {
1748 json_group = json_object_new_object();
1749 json_object_object_add(json, grp_str, json_group);
1750 }
9bf3c633 1751
ea4a71fc
DS
1752 json_row = json_object_new_object();
1753 json_object_pim_upstream_add(json_row, up);
1754 json_object_string_add(json_row, "interface", ch->interface->name);
1755 json_object_string_add(json_row, "source", src_str);
1756 json_object_string_add(json_row, "group", grp_str);
9bf3c633 1757
ea4a71fc
DS
1758 if (pim_macro_ch_lost_assert(ch))
1759 json_object_boolean_true_add(json_row, "lostAssert");
9bf3c633 1760
ea4a71fc
DS
1761 if (pim_macro_chisin_joins(ch))
1762 json_object_boolean_true_add(json_row, "joins");
9bf3c633 1763
ea4a71fc
DS
1764 if (pim_macro_chisin_pim_include(ch))
1765 json_object_boolean_true_add(json_row, "pimInclude");
9bf3c633 1766
ea4a71fc
DS
1767 if (pim_upstream_evaluate_join_desired(up))
1768 json_object_boolean_true_add(json_row, "evaluateJoinDesired");
9bf3c633 1769
ea4a71fc 1770 json_object_object_add(json_group, src_str, json_row);
9bf3c633 1771
ea4a71fc
DS
1772 } else {
1773 vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
1774 ch->interface->name,
1775 src_str,
1776 grp_str,
1777 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
1778 pim_macro_chisin_joins(ch) ? "yes" : "no",
1779 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
1780 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
1781 pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
1782 VTY_NEWLINE);
12e41d03
DL
1783 }
1784 }
9bf3c633
DW
1785
1786 if (uj) {
17b52be1 1787 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
9bf3c633
DW
1788 json_object_free(json);
1789 }
12e41d03
DL
1790}
1791
9bf3c633 1792static void pim_show_upstream_rpf(struct vty *vty, u_char uj)
12e41d03
DL
1793{
1794 struct listnode *upnode;
1795 struct pim_upstream *up;
9bf3c633 1796 json_object *json = NULL;
e775c0a4 1797 json_object *json_group = NULL;
9bf3c633
DW
1798 json_object *json_row = NULL;
1799
1800 if (uj)
1801 json = json_object_new_object();
1802 else
1803 vty_out(vty,
1804 "Source Group RpfIface RibNextHop RpfAddress %s",
1805 VTY_NEWLINE);
12e41d03 1806
0f588989 1807 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
eaa54bdb
DW
1808 char src_str[INET_ADDRSTRLEN];
1809 char grp_str[INET_ADDRSTRLEN];
1810 char rpf_nexthop_str[PREFIX_STRLEN];
1811 char rpf_addr_str[PREFIX_STRLEN];
12e41d03
DL
1812 struct pim_rpf *rpf;
1813 const char *rpf_ifname;
9bf3c633 1814
12e41d03 1815 rpf = &up->rpf;
9bf3c633 1816
4ed0af70
DS
1817 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
1818 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
63c59d0c
DS
1819 pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
1820 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
9bf3c633 1821
12e41d03 1822 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
9bf3c633
DW
1823
1824 if (uj) {
e775c0a4 1825 json_object_object_get_ex(json, grp_str, &json_group);
9bf3c633 1826
e775c0a4
DW
1827 if (!json_group) {
1828 json_group = json_object_new_object();
1829 json_object_object_add(json, grp_str, json_group);
9bf3c633
DW
1830 }
1831
9bf3c633 1832 json_row = json_object_new_object();
e775c0a4 1833 json_object_pim_upstream_add(json_row, up);
9bf3c633
DW
1834 json_object_string_add(json_row, "source", src_str);
1835 json_object_string_add(json_row, "group", grp_str);
1836 json_object_string_add(json_row, "rpfInterface", rpf_ifname);
1837 json_object_string_add(json_row, "ribNexthop", rpf_nexthop_str);
1838 json_object_string_add(json_row, "rpfAddress", rpf_addr_str);
e775c0a4 1839 json_object_object_add(json_group, src_str, json_row);
9bf3c633
DW
1840 } else {
1841 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
1842 src_str,
1843 grp_str,
1844 rpf_ifname,
1845 rpf_nexthop_str,
1846 rpf_addr_str,
1847 VTY_NEWLINE);
1848 }
1849 }
1850
1851 if (uj) {
17b52be1 1852 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
9bf3c633 1853 json_object_free(json);
12e41d03
DL
1854 }
1855}
1856
9bf3c633 1857static void show_rpf_refresh_stats(struct vty *vty, time_t now, json_object *json)
12e41d03
DL
1858{
1859 char refresh_uptime[10];
1860
1861 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
1862
9bf3c633
DW
1863 if (json) {
1864 json_object_int_add(json, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec);
1865 json_object_int_add(json, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher));
1866 json_object_int_add(json, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests);
1867 json_object_int_add(json, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events);
1868 json_object_string_add(json, "rpfCacheRefreshLast", refresh_uptime);
1869 json_object_int_add(json, "nexthopLookups", qpim_nexthop_lookups);
e71bf8f7 1870 json_object_int_add(json, "nexthopLookupsAvoided", nexthop_lookups_avoided);
9bf3c633
DW
1871 } else {
1872 vty_out(vty,
1873 "RPF Cache Refresh Delay: %ld msecs%s"
1874 "RPF Cache Refresh Timer: %ld msecs%s"
1875 "RPF Cache Refresh Requests: %lld%s"
1876 "RPF Cache Refresh Events: %lld%s"
1877 "RPF Cache Refresh Last: %s%s"
e71bf8f7
DS
1878 "Nexthop Lookups: %lld%s"
1879 "Nexthop Lookups Avoided: %lld%s",
9bf3c633
DW
1880 qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
1881 pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
1882 (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
1883 (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
1884 refresh_uptime, VTY_NEWLINE,
e71bf8f7
DS
1885 (long long) qpim_nexthop_lookups, VTY_NEWLINE,
1886 (long long)nexthop_lookups_avoided, VTY_NEWLINE);
9bf3c633 1887 }
12e41d03
DL
1888}
1889
1890static void show_scan_oil_stats(struct vty *vty, time_t now)
1891{
1892 char uptime_scan_oil[10];
1893 char uptime_mroute_add[10];
1894 char uptime_mroute_del[10];
1895
1896 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
1897 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
1898 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
1899
1900 vty_out(vty,
1901 "Scan OIL - Last: %s Events: %lld%s"
1902 "MFC Add - Last: %s Events: %lld%s"
1903 "MFC Del - Last: %s Events: %lld%s",
1904 uptime_scan_oil, (long long) qpim_scan_oil_events, VTY_NEWLINE,
1905 uptime_mroute_add, (long long) qpim_mroute_add_events, VTY_NEWLINE,
1906 uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
1907}
1908
9bf3c633 1909static void pim_show_rpf(struct vty *vty, u_char uj)
12e41d03
DL
1910{
1911 struct listnode *up_node;
1912 struct pim_upstream *up;
1913 time_t now = pim_time_monotonic_sec();
9bf3c633 1914 json_object *json = NULL;
e775c0a4 1915 json_object *json_group = NULL;
9bf3c633
DW
1916 json_object *json_row = NULL;
1917
9bf3c633
DW
1918 if (uj) {
1919 json = json_object_new_object();
1920 show_rpf_refresh_stats(vty, now, json);
1921 } else {
1922 show_rpf_refresh_stats(vty, now, json);
1923 vty_out(vty, "%s", VTY_NEWLINE);
1924 vty_out(vty,
1925 "Source Group RpfIface RpfAddress RibNextHop Metric Pref%s",
1926 VTY_NEWLINE);
1927 }
12e41d03 1928
0f588989 1929 for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) {
eaa54bdb
DW
1930 char src_str[INET_ADDRSTRLEN];
1931 char grp_str[INET_ADDRSTRLEN];
1932 char rpf_addr_str[PREFIX_STRLEN];
1933 char rib_nexthop_str[PREFIX_STRLEN];
12e41d03
DL
1934 const char *rpf_ifname;
1935 struct pim_rpf *rpf = &up->rpf;
1936
4ed0af70
DS
1937 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
1938 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
63c59d0c
DS
1939 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
1940 pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
12e41d03
DL
1941
1942 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
1943
9bf3c633 1944 if (uj) {
e775c0a4 1945 json_object_object_get_ex(json, grp_str, &json_group);
9bf3c633 1946
e775c0a4
DW
1947 if (!json_group) {
1948 json_group = json_object_new_object();
1949 json_object_object_add(json, grp_str, json_group);
1950 }
9bf3c633
DW
1951
1952 json_row = json_object_new_object();
1953 json_object_string_add(json_row, "source", src_str);
1954 json_object_string_add(json_row, "group", grp_str);
1955 json_object_string_add(json_row, "rpfInterface", rpf_ifname);
1956 json_object_string_add(json_row, "rpfAddress", rpf_addr_str);
1957 json_object_string_add(json_row, "ribNexthop", rib_nexthop_str);
1958 json_object_int_add(json_row, "routeMetric", rpf->source_nexthop.mrib_route_metric);
1959 json_object_int_add(json_row, "routePreference", rpf->source_nexthop.mrib_metric_preference);
e775c0a4 1960 json_object_object_add(json_group, src_str, json_row);
9bf3c633 1961
9bf3c633
DW
1962 } else {
1963 vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
1964 src_str,
1965 grp_str,
1966 rpf_ifname,
1967 rpf_addr_str,
1968 rib_nexthop_str,
1969 rpf->source_nexthop.mrib_route_metric,
1970 rpf->source_nexthop.mrib_metric_preference,
1971 VTY_NEWLINE);
1972 }
1973 }
1974
1975 if (uj) {
17b52be1 1976 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
9bf3c633 1977 json_object_free(json);
12e41d03
DL
1978 }
1979}
1980
9b91bb50 1981static void igmp_show_groups(struct vty *vty, u_char uj)
12e41d03
DL
1982{
1983 struct listnode *ifnode;
1984 struct interface *ifp;
1985 time_t now;
9b91bb50
DW
1986 json_object *json = NULL;
1987 json_object *json_iface = NULL;
1988 json_object *json_row = NULL;
12e41d03
DL
1989
1990 now = pim_time_monotonic_sec();
1991
9b91bb50
DW
1992 if (uj)
1993 json = json_object_new_object();
1994 else
1995 vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime %s", VTY_NEWLINE);
12e41d03
DL
1996
1997 /* scan interfaces */
469351b3 1998 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
1999 struct pim_interface *pim_ifp = ifp->info;
2000 struct listnode *sock_node;
2001 struct igmp_sock *igmp;
2002
2003 if (!pim_ifp)
2004 continue;
2005
2006 /* scan igmp sockets */
2007 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
eaa54bdb 2008 char ifaddr_str[INET_ADDRSTRLEN];
12e41d03
DL
2009 struct listnode *grpnode;
2010 struct igmp_group *grp;
2011
2012 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2013
2014 /* scan igmp groups */
2015 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
eaa54bdb 2016 char group_str[INET_ADDRSTRLEN];
12e41d03
DL
2017 char hhmmss[10];
2018 char uptime[10];
2019
2020 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
2021 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
2022 pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
2023
9b91bb50
DW
2024 if (uj) {
2025 json_object_object_get_ex(json, ifp->name, &json_iface);
12e41d03 2026
9b91bb50
DW
2027 if (!json_iface) {
2028 json_iface = json_object_new_object();
2029 json_object_pim_ifp_add(json_iface, ifp);
2030 json_object_object_add(json, ifp->name, json_iface);
2031 }
2032
2033 json_row = json_object_new_object();
2034 json_object_string_add(json_row, "source", ifaddr_str);
2035 json_object_string_add(json_row, "group", group_str);
b05b72e8
DW
2036
2037 if (grp->igmp_version == 3)
2038 json_object_string_add(json_row, "mode", grp->group_filtermode_isexcl ? "EXCLUDE" : "INCLUDE");
2039
9b91bb50
DW
2040 json_object_string_add(json_row, "timer", hhmmss);
2041 json_object_int_add(json_row, "sourcesCount", grp->group_source_list ? listcount(grp->group_source_list) : 0);
b05b72e8 2042 json_object_int_add(json_row, "version", grp->igmp_version);
9b91bb50
DW
2043 json_object_string_add(json_row, "uptime", uptime);
2044 json_object_object_add(json_iface, group_str, json_row);
2045
2046 } else {
2047 vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
2048 ifp->name,
2049 ifaddr_str,
2050 group_str,
b05b72e8 2051 grp->igmp_version == 3 ? (grp->group_filtermode_isexcl ? "EXCL" : "INCL") : "----",
9b91bb50
DW
2052 hhmmss,
2053 grp->group_source_list ? listcount(grp->group_source_list) : 0,
b05b72e8 2054 grp->igmp_version,
9b91bb50
DW
2055 uptime,
2056 VTY_NEWLINE);
2057 }
12e41d03
DL
2058 } /* scan igmp groups */
2059 } /* scan igmp sockets */
2060 } /* scan interfaces */
9b91bb50
DW
2061
2062 if (uj) {
17b52be1 2063 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
9b91bb50
DW
2064 json_object_free(json);
2065 }
12e41d03
DL
2066}
2067
2068static void igmp_show_group_retransmission(struct vty *vty)
2069{
2070 struct listnode *ifnode;
2071 struct interface *ifp;
2072
2073 vty_out(vty, "Interface Address Group RetTimer Counter RetSrcs%s", VTY_NEWLINE);
2074
2075 /* scan interfaces */
469351b3 2076 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
2077 struct pim_interface *pim_ifp = ifp->info;
2078 struct listnode *sock_node;
2079 struct igmp_sock *igmp;
2080
2081 if (!pim_ifp)
2082 continue;
2083
2084 /* scan igmp sockets */
2085 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
eaa54bdb 2086 char ifaddr_str[INET_ADDRSTRLEN];
12e41d03
DL
2087 struct listnode *grpnode;
2088 struct igmp_group *grp;
2089
2090 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2091
2092 /* scan igmp groups */
2093 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
eaa54bdb 2094 char group_str[INET_ADDRSTRLEN];
12e41d03
DL
2095 char grp_retr_mmss[10];
2096 struct listnode *src_node;
2097 struct igmp_source *src;
2098 int grp_retr_sources = 0;
2099
2100 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
2101 pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
2102
2103
2104 /* count group sources with retransmission state */
2105 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
2106 if (src->source_query_retransmit_count > 0) {
2107 ++grp_retr_sources;
2108 }
2109 }
2110
2111 vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
2112 ifp->name,
2113 ifaddr_str,
2114 group_str,
2115 grp_retr_mmss,
2116 grp->group_specific_query_retransmit_count,
2117 grp_retr_sources,
2118 VTY_NEWLINE);
2119
2120 } /* scan igmp groups */
2121 } /* scan igmp sockets */
2122 } /* scan interfaces */
2123}
2124
12e41d03
DL
2125static void igmp_show_sources(struct vty *vty)
2126{
2127 struct listnode *ifnode;
2128 struct interface *ifp;
2129 time_t now;
2130
2131 now = pim_time_monotonic_sec();
2132
2133 vty_out(vty, "Interface Address Group Source Timer Fwd Uptime %s", VTY_NEWLINE);
2134
2135 /* scan interfaces */
469351b3 2136 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
2137 struct pim_interface *pim_ifp = ifp->info;
2138 struct listnode *sock_node;
2139 struct igmp_sock *igmp;
2140
2141 if (!pim_ifp)
2142 continue;
2143
2144 /* scan igmp sockets */
2145 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
eaa54bdb 2146 char ifaddr_str[INET_ADDRSTRLEN];
12e41d03
DL
2147 struct listnode *grpnode;
2148 struct igmp_group *grp;
2149
2150 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2151
2152 /* scan igmp groups */
2153 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
eaa54bdb 2154 char group_str[INET_ADDRSTRLEN];
12e41d03
DL
2155 struct listnode *srcnode;
2156 struct igmp_source *src;
2157
2158 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
2159
2160 /* scan group sources */
2161 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
eaa54bdb 2162 char source_str[INET_ADDRSTRLEN];
12e41d03
DL
2163 char mmss[10];
2164 char uptime[10];
2165
2166 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
2167
2168 pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
2169
2170 pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
2171
2172 vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
2173 ifp->name,
2174 ifaddr_str,
2175 group_str,
2176 source_str,
2177 mmss,
2178 IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
2179 uptime,
2180 VTY_NEWLINE);
2181
2182 } /* scan group sources */
2183 } /* scan igmp groups */
2184 } /* scan igmp sockets */
2185 } /* scan interfaces */
2186}
2187
2188static void igmp_show_source_retransmission(struct vty *vty)
2189{
2190 struct listnode *ifnode;
2191 struct interface *ifp;
2192
2193 vty_out(vty, "Interface Address Group Source Counter%s", VTY_NEWLINE);
2194
2195 /* scan interfaces */
469351b3 2196 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
12e41d03
DL
2197 struct pim_interface *pim_ifp = ifp->info;
2198 struct listnode *sock_node;
2199 struct igmp_sock *igmp;
2200
2201 if (!pim_ifp)
2202 continue;
2203
2204 /* scan igmp sockets */
2205 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
eaa54bdb 2206 char ifaddr_str[INET_ADDRSTRLEN];
12e41d03
DL
2207 struct listnode *grpnode;
2208 struct igmp_group *grp;
2209
2210 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
2211
2212 /* scan igmp groups */
2213 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
eaa54bdb 2214 char group_str[INET_ADDRSTRLEN];
12e41d03
DL
2215 struct listnode *srcnode;
2216 struct igmp_source *src;
2217
2218 pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
2219
2220 /* scan group sources */
2221 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
eaa54bdb 2222 char source_str[INET_ADDRSTRLEN];
12e41d03
DL
2223
2224 pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
2225
2226 vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
2227 ifp->name,
2228 ifaddr_str,
2229 group_str,
2230 source_str,
2231 src->source_query_retransmit_count,
2232 VTY_NEWLINE);
2233
2234 } /* scan group sources */
2235 } /* scan igmp groups */
2236 } /* scan igmp sockets */
2237 } /* scan interfaces */
2238}
2239
2240static void clear_igmp_interfaces()
2241{
2242 struct listnode *ifnode;
2243 struct listnode *ifnextnode;
2244 struct interface *ifp;
2245
469351b3 2246 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
2247 pim_if_addr_del_all_igmp(ifp);
2248 }
2249
469351b3 2250 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
2251 pim_if_addr_add_all(ifp);
2252 }
2253}
2254
2255static void clear_pim_interfaces()
2256{
2257 struct listnode *ifnode;
2258 struct listnode *ifnextnode;
2259 struct interface *ifp;
2260
469351b3 2261 for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
12e41d03
DL
2262 if (ifp->info) {
2263 pim_neighbor_delete_all(ifp, "interface cleared");
2264 }
2265 }
2266}
2267
2268static void clear_interfaces()
2269{
2270 clear_igmp_interfaces();
2271 clear_pim_interfaces();
2272}
2273
12e41d03
DL
2274DEFUN (clear_ip_interfaces,
2275 clear_ip_interfaces_cmd,
2276 "clear ip interfaces",
2277 CLEAR_STR
2278 IP_STR
2279 "Reset interfaces\n")
2280{
2281 clear_interfaces();
2282
2283 return CMD_SUCCESS;
2284}
2285
2286DEFUN (clear_ip_igmp_interfaces,
2287 clear_ip_igmp_interfaces_cmd,
2288 "clear ip igmp interfaces",
2289 CLEAR_STR
2290 IP_STR
2291 CLEAR_IP_IGMP_STR
2292 "Reset IGMP interfaces\n")
2293{
2294 clear_igmp_interfaces();
2295
2296 return CMD_SUCCESS;
2297}
2298
2299static void mroute_add_all()
2300{
2301 struct listnode *node;
2302 struct channel_oil *c_oil;
2303
040d86ad 2304 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
6a78764e 2305 if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
12e41d03 2306 /* just log warning */
eaa54bdb
DW
2307 char source_str[INET_ADDRSTRLEN];
2308 char group_str[INET_ADDRSTRLEN];
12e41d03
DL
2309 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2310 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2311 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2312 __FILE__, __PRETTY_FUNCTION__,
2313 source_str, group_str);
2314 }
2315 }
2316}
2317
2318static void mroute_del_all()
2319{
2320 struct listnode *node;
2321 struct channel_oil *c_oil;
2322
040d86ad 2323 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
6a78764e 2324 if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
12e41d03 2325 /* just log warning */
eaa54bdb
DW
2326 char source_str[INET_ADDRSTRLEN];
2327 char group_str[INET_ADDRSTRLEN];
12e41d03
DL
2328 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
2329 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
2330 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2331 __FILE__, __PRETTY_FUNCTION__,
2332 source_str, group_str);
2333 }
2334 }
2335}
2336
6250610a
JAG
2337static void static_mroute_add_all()
2338{
2339 struct listnode *node;
2340 struct static_route *s_route;
2341
2342 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
6a78764e 2343 if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
6250610a 2344 /* just log warning */
eaa54bdb
DW
2345 char source_str[INET_ADDRSTRLEN];
2346 char group_str[INET_ADDRSTRLEN];
9867746a
DS
2347 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
2348 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
6250610a
JAG
2349 zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
2350 __FILE__, __PRETTY_FUNCTION__,
2351 source_str, group_str);
2352 }
2353 }
2354}
2355
2356static void static_mroute_del_all()
2357{
2358 struct listnode *node;
2359 struct static_route *s_route;
2360
2361 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
6a78764e 2362 if (pim_mroute_del(&s_route->c_oil, __PRETTY_FUNCTION__)) {
6250610a 2363 /* just log warning */
eaa54bdb
DW
2364 char source_str[INET_ADDRSTRLEN];
2365 char group_str[INET_ADDRSTRLEN];
9867746a
DS
2366 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
2367 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
6250610a
JAG
2368 zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
2369 __FILE__, __PRETTY_FUNCTION__,
2370 source_str, group_str);
2371 }
2372 }
2373}
2374
12e41d03
DL
2375DEFUN (clear_ip_mroute,
2376 clear_ip_mroute_cmd,
2377 "clear ip mroute",
2378 CLEAR_STR
2379 IP_STR
2380 "Reset multicast routes\n")
2381{
2382 mroute_del_all();
2383 mroute_add_all();
2384
2385 return CMD_SUCCESS;
2386}
2387
2388DEFUN (clear_ip_pim_interfaces,
2389 clear_ip_pim_interfaces_cmd,
2390 "clear ip pim interfaces",
2391 CLEAR_STR
2392 IP_STR
2393 CLEAR_IP_PIM_STR
2394 "Reset PIM interfaces\n")
2395{
2396 clear_pim_interfaces();
2397
2398 return CMD_SUCCESS;
2399}
2400
2401DEFUN (clear_ip_pim_oil,
2402 clear_ip_pim_oil_cmd,
2403 "clear ip pim oil",
2404 CLEAR_STR
2405 IP_STR
2406 CLEAR_IP_PIM_STR
2407 "Rescan PIM OIL (output interface list)\n")
2408{
2409 pim_scan_oil();
2410
2411 return CMD_SUCCESS;
2412}
2413
2414DEFUN (show_ip_igmp_interface,
2415 show_ip_igmp_interface_cmd,
9b91bb50 2416 "show ip igmp interface [detail|WORD] [json]",
12e41d03
DL
2417 SHOW_STR
2418 IP_STR
2419 IGMP_STR
a268493f 2420 "IGMP interface information\n"
9b91bb50 2421 "Detailed output\n"
a268493f
DW
2422 "interface name\n"
2423 "JavaScript Object Notation\n")
12e41d03 2424{
a268493f
DW
2425 u_char uj = use_json(argc, argv);
2426 if (argv[4]->arg)
2427 igmp_show_interfaces_single(vty, argv[4]->arg, uj);
2428 else
2429 igmp_show_interfaces(vty, uj);
12e41d03
DL
2430
2431 return CMD_SUCCESS;
2432}
2433
2434DEFUN (show_ip_igmp_join,
2435 show_ip_igmp_join_cmd,
2436 "show ip igmp join",
2437 SHOW_STR
2438 IP_STR
2439 IGMP_STR
2440 "IGMP static join information\n")
2441{
2442 igmp_show_interface_join(vty);
2443
2444 return CMD_SUCCESS;
2445}
2446
2447DEFUN (show_ip_igmp_groups,
2448 show_ip_igmp_groups_cmd,
9b91bb50 2449 "show ip igmp groups [json]",
12e41d03
DL
2450 SHOW_STR
2451 IP_STR
2452 IGMP_STR
9b91bb50
DW
2453 IGMP_GROUP_STR
2454 "JavaScript Object Notation\n")
12e41d03 2455{
9b91bb50
DW
2456 u_char uj = use_json(argc, argv);
2457 igmp_show_groups(vty, uj);
12e41d03
DL
2458
2459 return CMD_SUCCESS;
2460}
2461
2462DEFUN (show_ip_igmp_groups_retransmissions,
2463 show_ip_igmp_groups_retransmissions_cmd,
2464 "show ip igmp groups retransmissions",
2465 SHOW_STR
2466 IP_STR
2467 IGMP_STR
2468 IGMP_GROUP_STR
2469 "IGMP group retransmissions\n")
2470{
2471 igmp_show_group_retransmission(vty);
2472
2473 return CMD_SUCCESS;
2474}
2475
12e41d03
DL
2476DEFUN (show_ip_igmp_sources,
2477 show_ip_igmp_sources_cmd,
2478 "show ip igmp sources",
2479 SHOW_STR
2480 IP_STR
2481 IGMP_STR
2482 IGMP_SOURCE_STR)
2483{
2484 igmp_show_sources(vty);
2485
2486 return CMD_SUCCESS;
2487}
2488
2489DEFUN (show_ip_igmp_sources_retransmissions,
2490 show_ip_igmp_sources_retransmissions_cmd,
2491 "show ip igmp sources retransmissions",
2492 SHOW_STR
2493 IP_STR
2494 IGMP_STR
2495 IGMP_SOURCE_STR
2496 "IGMP source retransmissions\n")
2497{
2498 igmp_show_source_retransmission(vty);
2499
2500 return CMD_SUCCESS;
2501}
2502
12e41d03
DL
2503DEFUN (show_ip_pim_assert,
2504 show_ip_pim_assert_cmd,
2505 "show ip pim assert",
2506 SHOW_STR
2507 IP_STR
2508 PIM_STR
2509 "PIM interface assert\n")
2510{
2511 pim_show_assert(vty);
2512
2513 return CMD_SUCCESS;
2514}
2515
2516DEFUN (show_ip_pim_assert_internal,
2517 show_ip_pim_assert_internal_cmd,
2518 "show ip pim assert-internal",
2519 SHOW_STR
2520 IP_STR
2521 PIM_STR
2522 "PIM interface internal assert state\n")
2523{
2524 pim_show_assert_internal(vty);
2525
2526 return CMD_SUCCESS;
2527}
2528
2529DEFUN (show_ip_pim_assert_metric,
2530 show_ip_pim_assert_metric_cmd,
2531 "show ip pim assert-metric",
2532 SHOW_STR
2533 IP_STR
2534 PIM_STR
2535 "PIM interface assert metric\n")
2536{
2537 pim_show_assert_metric(vty);
2538
2539 return CMD_SUCCESS;
2540}
2541
2542DEFUN (show_ip_pim_assert_winner_metric,
2543 show_ip_pim_assert_winner_metric_cmd,
2544 "show ip pim assert-winner-metric",
2545 SHOW_STR
2546 IP_STR
2547 PIM_STR
2548 "PIM interface assert winner metric\n")
2549{
2550 pim_show_assert_winner_metric(vty);
2551
2552 return CMD_SUCCESS;
2553}
2554
12e41d03
DL
2555DEFUN (show_ip_pim_interface,
2556 show_ip_pim_interface_cmd,
9b91bb50 2557 "show ip pim interface [detail|WORD] [json]",
12e41d03
DL
2558 SHOW_STR
2559 IP_STR
2560 PIM_STR
a268493f 2561 "PIM interface information\n"
9b91bb50 2562 "Detailed output\n"
a268493f
DW
2563 "interface name\n"
2564 "JavaScript Object Notation\n")
12e41d03 2565{
9bf3c633 2566 u_char uj = use_json(argc, argv);
a268493f
DW
2567 if (argv[4]->arg)
2568 pim_show_interfaces_single(vty, argv[4]->arg, uj);
2569 else
2570 pim_show_interfaces(vty, uj);
12e41d03
DL
2571
2572 return CMD_SUCCESS;
2573}
2574
2575DEFUN (show_ip_pim_join,
2576 show_ip_pim_join_cmd,
e775c0a4 2577 "show ip pim join [json]",
12e41d03
DL
2578 SHOW_STR
2579 IP_STR
2580 PIM_STR
2581 "PIM interface join information\n")
2582{
e775c0a4
DW
2583 u_char uj = use_json(argc, argv);
2584 pim_show_join(vty, uj);
12e41d03
DL
2585
2586 return CMD_SUCCESS;
2587}
2588
12e41d03
DL
2589DEFUN (show_ip_pim_local_membership,
2590 show_ip_pim_local_membership_cmd,
e775c0a4 2591 "show ip pim local-membership [json]",
12e41d03
DL
2592 SHOW_STR
2593 IP_STR
2594 PIM_STR
2595 "PIM interface local-membership\n")
2596{
e775c0a4
DW
2597 u_char uj = use_json(argc, argv);
2598 pim_show_membership(vty, uj);
12e41d03
DL
2599
2600 return CMD_SUCCESS;
2601}
2602
12e41d03
DL
2603DEFUN (show_ip_pim_neighbor,
2604 show_ip_pim_neighbor_cmd,
9b91bb50 2605 "show ip pim neighbor [detail|WORD] [json]",
12e41d03
DL
2606 SHOW_STR
2607 IP_STR
2608 PIM_STR
a268493f 2609 "PIM neighbor information\n"
9b91bb50 2610 "Detailed output\n"
a268493f
DW
2611 "Name of interface or neighbor\n"
2612 "JavaScript Object Notation\n")
12e41d03 2613{
9bf3c633 2614 u_char uj = use_json(argc, argv);
a268493f
DW
2615 if (argv[4]->arg)
2616 pim_show_neighbors_single(vty, argv[4]->arg, uj);
2617 else
2618 pim_show_neighbors(vty, uj);
12e41d03
DL
2619
2620 return CMD_SUCCESS;
2621}
2622
2623DEFUN (show_ip_pim_secondary,
2624 show_ip_pim_secondary_cmd,
2625 "show ip pim secondary",
2626 SHOW_STR
2627 IP_STR
2628 PIM_STR
2629 "PIM neighbor addresses\n")
2630{
2631 pim_show_neighbors_secondary(vty);
2632
2633 return CMD_SUCCESS;
2634}
2635
31a21c9c
DW
2636DEFUN (show_ip_pim_state,
2637 show_ip_pim_state_cmd,
2638 "show ip pim state [A.B.C.D] [A.B.C.D] [json]",
2639 SHOW_STR
2640 IP_STR
2641 PIM_STR
2642 "PIM state information\n"
2643 "Unicast or Multicast address\n"
2644 "Multicast address\n"
2645 "JavaScript Object Notation\n")
2646{
2647 const char *src_or_group = NULL;
2648 const char *group = NULL;
2649 u_char uj = use_json(argc, argv);
2650
2651 src_or_group = argv[4]->arg;
2652 group = argv[5]->arg;
2653
2654 pim_show_state(vty, src_or_group, group, uj);
2655
2656 return CMD_SUCCESS;
2657}
2658
12e41d03
DL
2659DEFUN (show_ip_pim_upstream,
2660 show_ip_pim_upstream_cmd,
9bf3c633 2661 "show ip pim upstream [json]",
12e41d03
DL
2662 SHOW_STR
2663 IP_STR
2664 PIM_STR
a268493f
DW
2665 "PIM upstream information\n"
2666 "JavaScript Object Notation\n")
12e41d03 2667{
9bf3c633
DW
2668 u_char uj = use_json(argc, argv);
2669 pim_show_upstream(vty, uj);
12e41d03
DL
2670
2671 return CMD_SUCCESS;
2672}
2673
2674DEFUN (show_ip_pim_upstream_join_desired,
2675 show_ip_pim_upstream_join_desired_cmd,
9bf3c633 2676 "show ip pim upstream-join-desired [json]",
12e41d03
DL
2677 SHOW_STR
2678 IP_STR
2679 PIM_STR
a268493f
DW
2680 "PIM upstream join-desired\n"
2681 "JavaScript Object Notation\n")
12e41d03 2682{
9bf3c633
DW
2683 u_char uj = use_json(argc, argv);
2684 pim_show_join_desired(vty, uj);
12e41d03
DL
2685
2686 return CMD_SUCCESS;
2687}
2688
2689DEFUN (show_ip_pim_upstream_rpf,
2690 show_ip_pim_upstream_rpf_cmd,
9bf3c633 2691 "show ip pim upstream-rpf [json]",
12e41d03
DL
2692 SHOW_STR
2693 IP_STR
2694 PIM_STR
a268493f
DW
2695 "PIM upstream source rpf\n"
2696 "JavaScript Object Notation\n")
12e41d03 2697{
9bf3c633
DW
2698 u_char uj = use_json(argc, argv);
2699 pim_show_upstream_rpf(vty, uj);
12e41d03
DL
2700
2701 return CMD_SUCCESS;
2702}
2703
00d07c6f
DS
2704DEFUN (show_ip_pim_rp,
2705 show_ip_pim_rp_cmd,
9bf3c633 2706 "show ip pim rp-info [json]",
00d07c6f
DS
2707 SHOW_STR
2708 IP_STR
2709 PIM_STR
a268493f
DW
2710 "PIM RP information\n"
2711 "JavaScript Object Notation\n")
00d07c6f 2712{
9bf3c633
DW
2713 u_char uj = use_json(argc, argv);
2714 pim_rp_show_information (vty, uj);
00d07c6f
DS
2715
2716 return CMD_SUCCESS;
2717}
2718
12e41d03
DL
2719DEFUN (show_ip_pim_rpf,
2720 show_ip_pim_rpf_cmd,
9bf3c633 2721 "show ip pim rpf [json]",
12e41d03
DL
2722 SHOW_STR
2723 IP_STR
2724 PIM_STR
a268493f
DW
2725 "PIM cached source rpf information\n"
2726 "JavaScript Object Notation\n")
12e41d03 2727{
9bf3c633
DW
2728 u_char uj = use_json(argc, argv);
2729 pim_show_rpf(vty, uj);
12e41d03
DL
2730
2731 return CMD_SUCCESS;
2732}
2733
2734static void show_multicast_interfaces(struct vty *vty)
2735{
2736 struct listnode *node;
2737 struct interface *ifp;
2738
2739 vty_out(vty, "%s", VTY_NEWLINE);
2740
2741 vty_out(vty, "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut%s",
2742 VTY_NEWLINE);
2743
469351b3 2744 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
12e41d03
DL
2745 struct pim_interface *pim_ifp;
2746 struct in_addr ifaddr;
2747 struct sioc_vif_req vreq;
2748
2749 pim_ifp = ifp->info;
2750
2751 if (!pim_ifp)
2752 continue;
2753
2754 memset(&vreq, 0, sizeof(vreq));
2755 vreq.vifi = pim_ifp->mroute_vif_index;
2756
2757 if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
6c44fe22
DS
2758 zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
2759 (unsigned long)SIOCGETVIFCNT,
2760 ifp->name,
2761 pim_ifp->mroute_vif_index,
2762 errno,
2763 safe_strerror(errno),
2764 VTY_NEWLINE);
12e41d03
DL
2765 }
2766
2767 ifaddr = pim_ifp->primary_address;
2768
2769 vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
2770 ifp->name,
2771 inet_ntoa(ifaddr),
2772 ifp->ifindex,
2773 pim_ifp->mroute_vif_index,
ea8b7c71
RW
2774 (unsigned long) vreq.icount,
2775 (unsigned long) vreq.ocount,
2776 (unsigned long) vreq.ibytes,
2777 (unsigned long) vreq.obytes,
12e41d03
DL
2778 VTY_NEWLINE);
2779 }
2780}
2781
2782DEFUN (show_ip_multicast,
2783 show_ip_multicast_cmd,
2784 "show ip multicast",
2785 SHOW_STR
2786 IP_STR
2787 "Multicast global information\n")
2788{
2789 time_t now = pim_time_monotonic_sec();
2790
2791 if (PIM_MROUTE_IS_ENABLED) {
2792 char uptime[10];
2793
2794 vty_out(vty, "Mroute socket descriptor: %d%s",
2795 qpim_mroute_socket_fd,
2796 VTY_NEWLINE);
2797
2798 pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
2799 vty_out(vty, "Mroute socket uptime: %s%s",
2800 uptime,
2801 VTY_NEWLINE);
2802 }
2803 else {
2804 vty_out(vty, "Multicast disabled%s",
2805 VTY_NEWLINE);
2806 }
2807
2808 vty_out(vty, "%s", VTY_NEWLINE);
2809 vty_out(vty, "Zclient update socket: ");
2810 if (qpim_zclient_update) {
2811 vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
2812 qpim_zclient_update->fail, VTY_NEWLINE);
2813 }
2814 else {
2815 vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
2816 }
05b0d0d0
DS
2817
2818 pim_zlookup_show_ip_multicast (vty);
12e41d03
DL
2819
2820 vty_out(vty, "%s", VTY_NEWLINE);
2821 vty_out(vty, "Current highest VifIndex: %d%s",
2822 qpim_mroute_oif_highest_vif_index,
2823 VTY_NEWLINE);
2824 vty_out(vty, "Maximum highest VifIndex: %d%s",
1865a44a 2825 PIM_MAX_USABLE_VIFS,
12e41d03
DL
2826 VTY_NEWLINE);
2827
2828 vty_out(vty, "%s", VTY_NEWLINE);
2829 vty_out(vty, "Upstream Join Timer: %d secs%s",
2830 qpim_t_periodic,
2831 VTY_NEWLINE);
2832 vty_out(vty, "Join/Prune Holdtime: %d secs%s",
2833 PIM_JP_HOLDTIME,
2834 VTY_NEWLINE);
2835
2836 vty_out(vty, "%s", VTY_NEWLINE);
2837
9bf3c633 2838 show_rpf_refresh_stats(vty, now, NULL);
12e41d03
DL
2839
2840 vty_out(vty, "%s", VTY_NEWLINE);
2841
2842 show_scan_oil_stats(vty, now);
2843
2844 show_multicast_interfaces(vty);
2845
2846 return CMD_SUCCESS;
2847}
2848
b3fb2c27 2849static void show_mroute(struct vty *vty, u_char uj)
12e41d03
DL
2850{
2851 struct listnode *node;
2852 struct channel_oil *c_oil;
6250610a 2853 struct static_route *s_route;
12e41d03 2854 time_t now;
b3fb2c27
DW
2855 json_object *json = NULL;
2856 json_object *json_group = NULL;
2857 json_object *json_source = NULL;
01cb1466 2858 json_object *json_oil = NULL;
b3fb2c27 2859 json_object *json_ifp_out = NULL;
91c6aec4 2860 int found_oif = 0;
f59a8217 2861 int first = 1;
12e41d03 2862
b3fb2c27
DW
2863 if (uj) {
2864 json = json_object_new_object();
2865 } else {
f59a8217 2866 vty_out(vty, "Source Group Proto Input Output TTL Uptime%s",
b3fb2c27
DW
2867 VTY_NEWLINE);
2868 }
12e41d03
DL
2869
2870 now = pim_time_monotonic_sec();
2871
6250610a 2872 /* print list of PIM and IGMP routes */
040d86ad 2873 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
eaa54bdb
DW
2874 char grp_str[INET_ADDRSTRLEN];
2875 char src_str[INET_ADDRSTRLEN];
b3fb2c27
DW
2876 char in_ifname[16];
2877 char out_ifname[16];
12e41d03 2878 int oif_vif_index;
f59a8217 2879 char proto[100];
b3fb2c27 2880 struct interface *ifp_in;
91c6aec4 2881 found_oif = 0;
f59a8217 2882 first = 1;
07335c8d 2883 if (!c_oil->installed && !uj)
58302dc7
DS
2884 continue;
2885
b3fb2c27
DW
2886 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
2887 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
2888 ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
2889
2890 if (ifp_in)
2891 strcpy(in_ifname, ifp_in->name);
2892 else
2893 strcpy(in_ifname, "<iif?>");
2894
2895 if (uj) {
2896
2897 /* Find the group, create it if it doesn't exist */
2898 json_object_object_get_ex(json, grp_str, &json_group);
2899
2900 if (!json_group) {
2901 json_group = json_object_new_object();
2902 json_object_object_add(json, grp_str, json_group);
2903 }
2904
2905 /* Find the source nested under the group, create it if it doesn't exist */
2906 json_object_object_get_ex(json_group, src_str, &json_source);
2907
2908 if (!json_source) {
2909 json_source = json_object_new_object();
2910 json_object_object_add(json_group, src_str, json_source);
2911 }
2912
2913 /* Find the inbound interface nested under the source, create it if it doesn't exist */
07335c8d
DS
2914 json_object_int_add(json_source, "installed", c_oil->installed);
2915 json_object_int_add(json_source, "refCount", c_oil->oil_ref_count);
2916 json_object_int_add(json_source, "oilSize", c_oil->oil_size);
bfdf4096 2917 json_object_int_add(json_source, "OilInheritedRescan", c_oil->oil_inherited_rescan);
01cb1466 2918 json_object_string_add(json_source, "iif", in_ifname);
2919 json_oil = NULL;
b3fb2c27
DW
2920 }
2921
12e41d03 2922 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
12e41d03
DL
2923 struct interface *ifp_out;
2924 char oif_uptime[10];
2925 int ttl;
12e41d03
DL
2926
2927 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2928 if (ttl < 1)
2929 continue;
2930
12e41d03 2931 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
12e41d03 2932 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
91c6aec4 2933 found_oif = 1;
12e41d03 2934
b3fb2c27
DW
2935 if (ifp_out)
2936 strcpy(out_ifname, ifp_out->name);
2937 else
2938 strcpy(out_ifname, "<oif?>");
12e41d03 2939
b3fb2c27
DW
2940 if (uj) {
2941 json_ifp_out = json_object_new_object();
2942 json_object_string_add(json_ifp_out, "source", src_str);
2943 json_object_string_add(json_ifp_out, "group", grp_str);
2944
2945 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM)
2946 json_object_boolean_true_add(json_ifp_out, "protocolPim");
2947
2948 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP)
2949 json_object_boolean_true_add(json_ifp_out, "protocolIgmp");
2950
2951 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE)
2952 json_object_boolean_true_add(json_ifp_out, "protocolSource");
2953
2954 json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
2955 json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
2956 json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
2957 json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
2958 json_object_int_add(json_ifp_out, "ttl", ttl);
2959 json_object_string_add(json_ifp_out, "upTime", oif_uptime);
01cb1466 2960 if (!json_oil) {
2961 json_oil = json_object_new_object();
2962 json_object_object_add(json_source, "oil", json_oil);
2963 }
2964 json_object_object_add(json_oil, out_ifname, json_ifp_out);
b3fb2c27 2965 } else {
b3fb2c27 2966 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
f59a8217 2967 strcpy(proto, "PIM");
b3fb2c27
DW
2968 }
2969
2970 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
f59a8217 2971 strcpy(proto, "IGMP");
b3fb2c27
DW
2972 }
2973
2974 if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) {
f59a8217 2975 strcpy(proto, "SRC");
b3fb2c27
DW
2976 }
2977
f59a8217 2978 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
b3fb2c27
DW
2979 src_str,
2980 grp_str,
2981 proto,
2982 in_ifname,
b3fb2c27 2983 out_ifname,
b3fb2c27
DW
2984 ttl,
2985 oif_uptime,
2986 VTY_NEWLINE);
f59a8217
DS
2987
2988 if (first)
2989 {
2990 src_str[0] = '\0';
2991 grp_str[0] = '\0';
2992 in_ifname[0] = '\0';
2993 first = 0;
2994 }
b3fb2c27 2995 }
12e41d03 2996 }
91c6aec4
DW
2997
2998 if (!uj && !found_oif) {
31a21c9c 2999 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
91c6aec4
DW
3000 src_str,
3001 grp_str,
31a21c9c 3002 "none",
91c6aec4 3003 in_ifname,
91c6aec4
DW
3004 "none",
3005 0,
91c6aec4
DW
3006 "--:--:--",
3007 VTY_NEWLINE);
3008 }
12e41d03 3009 }
6250610a
JAG
3010
3011 /* Print list of static routes */
3012 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
eaa54bdb
DW
3013 char grp_str[INET_ADDRSTRLEN];
3014 char src_str[INET_ADDRSTRLEN];
b3fb2c27
DW
3015 char in_ifname[16];
3016 char out_ifname[16];
6250610a 3017 int oif_vif_index;
b3fb2c27 3018 struct interface *ifp_in;
f59a8217
DS
3019 char proto[100];
3020 first = 1;
6250610a 3021
58302dc7
DS
3022 if (!s_route->c_oil.installed)
3023 continue;
3024
b3fb2c27
DW
3025 pim_inet4_dump("<group?>", s_route->group, grp_str, sizeof(grp_str));
3026 pim_inet4_dump("<source?>", s_route->source, src_str, sizeof(src_str));
3027 ifp_in = pim_if_find_by_vif_index(s_route->iif);
91c6aec4 3028 found_oif = 0;
b3fb2c27
DW
3029
3030 if (ifp_in)
3031 strcpy(in_ifname, ifp_in->name);
3032 else
3033 strcpy(in_ifname, "<iif?>");
3034
3035 if (uj) {
3036
3037 /* Find the group, create it if it doesn't exist */
3038 json_object_object_get_ex(json, grp_str, &json_group);
3039
3040 if (!json_group) {
3041 json_group = json_object_new_object();
3042 json_object_object_add(json, grp_str, json_group);
3043 }
3044
3045 /* Find the source nested under the group, create it if it doesn't exist */
3046 json_object_object_get_ex(json_group, src_str, &json_source);
3047
3048 if (!json_source) {
3049 json_source = json_object_new_object();
3050 json_object_object_add(json_group, src_str, json_source);
3051 }
3052
01cb1466 3053 json_object_string_add(json_source, "iif", in_ifname);
3054 json_oil = NULL;
b3fb2c27 3055 } else {
f59a8217 3056 strcpy(proto, "STATIC");
b3fb2c27 3057 }
6250610a
JAG
3058
3059 for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
6250610a
JAG
3060 struct interface *ifp_out;
3061 char oif_uptime[10];
3062 int ttl;
6250610a
JAG
3063
3064 ttl = s_route->oif_ttls[oif_vif_index];
3065 if (ttl < 1)
3066 continue;
3067
6250610a 3068 ifp_out = pim_if_find_by_vif_index(oif_vif_index);
9867746a 3069 pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->c_oil.oif_creation[oif_vif_index]);
91c6aec4 3070 found_oif = 1;
6250610a 3071
b3fb2c27
DW
3072 if (ifp_out)
3073 strcpy(out_ifname, ifp_out->name);
3074 else
3075 strcpy(out_ifname, "<oif?>");
6250610a 3076
b3fb2c27
DW
3077 if (uj) {
3078 json_ifp_out = json_object_new_object();
3079 json_object_string_add(json_ifp_out, "source", src_str);
3080 json_object_string_add(json_ifp_out, "group", grp_str);
3081 json_object_boolean_true_add(json_ifp_out, "protocolStatic");
3082 json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
3083 json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
3084 json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
3085 json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
3086 json_object_int_add(json_ifp_out, "ttl", ttl);
3087 json_object_string_add(json_ifp_out, "upTime", oif_uptime);
01cb1466 3088 if (!json_oil) {
3089 json_oil = json_object_new_object();
3090 json_object_object_add(json_source, "oil", json_oil);
3091 }
3092 json_object_object_add(json_oil, out_ifname, json_ifp_out);
b3fb2c27 3093 } else {
f59a8217 3094 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
b3fb2c27
DW
3095 src_str,
3096 grp_str,
3097 proto,
3098 in_ifname,
b3fb2c27 3099 out_ifname,
b3fb2c27
DW
3100 ttl,
3101 oif_uptime,
3102 VTY_NEWLINE);
f59a8217
DS
3103 if (first)
3104 {
3105 src_str[0] = '\0';
3106 grp_str[0] = '\0';
3107 in_ifname[0] = '\0';
3108 first = 0;
3109 }
b3fb2c27 3110 }
6250610a 3111 }
91c6aec4
DW
3112
3113 if (!uj && !found_oif) {
f59a8217 3114 vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s%s",
91c6aec4
DW
3115 src_str,
3116 grp_str,
3117 proto,
3118 in_ifname,
91c6aec4
DW
3119 "none",
3120 0,
91c6aec4
DW
3121 "--:--:--",
3122 VTY_NEWLINE);
3123 }
6250610a 3124 }
b3fb2c27
DW
3125
3126 if (uj) {
17b52be1 3127 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
b3fb2c27
DW
3128 json_object_free(json);
3129 }
12e41d03
DL
3130}
3131
3132DEFUN (show_ip_mroute,
3133 show_ip_mroute_cmd,
b3fb2c27 3134 "show ip mroute [json]",
12e41d03
DL
3135 SHOW_STR
3136 IP_STR
3137 MROUTE_STR)
3138{
b3fb2c27
DW
3139 u_char uj = use_json(argc, argv);
3140 show_mroute(vty, uj);
12e41d03
DL
3141 return CMD_SUCCESS;
3142}
3143
3144static void show_mroute_count(struct vty *vty)
3145{
3146 struct listnode *node;
3147 struct channel_oil *c_oil;
6250610a 3148 struct static_route *s_route;
12e41d03
DL
3149
3150 vty_out(vty, "%s", VTY_NEWLINE);
3151
eccf56d2 3152 vty_out(vty, "Source Group LastUsed Packets Bytes WrongIf %s",
12e41d03
DL
3153 VTY_NEWLINE);
3154
6250610a 3155 /* Print PIM and IGMP route counts */
040d86ad 3156 for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
eaa54bdb
DW
3157 char group_str[INET_ADDRSTRLEN];
3158 char source_str[INET_ADDRSTRLEN];
12e41d03 3159
58302dc7
DS
3160 if (!c_oil->installed)
3161 continue;
3162
3667e8a0 3163 pim_mroute_update_counters (c_oil);
12e41d03
DL
3164
3165 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
3166 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
3167
eccf56d2 3168 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
12e41d03
DL
3169 source_str,
3170 group_str,
eccf56d2 3171 c_oil->cc.lastused/100,
3667e8a0
DS
3172 c_oil->cc.pktcnt,
3173 c_oil->cc.bytecnt,
3174 c_oil->cc.wrong_if,
12e41d03 3175 VTY_NEWLINE);
6250610a
JAG
3176 }
3177
3178 /* Print static route counts */
3179 for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
eaa54bdb
DW
3180 char group_str[INET_ADDRSTRLEN];
3181 char source_str[INET_ADDRSTRLEN];
6250610a 3182
58302dc7
DS
3183 if (!s_route->c_oil.installed)
3184 continue;
3185
3667e8a0 3186 pim_mroute_update_counters (&s_route->c_oil);
6250610a 3187
9867746a
DS
3188 pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
3189 pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
6250610a 3190
eccf56d2 3191 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld%s",
6250610a
JAG
3192 source_str,
3193 group_str,
eccf56d2 3194 s_route->c_oil.cc.lastused,
3667e8a0
DS
3195 s_route->c_oil.cc.pktcnt,
3196 s_route->c_oil.cc.bytecnt,
3197 s_route->c_oil.cc.wrong_if,
6250610a 3198 VTY_NEWLINE);
12e41d03
DL
3199 }
3200}
3201
3202DEFUN (show_ip_mroute_count,
3203 show_ip_mroute_count_cmd,
3204 "show ip mroute count",
3205 SHOW_STR
3206 IP_STR
3207 MROUTE_STR
3208 "Route and packet count data\n")
3209{
3210 show_mroute_count(vty);
3211 return CMD_SUCCESS;
3212}
3213
3214DEFUN (show_ip_rib,
3215 show_ip_rib_cmd,
3216 "show ip rib A.B.C.D",
3217 SHOW_STR
3218 IP_STR
3219 RIB_STR
3220 "Unicast address\n")
3221{
b181fa04 3222 int idx_ipv4 = 3;
12e41d03
DL
3223 struct in_addr addr;
3224 const char *addr_str;
3225 struct pim_nexthop nexthop;
eaa54bdb 3226 char nexthop_addr_str[PREFIX_STRLEN];
12e41d03
DL
3227 int result;
3228
580d7612 3229 memset (&nexthop, 0, sizeof (nexthop));
b181fa04 3230 addr_str = argv[idx_ipv4]->arg;
12e41d03
DL
3231 result = inet_pton(AF_INET, addr_str, &addr);
3232 if (result <= 0) {
3233 vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
3234 addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
3235 return CMD_WARNING;
3236 }
3237
63b8f7a3 3238 if (pim_nexthop_lookup(&nexthop, addr, 0)) {
12e41d03
DL
3239 vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
3240 addr_str, VTY_NEWLINE);
3241 return CMD_WARNING;
3242 }
3243
3244 vty_out(vty, "Address NextHop Interface Metric Preference%s",
3245 VTY_NEWLINE);
3246
63c59d0c
DS
3247 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
3248 nexthop_addr_str, sizeof(nexthop_addr_str));
12e41d03
DL
3249
3250 vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
3251 addr_str,
3252 nexthop_addr_str,
3253 nexthop.interface ? nexthop.interface->name : "<ifname?>",
3254 nexthop.mrib_route_metric,
3255 nexthop.mrib_metric_preference,
3256 VTY_NEWLINE);
3257
3258 return CMD_SUCCESS;
3259}
3260
3261static void show_ssmpingd(struct vty *vty)
3262{
3263 struct listnode *node;
3264 struct ssmpingd_sock *ss;
3265 time_t now;
3266
3267 vty_out(vty, "Source Socket Address Port Uptime Requests%s",
3268 VTY_NEWLINE);
3269
3270 if (!qpim_ssmpingd_list)
3271 return;
3272
3273 now = pim_time_monotonic_sec();
3274
3275 for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
eaa54bdb 3276 char source_str[INET_ADDRSTRLEN];
12e41d03
DL
3277 char ss_uptime[10];
3278 struct sockaddr_in bind_addr;
3279 socklen_t len = sizeof(bind_addr);
eaa54bdb 3280 char bind_addr_str[INET_ADDRSTRLEN];
12e41d03
DL
3281
3282 pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
3283
3284 if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
3285 vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
3286 source_str, ss->sock_fd, VTY_NEWLINE);
3287 }
3288
3289 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
3290 pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
3291
3292 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
3293 source_str,
3294 ss->sock_fd,
3295 bind_addr_str,
3296 ntohs(bind_addr.sin_port),
3297 ss_uptime,
3298 (long long)ss->requests,
3299 VTY_NEWLINE);
3300 }
3301}
3302
3303DEFUN (show_ip_ssmpingd,
3304 show_ip_ssmpingd_cmd,
3305 "show ip ssmpingd",
3306 SHOW_STR
3307 IP_STR
3308 SHOW_SSMPINGD_STR)
3309{
3310 show_ssmpingd(vty);
3311 return CMD_SUCCESS;
3312}
3313
36d6bd7d 3314static int
dfe43e25 3315pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const char *plist)
36d6bd7d
DS
3316{
3317 int result;
36d6bd7d 3318
dfe43e25
DW
3319 result = pim_rp_new (rp, group, plist);
3320
3321 if (result == PIM_MALLOC_FAIL)
3322 {
3323 vty_out (vty, "%% Out of memory%s", VTY_NEWLINE);
3324 return CMD_WARNING;
3325 }
3326
3327 if (result == PIM_GROUP_BAD_ADDRESS)
3328 {
3329 vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
3330 return CMD_WARNING;
3331 }
3332
3333 if (result == PIM_RP_BAD_ADDRESS)
36d6bd7d 3334 {
dfe43e25 3335 vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
36d6bd7d
DS
3336 return CMD_WARNING;
3337 }
3338
dfe43e25 3339 if (result == PIM_RP_NO_PATH)
36d6bd7d 3340 {
dfe43e25
DW
3341 vty_out (vty, "%% No Path to RP address specified: %s%s", rp, VTY_NEWLINE);
3342 return CMD_WARNING;
3343 }
3344
3345 if (result == PIM_GROUP_OVERLAP)
3346 {
3347 vty_out (vty, "%% Group range specified cannot overlap%s", VTY_NEWLINE);
3348 return CMD_WARNING;
3349 }
3350
3351 if (result == PIM_GROUP_PFXLIST_OVERLAP)
3352 {
3353 vty_out (vty, "%% This group is already covered by a RP prefix-list%s", VTY_NEWLINE);
3354 return CMD_WARNING;
36d6bd7d
DS
3355 }
3356
dfe43e25 3357 if (result == PIM_RP_PFXLIST_IN_USE)
36d6bd7d 3358 {
dfe43e25
DW
3359 vty_out (vty, "%% The same prefix-list cannot be applied to multiple RPs%s", VTY_NEWLINE);
3360 return CMD_WARNING;
36d6bd7d
DS
3361 }
3362
3363 return CMD_SUCCESS;
3364}
3365
ee1a0718
DS
3366DEFUN (ip_pim_joinprune_time,
3367 ip_pim_joinprune_time_cmd,
3368 "ip pim join-prune-interval <60-600>",
3369 IP_STR
3370 "pim multicast routing\n"
3371 "Join Prune Send Interval\n"
3372 "Seconds\n")
3373{
3374 qpim_t_periodic = atoi(argv[3]->arg);
3375 return CMD_SUCCESS;
3376}
3377
3378DEFUN (no_ip_pim_joinprune_time,
3379 no_ip_pim_joinprune_time_cmd,
3380 "no ip pim join-prune-interval <60-600>",
3381 NO_STR
3382 IP_STR
3383 "pim multicast routing\n"
3384 "Join Prune Send Interval\n"
3385 "Seconds\n")
3386{
3387 qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
3388 return CMD_SUCCESS;
3389}
3390
191f5695
DS
3391DEFUN (ip_pim_register_suppress,
3392 ip_pim_register_suppress_cmd,
3393 "ip pim register-suppress-time <5-60000>",
4304f95c
DS
3394 IP_STR
3395 "pim multicast routing\n"
191f5695
DS
3396 "Register Suppress Timer\n"
3397 "Seconds\n")
4304f95c
DS
3398{
3399 qpim_keep_alive_time = atoi (argv[3]->arg);
3400 return CMD_SUCCESS;
3401}
3402
191f5695
DS
3403DEFUN (no_ip_pim_register_suppress,
3404 no_ip_pim_register_suppress_cmd,
3405 "no ip pim register-suppress-time <5-60000>",
4304f95c
DS
3406 NO_STR
3407 IP_STR
3408 "pim multicast routing\n"
191f5695 3409 "Register Suppress Timer\n"
01408ede 3410 "Seconds\n")
4304f95c 3411{
191f5695 3412 qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
4304f95c
DS
3413 return CMD_SUCCESS;
3414}
3415
191f5695
DS
3416DEFUN (ip_pim_keep_alive,
3417 ip_pim_keep_alive_cmd,
3418 "ip pim keep-alive-timer <31-60000>",
01408ede
DS
3419 IP_STR
3420 "pim multicast routing\n"
01408ede
DS
3421 "Keep alive Timer\n"
3422 "Seconds\n")
3423{
3424 qpim_rp_keep_alive_time = atoi (argv[4]->arg);
3425 return CMD_SUCCESS;
3426}
3427
191f5695
DS
3428DEFUN (no_ip_pim_keep_alive,
3429 no_ip_pim_keep_alive_cmd,
3430 "no ip pim keep-alive-timer <31-60000>",
01408ede
DS
3431 NO_STR
3432 IP_STR
3433 "pim multicast routing\n"
01408ede
DS
3434 "Keep alive Timer\n"
3435 "Seconds\n")
3436{
191f5695 3437 qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
01408ede
DS
3438 return CMD_SUCCESS;
3439}
3440
8e4c9ef3
DS
3441DEFUN (ip_pim_packets,
3442 ip_pim_packets_cmd,
3443 "ip pim packets <1-100>",
3444 IP_STR
3445 "pim multicast routing\n"
3446 "Number of packets to process at one time per fd\n")
3447{
3448 qpim_packet_process = atoi (argv[3]->arg);
3449 return CMD_SUCCESS;
3450}
3451
3452DEFUN (no_ip_pim_packets,
3453 no_ip_pim_packets_cmd,
3454 "no ip pim packets <1-100>",
3455 NO_STR
3456 IP_STR
3457 "pim multicast routing\n"
3458 "Number of packets to process at one time per fd\n")
3459{
3460 qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
3461 return CMD_SUCCESS;
3462}
3463
981d6c7a
DS
3464DEFUN (ip_pim_rp,
3465 ip_pim_rp_cmd,
75a26779 3466 "ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a 3467 IP_STR
9b34069d
QY
3468 "pim multicast routing\n"
3469 "Rendevous Point\n"
3470 "ip address of RP\n")
981d6c7a 3471{
b181fa04 3472 int idx_ipv4 = 3;
dfe43e25
DW
3473 return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
3474}
3475
3476DEFUN (ip_pim_rp_prefix_list,
3477 ip_pim_rp_prefix_list_cmd,
3478 "ip pim rp A.B.C.D prefix-list WORD",
3479 IP_STR
3480 "pim multicast routing\n"
3481 "Rendevous Point\n"
3482 "ip address of RP\n"
3483 "group prefix-list filter\n"
3484 "Name of a prefix-list\n")
3485{
3486 return pim_rp_cmd_worker (vty, argv[3]->arg, NULL, argv[5]->arg);
36d6bd7d 3487}
981d6c7a 3488
36d6bd7d 3489static int
dfe43e25
DW
3490pim_no_rp_cmd_worker (struct vty *vty, const char *rp, const char *group,
3491 const char *plist)
36d6bd7d 3492{
dfe43e25
DW
3493 int result = pim_rp_del (rp, group, plist);
3494
3495 if (result == PIM_GROUP_BAD_ADDRESS)
3496 {
3497 vty_out (vty, "%% Bad group address specified: %s%s", group, VTY_NEWLINE);
3498 return CMD_WARNING;
3499 }
75a26779 3500
dfe43e25 3501 if (result == PIM_RP_BAD_ADDRESS)
75a26779 3502 {
dfe43e25 3503 vty_out (vty, "%% Bad RP address specified: %s%s", rp, VTY_NEWLINE);
36d6bd7d 3504 return CMD_WARNING;
75a26779 3505 }
981d6c7a 3506
dfe43e25 3507 if (result == PIM_RP_NOT_FOUND)
13afbd05 3508 {
dfe43e25 3509 vty_out (vty, "%% Unable to find specified RP%s", VTY_NEWLINE);
13afbd05
DS
3510 return CMD_WARNING;
3511 }
c8ae3ce8 3512
981d6c7a
DS
3513 return CMD_SUCCESS;
3514}
3515
3516DEFUN (no_ip_pim_rp,
3517 no_ip_pim_rp_cmd,
75a26779 3518 "no ip pim rp A.B.C.D [A.B.C.D/M]",
981d6c7a
DS
3519 NO_STR
3520 IP_STR
9b34069d
QY
3521 "pim multicast routing\n"
3522 "Rendevous Point\n"
3523 "ip address of RP\n")
981d6c7a 3524{
75a26779 3525 int idx_ipv4 = 4;
dfe43e25
DW
3526 return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
3527}
3528
3529DEFUN (no_ip_pim_rp_prefix_list,
3530 no_ip_pim_rp_prefix_list_cmd,
3531 "no ip pim rp A.B.C.D prefix-list WORD",
3532 NO_STR
3533 IP_STR
3534 "pim multicast routing\n"
3535 "Rendevous Point\n"
3536 "ip address of RP\n"
3537 "group prefix-list filter\n"
3538 "Name of a prefix-list\n")
3539{
3540 return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
981d6c7a
DS
3541}
3542
12e41d03
DL
3543DEFUN (ip_multicast_routing,
3544 ip_multicast_routing_cmd,
9ccf14f7 3545 "ip multicast-routing",
12e41d03
DL
3546 IP_STR
3547 "Enable IP multicast forwarding\n")
3548{
3549 pim_mroute_socket_enable();
3550 pim_if_add_vif_all();
3551 mroute_add_all();
6250610a 3552 static_mroute_add_all();
12e41d03
DL
3553 return CMD_SUCCESS;
3554}
3555
3556DEFUN (no_ip_multicast_routing,
3557 no_ip_multicast_routing_cmd,
9ccf14f7 3558 "no ip multicast-routing",
12e41d03
DL
3559 NO_STR
3560 IP_STR
3561 "Global IP configuration subcommands\n"
3562 "Enable IP multicast forwarding\n")
3563{
3564 mroute_del_all();
6250610a 3565 static_mroute_del_all();
12e41d03
DL
3566 pim_if_del_vif_all();
3567 pim_mroute_socket_disable();
3568 return CMD_SUCCESS;
3569}
3570
3571DEFUN (ip_ssmpingd,
3572 ip_ssmpingd_cmd,
3573 "ip ssmpingd [A.B.C.D]",
3574 IP_STR
3575 CONF_SSMPINGD_STR
3576 "Source address\n")
3577{
b181fa04 3578 int idx_ipv4 = 2;
12e41d03
DL
3579 int result;
3580 struct in_addr source_addr;
abddf075 3581 const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03
DL
3582
3583 result = inet_pton(AF_INET, source_str, &source_addr);
3584 if (result <= 0) {
3585 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
3586 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3587 return CMD_WARNING;
3588 }
3589
3590 result = pim_ssmpingd_start(source_addr);
3591 if (result) {
3592 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
3593 source_str, result, VTY_NEWLINE);
3594 return CMD_WARNING;
3595 }
3596
3597 return CMD_SUCCESS;
3598}
3599
3600DEFUN (no_ip_ssmpingd,
3601 no_ip_ssmpingd_cmd,
3602 "no ip ssmpingd [A.B.C.D]",
3603 NO_STR
3604 IP_STR
3605 CONF_SSMPINGD_STR
3606 "Source address\n")
3607{
b181fa04 3608 int idx_ipv4 = 3;
12e41d03
DL
3609 int result;
3610 struct in_addr source_addr;
abddf075 3611 const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
12e41d03
DL
3612
3613 result = inet_pton(AF_INET, source_str, &source_addr);
3614 if (result <= 0) {
3615 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
3616 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3617 return CMD_WARNING;
3618 }
3619
3620 result = pim_ssmpingd_stop(source_addr);
3621 if (result) {
3622 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
3623 source_str, result, VTY_NEWLINE);
3624 return CMD_WARNING;
3625 }
3626
3627 return CMD_SUCCESS;
3628}
3629
3630DEFUN (interface_ip_igmp,
3631 interface_ip_igmp_cmd,
3632 "ip igmp",
3633 IP_STR
3634 IFACE_IGMP_STR)
3635{
cdc2d765 3636 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3637 struct pim_interface *pim_ifp;
3638
12e41d03
DL
3639 pim_ifp = ifp->info;
3640
3641 if (!pim_ifp) {
3642 pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
3643 if (!pim_ifp) {
3644 vty_out(vty, "Could not enable IGMP on interface %s%s",
3645 ifp->name, VTY_NEWLINE);
3646 return CMD_WARNING;
3647 }
3648 }
3649 else {
3650 PIM_IF_DO_IGMP(pim_ifp->options);
3651 }
3652
3653 pim_if_addr_add_all(ifp);
3654 pim_if_membership_refresh(ifp);
3655
3656 return CMD_SUCCESS;
3657}
3658
3659DEFUN (interface_no_ip_igmp,
3660 interface_no_ip_igmp_cmd,
3661 "no ip igmp",
3662 NO_STR
3663 IP_STR
3664 IFACE_IGMP_STR)
3665{
cdc2d765 3666 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3667 struct pim_interface *pim_ifp;
3668
12e41d03
DL
3669 pim_ifp = ifp->info;
3670 if (!pim_ifp)
3671 return CMD_SUCCESS;
3672
3673 PIM_IF_DONT_IGMP(pim_ifp->options);
3674
3675 pim_if_membership_clear(ifp);
3676
3677 pim_if_addr_del_all_igmp(ifp);
3678
3679 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
3680 pim_if_delete(ifp);
3681 }
3682
3683 return CMD_SUCCESS;
3684}
3685
3686DEFUN (interface_ip_igmp_join,
3687 interface_ip_igmp_join_cmd,
3688 "ip igmp join A.B.C.D A.B.C.D",
3689 IP_STR
3690 IFACE_IGMP_STR
3691 "IGMP join multicast group\n"
3692 "Multicast group address\n"
3693 "Source address\n")
3694{
cdc2d765 3695 VTY_DECLVAR_CONTEXT(interface, ifp);
b181fa04
DW
3696 int idx_ipv4 = 3;
3697 int idx_ipv4_2 = 4;
12e41d03
DL
3698 const char *group_str;
3699 const char *source_str;
3700 struct in_addr group_addr;
3701 struct in_addr source_addr;
3702 int result;
3703
12e41d03 3704 /* Group address */
b181fa04 3705 group_str = argv[idx_ipv4]->arg;
12e41d03
DL
3706 result = inet_pton(AF_INET, group_str, &group_addr);
3707 if (result <= 0) {
3708 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3709 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
3710 return CMD_WARNING;
3711 }
3712
3713 /* Source address */
b181fa04 3714 source_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
3715 result = inet_pton(AF_INET, source_str, &source_addr);
3716 if (result <= 0) {
3717 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3718 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3719 return CMD_WARNING;
3720 }
3721
3722 result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
3723 if (result) {
3724 vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
3725 group_str, source_str, ifp->name, result, VTY_NEWLINE);
3726 return CMD_WARNING;
3727 }
3728
3729 return CMD_SUCCESS;
3730}
3731
3732DEFUN (interface_no_ip_igmp_join,
3733 interface_no_ip_igmp_join_cmd,
3734 "no ip igmp join A.B.C.D A.B.C.D",
3735 NO_STR
3736 IP_STR
3737 IFACE_IGMP_STR
3738 "IGMP join multicast group\n"
3739 "Multicast group address\n"
3740 "Source address\n")
3741{
cdc2d765 3742 VTY_DECLVAR_CONTEXT(interface, ifp);
b181fa04
DW
3743 int idx_ipv4 = 4;
3744 int idx_ipv4_2 = 5;
12e41d03
DL
3745 const char *group_str;
3746 const char *source_str;
3747 struct in_addr group_addr;
3748 struct in_addr source_addr;
3749 int result;
3750
12e41d03 3751 /* Group address */
b181fa04 3752 group_str = argv[idx_ipv4]->arg;
12e41d03
DL
3753 result = inet_pton(AF_INET, group_str, &group_addr);
3754 if (result <= 0) {
3755 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
3756 group_str, errno, safe_strerror(errno), VTY_NEWLINE);
3757 return CMD_WARNING;
3758 }
3759
3760 /* Source address */
b181fa04 3761 source_str = argv[idx_ipv4_2]->arg;
12e41d03
DL
3762 result = inet_pton(AF_INET, source_str, &source_addr);
3763 if (result <= 0) {
3764 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
3765 source_str, errno, safe_strerror(errno), VTY_NEWLINE);
3766 return CMD_WARNING;
3767 }
3768
3769 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
3770 if (result) {
3771 vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
3772 group_str, source_str, ifp->name, result, VTY_NEWLINE);
3773 return CMD_WARNING;
3774 }
3775
3776 return CMD_SUCCESS;
3777}
3778
3779/*
3780 CLI reconfiguration affects the interface level (struct pim_interface).
3781 This function propagates the reconfiguration to every active socket
3782 for that interface.
3783 */
3784static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
3785{
3786 struct interface *ifp;
3787 struct pim_interface *pim_ifp;
3788
3789 zassert(igmp);
3790
3791 /* other querier present? */
3792
3793 if (igmp->t_other_querier_timer)
3794 return;
3795
3796 /* this is the querier */
3797
3798 zassert(igmp->interface);
3799 zassert(igmp->interface->info);
3800
3801 ifp = igmp->interface;
3802 pim_ifp = ifp->info;
3803
3804 if (PIM_DEBUG_IGMP_TRACE) {
eaa54bdb 3805 char ifaddr_str[INET_ADDRSTRLEN];
12e41d03
DL
3806 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
3807 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
3808 __PRETTY_FUNCTION__,
3809 ifaddr_str,
3810 ifp->name,
3811 pim_ifp->igmp_default_query_interval);
3812 }
3813
3814 /*
3815 igmp_startup_mode_on() will reset QQI:
3816
3817 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
3818 */
3819 igmp_startup_mode_on(igmp);
3820}
3821
3822static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
3823{
3824 if (igmp->t_igmp_query_timer) {
3825 /* other querier present */
3826 zassert(igmp->t_igmp_query_timer);
3827 zassert(!igmp->t_other_querier_timer);
3828
3829 pim_igmp_general_query_off(igmp);
3830 pim_igmp_general_query_on(igmp);
3831
3832 zassert(igmp->t_igmp_query_timer);
3833 zassert(!igmp->t_other_querier_timer);
3834 }
3835 else {
3836 /* this is the querier */
3837
3838 zassert(!igmp->t_igmp_query_timer);
3839 zassert(igmp->t_other_querier_timer);
3840
3841 pim_igmp_other_querier_timer_off(igmp);
3842 pim_igmp_other_querier_timer_on(igmp);
3843
3844 zassert(!igmp->t_igmp_query_timer);
3845 zassert(igmp->t_other_querier_timer);
3846 }
3847}
3848
3849static void change_query_interval(struct pim_interface *pim_ifp,
3850 int query_interval)
3851{
3852 struct listnode *sock_node;
3853 struct igmp_sock *igmp;
3854
3855 pim_ifp->igmp_default_query_interval = query_interval;
3856
3857 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
3858 igmp_sock_query_interval_reconfig(igmp);
3859 igmp_sock_query_reschedule(igmp);
3860 }
3861}
3862
3863static void change_query_max_response_time(struct pim_interface *pim_ifp,
3864 int query_max_response_time_dsec)
3865{
3866 struct listnode *sock_node;
3867 struct igmp_sock *igmp;
3868
3869 pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
3870
3871 /*
3872 Below we modify socket/group/source timers in order to quickly
3873 reflect the change. Otherwise, those timers would eventually catch
3874 up.
3875 */
3876
3877 /* scan all sockets */
3878 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
3879 struct listnode *grp_node;
3880 struct igmp_group *grp;
3881
3882 /* reschedule socket general query */
3883 igmp_sock_query_reschedule(igmp);
3884
3885 /* scan socket groups */
3886 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
3887 struct listnode *src_node;
3888 struct igmp_source *src;
3889
3890 /* reset group timers for groups in EXCLUDE mode */
3891 if (grp->group_filtermode_isexcl) {
3892 igmp_group_reset_gmi(grp);
3893 }
3894
3895 /* scan group sources */
3896 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
3897
3898 /* reset source timers for sources with running timers */
3899 if (src->t_source_timer) {
3900 igmp_source_reset_gmi(igmp, grp, src);
3901 }
3902 }
3903 }
3904 }
3905}
3906
3907#define IGMP_QUERY_INTERVAL_MIN (1)
3908#define IGMP_QUERY_INTERVAL_MAX (1800)
3909
3910DEFUN (interface_ip_igmp_query_interval,
3911 interface_ip_igmp_query_interval_cmd,
9ccf14f7 3912 "ip igmp query-interval (1-1800)",
12e41d03
DL
3913 IP_STR
3914 IFACE_IGMP_STR
3915 IFACE_IGMP_QUERY_INTERVAL_STR
3916 "Query interval in seconds\n")
3917{
cdc2d765 3918 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3919 struct pim_interface *pim_ifp;
3920 int query_interval;
3921 int query_interval_dsec;
3922
12e41d03
DL
3923 pim_ifp = ifp->info;
3924
3925 if (!pim_ifp) {
3926 vty_out(vty,
3927 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
3928 ifp->name,
3929 VTY_NEWLINE);
3930 return CMD_WARNING;
3931 }
3932
91ac1d43 3933 query_interval = atoi(argv[4]->arg);
12e41d03
DL
3934 query_interval_dsec = 10 * query_interval;
3935
3936 /*
3937 It seems we don't need to check bounds since command.c does it
3938 already, but we verify them anyway for extra safety.
3939 */
3940 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
3941 vty_out(vty, "General query interval %d lower than minimum %d%s",
3942 query_interval,
3943 IGMP_QUERY_INTERVAL_MIN,
3944 VTY_NEWLINE);
3945 return CMD_WARNING;
3946 }
3947 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
3948 vty_out(vty, "General query interval %d higher than maximum %d%s",
3949 query_interval,
3950 IGMP_QUERY_INTERVAL_MAX,
3951 VTY_NEWLINE);
3952 return CMD_WARNING;
3953 }
3954
3955 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
3956 vty_out(vty,
3957 "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
3958 query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
3959 VTY_NEWLINE);
3960 return CMD_WARNING;
3961 }
3962
3963 change_query_interval(pim_ifp, query_interval);
3964
3965 return CMD_SUCCESS;
3966}
3967
3968DEFUN (interface_no_ip_igmp_query_interval,
3969 interface_no_ip_igmp_query_interval_cmd,
9ccf14f7 3970 "no ip igmp query-interval",
12e41d03
DL
3971 NO_STR
3972 IP_STR
3973 IFACE_IGMP_STR
3974 IFACE_IGMP_QUERY_INTERVAL_STR)
3975{
cdc2d765 3976 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
3977 struct pim_interface *pim_ifp;
3978 int default_query_interval_dsec;
3979
12e41d03
DL
3980 pim_ifp = ifp->info;
3981
3982 if (!pim_ifp)
3983 return CMD_SUCCESS;
3984
3985 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
3986
3987 if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
3988 vty_out(vty,
3989 "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
3990 default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
3991 VTY_NEWLINE);
3992 return CMD_WARNING;
3993 }
3994
3995 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
3996
3997 return CMD_SUCCESS;
3998}
3999
b05b72e8
DW
4000DEFUN (interface_ip_igmp_version,
4001 interface_ip_igmp_version_cmd,
4002 "ip igmp version <2-3>",
4003 IP_STR
4004 IFACE_IGMP_STR
4005 "IGMP version\n"
4006 "IGMP version number\n")
4007{
4008 VTY_DECLVAR_CONTEXT(interface,ifp);
4009 struct pim_interface *pim_ifp;
4010 int igmp_version;
4011
4012 pim_ifp = ifp->info;
4013
4014 if (!pim_ifp) {
4015 vty_out(vty,
4016 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4017 ifp->name,
4018 VTY_NEWLINE);
4019 return CMD_WARNING;
4020 }
4021
4022 igmp_version = atoi(argv[3]->arg);
4023 pim_ifp->igmp_version = igmp_version;
4024
4025 return CMD_SUCCESS;
4026}
4027
4028DEFUN (interface_no_ip_igmp_version,
4029 interface_no_ip_igmp_version_cmd,
4030 "no ip igmp version <2-3>",
4031 NO_STR
4032 IP_STR
4033 IFACE_IGMP_STR
4034 "IGMP version\n"
4035 "IGMP version number\n")
4036{
4037 VTY_DECLVAR_CONTEXT(interface, ifp);
4038 struct pim_interface *pim_ifp;
4039
4040 pim_ifp = ifp->info;
4041
4042 if (!pim_ifp)
4043 return CMD_SUCCESS;
4044
4045 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
4046
4047 return CMD_SUCCESS;
4048}
4049
58344b65
DS
4050#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4051#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
12e41d03
DL
4052
4053DEFUN (interface_ip_igmp_query_max_response_time,
4054 interface_ip_igmp_query_max_response_time_cmd,
58344b65 4055 "ip igmp query-max-response-time (10-250)",
12e41d03
DL
4056 IP_STR
4057 IFACE_IGMP_STR
4058 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
58344b65 4059 "Query response value in deci-seconds\n")
12e41d03 4060{
cdc2d765 4061 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
4062 struct pim_interface *pim_ifp;
4063 int query_max_response_time;
4064
12e41d03
DL
4065 pim_ifp = ifp->info;
4066
4067 if (!pim_ifp) {
4068 vty_out(vty,
4069 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4070 ifp->name,
4071 VTY_NEWLINE);
4072 return CMD_WARNING;
4073 }
4074
91ac1d43 4075 query_max_response_time = atoi(argv[4]->arg);
12e41d03 4076
58344b65 4077 if (query_max_response_time >= pim_ifp->igmp_default_query_interval * 10) {
12e41d03
DL
4078 vty_out(vty,
4079 "Can't set query max response time %d sec >= general query interval %d sec%s",
4080 query_max_response_time, pim_ifp->igmp_default_query_interval,
4081 VTY_NEWLINE);
4082 return CMD_WARNING;
4083 }
4084
58344b65 4085 change_query_max_response_time(pim_ifp, query_max_response_time);
12e41d03
DL
4086
4087 return CMD_SUCCESS;
4088}
4089
4090DEFUN (interface_no_ip_igmp_query_max_response_time,
4091 interface_no_ip_igmp_query_max_response_time_cmd,
f041117e 4092 "no ip igmp query-max-response-time <10-250>",
12e41d03
DL
4093 NO_STR
4094 IP_STR
4095 IFACE_IGMP_STR
4096 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
4097{
cdc2d765 4098 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03 4099 struct pim_interface *pim_ifp;
12e41d03 4100
12e41d03
DL
4101 pim_ifp = ifp->info;
4102
4103 if (!pim_ifp)
4104 return CMD_SUCCESS;
4105
12e41d03
DL
4106 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
4107
4108 return CMD_SUCCESS;
4109}
4110
4111#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
4112#define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
4113
58344b65
DS
4114DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
4115 interface_ip_igmp_query_max_response_time_dsec_cmd,
4116 "ip igmp query-max-response-time-dsec (10-250)",
4117 IP_STR
4118 IFACE_IGMP_STR
4119 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
4120 "Query response value in deciseconds\n")
12e41d03 4121{
cdc2d765 4122 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03
DL
4123 struct pim_interface *pim_ifp;
4124 int query_max_response_time_dsec;
4125 int default_query_interval_dsec;
4126
12e41d03
DL
4127 pim_ifp = ifp->info;
4128
4129 if (!pim_ifp) {
4130 vty_out(vty,
4131 "IGMP not enabled on interface %s. Please enable IGMP first.%s",
4132 ifp->name,
4133 VTY_NEWLINE);
4134 return CMD_WARNING;
4135 }
4136
91ac1d43 4137 query_max_response_time_dsec = atoi(argv[4]->arg);
12e41d03 4138
12e41d03
DL
4139 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
4140
4141 if (query_max_response_time_dsec >= default_query_interval_dsec) {
4142 vty_out(vty,
4143 "Can't set query max response time %d dsec >= general query interval %d dsec%s",
4144 query_max_response_time_dsec, default_query_interval_dsec,
4145 VTY_NEWLINE);
4146 return CMD_WARNING;
4147 }
4148
4149 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
4150
4151 return CMD_SUCCESS;
4152}
4153
58344b65
DS
4154DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
4155 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
4156 "no ip igmp query-max-response-time-dsec",
4157 NO_STR
4158 IP_STR
4159 IFACE_IGMP_STR
4160 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
12e41d03 4161{
cdc2d765 4162 VTY_DECLVAR_CONTEXT(interface, ifp);
12e41d03 4163 struct pim_interface *pim_ifp;
12e41d03 4164
12e41d03
DL
4165 pim_ifp = ifp->info;
4166
4167 if (!pim_ifp)
4168 return CMD_SUCCESS;
4169
12e41d03
DL
4170 change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
4171
4172 return CMD_SUCCESS;
4173}
4174
dedccda6
DS
4175DEFUN (interface_ip_pim_drprio,
4176 interface_ip_pim_drprio_cmd,
b181fa04 4177 "ip pim drpriority (1-4294967295)",
dedccda6
DS
4178 IP_STR
4179 PIM_STR
4180 "Set the Designated Router Election Priority\n"
4181 "Value of the new DR Priority\n")
4182{
cdc2d765 4183 VTY_DECLVAR_CONTEXT(interface, ifp);
b181fa04 4184 int idx_number = 3;
dedccda6
DS
4185 struct pim_interface *pim_ifp;
4186 uint32_t old_dr_prio;
4187
dedccda6
DS
4188 pim_ifp = ifp->info;
4189
4190 if (!pim_ifp) {
4191 vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
4192 return CMD_WARNING;
4193 }
4194
4195 old_dr_prio = pim_ifp->pim_dr_priority;
4196
b181fa04 4197 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
dedccda6
DS
4198
4199 if (old_dr_prio != pim_ifp->pim_dr_priority) {
4200 if (pim_if_dr_election(ifp))
4201 pim_hello_restart_now(ifp);
4202 }
4203
4204 return CMD_SUCCESS;
4205}
4206
4207DEFUN (interface_no_ip_pim_drprio,
4208 interface_no_ip_pim_drprio_cmd,
b181fa04 4209 "no ip pim drpriority [(1-4294967295)]",
d7fa34c1 4210 NO_STR
dedccda6
DS
4211 IP_STR
4212 PIM_STR
4213 "Revert the Designated Router Priority to default\n"
4214 "Old Value of the Priority\n")
4215{
cdc2d765 4216 VTY_DECLVAR_CONTEXT(interface, ifp);
dedccda6
DS
4217 struct pim_interface *pim_ifp;
4218
dedccda6
DS
4219 pim_ifp = ifp->info;
4220
4221 if (!pim_ifp) {
7960fa8f 4222 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
dedccda6
DS
4223 return CMD_WARNING;
4224 }
4225
4226 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
4227 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
4228 if (pim_if_dr_election(ifp))
4229 pim_hello_restart_now(ifp);
4230 }
4231
4232 return CMD_SUCCESS;
4233}
4234
981d6c7a
DS
4235static int
4236pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
12e41d03 4237{
981d6c7a 4238 struct pim_interface *pim_ifp = ifp->info;
12e41d03
DL
4239
4240 if (!pim_ifp) {
4241 pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
4242 if (!pim_ifp) {
981d6c7a 4243 return 0;
12e41d03
DL
4244 }
4245 }
4246 else {
4247 PIM_IF_DO_PIM(pim_ifp->options);
4248 }
4249
981d6c7a 4250 pim_ifp->itype = itype;
12e41d03
DL
4251 pim_if_addr_add_all(ifp);
4252 pim_if_membership_refresh(ifp);
981d6c7a
DS
4253 return 1;
4254}
4255
4256
4257DEFUN (interface_ip_pim_ssm,
4258 interface_ip_pim_ssm_cmd,
4259 "ip pim ssm",
4260 IP_STR
4261 PIM_STR
4262 IFACE_PIM_STR)
4263{
cdc2d765 4264 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
4265
4266 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) {
4267 vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE);
4268 return CMD_WARNING;
4269 }
4270
12e41d03
DL
4271 return CMD_SUCCESS;
4272}
4273
981d6c7a
DS
4274DEFUN (interface_ip_pim_sm,
4275 interface_ip_pim_sm_cmd,
4276 "ip pim sm",
12e41d03
DL
4277 IP_STR
4278 PIM_STR
8371bd60 4279 IFACE_PIM_SM_STR)
12e41d03 4280{
cdc2d765 4281 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
4282 if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) {
4283 vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
4284 return CMD_WARNING;
4285 }
4286
c992c9a0
DS
4287 pim_if_create_pimreg();
4288
981d6c7a
DS
4289 return CMD_SUCCESS;
4290}
4291
4292static int
4293pim_cmd_interface_delete (struct interface *ifp)
4294{
4295 struct pim_interface *pim_ifp = ifp->info;
4296
12e41d03 4297 if (!pim_ifp)
981d6c7a 4298 return 1;
12e41d03
DL
4299
4300 PIM_IF_DONT_PIM(pim_ifp->options);
4301
4302 pim_if_membership_clear(ifp);
4303
12e41d03
DL
4304 /*
4305 pim_sock_delete() removes all neighbors from
4306 pim_ifp->pim_neighbor_list.
4307 */
4308 pim_sock_delete(ifp, "pim unconfigured on interface");
4309
4310 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
c83778f7 4311 pim_if_addr_del_all(ifp);
12e41d03
DL
4312 pim_if_delete(ifp);
4313 }
4314
981d6c7a
DS
4315 return 1;
4316}
4317
4318DEFUN (interface_no_ip_pim_ssm,
4319 interface_no_ip_pim_ssm_cmd,
4320 "no ip pim ssm",
4321 NO_STR
4322 IP_STR
4323 PIM_STR
4324 IFACE_PIM_STR)
4325{
cdc2d765 4326 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
4327 if (!pim_cmd_interface_delete(ifp)) {
4328 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
4329 return CMD_WARNING;
4330 }
4331
4332 return CMD_SUCCESS;
4333}
4334
4335DEFUN (interface_no_ip_pim_sm,
4336 interface_no_ip_pim_sm_cmd,
4337 "no ip pim sm",
4338 NO_STR
4339 IP_STR
4340 PIM_STR
8371bd60 4341 IFACE_PIM_SM_STR)
981d6c7a 4342{
cdc2d765 4343 VTY_DECLVAR_CONTEXT(interface, ifp);
981d6c7a
DS
4344 if (!pim_cmd_interface_delete(ifp)) {
4345 vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE);
4346 return CMD_WARNING;
4347 }
4348
12e41d03
DL
4349 return CMD_SUCCESS;
4350}
4351
6250610a
JAG
4352DEFUN (interface_ip_mroute,
4353 interface_ip_mroute_cmd,
4354 "ip mroute INTERFACE A.B.C.D",
4355 IP_STR
4356 "Add multicast route\n"
4357 "Outgoing interface name\n"
4358 "Group address\n")
4359{
cdc2d765 4360 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
4361 int idx_interface = 2;
4362 int idx_ipv4 = 3;
6250610a
JAG
4363 struct interface *oif;
4364 const char *oifname;
4365 const char *grp_str;
4366 struct in_addr grp_addr;
4367 struct in_addr src_addr;
4368 int result;
4369
b181fa04 4370 oifname = argv[idx_interface]->arg;
6250610a
JAG
4371 oif = if_lookup_by_name(oifname);
4372 if (!oif) {
4373 vty_out(vty, "No such interface name %s%s",
4374 oifname, VTY_NEWLINE);
4375 return CMD_WARNING;
4376 }
4377
b181fa04 4378 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
4379 result = inet_pton(AF_INET, grp_str, &grp_addr);
4380 if (result <= 0) {
4381 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4382 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4383 return CMD_WARNING;
4384 }
4385
4386 src_addr.s_addr = INADDR_ANY;
4387
4388 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
4389 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
4390 return CMD_WARNING;
4391 }
4392
4393 return CMD_SUCCESS;
4394}
4395
4396DEFUN (interface_ip_mroute_source,
4397 interface_ip_mroute_source_cmd,
4398 "ip mroute INTERFACE A.B.C.D A.B.C.D",
4399 IP_STR
4400 "Add multicast route\n"
4401 "Outgoing interface name\n"
4402 "Group address\n"
4403 "Source address\n")
4404{
cdc2d765 4405 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
4406 int idx_interface = 2;
4407 int idx_ipv4 = 3;
4408 int idx_ipv4_2 = 4;
6250610a
JAG
4409 struct interface *oif;
4410 const char *oifname;
4411 const char *grp_str;
4412 struct in_addr grp_addr;
4413 const char *src_str;
4414 struct in_addr src_addr;
4415 int result;
4416
b181fa04 4417 oifname = argv[idx_interface]->arg;
6250610a
JAG
4418 oif = if_lookup_by_name(oifname);
4419 if (!oif) {
4420 vty_out(vty, "No such interface name %s%s",
4421 oifname, VTY_NEWLINE);
4422 return CMD_WARNING;
4423 }
4424
b181fa04 4425 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
4426 result = inet_pton(AF_INET, grp_str, &grp_addr);
4427 if (result <= 0) {
4428 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4429 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4430 return CMD_WARNING;
4431 }
4432
b181fa04 4433 src_str = argv[idx_ipv4_2]->arg;
6250610a
JAG
4434 result = inet_pton(AF_INET, src_str, &src_addr);
4435 if (result <= 0) {
4436 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4437 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4438 return CMD_WARNING;
4439 }
4440
4441 if (pim_static_add(iif, oif, grp_addr, src_addr)) {
4442 vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
4443 return CMD_WARNING;
4444 }
4445
4446 return CMD_SUCCESS;
4447}
4448
4449DEFUN (interface_no_ip_mroute,
4450 interface_no_ip_mroute_cmd,
4451 "no ip mroute INTERFACE A.B.C.D",
4452 NO_STR
4453 IP_STR
4454 "Add multicast route\n"
4455 "Outgoing interface name\n"
4456 "Group Address\n")
4457{
cdc2d765 4458 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
4459 int idx_interface = 3;
4460 int idx_ipv4 = 4;
6250610a
JAG
4461 struct interface *oif;
4462 const char *oifname;
4463 const char *grp_str;
4464 struct in_addr grp_addr;
4465 struct in_addr src_addr;
4466 int result;
4467
b181fa04 4468 oifname = argv[idx_interface]->arg;
6250610a
JAG
4469 oif = if_lookup_by_name(oifname);
4470 if (!oif) {
4471 vty_out(vty, "No such interface name %s%s",
4472 oifname, VTY_NEWLINE);
4473 return CMD_WARNING;
4474 }
4475
b181fa04 4476 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
4477 result = inet_pton(AF_INET, grp_str, &grp_addr);
4478 if (result <= 0) {
4479 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4480 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4481 return CMD_WARNING;
4482 }
4483
4484 src_addr.s_addr = INADDR_ANY;
4485
4486 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
4487 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
4488 return CMD_WARNING;
4489 }
4490
4491 return CMD_SUCCESS;
4492}
4493
4494DEFUN (interface_no_ip_mroute_source,
4495 interface_no_ip_mroute_source_cmd,
4496 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
4497 NO_STR
4498 IP_STR
4499 "Add multicast route\n"
4500 "Outgoing interface name\n"
4501 "Group Address\n"
4502 "Source Address\n")
4503{
cdc2d765 4504 VTY_DECLVAR_CONTEXT(interface, iif);
b181fa04
DW
4505 int idx_interface = 3;
4506 int idx_ipv4 = 4;
4507 int idx_ipv4_2 = 5;
6250610a
JAG
4508 struct interface *oif;
4509 const char *oifname;
4510 const char *grp_str;
4511 struct in_addr grp_addr;
4512 const char *src_str;
4513 struct in_addr src_addr;
4514 int result;
4515
b181fa04 4516 oifname = argv[idx_interface]->arg;
6250610a
JAG
4517 oif = if_lookup_by_name(oifname);
4518 if (!oif) {
4519 vty_out(vty, "No such interface name %s%s",
4520 oifname, VTY_NEWLINE);
4521 return CMD_WARNING;
4522 }
4523
b181fa04 4524 grp_str = argv[idx_ipv4]->arg;
6250610a
JAG
4525 result = inet_pton(AF_INET, grp_str, &grp_addr);
4526 if (result <= 0) {
4527 vty_out(vty, "Bad group address %s: errno=%d: %s%s",
4528 grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
4529 return CMD_WARNING;
4530 }
4531
b181fa04 4532 src_str = argv[idx_ipv4_2]->arg;
6250610a
JAG
4533 result = inet_pton(AF_INET, src_str, &src_addr);
4534 if (result <= 0) {
4535 vty_out(vty, "Bad source address %s: errno=%d: %s%s",
4536 src_str, errno, safe_strerror(errno), VTY_NEWLINE);
4537 return CMD_WARNING;
4538 }
4539
4540 if (pim_static_del(iif, oif, grp_addr, src_addr)) {
4541 vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
4542 return CMD_WARNING;
4543 }
4544
4545 return CMD_SUCCESS;
4546}
4547
7960fa8f
DS
4548DEFUN (interface_ip_pim_hello,
4549 interface_ip_pim_hello_cmd,
80d3d26b 4550 "ip pim hello (1-180) [(1-180)]",
7960fa8f
DS
4551 IP_STR
4552 PIM_STR
4553 IFACE_PIM_HELLO_STR
80d3d26b
DW
4554 IFACE_PIM_HELLO_TIME_STR
4555 IFACE_PIM_HELLO_HOLD_STR)
7960fa8f 4556{
cdc2d765 4557 VTY_DECLVAR_CONTEXT(interface, ifp);
80d3d26b
DW
4558 int idx_time = 3;
4559 int idx_hold = 4;
7960fa8f
DS
4560 struct pim_interface *pim_ifp;
4561
7960fa8f
DS
4562 pim_ifp = ifp->info;
4563
4564 if (!pim_ifp) {
4565 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
4566 return CMD_WARNING;
4567 }
4568
80d3d26b 4569 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
7960fa8f 4570
80d3d26b
DW
4571 if (argc > idx_hold)
4572 pim_ifp->pim_default_holdtime = strtol(argv[idx_hold]->arg, NULL, 10);
7960fa8f
DS
4573
4574 return CMD_SUCCESS;
4575}
4576
7960fa8f
DS
4577
4578
4579DEFUN (interface_no_ip_pim_hello,
4580 interface_no_ip_pim_hello_cmd,
b181fa04 4581 "no ip pim hello [(1-180) (1-180)]",
7960fa8f
DS
4582 NO_STR
4583 IP_STR
4584 PIM_STR
4585 IFACE_PIM_HELLO_STR
4586 IFACE_PIM_HELLO_TIME_STR
4587 IFACE_PIM_HELLO_HOLD_STR)
4588{
cdc2d765 4589 VTY_DECLVAR_CONTEXT(interface, ifp);
7960fa8f
DS
4590 struct pim_interface *pim_ifp;
4591
7960fa8f
DS
4592 pim_ifp = ifp->info;
4593
4594 if (!pim_ifp) {
4595 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
4596 return CMD_WARNING;
4597 }
4598
4599 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
4600 pim_ifp->pim_default_holdtime = -1;
4601
4602 return CMD_SUCCESS;
4603}
4604
12e41d03
DL
4605DEFUN (debug_igmp,
4606 debug_igmp_cmd,
4607 "debug igmp",
4608 DEBUG_STR
4609 DEBUG_IGMP_STR)
4610{
4611 PIM_DO_DEBUG_IGMP_EVENTS;
4612 PIM_DO_DEBUG_IGMP_PACKETS;
4613 PIM_DO_DEBUG_IGMP_TRACE;
4614 return CMD_SUCCESS;
4615}
4616
4617DEFUN (no_debug_igmp,
4618 no_debug_igmp_cmd,
4619 "no debug igmp",
4620 NO_STR
4621 DEBUG_STR
4622 DEBUG_IGMP_STR)
4623{
4624 PIM_DONT_DEBUG_IGMP_EVENTS;
4625 PIM_DONT_DEBUG_IGMP_PACKETS;
4626 PIM_DONT_DEBUG_IGMP_TRACE;
4627 return CMD_SUCCESS;
4628}
4629
12e41d03
DL
4630
4631DEFUN (debug_igmp_events,
4632 debug_igmp_events_cmd,
4633 "debug igmp events",
4634 DEBUG_STR
4635 DEBUG_IGMP_STR
4636 DEBUG_IGMP_EVENTS_STR)
4637{
4638 PIM_DO_DEBUG_IGMP_EVENTS;
4639 return CMD_SUCCESS;
4640}
4641
4642DEFUN (no_debug_igmp_events,
4643 no_debug_igmp_events_cmd,
4644 "no debug igmp events",
4645 NO_STR
4646 DEBUG_STR
4647 DEBUG_IGMP_STR
4648 DEBUG_IGMP_EVENTS_STR)
4649{
4650 PIM_DONT_DEBUG_IGMP_EVENTS;
4651 return CMD_SUCCESS;
4652}
4653
12e41d03
DL
4654
4655DEFUN (debug_igmp_packets,
4656 debug_igmp_packets_cmd,
4657 "debug igmp packets",
4658 DEBUG_STR
4659 DEBUG_IGMP_STR
4660 DEBUG_IGMP_PACKETS_STR)
4661{
4662 PIM_DO_DEBUG_IGMP_PACKETS;
4663 return CMD_SUCCESS;
4664}
4665
4666DEFUN (no_debug_igmp_packets,
4667 no_debug_igmp_packets_cmd,
4668 "no debug igmp packets",
4669 NO_STR
4670 DEBUG_STR
4671 DEBUG_IGMP_STR
4672 DEBUG_IGMP_PACKETS_STR)
4673{
4674 PIM_DONT_DEBUG_IGMP_PACKETS;
4675 return CMD_SUCCESS;
4676}
4677
12e41d03
DL
4678
4679DEFUN (debug_igmp_trace,
4680 debug_igmp_trace_cmd,
4681 "debug igmp trace",
4682 DEBUG_STR
4683 DEBUG_IGMP_STR
4684 DEBUG_IGMP_TRACE_STR)
4685{
4686 PIM_DO_DEBUG_IGMP_TRACE;
4687 return CMD_SUCCESS;
4688}
4689
4690DEFUN (no_debug_igmp_trace,
4691 no_debug_igmp_trace_cmd,
4692 "no debug igmp trace",
4693 NO_STR
4694 DEBUG_STR
4695 DEBUG_IGMP_STR
4696 DEBUG_IGMP_TRACE_STR)
4697{
4698 PIM_DONT_DEBUG_IGMP_TRACE;
4699 return CMD_SUCCESS;
4700}
4701
12e41d03
DL
4702
4703DEFUN (debug_mroute,
4704 debug_mroute_cmd,
4705 "debug mroute",
4706 DEBUG_STR
4707 DEBUG_MROUTE_STR)
4708{
4709 PIM_DO_DEBUG_MROUTE;
4710 return CMD_SUCCESS;
4711}
4712
6c7197b1
DS
4713DEFUN (debug_mroute_detail,
4714 debug_mroute_detail_cmd,
4715 "debug mroute detail",
4716 DEBUG_STR
4717 DEBUG_MROUTE_STR
4718 "detailed\n")
4719{
4720 PIM_DO_DEBUG_MROUTE_DETAIL;
4721 return CMD_SUCCESS;
4722}
4723
12e41d03
DL
4724DEFUN (no_debug_mroute,
4725 no_debug_mroute_cmd,
4726 "no debug mroute",
4727 NO_STR
4728 DEBUG_STR
4729 DEBUG_MROUTE_STR)
4730{
4731 PIM_DONT_DEBUG_MROUTE;
4732 return CMD_SUCCESS;
4733}
4734
6c7197b1
DS
4735DEFUN (no_debug_mroute_detail,
4736 no_debug_mroute_detail_cmd,
4737 "no debug mroute detail",
4738 NO_STR
4739 DEBUG_STR
4740 DEBUG_MROUTE_STR
4741 "detailed\n")
4742{
4743 PIM_DONT_DEBUG_MROUTE_DETAIL;
4744 return CMD_SUCCESS;
4745}
12e41d03 4746
6250610a
JAG
4747DEFUN (debug_static,
4748 debug_static_cmd,
4749 "debug static",
4750 DEBUG_STR
4751 DEBUG_STATIC_STR)
4752{
4753 PIM_DO_DEBUG_STATIC;
4754 return CMD_SUCCESS;
4755}
4756
4757DEFUN (no_debug_static,
4758 no_debug_static_cmd,
4759 "no debug static",
4760 NO_STR
4761 DEBUG_STR
4762 DEBUG_STATIC_STR)
4763{
4764 PIM_DONT_DEBUG_STATIC;
4765 return CMD_SUCCESS;
4766}
4767
6250610a 4768
12e41d03
DL
4769DEFUN (debug_pim,
4770 debug_pim_cmd,
4771 "debug pim",
4772 DEBUG_STR
4773 DEBUG_PIM_STR)
4774{
4775 PIM_DO_DEBUG_PIM_EVENTS;
4776 PIM_DO_DEBUG_PIM_PACKETS;
4777 PIM_DO_DEBUG_PIM_TRACE;
886d1e80 4778 PIM_DO_DEBUG_MSDP_EVENTS;
4779 PIM_DO_DEBUG_MSDP_PACKETS;
12e41d03
DL
4780 return CMD_SUCCESS;
4781}
4782
4783DEFUN (no_debug_pim,
4784 no_debug_pim_cmd,
4785 "no debug pim",
4786 NO_STR
4787 DEBUG_STR
4788 DEBUG_PIM_STR)
4789{
4790 PIM_DONT_DEBUG_PIM_EVENTS;
4791 PIM_DONT_DEBUG_PIM_PACKETS;
4792 PIM_DONT_DEBUG_PIM_TRACE;
886d1e80 4793 PIM_DONT_DEBUG_MSDP_EVENTS;
4794 PIM_DONT_DEBUG_MSDP_PACKETS;
12e41d03
DL
4795
4796 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
4797 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4798
4799 return CMD_SUCCESS;
4800}
4801
12e41d03
DL
4802
4803DEFUN (debug_pim_events,
4804 debug_pim_events_cmd,
4805 "debug pim events",
4806 DEBUG_STR
4807 DEBUG_PIM_STR
4808 DEBUG_PIM_EVENTS_STR)
4809{
4810 PIM_DO_DEBUG_PIM_EVENTS;
4811 return CMD_SUCCESS;
4812}
4813
4814DEFUN (no_debug_pim_events,
4815 no_debug_pim_events_cmd,
4816 "no debug pim events",
4817 NO_STR
4818 DEBUG_STR
4819 DEBUG_PIM_STR
4820 DEBUG_PIM_EVENTS_STR)
4821{
4822 PIM_DONT_DEBUG_PIM_EVENTS;
4823 return CMD_SUCCESS;
4824}
4825
12e41d03
DL
4826
4827DEFUN (debug_pim_packets,
4828 debug_pim_packets_cmd,
4829 "debug pim packets",
4830 DEBUG_STR
4831 DEBUG_PIM_STR
4832 DEBUG_PIM_PACKETS_STR)
4833{
4834 PIM_DO_DEBUG_PIM_PACKETS;
4835 vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
4836 return CMD_SUCCESS;
4837}
4838
4839DEFUN (debug_pim_packets_filter,
4840 debug_pim_packets_filter_cmd,
9add3b88 4841 "debug pim packets <hello|joins|register>",
12e41d03
DL
4842 DEBUG_STR
4843 DEBUG_PIM_STR
4844 DEBUG_PIM_PACKETS_STR
4845 DEBUG_PIM_HELLO_PACKETS_STR
9add3b88
DS
4846 DEBUG_PIM_J_P_PACKETS_STR
4847 DEBUG_PIM_PIM_REG_PACKETS_STR)
12e41d03 4848{
b181fa04 4849 int idx_hello_join = 3;
9add3b88 4850 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
12e41d03
DL
4851 {
4852 PIM_DO_DEBUG_PIM_HELLO;
9add3b88 4853 vty_out (vty, "PIM Hello debugging is on%s", VTY_NEWLINE);
12e41d03 4854 }
9add3b88 4855 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
12e41d03
DL
4856 {
4857 PIM_DO_DEBUG_PIM_J_P;
9add3b88
DS
4858 vty_out (vty, "PIM Join/Prune debugging is on%s", VTY_NEWLINE);
4859 }
4860 else if (strncmp(argv[idx_hello_join]->arg,"r",1) == 0)
4861 {
4862 PIM_DO_DEBUG_PIM_REG;
4863 vty_out (vty, "PIM Register debugging is on%s", VTY_NEWLINE);
12e41d03
DL
4864 }
4865 return CMD_SUCCESS;
4866}
4867
4868DEFUN (no_debug_pim_packets,
4869 no_debug_pim_packets_cmd,
4870 "no debug pim packets",
4871 NO_STR
4872 DEBUG_STR
4873 DEBUG_PIM_STR
4874 DEBUG_PIM_PACKETS_STR
4875 DEBUG_PIM_HELLO_PACKETS_STR
4876 DEBUG_PIM_J_P_PACKETS_STR)
4877{
4878 PIM_DONT_DEBUG_PIM_PACKETS;
4879 vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
4880 return CMD_SUCCESS;
4881}
4882
4883DEFUN (no_debug_pim_packets_filter,
4884 no_debug_pim_packets_filter_cmd,
9add3b88 4885 "no debug pim packets <hello|joins|register>",
12e41d03
DL
4886 NO_STR
4887 DEBUG_STR
4888 DEBUG_PIM_STR
4889 DEBUG_PIM_PACKETS_STR
4890 DEBUG_PIM_HELLO_PACKETS_STR
4891 DEBUG_PIM_J_P_PACKETS_STR)
4892{
b181fa04 4893 int idx_hello_join = 4;
9add3b88 4894 if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0)
12e41d03
DL
4895 {
4896 PIM_DONT_DEBUG_PIM_HELLO;
4897 vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
4898 }
9add3b88 4899 else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
12e41d03
DL
4900 {
4901 PIM_DONT_DEBUG_PIM_J_P;
4902 vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
4903 }
9add3b88
DS
4904 else if (strncmp (argv[idx_hello_join]->arg, "r", 1) == 0)
4905 {
4906 PIM_DONT_DEBUG_PIM_REG;
4907 vty_out (vty, "PIM Register debugging is off%s", VTY_NEWLINE);
4908 }
4909 return CMD_SUCCESS;
12e41d03
DL
4910}
4911
12e41d03
DL
4912
4913DEFUN (debug_pim_packetdump_send,
4914 debug_pim_packetdump_send_cmd,
4915 "debug pim packet-dump send",
4916 DEBUG_STR
4917 DEBUG_PIM_STR
4918 DEBUG_PIM_PACKETDUMP_STR
4919 DEBUG_PIM_PACKETDUMP_SEND_STR)
4920{
4921 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
4922 return CMD_SUCCESS;
4923}
4924
4925DEFUN (no_debug_pim_packetdump_send,
4926 no_debug_pim_packetdump_send_cmd,
4927 "no debug pim packet-dump send",
4928 NO_STR
4929 DEBUG_STR
4930 DEBUG_PIM_STR
4931 DEBUG_PIM_PACKETDUMP_STR
4932 DEBUG_PIM_PACKETDUMP_SEND_STR)
4933{
4934 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
4935 return CMD_SUCCESS;
4936}
4937
12e41d03
DL
4938
4939DEFUN (debug_pim_packetdump_recv,
4940 debug_pim_packetdump_recv_cmd,
4941 "debug pim packet-dump receive",
4942 DEBUG_STR
4943 DEBUG_PIM_STR
4944 DEBUG_PIM_PACKETDUMP_STR
4945 DEBUG_PIM_PACKETDUMP_RECV_STR)
4946{
4947 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
4948 return CMD_SUCCESS;
4949}
4950
4951DEFUN (no_debug_pim_packetdump_recv,
4952 no_debug_pim_packetdump_recv_cmd,
4953 "no debug pim packet-dump receive",
4954 NO_STR
4955 DEBUG_STR
4956 DEBUG_PIM_STR
4957 DEBUG_PIM_PACKETDUMP_STR
4958 DEBUG_PIM_PACKETDUMP_RECV_STR)
4959{
4960 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4961 return CMD_SUCCESS;
4962}
4963
12e41d03
DL
4964
4965DEFUN (debug_pim_trace,
4966 debug_pim_trace_cmd,
4967 "debug pim trace",
4968 DEBUG_STR
4969 DEBUG_PIM_STR
4970 DEBUG_PIM_TRACE_STR)
4971{
4972 PIM_DO_DEBUG_PIM_TRACE;
4973 return CMD_SUCCESS;
4974}
4975
4976DEFUN (no_debug_pim_trace,
4977 no_debug_pim_trace_cmd,
4978 "no debug pim trace",
4979 NO_STR
4980 DEBUG_STR
4981 DEBUG_PIM_STR
4982 DEBUG_PIM_TRACE_STR)
4983{
4984 PIM_DONT_DEBUG_PIM_TRACE;
4985 return CMD_SUCCESS;
4986}
4987
12e41d03
DL
4988
4989DEFUN (debug_ssmpingd,
4990 debug_ssmpingd_cmd,
4991 "debug ssmpingd",
4992 DEBUG_STR
4993 DEBUG_PIM_STR
4994 DEBUG_SSMPINGD_STR)
4995{
4996 PIM_DO_DEBUG_SSMPINGD;
4997 return CMD_SUCCESS;
4998}
4999
5000DEFUN (no_debug_ssmpingd,
5001 no_debug_ssmpingd_cmd,
5002 "no debug ssmpingd",
5003 NO_STR
5004 DEBUG_STR
5005 DEBUG_PIM_STR
5006 DEBUG_SSMPINGD_STR)
5007{
5008 PIM_DONT_DEBUG_SSMPINGD;
5009 return CMD_SUCCESS;
5010}
5011
12e41d03
DL
5012
5013DEFUN (debug_pim_zebra,
5014 debug_pim_zebra_cmd,
5015 "debug pim zebra",
5016 DEBUG_STR
5017 DEBUG_PIM_STR
5018 DEBUG_PIM_ZEBRA_STR)
5019{
5020 PIM_DO_DEBUG_ZEBRA;
5021 return CMD_SUCCESS;
5022}
5023
5024DEFUN (no_debug_pim_zebra,
5025 no_debug_pim_zebra_cmd,
5026 "no debug pim zebra",
5027 NO_STR
5028 DEBUG_STR
5029 DEBUG_PIM_STR
5030 DEBUG_PIM_ZEBRA_STR)
5031{
5032 PIM_DONT_DEBUG_ZEBRA;
5033 return CMD_SUCCESS;
5034}
5035
12e41d03 5036
2a333e0f 5037DEFUN (debug_msdp,
5038 debug_msdp_cmd,
5039 "debug msdp",
5040 DEBUG_STR
5041 DEBUG_MSDP_STR)
5042{
5043 PIM_DO_DEBUG_MSDP_EVENTS;
5044 PIM_DO_DEBUG_MSDP_PACKETS;
5045 return CMD_SUCCESS;
5046}
5047
5048DEFUN (no_debug_msdp,
5049 no_debug_msdp_cmd,
5050 "no debug msdp",
5051 NO_STR
5052 DEBUG_STR
5053 DEBUG_MSDP_STR)
5054{
5055 PIM_DONT_DEBUG_MSDP_EVENTS;
5056 PIM_DONT_DEBUG_MSDP_PACKETS;
5057 return CMD_SUCCESS;
5058}
5059
5060ALIAS (no_debug_msdp,
5061 undebug_msdp_cmd,
5062 "undebug msdp",
5063 UNDEBUG_STR
5064 DEBUG_MSDP_STR)
5065
5066DEFUN (debug_msdp_events,
5067 debug_msdp_events_cmd,
5068 "debug msdp events",
5069 DEBUG_STR
5070 DEBUG_MSDP_STR
5071 DEBUG_MSDP_EVENTS_STR)
5072{
5073 PIM_DO_DEBUG_MSDP_EVENTS;
5074 return CMD_SUCCESS;
5075}
5076
5077DEFUN (no_debug_msdp_events,
5078 no_debug_msdp_events_cmd,
5079 "no debug msdp events",
5080 NO_STR
5081 DEBUG_STR
5082 DEBUG_MSDP_STR
5083 DEBUG_MSDP_EVENTS_STR)
5084{
5085 PIM_DONT_DEBUG_MSDP_EVENTS;
5086 return CMD_SUCCESS;
5087}
5088
5089ALIAS (no_debug_msdp_events,
5090 undebug_msdp_events_cmd,
5091 "undebug msdp events",
5092 UNDEBUG_STR
5093 DEBUG_MSDP_STR
5094 DEBUG_MSDP_EVENTS_STR)
5095
5096DEFUN (debug_msdp_packets,
5097 debug_msdp_packets_cmd,
5098 "debug msdp packets",
5099 DEBUG_STR
5100 DEBUG_MSDP_STR
5101 DEBUG_MSDP_PACKETS_STR)
5102{
5103 PIM_DO_DEBUG_MSDP_PACKETS;
5104 return CMD_SUCCESS;
5105}
5106
5107DEFUN (no_debug_msdp_packets,
5108 no_debug_msdp_packets_cmd,
5109 "no debug msdp packets",
5110 NO_STR
5111 DEBUG_STR
5112 DEBUG_MSDP_STR
5113 DEBUG_MSDP_PACKETS_STR)
5114{
5115 PIM_DONT_DEBUG_MSDP_PACKETS;
5116 return CMD_SUCCESS;
5117}
5118
5119ALIAS (no_debug_msdp_packets,
5120 undebug_msdp_packets_cmd,
5121 "undebug msdp packets",
5122 UNDEBUG_STR
5123 DEBUG_MSDP_STR
5124 DEBUG_MSDP_PACKETS_STR)
5125
7a1d58ce
DS
5126DEFUN (show_debugging_pim,
5127 show_debugging_pim_cmd,
5128 "show debugging pim",
12e41d03 5129 SHOW_STR
7a1d58ce
DS
5130 DEBUG_STR
5131 PIM_STR)
12e41d03
DL
5132{
5133 pim_debug_config_write(vty);
5134 return CMD_SUCCESS;
5135}
5136
4763cd0e 5137static int
5138interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
5139{
5140 int result;
5141 struct in_addr source_addr;
5142 VTY_DECLVAR_CONTEXT(interface, ifp);
5143
5144 result = inet_pton(AF_INET, source, &source_addr);
5145 if (result <= 0) {
5146 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
5147 source, errno, safe_strerror(errno), VTY_NEWLINE);
5148 return CMD_WARNING;
5149 }
5150
5151 result = pim_update_source_set(ifp, source_addr);
5152 switch (result) {
5153 case PIM_SUCCESS:
5154 break;
7cdb24da 5155 case PIM_IFACE_NOT_FOUND:
5156 vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
5157 break;
4763cd0e 5158 case PIM_UPDATE_SOURCE_DUP:
5159 vty_out(vty, "%% Source already set to %s%s", source, VTY_NEWLINE);
5160 break;
5161 default:
5162 vty_out(vty, "%% Source set failed%s", VTY_NEWLINE);
5163 }
5164
5165 return result?CMD_WARNING:CMD_SUCCESS;
5166}
5167
5168DEFUN (interface_pim_use_source,
5169 interface_pim_use_source_cmd,
5170 "ip pim use-source A.B.C.D",
5171 IP_STR
5172 "pim multicast routing\n"
5173 "Configure primary IP address\n"
5174 "source ip address\n")
5175{
5176 return interface_pim_use_src_cmd_worker (vty, argv[3]->arg);
5177}
5178
5179DEFUN (interface_no_pim_use_source,
5180 interface_no_pim_use_source_cmd,
5181 "no ip pim use-source",
5182 NO_STR
5183 IP_STR
5184 "pim multicast routing\n"
5185 "Delete source IP address\n")
5186{
5187 return interface_pim_use_src_cmd_worker (vty, "0.0.0.0");
5188}
5189
2a333e0f 5190static int
5191ip_msdp_peer_cmd_worker (struct vty *vty, const char *peer, const char *local)
5192{
5193 enum pim_msdp_err result;
5194 struct in_addr peer_addr;
5195 struct in_addr local_addr;
5196
5197 result = inet_pton(AF_INET, peer, &peer_addr);
5198 if (result <= 0) {
5199 vty_out(vty, "%% Bad peer address %s: errno=%d: %s%s",
5200 peer, errno, safe_strerror(errno), VTY_NEWLINE);
5201 return CMD_WARNING;
5202 }
5203
5204 result = inet_pton(AF_INET, local, &local_addr);
5205 if (result <= 0) {
5206 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
5207 local, errno, safe_strerror(errno), VTY_NEWLINE);
5208 return CMD_WARNING;
5209 }
5210
977d71cc 5211 result = pim_msdp_peer_add(peer_addr, local_addr, "default", NULL/* mp_p */);
2a333e0f 5212 switch (result) {
5213 case PIM_MSDP_ERR_NONE:
5214 break;
5215 case PIM_MSDP_ERR_OOM:
5216 vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
5217 break;
5218 case PIM_MSDP_ERR_PEER_EXISTS:
5219 vty_out(vty, "%% Peer exists%s", VTY_NEWLINE);
5220 break;
5221 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
5222 vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
5223 break;
5224 default:
5225 vty_out(vty, "%% peer add failed%s", VTY_NEWLINE);
5226 }
5227
5228 return result?CMD_WARNING:CMD_SUCCESS;
5229}
5230
977d71cc 5231DEFUN_HIDDEN (ip_msdp_peer,
2a333e0f 5232 ip_msdp_peer_cmd,
5233 "ip msdp peer A.B.C.D source A.B.C.D",
5234 IP_STR
5235 CFG_MSDP_STR
5236 "Configure MSDP peer\n"
5237 "peer ip address\n"
5238 "Source address for TCP connection\n"
5239 "local ip address\n")
5240{
5241 return ip_msdp_peer_cmd_worker (vty, argv[3]->arg, argv[5]->arg);
5242}
5243
5244static int
5245ip_no_msdp_peer_cmd_worker (struct vty *vty, const char *peer)
5246{
5247 enum pim_msdp_err result;
5248 struct in_addr peer_addr;
5249
5250 result = inet_pton(AF_INET, peer, &peer_addr);
5251 if (result <= 0) {
5252 vty_out(vty, "%% Bad peer address %s: errno=%d: %s%s",
5253 peer, errno, safe_strerror(errno), VTY_NEWLINE);
5254 return CMD_WARNING;
5255 }
5256
5257 result = pim_msdp_peer_del(peer_addr);
5258 switch (result) {
5259 case PIM_MSDP_ERR_NONE:
5260 break;
5261 case PIM_MSDP_ERR_NO_PEER:
5262 vty_out(vty, "%% Peer does not exist%s", VTY_NEWLINE);
5263 break;
5264 default:
5265 vty_out(vty, "%% peer del failed%s", VTY_NEWLINE);
5266 }
5267
5268 return result?CMD_WARNING:CMD_SUCCESS;
5269}
5270
977d71cc 5271DEFUN_HIDDEN (no_ip_msdp_peer,
2a333e0f 5272 no_ip_msdp_peer_cmd,
5273 "no ip msdp peer A.B.C.D",
977d71cc 5274 NO_STR
2a333e0f 5275 IP_STR
5276 CFG_MSDP_STR
5277 "Delete MSDP peer\n"
5278 "peer ip address\n")
5279{
5280 return ip_no_msdp_peer_cmd_worker (vty, argv[4]->arg);
5281}
5282
977d71cc 5283static int
5284ip_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
5285{
5286 enum pim_msdp_err result;
5287 struct in_addr mbr_ip;
5288
5289 result = inet_pton(AF_INET, mbr, &mbr_ip);
5290 if (result <= 0) {
5291 vty_out(vty, "%% Bad member address %s: errno=%d: %s%s",
5292 mbr, errno, safe_strerror(errno), VTY_NEWLINE);
5293 return CMD_WARNING;
5294 }
5295
5296 result = pim_msdp_mg_mbr_add(mg, mbr_ip);
5297 switch (result) {
5298 case PIM_MSDP_ERR_NONE:
5299 break;
5300 case PIM_MSDP_ERR_OOM:
5301 vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
5302 break;
5303 case PIM_MSDP_ERR_MG_MBR_EXISTS:
5304 vty_out(vty, "%% mesh-group member exists%s", VTY_NEWLINE);
5305 break;
5306 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
5307 vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
5308 break;
5309 default:
5310 vty_out(vty, "%% member add failed%s", VTY_NEWLINE);
5311 }
5312
5313 return result?CMD_WARNING:CMD_SUCCESS;
5314}
5315
5316DEFUN (ip_msdp_mesh_group_member,
5317 ip_msdp_mesh_group_member_cmd,
5318 "ip msdp mesh-group WORD member A.B.C.D",
5319 IP_STR
5320 CFG_MSDP_STR
5321 "Configure MSDP mesh-group\n"
5322 "mesh group name\n"
5323 "mesh group member\n"
5324 "peer ip address\n")
5325{
5326 return ip_msdp_mesh_group_member_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
5327}
5328
5329static int
5330ip_no_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
5331{
5332 enum pim_msdp_err result;
5333 struct in_addr mbr_ip;
5334
5335 result = inet_pton(AF_INET, mbr, &mbr_ip);
5336 if (result <= 0) {
5337 vty_out(vty, "%% Bad member address %s: errno=%d: %s%s",
5338 mbr, errno, safe_strerror(errno), VTY_NEWLINE);
5339 return CMD_WARNING;
5340 }
5341
5342 result = pim_msdp_mg_mbr_del(mg, mbr_ip);
5343 switch (result) {
5344 case PIM_MSDP_ERR_NONE:
5345 break;
5346 case PIM_MSDP_ERR_NO_MG:
5347 vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
5348 break;
5349 case PIM_MSDP_ERR_NO_MG_MBR:
5350 vty_out(vty, "%% mesh-group member does not exist%s", VTY_NEWLINE);
5351 break;
5352 default:
5353 vty_out(vty, "%% mesh-group member del failed%s", VTY_NEWLINE);
5354 }
5355
5356 return result?CMD_WARNING:CMD_SUCCESS;
5357}
5358DEFUN (no_ip_msdp_mesh_group_member,
5359 no_ip_msdp_mesh_group_member_cmd,
5360 "no ip msdp mesh-group WORD member A.B.C.D",
5361 NO_STR
5362 IP_STR
5363 CFG_MSDP_STR
5364 "Delete MSDP mesh-group member\n"
5365 "mesh group name\n"
5366 "mesh group member\n"
5367 "peer ip address\n")
5368{
5369 return ip_no_msdp_mesh_group_member_cmd_worker(vty, argv[4]->arg, argv[6]->arg);
5370}
5371
5372static int
5373ip_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg, const char *src)
5374{
5375 enum pim_msdp_err result;
5376 struct in_addr src_ip;
5377
5378 result = inet_pton(AF_INET, src, &src_ip);
5379 if (result <= 0) {
5380 vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
5381 src, errno, safe_strerror(errno), VTY_NEWLINE);
5382 return CMD_WARNING;
5383 }
5384
5385 result = pim_msdp_mg_src_add(mg, src_ip);
5386 switch (result) {
5387 case PIM_MSDP_ERR_NONE:
5388 break;
5389 case PIM_MSDP_ERR_OOM:
5390 vty_out(vty, "%% Out of memory%s", VTY_NEWLINE);
5391 break;
5392 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
5393 vty_out(vty, "%% Only one mesh-group allowed currently%s", VTY_NEWLINE);
5394 break;
5395 default:
5396 vty_out(vty, "%% source add failed%s", VTY_NEWLINE);
5397 }
5398
5399 return result?CMD_WARNING:CMD_SUCCESS;
5400}
5401
5402
5403DEFUN (ip_msdp_mesh_group_source,
5404 ip_msdp_mesh_group_source_cmd,
5405 "ip msdp mesh-group WORD source A.B.C.D",
5406 IP_STR
5407 CFG_MSDP_STR
5408 "Configure MSDP mesh-group\n"
5409 "mesh group name\n"
5410 "mesh group local address\n"
5411 "source ip address for the TCP connection\n")
5412{
5413 return ip_msdp_mesh_group_source_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
5414}
5415
5416static int
5417ip_no_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg)
5418{
5419 enum pim_msdp_err result;
5420
5421 result = pim_msdp_mg_src_del(mg);
5422 switch (result) {
5423 case PIM_MSDP_ERR_NONE:
5424 break;
5425 case PIM_MSDP_ERR_NO_MG:
5426 vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
5427 break;
5428 default:
5429 vty_out(vty, "%% mesh-group source del failed%s", VTY_NEWLINE);
5430 }
5431
5432 return result?CMD_WARNING:CMD_SUCCESS;
5433}
5434
977d71cc 5435static int
5436ip_no_msdp_mesh_group_cmd_worker(struct vty *vty, const char *mg)
5437{
5438 enum pim_msdp_err result;
5439
5440 result = pim_msdp_mg_del(mg);
5441 switch (result) {
5442 case PIM_MSDP_ERR_NONE:
5443 break;
5444 case PIM_MSDP_ERR_NO_MG:
5445 vty_out(vty, "%% mesh-group does not exist%s", VTY_NEWLINE);
5446 break;
5447 default:
5448 vty_out(vty, "%% mesh-group source del failed%s", VTY_NEWLINE);
5449 }
5450
58344b65 5451 return result ? CMD_WARNING : CMD_SUCCESS;
977d71cc 5452}
5453
58344b65
DS
5454DEFUN (no_ip_msdp_mesh_group_source,
5455 no_ip_msdp_mesh_group_source_cmd,
5456 "no ip msdp mesh-group WORD source [A.B.C.D]",
977d71cc 5457 NO_STR
5458 IP_STR
5459 CFG_MSDP_STR
58344b65
DS
5460 "Delete MSDP mesh-group source\n"
5461 "mesh group name\n"
5462 "mesh group local address\n")
977d71cc 5463{
58344b65
DS
5464 if (argv[6]->arg)
5465 return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
5466 else
5467 return ip_no_msdp_mesh_group_source_cmd_worker(vty, argv[4]->arg);
977d71cc 5468}
5469
1bf16443 5470static void
5471print_empty_json_obj(struct vty *vty)
5472{
5473 json_object *json;
5474 json = json_object_new_object();
5475 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5476 json_object_free(json);
5477}
5478
977d71cc 5479static void
5480ip_msdp_show_mesh_group(struct vty *vty, u_char uj)
5481{
5482 struct listnode *mbrnode;
5483 struct pim_msdp_mg_mbr *mbr;
5484 struct pim_msdp_mg *mg = msdp->mg;
5485 char mbr_str[INET_ADDRSTRLEN];
5486 char src_str[INET_ADDRSTRLEN];
5487 char state_str[PIM_MSDP_STATE_STRLEN];
5488 enum pim_msdp_peer_state state;
5489 json_object *json = NULL;
5490 json_object *json_mg_row = NULL;
01cb1466 5491 json_object *json_members = NULL;
977d71cc 5492 json_object *json_row = NULL;
5493
5494 if (!mg) {
1bf16443 5495 if (uj)
5496 print_empty_json_obj(vty);
977d71cc 5497 return;
5498 }
5499
5500 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
5501 if (uj) {
5502 json = json_object_new_object();
5503 /* currently there is only one mesh group but we should still make
5504 * it a dict with mg-name as key */
5505 json_mg_row = json_object_new_object();
5506 json_object_string_add(json_mg_row, "name", mg->mesh_group_name);
5507 json_object_string_add(json_mg_row, "source", src_str);
5508 } else {
5509 vty_out(vty, "Mesh group : %s%s", mg->mesh_group_name, VTY_NEWLINE);
5510 vty_out(vty, " Source : %s%s", src_str, VTY_NEWLINE);
5511 vty_out(vty, " Member State%s", VTY_NEWLINE);
5512 }
5513
5514 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
5515 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
5516 if (mbr->mp) {
5517 state = mbr->mp->state;
5518 } else {
5519 state = PIM_MSDP_DISABLED;
5520 }
5521 pim_msdp_state_dump(state, state_str, sizeof(state_str));
5522 if (uj) {
5523 json_row = json_object_new_object();
5524 json_object_string_add(json_row, "member", mbr_str);
5525 json_object_string_add(json_row, "state", state_str);
01cb1466 5526 if (!json_members) {
5527 json_members = json_object_new_object();
5528 json_object_object_add(json_mg_row, "members", json_members);
5529 }
5530 json_object_object_add(json_members, mbr_str, json_row);
977d71cc 5531 } else {
5532 vty_out(vty, " %-15s %11s%s",
5533 mbr_str, state_str, VTY_NEWLINE);
5534 }
5535 }
5536
5537 if (uj) {
5538 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
5539 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5540 json_object_free(json);
5541 }
5542}
5543
5544DEFUN (show_ip_msdp_mesh_group,
5545 show_ip_msdp_mesh_group_cmd,
5546 "show ip msdp mesh-group [json]",
5547 SHOW_STR
5548 IP_STR
5549 MSDP_STR
5550 "MSDP mesh-group information\n"
5551 "JavaScript Object Notation\n")
5552{
5553 u_char uj = use_json(argc, argv);
5554 ip_msdp_show_mesh_group(vty, uj);
5555
5556 return CMD_SUCCESS;
5557}
5558
2a333e0f 5559static void
5560ip_msdp_show_peers(struct vty *vty, u_char uj)
5561{
5562 struct listnode *mpnode;
5563 struct pim_msdp_peer *mp;
5564 char peer_str[INET_ADDRSTRLEN];
5565 char local_str[INET_ADDRSTRLEN];
5566 char state_str[PIM_MSDP_STATE_STRLEN];
5567 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5568 int64_t now;
977d71cc 5569 json_object *json = NULL;
5570 json_object *json_row = NULL;
5571
2a333e0f 5572
5573 if (uj) {
977d71cc 5574 json = json_object_new_object();
2a333e0f 5575 } else {
886d1e80 5576 vty_out(vty, "Peer Local State Uptime SaCnt%s", VTY_NEWLINE);
977d71cc 5577 }
5578
5579 for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
5580 if (mp->state == PIM_MSDP_ESTABLISHED) {
5581 now = pim_time_monotonic_sec();
5582 pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
5583 } else {
5584 strcpy(timebuf, "-");
5585 }
5586 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5587 pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
5588 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5589 if (uj) {
5590 json_row = json_object_new_object();
5591 json_object_string_add(json_row, "peer", peer_str);
5592 json_object_string_add(json_row, "local", local_str);
977d71cc 5593 json_object_string_add(json_row, "state", state_str);
5594 json_object_string_add(json_row, "upTime", timebuf);
15ad0c71 5595 json_object_int_add(json_row, "saCount", mp->sa_cnt);
977d71cc 5596 json_object_object_add(json, peer_str, json_row);
5597 } else {
886d1e80 5598 vty_out(vty, "%-15s %15s %11s %8s %6d%s",
15ad0c71 5599 peer_str, local_str, state_str,
5600 timebuf, mp->sa_cnt, VTY_NEWLINE);
2a333e0f 5601 }
5602 }
977d71cc 5603
5604 if (uj) {
5605 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5606 json_object_free(json);
5607 }
2a333e0f 5608}
5609
977d71cc 5610static void
5611ip_msdp_show_peers_detail(struct vty *vty, const char *peer, u_char uj)
5612{
5613 struct listnode *mpnode;
5614 struct pim_msdp_peer *mp;
5615 char peer_str[INET_ADDRSTRLEN];
5616 char local_str[INET_ADDRSTRLEN];
5617 char state_str[PIM_MSDP_STATE_STRLEN];
5618 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5619 char katimer[PIM_MSDP_TIMER_STRLEN];
5620 char crtimer[PIM_MSDP_TIMER_STRLEN];
5621 char holdtimer[PIM_MSDP_TIMER_STRLEN];
5622 int64_t now;
5623 json_object *json = NULL;
5624 json_object *json_row = NULL;
5625
5626 if (uj) {
5627 json = json_object_new_object();
5628 }
5629
5630 for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
5631 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5632 if (strcmp(peer, "detail") &&
5633 strcmp(peer, peer_str))
5634 continue;
5635
5636 if (mp->state == PIM_MSDP_ESTABLISHED) {
5637 now = pim_time_monotonic_sec();
5638 pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
5639 } else {
5640 strcpy(timebuf, "-");
5641 }
5642 pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
5643 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5644 pim_time_timer_to_hhmmss(katimer, sizeof(katimer), mp->ka_timer);
5645 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer), mp->cr_timer);
5646 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer), mp->hold_timer);
5647
5648 if (uj) {
5649 json_row = json_object_new_object();
5650 json_object_string_add(json_row, "peer", peer_str);
5651 json_object_string_add(json_row, "local", local_str);
5652 json_object_string_add(json_row, "meshGroupName", mp->mesh_group_name);
5653 json_object_string_add(json_row, "state", state_str);
5654 json_object_string_add(json_row, "upTime", timebuf);
15ad0c71 5655 json_object_string_add(json_row, "keepAliveTimer", katimer);
5656 json_object_string_add(json_row, "connRetryTimer", crtimer);
5657 json_object_string_add(json_row, "holdTimer", holdtimer);
977d71cc 5658 json_object_string_add(json_row, "lastReset", mp->last_reset);
5659 json_object_int_add(json_row, "connAttempts", mp->conn_attempts);
15ad0c71 5660 json_object_int_add(json_row, "establishedChanges", mp->est_flaps);
5661 json_object_int_add(json_row, "saCount", mp->sa_cnt);
977d71cc 5662 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
5663 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
5664 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
5665 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
5666 json_object_object_add(json, peer_str, json_row);
5667 } else {
5668 vty_out(vty, "Peer : %s%s", peer_str, VTY_NEWLINE);
15ad0c71 5669 vty_out(vty, " Local : %s%s", local_str, VTY_NEWLINE);
5670 vty_out(vty, " Mesh Group : %s%s", mp->mesh_group_name, VTY_NEWLINE);
5671 vty_out(vty, " State : %s%s", state_str, VTY_NEWLINE);
5672 vty_out(vty, " Uptime : %s%s", timebuf, VTY_NEWLINE);
5673
5674 vty_out(vty, " Keepalive Timer : %s%s", katimer, VTY_NEWLINE);
5675 vty_out(vty, " Conn Retry Timer : %s%s", crtimer, VTY_NEWLINE);
5676 vty_out(vty, " Hold Timer : %s%s", holdtimer, VTY_NEWLINE);
5677 vty_out(vty, " Last Reset : %s%s", mp->last_reset, VTY_NEWLINE);
5678 vty_out(vty, " Conn Attempts : %d%s", mp->conn_attempts, VTY_NEWLINE);
5679 vty_out(vty, " Established Changes : %d%s", mp->est_flaps, VTY_NEWLINE);
5680 vty_out(vty, " SA Count : %d%s", mp->sa_cnt, VTY_NEWLINE);
5681 vty_out(vty, " Statistics :%s", VTY_NEWLINE);
977d71cc 5682 vty_out(vty, " Sent Rcvd%s", VTY_NEWLINE);
5683 vty_out(vty, " Keepalives : %10d %10d%s",
5684 mp->ka_tx_cnt, mp->ka_rx_cnt, VTY_NEWLINE);
5685 vty_out(vty, " SAs : %10d %10d%s",
5686 mp->sa_tx_cnt, mp->sa_rx_cnt, VTY_NEWLINE);
5687 vty_out(vty, "%s", VTY_NEWLINE);
5688 }
5689 }
5690
5691 if (uj) {
5692 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5693 json_object_free(json);
5694 }
5695}
5696
5697DEFUN (show_ip_msdp_peer_detail,
5698 show_ip_msdp_peer_detail_cmd,
5699 "show ip msdp peer [detail|A.B.C.D] [json]",
2a333e0f 5700 SHOW_STR
5701 IP_STR
5702 MSDP_STR
5703 "MSDP peer information\n"
977d71cc 5704 "Detailed output\n"
5705 "peer ip address\n"
2a333e0f 5706 "JavaScript Object Notation\n")
5707{
5708 u_char uj = use_json(argc, argv);
977d71cc 5709 if (argv[4]->arg)
5710 ip_msdp_show_peers_detail(vty, argv[4]->arg, uj);
5711 else
5712 ip_msdp_show_peers(vty, uj);
2a333e0f 5713
5714 return CMD_SUCCESS;
5715}
5716
3c72d654 5717static void
5718ip_msdp_show_sa(struct vty *vty, u_char uj)
5719{
5720 struct listnode *sanode;
5721 struct pim_msdp_sa *sa;
5722 char src_str[INET_ADDRSTRLEN];
5723 char grp_str[INET_ADDRSTRLEN];
5724 char rp_str[INET_ADDRSTRLEN];
5725 char timebuf[PIM_MSDP_UPTIME_STRLEN];
977d71cc 5726 char spt_str[8];
1bf16443 5727 char local_str[8];
3c72d654 5728 int64_t now;
977d71cc 5729 json_object *json = NULL;
5730 json_object *json_group = NULL;
5731 json_object *json_row = NULL;
3c72d654 5732
5733 if (uj) {
977d71cc 5734 json = json_object_new_object();
3c72d654 5735 } else {
1bf16443 5736 vty_out(vty, "Source Group RP Local SPT Uptime%s", VTY_NEWLINE);
977d71cc 5737 }
5738
5739 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5740 now = pim_time_monotonic_sec();
5741 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
5742 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5743 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
1bf16443 5744 if (sa->flags & PIM_MSDP_SAF_PEER) {
977d71cc 5745 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
977d71cc 5746 if (sa->up) {
5747 strcpy(spt_str, "yes");
3c72d654 5748 } else {
977d71cc 5749 strcpy(spt_str, "no");
5750 }
1bf16443 5751 } else {
5752 strcpy(rp_str, "-");
5753 strcpy(spt_str, "-");
5754 }
5755 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5756 strcpy(local_str, "yes");
5757 } else {
5758 strcpy(local_str, "no");
5759 }
5760 if (uj) {
977d71cc 5761 json_object_object_get_ex(json, grp_str, &json_group);
5762
5763 if (!json_group) {
5764 json_group = json_object_new_object();
5765 json_object_object_add(json, grp_str, json_group);
5766 }
5767
5768 json_row = json_object_new_object();
5769 json_object_string_add(json_row, "source", src_str);
5770 json_object_string_add(json_row, "group", grp_str);
5771 json_object_string_add(json_row, "rp", rp_str);
1bf16443 5772 json_object_string_add(json_row, "local", local_str);
977d71cc 5773 json_object_string_add(json_row, "sptSetup", spt_str);
5774 json_object_string_add(json_row, "upTime", timebuf);
5775 json_object_object_add(json_group, src_str, json_row);
5776 } else {
1bf16443 5777 vty_out(vty, "%-15s %15s %15s %5c %3c %8s%s",
5778 src_str, grp_str, rp_str, local_str[0], spt_str[0], timebuf, VTY_NEWLINE);
3c72d654 5779 }
5780 }
977d71cc 5781
5782
5783 if (uj) {
5784 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5785 json_object_free(json);
5786 }
3c72d654 5787}
5788
977d71cc 5789static void
5790ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, const char *src_str,
5791 const char *grp_str, struct vty *vty,
5792 u_char uj, json_object *json)
5793{
5794 char rp_str[INET_ADDRSTRLEN];
5795 char peer_str[INET_ADDRSTRLEN];
5796 char timebuf[PIM_MSDP_UPTIME_STRLEN];
5797 char spt_str[8];
1bf16443 5798 char local_str[8];
977d71cc 5799 char statetimer[PIM_MSDP_TIMER_STRLEN];
5800 int64_t now;
5801 json_object *json_group = NULL;
5802 json_object *json_row = NULL;
5803
5804 now = pim_time_monotonic_sec();
5805 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
1bf16443 5806 if (sa->flags & PIM_MSDP_SAF_PEER) {
977d71cc 5807 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
5808 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
5809 if (sa->up) {
5810 strcpy(spt_str, "yes");
5811 } else {
5812 strcpy(spt_str, "no");
5813 }
1bf16443 5814 } else {
5815 strcpy(rp_str, "-");
5816 strcpy(peer_str, "-");
5817 strcpy(spt_str, "-");
5818 }
5819 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5820 strcpy(local_str, "yes");
5821 } else {
5822 strcpy(local_str, "no");
977d71cc 5823 }
5824 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer), sa->sa_state_timer);
5825 if (uj) {
5826 json_object_object_get_ex(json, grp_str, &json_group);
5827
5828 if (!json_group) {
5829 json_group = json_object_new_object();
5830 json_object_object_add(json, grp_str, json_group);
5831 }
5832
5833 json_row = json_object_new_object();
5834 json_object_string_add(json_row, "source", src_str);
5835 json_object_string_add(json_row, "group", grp_str);
5836 json_object_string_add(json_row, "rp", rp_str);
1bf16443 5837 json_object_string_add(json_row, "local", local_str);
977d71cc 5838 json_object_string_add(json_row, "sptSetup", spt_str);
5839 json_object_string_add(json_row, "upTime", timebuf);
15ad0c71 5840 json_object_string_add(json_row, "stateTimer", statetimer);
977d71cc 5841 json_object_object_add(json_group, src_str, json_row);
5842 } else {
8bfb8b67 5843 vty_out(vty, "SA : %s%s", sa->sg_str, VTY_NEWLINE);
15ad0c71 5844 vty_out(vty, " RP : %s%s", rp_str, VTY_NEWLINE);
5845 vty_out(vty, " Peer : %s%s", peer_str, VTY_NEWLINE);
5846 vty_out(vty, " Local : %s%s", local_str, VTY_NEWLINE);
5847 vty_out(vty, " SPT Setup : %s%s", spt_str, VTY_NEWLINE);
5848 vty_out(vty, " Uptime : %s%s", timebuf, VTY_NEWLINE);
5849 vty_out(vty, " State Timer : %s%s", statetimer, VTY_NEWLINE);
977d71cc 5850 vty_out(vty, "%s", VTY_NEWLINE);
5851 }
5852}
5853
5854static void
5855ip_msdp_show_sa_detail(struct vty *vty, u_char uj)
5856{
5857 struct listnode *sanode;
5858 struct pim_msdp_sa *sa;
5859 char src_str[INET_ADDRSTRLEN];
5860 char grp_str[INET_ADDRSTRLEN];
5861 json_object *json = NULL;
5862
5863 if (uj) {
5864 json = json_object_new_object();
5865 }
5866
5867 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5868 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5869 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
5870 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
5871 }
5872
5873 if (uj) {
5874 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5875 json_object_free(json);
5876 }
5877}
5878
5879DEFUN (show_ip_msdp_sa_detail,
5880 show_ip_msdp_sa_detail_cmd,
5881 "show ip msdp sa detail [json]",
3c72d654 5882 SHOW_STR
5883 IP_STR
5884 MSDP_STR
5885 "MSDP active-source information\n"
977d71cc 5886 "Detailed output\n"
3c72d654 5887 "JavaScript Object Notation\n")
5888{
5889 u_char uj = use_json(argc, argv);
977d71cc 5890 ip_msdp_show_sa_detail(vty, uj);
5891
5892 return CMD_SUCCESS;
5893}
5894
5895static void
5896ip_msdp_show_sa_addr(struct vty *vty, const char *addr, u_char uj)
5897{
5898 struct listnode *sanode;
5899 struct pim_msdp_sa *sa;
5900 char src_str[INET_ADDRSTRLEN];
5901 char grp_str[INET_ADDRSTRLEN];
5902 json_object *json = NULL;
5903
5904 if (uj) {
5905 json = json_object_new_object();
5906 }
5907
5908 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5909 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5910 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
5911 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
5912 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
5913 }
5914 }
5915
5916 if (uj) {
5917 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5918 json_object_free(json);
5919 }
5920}
5921
5922static void
5923ip_msdp_show_sa_sg(struct vty *vty, const char *src, const char *grp, u_char uj)
5924{
5925 struct listnode *sanode;
5926 struct pim_msdp_sa *sa;
5927 char src_str[INET_ADDRSTRLEN];
5928 char grp_str[INET_ADDRSTRLEN];
5929 json_object *json = NULL;
5930
5931 if (uj) {
5932 json = json_object_new_object();
5933 }
5934
5935 for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
5936 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
5937 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
5938 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
5939 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
5940 }
5941 }
5942
5943 if (uj) {
5944 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
5945 json_object_free(json);
5946 }
5947}
5948
5949DEFUN (show_ip_msdp_sa_sg,
5950 show_ip_msdp_sa_sg_cmd,
5951 "show ip msdp sa [A.B.C.D] [A.B.C.D] [json]",
5952 SHOW_STR
5953 IP_STR
5954 MSDP_STR
5955 "MSDP active-source information\n"
5956 "source or group ip\n"
977d71cc 5957 "JavaScript Object Notation\n")
5958{
5959 u_char uj = use_json(argc, argv);
5960 if (argv[5]->arg)
5961 ip_msdp_show_sa_sg(vty, argv[4]->arg, argv[5]->arg, uj);
5962 else if (argv[4]->arg)
5963 ip_msdp_show_sa_addr(vty, argv[4]->arg, uj);
5964 else
5965 ip_msdp_show_sa(vty, uj);
3c72d654 5966
5967 return CMD_SUCCESS;
5968}
5969
12e41d03
DL
5970void pim_cmd_init()
5971{
5972 install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
5973 install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
0b84f294 5974 if_cmd_init ();
12e41d03 5975
eb7a976a
DS
5976 install_node (&debug_node, pim_debug_config_write);
5977
12e41d03
DL
5978 install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
5979 install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
981d6c7a
DS
5980 install_element (CONFIG_NODE, &ip_pim_rp_cmd);
5981 install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
dfe43e25
DW
5982 install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
5983 install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
191f5695
DS
5984 install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd);
5985 install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
ee1a0718
DS
5986 install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd);
5987 install_element (CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
4304f95c
DS
5988 install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
5989 install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
8e4c9ef3
DS
5990 install_element (CONFIG_NODE, &ip_pim_packets_cmd);
5991 install_element (CONFIG_NODE, &no_ip_pim_packets_cmd);
12e41d03
DL
5992 install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
5993 install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
2a333e0f 5994 install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
5995 install_element (CONFIG_NODE, &no_ip_msdp_peer_cmd);
0b84f294 5996
12e41d03
DL
5997 install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
5998 install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
5999 install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
6000 install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
b05b72e8
DW
6001 install_element (INTERFACE_NODE, &interface_ip_igmp_version_cmd);
6002 install_element (INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
12e41d03
DL
6003 install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
6004 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
6005 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
6006 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
6007 install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
6008 install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
6009 install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
dedccda6 6010 install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
981d6c7a 6011 install_element (INTERFACE_NODE, &interface_ip_pim_sm_cmd);
8371bd60 6012 install_element (INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
dedccda6
DS
6013 install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
6014 install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
7960fa8f 6015 install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
7960fa8f 6016 install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
12e41d03 6017
6250610a
JAG
6018 // Static mroutes NEB
6019 install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
6020 install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
6021 install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
6022 install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
6023
12e41d03
DL
6024 install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
6025 install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
12e41d03
DL
6026 install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
6027 install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
6028 install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
6029 install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
12e41d03
DL
6030 install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
6031 install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
6032 install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
6033 install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
12e41d03
DL
6034 install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
6035 install_element (VIEW_NODE, &show_ip_pim_join_cmd);
12e41d03
DL
6036 install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
6037 install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
6038 install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
6039 install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
31a21c9c 6040 install_element (VIEW_NODE, &show_ip_pim_state_cmd);
12e41d03
DL
6041 install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
6042 install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
6043 install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
00d07c6f 6044 install_element (VIEW_NODE, &show_ip_pim_rp_cmd);
12e41d03
DL
6045 install_element (VIEW_NODE, &show_ip_multicast_cmd);
6046 install_element (VIEW_NODE, &show_ip_mroute_cmd);
6047 install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
6048 install_element (VIEW_NODE, &show_ip_rib_cmd);
6049 install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
7a1d58ce 6050 install_element (VIEW_NODE, &show_debugging_pim_cmd);
12e41d03
DL
6051
6052 install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
6053 install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
6054 install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
6055 install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
6056 install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
6057
12e41d03
DL
6058 install_element (ENABLE_NODE, &debug_igmp_cmd);
6059 install_element (ENABLE_NODE, &no_debug_igmp_cmd);
12e41d03
DL
6060 install_element (ENABLE_NODE, &debug_igmp_events_cmd);
6061 install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
12e41d03
DL
6062 install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
6063 install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
12e41d03
DL
6064 install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
6065 install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
12e41d03 6066 install_element (ENABLE_NODE, &debug_mroute_cmd);
6c7197b1 6067 install_element (ENABLE_NODE, &debug_mroute_detail_cmd);
12e41d03 6068 install_element (ENABLE_NODE, &no_debug_mroute_cmd);
6c7197b1 6069 install_element (ENABLE_NODE, &no_debug_mroute_detail_cmd);
6250610a
JAG
6070 install_element (ENABLE_NODE, &debug_static_cmd);
6071 install_element (ENABLE_NODE, &no_debug_static_cmd);
12e41d03
DL
6072 install_element (ENABLE_NODE, &debug_pim_cmd);
6073 install_element (ENABLE_NODE, &no_debug_pim_cmd);
12e41d03
DL
6074 install_element (ENABLE_NODE, &debug_pim_events_cmd);
6075 install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
12e41d03
DL
6076 install_element (ENABLE_NODE, &debug_pim_packets_cmd);
6077 install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
6078 install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
6079 install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
12e41d03
DL
6080 install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
6081 install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
12e41d03
DL
6082 install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
6083 install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
12e41d03
DL
6084 install_element (ENABLE_NODE, &debug_pim_trace_cmd);
6085 install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
12e41d03
DL
6086 install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
6087 install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
12e41d03
DL
6088 install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
6089 install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
2a333e0f 6090 install_element (ENABLE_NODE, &debug_msdp_cmd);
6091 install_element (ENABLE_NODE, &no_debug_msdp_cmd);
6092 install_element (ENABLE_NODE, &undebug_msdp_cmd);
6093 install_element (ENABLE_NODE, &debug_msdp_events_cmd);
6094 install_element (ENABLE_NODE, &no_debug_msdp_events_cmd);
6095 install_element (ENABLE_NODE, &undebug_msdp_events_cmd);
6096 install_element (ENABLE_NODE, &debug_msdp_packets_cmd);
6097 install_element (ENABLE_NODE, &no_debug_msdp_packets_cmd);
6098 install_element (ENABLE_NODE, &undebug_msdp_packets_cmd);
12e41d03
DL
6099
6100 install_element (CONFIG_NODE, &debug_igmp_cmd);
6101 install_element (CONFIG_NODE, &no_debug_igmp_cmd);
12e41d03
DL
6102 install_element (CONFIG_NODE, &debug_igmp_events_cmd);
6103 install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
12e41d03
DL
6104 install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
6105 install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
12e41d03
DL
6106 install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
6107 install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
12e41d03 6108 install_element (CONFIG_NODE, &debug_mroute_cmd);
6c7197b1 6109 install_element (CONFIG_NODE, &debug_mroute_detail_cmd);
12e41d03 6110 install_element (CONFIG_NODE, &no_debug_mroute_cmd);
6c7197b1 6111 install_element (CONFIG_NODE, &no_debug_mroute_detail_cmd);
6250610a
JAG
6112 install_element (CONFIG_NODE, &debug_static_cmd);
6113 install_element (CONFIG_NODE, &no_debug_static_cmd);
12e41d03
DL
6114 install_element (CONFIG_NODE, &debug_pim_cmd);
6115 install_element (CONFIG_NODE, &no_debug_pim_cmd);
12e41d03
DL
6116 install_element (CONFIG_NODE, &debug_pim_events_cmd);
6117 install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
12e41d03
DL
6118 install_element (CONFIG_NODE, &debug_pim_packets_cmd);
6119 install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
6120 install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
6121 install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
12e41d03
DL
6122 install_element (CONFIG_NODE, &debug_pim_trace_cmd);
6123 install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
12e41d03
DL
6124 install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
6125 install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
12e41d03
DL
6126 install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
6127 install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
2a333e0f 6128 install_element (CONFIG_NODE, &debug_msdp_cmd);
6129 install_element (CONFIG_NODE, &no_debug_msdp_cmd);
6130 install_element (CONFIG_NODE, &undebug_msdp_cmd);
6131 install_element (CONFIG_NODE, &debug_msdp_events_cmd);
6132 install_element (CONFIG_NODE, &no_debug_msdp_events_cmd);
6133 install_element (CONFIG_NODE, &undebug_msdp_events_cmd);
6134 install_element (CONFIG_NODE, &debug_msdp_packets_cmd);
6135 install_element (CONFIG_NODE, &no_debug_msdp_packets_cmd);
6136 install_element (CONFIG_NODE, &undebug_msdp_packets_cmd);
977d71cc 6137 install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
6138 install_element (CONFIG_NODE, &no_ip_msdp_peer_cmd);
6139 install_element (CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
6140 install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
6141 install_element (CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
6142 install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
977d71cc 6143 install_element (VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
6144 install_element (VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
6145 install_element (VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
6146 install_element (VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
4763cd0e 6147 install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
6148 install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
12e41d03 6149}