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