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