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