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