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