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