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