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