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