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