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