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