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