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