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