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