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