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