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