]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_cmd.c
Merge pull request #5890 from mjstapp/zapi_allow_label_num
[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 "pim_vxlan.h"
64 #include "pim_mlag.h"
65 #include "bfd.h"
66 #include "pim_bsm.h"
67
68 #ifndef VTYSH_EXTRACT_PL
69 #include "pimd/pim_cmd_clippy.c"
70 #endif
71
72 static struct cmd_node interface_node = {
73 INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
74 };
75
76 static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
77
78 static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
79 const int argc, int *idx)
80 {
81 struct vrf *vrf;
82
83 if (argv_find(argv, argc, "NAME", idx))
84 vrf = vrf_lookup_by_name(argv[*idx]->arg);
85 else
86 vrf = vrf_lookup_by_id(VRF_DEFAULT);
87
88 if (!vrf)
89 vty_out(vty, "Specified VRF: %s does not exist\n",
90 argv[*idx]->arg);
91
92 return vrf;
93 }
94
95 static void pim_if_membership_clear(struct interface *ifp)
96 {
97 struct pim_interface *pim_ifp;
98
99 pim_ifp = ifp->info;
100 zassert(pim_ifp);
101
102 if (PIM_IF_TEST_PIM(pim_ifp->options)
103 && PIM_IF_TEST_IGMP(pim_ifp->options)) {
104 return;
105 }
106
107 pim_ifchannel_membership_clear(ifp);
108 }
109
110 /*
111 When PIM is disabled on interface, IGMPv3 local membership
112 information is not injected into PIM interface state.
113
114 The function pim_if_membership_refresh() fetches all IGMPv3 local
115 membership information into PIM. It is intented to be called
116 whenever PIM is enabled on the interface in order to collect missed
117 local membership information.
118 */
119 static void pim_if_membership_refresh(struct interface *ifp)
120 {
121 struct pim_interface *pim_ifp;
122 struct listnode *sock_node;
123 struct igmp_sock *igmp;
124
125 pim_ifp = ifp->info;
126 zassert(pim_ifp);
127
128 if (!PIM_IF_TEST_PIM(pim_ifp->options))
129 return;
130 if (!PIM_IF_TEST_IGMP(pim_ifp->options))
131 return;
132
133 /*
134 First clear off membership from all PIM (S,G) entries on the
135 interface
136 */
137
138 pim_ifchannel_membership_clear(ifp);
139
140 /*
141 Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
142 the interface
143 */
144
145 /* scan igmp sockets */
146 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
147 struct listnode *grpnode;
148 struct igmp_group *grp;
149
150 /* scan igmp groups */
151 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
152 grp)) {
153 struct listnode *srcnode;
154 struct igmp_source *src;
155
156 /* scan group sources */
157 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
158 srcnode, src)) {
159
160 if (IGMP_SOURCE_TEST_FORWARDING(
161 src->source_flags)) {
162 struct prefix_sg sg;
163
164 memset(&sg, 0,
165 sizeof(struct prefix_sg));
166 sg.src = src->source_addr;
167 sg.grp = grp->group_addr;
168 pim_ifchannel_local_membership_add(ifp,
169 &sg, false /*is_vxlan*/);
170 }
171
172 } /* scan group sources */
173 } /* scan igmp groups */
174 } /* scan igmp sockets */
175
176 /*
177 Finally delete every PIM (S,G) entry lacking all state info
178 */
179
180 pim_ifchannel_delete_on_noinfo(ifp);
181 }
182
183 static void pim_show_assert_helper(struct vty *vty,
184 struct pim_interface *pim_ifp,
185 struct pim_ifchannel *ch, time_t now)
186 {
187 char ch_src_str[INET_ADDRSTRLEN];
188 char ch_grp_str[INET_ADDRSTRLEN];
189 char winner_str[INET_ADDRSTRLEN];
190 struct in_addr ifaddr;
191 char uptime[10];
192 char timer[10];
193
194 ifaddr = pim_ifp->primary_address;
195
196 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
197 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
198 pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
199 sizeof(winner_str));
200
201 pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
202 pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
203
204 vty_out(vty, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
205 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
206 pim_ifchannel_ifassert_name(ch->ifassert_state), winner_str,
207 uptime, timer);
208 }
209
210 static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
211 {
212 struct pim_interface *pim_ifp;
213 struct pim_ifchannel *ch;
214 struct interface *ifp;
215 time_t now;
216
217 now = pim_time_monotonic_sec();
218
219 vty_out(vty,
220 "Interface Address Source Group State Winner Uptime Timer\n");
221
222 FOR_ALL_INTERFACES (pim->vrf, ifp) {
223 pim_ifp = ifp->info;
224 if (!pim_ifp)
225 continue;
226
227 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
228 pim_show_assert_helper(vty, pim_ifp, ch, now);
229 } /* scan interface channels */
230 }
231 }
232
233 static void pim_show_assert_internal_helper(struct vty *vty,
234 struct pim_interface *pim_ifp,
235 struct pim_ifchannel *ch)
236 {
237 char ch_src_str[INET_ADDRSTRLEN];
238 char ch_grp_str[INET_ADDRSTRLEN];
239 struct in_addr ifaddr;
240
241 ifaddr = pim_ifp->primary_address;
242
243 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
244 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
245 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
246 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
247 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
248 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
249 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
250 : "no",
251 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
252 }
253
254 static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
255 {
256 struct pim_interface *pim_ifp;
257 struct pim_ifchannel *ch;
258 struct interface *ifp;
259
260 vty_out(vty,
261 "CA: CouldAssert\n"
262 "ECA: Evaluate CouldAssert\n"
263 "ATD: AssertTrackingDesired\n"
264 "eATD: Evaluate AssertTrackingDesired\n\n");
265
266 vty_out(vty,
267 "Interface Address Source Group CA eCA ATD eATD\n");
268 FOR_ALL_INTERFACES (pim->vrf, ifp) {
269 pim_ifp = ifp->info;
270 if (!pim_ifp)
271 continue;
272
273 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
274 pim_show_assert_internal_helper(vty, pim_ifp, ch);
275 } /* scan interface channels */
276 }
277 }
278
279 static void pim_show_assert_metric_helper(struct vty *vty,
280 struct pim_interface *pim_ifp,
281 struct pim_ifchannel *ch)
282 {
283 char ch_src_str[INET_ADDRSTRLEN];
284 char ch_grp_str[INET_ADDRSTRLEN];
285 char addr_str[INET_ADDRSTRLEN];
286 struct pim_assert_metric am;
287 struct in_addr ifaddr;
288
289 ifaddr = pim_ifp->primary_address;
290
291 am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
292 pim_ifp->primary_address);
293
294 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
295 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
296 pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
297
298 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
299 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
300 am.rpt_bit_flag ? "yes" : "no", am.metric_preference,
301 am.route_metric, addr_str);
302 }
303
304 static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
305 {
306 struct pim_interface *pim_ifp;
307 struct pim_ifchannel *ch;
308 struct interface *ifp;
309
310 vty_out(vty,
311 "Interface Address Source Group RPT Pref Metric Address \n");
312
313 FOR_ALL_INTERFACES (pim->vrf, ifp) {
314 pim_ifp = ifp->info;
315 if (!pim_ifp)
316 continue;
317
318 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
319 pim_show_assert_metric_helper(vty, pim_ifp, ch);
320 } /* scan interface channels */
321 }
322 }
323
324 static void pim_show_assert_winner_metric_helper(struct vty *vty,
325 struct pim_interface *pim_ifp,
326 struct pim_ifchannel *ch)
327 {
328 char ch_src_str[INET_ADDRSTRLEN];
329 char ch_grp_str[INET_ADDRSTRLEN];
330 char addr_str[INET_ADDRSTRLEN];
331 struct pim_assert_metric *am;
332 struct in_addr ifaddr;
333 char pref_str[16];
334 char metr_str[16];
335
336 ifaddr = pim_ifp->primary_address;
337
338 am = &ch->ifassert_winner_metric;
339
340 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
341 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
342 pim_inet4_dump("<addr?>", am->ip_address, addr_str, sizeof(addr_str));
343
344 if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
345 snprintf(pref_str, sizeof(pref_str), "INFI");
346 else
347 snprintf(pref_str, sizeof(pref_str), "%4u",
348 am->metric_preference);
349
350 if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
351 snprintf(metr_str, sizeof(metr_str), "INFI");
352 else
353 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
354
355 vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
356 ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
357 am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, addr_str);
358 }
359
360 static void pim_show_assert_winner_metric(struct pim_instance *pim,
361 struct vty *vty)
362 {
363 struct pim_interface *pim_ifp;
364 struct pim_ifchannel *ch;
365 struct interface *ifp;
366
367 vty_out(vty,
368 "Interface Address Source Group RPT Pref Metric Address \n");
369
370 FOR_ALL_INTERFACES (pim->vrf, ifp) {
371 pim_ifp = ifp->info;
372 if (!pim_ifp)
373 continue;
374
375 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
376 pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
377 } /* scan interface channels */
378 }
379 }
380
381 static void json_object_pim_ifp_add(struct json_object *json,
382 struct interface *ifp)
383 {
384 struct pim_interface *pim_ifp;
385
386 pim_ifp = ifp->info;
387 json_object_string_add(json, "name", ifp->name);
388 json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
389 json_object_string_add(json, "address",
390 inet_ntoa(pim_ifp->primary_address));
391 json_object_int_add(json, "index", ifp->ifindex);
392
393 if (if_is_multicast(ifp))
394 json_object_boolean_true_add(json, "flagMulticast");
395
396 if (if_is_broadcast(ifp))
397 json_object_boolean_true_add(json, "flagBroadcast");
398
399 if (ifp->flags & IFF_ALLMULTI)
400 json_object_boolean_true_add(json, "flagAllMulticast");
401
402 if (ifp->flags & IFF_PROMISC)
403 json_object_boolean_true_add(json, "flagPromiscuous");
404
405 if (PIM_IF_IS_DELETED(ifp))
406 json_object_boolean_true_add(json, "flagDeleted");
407
408 if (pim_if_lan_delay_enabled(ifp))
409 json_object_boolean_true_add(json, "lanDelayEnabled");
410 }
411
412 static void pim_show_membership_helper(struct vty *vty,
413 struct pim_interface *pim_ifp,
414 struct pim_ifchannel *ch,
415 struct json_object *json)
416 {
417 char ch_src_str[INET_ADDRSTRLEN];
418 char ch_grp_str[INET_ADDRSTRLEN];
419 json_object *json_iface = NULL;
420 json_object *json_row = NULL;
421
422 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
423 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
424
425 json_object_object_get_ex(json, ch->interface->name, &json_iface);
426 if (!json_iface) {
427 json_iface = json_object_new_object();
428 json_object_pim_ifp_add(json_iface, ch->interface);
429 json_object_object_add(json, ch->interface->name, json_iface);
430 }
431
432 json_row = json_object_new_object();
433 json_object_string_add(json_row, "source", ch_src_str);
434 json_object_string_add(json_row, "group", ch_grp_str);
435 json_object_string_add(json_row, "localMembership",
436 ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
437 ? "NOINFO"
438 : "INCLUDE");
439 json_object_object_add(json_iface, ch_grp_str, json_row);
440 }
441 static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
442 bool uj)
443 {
444 struct pim_interface *pim_ifp;
445 struct pim_ifchannel *ch;
446 struct interface *ifp;
447 enum json_type type;
448 json_object *json = NULL;
449 json_object *json_tmp = NULL;
450
451 json = json_object_new_object();
452
453 FOR_ALL_INTERFACES (pim->vrf, ifp) {
454 pim_ifp = ifp->info;
455 if (!pim_ifp)
456 continue;
457
458 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
459 pim_show_membership_helper(vty, pim_ifp, ch, json);
460 } /* scan interface channels */
461 }
462
463 if (uj) {
464 vty_out(vty, "%s\n", json_object_to_json_string_ext(
465 json, JSON_C_TO_STRING_PRETTY));
466 } else {
467 vty_out(vty,
468 "Interface Address Source Group Membership\n");
469
470 /*
471 * Example of the json data we are traversing
472 *
473 * {
474 * "swp3":{
475 * "name":"swp3",
476 * "state":"up",
477 * "address":"10.1.20.1",
478 * "index":5,
479 * "flagMulticast":true,
480 * "flagBroadcast":true,
481 * "lanDelayEnabled":true,
482 * "226.10.10.10":{
483 * "source":"*",
484 * "group":"226.10.10.10",
485 * "localMembership":"INCLUDE"
486 * }
487 * }
488 * }
489 */
490
491 /* foreach interface */
492 json_object_object_foreach(json, key, val)
493 {
494
495 /* Find all of the keys where the val is an object. In
496 * the example
497 * above the only one is 226.10.10.10
498 */
499 json_object_object_foreach(val, if_field_key,
500 if_field_val)
501 {
502 type = json_object_get_type(if_field_val);
503
504 if (type == json_type_object) {
505 vty_out(vty, "%-16s ", key);
506
507 json_object_object_get_ex(
508 val, "address", &json_tmp);
509 vty_out(vty, "%-15s ",
510 json_object_get_string(
511 json_tmp));
512
513 json_object_object_get_ex(if_field_val,
514 "source",
515 &json_tmp);
516 vty_out(vty, "%-15s ",
517 json_object_get_string(
518 json_tmp));
519
520 /* Group */
521 vty_out(vty, "%-15s ", if_field_key);
522
523 json_object_object_get_ex(
524 if_field_val, "localMembership",
525 &json_tmp);
526 vty_out(vty, "%-10s\n",
527 json_object_get_string(
528 json_tmp));
529 }
530 }
531 }
532 }
533
534 json_object_free(json);
535 }
536
537 static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp,
538 int mloop)
539 {
540 vty_out(vty, "Flags\n");
541 vty_out(vty, "-----\n");
542 vty_out(vty, "All Multicast : %s\n",
543 (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
544 vty_out(vty, "Broadcast : %s\n",
545 if_is_broadcast(ifp) ? "yes" : "no");
546 vty_out(vty, "Deleted : %s\n",
547 PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
548 vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
549 vty_out(vty, "Multicast : %s\n",
550 if_is_multicast(ifp) ? "yes" : "no");
551 vty_out(vty, "Multicast Loop : %d\n", mloop);
552 vty_out(vty, "Promiscuous : %s\n",
553 (ifp->flags & IFF_PROMISC) ? "yes" : "no");
554 vty_out(vty, "\n");
555 vty_out(vty, "\n");
556 }
557
558 static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
559 bool uj)
560 {
561 struct interface *ifp;
562 time_t now;
563 json_object *json = NULL;
564 json_object *json_row = NULL;
565
566 now = pim_time_monotonic_sec();
567
568 if (uj)
569 json = json_object_new_object();
570 else
571 vty_out(vty,
572 "Interface State Address V Querier Query Timer Uptime\n");
573
574 FOR_ALL_INTERFACES (pim->vrf, ifp) {
575 struct pim_interface *pim_ifp;
576 struct listnode *sock_node;
577 struct igmp_sock *igmp;
578
579 pim_ifp = ifp->info;
580
581 if (!pim_ifp)
582 continue;
583
584 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
585 igmp)) {
586 char uptime[10];
587 char query_hhmmss[10];
588
589 pim_time_uptime(uptime, sizeof(uptime),
590 now - igmp->sock_creation);
591 pim_time_timer_to_hhmmss(query_hhmmss,
592 sizeof(query_hhmmss),
593 igmp->t_igmp_query_timer);
594
595 if (uj) {
596 json_row = json_object_new_object();
597 json_object_pim_ifp_add(json_row, ifp);
598 json_object_string_add(json_row, "upTime",
599 uptime);
600 json_object_int_add(json_row, "version",
601 pim_ifp->igmp_version);
602
603 if (igmp->t_igmp_query_timer) {
604 json_object_boolean_true_add(json_row,
605 "querier");
606 json_object_string_add(json_row,
607 "queryTimer",
608 query_hhmmss);
609 }
610
611 json_object_object_add(json, ifp->name,
612 json_row);
613
614 if (igmp->mtrace_only) {
615 json_object_boolean_true_add(
616 json_row, "mtraceOnly");
617 }
618 } else {
619 vty_out(vty,
620 "%-16s %5s %15s %d %7s %11s %8s\n",
621 ifp->name,
622 if_is_up(ifp)
623 ? (igmp->mtrace_only ? "mtrc"
624 : "up")
625 : "down",
626 inet_ntoa(igmp->ifaddr),
627 pim_ifp->igmp_version,
628 igmp->t_igmp_query_timer ? "local"
629 : "other",
630 query_hhmmss, uptime);
631 }
632 }
633 }
634
635 if (uj) {
636 vty_out(vty, "%s\n", json_object_to_json_string_ext(
637 json, JSON_C_TO_STRING_PRETTY));
638 json_object_free(json);
639 }
640 }
641
642 static void igmp_show_interfaces_single(struct pim_instance *pim,
643 struct vty *vty, const char *ifname,
644 bool uj)
645 {
646 struct igmp_sock *igmp;
647 struct interface *ifp;
648 struct listnode *sock_node;
649 struct pim_interface *pim_ifp;
650 char uptime[10];
651 char query_hhmmss[10];
652 char other_hhmmss[10];
653 int found_ifname = 0;
654 int sqi;
655 int mloop = 0;
656 long gmi_msec; /* Group Membership Interval */
657 long lmqt_msec;
658 long ohpi_msec;
659 long oqpi_msec; /* Other Querier Present Interval */
660 long qri_msec;
661 time_t now;
662 int lmqc;
663
664 json_object *json = NULL;
665 json_object *json_row = NULL;
666
667 if (uj)
668 json = json_object_new_object();
669
670 now = pim_time_monotonic_sec();
671
672 FOR_ALL_INTERFACES (pim->vrf, ifp) {
673 pim_ifp = ifp->info;
674
675 if (!pim_ifp)
676 continue;
677
678 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
679 continue;
680
681 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
682 igmp)) {
683 found_ifname = 1;
684 pim_time_uptime(uptime, sizeof(uptime),
685 now - igmp->sock_creation);
686 pim_time_timer_to_hhmmss(query_hhmmss,
687 sizeof(query_hhmmss),
688 igmp->t_igmp_query_timer);
689 pim_time_timer_to_hhmmss(other_hhmmss,
690 sizeof(other_hhmmss),
691 igmp->t_other_querier_timer);
692
693 gmi_msec = PIM_IGMP_GMI_MSEC(
694 igmp->querier_robustness_variable,
695 igmp->querier_query_interval,
696 pim_ifp->igmp_query_max_response_time_dsec);
697
698 sqi = PIM_IGMP_SQI(
699 pim_ifp->igmp_default_query_interval);
700
701 oqpi_msec = PIM_IGMP_OQPI_MSEC(
702 igmp->querier_robustness_variable,
703 igmp->querier_query_interval,
704 pim_ifp->igmp_query_max_response_time_dsec);
705
706 lmqt_msec = PIM_IGMP_LMQT_MSEC(
707 pim_ifp->igmp_specific_query_max_response_time_dsec,
708 pim_ifp->igmp_last_member_query_count);
709
710 ohpi_msec =
711 PIM_IGMP_OHPI_DSEC(
712 igmp->querier_robustness_variable,
713 igmp->querier_query_interval,
714 pim_ifp->igmp_query_max_response_time_dsec)
715 * 100;
716
717 qri_msec = pim_ifp->igmp_query_max_response_time_dsec
718 * 100;
719 if (pim_ifp->pim_sock_fd >= 0)
720 mloop = pim_socket_mcastloop_get(
721 pim_ifp->pim_sock_fd);
722 else
723 mloop = 0;
724 lmqc = pim_ifp->igmp_last_member_query_count;
725
726 if (uj) {
727 json_row = json_object_new_object();
728 json_object_pim_ifp_add(json_row, ifp);
729 json_object_string_add(json_row, "upTime",
730 uptime);
731 json_object_string_add(json_row, "querier",
732 igmp->t_igmp_query_timer
733 ? "local"
734 : "other");
735 json_object_int_add(json_row, "queryStartCount",
736 igmp->startup_query_count);
737 json_object_string_add(json_row,
738 "queryQueryTimer",
739 query_hhmmss);
740 json_object_string_add(json_row,
741 "queryOtherTimer",
742 other_hhmmss);
743 json_object_int_add(json_row, "version",
744 pim_ifp->igmp_version);
745 json_object_int_add(
746 json_row,
747 "timerGroupMembershipIntervalMsec",
748 gmi_msec);
749 json_object_int_add(json_row,
750 "lastMemberQueryCount",
751 lmqc);
752 json_object_int_add(json_row,
753 "timerLastMemberQueryMsec",
754 lmqt_msec);
755 json_object_int_add(
756 json_row,
757 "timerOlderHostPresentIntervalMsec",
758 ohpi_msec);
759 json_object_int_add(
760 json_row,
761 "timerOtherQuerierPresentIntervalMsec",
762 oqpi_msec);
763 json_object_int_add(
764 json_row, "timerQueryInterval",
765 igmp->querier_query_interval);
766 json_object_int_add(
767 json_row,
768 "timerQueryResponseIntervalMsec",
769 qri_msec);
770 json_object_int_add(
771 json_row, "timerRobustnessVariable",
772 igmp->querier_robustness_variable);
773 json_object_int_add(json_row,
774 "timerStartupQueryInterval",
775 sqi);
776
777 json_object_object_add(json, ifp->name,
778 json_row);
779
780 if (igmp->mtrace_only) {
781 json_object_boolean_true_add(
782 json_row, "mtraceOnly");
783 }
784 } else {
785 vty_out(vty, "Interface : %s\n", ifp->name);
786 vty_out(vty, "State : %s\n",
787 if_is_up(ifp)
788 ? (igmp->mtrace_only ? "mtrace"
789 : "up")
790 : "down");
791 vty_out(vty, "Address : %s\n",
792 inet_ntoa(pim_ifp->primary_address));
793 vty_out(vty, "Uptime : %s\n", uptime);
794 vty_out(vty, "Version : %d\n",
795 pim_ifp->igmp_version);
796 vty_out(vty, "\n");
797 vty_out(vty, "\n");
798
799 vty_out(vty, "Querier\n");
800 vty_out(vty, "-------\n");
801 vty_out(vty, "Querier : %s\n",
802 igmp->t_igmp_query_timer ? "local"
803 : "other");
804 vty_out(vty, "Start Count : %d\n",
805 igmp->startup_query_count);
806 vty_out(vty, "Query Timer : %s\n",
807 query_hhmmss);
808 vty_out(vty, "Other Timer : %s\n",
809 other_hhmmss);
810 vty_out(vty, "\n");
811 vty_out(vty, "\n");
812
813 vty_out(vty, "Timers\n");
814 vty_out(vty, "------\n");
815 vty_out(vty,
816 "Group Membership Interval : %lis\n",
817 gmi_msec / 1000);
818 vty_out(vty,
819 "Last Member Query Count : %d\n",
820 lmqc);
821 vty_out(vty,
822 "Last Member Query Time : %lis\n",
823 lmqt_msec / 1000);
824 vty_out(vty,
825 "Older Host Present Interval : %lis\n",
826 ohpi_msec / 1000);
827 vty_out(vty,
828 "Other Querier Present Interval : %lis\n",
829 oqpi_msec / 1000);
830 vty_out(vty,
831 "Query Interval : %ds\n",
832 igmp->querier_query_interval);
833 vty_out(vty,
834 "Query Response Interval : %lis\n",
835 qri_msec / 1000);
836 vty_out(vty,
837 "Robustness Variable : %d\n",
838 igmp->querier_robustness_variable);
839 vty_out(vty,
840 "Startup Query Interval : %ds\n",
841 sqi);
842 vty_out(vty, "\n");
843 vty_out(vty, "\n");
844
845 pim_print_ifp_flags(vty, ifp, mloop);
846 }
847 }
848 }
849
850 if (uj) {
851 vty_out(vty, "%s\n", json_object_to_json_string_ext(
852 json, JSON_C_TO_STRING_PRETTY));
853 json_object_free(json);
854 } else {
855 if (!found_ifname)
856 vty_out(vty, "%% No such interface\n");
857 }
858 }
859
860 static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty)
861 {
862 struct interface *ifp;
863 time_t now;
864
865 now = pim_time_monotonic_sec();
866
867 vty_out(vty,
868 "Interface Address Source Group Socket Uptime \n");
869
870 FOR_ALL_INTERFACES (pim->vrf, ifp) {
871 struct pim_interface *pim_ifp;
872 struct listnode *join_node;
873 struct igmp_join *ij;
874 struct in_addr pri_addr;
875 char pri_addr_str[INET_ADDRSTRLEN];
876
877 pim_ifp = ifp->info;
878
879 if (!pim_ifp)
880 continue;
881
882 if (!pim_ifp->igmp_join_list)
883 continue;
884
885 pri_addr = pim_find_primary_addr(ifp);
886 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
887 sizeof(pri_addr_str));
888
889 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node,
890 ij)) {
891 char group_str[INET_ADDRSTRLEN];
892 char source_str[INET_ADDRSTRLEN];
893 char uptime[10];
894
895 pim_time_uptime(uptime, sizeof(uptime),
896 now - ij->sock_creation);
897 pim_inet4_dump("<grp?>", ij->group_addr, group_str,
898 sizeof(group_str));
899 pim_inet4_dump("<src?>", ij->source_addr, source_str,
900 sizeof(source_str));
901
902 vty_out(vty, "%-16s %-15s %-15s %-15s %6d %8s\n",
903 ifp->name, pri_addr_str, source_str, group_str,
904 ij->sock_fd, uptime);
905 } /* for (pim_ifp->igmp_join_list) */
906
907 } /* for (iflist) */
908 }
909
910 static void pim_show_interfaces_single(struct pim_instance *pim,
911 struct vty *vty, const char *ifname,
912 bool uj)
913 {
914 struct in_addr ifaddr;
915 struct interface *ifp;
916 struct listnode *neighnode;
917 struct pim_interface *pim_ifp;
918 struct pim_neighbor *neigh;
919 struct pim_upstream *up;
920 time_t now;
921 char dr_str[INET_ADDRSTRLEN];
922 char dr_uptime[10];
923 char expire[10];
924 char grp_str[INET_ADDRSTRLEN];
925 char hello_period[10];
926 char hello_timer[10];
927 char neigh_src_str[INET_ADDRSTRLEN];
928 char src_str[INET_ADDRSTRLEN];
929 char stat_uptime[10];
930 char uptime[10];
931 int mloop = 0;
932 int found_ifname = 0;
933 int print_header;
934 json_object *json = NULL;
935 json_object *json_row = NULL;
936 json_object *json_pim_neighbor = NULL;
937 json_object *json_pim_neighbors = NULL;
938 json_object *json_group = NULL;
939 json_object *json_group_source = NULL;
940 json_object *json_fhr_sources = NULL;
941 struct pim_secondary_addr *sec_addr;
942 struct listnode *sec_node;
943
944 now = pim_time_monotonic_sec();
945
946 if (uj)
947 json = json_object_new_object();
948
949 FOR_ALL_INTERFACES (pim->vrf, ifp) {
950 pim_ifp = ifp->info;
951
952 if (!pim_ifp)
953 continue;
954
955 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
956 continue;
957
958 found_ifname = 1;
959 ifaddr = pim_ifp->primary_address;
960 pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
961 sizeof(dr_str));
962 pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
963 pim_ifp->pim_dr_election_last);
964 pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
965 pim_ifp->t_pim_hello_timer);
966 pim_time_mmss(hello_period, sizeof(hello_period),
967 pim_ifp->pim_hello_period);
968 pim_time_uptime(stat_uptime, sizeof(stat_uptime),
969 now - pim_ifp->pim_ifstat_start);
970 if (pim_ifp->pim_sock_fd >= 0)
971 mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
972 else
973 mloop = 0;
974
975 if (uj) {
976 char pbuf[PREFIX2STR_BUFFER];
977 json_row = json_object_new_object();
978 json_object_pim_ifp_add(json_row, ifp);
979
980 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
981 json_object_string_add(
982 json_row, "useSource",
983 inet_ntoa(pim_ifp->update_source));
984 }
985 if (pim_ifp->sec_addr_list) {
986 json_object *sec_list = NULL;
987
988 sec_list = json_object_new_array();
989 for (ALL_LIST_ELEMENTS_RO(
990 pim_ifp->sec_addr_list, sec_node,
991 sec_addr)) {
992 json_object_array_add(
993 sec_list,
994 json_object_new_string(
995 prefix2str(
996 &sec_addr->addr,
997 pbuf,
998 sizeof(pbuf))));
999 }
1000 json_object_object_add(json_row,
1001 "secondaryAddressList",
1002 sec_list);
1003 }
1004
1005 // PIM neighbors
1006 if (pim_ifp->pim_neighbor_list->count) {
1007 json_pim_neighbors = json_object_new_object();
1008
1009 for (ALL_LIST_ELEMENTS_RO(
1010 pim_ifp->pim_neighbor_list,
1011 neighnode, neigh)) {
1012 json_pim_neighbor =
1013 json_object_new_object();
1014 pim_inet4_dump("<src?>",
1015 neigh->source_addr,
1016 neigh_src_str,
1017 sizeof(neigh_src_str));
1018 pim_time_uptime(uptime, sizeof(uptime),
1019 now - neigh->creation);
1020 pim_time_timer_to_hhmmss(
1021 expire, sizeof(expire),
1022 neigh->t_expire_timer);
1023
1024 json_object_string_add(
1025 json_pim_neighbor, "address",
1026 neigh_src_str);
1027 json_object_string_add(
1028 json_pim_neighbor, "upTime",
1029 uptime);
1030 json_object_string_add(
1031 json_pim_neighbor, "holdtime",
1032 expire);
1033
1034 json_object_object_add(
1035 json_pim_neighbors,
1036 neigh_src_str,
1037 json_pim_neighbor);
1038 }
1039
1040 json_object_object_add(json_row, "neighbors",
1041 json_pim_neighbors);
1042 }
1043
1044 json_object_string_add(json_row, "drAddress", dr_str);
1045 json_object_int_add(json_row, "drPriority",
1046 pim_ifp->pim_dr_priority);
1047 json_object_string_add(json_row, "drUptime", dr_uptime);
1048 json_object_int_add(json_row, "drElections",
1049 pim_ifp->pim_dr_election_count);
1050 json_object_int_add(json_row, "drChanges",
1051 pim_ifp->pim_dr_election_changes);
1052
1053 // FHR
1054 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
1055 if (ifp != up->rpf.source_nexthop.interface)
1056 continue;
1057
1058 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1059 continue;
1060
1061 if (!json_fhr_sources)
1062 json_fhr_sources =
1063 json_object_new_object();
1064
1065 pim_inet4_dump("<src?>", up->sg.src, src_str,
1066 sizeof(src_str));
1067 pim_inet4_dump("<grp?>", up->sg.grp, grp_str,
1068 sizeof(grp_str));
1069 pim_time_uptime(uptime, sizeof(uptime),
1070 now - up->state_transition);
1071
1072 /*
1073 * Does this group live in json_fhr_sources?
1074 * If not create it.
1075 */
1076 json_object_object_get_ex(json_fhr_sources,
1077 grp_str, &json_group);
1078
1079 if (!json_group) {
1080 json_group = json_object_new_object();
1081 json_object_object_add(json_fhr_sources,
1082 grp_str,
1083 json_group);
1084 }
1085
1086 json_group_source = json_object_new_object();
1087 json_object_string_add(json_group_source,
1088 "source", src_str);
1089 json_object_string_add(json_group_source,
1090 "group", grp_str);
1091 json_object_string_add(json_group_source,
1092 "upTime", uptime);
1093 json_object_object_add(json_group, src_str,
1094 json_group_source);
1095 }
1096
1097 if (json_fhr_sources) {
1098 json_object_object_add(json_row,
1099 "firstHopRouter",
1100 json_fhr_sources);
1101 }
1102
1103 json_object_int_add(json_row, "helloPeriod",
1104 pim_ifp->pim_hello_period);
1105 json_object_string_add(json_row, "helloTimer",
1106 hello_timer);
1107 json_object_string_add(json_row, "helloStatStart",
1108 stat_uptime);
1109 json_object_int_add(json_row, "helloReceived",
1110 pim_ifp->pim_ifstat_hello_recv);
1111 json_object_int_add(json_row, "helloReceivedFailed",
1112 pim_ifp->pim_ifstat_hello_recvfail);
1113 json_object_int_add(json_row, "helloSend",
1114 pim_ifp->pim_ifstat_hello_sent);
1115 json_object_int_add(json_row, "hellosendFailed",
1116 pim_ifp->pim_ifstat_hello_sendfail);
1117 json_object_int_add(json_row, "helloGenerationId",
1118 pim_ifp->pim_generation_id);
1119 json_object_int_add(json_row, "flagMulticastLoop",
1120 mloop);
1121
1122 json_object_int_add(
1123 json_row, "effectivePropagationDelay",
1124 pim_if_effective_propagation_delay_msec(ifp));
1125 json_object_int_add(
1126 json_row, "effectiveOverrideInterval",
1127 pim_if_effective_override_interval_msec(ifp));
1128 json_object_int_add(
1129 json_row, "joinPruneOverrideInterval",
1130 pim_if_jp_override_interval_msec(ifp));
1131
1132 json_object_int_add(
1133 json_row, "propagationDelay",
1134 pim_ifp->pim_propagation_delay_msec);
1135 json_object_int_add(
1136 json_row, "propagationDelayHighest",
1137 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1138 json_object_int_add(
1139 json_row, "overrideInterval",
1140 pim_ifp->pim_override_interval_msec);
1141 json_object_int_add(
1142 json_row, "overrideIntervalHighest",
1143 pim_ifp->pim_neighbors_highest_override_interval_msec);
1144 json_object_object_add(json, ifp->name, json_row);
1145
1146 } else {
1147 vty_out(vty, "Interface : %s\n", ifp->name);
1148 vty_out(vty, "State : %s\n",
1149 if_is_up(ifp) ? "up" : "down");
1150 if (pim_ifp->update_source.s_addr != INADDR_ANY) {
1151 vty_out(vty, "Use Source : %s\n",
1152 inet_ntoa(pim_ifp->update_source));
1153 }
1154 if (pim_ifp->sec_addr_list) {
1155 char pbuf[PREFIX2STR_BUFFER];
1156 vty_out(vty, "Address : %s (primary)\n",
1157 inet_ntoa(ifaddr));
1158 for (ALL_LIST_ELEMENTS_RO(
1159 pim_ifp->sec_addr_list, sec_node,
1160 sec_addr)) {
1161 vty_out(vty, " %s\n",
1162 prefix2str(&sec_addr->addr,
1163 pbuf, sizeof(pbuf)));
1164 }
1165 } else {
1166 vty_out(vty, "Address : %s\n",
1167 inet_ntoa(ifaddr));
1168 }
1169 vty_out(vty, "\n");
1170
1171 // PIM neighbors
1172 print_header = 1;
1173
1174 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
1175 neighnode, neigh)) {
1176
1177 if (print_header) {
1178 vty_out(vty, "PIM Neighbors\n");
1179 vty_out(vty, "-------------\n");
1180 print_header = 0;
1181 }
1182
1183 pim_inet4_dump("<src?>", neigh->source_addr,
1184 neigh_src_str,
1185 sizeof(neigh_src_str));
1186 pim_time_uptime(uptime, sizeof(uptime),
1187 now - neigh->creation);
1188 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1189 neigh->t_expire_timer);
1190 vty_out(vty,
1191 "%-15s : up for %s, holdtime expires in %s\n",
1192 neigh_src_str, uptime, expire);
1193 }
1194
1195 if (!print_header) {
1196 vty_out(vty, "\n");
1197 vty_out(vty, "\n");
1198 }
1199
1200 vty_out(vty, "Designated Router\n");
1201 vty_out(vty, "-----------------\n");
1202 vty_out(vty, "Address : %s\n", dr_str);
1203 vty_out(vty, "Priority : %u(%d)\n",
1204 pim_ifp->pim_dr_priority,
1205 pim_ifp->pim_dr_num_nondrpri_neighbors);
1206 vty_out(vty, "Uptime : %s\n", dr_uptime);
1207 vty_out(vty, "Elections : %d\n",
1208 pim_ifp->pim_dr_election_count);
1209 vty_out(vty, "Changes : %d\n",
1210 pim_ifp->pim_dr_election_changes);
1211 vty_out(vty, "\n");
1212 vty_out(vty, "\n");
1213
1214 // FHR
1215 print_header = 1;
1216 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
1217 if (!up->rpf.source_nexthop.interface)
1218 continue;
1219
1220 if (strcmp(ifp->name,
1221 up->rpf.source_nexthop
1222 .interface->name)
1223 != 0)
1224 continue;
1225
1226 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
1227 continue;
1228
1229 if (print_header) {
1230 vty_out(vty,
1231 "FHR - First Hop Router\n");
1232 vty_out(vty,
1233 "----------------------\n");
1234 print_header = 0;
1235 }
1236
1237 pim_inet4_dump("<src?>", up->sg.src, src_str,
1238 sizeof(src_str));
1239 pim_inet4_dump("<grp?>", up->sg.grp, grp_str,
1240 sizeof(grp_str));
1241 pim_time_uptime(uptime, sizeof(uptime),
1242 now - up->state_transition);
1243 vty_out(vty,
1244 "%s : %s is a source, uptime is %s\n",
1245 grp_str, src_str, uptime);
1246 }
1247
1248 if (!print_header) {
1249 vty_out(vty, "\n");
1250 vty_out(vty, "\n");
1251 }
1252
1253 vty_out(vty, "Hellos\n");
1254 vty_out(vty, "------\n");
1255 vty_out(vty, "Period : %d\n",
1256 pim_ifp->pim_hello_period);
1257 vty_out(vty, "Timer : %s\n", hello_timer);
1258 vty_out(vty, "StatStart : %s\n", stat_uptime);
1259 vty_out(vty, "Receive : %d\n",
1260 pim_ifp->pim_ifstat_hello_recv);
1261 vty_out(vty, "Receive Failed : %d\n",
1262 pim_ifp->pim_ifstat_hello_recvfail);
1263 vty_out(vty, "Send : %d\n",
1264 pim_ifp->pim_ifstat_hello_sent);
1265 vty_out(vty, "Send Failed : %d\n",
1266 pim_ifp->pim_ifstat_hello_sendfail);
1267 vty_out(vty, "Generation ID : %08x\n",
1268 pim_ifp->pim_generation_id);
1269 vty_out(vty, "\n");
1270 vty_out(vty, "\n");
1271
1272 pim_print_ifp_flags(vty, ifp, mloop);
1273
1274 vty_out(vty, "Join Prune Interval\n");
1275 vty_out(vty, "-------------------\n");
1276 vty_out(vty, "LAN Delay : %s\n",
1277 pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
1278 vty_out(vty, "Effective Propagation Delay : %d msec\n",
1279 pim_if_effective_propagation_delay_msec(ifp));
1280 vty_out(vty, "Effective Override Interval : %d msec\n",
1281 pim_if_effective_override_interval_msec(ifp));
1282 vty_out(vty, "Join Prune Override Interval : %d msec\n",
1283 pim_if_jp_override_interval_msec(ifp));
1284 vty_out(vty, "\n");
1285 vty_out(vty, "\n");
1286
1287 vty_out(vty, "LAN Prune Delay\n");
1288 vty_out(vty, "---------------\n");
1289 vty_out(vty, "Propagation Delay : %d msec\n",
1290 pim_ifp->pim_propagation_delay_msec);
1291 vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
1292 pim_ifp->pim_neighbors_highest_propagation_delay_msec);
1293 vty_out(vty, "Override Interval : %d msec\n",
1294 pim_ifp->pim_override_interval_msec);
1295 vty_out(vty, "Override Interval (Highest) : %d msec\n",
1296 pim_ifp->pim_neighbors_highest_override_interval_msec);
1297 vty_out(vty, "\n");
1298 vty_out(vty, "\n");
1299 }
1300 }
1301
1302 if (uj) {
1303 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1304 json, JSON_C_TO_STRING_PRETTY));
1305 json_object_free(json);
1306 } else {
1307 if (!found_ifname)
1308 vty_out(vty, "%% No such interface\n");
1309 }
1310 }
1311
1312 static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
1313 const char *ifname, bool uj)
1314 {
1315 struct interface *ifp;
1316 struct igmp_stats rx_stats;
1317
1318 igmp_stats_init(&rx_stats);
1319
1320 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1321 struct pim_interface *pim_ifp;
1322 struct listnode *sock_node;
1323 struct igmp_sock *igmp;
1324
1325 pim_ifp = ifp->info;
1326
1327 if (!pim_ifp)
1328 continue;
1329
1330 if (ifname && strcmp(ifname, ifp->name))
1331 continue;
1332
1333 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
1334 igmp)) {
1335 igmp_stats_add(&rx_stats, &igmp->rx_stats);
1336 }
1337 }
1338 if (uj) {
1339 json_object *json = NULL;
1340 json_object *json_row = NULL;
1341
1342 json = json_object_new_object();
1343 json_row = json_object_new_object();
1344
1345 json_object_string_add(json_row, "name", ifname ? ifname :
1346 "global");
1347 json_object_int_add(json_row, "queryV1", rx_stats.query_v1);
1348 json_object_int_add(json_row, "queryV2", rx_stats.query_v2);
1349 json_object_int_add(json_row, "queryV3", rx_stats.query_v3);
1350 json_object_int_add(json_row, "leaveV3", rx_stats.leave_v2);
1351 json_object_int_add(json_row, "reportV1", rx_stats.report_v1);
1352 json_object_int_add(json_row, "reportV2", rx_stats.report_v2);
1353 json_object_int_add(json_row, "reportV3", rx_stats.report_v3);
1354 json_object_int_add(json_row, "mtraceResponse",
1355 rx_stats.mtrace_rsp);
1356 json_object_int_add(json_row, "mtraceRequest",
1357 rx_stats.mtrace_req);
1358 json_object_int_add(json_row, "unsupported",
1359 rx_stats.unsupported);
1360 json_object_object_add(json, ifname ? ifname : "global",
1361 json_row);
1362 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1363 json, JSON_C_TO_STRING_PRETTY));
1364 json_object_free(json);
1365 } else {
1366 vty_out(vty, "IGMP RX statistics\n");
1367 vty_out(vty, "Interface : %s\n",
1368 ifname ? ifname : "global");
1369 vty_out(vty, "V1 query : %u\n", rx_stats.query_v1);
1370 vty_out(vty, "V2 query : %u\n", rx_stats.query_v2);
1371 vty_out(vty, "V3 query : %u\n", rx_stats.query_v3);
1372 vty_out(vty, "V2 leave : %u\n", rx_stats.leave_v2);
1373 vty_out(vty, "V1 report : %u\n", rx_stats.report_v1);
1374 vty_out(vty, "V2 report : %u\n", rx_stats.report_v2);
1375 vty_out(vty, "V3 report : %u\n", rx_stats.report_v3);
1376 vty_out(vty, "mtrace response : %u\n", rx_stats.mtrace_rsp);
1377 vty_out(vty, "mtrace request : %u\n", rx_stats.mtrace_req);
1378 vty_out(vty, "unsupported : %u\n", rx_stats.unsupported);
1379 }
1380 }
1381
1382 static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
1383 bool uj)
1384 {
1385 struct interface *ifp;
1386 struct pim_interface *pim_ifp;
1387 struct pim_upstream *up;
1388 int fhr = 0;
1389 int pim_nbrs = 0;
1390 int pim_ifchannels = 0;
1391 json_object *json = NULL;
1392 json_object *json_row = NULL;
1393 json_object *json_tmp;
1394
1395 json = json_object_new_object();
1396
1397 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1398 pim_ifp = ifp->info;
1399
1400 if (!pim_ifp)
1401 continue;
1402
1403 pim_nbrs = pim_ifp->pim_neighbor_list->count;
1404 pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
1405 fhr = 0;
1406
1407 frr_each (rb_pim_upstream, &pim->upstream_head, up)
1408 if (ifp == up->rpf.source_nexthop.interface)
1409 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
1410 fhr++;
1411
1412 json_row = json_object_new_object();
1413 json_object_pim_ifp_add(json_row, ifp);
1414 json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
1415 json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
1416 json_object_int_add(json_row, "firstHopRouterCount", fhr);
1417 json_object_string_add(json_row, "pimDesignatedRouter",
1418 inet_ntoa(pim_ifp->pim_dr_addr));
1419
1420 if (pim_ifp->pim_dr_addr.s_addr
1421 == pim_ifp->primary_address.s_addr)
1422 json_object_boolean_true_add(
1423 json_row, "pimDesignatedRouterLocal");
1424
1425 json_object_object_add(json, ifp->name, json_row);
1426 }
1427
1428 if (uj) {
1429 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1430 json, JSON_C_TO_STRING_PRETTY));
1431 } else {
1432 vty_out(vty,
1433 "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
1434
1435 json_object_object_foreach(json, key, val)
1436 {
1437 vty_out(vty, "%-16s ", key);
1438
1439 json_object_object_get_ex(val, "state", &json_tmp);
1440 vty_out(vty, "%5s ", json_object_get_string(json_tmp));
1441
1442 json_object_object_get_ex(val, "address", &json_tmp);
1443 vty_out(vty, "%15s ",
1444 json_object_get_string(json_tmp));
1445
1446 json_object_object_get_ex(val, "pimNeighbors",
1447 &json_tmp);
1448 vty_out(vty, "%8d ", json_object_get_int(json_tmp));
1449
1450 if (json_object_object_get_ex(
1451 val, "pimDesignatedRouterLocal",
1452 &json_tmp)) {
1453 vty_out(vty, "%15s ", "local");
1454 } else {
1455 json_object_object_get_ex(
1456 val, "pimDesignatedRouter", &json_tmp);
1457 vty_out(vty, "%15s ",
1458 json_object_get_string(json_tmp));
1459 }
1460
1461 json_object_object_get_ex(val, "firstHopRouter",
1462 &json_tmp);
1463 vty_out(vty, "%3d ", json_object_get_int(json_tmp));
1464
1465 json_object_object_get_ex(val, "pimIfChannels",
1466 &json_tmp);
1467 vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
1468 }
1469 }
1470
1471 json_object_free(json);
1472 }
1473
1474 static void pim_show_interface_traffic(struct pim_instance *pim,
1475 struct vty *vty, bool uj)
1476 {
1477 struct interface *ifp = NULL;
1478 struct pim_interface *pim_ifp = NULL;
1479 json_object *json = NULL;
1480 json_object *json_row = NULL;
1481
1482 if (uj)
1483 json = json_object_new_object();
1484 else {
1485 vty_out(vty, "\n");
1486 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1487 "Interface", " HELLO", " JOIN",
1488 " PRUNE", " REGISTER", "REGISTER-STOP",
1489 " ASSERT", " BSM");
1490 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1491 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1492 " Rx/Tx", " Rx/Tx", " Rx/Tx",
1493 " Rx/Tx");
1494 vty_out(vty,
1495 "---------------------------------------------------------------------------------------------------------------\n");
1496 }
1497
1498 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1499 pim_ifp = ifp->info;
1500
1501 if (!pim_ifp)
1502 continue;
1503
1504 if (pim_ifp->pim_sock_fd < 0)
1505 continue;
1506 if (uj) {
1507 json_row = json_object_new_object();
1508 json_object_pim_ifp_add(json_row, ifp);
1509 json_object_int_add(json_row, "helloRx",
1510 pim_ifp->pim_ifstat_hello_recv);
1511 json_object_int_add(json_row, "helloTx",
1512 pim_ifp->pim_ifstat_hello_sent);
1513 json_object_int_add(json_row, "joinRx",
1514 pim_ifp->pim_ifstat_join_recv);
1515 json_object_int_add(json_row, "joinTx",
1516 pim_ifp->pim_ifstat_join_send);
1517 json_object_int_add(json_row, "registerRx",
1518 pim_ifp->pim_ifstat_reg_recv);
1519 json_object_int_add(json_row, "registerTx",
1520 pim_ifp->pim_ifstat_reg_recv);
1521 json_object_int_add(json_row, "registerStopRx",
1522 pim_ifp->pim_ifstat_reg_stop_recv);
1523 json_object_int_add(json_row, "registerStopTx",
1524 pim_ifp->pim_ifstat_reg_stop_send);
1525 json_object_int_add(json_row, "assertRx",
1526 pim_ifp->pim_ifstat_assert_recv);
1527 json_object_int_add(json_row, "assertTx",
1528 pim_ifp->pim_ifstat_assert_send);
1529 json_object_int_add(json_row, "bsmRx",
1530 pim_ifp->pim_ifstat_bsm_rx);
1531 json_object_int_add(json_row, "bsmTx",
1532 pim_ifp->pim_ifstat_bsm_tx);
1533 json_object_object_add(json, ifp->name, json_row);
1534 } else {
1535 vty_out(vty,
1536 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64 "/%-7" PRIu64 "\n",
1537 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1538 pim_ifp->pim_ifstat_hello_sent,
1539 pim_ifp->pim_ifstat_join_recv,
1540 pim_ifp->pim_ifstat_join_send,
1541 pim_ifp->pim_ifstat_prune_recv,
1542 pim_ifp->pim_ifstat_prune_send,
1543 pim_ifp->pim_ifstat_reg_recv,
1544 pim_ifp->pim_ifstat_reg_send,
1545 pim_ifp->pim_ifstat_reg_stop_recv,
1546 pim_ifp->pim_ifstat_reg_stop_send,
1547 pim_ifp->pim_ifstat_assert_recv,
1548 pim_ifp->pim_ifstat_assert_send,
1549 pim_ifp->pim_ifstat_bsm_rx,
1550 pim_ifp->pim_ifstat_bsm_tx);
1551 }
1552 }
1553 if (uj) {
1554 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1555 json, JSON_C_TO_STRING_PRETTY));
1556 json_object_free(json);
1557 }
1558 }
1559
1560 static void pim_show_interface_traffic_single(struct pim_instance *pim,
1561 struct vty *vty,
1562 const char *ifname, bool uj)
1563 {
1564 struct interface *ifp = NULL;
1565 struct pim_interface *pim_ifp = NULL;
1566 json_object *json = NULL;
1567 json_object *json_row = NULL;
1568 uint8_t found_ifname = 0;
1569
1570 if (uj)
1571 json = json_object_new_object();
1572 else {
1573 vty_out(vty, "\n");
1574 vty_out(vty, "%-16s%-17s%-17s%-17s%-17s%-17s%-17s%-17s\n",
1575 "Interface", " HELLO", " JOIN", " PRUNE",
1576 " REGISTER", " REGISTER-STOP", " ASSERT",
1577 " BSM");
1578 vty_out(vty, "%-14s%-18s%-17s%-17s%-17s%-17s%-17s%-17s\n", "",
1579 " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
1580 " Rx/Tx", " Rx/Tx", " Rx/Tx");
1581 vty_out(vty,
1582 "-------------------------------------------------------------------------------------------------------------------------------\n");
1583 }
1584
1585 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1586 if (strcmp(ifname, ifp->name))
1587 continue;
1588
1589 pim_ifp = ifp->info;
1590
1591 if (!pim_ifp)
1592 continue;
1593
1594 if (pim_ifp->pim_sock_fd < 0)
1595 continue;
1596
1597 found_ifname = 1;
1598 if (uj) {
1599 json_row = json_object_new_object();
1600 json_object_pim_ifp_add(json_row, ifp);
1601 json_object_int_add(json_row, "helloRx",
1602 pim_ifp->pim_ifstat_hello_recv);
1603 json_object_int_add(json_row, "helloTx",
1604 pim_ifp->pim_ifstat_hello_sent);
1605 json_object_int_add(json_row, "joinRx",
1606 pim_ifp->pim_ifstat_join_recv);
1607 json_object_int_add(json_row, "joinTx",
1608 pim_ifp->pim_ifstat_join_send);
1609 json_object_int_add(json_row, "registerRx",
1610 pim_ifp->pim_ifstat_reg_recv);
1611 json_object_int_add(json_row, "registerTx",
1612 pim_ifp->pim_ifstat_reg_recv);
1613 json_object_int_add(json_row, "registerStopRx",
1614 pim_ifp->pim_ifstat_reg_stop_recv);
1615 json_object_int_add(json_row, "registerStopTx",
1616 pim_ifp->pim_ifstat_reg_stop_send);
1617 json_object_int_add(json_row, "assertRx",
1618 pim_ifp->pim_ifstat_assert_recv);
1619 json_object_int_add(json_row, "assertTx",
1620 pim_ifp->pim_ifstat_assert_send);
1621 json_object_int_add(json_row, "bsmRx",
1622 pim_ifp->pim_ifstat_bsm_rx);
1623 json_object_int_add(json_row, "bsmTx",
1624 pim_ifp->pim_ifstat_bsm_tx);
1625
1626 json_object_object_add(json, ifp->name, json_row);
1627 } else {
1628 vty_out(vty,
1629 "%-16s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7" PRIu64 "/%-7" PRIu64 "\n",
1630 ifp->name, pim_ifp->pim_ifstat_hello_recv,
1631 pim_ifp->pim_ifstat_hello_sent,
1632 pim_ifp->pim_ifstat_join_recv,
1633 pim_ifp->pim_ifstat_join_send,
1634 pim_ifp->pim_ifstat_prune_recv,
1635 pim_ifp->pim_ifstat_prune_send,
1636 pim_ifp->pim_ifstat_reg_recv,
1637 pim_ifp->pim_ifstat_reg_send,
1638 pim_ifp->pim_ifstat_reg_stop_recv,
1639 pim_ifp->pim_ifstat_reg_stop_send,
1640 pim_ifp->pim_ifstat_assert_recv,
1641 pim_ifp->pim_ifstat_assert_send,
1642 pim_ifp->pim_ifstat_bsm_rx,
1643 pim_ifp->pim_ifstat_bsm_tx);
1644 }
1645 }
1646 if (uj) {
1647 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1648 json, JSON_C_TO_STRING_PRETTY));
1649 json_object_free(json);
1650 } else {
1651 if (!found_ifname)
1652 vty_out(vty, "%% No such interface\n");
1653 }
1654 }
1655
1656 static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
1657 struct pim_ifchannel *ch, json_object *json,
1658 time_t now, bool uj)
1659 {
1660 char ch_src_str[INET_ADDRSTRLEN];
1661 char ch_grp_str[INET_ADDRSTRLEN];
1662 json_object *json_iface = NULL;
1663 json_object *json_row = NULL;
1664 json_object *json_grp = NULL;
1665 struct in_addr ifaddr;
1666 char uptime[10];
1667 char expire[10];
1668 char prune[10];
1669
1670 ifaddr = pim_ifp->primary_address;
1671
1672 pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
1673 pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
1674
1675 pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
1676 pim_time_timer_to_mmss(expire, sizeof(expire),
1677 ch->t_ifjoin_expiry_timer);
1678 pim_time_timer_to_mmss(prune, sizeof(prune),
1679 ch->t_ifjoin_prune_pending_timer);
1680
1681 if (uj) {
1682 json_object_object_get_ex(json, ch->interface->name,
1683 &json_iface);
1684
1685 if (!json_iface) {
1686 json_iface = json_object_new_object();
1687 json_object_pim_ifp_add(json_iface, ch->interface);
1688 json_object_object_add(json, ch->interface->name,
1689 json_iface);
1690 }
1691
1692 json_row = json_object_new_object();
1693 json_object_string_add(json_row, "source", ch_src_str);
1694 json_object_string_add(json_row, "group", ch_grp_str);
1695 json_object_string_add(json_row, "upTime", uptime);
1696 json_object_string_add(json_row, "expire", expire);
1697 json_object_string_add(json_row, "prune", prune);
1698 json_object_string_add(
1699 json_row, "channelJoinName",
1700 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
1701 if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
1702 json_object_int_add(json_row, "SGRpt", 1);
1703
1704 json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
1705 if (!json_grp) {
1706 json_grp = json_object_new_object();
1707 json_object_object_add(json_grp, ch_src_str, json_row);
1708 json_object_object_add(json_iface, ch_grp_str,
1709 json_grp);
1710 } else
1711 json_object_object_add(json_grp, ch_src_str, json_row);
1712 } else {
1713 vty_out(vty, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
1714 ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
1715 ch_grp_str,
1716 pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
1717 uptime, expire, prune);
1718 }
1719 }
1720
1721 static void pim_show_join(struct pim_instance *pim, struct vty *vty,
1722 struct prefix_sg *sg, bool uj)
1723 {
1724 struct pim_interface *pim_ifp;
1725 struct pim_ifchannel *ch;
1726 struct interface *ifp;
1727 time_t now;
1728 json_object *json = NULL;
1729
1730 now = pim_time_monotonic_sec();
1731
1732 if (uj)
1733 json = json_object_new_object();
1734 else
1735 vty_out(vty,
1736 "Interface Address Source Group State Uptime Expire Prune\n");
1737
1738 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1739 pim_ifp = ifp->info;
1740 if (!pim_ifp)
1741 continue;
1742
1743 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
1744 if (sg->grp.s_addr != INADDR_ANY
1745 && sg->grp.s_addr != ch->sg.grp.s_addr)
1746 continue;
1747 if (sg->src.s_addr != INADDR_ANY
1748 && sg->src.s_addr != ch->sg.src.s_addr)
1749 continue;
1750 pim_show_join_helper(vty, pim_ifp, ch, json, now, uj);
1751 } /* scan interface channels */
1752 }
1753
1754 if (uj) {
1755 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1756 json, JSON_C_TO_STRING_PRETTY));
1757 json_object_free(json);
1758 }
1759 }
1760
1761 static void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
1762 const char *neighbor, bool uj)
1763 {
1764 struct listnode *neighnode;
1765 struct interface *ifp;
1766 struct pim_interface *pim_ifp;
1767 struct pim_neighbor *neigh;
1768 time_t now;
1769 int found_neighbor = 0;
1770 int option_address_list;
1771 int option_dr_priority;
1772 int option_generation_id;
1773 int option_holdtime;
1774 int option_lan_prune_delay;
1775 int option_t_bit;
1776 char uptime[10];
1777 char expire[10];
1778 char neigh_src_str[INET_ADDRSTRLEN];
1779
1780 json_object *json = NULL;
1781 json_object *json_ifp = NULL;
1782 json_object *json_row = NULL;
1783
1784 now = pim_time_monotonic_sec();
1785
1786 if (uj)
1787 json = json_object_new_object();
1788
1789 FOR_ALL_INTERFACES (pim->vrf, ifp) {
1790 pim_ifp = ifp->info;
1791
1792 if (!pim_ifp)
1793 continue;
1794
1795 if (pim_ifp->pim_sock_fd < 0)
1796 continue;
1797
1798 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
1799 neigh)) {
1800 pim_inet4_dump("<src?>", neigh->source_addr,
1801 neigh_src_str, sizeof(neigh_src_str));
1802
1803 /*
1804 * The user can specify either the interface name or the
1805 * PIM neighbor IP.
1806 * If this pim_ifp matches neither then skip.
1807 */
1808 if (strcmp(neighbor, "detail")
1809 && strcmp(neighbor, ifp->name)
1810 && strcmp(neighbor, neigh_src_str))
1811 continue;
1812
1813 found_neighbor = 1;
1814 pim_time_uptime(uptime, sizeof(uptime),
1815 now - neigh->creation);
1816 pim_time_timer_to_hhmmss(expire, sizeof(expire),
1817 neigh->t_expire_timer);
1818
1819 option_address_list = 0;
1820 option_dr_priority = 0;
1821 option_generation_id = 0;
1822 option_holdtime = 0;
1823 option_lan_prune_delay = 0;
1824 option_t_bit = 0;
1825
1826 if (PIM_OPTION_IS_SET(neigh->hello_options,
1827 PIM_OPTION_MASK_ADDRESS_LIST))
1828 option_address_list = 1;
1829
1830 if (PIM_OPTION_IS_SET(neigh->hello_options,
1831 PIM_OPTION_MASK_DR_PRIORITY))
1832 option_dr_priority = 1;
1833
1834 if (PIM_OPTION_IS_SET(neigh->hello_options,
1835 PIM_OPTION_MASK_GENERATION_ID))
1836 option_generation_id = 1;
1837
1838 if (PIM_OPTION_IS_SET(neigh->hello_options,
1839 PIM_OPTION_MASK_HOLDTIME))
1840 option_holdtime = 1;
1841
1842 if (PIM_OPTION_IS_SET(neigh->hello_options,
1843 PIM_OPTION_MASK_LAN_PRUNE_DELAY))
1844 option_lan_prune_delay = 1;
1845
1846 if (PIM_OPTION_IS_SET(
1847 neigh->hello_options,
1848 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
1849 option_t_bit = 1;
1850
1851 if (uj) {
1852
1853 /* Does this ifp live in json? If not create
1854 * it. */
1855 json_object_object_get_ex(json, ifp->name,
1856 &json_ifp);
1857
1858 if (!json_ifp) {
1859 json_ifp = json_object_new_object();
1860 json_object_pim_ifp_add(json_ifp, ifp);
1861 json_object_object_add(json, ifp->name,
1862 json_ifp);
1863 }
1864
1865 json_row = json_object_new_object();
1866 json_object_string_add(json_row, "interface",
1867 ifp->name);
1868 json_object_string_add(json_row, "address",
1869 neigh_src_str);
1870 json_object_string_add(json_row, "upTime",
1871 uptime);
1872 json_object_string_add(json_row, "holdtime",
1873 expire);
1874 json_object_int_add(json_row, "drPriority",
1875 neigh->dr_priority);
1876 json_object_int_add(json_row, "generationId",
1877 neigh->generation_id);
1878
1879 if (option_address_list)
1880 json_object_boolean_true_add(
1881 json_row,
1882 "helloOptionAddressList");
1883
1884 if (option_dr_priority)
1885 json_object_boolean_true_add(
1886 json_row,
1887 "helloOptionDrPriority");
1888
1889 if (option_generation_id)
1890 json_object_boolean_true_add(
1891 json_row,
1892 "helloOptionGenerationId");
1893
1894 if (option_holdtime)
1895 json_object_boolean_true_add(
1896 json_row,
1897 "helloOptionHoldtime");
1898
1899 if (option_lan_prune_delay)
1900 json_object_boolean_true_add(
1901 json_row,
1902 "helloOptionLanPruneDelay");
1903
1904 if (option_t_bit)
1905 json_object_boolean_true_add(
1906 json_row, "helloOptionTBit");
1907
1908 json_object_object_add(json_ifp, neigh_src_str,
1909 json_row);
1910
1911 } else {
1912 vty_out(vty, "Interface : %s\n", ifp->name);
1913 vty_out(vty, "Neighbor : %s\n", neigh_src_str);
1914 vty_out(vty,
1915 " Uptime : %s\n",
1916 uptime);
1917 vty_out(vty,
1918 " Holdtime : %s\n",
1919 expire);
1920 vty_out(vty,
1921 " DR Priority : %d\n",
1922 neigh->dr_priority);
1923 vty_out(vty,
1924 " Generation ID : %08x\n",
1925 neigh->generation_id);
1926 vty_out(vty,
1927 " Override Interval (msec) : %d\n",
1928 neigh->override_interval_msec);
1929 vty_out(vty,
1930 " Propagation Delay (msec) : %d\n",
1931 neigh->propagation_delay_msec);
1932 vty_out(vty,
1933 " Hello Option - Address List : %s\n",
1934 option_address_list ? "yes" : "no");
1935 vty_out(vty,
1936 " Hello Option - DR Priority : %s\n",
1937 option_dr_priority ? "yes" : "no");
1938 vty_out(vty,
1939 " Hello Option - Generation ID : %s\n",
1940 option_generation_id ? "yes" : "no");
1941 vty_out(vty,
1942 " Hello Option - Holdtime : %s\n",
1943 option_holdtime ? "yes" : "no");
1944 vty_out(vty,
1945 " Hello Option - LAN Prune Delay : %s\n",
1946 option_lan_prune_delay ? "yes" : "no");
1947 vty_out(vty,
1948 " Hello Option - T-bit : %s\n",
1949 option_t_bit ? "yes" : "no");
1950 pim_bfd_show_info(vty, neigh->bfd_info,
1951 json_ifp, uj, 0);
1952 vty_out(vty, "\n");
1953 }
1954 }
1955 }
1956
1957 if (uj) {
1958 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1959 json, JSON_C_TO_STRING_PRETTY));
1960 json_object_free(json);
1961 } else {
1962 {
1963 if (!found_neighbor)
1964 vty_out(vty,
1965 "%% No such interface or neighbor\n");
1966 }
1967 }
1968 }
1969
1970 static void pim_show_state(struct pim_instance *pim, struct vty *vty,
1971 const char *src_or_group, const char *group, bool uj)
1972 {
1973 struct channel_oil *c_oil;
1974 json_object *json = NULL;
1975 json_object *json_group = NULL;
1976 json_object *json_ifp_in = NULL;
1977 json_object *json_ifp_out = NULL;
1978 json_object *json_source = NULL;
1979 time_t now;
1980 int first_oif;
1981 now = pim_time_monotonic_sec();
1982
1983 if (uj) {
1984 json = json_object_new_object();
1985 } else {
1986 vty_out(vty,
1987 "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
1988 vty_out(vty,
1989 "\nActive Source Group RPT IIF OIL\n");
1990 }
1991
1992 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
1993 char grp_str[INET_ADDRSTRLEN];
1994 char src_str[INET_ADDRSTRLEN];
1995 char in_ifname[INTERFACE_NAMSIZ + 1];
1996 char out_ifname[INTERFACE_NAMSIZ + 1];
1997 int oif_vif_index;
1998 struct interface *ifp_in;
1999 bool isRpt;
2000 first_oif = 1;
2001
2002 if ((c_oil->up &&
2003 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil->up->flags)) ||
2004 c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
2005 isRpt = true;
2006 else
2007 isRpt = false;
2008
2009 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
2010 sizeof(grp_str));
2011 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
2012 sizeof(src_str));
2013 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
2014
2015 if (ifp_in)
2016 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
2017 else
2018 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
2019
2020 if (src_or_group) {
2021 if (strcmp(src_or_group, src_str)
2022 && strcmp(src_or_group, grp_str))
2023 continue;
2024
2025 if (group && strcmp(group, grp_str))
2026 continue;
2027 }
2028
2029 if (uj) {
2030
2031 /* Find the group, create it if it doesn't exist */
2032 json_object_object_get_ex(json, grp_str, &json_group);
2033
2034 if (!json_group) {
2035 json_group = json_object_new_object();
2036 json_object_object_add(json, grp_str,
2037 json_group);
2038 }
2039
2040 /* Find the source nested under the group, create it if
2041 * it doesn't exist */
2042 json_object_object_get_ex(json_group, src_str,
2043 &json_source);
2044
2045 if (!json_source) {
2046 json_source = json_object_new_object();
2047 json_object_object_add(json_group, src_str,
2048 json_source);
2049 }
2050
2051 /* Find the inbound interface nested under the source,
2052 * create it if it doesn't exist */
2053 json_object_object_get_ex(json_source, in_ifname,
2054 &json_ifp_in);
2055
2056 if (!json_ifp_in) {
2057 json_ifp_in = json_object_new_object();
2058 json_object_object_add(json_source, in_ifname,
2059 json_ifp_in);
2060 json_object_int_add(json_source, "Installed",
2061 c_oil->installed);
2062 if (isRpt)
2063 json_object_boolean_true_add(
2064 json_source, "isRpt");
2065 else
2066 json_object_boolean_false_add(
2067 json_source, "isRpt");
2068 json_object_int_add(json_source, "RefCount",
2069 c_oil->oil_ref_count);
2070 json_object_int_add(json_source, "OilListSize",
2071 c_oil->oil_size);
2072 json_object_int_add(
2073 json_source, "OilRescan",
2074 c_oil->oil_inherited_rescan);
2075 json_object_int_add(json_source, "LastUsed",
2076 c_oil->cc.lastused);
2077 json_object_int_add(json_source, "PacketCount",
2078 c_oil->cc.pktcnt);
2079 json_object_int_add(json_source, "ByteCount",
2080 c_oil->cc.bytecnt);
2081 json_object_int_add(json_source,
2082 "WrongInterface",
2083 c_oil->cc.wrong_if);
2084 }
2085 } else {
2086 vty_out(vty, "%-6d %-15s %-15s %-3s %-16s ",
2087 c_oil->installed, src_str, grp_str,
2088 isRpt ? "y" : "n", in_ifname);
2089 }
2090
2091 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
2092 ++oif_vif_index) {
2093 struct interface *ifp_out;
2094 char oif_uptime[10];
2095 int ttl;
2096
2097 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2098 if (ttl < 1)
2099 continue;
2100
2101 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
2102 pim_time_uptime(
2103 oif_uptime, sizeof(oif_uptime),
2104 now - c_oil->oif_creation[oif_vif_index]);
2105
2106 if (ifp_out)
2107 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
2108 else
2109 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
2110
2111 if (uj) {
2112 json_ifp_out = json_object_new_object();
2113 json_object_string_add(json_ifp_out, "source",
2114 src_str);
2115 json_object_string_add(json_ifp_out, "group",
2116 grp_str);
2117 json_object_string_add(json_ifp_out,
2118 "inboundInterface",
2119 in_ifname);
2120 json_object_string_add(json_ifp_out,
2121 "outboundInterface",
2122 out_ifname);
2123 json_object_int_add(json_ifp_out, "installed",
2124 c_oil->installed);
2125
2126 json_object_object_add(json_ifp_in, out_ifname,
2127 json_ifp_out);
2128 } else {
2129 if (first_oif) {
2130 first_oif = 0;
2131 vty_out(vty, "%s(%c%c%c%c%c)",
2132 out_ifname,
2133 (c_oil->oif_flags[oif_vif_index]
2134 & PIM_OIF_FLAG_PROTO_IGMP)
2135 ? 'I'
2136 : ' ',
2137 (c_oil->oif_flags[oif_vif_index]
2138 & PIM_OIF_FLAG_PROTO_PIM)
2139 ? 'J'
2140 : ' ',
2141 (c_oil->oif_flags[oif_vif_index]
2142 & PIM_OIF_FLAG_PROTO_VXLAN)
2143 ? 'V'
2144 : ' ',
2145 (c_oil->oif_flags[oif_vif_index]
2146 & PIM_OIF_FLAG_PROTO_STAR)
2147 ? '*'
2148 : ' ',
2149 (c_oil->oif_flags[oif_vif_index]
2150 & PIM_OIF_FLAG_MUTE)
2151 ? 'M'
2152 : ' ');
2153 } else
2154 vty_out(vty, ", %s(%c%c%c%c%c)",
2155 out_ifname,
2156 (c_oil->oif_flags[oif_vif_index]
2157 & PIM_OIF_FLAG_PROTO_IGMP)
2158 ? 'I'
2159 : ' ',
2160 (c_oil->oif_flags[oif_vif_index]
2161 & PIM_OIF_FLAG_PROTO_PIM)
2162 ? 'J'
2163 : ' ',
2164 (c_oil->oif_flags[oif_vif_index]
2165 & PIM_OIF_FLAG_PROTO_VXLAN)
2166 ? 'V'
2167 : ' ',
2168 (c_oil->oif_flags[oif_vif_index]
2169 & PIM_OIF_FLAG_PROTO_STAR)
2170 ? '*'
2171 : ' ',
2172 (c_oil->oif_flags[oif_vif_index]
2173 & PIM_OIF_FLAG_MUTE)
2174 ? 'M'
2175 : ' ');
2176 }
2177 }
2178
2179 if (!uj)
2180 vty_out(vty, "\n");
2181 }
2182
2183
2184 if (uj) {
2185 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2186 json, JSON_C_TO_STRING_PRETTY));
2187 json_object_free(json);
2188 } else {
2189 vty_out(vty, "\n");
2190 }
2191 }
2192
2193 static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
2194 bool uj)
2195 {
2196 struct listnode *neighnode;
2197 struct interface *ifp;
2198 struct pim_interface *pim_ifp;
2199 struct pim_neighbor *neigh;
2200 time_t now;
2201 char uptime[10];
2202 char expire[10];
2203 char neigh_src_str[INET_ADDRSTRLEN];
2204 json_object *json = NULL;
2205 json_object *json_ifp_rows = NULL;
2206 json_object *json_row = NULL;
2207
2208 now = pim_time_monotonic_sec();
2209
2210 if (uj) {
2211 json = json_object_new_object();
2212 } else {
2213 vty_out(vty,
2214 "Interface Neighbor Uptime Holdtime DR Pri\n");
2215 }
2216
2217 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2218 pim_ifp = ifp->info;
2219
2220 if (!pim_ifp)
2221 continue;
2222
2223 if (pim_ifp->pim_sock_fd < 0)
2224 continue;
2225
2226 if (uj)
2227 json_ifp_rows = json_object_new_object();
2228
2229 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2230 neigh)) {
2231 pim_inet4_dump("<src?>", neigh->source_addr,
2232 neigh_src_str, sizeof(neigh_src_str));
2233 pim_time_uptime(uptime, sizeof(uptime),
2234 now - neigh->creation);
2235 pim_time_timer_to_hhmmss(expire, sizeof(expire),
2236 neigh->t_expire_timer);
2237
2238 if (uj) {
2239 json_row = json_object_new_object();
2240 json_object_string_add(json_row, "interface",
2241 ifp->name);
2242 json_object_string_add(json_row, "neighbor",
2243 neigh_src_str);
2244 json_object_string_add(json_row, "upTime",
2245 uptime);
2246 json_object_string_add(json_row, "holdTime",
2247 expire);
2248 json_object_int_add(json_row, "holdTimeMax",
2249 neigh->holdtime);
2250 json_object_int_add(json_row, "drPriority",
2251 neigh->dr_priority);
2252 json_object_object_add(json_ifp_rows,
2253 neigh_src_str, json_row);
2254
2255 } else {
2256 vty_out(vty, "%-16s %15s %8s %8s %6d\n",
2257 ifp->name, neigh_src_str, uptime,
2258 expire, neigh->dr_priority);
2259 }
2260 }
2261
2262 if (uj) {
2263 json_object_object_add(json, ifp->name, json_ifp_rows);
2264 json_ifp_rows = NULL;
2265 }
2266 }
2267
2268 if (uj) {
2269 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2270 json, JSON_C_TO_STRING_PRETTY));
2271 json_object_free(json);
2272 }
2273 }
2274
2275 static void pim_show_neighbors_secondary(struct pim_instance *pim,
2276 struct vty *vty)
2277 {
2278 struct interface *ifp;
2279
2280 vty_out(vty,
2281 "Interface Address Neighbor Secondary \n");
2282
2283 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2284 struct pim_interface *pim_ifp;
2285 struct in_addr ifaddr;
2286 struct listnode *neighnode;
2287 struct pim_neighbor *neigh;
2288
2289 pim_ifp = ifp->info;
2290
2291 if (!pim_ifp)
2292 continue;
2293
2294 if (pim_ifp->pim_sock_fd < 0)
2295 continue;
2296
2297 ifaddr = pim_ifp->primary_address;
2298
2299 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2300 neigh)) {
2301 char neigh_src_str[INET_ADDRSTRLEN];
2302 struct listnode *prefix_node;
2303 struct prefix *p;
2304
2305 if (!neigh->prefix_list)
2306 continue;
2307
2308 pim_inet4_dump("<src?>", neigh->source_addr,
2309 neigh_src_str, sizeof(neigh_src_str));
2310
2311 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
2312 prefix_node, p)) {
2313 char neigh_sec_str[PREFIX2STR_BUFFER];
2314
2315 prefix2str(p, neigh_sec_str,
2316 sizeof(neigh_sec_str));
2317
2318 vty_out(vty, "%-16s %-15s %-15s %-15s\n",
2319 ifp->name, inet_ntoa(ifaddr),
2320 neigh_src_str, neigh_sec_str);
2321 }
2322 }
2323 }
2324 }
2325
2326 static void json_object_pim_upstream_add(json_object *json,
2327 struct pim_upstream *up)
2328 {
2329 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
2330 json_object_boolean_true_add(json, "drJoinDesired");
2331
2332 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
2333 json_object_boolean_true_add(json, "drJoinDesiredUpdated");
2334
2335 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
2336 json_object_boolean_true_add(json, "firstHopRouter");
2337
2338 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
2339 json_object_boolean_true_add(json, "sourceIgmp");
2340
2341 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
2342 json_object_boolean_true_add(json, "sourcePim");
2343
2344 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
2345 json_object_boolean_true_add(json, "sourceStream");
2346
2347 /* XXX: need to print ths flag in the plain text display as well */
2348 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
2349 json_object_boolean_true_add(json, "sourceMsdp");
2350
2351 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
2352 json_object_boolean_true_add(json, "sendSGRptPrune");
2353
2354 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
2355 json_object_boolean_true_add(json, "lastHopRouter");
2356
2357 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY)
2358 json_object_boolean_true_add(json, "disableKATExpiry");
2359
2360 if (up->flags & PIM_UPSTREAM_FLAG_MASK_STATIC_IIF)
2361 json_object_boolean_true_add(json, "staticIncomingInterface");
2362
2363 if (up->flags & PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL)
2364 json_object_boolean_true_add(json,
2365 "allowIncomingInterfaceinOil");
2366
2367 if (up->flags & PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA)
2368 json_object_boolean_true_add(json, "noPimRegistrationData");
2369
2370 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG)
2371 json_object_boolean_true_add(json, "forcePimRegistration");
2372
2373 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG)
2374 json_object_boolean_true_add(json, "sourceVxlanOrigination");
2375
2376 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
2377 json_object_boolean_true_add(json, "sourceVxlanTermination");
2378
2379 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
2380 json_object_boolean_true_add(json, "mlagVxlan");
2381
2382 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
2383 json_object_boolean_true_add(json,
2384 "mlagNonDesignatedForwarder");
2385 }
2386
2387 static const char *
2388 pim_upstream_state2brief_str(enum pim_upstream_state join_state,
2389 char *state_str, size_t state_str_len)
2390 {
2391 switch (join_state) {
2392 case PIM_UPSTREAM_NOTJOINED:
2393 strlcpy(state_str, "NotJ", state_str_len);
2394 break;
2395 case PIM_UPSTREAM_JOINED:
2396 strlcpy(state_str, "J", state_str_len);
2397 break;
2398 default:
2399 strlcpy(state_str, "Unk", state_str_len);
2400 }
2401 return state_str;
2402 }
2403
2404 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
2405 char *state_str, size_t state_str_len)
2406 {
2407 switch (reg_state) {
2408 case PIM_REG_NOINFO:
2409 strlcpy(state_str, "RegNI", state_str_len);
2410 break;
2411 case PIM_REG_JOIN:
2412 strlcpy(state_str, "RegJ", state_str_len);
2413 break;
2414 case PIM_REG_JOIN_PENDING:
2415 case PIM_REG_PRUNE:
2416 strlcpy(state_str, "RegP", state_str_len);
2417 break;
2418 default:
2419 strlcpy(state_str, "Unk", state_str_len);
2420 }
2421 return state_str;
2422 }
2423
2424 static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
2425 struct prefix_sg *sg, bool uj)
2426 {
2427 struct pim_upstream *up;
2428 time_t now;
2429 json_object *json = NULL;
2430 json_object *json_group = NULL;
2431 json_object *json_row = NULL;
2432
2433 now = pim_time_monotonic_sec();
2434
2435 if (uj)
2436 json = json_object_new_object();
2437 else
2438 vty_out(vty,
2439 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2440
2441 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
2442 char src_str[INET_ADDRSTRLEN];
2443 char grp_str[INET_ADDRSTRLEN];
2444 char uptime[10];
2445 char join_timer[10];
2446 char rs_timer[10];
2447 char ka_timer[10];
2448 char msdp_reg_timer[10];
2449 char state_str[PIM_REG_STATE_STR_LEN];
2450
2451 if (sg->grp.s_addr != INADDR_ANY
2452 && sg->grp.s_addr != up->sg.grp.s_addr)
2453 continue;
2454 if (sg->src.s_addr != INADDR_ANY
2455 && sg->src.s_addr != up->sg.src.s_addr)
2456 continue;
2457
2458 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2459 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2460 pim_time_uptime(uptime, sizeof(uptime),
2461 now - up->state_transition);
2462 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
2463 up->t_join_timer);
2464
2465 /*
2466 * If the upstream is not dummy and it has a J/P timer for the
2467 * neighbor display that
2468 */
2469 if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
2470 struct pim_neighbor *nbr;
2471
2472 nbr = pim_neighbor_find(
2473 up->rpf.source_nexthop.interface,
2474 up->rpf.rpf_addr.u.prefix4);
2475 if (nbr)
2476 pim_time_timer_to_hhmmss(join_timer,
2477 sizeof(join_timer),
2478 nbr->jp_timer);
2479 }
2480
2481 pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
2482 up->t_rs_timer);
2483 pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
2484 up->t_ka_timer);
2485 pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
2486 up->t_msdp_reg_timer);
2487
2488 pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str));
2489 if (up->reg_state != PIM_REG_NOINFO) {
2490 char tmp_str[PIM_REG_STATE_STR_LEN];
2491
2492 sprintf(state_str + strlen(state_str), ",%s",
2493 pim_reg_state2brief_str(up->reg_state, tmp_str,
2494 sizeof(tmp_str)));
2495 }
2496
2497 if (uj) {
2498 json_object_object_get_ex(json, grp_str, &json_group);
2499
2500 if (!json_group) {
2501 json_group = json_object_new_object();
2502 json_object_object_add(json, grp_str,
2503 json_group);
2504 }
2505
2506 json_row = json_object_new_object();
2507 json_object_pim_upstream_add(json_row, up);
2508 json_object_string_add(
2509 json_row, "inboundInterface",
2510 up->rpf.source_nexthop.interface
2511 ? up->rpf.source_nexthop.interface->name
2512 : "Unknown");
2513
2514 /*
2515 * The RPF address we use is slightly different
2516 * based upon what we are looking up.
2517 * If we have a S, list that unless
2518 * we are the FHR, else we just put
2519 * the RP as the rpfAddress
2520 */
2521 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR
2522 || up->sg.src.s_addr == INADDR_ANY) {
2523 char rpf[PREFIX_STRLEN];
2524 struct pim_rpf *rpg;
2525
2526 rpg = RP(pim, up->sg.grp);
2527 pim_inet4_dump("<rpf?>",
2528 rpg->rpf_addr.u.prefix4, rpf,
2529 sizeof(rpf));
2530 json_object_string_add(json_row, "rpfAddress",
2531 rpf);
2532 } else {
2533 json_object_string_add(json_row, "rpfAddress",
2534 src_str);
2535 }
2536
2537 json_object_string_add(json_row, "source", src_str);
2538 json_object_string_add(json_row, "group", grp_str);
2539 json_object_string_add(json_row, "state", state_str);
2540 json_object_string_add(
2541 json_row, "joinState",
2542 pim_upstream_state2str(up->join_state));
2543 json_object_string_add(
2544 json_row, "regState",
2545 pim_reg_state2str(up->reg_state, state_str, sizeof(state_str)));
2546 json_object_string_add(json_row, "upTime", uptime);
2547 json_object_string_add(json_row, "joinTimer",
2548 join_timer);
2549 json_object_string_add(json_row, "resetTimer",
2550 rs_timer);
2551 json_object_string_add(json_row, "keepaliveTimer",
2552 ka_timer);
2553 json_object_string_add(json_row, "msdpRegTimer",
2554 msdp_reg_timer);
2555 json_object_int_add(json_row, "refCount",
2556 up->ref_count);
2557 json_object_int_add(json_row, "sptBit", up->sptbit);
2558 json_object_object_add(json_group, src_str, json_row);
2559 } else {
2560 vty_out(vty,
2561 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2562 up->rpf.source_nexthop.interface
2563 ? up->rpf.source_nexthop.interface->name
2564 : "Unknown",
2565 src_str, grp_str, state_str, uptime, join_timer,
2566 rs_timer, ka_timer, up->ref_count);
2567 }
2568 }
2569
2570 if (uj) {
2571 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2572 json, JSON_C_TO_STRING_PRETTY));
2573 json_object_free(json);
2574 }
2575 }
2576
2577 static void pim_show_channel_helper(struct pim_instance *pim,
2578 struct vty *vty,
2579 struct pim_interface *pim_ifp,
2580 struct pim_ifchannel *ch,
2581 json_object *json, bool uj)
2582 {
2583 struct pim_upstream *up = ch->upstream;
2584 json_object *json_group = NULL;
2585 char src_str[INET_ADDRSTRLEN];
2586 char grp_str[INET_ADDRSTRLEN];
2587 json_object *json_row = NULL;
2588
2589 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2590 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2591
2592 if (uj) {
2593 json_object_object_get_ex(json, grp_str, &json_group);
2594
2595 if (!json_group) {
2596 json_group = json_object_new_object();
2597 json_object_object_add(json, grp_str, json_group);
2598 }
2599
2600 json_row = json_object_new_object();
2601 json_object_pim_upstream_add(json_row, up);
2602 json_object_string_add(json_row, "interface",
2603 ch->interface->name);
2604 json_object_string_add(json_row, "source", src_str);
2605 json_object_string_add(json_row, "group", grp_str);
2606
2607 if (pim_macro_ch_lost_assert(ch))
2608 json_object_boolean_true_add(json_row, "lostAssert");
2609
2610 if (pim_macro_chisin_joins(ch))
2611 json_object_boolean_true_add(json_row, "joins");
2612
2613 if (pim_macro_chisin_pim_include(ch))
2614 json_object_boolean_true_add(json_row, "pimInclude");
2615
2616 if (pim_upstream_evaluate_join_desired(pim, up))
2617 json_object_boolean_true_add(json_row,
2618 "evaluateJoinDesired");
2619
2620 json_object_object_add(json_group, src_str, json_row);
2621
2622 } else {
2623 vty_out(vty, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2624 ch->interface->name, src_str, grp_str,
2625 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2626 pim_macro_chisin_joins(ch) ? "yes" : "no",
2627 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
2628 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
2629 ? "yes"
2630 : "no",
2631 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2632 : "no");
2633 }
2634 }
2635
2636 static void pim_show_channel(struct pim_instance *pim, struct vty *vty,
2637 bool uj)
2638 {
2639 struct pim_interface *pim_ifp;
2640 struct pim_ifchannel *ch;
2641 struct interface *ifp;
2642
2643 json_object *json = NULL;
2644
2645 if (uj)
2646 json = json_object_new_object();
2647 else
2648 vty_out(vty,
2649 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2650
2651 /* scan per-interface (S,G) state */
2652 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2653 pim_ifp = ifp->info;
2654 if (!pim_ifp)
2655 continue;
2656
2657
2658 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
2659 /* scan all interfaces */
2660 pim_show_channel_helper(pim, vty, pim_ifp, ch,
2661 json, uj);
2662 }
2663 }
2664
2665 if (uj) {
2666 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2667 json, JSON_C_TO_STRING_PRETTY));
2668 json_object_free(json);
2669 }
2670 }
2671
2672 static void pim_show_join_desired_helper(struct pim_instance *pim,
2673 struct vty *vty,
2674 struct pim_upstream *up,
2675 json_object *json, bool uj)
2676 {
2677 json_object *json_group = NULL;
2678 char src_str[INET_ADDRSTRLEN];
2679 char grp_str[INET_ADDRSTRLEN];
2680 json_object *json_row = NULL;
2681
2682 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2683 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2684
2685 if (uj) {
2686 json_object_object_get_ex(json, grp_str, &json_group);
2687
2688 if (!json_group) {
2689 json_group = json_object_new_object();
2690 json_object_object_add(json, grp_str, json_group);
2691 }
2692
2693 json_row = json_object_new_object();
2694 json_object_pim_upstream_add(json_row, up);
2695 json_object_string_add(json_row, "source", src_str);
2696 json_object_string_add(json_row, "group", grp_str);
2697
2698 if (pim_upstream_evaluate_join_desired(pim, up))
2699 json_object_boolean_true_add(json_row,
2700 "evaluateJoinDesired");
2701
2702 json_object_object_add(json_group, src_str, json_row);
2703
2704 } else {
2705 vty_out(vty, "%-15s %-15s %-6s\n",
2706 src_str, grp_str,
2707 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2708 : "no");
2709 }
2710 }
2711
2712 static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
2713 bool uj)
2714 {
2715 struct pim_upstream *up;
2716
2717 json_object *json = NULL;
2718
2719 if (uj)
2720 json = json_object_new_object();
2721 else
2722 vty_out(vty,
2723 "Source Group EvalJD\n");
2724
2725 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
2726 /* scan all interfaces */
2727 pim_show_join_desired_helper(pim, vty, up,
2728 json, uj);
2729 }
2730
2731 if (uj) {
2732 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2733 json, JSON_C_TO_STRING_PRETTY));
2734 json_object_free(json);
2735 }
2736 }
2737
2738 static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
2739 bool uj)
2740 {
2741 struct pim_upstream *up;
2742 json_object *json = NULL;
2743 json_object *json_group = NULL;
2744 json_object *json_row = NULL;
2745
2746 if (uj)
2747 json = json_object_new_object();
2748 else
2749 vty_out(vty,
2750 "Source Group RpfIface RibNextHop RpfAddress \n");
2751
2752 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
2753 char src_str[INET_ADDRSTRLEN];
2754 char grp_str[INET_ADDRSTRLEN];
2755 char rpf_nexthop_str[PREFIX_STRLEN];
2756 char rpf_addr_str[PREFIX_STRLEN];
2757 struct pim_rpf *rpf;
2758 const char *rpf_ifname;
2759
2760 rpf = &up->rpf;
2761
2762 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2763 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2764 pim_addr_dump("<nexthop?>",
2765 &rpf->source_nexthop.mrib_nexthop_addr,
2766 rpf_nexthop_str, sizeof(rpf_nexthop_str));
2767 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2768 sizeof(rpf_addr_str));
2769
2770 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
2771
2772 if (uj) {
2773 json_object_object_get_ex(json, grp_str, &json_group);
2774
2775 if (!json_group) {
2776 json_group = json_object_new_object();
2777 json_object_object_add(json, grp_str,
2778 json_group);
2779 }
2780
2781 json_row = json_object_new_object();
2782 json_object_pim_upstream_add(json_row, up);
2783 json_object_string_add(json_row, "source", src_str);
2784 json_object_string_add(json_row, "group", grp_str);
2785 json_object_string_add(json_row, "rpfInterface",
2786 rpf_ifname);
2787 json_object_string_add(json_row, "ribNexthop",
2788 rpf_nexthop_str);
2789 json_object_string_add(json_row, "rpfAddress",
2790 rpf_addr_str);
2791 json_object_object_add(json_group, src_str, json_row);
2792 } else {
2793 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s\n", src_str,
2794 grp_str, rpf_ifname, rpf_nexthop_str,
2795 rpf_addr_str);
2796 }
2797 }
2798
2799 if (uj) {
2800 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2801 json, JSON_C_TO_STRING_PRETTY));
2802 json_object_free(json);
2803 }
2804 }
2805
2806 static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
2807 time_t now, json_object *json)
2808 {
2809 char refresh_uptime[10];
2810
2811 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
2812 pim->rpf_cache_refresh_last);
2813
2814 if (json) {
2815 json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
2816 router->rpf_cache_refresh_delay_msec);
2817 json_object_int_add(
2818 json, "rpfCacheRefreshTimer",
2819 pim_time_timer_remain_msec(pim->rpf_cache_refresher));
2820 json_object_int_add(json, "rpfCacheRefreshRequests",
2821 pim->rpf_cache_refresh_requests);
2822 json_object_int_add(json, "rpfCacheRefreshEvents",
2823 pim->rpf_cache_refresh_events);
2824 json_object_string_add(json, "rpfCacheRefreshLast",
2825 refresh_uptime);
2826 json_object_int_add(json, "nexthopLookups",
2827 pim->nexthop_lookups);
2828 json_object_int_add(json, "nexthopLookupsAvoided",
2829 pim->nexthop_lookups_avoided);
2830 } else {
2831 vty_out(vty,
2832 "RPF Cache Refresh Delay: %ld msecs\n"
2833 "RPF Cache Refresh Timer: %ld msecs\n"
2834 "RPF Cache Refresh Requests: %lld\n"
2835 "RPF Cache Refresh Events: %lld\n"
2836 "RPF Cache Refresh Last: %s\n"
2837 "Nexthop Lookups: %lld\n"
2838 "Nexthop Lookups Avoided: %lld\n",
2839 router->rpf_cache_refresh_delay_msec,
2840 pim_time_timer_remain_msec(pim->rpf_cache_refresher),
2841 (long long)pim->rpf_cache_refresh_requests,
2842 (long long)pim->rpf_cache_refresh_events,
2843 refresh_uptime, (long long)pim->nexthop_lookups,
2844 (long long)pim->nexthop_lookups_avoided);
2845 }
2846 }
2847
2848 static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
2849 time_t now)
2850 {
2851 char uptime_scan_oil[10];
2852 char uptime_mroute_add[10];
2853 char uptime_mroute_del[10];
2854
2855 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
2856 pim->scan_oil_last);
2857 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
2858 pim->mroute_add_last);
2859 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
2860 pim->mroute_del_last);
2861
2862 vty_out(vty,
2863 "Scan OIL - Last: %s Events: %lld\n"
2864 "MFC Add - Last: %s Events: %lld\n"
2865 "MFC Del - Last: %s Events: %lld\n",
2866 uptime_scan_oil, (long long)pim->scan_oil_events,
2867 uptime_mroute_add, (long long)pim->mroute_add_events,
2868 uptime_mroute_del, (long long)pim->mroute_del_events);
2869 }
2870
2871 static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
2872 {
2873 struct pim_upstream *up;
2874 time_t now = pim_time_monotonic_sec();
2875 json_object *json = NULL;
2876 json_object *json_group = NULL;
2877 json_object *json_row = NULL;
2878
2879 if (uj) {
2880 json = json_object_new_object();
2881 show_rpf_refresh_stats(vty, pim, now, json);
2882 } else {
2883 show_rpf_refresh_stats(vty, pim, now, json);
2884 vty_out(vty, "\n");
2885 vty_out(vty,
2886 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2887 }
2888
2889 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
2890 char src_str[INET_ADDRSTRLEN];
2891 char grp_str[INET_ADDRSTRLEN];
2892 char rpf_addr_str[PREFIX_STRLEN];
2893 char rib_nexthop_str[PREFIX_STRLEN];
2894 const char *rpf_ifname;
2895 struct pim_rpf *rpf = &up->rpf;
2896
2897 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2898 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2899 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2900 sizeof(rpf_addr_str));
2901 pim_addr_dump("<nexthop?>",
2902 &rpf->source_nexthop.mrib_nexthop_addr,
2903 rib_nexthop_str, sizeof(rib_nexthop_str));
2904
2905 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
2906
2907 if (uj) {
2908 json_object_object_get_ex(json, grp_str, &json_group);
2909
2910 if (!json_group) {
2911 json_group = json_object_new_object();
2912 json_object_object_add(json, grp_str,
2913 json_group);
2914 }
2915
2916 json_row = json_object_new_object();
2917 json_object_string_add(json_row, "source", src_str);
2918 json_object_string_add(json_row, "group", grp_str);
2919 json_object_string_add(json_row, "rpfInterface",
2920 rpf_ifname);
2921 json_object_string_add(json_row, "rpfAddress",
2922 rpf_addr_str);
2923 json_object_string_add(json_row, "ribNexthop",
2924 rib_nexthop_str);
2925 json_object_int_add(
2926 json_row, "routeMetric",
2927 rpf->source_nexthop.mrib_route_metric);
2928 json_object_int_add(
2929 json_row, "routePreference",
2930 rpf->source_nexthop.mrib_metric_preference);
2931 json_object_object_add(json_group, src_str, json_row);
2932
2933 } else {
2934 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2935 src_str, grp_str, rpf_ifname, rpf_addr_str,
2936 rib_nexthop_str,
2937 rpf->source_nexthop.mrib_route_metric,
2938 rpf->source_nexthop.mrib_metric_preference);
2939 }
2940 }
2941
2942 if (uj) {
2943 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2944 json, JSON_C_TO_STRING_PRETTY));
2945 json_object_free(json);
2946 }
2947 }
2948
2949 struct pnc_cache_walk_data {
2950 struct vty *vty;
2951 struct pim_instance *pim;
2952 };
2953
2954 static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
2955 {
2956 struct pim_nexthop_cache *pnc = bucket->data;
2957 struct pnc_cache_walk_data *cwd = arg;
2958 struct vty *vty = cwd->vty;
2959 struct pim_instance *pim = cwd->pim;
2960 struct nexthop *nh_node = NULL;
2961 ifindex_t first_ifindex;
2962 struct interface *ifp = NULL;
2963
2964 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
2965 first_ifindex = nh_node->ifindex;
2966 ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
2967
2968 vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
2969 vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
2970 vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
2971 vty_out(vty, "\n");
2972 }
2973 return CMD_SUCCESS;
2974 }
2975
2976 static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
2977 {
2978 struct pnc_cache_walk_data cwd;
2979
2980 cwd.vty = vty;
2981 cwd.pim = pim;
2982 vty_out(vty, "Number of registered addresses: %lu\n",
2983 pim->rpf_hash->count);
2984 vty_out(vty, "Address Interface Nexthop\n");
2985 vty_out(vty, "---------------------------------------------\n");
2986
2987 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
2988 }
2989
2990 /* Display the bsm database details */
2991 static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
2992 {
2993 struct listnode *bsmnode;
2994 int count = 0;
2995 int fragment = 1;
2996 struct bsm_info *bsm;
2997 json_object *json = NULL;
2998 json_object *json_group = NULL;
2999 json_object *json_row = NULL;
3000
3001 count = pim->global_scope.bsm_list->count;
3002
3003 if (uj) {
3004 json = json_object_new_object();
3005 json_object_int_add(json, "Number of the fragments", count);
3006 } else {
3007 vty_out(vty, "Scope Zone: Global\n");
3008 vty_out(vty, "Number of the fragments: %d\n", count);
3009 vty_out(vty, "\n");
3010 }
3011
3012 for (ALL_LIST_ELEMENTS_RO(pim->global_scope.bsm_list, bsmnode, bsm)) {
3013 char grp_str[INET_ADDRSTRLEN];
3014 char rp_str[INET_ADDRSTRLEN];
3015 char bsr_str[INET_ADDRSTRLEN];
3016 struct bsmmsg_grpinfo *group;
3017 struct bsmmsg_rpinfo *rpaddr;
3018 struct prefix grp;
3019 struct bsm_hdr *hdr;
3020 uint32_t offset = 0;
3021 uint8_t *buf;
3022 uint32_t len = 0;
3023 uint32_t frag_rp_cnt = 0;
3024
3025 buf = bsm->bsm;
3026 len = bsm->size;
3027
3028 /* skip pim header */
3029 buf += PIM_MSG_HEADER_LEN;
3030 len -= PIM_MSG_HEADER_LEN;
3031
3032 hdr = (struct bsm_hdr *)buf;
3033
3034 /* BSM starts with bsr header */
3035 buf += sizeof(struct bsm_hdr);
3036 len -= sizeof(struct bsm_hdr);
3037
3038 pim_inet4_dump("<BSR Address?>", hdr->bsr_addr.addr, bsr_str,
3039 sizeof(bsr_str));
3040
3041
3042 if (uj) {
3043 json_object_string_add(json, "BSR address", bsr_str);
3044 json_object_int_add(json, "BSR priority",
3045 hdr->bsr_prio);
3046 json_object_int_add(json, "Hashmask Length",
3047 hdr->hm_len);
3048 json_object_int_add(json, "Fragment Tag",
3049 ntohs(hdr->frag_tag));
3050 } else {
3051 vty_out(vty, "BSM Fragment : %d\n", fragment);
3052 vty_out(vty, "------------------\n");
3053 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3054 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3055 vty_out(vty, "%-15s %-15d %-15d %-15d\n", bsr_str,
3056 hdr->bsr_prio, hdr->hm_len,
3057 ntohs(hdr->frag_tag));
3058 }
3059
3060 vty_out(vty, "\n");
3061
3062 while (offset < len) {
3063 group = (struct bsmmsg_grpinfo *)buf;
3064
3065 if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
3066 grp.family = AF_INET;
3067
3068 grp.prefixlen = group->group.mask;
3069 grp.u.prefix4.s_addr = group->group.addr.s_addr;
3070
3071 prefix2str(&grp, grp_str, sizeof(grp_str));
3072
3073 buf += sizeof(struct bsmmsg_grpinfo);
3074 offset += sizeof(struct bsmmsg_grpinfo);
3075
3076 if (uj) {
3077 json_object_object_get_ex(json, grp_str,
3078 &json_group);
3079 if (!json_group) {
3080 json_group = json_object_new_object();
3081 json_object_int_add(json_group,
3082 "Rp Count",
3083 group->rp_count);
3084 json_object_int_add(
3085 json_group, "Fragment Rp count",
3086 group->frag_rp_count);
3087 json_object_object_add(json, grp_str,
3088 json_group);
3089 }
3090 } else {
3091 vty_out(vty, "Group : %s\n", grp_str);
3092 vty_out(vty, "-------------------\n");
3093 vty_out(vty, "Rp Count:%d\n", group->rp_count);
3094 vty_out(vty, "Fragment Rp Count : %d\n",
3095 group->frag_rp_count);
3096 }
3097
3098 frag_rp_cnt = group->frag_rp_count;
3099
3100 if (!frag_rp_cnt)
3101 continue;
3102
3103 if (!uj)
3104 vty_out(vty,
3105 "RpAddress HoldTime Priority\n");
3106
3107 while (frag_rp_cnt--) {
3108 rpaddr = (struct bsmmsg_rpinfo *)buf;
3109
3110 buf += sizeof(struct bsmmsg_rpinfo);
3111 offset += sizeof(struct bsmmsg_rpinfo);
3112
3113 pim_inet4_dump("<Rp addr?>",
3114 rpaddr->rpaddr.addr, rp_str,
3115 sizeof(rp_str));
3116
3117 if (uj) {
3118 json_row = json_object_new_object();
3119 json_object_string_add(
3120 json_row, "Rp Address", rp_str);
3121 json_object_int_add(
3122 json_row, "Rp HoldTime",
3123 ntohs(rpaddr->rp_holdtime));
3124 json_object_int_add(json_row,
3125 "Rp Priority",
3126 rpaddr->rp_pri);
3127 json_object_object_add(
3128 json_group, rp_str, json_row);
3129 } else {
3130 vty_out(vty, "%-15s %-12d %d\n", rp_str,
3131 ntohs(rpaddr->rp_holdtime),
3132 rpaddr->rp_pri);
3133 }
3134 }
3135 vty_out(vty, "\n");
3136 }
3137
3138 fragment++;
3139 }
3140
3141 if (uj) {
3142 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3143 json, JSON_C_TO_STRING_PRETTY));
3144 json_object_free(json);
3145 }
3146 }
3147
3148 /*Display the group-rp mappings */
3149 static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
3150 struct vty *vty, bool uj)
3151 {
3152 struct bsgrp_node *bsgrp;
3153 struct listnode *rpnode;
3154 struct bsm_rpinfo *bsm_rp;
3155 struct route_node *rn;
3156 char bsr_str[INET_ADDRSTRLEN];
3157 json_object *json = NULL;
3158 json_object *json_group = NULL;
3159 json_object *json_row = NULL;
3160
3161 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY)
3162 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
3163
3164 else
3165 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str,
3166 sizeof(bsr_str));
3167
3168 if (uj) {
3169 json = json_object_new_object();
3170 json_object_string_add(json, "BSR Address", bsr_str);
3171 } else {
3172 vty_out(vty, "BSR Address %s\n", bsr_str);
3173 }
3174
3175 for (rn = route_top(pim->global_scope.bsrp_table); rn;
3176 rn = route_next(rn)) {
3177 bsgrp = (struct bsgrp_node *)rn->info;
3178
3179 if (!bsgrp)
3180 continue;
3181
3182 char grp_str[INET_ADDRSTRLEN];
3183
3184 prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
3185
3186 if (uj) {
3187 json_object_object_get_ex(json, grp_str, &json_group);
3188 if (!json_group) {
3189 json_group = json_object_new_object();
3190 json_object_object_add(json, grp_str,
3191 json_group);
3192 }
3193 } else {
3194 vty_out(vty, "Group Address %s\n", grp_str);
3195 vty_out(vty, "--------------------------\n");
3196 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3197 "priority", "Holdtime", "Hash");
3198
3199 vty_out(vty, "(ACTIVE)\n");
3200 }
3201
3202 if (bsgrp->bsrp_list) {
3203 for (ALL_LIST_ELEMENTS_RO(bsgrp->bsrp_list, rpnode,
3204 bsm_rp)) {
3205 char rp_str[INET_ADDRSTRLEN];
3206
3207 pim_inet4_dump("<Rp Address?>",
3208 bsm_rp->rp_address, rp_str,
3209 sizeof(rp_str));
3210
3211 if (uj) {
3212 json_row = json_object_new_object();
3213 json_object_string_add(
3214 json_row, "Rp Address", rp_str);
3215 json_object_int_add(
3216 json_row, "Rp HoldTime",
3217 bsm_rp->rp_holdtime);
3218 json_object_int_add(json_row,
3219 "Rp Priority",
3220 bsm_rp->rp_prio);
3221 json_object_int_add(json_row,
3222 "Hash Val",
3223 bsm_rp->hash);
3224 json_object_object_add(
3225 json_group, rp_str, json_row);
3226
3227 } else {
3228 vty_out(vty,
3229 "%-15s %-15u %-15u %-15u\n",
3230 rp_str, bsm_rp->rp_prio,
3231 bsm_rp->rp_holdtime,
3232 bsm_rp->hash);
3233 }
3234 }
3235 if (!bsgrp->bsrp_list->count && !uj)
3236 vty_out(vty, "Active List is empty.\n");
3237 }
3238
3239 if (uj) {
3240 json_object_int_add(json_group, "Pending RP count",
3241 bsgrp->pend_rp_cnt);
3242 } else {
3243 vty_out(vty, "(PENDING)\n");
3244 vty_out(vty, "Pending RP count :%d\n",
3245 bsgrp->pend_rp_cnt);
3246 if (bsgrp->pend_rp_cnt)
3247 vty_out(vty, "%-15s %-15s %-15s %-15s\n",
3248 "Rp Address", "priority", "Holdtime",
3249 "Hash");
3250 }
3251
3252 if (bsgrp->partial_bsrp_list) {
3253 for (ALL_LIST_ELEMENTS_RO(bsgrp->partial_bsrp_list,
3254 rpnode, bsm_rp)) {
3255 char rp_str[INET_ADDRSTRLEN];
3256
3257 pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address,
3258 rp_str, sizeof(rp_str));
3259
3260 if (uj) {
3261 json_row = json_object_new_object();
3262 json_object_string_add(
3263 json_row, "Rp Address", rp_str);
3264 json_object_int_add(
3265 json_row, "Rp HoldTime",
3266 bsm_rp->rp_holdtime);
3267 json_object_int_add(json_row,
3268 "Rp Priority",
3269 bsm_rp->rp_prio);
3270 json_object_int_add(json_row,
3271 "Hash Val",
3272 bsm_rp->hash);
3273 json_object_object_add(
3274 json_group, rp_str, json_row);
3275 } else {
3276 vty_out(vty,
3277 "%-15s %-15u %-15u %-15u\n",
3278 rp_str, bsm_rp->rp_prio,
3279 bsm_rp->rp_holdtime,
3280 bsm_rp->hash);
3281 }
3282 }
3283 if (!bsgrp->partial_bsrp_list->count && !uj)
3284 vty_out(vty, "Partial List is empty\n");
3285 }
3286
3287 if (!uj)
3288 vty_out(vty, "\n");
3289 }
3290
3291 if (uj) {
3292 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3293 json, JSON_C_TO_STRING_PRETTY));
3294 json_object_free(json);
3295 }
3296 }
3297
3298 /* pim statistics - just adding only bsm related now.
3299 * We can continue to add all pim related stats here.
3300 */
3301 static void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
3302 const char *ifname, bool uj)
3303 {
3304 json_object *json = NULL;
3305 struct interface *ifp;
3306
3307 if (uj) {
3308 json = json_object_new_object();
3309 json_object_int_add(json, "Number of Received BSMs",
3310 pim->bsm_rcvd);
3311 json_object_int_add(json, "Number of Forwared BSMs",
3312 pim->bsm_sent);
3313 json_object_int_add(json, "Number of Dropped BSMs",
3314 pim->bsm_dropped);
3315 } else {
3316 vty_out(vty, "BSM Statistics :\n");
3317 vty_out(vty, "----------------\n");
3318 vty_out(vty, "Number of Received BSMs : %" PRIu64 "\n",
3319 pim->bsm_rcvd);
3320 vty_out(vty, "Number of Forwared BSMs : %" PRIu64 "\n",
3321 pim->bsm_sent);
3322 vty_out(vty, "Number of Dropped BSMs : %" PRIu64 "\n",
3323 pim->bsm_dropped);
3324 }
3325
3326 vty_out(vty, "\n");
3327
3328 /* scan interfaces */
3329 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3330 struct pim_interface *pim_ifp = ifp->info;
3331
3332 if (ifname && strcmp(ifname, ifp->name))
3333 continue;
3334
3335 if (!pim_ifp)
3336 continue;
3337
3338 if (!uj) {
3339 vty_out(vty, "Interface : %s\n", ifp->name);
3340 vty_out(vty, "-------------------\n");
3341 vty_out(vty,
3342 "Number of BSMs dropped due to config miss : %u\n",
3343 pim_ifp->pim_ifstat_bsm_cfg_miss);
3344 vty_out(vty, "Number of unicast BSMs dropped : %u\n",
3345 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3346 vty_out(vty,
3347 "Number of BSMs dropped due to invalid scope zone : %u\n",
3348 pim_ifp->pim_ifstat_bsm_invalid_sz);
3349 } else {
3350
3351 json_object *json_row = NULL;
3352
3353 json_row = json_object_new_object();
3354
3355 json_object_string_add(json_row, "If Name", ifp->name);
3356 json_object_int_add(
3357 json_row,
3358 "Number of BSMs dropped due to config miss",
3359 pim_ifp->pim_ifstat_bsm_cfg_miss);
3360 json_object_int_add(
3361 json_row, "Number of unicast BSMs dropped",
3362 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3363 json_object_int_add(json_row,
3364 "Number of BSMs dropped due to invalid scope zone",
3365 pim_ifp->pim_ifstat_bsm_invalid_sz);
3366 json_object_object_add(json, ifp->name, json_row);
3367 }
3368 vty_out(vty, "\n");
3369 }
3370
3371 if (uj) {
3372 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3373 json, JSON_C_TO_STRING_PRETTY));
3374 json_object_free(json);
3375 }
3376 }
3377
3378 static void clear_pim_statistics(struct pim_instance *pim)
3379 {
3380 struct interface *ifp;
3381
3382 pim->bsm_rcvd = 0;
3383 pim->bsm_sent = 0;
3384 pim->bsm_dropped = 0;
3385
3386 /* scan interfaces */
3387 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3388 struct pim_interface *pim_ifp = ifp->info;
3389
3390 if (!pim_ifp)
3391 continue;
3392
3393 pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
3394 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
3395 pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
3396 }
3397 }
3398
3399 static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
3400 {
3401 struct interface *ifp;
3402 time_t now;
3403 json_object *json = NULL;
3404 json_object *json_iface = NULL;
3405 json_object *json_row = NULL;
3406
3407 now = pim_time_monotonic_sec();
3408
3409 if (uj)
3410 json = json_object_new_object();
3411 else
3412 vty_out(vty,
3413 "Interface Address Group Mode Timer Srcs V Uptime \n");
3414
3415 /* scan interfaces */
3416 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3417 struct pim_interface *pim_ifp = ifp->info;
3418 struct listnode *sock_node;
3419 struct igmp_sock *igmp;
3420
3421 if (!pim_ifp)
3422 continue;
3423
3424 /* scan igmp sockets */
3425 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3426 igmp)) {
3427 char ifaddr_str[INET_ADDRSTRLEN];
3428 struct listnode *grpnode;
3429 struct igmp_group *grp;
3430
3431 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3432 sizeof(ifaddr_str));
3433
3434 /* scan igmp groups */
3435 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3436 grpnode, grp)) {
3437 char group_str[INET_ADDRSTRLEN];
3438 char hhmmss[10];
3439 char uptime[10];
3440
3441 pim_inet4_dump("<group?>", grp->group_addr,
3442 group_str, sizeof(group_str));
3443 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
3444 grp->t_group_timer);
3445 pim_time_uptime(uptime, sizeof(uptime),
3446 now - grp->group_creation);
3447
3448 if (uj) {
3449 json_object_object_get_ex(
3450 json, ifp->name, &json_iface);
3451
3452 if (!json_iface) {
3453 json_iface =
3454 json_object_new_object();
3455 json_object_pim_ifp_add(
3456 json_iface, ifp);
3457 json_object_object_add(
3458 json, ifp->name,
3459 json_iface);
3460 }
3461
3462 json_row = json_object_new_object();
3463 json_object_string_add(
3464 json_row, "source", ifaddr_str);
3465 json_object_string_add(
3466 json_row, "group", group_str);
3467
3468 if (grp->igmp_version == 3)
3469 json_object_string_add(
3470 json_row, "mode",
3471 grp->group_filtermode_isexcl
3472 ? "EXCLUDE"
3473 : "INCLUDE");
3474
3475 json_object_string_add(json_row,
3476 "timer", hhmmss);
3477 json_object_int_add(
3478 json_row, "sourcesCount",
3479 grp->group_source_list
3480 ? listcount(
3481 grp->group_source_list)
3482 : 0);
3483 json_object_int_add(json_row, "version",
3484 grp->igmp_version);
3485 json_object_string_add(
3486 json_row, "uptime", uptime);
3487 json_object_object_add(json_iface,
3488 group_str,
3489 json_row);
3490
3491 } else {
3492 vty_out(vty,
3493 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3494 ifp->name, ifaddr_str,
3495 group_str,
3496 grp->igmp_version == 3
3497 ? (grp->group_filtermode_isexcl
3498 ? "EXCL"
3499 : "INCL")
3500 : "----",
3501 hhmmss,
3502 grp->group_source_list
3503 ? listcount(
3504 grp->group_source_list)
3505 : 0,
3506 grp->igmp_version, uptime);
3507 }
3508 } /* scan igmp groups */
3509 } /* scan igmp sockets */
3510 } /* scan interfaces */
3511
3512 if (uj) {
3513 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3514 json, JSON_C_TO_STRING_PRETTY));
3515 json_object_free(json);
3516 }
3517 }
3518
3519 static void igmp_show_group_retransmission(struct pim_instance *pim,
3520 struct vty *vty)
3521 {
3522 struct interface *ifp;
3523
3524 vty_out(vty,
3525 "Interface Address Group RetTimer Counter RetSrcs\n");
3526
3527 /* scan interfaces */
3528 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3529 struct pim_interface *pim_ifp = ifp->info;
3530 struct listnode *sock_node;
3531 struct igmp_sock *igmp;
3532
3533 if (!pim_ifp)
3534 continue;
3535
3536 /* scan igmp sockets */
3537 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3538 igmp)) {
3539 char ifaddr_str[INET_ADDRSTRLEN];
3540 struct listnode *grpnode;
3541 struct igmp_group *grp;
3542
3543 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3544 sizeof(ifaddr_str));
3545
3546 /* scan igmp groups */
3547 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3548 grpnode, grp)) {
3549 char group_str[INET_ADDRSTRLEN];
3550 char grp_retr_mmss[10];
3551 struct listnode *src_node;
3552 struct igmp_source *src;
3553 int grp_retr_sources = 0;
3554
3555 pim_inet4_dump("<group?>", grp->group_addr,
3556 group_str, sizeof(group_str));
3557 pim_time_timer_to_mmss(
3558 grp_retr_mmss, sizeof(grp_retr_mmss),
3559 grp->t_group_query_retransmit_timer);
3560
3561
3562 /* count group sources with retransmission state
3563 */
3564 for (ALL_LIST_ELEMENTS_RO(
3565 grp->group_source_list, src_node,
3566 src)) {
3567 if (src->source_query_retransmit_count
3568 > 0) {
3569 ++grp_retr_sources;
3570 }
3571 }
3572
3573 vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
3574 ifp->name, ifaddr_str, group_str,
3575 grp_retr_mmss,
3576 grp->group_specific_query_retransmit_count,
3577 grp_retr_sources);
3578
3579 } /* scan igmp groups */
3580 } /* scan igmp sockets */
3581 } /* scan interfaces */
3582 }
3583
3584 static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
3585 {
3586 struct interface *ifp;
3587 time_t now;
3588
3589 now = pim_time_monotonic_sec();
3590
3591 vty_out(vty,
3592 "Interface Address Group Source Timer Fwd Uptime \n");
3593
3594 /* scan interfaces */
3595 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3596 struct pim_interface *pim_ifp = ifp->info;
3597 struct listnode *sock_node;
3598 struct igmp_sock *igmp;
3599
3600 if (!pim_ifp)
3601 continue;
3602
3603 /* scan igmp sockets */
3604 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3605 igmp)) {
3606 char ifaddr_str[INET_ADDRSTRLEN];
3607 struct listnode *grpnode;
3608 struct igmp_group *grp;
3609
3610 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3611 sizeof(ifaddr_str));
3612
3613 /* scan igmp groups */
3614 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3615 grpnode, grp)) {
3616 char group_str[INET_ADDRSTRLEN];
3617 struct listnode *srcnode;
3618 struct igmp_source *src;
3619
3620 pim_inet4_dump("<group?>", grp->group_addr,
3621 group_str, sizeof(group_str));
3622
3623 /* scan group sources */
3624 for (ALL_LIST_ELEMENTS_RO(
3625 grp->group_source_list, srcnode,
3626 src)) {
3627 char source_str[INET_ADDRSTRLEN];
3628 char mmss[10];
3629 char uptime[10];
3630
3631 pim_inet4_dump(
3632 "<source?>", src->source_addr,
3633 source_str, sizeof(source_str));
3634
3635 pim_time_timer_to_mmss(
3636 mmss, sizeof(mmss),
3637 src->t_source_timer);
3638
3639 pim_time_uptime(
3640 uptime, sizeof(uptime),
3641 now - src->source_creation);
3642
3643 vty_out(vty,
3644 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3645 ifp->name, ifaddr_str,
3646 group_str, source_str, mmss,
3647 IGMP_SOURCE_TEST_FORWARDING(
3648 src->source_flags)
3649 ? "Y"
3650 : "N",
3651 uptime);
3652
3653 } /* scan group sources */
3654 } /* scan igmp groups */
3655 } /* scan igmp sockets */
3656 } /* scan interfaces */
3657 }
3658
3659 static void igmp_show_source_retransmission(struct pim_instance *pim,
3660 struct vty *vty)
3661 {
3662 struct interface *ifp;
3663
3664 vty_out(vty,
3665 "Interface Address Group Source Counter\n");
3666
3667 /* scan interfaces */
3668 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3669 struct pim_interface *pim_ifp = ifp->info;
3670 struct listnode *sock_node;
3671 struct igmp_sock *igmp;
3672
3673 if (!pim_ifp)
3674 continue;
3675
3676 /* scan igmp sockets */
3677 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3678 igmp)) {
3679 char ifaddr_str[INET_ADDRSTRLEN];
3680 struct listnode *grpnode;
3681 struct igmp_group *grp;
3682
3683 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3684 sizeof(ifaddr_str));
3685
3686 /* scan igmp groups */
3687 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3688 grpnode, grp)) {
3689 char group_str[INET_ADDRSTRLEN];
3690 struct listnode *srcnode;
3691 struct igmp_source *src;
3692
3693 pim_inet4_dump("<group?>", grp->group_addr,
3694 group_str, sizeof(group_str));
3695
3696 /* scan group sources */
3697 for (ALL_LIST_ELEMENTS_RO(
3698 grp->group_source_list, srcnode,
3699 src)) {
3700 char source_str[INET_ADDRSTRLEN];
3701
3702 pim_inet4_dump(
3703 "<source?>", src->source_addr,
3704 source_str, sizeof(source_str));
3705
3706 vty_out(vty,
3707 "%-16s %-15s %-15s %-15s %7d\n",
3708 ifp->name, ifaddr_str,
3709 group_str, source_str,
3710 src->source_query_retransmit_count);
3711
3712 } /* scan group sources */
3713 } /* scan igmp groups */
3714 } /* scan igmp sockets */
3715 } /* scan interfaces */
3716 }
3717
3718 static void pim_show_bsr(struct pim_instance *pim,
3719 struct vty *vty,
3720 bool uj)
3721 {
3722 char uptime[10];
3723 char last_bsm_seen[10];
3724 time_t now;
3725 char bsr_state[20];
3726 char bsr_str[PREFIX_STRLEN];
3727 json_object *json = NULL;
3728
3729 vty_out(vty, "PIMv2 Bootstrap information\n");
3730
3731 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) {
3732 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
3733 pim_time_uptime(uptime, sizeof(uptime),
3734 pim->global_scope.current_bsr_first_ts);
3735 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3736 pim->global_scope.current_bsr_last_ts);
3737 }
3738
3739 else {
3740 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr,
3741 bsr_str, sizeof(bsr_str));
3742 now = pim_time_monotonic_sec();
3743 pim_time_uptime(uptime, sizeof(uptime),
3744 (now - pim->global_scope.current_bsr_first_ts));
3745 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3746 now - pim->global_scope.current_bsr_last_ts);
3747 }
3748
3749 switch (pim->global_scope.state) {
3750 case NO_INFO:
3751 strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
3752 break;
3753 case ACCEPT_ANY:
3754 strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
3755 break;
3756 case ACCEPT_PREFERRED:
3757 strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
3758 break;
3759 default:
3760 strlcpy(bsr_state, "", sizeof(bsr_state));
3761 }
3762
3763 if (uj) {
3764 json = json_object_new_object();
3765 json_object_string_add(json, "bsr", bsr_str);
3766 json_object_int_add(json, "priority",
3767 pim->global_scope.current_bsr_prio);
3768 json_object_int_add(json, "fragment_tag",
3769 pim->global_scope.bsm_frag_tag);
3770 json_object_string_add(json, "state", bsr_state);
3771 json_object_string_add(json, "upTime", uptime);
3772 json_object_string_add(json, "last_bsm_seen", last_bsm_seen);
3773 }
3774
3775 else {
3776 vty_out(vty, "Current preferred BSR address: %s\n", bsr_str);
3777 vty_out(vty,
3778 "Priority Fragment-Tag State UpTime\n");
3779 vty_out(vty, " %-12d %-12d %-13s %7s\n",
3780 pim->global_scope.current_bsr_prio,
3781 pim->global_scope.bsm_frag_tag,
3782 bsr_state,
3783 uptime);
3784 vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
3785 }
3786
3787 if (uj) {
3788 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3789 json, JSON_C_TO_STRING_PRETTY));
3790 json_object_free(json);
3791 }
3792 }
3793
3794 static void clear_igmp_interfaces(struct pim_instance *pim)
3795 {
3796 struct interface *ifp;
3797
3798 FOR_ALL_INTERFACES (pim->vrf, ifp)
3799 pim_if_addr_del_all_igmp(ifp);
3800
3801 FOR_ALL_INTERFACES (pim->vrf, ifp)
3802 pim_if_addr_add_all(ifp);
3803 }
3804
3805 static void clear_pim_interfaces(struct pim_instance *pim)
3806 {
3807 struct interface *ifp;
3808
3809 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3810 if (ifp->info) {
3811 pim_neighbor_delete_all(ifp, "interface cleared");
3812 }
3813 }
3814 }
3815
3816 static void clear_interfaces(struct pim_instance *pim)
3817 {
3818 clear_igmp_interfaces(pim);
3819 clear_pim_interfaces(pim);
3820 }
3821
3822 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3823 pim_ifp = ifp->info; \
3824 if (!pim_ifp) { \
3825 vty_out(vty, \
3826 "%% Enable PIM and/or IGMP on this interface first\n"); \
3827 return CMD_WARNING_CONFIG_FAILED; \
3828 }
3829
3830 DEFUN (clear_ip_interfaces,
3831 clear_ip_interfaces_cmd,
3832 "clear ip interfaces [vrf NAME]",
3833 CLEAR_STR
3834 IP_STR
3835 "Reset interfaces\n"
3836 VRF_CMD_HELP_STR)
3837 {
3838 int idx = 2;
3839 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3840
3841 if (!vrf)
3842 return CMD_WARNING;
3843
3844 clear_interfaces(vrf->info);
3845
3846 return CMD_SUCCESS;
3847 }
3848
3849 DEFUN (clear_ip_igmp_interfaces,
3850 clear_ip_igmp_interfaces_cmd,
3851 "clear ip igmp [vrf NAME] interfaces",
3852 CLEAR_STR
3853 IP_STR
3854 CLEAR_IP_IGMP_STR
3855 VRF_CMD_HELP_STR
3856 "Reset IGMP interfaces\n")
3857 {
3858 int idx = 2;
3859 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3860
3861 if (!vrf)
3862 return CMD_WARNING;
3863
3864 clear_igmp_interfaces(vrf->info);
3865
3866 return CMD_SUCCESS;
3867 }
3868
3869 DEFUN (clear_ip_pim_statistics,
3870 clear_ip_pim_statistics_cmd,
3871 "clear ip pim statistics [vrf NAME]",
3872 CLEAR_STR
3873 IP_STR
3874 CLEAR_IP_PIM_STR
3875 VRF_CMD_HELP_STR
3876 "Reset PIM statistics\n")
3877 {
3878 int idx = 2;
3879 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3880
3881 if (!vrf)
3882 return CMD_WARNING;
3883
3884 clear_pim_statistics(vrf->info);
3885 return CMD_SUCCESS;
3886 }
3887
3888 static void clear_mroute(struct pim_instance *pim)
3889 {
3890 struct pim_upstream *up;
3891 struct interface *ifp;
3892
3893 /* scan interfaces */
3894 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3895 struct pim_interface *pim_ifp = ifp->info;
3896 struct listnode *sock_node;
3897 struct igmp_sock *igmp;
3898 struct pim_ifchannel *ch;
3899
3900 if (!pim_ifp)
3901 continue;
3902
3903 /* deleting all ifchannels */
3904 while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
3905 ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
3906
3907 pim_ifchannel_delete(ch);
3908 }
3909
3910 /* clean up all igmp groups */
3911 /* scan igmp sockets */
3912 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3913 igmp)) {
3914
3915 struct igmp_group *grp;
3916
3917 if (igmp->igmp_group_list) {
3918 while (igmp->igmp_group_list->count) {
3919 grp = listnode_head(
3920 igmp->igmp_group_list);
3921 igmp_group_delete(grp);
3922 }
3923 }
3924
3925 }
3926 }
3927
3928 /* clean up all upstreams*/
3929 while ((up = rb_pim_upstream_first(&pim->upstream_head))) {
3930 pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
3931 }
3932 }
3933
3934 DEFUN (clear_ip_mroute,
3935 clear_ip_mroute_cmd,
3936 "clear ip mroute [vrf NAME]",
3937 CLEAR_STR
3938 IP_STR
3939 "Reset multicast routes\n"
3940 VRF_CMD_HELP_STR)
3941 {
3942 int idx = 2;
3943 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3944
3945 if (!vrf)
3946 return CMD_WARNING;
3947
3948 clear_mroute(vrf->info);
3949
3950 return CMD_SUCCESS;
3951 }
3952
3953 DEFUN (clear_ip_pim_interfaces,
3954 clear_ip_pim_interfaces_cmd,
3955 "clear ip pim [vrf NAME] interfaces",
3956 CLEAR_STR
3957 IP_STR
3958 CLEAR_IP_PIM_STR
3959 VRF_CMD_HELP_STR
3960 "Reset PIM interfaces\n")
3961 {
3962 int idx = 2;
3963 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3964
3965 if (!vrf)
3966 return CMD_WARNING;
3967
3968 clear_pim_interfaces(vrf->info);
3969
3970 return CMD_SUCCESS;
3971 }
3972
3973 DEFUN (clear_ip_pim_interface_traffic,
3974 clear_ip_pim_interface_traffic_cmd,
3975 "clear ip pim [vrf NAME] interface traffic",
3976 "Reset functions\n"
3977 "IP information\n"
3978 "PIM clear commands\n"
3979 VRF_CMD_HELP_STR
3980 "Reset PIM interfaces\n"
3981 "Reset Protocol Packet counters\n")
3982 {
3983 int idx = 2;
3984 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3985 struct interface *ifp = NULL;
3986 struct pim_interface *pim_ifp = NULL;
3987
3988 if (!vrf)
3989 return CMD_WARNING;
3990
3991 FOR_ALL_INTERFACES (vrf, ifp) {
3992 pim_ifp = ifp->info;
3993
3994 if (!pim_ifp)
3995 continue;
3996
3997 pim_ifp->pim_ifstat_hello_recv = 0;
3998 pim_ifp->pim_ifstat_hello_sent = 0;
3999 pim_ifp->pim_ifstat_join_recv = 0;
4000 pim_ifp->pim_ifstat_join_send = 0;
4001 pim_ifp->pim_ifstat_prune_recv = 0;
4002 pim_ifp->pim_ifstat_prune_send = 0;
4003 pim_ifp->pim_ifstat_reg_recv = 0;
4004 pim_ifp->pim_ifstat_reg_send = 0;
4005 pim_ifp->pim_ifstat_reg_stop_recv = 0;
4006 pim_ifp->pim_ifstat_reg_stop_send = 0;
4007 pim_ifp->pim_ifstat_assert_recv = 0;
4008 pim_ifp->pim_ifstat_assert_send = 0;
4009 pim_ifp->pim_ifstat_bsm_rx = 0;
4010 pim_ifp->pim_ifstat_bsm_tx = 0;
4011 }
4012
4013 return CMD_SUCCESS;
4014 }
4015
4016 DEFUN (clear_ip_pim_oil,
4017 clear_ip_pim_oil_cmd,
4018 "clear ip pim [vrf NAME] oil",
4019 CLEAR_STR
4020 IP_STR
4021 CLEAR_IP_PIM_STR
4022 VRF_CMD_HELP_STR
4023 "Rescan PIM OIL (output interface list)\n")
4024 {
4025 int idx = 2;
4026 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4027
4028 if (!vrf)
4029 return CMD_WARNING;
4030
4031 pim_scan_oil(vrf->info);
4032
4033 return CMD_SUCCESS;
4034 }
4035
4036 DEFUN (show_ip_igmp_interface,
4037 show_ip_igmp_interface_cmd,
4038 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4039 SHOW_STR
4040 IP_STR
4041 IGMP_STR
4042 VRF_CMD_HELP_STR
4043 "IGMP interface information\n"
4044 "Detailed output\n"
4045 "interface name\n"
4046 JSON_STR)
4047 {
4048 int idx = 2;
4049 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4050 bool uj = use_json(argc, argv);
4051
4052 if (!vrf)
4053 return CMD_WARNING;
4054
4055 if (argv_find(argv, argc, "detail", &idx)
4056 || argv_find(argv, argc, "WORD", &idx))
4057 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
4058 else
4059 igmp_show_interfaces(vrf->info, vty, uj);
4060
4061 return CMD_SUCCESS;
4062 }
4063
4064 DEFUN (show_ip_igmp_interface_vrf_all,
4065 show_ip_igmp_interface_vrf_all_cmd,
4066 "show ip igmp vrf all interface [detail|WORD] [json]",
4067 SHOW_STR
4068 IP_STR
4069 IGMP_STR
4070 VRF_CMD_HELP_STR
4071 "IGMP interface information\n"
4072 "Detailed output\n"
4073 "interface name\n"
4074 JSON_STR)
4075 {
4076 int idx = 2;
4077 bool uj = use_json(argc, argv);
4078 struct vrf *vrf;
4079 bool first = true;
4080
4081 if (uj)
4082 vty_out(vty, "{ ");
4083 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4084 if (uj) {
4085 if (!first)
4086 vty_out(vty, ", ");
4087 vty_out(vty, " \"%s\": ", vrf->name);
4088 first = false;
4089 } else
4090 vty_out(vty, "VRF: %s\n", vrf->name);
4091 if (argv_find(argv, argc, "detail", &idx)
4092 || argv_find(argv, argc, "WORD", &idx))
4093 igmp_show_interfaces_single(vrf->info, vty,
4094 argv[idx]->arg, uj);
4095 else
4096 igmp_show_interfaces(vrf->info, vty, uj);
4097 }
4098 if (uj)
4099 vty_out(vty, "}\n");
4100
4101 return CMD_SUCCESS;
4102 }
4103
4104 DEFUN (show_ip_igmp_join,
4105 show_ip_igmp_join_cmd,
4106 "show ip igmp [vrf NAME] join",
4107 SHOW_STR
4108 IP_STR
4109 IGMP_STR
4110 VRF_CMD_HELP_STR
4111 "IGMP static join information\n")
4112 {
4113 int idx = 2;
4114 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4115
4116 if (!vrf)
4117 return CMD_WARNING;
4118
4119 igmp_show_interface_join(vrf->info, vty);
4120
4121 return CMD_SUCCESS;
4122 }
4123
4124 DEFUN (show_ip_igmp_join_vrf_all,
4125 show_ip_igmp_join_vrf_all_cmd,
4126 "show ip igmp vrf all join",
4127 SHOW_STR
4128 IP_STR
4129 IGMP_STR
4130 VRF_CMD_HELP_STR
4131 "IGMP static join information\n")
4132 {
4133 bool uj = use_json(argc, argv);
4134 struct vrf *vrf;
4135 bool first = true;
4136
4137 if (uj)
4138 vty_out(vty, "{ ");
4139 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4140 if (uj) {
4141 if (!first)
4142 vty_out(vty, ", ");
4143 vty_out(vty, " \"%s\": ", vrf->name);
4144 first = false;
4145 } else
4146 vty_out(vty, "VRF: %s\n", vrf->name);
4147 igmp_show_interface_join(vrf->info, vty);
4148 }
4149 if (uj)
4150 vty_out(vty, "}\n");
4151
4152 return CMD_SUCCESS;
4153 }
4154
4155 DEFUN (show_ip_igmp_groups,
4156 show_ip_igmp_groups_cmd,
4157 "show ip igmp [vrf NAME] groups [json]",
4158 SHOW_STR
4159 IP_STR
4160 IGMP_STR
4161 VRF_CMD_HELP_STR
4162 IGMP_GROUP_STR
4163 JSON_STR)
4164 {
4165 int idx = 2;
4166 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4167 bool uj = use_json(argc, argv);
4168
4169 if (!vrf)
4170 return CMD_WARNING;
4171
4172 igmp_show_groups(vrf->info, vty, uj);
4173
4174 return CMD_SUCCESS;
4175 }
4176
4177 DEFUN (show_ip_igmp_groups_vrf_all,
4178 show_ip_igmp_groups_vrf_all_cmd,
4179 "show ip igmp vrf all groups [json]",
4180 SHOW_STR
4181 IP_STR
4182 IGMP_STR
4183 VRF_CMD_HELP_STR
4184 IGMP_GROUP_STR
4185 JSON_STR)
4186 {
4187 bool uj = use_json(argc, argv);
4188 struct vrf *vrf;
4189 bool first = true;
4190
4191 if (uj)
4192 vty_out(vty, "{ ");
4193 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4194 if (uj) {
4195 if (!first)
4196 vty_out(vty, ", ");
4197 vty_out(vty, " \"%s\": ", vrf->name);
4198 first = false;
4199 } else
4200 vty_out(vty, "VRF: %s\n", vrf->name);
4201 igmp_show_groups(vrf->info, vty, uj);
4202 }
4203 if (uj)
4204 vty_out(vty, "}\n");
4205
4206 return CMD_SUCCESS;
4207 }
4208
4209 DEFUN (show_ip_igmp_groups_retransmissions,
4210 show_ip_igmp_groups_retransmissions_cmd,
4211 "show ip igmp [vrf NAME] groups retransmissions",
4212 SHOW_STR
4213 IP_STR
4214 IGMP_STR
4215 VRF_CMD_HELP_STR
4216 IGMP_GROUP_STR
4217 "IGMP group retransmissions\n")
4218 {
4219 int idx = 2;
4220 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4221
4222 if (!vrf)
4223 return CMD_WARNING;
4224
4225 igmp_show_group_retransmission(vrf->info, vty);
4226
4227 return CMD_SUCCESS;
4228 }
4229
4230 DEFUN (show_ip_igmp_sources,
4231 show_ip_igmp_sources_cmd,
4232 "show ip igmp [vrf NAME] sources",
4233 SHOW_STR
4234 IP_STR
4235 IGMP_STR
4236 VRF_CMD_HELP_STR
4237 IGMP_SOURCE_STR)
4238 {
4239 int idx = 2;
4240 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4241
4242 if (!vrf)
4243 return CMD_WARNING;
4244
4245 igmp_show_sources(vrf->info, vty);
4246
4247 return CMD_SUCCESS;
4248 }
4249
4250 DEFUN (show_ip_igmp_sources_retransmissions,
4251 show_ip_igmp_sources_retransmissions_cmd,
4252 "show ip igmp [vrf NAME] sources retransmissions",
4253 SHOW_STR
4254 IP_STR
4255 IGMP_STR
4256 VRF_CMD_HELP_STR
4257 IGMP_SOURCE_STR
4258 "IGMP source retransmissions\n")
4259 {
4260 int idx = 2;
4261 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4262
4263 if (!vrf)
4264 return CMD_WARNING;
4265
4266 igmp_show_source_retransmission(vrf->info, vty);
4267
4268 return CMD_SUCCESS;
4269 }
4270
4271 DEFUN (show_ip_igmp_statistics,
4272 show_ip_igmp_statistics_cmd,
4273 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4274 SHOW_STR
4275 IP_STR
4276 IGMP_STR
4277 VRF_CMD_HELP_STR
4278 "IGMP statistics\n"
4279 "interface\n"
4280 "IGMP interface\n"
4281 JSON_STR)
4282 {
4283 int idx = 2;
4284 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4285 bool uj = use_json(argc, argv);
4286
4287 if (!vrf)
4288 return CMD_WARNING;
4289
4290 if (argv_find(argv, argc, "WORD", &idx))
4291 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
4292 else
4293 igmp_show_statistics(vrf->info, vty, NULL, uj);
4294
4295 return CMD_SUCCESS;
4296 }
4297
4298 DEFUN (show_ip_pim_assert,
4299 show_ip_pim_assert_cmd,
4300 "show ip pim [vrf NAME] assert",
4301 SHOW_STR
4302 IP_STR
4303 PIM_STR
4304 VRF_CMD_HELP_STR
4305 "PIM interface assert\n")
4306 {
4307 int idx = 2;
4308 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4309
4310 if (!vrf)
4311 return CMD_WARNING;
4312
4313 pim_show_assert(vrf->info, vty);
4314
4315 return CMD_SUCCESS;
4316 }
4317
4318 DEFUN (show_ip_pim_assert_internal,
4319 show_ip_pim_assert_internal_cmd,
4320 "show ip pim [vrf NAME] assert-internal",
4321 SHOW_STR
4322 IP_STR
4323 PIM_STR
4324 VRF_CMD_HELP_STR
4325 "PIM interface internal assert state\n")
4326 {
4327 int idx = 2;
4328 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4329
4330 if (!vrf)
4331 return CMD_WARNING;
4332
4333 pim_show_assert_internal(vrf->info, vty);
4334
4335 return CMD_SUCCESS;
4336 }
4337
4338 DEFUN (show_ip_pim_assert_metric,
4339 show_ip_pim_assert_metric_cmd,
4340 "show ip pim [vrf NAME] assert-metric",
4341 SHOW_STR
4342 IP_STR
4343 PIM_STR
4344 VRF_CMD_HELP_STR
4345 "PIM interface assert metric\n")
4346 {
4347 int idx = 2;
4348 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4349
4350 if (!vrf)
4351 return CMD_WARNING;
4352
4353 pim_show_assert_metric(vrf->info, vty);
4354
4355 return CMD_SUCCESS;
4356 }
4357
4358 DEFUN (show_ip_pim_assert_winner_metric,
4359 show_ip_pim_assert_winner_metric_cmd,
4360 "show ip pim [vrf NAME] assert-winner-metric",
4361 SHOW_STR
4362 IP_STR
4363 PIM_STR
4364 VRF_CMD_HELP_STR
4365 "PIM interface assert winner metric\n")
4366 {
4367 int idx = 2;
4368 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4369
4370 if (!vrf)
4371 return CMD_WARNING;
4372
4373 pim_show_assert_winner_metric(vrf->info, vty);
4374
4375 return CMD_SUCCESS;
4376 }
4377
4378 DEFUN (show_ip_pim_interface,
4379 show_ip_pim_interface_cmd,
4380 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4381 SHOW_STR
4382 IP_STR
4383 PIM_STR
4384 VRF_CMD_HELP_STR
4385 "PIM interface information\n"
4386 "Detailed output\n"
4387 "interface name\n"
4388 JSON_STR)
4389 {
4390 int idx = 2;
4391 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4392 bool uj = use_json(argc, argv);
4393
4394 if (!vrf)
4395 return CMD_WARNING;
4396
4397 if (argv_find(argv, argc, "WORD", &idx)
4398 || argv_find(argv, argc, "detail", &idx))
4399 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
4400 else
4401 pim_show_interfaces(vrf->info, vty, uj);
4402
4403 return CMD_SUCCESS;
4404 }
4405
4406 DEFUN (show_ip_pim_interface_vrf_all,
4407 show_ip_pim_interface_vrf_all_cmd,
4408 "show ip pim vrf all interface [detail|WORD] [json]",
4409 SHOW_STR
4410 IP_STR
4411 PIM_STR
4412 VRF_CMD_HELP_STR
4413 "PIM interface information\n"
4414 "Detailed output\n"
4415 "interface name\n"
4416 JSON_STR)
4417 {
4418 int idx = 6;
4419 bool uj = use_json(argc, argv);
4420 struct vrf *vrf;
4421 bool first = true;
4422
4423 if (uj)
4424 vty_out(vty, "{ ");
4425 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4426 if (uj) {
4427 if (!first)
4428 vty_out(vty, ", ");
4429 vty_out(vty, " \"%s\": ", vrf->name);
4430 first = false;
4431 } else
4432 vty_out(vty, "VRF: %s\n", vrf->name);
4433 if (argv_find(argv, argc, "WORD", &idx)
4434 || argv_find(argv, argc, "detail", &idx))
4435 pim_show_interfaces_single(vrf->info, vty,
4436 argv[idx]->arg, uj);
4437 else
4438 pim_show_interfaces(vrf->info, vty, uj);
4439 }
4440 if (uj)
4441 vty_out(vty, "}\n");
4442
4443 return CMD_SUCCESS;
4444 }
4445
4446 DEFPY (show_ip_pim_join,
4447 show_ip_pim_join_cmd,
4448 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4449 SHOW_STR
4450 IP_STR
4451 PIM_STR
4452 VRF_CMD_HELP_STR
4453 "PIM interface join information\n"
4454 "The Source or Group\n"
4455 "The Group\n"
4456 JSON_STR)
4457 {
4458 struct prefix_sg sg = {0};
4459 struct vrf *v;
4460 bool uj = !!json;
4461 struct pim_instance *pim;
4462
4463 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4464
4465 if (!v) {
4466 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4467 return CMD_WARNING;
4468 }
4469 pim = pim_get_pim_instance(v->vrf_id);
4470
4471 if (!pim) {
4472 vty_out(vty, "%% Unable to find pim instance\n");
4473 return CMD_WARNING;
4474 }
4475
4476 if (s_or_g.s_addr != 0) {
4477 if (g.s_addr != 0) {
4478 sg.src = s_or_g;
4479 sg.grp = g;
4480 } else
4481 sg.grp = s_or_g;
4482 }
4483
4484 pim_show_join(pim, vty, &sg, uj);
4485
4486 return CMD_SUCCESS;
4487 }
4488
4489 DEFUN (show_ip_pim_join_vrf_all,
4490 show_ip_pim_join_vrf_all_cmd,
4491 "show ip pim vrf all join [json]",
4492 SHOW_STR
4493 IP_STR
4494 PIM_STR
4495 VRF_CMD_HELP_STR
4496 "PIM interface join information\n"
4497 JSON_STR)
4498 {
4499 struct prefix_sg sg = {0};
4500 bool uj = use_json(argc, argv);
4501 struct vrf *vrf;
4502 bool first = true;
4503
4504 if (uj)
4505 vty_out(vty, "{ ");
4506 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4507 if (uj) {
4508 if (!first)
4509 vty_out(vty, ", ");
4510 vty_out(vty, " \"%s\": ", vrf->name);
4511 first = false;
4512 } else
4513 vty_out(vty, "VRF: %s\n", vrf->name);
4514 pim_show_join(vrf->info, vty, &sg, uj);
4515 }
4516 if (uj)
4517 vty_out(vty, "}\n");
4518
4519 return CMD_WARNING;
4520 }
4521
4522 static void pim_show_jp_agg_helper(struct vty *vty,
4523 struct interface *ifp,
4524 struct pim_neighbor *neigh,
4525 struct pim_upstream *up,
4526 int is_join)
4527 {
4528 char src_str[INET_ADDRSTRLEN];
4529 char grp_str[INET_ADDRSTRLEN];
4530 char rpf_str[INET_ADDRSTRLEN];
4531
4532 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
4533 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
4534 /* pius->address.s_addr */
4535 pim_inet4_dump("<rpf?>", neigh->source_addr, rpf_str, sizeof(rpf_str));
4536
4537 vty_out(vty, "%-16s %-15s %-15s %-15s %5s\n",
4538 ifp->name, rpf_str, src_str,
4539 grp_str, is_join?"J":"P");
4540 }
4541
4542 static void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
4543 {
4544 struct interface *ifp;
4545 struct pim_interface *pim_ifp;
4546 struct listnode *n_node;
4547 struct pim_neighbor *neigh;
4548 struct listnode *jag_node;
4549 struct pim_jp_agg_group *jag;
4550 struct listnode *js_node;
4551 struct pim_jp_sources *js;
4552
4553 vty_out(vty,
4554 "Interface RPF Nbr Source Group State\n");
4555
4556 FOR_ALL_INTERFACES (pim->vrf, ifp) {
4557 pim_ifp = ifp->info;
4558 if (!pim_ifp)
4559 continue;
4560
4561 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
4562 n_node, neigh)) {
4563 for (ALL_LIST_ELEMENTS_RO(neigh->upstream_jp_agg,
4564 jag_node, jag)) {
4565 for (ALL_LIST_ELEMENTS_RO(jag->sources,
4566 js_node, js)) {
4567 pim_show_jp_agg_helper(vty,
4568 ifp, neigh, js->up,
4569 js->is_join);
4570 }
4571 }
4572 }
4573 }
4574 }
4575
4576 DEFPY (show_ip_pim_jp_agg,
4577 show_ip_pim_jp_agg_cmd,
4578 "show ip pim [vrf NAME] jp-agg",
4579 SHOW_STR
4580 IP_STR
4581 PIM_STR
4582 VRF_CMD_HELP_STR
4583 "join prune aggregation list\n")
4584 {
4585 struct vrf *v;
4586 struct pim_instance *pim;
4587
4588 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4589
4590 if (!v) {
4591 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4592 return CMD_WARNING;
4593 }
4594 pim = pim_get_pim_instance(v->vrf_id);
4595
4596 if (!pim) {
4597 vty_out(vty, "%% Unable to find pim instance\n");
4598 return CMD_WARNING;
4599 }
4600
4601 pim_show_jp_agg_list(pim, vty);
4602
4603 return CMD_SUCCESS;
4604 }
4605
4606 DEFUN (show_ip_pim_local_membership,
4607 show_ip_pim_local_membership_cmd,
4608 "show ip pim [vrf NAME] local-membership [json]",
4609 SHOW_STR
4610 IP_STR
4611 PIM_STR
4612 VRF_CMD_HELP_STR
4613 "PIM interface local-membership\n"
4614 JSON_STR)
4615 {
4616 int idx = 2;
4617 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4618 bool uj = use_json(argc, argv);
4619
4620 if (!vrf)
4621 return CMD_WARNING;
4622
4623 pim_show_membership(vrf->info, vty, uj);
4624
4625 return CMD_SUCCESS;
4626 }
4627
4628 DEFUN (show_ip_pim_mlag_summary,
4629 show_ip_pim_mlag_summary_cmd,
4630 "show ip pim mlag summary [json]",
4631 SHOW_STR
4632 IP_STR
4633 PIM_STR
4634 "MLAG\n"
4635 "status and stats\n"
4636 JSON_STR)
4637 {
4638 bool uj = use_json(argc, argv);
4639 char role_buf[MLAG_ROLE_STRSIZE];
4640 char addr_buf[INET_ADDRSTRLEN];
4641
4642 if (uj) {
4643 json_object *json = NULL;
4644 json_object *json_stat = NULL;
4645
4646 json = json_object_new_object();
4647 if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
4648 json_object_boolean_true_add(json, "mlagConnUp");
4649 if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
4650 json_object_boolean_true_add(json, "mlagPeerConnUp");
4651 if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
4652 json_object_boolean_true_add(json, "mlagPeerZebraUp");
4653 json_object_string_add(json, "mlagRole",
4654 mlag_role2str(router->mlag_role,
4655 role_buf, sizeof(role_buf)));
4656 inet_ntop(AF_INET, &router->local_vtep_ip,
4657 addr_buf, INET_ADDRSTRLEN);
4658 json_object_string_add(json, "localVtepIp", addr_buf);
4659 inet_ntop(AF_INET, &router->anycast_vtep_ip,
4660 addr_buf, INET_ADDRSTRLEN);
4661 json_object_string_add(json, "anycastVtepIp", addr_buf);
4662 json_object_string_add(json, "peerlinkRif",
4663 router->peerlink_rif);
4664
4665 json_stat = json_object_new_object();
4666 json_object_int_add(json_stat, "mlagConnFlaps",
4667 router->mlag_stats.mlagd_session_downs);
4668 json_object_int_add(json_stat, "mlagPeerConnFlaps",
4669 router->mlag_stats.peer_session_downs);
4670 json_object_int_add(json_stat, "mlagPeerZebraFlaps",
4671 router->mlag_stats.peer_zebra_downs);
4672 json_object_int_add(json_stat, "mrouteAddRx",
4673 router->mlag_stats.msg.mroute_add_rx);
4674 json_object_int_add(json_stat, "mrouteAddTx",
4675 router->mlag_stats.msg.mroute_add_tx);
4676 json_object_int_add(json_stat, "mrouteDelRx",
4677 router->mlag_stats.msg.mroute_del_rx);
4678 json_object_int_add(json_stat, "mrouteDelTx",
4679 router->mlag_stats.msg.mroute_del_tx);
4680 json_object_int_add(json_stat, "mlagStatusUpdates",
4681 router->mlag_stats.msg.mlag_status_updates);
4682 json_object_int_add(json_stat, "peerZebraStatusUpdates",
4683 router->mlag_stats.msg.peer_zebra_status_updates);
4684 json_object_int_add(json_stat, "pimStatusUpdates",
4685 router->mlag_stats.msg.pim_status_updates);
4686 json_object_int_add(json_stat, "vxlanUpdates",
4687 router->mlag_stats.msg.vxlan_updates);
4688 json_object_object_add(json, "connStats", json_stat);
4689
4690 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4691 json, JSON_C_TO_STRING_PRETTY));
4692 json_object_free(json);
4693 return CMD_SUCCESS;
4694 }
4695
4696 vty_out(vty, "MLAG daemon connection: %s\n",
4697 (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
4698 ? "up" : "down");
4699 vty_out(vty, "MLAG peer state: %s\n",
4700 (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
4701 ? "up" : "down");
4702 vty_out(vty, "Zebra peer state: %s\n",
4703 (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
4704 ? "up" : "down");
4705 vty_out(vty, "MLAG role: %s\n",
4706 mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
4707 inet_ntop(AF_INET, &router->local_vtep_ip,
4708 addr_buf, INET_ADDRSTRLEN);
4709 vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
4710 inet_ntop(AF_INET, &router->anycast_vtep_ip,
4711 addr_buf, INET_ADDRSTRLEN);
4712 vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
4713 vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
4714 vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
4715 router->mlag_stats.mlagd_session_downs,
4716 router->mlag_stats.peer_session_downs,
4717 router->mlag_stats.peer_zebra_downs);
4718 vty_out(vty, "Message Statistics:\n");
4719 vty_out(vty, " mroute adds: rx: %d, tx: %d\n",
4720 router->mlag_stats.msg.mroute_add_rx,
4721 router->mlag_stats.msg.mroute_add_tx);
4722 vty_out(vty, " mroute dels: rx: %d, tx: %d\n",
4723 router->mlag_stats.msg.mroute_del_rx,
4724 router->mlag_stats.msg.mroute_del_tx);
4725 vty_out(vty, " peer zebra status updates: %d\n",
4726 router->mlag_stats.msg.peer_zebra_status_updates);
4727 vty_out(vty, " PIM status updates: %d\n",
4728 router->mlag_stats.msg.pim_status_updates);
4729 vty_out(vty, " VxLAN updates: %d\n",
4730 router->mlag_stats.msg.vxlan_updates);
4731
4732 return CMD_SUCCESS;
4733 }
4734
4735 static void pim_show_mlag_up_entry_detail(struct vrf *vrf,
4736 struct vty *vty, struct pim_upstream *up,
4737 char *src_str, char *grp_str, json_object *json)
4738 {
4739 if (json) {
4740 json_object *json_row = NULL;
4741 json_object *own_list = NULL;
4742 json_object *json_group = NULL;
4743
4744
4745 json_object_object_get_ex(json, grp_str, &json_group);
4746 if (!json_group) {
4747 json_group = json_object_new_object();
4748 json_object_object_add(json, grp_str,
4749 json_group);
4750 }
4751
4752 json_row = json_object_new_object();
4753 json_object_string_add(json_row, "source", src_str);
4754 json_object_string_add(json_row, "group", grp_str);
4755
4756 own_list = json_object_new_array();
4757 if (pim_up_mlag_is_local(up))
4758 json_object_array_add(own_list,
4759 json_object_new_string("local"));
4760 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
4761 json_object_array_add(own_list,
4762 json_object_new_string("peer"));
4763 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
4764 json_object_array_add(
4765 own_list, json_object_new_string("Interface"));
4766 json_object_object_add(json_row, "owners", own_list);
4767
4768 json_object_int_add(json_row, "localCost",
4769 pim_up_mlag_local_cost(up));
4770 json_object_int_add(json_row, "peerCost",
4771 pim_up_mlag_peer_cost(up));
4772 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
4773 json_object_boolean_false_add(json_row, "df");
4774 else
4775 json_object_boolean_true_add(json_row, "df");
4776 json_object_object_add(json_group, src_str, json_row);
4777 } else {
4778 char own_str[6];
4779
4780 own_str[0] = '\0';
4781 if (pim_up_mlag_is_local(up))
4782 strlcat(own_str, "L", sizeof(own_str));
4783 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
4784 strlcat(own_str, "P", sizeof(own_str));
4785 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
4786 strlcat(own_str, "I", sizeof(own_str));
4787 /* XXX - fixup, print paragraph output */
4788 vty_out(vty,
4789 "%-15s %-15s %-6s %-11u %-10d %2s\n",
4790 src_str, grp_str, own_str,
4791 pim_up_mlag_local_cost(up),
4792 pim_up_mlag_peer_cost(up),
4793 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
4794 ? "n" : "y");
4795 }
4796 }
4797
4798 static void pim_show_mlag_up_detail(struct vrf *vrf,
4799 struct vty *vty, const char *src_or_group,
4800 const char *group, bool uj)
4801 {
4802 char src_str[INET_ADDRSTRLEN];
4803 char grp_str[INET_ADDRSTRLEN];
4804 struct pim_upstream *up;
4805 struct pim_instance *pim = vrf->info;
4806 json_object *json = NULL;
4807
4808 if (uj)
4809 json = json_object_new_object();
4810 else
4811 vty_out(vty,
4812 "Source Group Owner Local-cost Peer-cost DF\n");
4813
4814 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
4815 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
4816 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
4817 && !pim_up_mlag_is_local(up))
4818 continue;
4819
4820 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
4821 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
4822 /* XXX: strcmps are clearly inefficient. we should do uint comps
4823 * here instead.
4824 */
4825 if (group) {
4826 if (strcmp(src_str, src_or_group) ||
4827 strcmp(grp_str, group))
4828 continue;
4829 } else {
4830 if (strcmp(src_str, src_or_group) &&
4831 strcmp(grp_str, src_or_group))
4832 continue;
4833 }
4834 pim_show_mlag_up_entry_detail(vrf, vty, up,
4835 src_str, grp_str, json);
4836 }
4837
4838 if (uj) {
4839 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4840 json, JSON_C_TO_STRING_PRETTY));
4841 json_object_free(json);
4842 }
4843 }
4844
4845 static void pim_show_mlag_up_vrf(struct vrf *vrf, struct vty *vty, bool uj)
4846 {
4847 json_object *json = NULL;
4848 json_object *json_row;
4849 struct pim_upstream *up;
4850 char src_str[INET_ADDRSTRLEN];
4851 char grp_str[INET_ADDRSTRLEN];
4852 struct pim_instance *pim = vrf->info;
4853 json_object *json_group = NULL;
4854
4855 if (uj) {
4856 json = json_object_new_object();
4857 } else {
4858 vty_out(vty,
4859 "Source Group Owner Local-cost Peer-cost DF\n");
4860 }
4861
4862 frr_each (rb_pim_upstream, &pim->upstream_head, up) {
4863 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
4864 && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
4865 && !pim_up_mlag_is_local(up))
4866 continue;
4867 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
4868 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
4869 if (uj) {
4870 json_object *own_list = NULL;
4871
4872 json_object_object_get_ex(json, grp_str, &json_group);
4873 if (!json_group) {
4874 json_group = json_object_new_object();
4875 json_object_object_add(json, grp_str,
4876 json_group);
4877 }
4878
4879 json_row = json_object_new_object();
4880 json_object_string_add(json_row, "vrf", vrf->name);
4881 json_object_string_add(json_row, "source", src_str);
4882 json_object_string_add(json_row, "group", grp_str);
4883
4884 own_list = json_object_new_array();
4885 if (pim_up_mlag_is_local(up)) {
4886
4887 json_object_array_add(own_list,
4888 json_object_new_string("local"));
4889 }
4890 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)) {
4891 json_object_array_add(own_list,
4892 json_object_new_string("peer"));
4893 }
4894 json_object_object_add(json_row, "owners", own_list);
4895
4896 json_object_int_add(json_row, "localCost",
4897 pim_up_mlag_local_cost(up));
4898 json_object_int_add(json_row, "peerCost",
4899 pim_up_mlag_peer_cost(up));
4900 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
4901 json_object_boolean_false_add(json_row, "df");
4902 else
4903 json_object_boolean_true_add(json_row, "df");
4904 json_object_object_add(json_group, src_str, json_row);
4905 } else {
4906 char own_str[6];
4907
4908 own_str[0] = '\0';
4909 if (pim_up_mlag_is_local(up))
4910 strlcat(own_str, "L", sizeof(own_str));
4911 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
4912 strlcat(own_str, "P", sizeof(own_str));
4913 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
4914 strlcat(own_str, "I", sizeof(own_str));
4915 vty_out(vty,
4916 "%-15s %-15s %-6s %-11u %-10u %2s\n",
4917 src_str, grp_str, own_str,
4918 pim_up_mlag_local_cost(up),
4919 pim_up_mlag_peer_cost(up),
4920 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
4921 ? "n" : "y");
4922 }
4923 }
4924 if (uj) {
4925 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4926 json, JSON_C_TO_STRING_PRETTY));
4927 json_object_free(json);
4928 }
4929 }
4930
4931 static void pim_show_mlag_help_string(struct vty *vty, bool uj)
4932 {
4933 if (!uj) {
4934 vty_out(vty, "Owner codes:\n");
4935 vty_out(vty,
4936 "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, "
4937 "P: Peer Entry\n");
4938 }
4939 }
4940
4941
4942 DEFUN(show_ip_pim_mlag_up, show_ip_pim_mlag_up_cmd,
4943 "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
4944 SHOW_STR
4945 IP_STR
4946 PIM_STR
4947 VRF_CMD_HELP_STR
4948 "MLAG\n"
4949 "upstream\n"
4950 "Unicast or Multicast address\n"
4951 "Multicast address\n" JSON_STR)
4952 {
4953 const char *src_or_group = NULL;
4954 const char *group = NULL;
4955 int idx = 2;
4956 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4957 bool uj = use_json(argc, argv);
4958
4959 if (!vrf || !vrf->info) {
4960 vty_out(vty, "%s: VRF or Info missing\n", __func__);
4961 return CMD_WARNING;
4962 }
4963
4964 if (uj)
4965 argc--;
4966
4967 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4968 src_or_group = argv[idx]->arg;
4969 if (idx + 1 < argc)
4970 group = argv[idx + 1]->arg;
4971 }
4972
4973 pim_show_mlag_help_string(vty, uj);
4974
4975 if (src_or_group)
4976 pim_show_mlag_up_detail(vrf, vty, src_or_group, group, uj);
4977 else
4978 pim_show_mlag_up_vrf(vrf, vty, uj);
4979
4980 return CMD_SUCCESS;
4981 }
4982
4983
4984 DEFUN(show_ip_pim_mlag_up_vrf_all, show_ip_pim_mlag_up_vrf_all_cmd,
4985 "show ip pim vrf all mlag upstream [json]",
4986 SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
4987 "MLAG\n"
4988 "upstream\n" JSON_STR)
4989 {
4990 struct vrf *vrf;
4991 bool uj = use_json(argc, argv);
4992
4993 pim_show_mlag_help_string(vty, uj);
4994 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4995 pim_show_mlag_up_vrf(vrf, vty, uj);
4996 }
4997
4998 return CMD_SUCCESS;
4999 }
5000
5001 DEFUN (show_ip_pim_neighbor,
5002 show_ip_pim_neighbor_cmd,
5003 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
5004 SHOW_STR
5005 IP_STR
5006 PIM_STR
5007 VRF_CMD_HELP_STR
5008 "PIM neighbor information\n"
5009 "Detailed output\n"
5010 "Name of interface or neighbor\n"
5011 JSON_STR)
5012 {
5013 int idx = 2;
5014 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5015 bool uj = use_json(argc, argv);
5016
5017 if (!vrf)
5018 return CMD_WARNING;
5019
5020 if (argv_find(argv, argc, "detail", &idx)
5021 || argv_find(argv, argc, "WORD", &idx))
5022 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
5023 else
5024 pim_show_neighbors(vrf->info, vty, uj);
5025
5026 return CMD_SUCCESS;
5027 }
5028
5029 DEFUN (show_ip_pim_neighbor_vrf_all,
5030 show_ip_pim_neighbor_vrf_all_cmd,
5031 "show ip pim vrf all neighbor [detail|WORD] [json]",
5032 SHOW_STR
5033 IP_STR
5034 PIM_STR
5035 VRF_CMD_HELP_STR
5036 "PIM neighbor information\n"
5037 "Detailed output\n"
5038 "Name of interface or neighbor\n"
5039 JSON_STR)
5040 {
5041 int idx = 2;
5042 bool uj = use_json(argc, argv);
5043 struct vrf *vrf;
5044 bool first = true;
5045
5046 if (uj)
5047 vty_out(vty, "{ ");
5048 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5049 if (uj) {
5050 if (!first)
5051 vty_out(vty, ", ");
5052 vty_out(vty, " \"%s\": ", vrf->name);
5053 first = false;
5054 } else
5055 vty_out(vty, "VRF: %s\n", vrf->name);
5056 if (argv_find(argv, argc, "detail", &idx)
5057 || argv_find(argv, argc, "WORD", &idx))
5058 pim_show_neighbors_single(vrf->info, vty,
5059 argv[idx]->arg, uj);
5060 else
5061 pim_show_neighbors(vrf->info, vty, uj);
5062 }
5063 if (uj)
5064 vty_out(vty, "}\n");
5065
5066 return CMD_SUCCESS;
5067 }
5068
5069 DEFUN (show_ip_pim_secondary,
5070 show_ip_pim_secondary_cmd,
5071 "show ip pim [vrf NAME] secondary",
5072 SHOW_STR
5073 IP_STR
5074 PIM_STR
5075 VRF_CMD_HELP_STR
5076 "PIM neighbor addresses\n")
5077 {
5078 int idx = 2;
5079 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5080
5081 if (!vrf)
5082 return CMD_WARNING;
5083
5084 pim_show_neighbors_secondary(vrf->info, vty);
5085
5086 return CMD_SUCCESS;
5087 }
5088
5089 DEFUN (show_ip_pim_state,
5090 show_ip_pim_state_cmd,
5091 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
5092 SHOW_STR
5093 IP_STR
5094 PIM_STR
5095 VRF_CMD_HELP_STR
5096 "PIM state information\n"
5097 "Unicast or Multicast address\n"
5098 "Multicast address\n"
5099 JSON_STR)
5100 {
5101 const char *src_or_group = NULL;
5102 const char *group = NULL;
5103 int idx = 2;
5104 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5105 bool uj = use_json(argc, argv);
5106
5107 if (!vrf)
5108 return CMD_WARNING;
5109
5110 if (uj)
5111 argc--;
5112
5113 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
5114 src_or_group = argv[idx]->arg;
5115 if (idx + 1 < argc)
5116 group = argv[idx + 1]->arg;
5117 }
5118
5119 pim_show_state(vrf->info, vty, src_or_group, group, uj);
5120
5121 return CMD_SUCCESS;
5122 }
5123
5124 DEFUN (show_ip_pim_state_vrf_all,
5125 show_ip_pim_state_vrf_all_cmd,
5126 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
5127 SHOW_STR
5128 IP_STR
5129 PIM_STR
5130 VRF_CMD_HELP_STR
5131 "PIM state information\n"
5132 "Unicast or Multicast address\n"
5133 "Multicast address\n"
5134 JSON_STR)
5135 {
5136 const char *src_or_group = NULL;
5137 const char *group = NULL;
5138 int idx = 2;
5139 bool uj = use_json(argc, argv);
5140 struct vrf *vrf;
5141 bool first = true;
5142
5143 if (uj) {
5144 vty_out(vty, "{ ");
5145 argc--;
5146 }
5147
5148 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
5149 src_or_group = argv[idx]->arg;
5150 if (idx + 1 < argc)
5151 group = argv[idx + 1]->arg;
5152 }
5153
5154 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5155 if (uj) {
5156 if (!first)
5157 vty_out(vty, ", ");
5158 vty_out(vty, " \"%s\": ", vrf->name);
5159 first = false;
5160 } else
5161 vty_out(vty, "VRF: %s\n", vrf->name);
5162 pim_show_state(vrf->info, vty, src_or_group, group, uj);
5163 }
5164 if (uj)
5165 vty_out(vty, "}\n");
5166
5167 return CMD_SUCCESS;
5168 }
5169
5170 DEFPY (show_ip_pim_upstream,
5171 show_ip_pim_upstream_cmd,
5172 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
5173 SHOW_STR
5174 IP_STR
5175 PIM_STR
5176 VRF_CMD_HELP_STR
5177 "PIM upstream information\n"
5178 "The Source or Group\n"
5179 "The Group\n"
5180 JSON_STR)
5181 {
5182 struct prefix_sg sg = {0};
5183 struct vrf *v;
5184 bool uj = !!json;
5185 struct pim_instance *pim;
5186
5187 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
5188
5189 if (!v) {
5190 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
5191 return CMD_WARNING;
5192 }
5193 pim = pim_get_pim_instance(v->vrf_id);
5194
5195 if (!pim) {
5196 vty_out(vty, "%% Unable to find pim instance\n");
5197 return CMD_WARNING;
5198 }
5199
5200 if (s_or_g.s_addr != 0) {
5201 if (g.s_addr != 0) {
5202 sg.src = s_or_g;
5203 sg.grp = g;
5204 } else
5205 sg.grp = s_or_g;
5206 }
5207 pim_show_upstream(pim, vty, &sg, uj);
5208
5209 return CMD_SUCCESS;
5210 }
5211
5212 DEFUN (show_ip_pim_upstream_vrf_all,
5213 show_ip_pim_upstream_vrf_all_cmd,
5214 "show ip pim vrf all upstream [json]",
5215 SHOW_STR
5216 IP_STR
5217 PIM_STR
5218 VRF_CMD_HELP_STR
5219 "PIM upstream information\n"
5220 JSON_STR)
5221 {
5222 struct prefix_sg sg = {0};
5223 bool uj = use_json(argc, argv);
5224 struct vrf *vrf;
5225 bool first = true;
5226
5227 if (uj)
5228 vty_out(vty, "{ ");
5229 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5230 if (uj) {
5231 if (!first)
5232 vty_out(vty, ", ");
5233 vty_out(vty, " \"%s\": ", vrf->name);
5234 first = false;
5235 } else
5236 vty_out(vty, "VRF: %s\n", vrf->name);
5237 pim_show_upstream(vrf->info, vty, &sg, uj);
5238 }
5239
5240 return CMD_SUCCESS;
5241 }
5242
5243 DEFUN (show_ip_pim_channel,
5244 show_ip_pim_channel_cmd,
5245 "show ip pim [vrf NAME] channel [json]",
5246 SHOW_STR
5247 IP_STR
5248 PIM_STR
5249 VRF_CMD_HELP_STR
5250 "PIM downstream channel info\n"
5251 JSON_STR)
5252 {
5253 int idx = 2;
5254 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5255 bool uj = use_json(argc, argv);
5256
5257 if (!vrf)
5258 return CMD_WARNING;
5259
5260 pim_show_channel(vrf->info, vty, uj);
5261
5262 return CMD_SUCCESS;
5263 }
5264
5265 DEFUN (show_ip_pim_upstream_join_desired,
5266 show_ip_pim_upstream_join_desired_cmd,
5267 "show ip pim [vrf NAME] upstream-join-desired [json]",
5268 SHOW_STR
5269 IP_STR
5270 PIM_STR
5271 VRF_CMD_HELP_STR
5272 "PIM upstream join-desired\n"
5273 JSON_STR)
5274 {
5275 int idx = 2;
5276 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5277 bool uj = use_json(argc, argv);
5278
5279 if (!vrf)
5280 return CMD_WARNING;
5281
5282 pim_show_join_desired(vrf->info, vty, uj);
5283
5284 return CMD_SUCCESS;
5285 }
5286
5287 DEFUN (show_ip_pim_upstream_rpf,
5288 show_ip_pim_upstream_rpf_cmd,
5289 "show ip pim [vrf NAME] upstream-rpf [json]",
5290 SHOW_STR
5291 IP_STR
5292 PIM_STR
5293 VRF_CMD_HELP_STR
5294 "PIM upstream source rpf\n"
5295 JSON_STR)
5296 {
5297 int idx = 2;
5298 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5299 bool uj = use_json(argc, argv);
5300
5301 if (!vrf)
5302 return CMD_WARNING;
5303
5304 pim_show_upstream_rpf(vrf->info, vty, uj);
5305
5306 return CMD_SUCCESS;
5307 }
5308
5309 DEFUN (show_ip_pim_rp,
5310 show_ip_pim_rp_cmd,
5311 "show ip pim [vrf NAME] rp-info [json]",
5312 SHOW_STR
5313 IP_STR
5314 PIM_STR
5315 VRF_CMD_HELP_STR
5316 "PIM RP information\n"
5317 JSON_STR)
5318 {
5319 int idx = 2;
5320 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5321 bool uj = use_json(argc, argv);
5322
5323 if (!vrf)
5324 return CMD_WARNING;
5325
5326 pim_rp_show_information(vrf->info, vty, uj);
5327
5328 return CMD_SUCCESS;
5329 }
5330
5331 DEFUN (show_ip_pim_rp_vrf_all,
5332 show_ip_pim_rp_vrf_all_cmd,
5333 "show ip pim vrf all rp-info [json]",
5334 SHOW_STR
5335 IP_STR
5336 PIM_STR
5337 VRF_CMD_HELP_STR
5338 "PIM RP information\n"
5339 JSON_STR)
5340 {
5341 bool uj = use_json(argc, argv);
5342 struct vrf *vrf;
5343 bool first = true;
5344
5345 if (uj)
5346 vty_out(vty, "{ ");
5347 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5348 if (uj) {
5349 if (!first)
5350 vty_out(vty, ", ");
5351 vty_out(vty, " \"%s\": ", vrf->name);
5352 first = false;
5353 } else
5354 vty_out(vty, "VRF: %s\n", vrf->name);
5355 pim_rp_show_information(vrf->info, vty, uj);
5356 }
5357 if (uj)
5358 vty_out(vty, "}\n");
5359
5360 return CMD_SUCCESS;
5361 }
5362
5363 DEFUN (show_ip_pim_rpf,
5364 show_ip_pim_rpf_cmd,
5365 "show ip pim [vrf NAME] rpf [json]",
5366 SHOW_STR
5367 IP_STR
5368 PIM_STR
5369 VRF_CMD_HELP_STR
5370 "PIM cached source rpf information\n"
5371 JSON_STR)
5372 {
5373 int idx = 2;
5374 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5375 bool uj = use_json(argc, argv);
5376
5377 if (!vrf)
5378 return CMD_WARNING;
5379
5380 pim_show_rpf(vrf->info, vty, uj);
5381
5382 return CMD_SUCCESS;
5383 }
5384
5385 DEFUN (show_ip_pim_rpf_vrf_all,
5386 show_ip_pim_rpf_vrf_all_cmd,
5387 "show ip pim vrf all rpf [json]",
5388 SHOW_STR
5389 IP_STR
5390 PIM_STR
5391 VRF_CMD_HELP_STR
5392 "PIM cached source rpf information\n"
5393 JSON_STR)
5394 {
5395 bool uj = use_json(argc, argv);
5396 struct vrf *vrf;
5397 bool first = true;
5398
5399 if (uj)
5400 vty_out(vty, "{ ");
5401 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5402 if (uj) {
5403 if (!first)
5404 vty_out(vty, ", ");
5405 vty_out(vty, " \"%s\": ", vrf->name);
5406 first = false;
5407 } else
5408 vty_out(vty, "VRF: %s\n", vrf->name);
5409 pim_show_rpf(vrf->info, vty, uj);
5410 }
5411 if (uj)
5412 vty_out(vty, "}\n");
5413
5414 return CMD_SUCCESS;
5415 }
5416
5417 DEFUN (show_ip_pim_nexthop,
5418 show_ip_pim_nexthop_cmd,
5419 "show ip pim [vrf NAME] nexthop",
5420 SHOW_STR
5421 IP_STR
5422 PIM_STR
5423 VRF_CMD_HELP_STR
5424 "PIM cached nexthop rpf information\n")
5425 {
5426 int idx = 2;
5427 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5428
5429 if (!vrf)
5430 return CMD_WARNING;
5431
5432 pim_show_nexthop(vrf->info, vty);
5433
5434 return CMD_SUCCESS;
5435 }
5436
5437 DEFUN (show_ip_pim_nexthop_lookup,
5438 show_ip_pim_nexthop_lookup_cmd,
5439 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5440 SHOW_STR
5441 IP_STR
5442 PIM_STR
5443 VRF_CMD_HELP_STR
5444 "PIM cached nexthop rpf lookup\n"
5445 "Source/RP address\n"
5446 "Multicast Group address\n")
5447 {
5448 struct prefix nht_p;
5449 int result = 0;
5450 struct in_addr src_addr, grp_addr;
5451 struct in_addr vif_source;
5452 const char *addr_str, *addr_str1;
5453 struct prefix grp;
5454 struct pim_nexthop nexthop;
5455 char nexthop_addr_str[PREFIX_STRLEN];
5456 char grp_str[PREFIX_STRLEN];
5457 int idx = 2;
5458 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5459
5460 if (!vrf)
5461 return CMD_WARNING;
5462
5463 argv_find(argv, argc, "A.B.C.D", &idx);
5464 addr_str = argv[idx]->arg;
5465 result = inet_pton(AF_INET, addr_str, &src_addr);
5466 if (result <= 0) {
5467 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5468 errno, safe_strerror(errno));
5469 return CMD_WARNING;
5470 }
5471
5472 if (pim_is_group_224_4(src_addr)) {
5473 vty_out(vty,
5474 "Invalid argument. Expected Valid Source Address.\n");
5475 return CMD_WARNING;
5476 }
5477
5478 addr_str1 = argv[idx + 1]->arg;
5479 result = inet_pton(AF_INET, addr_str1, &grp_addr);
5480 if (result <= 0) {
5481 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5482 errno, safe_strerror(errno));
5483 return CMD_WARNING;
5484 }
5485
5486 if (!pim_is_group_224_4(grp_addr)) {
5487 vty_out(vty,
5488 "Invalid argument. Expected Valid Multicast Group Address.\n");
5489 return CMD_WARNING;
5490 }
5491
5492 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
5493 grp_addr))
5494 return CMD_SUCCESS;
5495
5496 nht_p.family = AF_INET;
5497 nht_p.prefixlen = IPV4_MAX_BITLEN;
5498 nht_p.u.prefix4 = vif_source;
5499 grp.family = AF_INET;
5500 grp.prefixlen = IPV4_MAX_BITLEN;
5501 grp.u.prefix4 = grp_addr;
5502 memset(&nexthop, 0, sizeof(nexthop));
5503
5504 result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
5505
5506 if (!result) {
5507 vty_out(vty,
5508 "Nexthop Lookup failed, no usable routes returned.\n");
5509 return CMD_SUCCESS;
5510 }
5511
5512 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
5513 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
5514 nexthop_addr_str, sizeof(nexthop_addr_str));
5515 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
5516 nexthop_addr_str, nexthop.interface->name);
5517
5518 return CMD_SUCCESS;
5519 }
5520
5521 DEFUN (show_ip_pim_interface_traffic,
5522 show_ip_pim_interface_traffic_cmd,
5523 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5524 SHOW_STR
5525 IP_STR
5526 PIM_STR
5527 VRF_CMD_HELP_STR
5528 "PIM interface information\n"
5529 "Protocol Packet counters\n"
5530 "Interface name\n"
5531 JSON_STR)
5532 {
5533 int idx = 2;
5534 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5535 bool uj = use_json(argc, argv);
5536
5537 if (!vrf)
5538 return CMD_WARNING;
5539
5540 if (argv_find(argv, argc, "WORD", &idx))
5541 pim_show_interface_traffic_single(vrf->info, vty,
5542 argv[idx]->arg, uj);
5543 else
5544 pim_show_interface_traffic(vrf->info, vty, uj);
5545
5546 return CMD_SUCCESS;
5547 }
5548
5549 DEFUN (show_ip_pim_bsm_db,
5550 show_ip_pim_bsm_db_cmd,
5551 "show ip pim bsm-database [vrf NAME] [json]",
5552 SHOW_STR
5553 IP_STR
5554 PIM_STR
5555 "PIM cached bsm packets information\n"
5556 VRF_CMD_HELP_STR
5557 JSON_STR)
5558 {
5559 int idx = 2;
5560 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5561 bool uj = use_json(argc, argv);
5562
5563 if (!vrf)
5564 return CMD_WARNING;
5565
5566 pim_show_bsm_db(vrf->info, vty, uj);
5567 return CMD_SUCCESS;
5568 }
5569
5570 DEFUN (show_ip_pim_bsrp,
5571 show_ip_pim_bsrp_cmd,
5572 "show ip pim bsrp-info [vrf NAME] [json]",
5573 SHOW_STR
5574 IP_STR
5575 PIM_STR
5576 "PIM cached group-rp mappings information\n"
5577 VRF_CMD_HELP_STR
5578 JSON_STR)
5579 {
5580 int idx = 2;
5581 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5582 bool uj = use_json(argc, argv);
5583
5584 if (!vrf)
5585 return CMD_WARNING;
5586
5587 pim_show_group_rp_mappings_info(vrf->info, vty, uj);
5588
5589 return CMD_SUCCESS;
5590 }
5591
5592 DEFUN (show_ip_pim_statistics,
5593 show_ip_pim_statistics_cmd,
5594 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5595 SHOW_STR
5596 IP_STR
5597 PIM_STR
5598 VRF_CMD_HELP_STR
5599 "PIM statistics\n"
5600 INTERFACE_STR
5601 "PIM interface\n"
5602 JSON_STR)
5603 {
5604 int idx = 2;
5605 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5606 bool uj = use_json(argc, argv);
5607
5608 if (!vrf)
5609 return CMD_WARNING;
5610
5611 if (argv_find(argv, argc, "WORD", &idx))
5612 pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
5613 else
5614 pim_show_statistics(vrf->info, vty, NULL, uj);
5615
5616 return CMD_SUCCESS;
5617 }
5618
5619 static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
5620 {
5621 struct interface *ifp;
5622
5623 vty_out(vty, "\n");
5624
5625 vty_out(vty,
5626 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5627
5628 FOR_ALL_INTERFACES (pim->vrf, ifp) {
5629 struct pim_interface *pim_ifp;
5630 struct in_addr ifaddr;
5631 struct sioc_vif_req vreq;
5632
5633 pim_ifp = ifp->info;
5634
5635 if (!pim_ifp)
5636 continue;
5637
5638 memset(&vreq, 0, sizeof(vreq));
5639 vreq.vifi = pim_ifp->mroute_vif_index;
5640
5641 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
5642 zlog_warn(
5643 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5644 (unsigned long)SIOCGETVIFCNT, ifp->name,
5645 pim_ifp->mroute_vif_index, errno,
5646 safe_strerror(errno));
5647 }
5648
5649 ifaddr = pim_ifp->primary_address;
5650
5651 vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5652 ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
5653 pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
5654 (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
5655 (unsigned long)vreq.obytes);
5656 }
5657 }
5658
5659 static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
5660 struct vty *vty)
5661 {
5662 struct vrf *vrf = pim->vrf;
5663 time_t now = pim_time_monotonic_sec();
5664 char uptime[10];
5665 char mlag_role[80];
5666
5667 pim = vrf->info;
5668
5669 vty_out(vty, "Router MLAG Role: %s\n",
5670 mlag_role2str(router->mlag_role, mlag_role, sizeof(mlag_role)));
5671 vty_out(vty, "Mroute socket descriptor:");
5672
5673 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
5674
5675 pim_time_uptime(uptime, sizeof(uptime),
5676 now - pim->mroute_socket_creation);
5677 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
5678
5679 vty_out(vty, "\n");
5680
5681 pim_zebra_zclient_update(vty);
5682 pim_zlookup_show_ip_multicast(vty);
5683
5684 vty_out(vty, "\n");
5685 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
5686
5687 vty_out(vty, "\n");
5688 vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
5689 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
5690 vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
5691 vty_out(vty, "PIM ECMP Rebalance: %s\n",
5692 pim->ecmp_rebalance_enable ? "Enable" : "Disable");
5693
5694 vty_out(vty, "\n");
5695
5696 show_rpf_refresh_stats(vty, pim, now, NULL);
5697
5698 vty_out(vty, "\n");
5699
5700 show_scan_oil_stats(pim, vty, now);
5701
5702 show_multicast_interfaces(pim, vty);
5703 }
5704
5705 DEFUN (show_ip_multicast,
5706 show_ip_multicast_cmd,
5707 "show ip multicast [vrf NAME]",
5708 SHOW_STR
5709 IP_STR
5710 VRF_CMD_HELP_STR
5711 "Multicast global information\n")
5712 {
5713 int idx = 2;
5714 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5715
5716 if (!vrf)
5717 return CMD_WARNING;
5718
5719 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5720
5721 return CMD_SUCCESS;
5722 }
5723
5724 DEFUN (show_ip_multicast_vrf_all,
5725 show_ip_multicast_vrf_all_cmd,
5726 "show ip multicast vrf all",
5727 SHOW_STR
5728 IP_STR
5729 VRF_CMD_HELP_STR
5730 "Multicast global information\n")
5731 {
5732 bool uj = use_json(argc, argv);
5733 struct vrf *vrf;
5734 bool first = true;
5735
5736 if (uj)
5737 vty_out(vty, "{ ");
5738 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5739 if (uj) {
5740 if (!first)
5741 vty_out(vty, ", ");
5742 vty_out(vty, " \"%s\": ", vrf->name);
5743 first = false;
5744 } else
5745 vty_out(vty, "VRF: %s\n", vrf->name);
5746 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5747 }
5748 if (uj)
5749 vty_out(vty, "}\n");
5750
5751 return CMD_SUCCESS;
5752 }
5753
5754 static void show_mroute(struct pim_instance *pim, struct vty *vty,
5755 struct prefix_sg *sg, bool fill, bool uj)
5756 {
5757 struct listnode *node;
5758 struct channel_oil *c_oil;
5759 struct static_route *s_route;
5760 time_t now;
5761 json_object *json = NULL;
5762 json_object *json_group = NULL;
5763 json_object *json_source = NULL;
5764 json_object *json_oil = NULL;
5765 json_object *json_ifp_out = NULL;
5766 int found_oif;
5767 int first;
5768 char grp_str[INET_ADDRSTRLEN];
5769 char src_str[INET_ADDRSTRLEN];
5770 char in_ifname[INTERFACE_NAMSIZ + 1];
5771 char out_ifname[INTERFACE_NAMSIZ + 1];
5772 int oif_vif_index;
5773 struct interface *ifp_in;
5774 char proto[100];
5775
5776 if (uj) {
5777 json = json_object_new_object();
5778 } else {
5779 vty_out(vty,
5780 "Source Group Proto Input Output TTL Uptime\n");
5781 }
5782
5783 now = pim_time_monotonic_sec();
5784
5785 /* print list of PIM and IGMP routes */
5786 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
5787 found_oif = 0;
5788 first = 1;
5789 if (!c_oil->installed && !uj)
5790 continue;
5791
5792 if (sg->grp.s_addr != 0 &&
5793 sg->grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr)
5794 continue;
5795 if (sg->src.s_addr != 0 &&
5796 sg->src.s_addr != c_oil->oil.mfcc_origin.s_addr)
5797 continue;
5798
5799 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
5800 sizeof(grp_str));
5801 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
5802 sizeof(src_str));
5803 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
5804
5805 if (ifp_in)
5806 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
5807 else
5808 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
5809
5810 if (uj) {
5811
5812 /* Find the group, create it if it doesn't exist */
5813 json_object_object_get_ex(json, grp_str, &json_group);
5814
5815 if (!json_group) {
5816 json_group = json_object_new_object();
5817 json_object_object_add(json, grp_str,
5818 json_group);
5819 }
5820
5821 /* Find the source nested under the group, create it if
5822 * it doesn't exist */
5823 json_object_object_get_ex(json_group, src_str,
5824 &json_source);
5825
5826 if (!json_source) {
5827 json_source = json_object_new_object();
5828 json_object_object_add(json_group, src_str,
5829 json_source);
5830 }
5831
5832 /* Find the inbound interface nested under the source,
5833 * create it if it doesn't exist */
5834 json_object_int_add(json_source, "installed",
5835 c_oil->installed);
5836 json_object_int_add(json_source, "refCount",
5837 c_oil->oil_ref_count);
5838 json_object_int_add(json_source, "oilSize",
5839 c_oil->oil_size);
5840 json_object_int_add(json_source, "OilInheritedRescan",
5841 c_oil->oil_inherited_rescan);
5842 json_object_string_add(json_source, "iif", in_ifname);
5843 json_oil = NULL;
5844 }
5845
5846 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5847 ++oif_vif_index) {
5848 struct interface *ifp_out;
5849 char mroute_uptime[10];
5850 int ttl;
5851
5852 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
5853 if (ttl < 1)
5854 continue;
5855
5856 /* do not display muted OIFs */
5857 if (c_oil->oif_flags[oif_vif_index]
5858 & PIM_OIF_FLAG_MUTE)
5859 continue;
5860
5861 if (c_oil->oil.mfcc_parent == oif_vif_index &&
5862 !pim_mroute_allow_iif_in_oil(c_oil,
5863 oif_vif_index))
5864 continue;
5865
5866 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
5867 pim_time_uptime(
5868 mroute_uptime, sizeof(mroute_uptime),
5869 now - c_oil->mroute_creation);
5870 found_oif = 1;
5871
5872 if (ifp_out)
5873 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
5874 else
5875 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
5876
5877 if (uj) {
5878 json_ifp_out = json_object_new_object();
5879 json_object_string_add(json_ifp_out, "source",
5880 src_str);
5881 json_object_string_add(json_ifp_out, "group",
5882 grp_str);
5883
5884 if (c_oil->oif_flags[oif_vif_index]
5885 & PIM_OIF_FLAG_PROTO_PIM)
5886 json_object_boolean_true_add(
5887 json_ifp_out, "protocolPim");
5888
5889 if (c_oil->oif_flags[oif_vif_index]
5890 & PIM_OIF_FLAG_PROTO_IGMP)
5891 json_object_boolean_true_add(
5892 json_ifp_out, "protocolIgmp");
5893
5894 if (c_oil->oif_flags[oif_vif_index]
5895 & PIM_OIF_FLAG_PROTO_VXLAN)
5896 json_object_boolean_true_add(
5897 json_ifp_out, "protocolVxlan");
5898
5899 if (c_oil->oif_flags[oif_vif_index]
5900 & PIM_OIF_FLAG_PROTO_STAR)
5901 json_object_boolean_true_add(
5902 json_ifp_out,
5903 "protocolInherited");
5904
5905 json_object_string_add(json_ifp_out,
5906 "inboundInterface",
5907 in_ifname);
5908 json_object_int_add(json_ifp_out, "iVifI",
5909 c_oil->oil.mfcc_parent);
5910 json_object_string_add(json_ifp_out,
5911 "outboundInterface",
5912 out_ifname);
5913 json_object_int_add(json_ifp_out, "oVifI",
5914 oif_vif_index);
5915 json_object_int_add(json_ifp_out, "ttl", ttl);
5916 json_object_string_add(json_ifp_out, "upTime",
5917 mroute_uptime);
5918 if (!json_oil) {
5919 json_oil = json_object_new_object();
5920 json_object_object_add(json_source,
5921 "oil", json_oil);
5922 }
5923 json_object_object_add(json_oil, out_ifname,
5924 json_ifp_out);
5925 } else {
5926 if (c_oil->oif_flags[oif_vif_index]
5927 & PIM_OIF_FLAG_PROTO_PIM) {
5928 strlcpy(proto, "PIM", sizeof(proto));
5929 }
5930
5931 if (c_oil->oif_flags[oif_vif_index]
5932 & PIM_OIF_FLAG_PROTO_IGMP) {
5933 strlcpy(proto, "IGMP", sizeof(proto));
5934 }
5935
5936 if (c_oil->oif_flags[oif_vif_index]
5937 & PIM_OIF_FLAG_PROTO_VXLAN) {
5938 strlcpy(proto, "VxLAN", sizeof(proto));
5939 }
5940
5941 if (c_oil->oif_flags[oif_vif_index]
5942 & PIM_OIF_FLAG_PROTO_STAR) {
5943 strlcpy(proto, "STAR", sizeof(proto));
5944 }
5945
5946 vty_out(vty,
5947 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5948 src_str, grp_str, proto, in_ifname,
5949 out_ifname, ttl, mroute_uptime);
5950
5951 if (first) {
5952 src_str[0] = '\0';
5953 grp_str[0] = '\0';
5954 in_ifname[0] = '\0';
5955 first = 0;
5956 }
5957 }
5958 }
5959
5960 if (!uj && !found_oif) {
5961 vty_out(vty, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5962 src_str, grp_str, "none", in_ifname, "none", 0,
5963 "--:--:--");
5964 }
5965 }
5966
5967 /* Print list of static routes */
5968 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5969 first = 1;
5970
5971 if (!s_route->c_oil.installed)
5972 continue;
5973
5974 pim_inet4_dump("<group?>", s_route->group, grp_str,
5975 sizeof(grp_str));
5976 pim_inet4_dump("<source?>", s_route->source, src_str,
5977 sizeof(src_str));
5978 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
5979 found_oif = 0;
5980
5981 if (ifp_in)
5982 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
5983 else
5984 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
5985
5986 if (uj) {
5987
5988 /* Find the group, create it if it doesn't exist */
5989 json_object_object_get_ex(json, grp_str, &json_group);
5990
5991 if (!json_group) {
5992 json_group = json_object_new_object();
5993 json_object_object_add(json, grp_str,
5994 json_group);
5995 }
5996
5997 /* Find the source nested under the group, create it if
5998 * it doesn't exist */
5999 json_object_object_get_ex(json_group, src_str,
6000 &json_source);
6001
6002 if (!json_source) {
6003 json_source = json_object_new_object();
6004 json_object_object_add(json_group, src_str,
6005 json_source);
6006 }
6007
6008 json_object_string_add(json_source, "iif", in_ifname);
6009 json_oil = NULL;
6010 } else {
6011 strlcpy(proto, "STATIC", sizeof(proto));
6012 }
6013
6014 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
6015 ++oif_vif_index) {
6016 struct interface *ifp_out;
6017 char oif_uptime[10];
6018 int ttl;
6019
6020 ttl = s_route->oif_ttls[oif_vif_index];
6021 if (ttl < 1)
6022 continue;
6023
6024 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
6025 pim_time_uptime(
6026 oif_uptime, sizeof(oif_uptime),
6027 now
6028 - s_route->c_oil
6029 .oif_creation[oif_vif_index]);
6030 found_oif = 1;
6031
6032 if (ifp_out)
6033 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
6034 else
6035 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
6036
6037 if (uj) {
6038 json_ifp_out = json_object_new_object();
6039 json_object_string_add(json_ifp_out, "source",
6040 src_str);
6041 json_object_string_add(json_ifp_out, "group",
6042 grp_str);
6043 json_object_boolean_true_add(json_ifp_out,
6044 "protocolStatic");
6045 json_object_string_add(json_ifp_out,
6046 "inboundInterface",
6047 in_ifname);
6048 json_object_int_add(
6049 json_ifp_out, "iVifI",
6050 s_route->c_oil.oil.mfcc_parent);
6051 json_object_string_add(json_ifp_out,
6052 "outboundInterface",
6053 out_ifname);
6054 json_object_int_add(json_ifp_out, "oVifI",
6055 oif_vif_index);
6056 json_object_int_add(json_ifp_out, "ttl", ttl);
6057 json_object_string_add(json_ifp_out, "upTime",
6058 oif_uptime);
6059 if (!json_oil) {
6060 json_oil = json_object_new_object();
6061 json_object_object_add(json_source,
6062 "oil", json_oil);
6063 }
6064 json_object_object_add(json_oil, out_ifname,
6065 json_ifp_out);
6066 } else {
6067 vty_out(vty,
6068 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6069 src_str, grp_str, proto, in_ifname,
6070 out_ifname, ttl, oif_uptime,
6071 pim->vrf->name);
6072 if (first && !fill) {
6073 src_str[0] = '\0';
6074 grp_str[0] = '\0';
6075 in_ifname[0] = '\0';
6076 first = 0;
6077 }
6078 }
6079 }
6080
6081 if (!uj && !found_oif) {
6082 vty_out(vty,
6083 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
6084 src_str, grp_str, proto, in_ifname, "none", 0,
6085 "--:--:--", pim->vrf->name);
6086 }
6087 }
6088
6089 if (uj) {
6090 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6091 json, JSON_C_TO_STRING_PRETTY));
6092 json_object_free(json);
6093 }
6094 }
6095
6096 DEFPY (show_ip_mroute,
6097 show_ip_mroute_cmd,
6098 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
6099 SHOW_STR
6100 IP_STR
6101 MROUTE_STR
6102 VRF_CMD_HELP_STR
6103 "The Source or Group\n"
6104 "The Group\n"
6105 "Fill in Assumed data\n"
6106 JSON_STR)
6107 {
6108 struct prefix_sg sg = {0};
6109 struct pim_instance *pim;
6110 struct vrf *v;
6111
6112 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
6113
6114 if (!v) {
6115 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
6116 return CMD_WARNING;
6117 }
6118 pim = pim_get_pim_instance(v->vrf_id);
6119
6120 if (!pim) {
6121 vty_out(vty, "%% Unable to find pim instance\n");
6122 return CMD_WARNING;
6123 }
6124
6125 if (s_or_g.s_addr != 0) {
6126 if (g.s_addr != 0) {
6127 sg.src = s_or_g;
6128 sg.grp = g;
6129 } else
6130 sg.grp = s_or_g;
6131 }
6132 show_mroute(pim, vty, &sg, !!fill, !!json);
6133 return CMD_SUCCESS;
6134 }
6135
6136 DEFUN (show_ip_mroute_vrf_all,
6137 show_ip_mroute_vrf_all_cmd,
6138 "show ip mroute vrf all [fill] [json]",
6139 SHOW_STR
6140 IP_STR
6141 MROUTE_STR
6142 VRF_CMD_HELP_STR
6143 "Fill in Assumed data\n"
6144 JSON_STR)
6145 {
6146 struct prefix_sg sg = {0};
6147 bool uj = use_json(argc, argv);
6148 int idx = 4;
6149 struct vrf *vrf;
6150 bool first = true;
6151 bool fill = false;
6152
6153 if (argv_find(argv, argc, "fill", &idx))
6154 fill = true;
6155
6156 if (uj)
6157 vty_out(vty, "{ ");
6158 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
6159 if (uj) {
6160 if (!first)
6161 vty_out(vty, ", ");
6162 vty_out(vty, " \"%s\": ", vrf->name);
6163 first = false;
6164 } else
6165 vty_out(vty, "VRF: %s\n", vrf->name);
6166 show_mroute(vrf->info, vty, &sg, fill, uj);
6167 }
6168 if (uj)
6169 vty_out(vty, "}\n");
6170
6171 return CMD_SUCCESS;
6172 }
6173
6174 DEFUN (clear_ip_mroute_count,
6175 clear_ip_mroute_count_cmd,
6176 "clear ip mroute [vrf NAME] count",
6177 CLEAR_STR
6178 IP_STR
6179 MROUTE_STR
6180 VRF_CMD_HELP_STR
6181 "Route and packet count data\n")
6182 {
6183 int idx = 2;
6184 struct listnode *node;
6185 struct channel_oil *c_oil;
6186 struct static_route *sr;
6187 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6188 struct pim_instance *pim;
6189
6190 if (!vrf)
6191 return CMD_WARNING;
6192
6193 pim = vrf->info;
6194 frr_each(rb_pim_oil, &pim->channel_oil_head, c_oil) {
6195 if (!c_oil->installed)
6196 continue;
6197
6198 pim_mroute_update_counters(c_oil);
6199 c_oil->cc.origpktcnt = c_oil->cc.pktcnt;
6200 c_oil->cc.origbytecnt = c_oil->cc.bytecnt;
6201 c_oil->cc.origwrong_if = c_oil->cc.wrong_if;
6202 }
6203
6204 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
6205 if (!sr->c_oil.installed)
6206 continue;
6207
6208 pim_mroute_update_counters(&sr->c_oil);
6209
6210 sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt;
6211 sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt;
6212 sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if;
6213 }
6214 return CMD_SUCCESS;
6215 }
6216
6217 static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
6218 {
6219 struct listnode *node;
6220 struct channel_oil *c_oil;
6221 struct static_route *sr;
6222
6223 vty_out(vty, "\n");
6224
6225 vty_out(vty,
6226 "Source Group LastUsed Packets Bytes WrongIf \n");
6227
6228 /* Print PIM and IGMP route counts */
6229 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
6230 char group_str[INET_ADDRSTRLEN];
6231 char source_str[INET_ADDRSTRLEN];
6232
6233 if (!c_oil->installed)
6234 continue;
6235
6236 pim_mroute_update_counters(c_oil);
6237
6238 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
6239 sizeof(group_str));
6240 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
6241 sizeof(source_str));
6242
6243 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6244 source_str, group_str, c_oil->cc.lastused / 100,
6245 c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
6246 c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
6247 c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
6248 }
6249
6250 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
6251 char group_str[INET_ADDRSTRLEN];
6252 char source_str[INET_ADDRSTRLEN];
6253
6254 if (!sr->c_oil.installed)
6255 continue;
6256
6257 pim_mroute_update_counters(&sr->c_oil);
6258
6259 pim_inet4_dump("<group?>", sr->c_oil.oil.mfcc_mcastgrp,
6260 group_str, sizeof(group_str));
6261 pim_inet4_dump("<source?>", sr->c_oil.oil.mfcc_origin,
6262 source_str, sizeof(source_str));
6263
6264 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
6265 source_str, group_str, sr->c_oil.cc.lastused,
6266 sr->c_oil.cc.pktcnt - sr->c_oil.cc.origpktcnt,
6267 sr->c_oil.cc.bytecnt - sr->c_oil.cc.origbytecnt,
6268 sr->c_oil.cc.wrong_if - sr->c_oil.cc.origwrong_if);
6269 }
6270 }
6271
6272 DEFUN (show_ip_mroute_count,
6273 show_ip_mroute_count_cmd,
6274 "show ip mroute [vrf NAME] count",
6275 SHOW_STR
6276 IP_STR
6277 MROUTE_STR
6278 VRF_CMD_HELP_STR
6279 "Route and packet count data\n")
6280 {
6281 int idx = 2;
6282 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6283
6284 if (!vrf)
6285 return CMD_WARNING;
6286
6287 show_mroute_count(vrf->info, vty);
6288 return CMD_SUCCESS;
6289 }
6290
6291 DEFUN (show_ip_mroute_count_vrf_all,
6292 show_ip_mroute_count_vrf_all_cmd,
6293 "show ip mroute vrf all count",
6294 SHOW_STR
6295 IP_STR
6296 MROUTE_STR
6297 VRF_CMD_HELP_STR
6298 "Route and packet count data\n")
6299 {
6300 bool uj = use_json(argc, argv);
6301 struct vrf *vrf;
6302 bool first = true;
6303
6304 if (uj)
6305 vty_out(vty, "{ ");
6306 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
6307 if (uj) {
6308 if (!first)
6309 vty_out(vty, ", ");
6310 vty_out(vty, " \"%s\": ", vrf->name);
6311 first = false;
6312 } else
6313 vty_out(vty, "VRF: %s\n", vrf->name);
6314 show_mroute_count(vrf->info, vty);
6315 }
6316 if (uj)
6317 vty_out(vty, "}\n");
6318
6319 return CMD_SUCCESS;
6320 }
6321
6322 static void show_mroute_summary(struct pim_instance *pim, struct vty *vty)
6323 {
6324 struct listnode *node;
6325 struct channel_oil *c_oil;
6326 struct static_route *s_route;
6327 uint32_t starg_sw_mroute_cnt = 0;
6328 uint32_t sg_sw_mroute_cnt = 0;
6329 uint32_t starg_hw_mroute_cnt = 0;
6330 uint32_t sg_hw_mroute_cnt = 0;
6331
6332 vty_out(vty, "Mroute Type Installed/Total\n");
6333
6334 frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
6335 if (!c_oil->installed) {
6336 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
6337 starg_sw_mroute_cnt++;
6338 else
6339 sg_sw_mroute_cnt++;
6340 } else {
6341 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
6342 starg_hw_mroute_cnt++;
6343 else
6344 sg_hw_mroute_cnt++;
6345 }
6346 }
6347
6348 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
6349 if (!s_route->c_oil.installed) {
6350 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
6351 starg_sw_mroute_cnt++;
6352 else
6353 sg_sw_mroute_cnt++;
6354 } else {
6355 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
6356 starg_hw_mroute_cnt++;
6357 else
6358 sg_hw_mroute_cnt++;
6359 }
6360 }
6361
6362 vty_out(vty, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt,
6363 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
6364 vty_out(vty, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt,
6365 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
6366 vty_out(vty, "------\n");
6367 vty_out(vty, "%-20s %d/%d\n", "Total",
6368 (starg_hw_mroute_cnt + sg_hw_mroute_cnt),
6369 (starg_sw_mroute_cnt +
6370 starg_hw_mroute_cnt +
6371 sg_sw_mroute_cnt +
6372 sg_hw_mroute_cnt));
6373 }
6374
6375 DEFUN (show_ip_mroute_summary,
6376 show_ip_mroute_summary_cmd,
6377 "show ip mroute [vrf NAME] summary",
6378 SHOW_STR
6379 IP_STR
6380 MROUTE_STR
6381 VRF_CMD_HELP_STR
6382 "Summary of all mroutes\n")
6383 {
6384 int idx = 2;
6385 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6386
6387 if (!vrf)
6388 return CMD_WARNING;
6389
6390 show_mroute_summary(vrf->info, vty);
6391 return CMD_SUCCESS;
6392 }
6393
6394 DEFUN (show_ip_mroute_summary_vrf_all,
6395 show_ip_mroute_summary_vrf_all_cmd,
6396 "show ip mroute vrf all summary",
6397 SHOW_STR
6398 IP_STR
6399 MROUTE_STR
6400 VRF_CMD_HELP_STR
6401 "Summary of all mroutes\n")
6402 {
6403 struct vrf *vrf;
6404
6405 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
6406 vty_out(vty, "VRF: %s\n", vrf->name);
6407 show_mroute_summary(vrf->info, vty);
6408 }
6409
6410 return CMD_SUCCESS;
6411 }
6412
6413 DEFUN (show_ip_rib,
6414 show_ip_rib_cmd,
6415 "show ip rib [vrf NAME] A.B.C.D",
6416 SHOW_STR
6417 IP_STR
6418 RIB_STR
6419 VRF_CMD_HELP_STR
6420 "Unicast address\n")
6421 {
6422 int idx = 2;
6423 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6424 struct in_addr addr;
6425 const char *addr_str;
6426 struct pim_nexthop nexthop;
6427 char nexthop_addr_str[PREFIX_STRLEN];
6428 int result;
6429
6430 if (!vrf)
6431 return CMD_WARNING;
6432
6433 memset(&nexthop, 0, sizeof(nexthop));
6434 argv_find(argv, argc, "A.B.C.D", &idx);
6435 addr_str = argv[idx]->arg;
6436 result = inet_pton(AF_INET, addr_str, &addr);
6437 if (result <= 0) {
6438 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
6439 errno, safe_strerror(errno));
6440 return CMD_WARNING;
6441 }
6442
6443 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
6444 vty_out(vty,
6445 "Failure querying RIB nexthop for unicast address %s\n",
6446 addr_str);
6447 return CMD_WARNING;
6448 }
6449
6450 vty_out(vty,
6451 "Address NextHop Interface Metric Preference\n");
6452
6453 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
6454 nexthop_addr_str, sizeof(nexthop_addr_str));
6455
6456 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
6457 nexthop.interface ? nexthop.interface->name : "<ifname?>",
6458 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
6459
6460 return CMD_SUCCESS;
6461 }
6462
6463 static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
6464 {
6465 struct listnode *node;
6466 struct ssmpingd_sock *ss;
6467 time_t now;
6468
6469 vty_out(vty,
6470 "Source Socket Address Port Uptime Requests\n");
6471
6472 if (!pim->ssmpingd_list)
6473 return;
6474
6475 now = pim_time_monotonic_sec();
6476
6477 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
6478 char source_str[INET_ADDRSTRLEN];
6479 char ss_uptime[10];
6480 struct sockaddr_in bind_addr;
6481 socklen_t len = sizeof(bind_addr);
6482 char bind_addr_str[INET_ADDRSTRLEN];
6483
6484 pim_inet4_dump("<src?>", ss->source_addr, source_str,
6485 sizeof(source_str));
6486
6487 if (pim_socket_getsockname(
6488 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
6489 vty_out(vty,
6490 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6491 source_str, ss->sock_fd);
6492 }
6493
6494 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
6495 sizeof(bind_addr_str));
6496 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
6497 now - ss->creation);
6498
6499 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
6500 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
6501 ss_uptime, (long long)ss->requests);
6502 }
6503 }
6504
6505 DEFUN (show_ip_ssmpingd,
6506 show_ip_ssmpingd_cmd,
6507 "show ip ssmpingd [vrf NAME]",
6508 SHOW_STR
6509 IP_STR
6510 SHOW_SSMPINGD_STR
6511 VRF_CMD_HELP_STR)
6512 {
6513 int idx = 2;
6514 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6515
6516 if (!vrf)
6517 return CMD_WARNING;
6518
6519 show_ssmpingd(vrf->info, vty);
6520 return CMD_SUCCESS;
6521 }
6522
6523 static int pim_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
6524 const char *rp, const char *group,
6525 const char *plist)
6526 {
6527 int result;
6528
6529 result = pim_rp_new_config(pim, rp, group, plist);
6530
6531 if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
6532 vty_out(vty, "%% Inconsistent address and mask: %s\n",
6533 group);
6534 return CMD_WARNING_CONFIG_FAILED;
6535 }
6536
6537 if (result == PIM_GROUP_BAD_ADDRESS) {
6538 vty_out(vty, "%% Bad group address specified: %s\n", group);
6539 return CMD_WARNING_CONFIG_FAILED;
6540 }
6541
6542 if (result == PIM_RP_BAD_ADDRESS) {
6543 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
6544 return CMD_WARNING_CONFIG_FAILED;
6545 }
6546
6547 if (result == PIM_RP_NO_PATH) {
6548 vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
6549 return CMD_WARNING;
6550 }
6551
6552 if (result == PIM_GROUP_OVERLAP) {
6553 vty_out(vty,
6554 "%% Group range specified cannot exact match another\n");
6555 return CMD_WARNING_CONFIG_FAILED;
6556 }
6557
6558 if (result == PIM_GROUP_PFXLIST_OVERLAP) {
6559 vty_out(vty,
6560 "%% This group is already covered by a RP prefix-list\n");
6561 return CMD_WARNING_CONFIG_FAILED;
6562 }
6563
6564 if (result == PIM_RP_PFXLIST_IN_USE) {
6565 vty_out(vty,
6566 "%% The same prefix-list cannot be applied to multiple RPs\n");
6567 return CMD_WARNING_CONFIG_FAILED;
6568 }
6569
6570 return CMD_SUCCESS;
6571 }
6572
6573 static int pim_cmd_spt_switchover(struct pim_instance *pim,
6574 enum pim_spt_switchover spt,
6575 const char *plist)
6576 {
6577 pim->spt.switchover = spt;
6578
6579 switch (pim->spt.switchover) {
6580 case PIM_SPT_IMMEDIATE:
6581 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
6582
6583 pim_upstream_add_lhr_star_pimreg(pim);
6584 break;
6585 case PIM_SPT_INFINITY:
6586 pim_upstream_remove_lhr_star_pimreg(pim, plist);
6587
6588 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
6589
6590 if (plist)
6591 pim->spt.plist =
6592 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
6593 break;
6594 }
6595
6596 return CMD_SUCCESS;
6597 }
6598
6599 DEFUN (ip_pim_spt_switchover_infinity,
6600 ip_pim_spt_switchover_infinity_cmd,
6601 "ip pim spt-switchover infinity-and-beyond",
6602 IP_STR
6603 PIM_STR
6604 "SPT-Switchover\n"
6605 "Never switch to SPT Tree\n")
6606 {
6607 PIM_DECLVAR_CONTEXT(vrf, pim);
6608 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, NULL);
6609 }
6610
6611 DEFUN (ip_pim_spt_switchover_infinity_plist,
6612 ip_pim_spt_switchover_infinity_plist_cmd,
6613 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6614 IP_STR
6615 PIM_STR
6616 "SPT-Switchover\n"
6617 "Never switch to SPT Tree\n"
6618 "Prefix-List to control which groups to switch\n"
6619 "Prefix-List name\n")
6620 {
6621 PIM_DECLVAR_CONTEXT(vrf, pim);
6622 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, argv[5]->arg);
6623 }
6624
6625 DEFUN (no_ip_pim_spt_switchover_infinity,
6626 no_ip_pim_spt_switchover_infinity_cmd,
6627 "no ip pim spt-switchover infinity-and-beyond",
6628 NO_STR
6629 IP_STR
6630 PIM_STR
6631 "SPT_Switchover\n"
6632 "Never switch to SPT Tree\n")
6633 {
6634 PIM_DECLVAR_CONTEXT(vrf, pim);
6635 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
6636 }
6637
6638 DEFUN (no_ip_pim_spt_switchover_infinity_plist,
6639 no_ip_pim_spt_switchover_infinity_plist_cmd,
6640 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6641 NO_STR
6642 IP_STR
6643 PIM_STR
6644 "SPT_Switchover\n"
6645 "Never switch to SPT Tree\n"
6646 "Prefix-List to control which groups to switch\n"
6647 "Prefix-List name\n")
6648 {
6649 PIM_DECLVAR_CONTEXT(vrf, pim);
6650 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
6651 }
6652
6653 DEFUN (ip_pim_joinprune_time,
6654 ip_pim_joinprune_time_cmd,
6655 "ip pim join-prune-interval (60-600)",
6656 IP_STR
6657 "pim multicast routing\n"
6658 "Join Prune Send Interval\n"
6659 "Seconds\n")
6660 {
6661 PIM_DECLVAR_CONTEXT(vrf, pim);
6662 router->t_periodic = atoi(argv[3]->arg);
6663 return CMD_SUCCESS;
6664 }
6665
6666 DEFUN (no_ip_pim_joinprune_time,
6667 no_ip_pim_joinprune_time_cmd,
6668 "no ip pim join-prune-interval (60-600)",
6669 NO_STR
6670 IP_STR
6671 "pim multicast routing\n"
6672 "Join Prune Send Interval\n"
6673 "Seconds\n")
6674 {
6675 PIM_DECLVAR_CONTEXT(vrf, pim);
6676 router->t_periodic = PIM_DEFAULT_T_PERIODIC;
6677 return CMD_SUCCESS;
6678 }
6679
6680 DEFUN (ip_pim_register_suppress,
6681 ip_pim_register_suppress_cmd,
6682 "ip pim register-suppress-time (5-60000)",
6683 IP_STR
6684 "pim multicast routing\n"
6685 "Register Suppress Timer\n"
6686 "Seconds\n")
6687 {
6688 PIM_DECLVAR_CONTEXT(vrf, pim);
6689 router->register_suppress_time = atoi(argv[3]->arg);
6690 return CMD_SUCCESS;
6691 }
6692
6693 DEFUN (no_ip_pim_register_suppress,
6694 no_ip_pim_register_suppress_cmd,
6695 "no ip pim register-suppress-time (5-60000)",
6696 NO_STR
6697 IP_STR
6698 "pim multicast routing\n"
6699 "Register Suppress Timer\n"
6700 "Seconds\n")
6701 {
6702 PIM_DECLVAR_CONTEXT(vrf, pim);
6703 router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
6704 return CMD_SUCCESS;
6705 }
6706
6707 DEFUN (ip_pim_rp_keep_alive,
6708 ip_pim_rp_keep_alive_cmd,
6709 "ip pim rp keep-alive-timer (31-60000)",
6710 IP_STR
6711 "pim multicast routing\n"
6712 "Rendevous Point\n"
6713 "Keep alive Timer\n"
6714 "Seconds\n")
6715 {
6716 PIM_DECLVAR_CONTEXT(vrf, pim);
6717 pim->rp_keep_alive_time = atoi(argv[4]->arg);
6718 return CMD_SUCCESS;
6719 }
6720
6721 DEFUN (no_ip_pim_rp_keep_alive,
6722 no_ip_pim_rp_keep_alive_cmd,
6723 "no ip pim rp keep-alive-timer (31-60000)",
6724 NO_STR
6725 IP_STR
6726 "pim multicast routing\n"
6727 "Rendevous Point\n"
6728 "Keep alive Timer\n"
6729 "Seconds\n")
6730 {
6731 PIM_DECLVAR_CONTEXT(vrf, pim);
6732 pim->rp_keep_alive_time = PIM_KEEPALIVE_PERIOD;
6733 return CMD_SUCCESS;
6734 }
6735
6736 DEFUN (ip_pim_keep_alive,
6737 ip_pim_keep_alive_cmd,
6738 "ip pim keep-alive-timer (31-60000)",
6739 IP_STR
6740 "pim multicast routing\n"
6741 "Keep alive Timer\n"
6742 "Seconds\n")
6743 {
6744 PIM_DECLVAR_CONTEXT(vrf, pim);
6745 pim->keep_alive_time = atoi(argv[3]->arg);
6746 return CMD_SUCCESS;
6747 }
6748
6749 DEFUN (no_ip_pim_keep_alive,
6750 no_ip_pim_keep_alive_cmd,
6751 "no ip pim keep-alive-timer (31-60000)",
6752 NO_STR
6753 IP_STR
6754 "pim multicast routing\n"
6755 "Keep alive Timer\n"
6756 "Seconds\n")
6757 {
6758 PIM_DECLVAR_CONTEXT(vrf, pim);
6759 pim->keep_alive_time = PIM_KEEPALIVE_PERIOD;
6760 return CMD_SUCCESS;
6761 }
6762
6763 DEFUN (ip_pim_packets,
6764 ip_pim_packets_cmd,
6765 "ip pim packets (1-100)",
6766 IP_STR
6767 "pim multicast routing\n"
6768 "packets to process at one time per fd\n"
6769 "Number of packets\n")
6770 {
6771 PIM_DECLVAR_CONTEXT(vrf, pim);
6772 router->packet_process = atoi(argv[3]->arg);
6773 return CMD_SUCCESS;
6774 }
6775
6776 DEFUN (no_ip_pim_packets,
6777 no_ip_pim_packets_cmd,
6778 "no ip pim packets (1-100)",
6779 NO_STR
6780 IP_STR
6781 "pim multicast routing\n"
6782 "packets to process at one time per fd\n"
6783 "Number of packets\n")
6784 {
6785 PIM_DECLVAR_CONTEXT(vrf, pim);
6786 router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
6787 return CMD_SUCCESS;
6788 }
6789
6790 DEFUN (ip_pim_v6_secondary,
6791 ip_pim_v6_secondary_cmd,
6792 "ip pim send-v6-secondary",
6793 IP_STR
6794 "pim multicast routing\n"
6795 "Send v6 secondary addresses\n")
6796 {
6797 PIM_DECLVAR_CONTEXT(vrf, pim);
6798 pim->send_v6_secondary = 1;
6799
6800 return CMD_SUCCESS;
6801 }
6802
6803 DEFUN (no_ip_pim_v6_secondary,
6804 no_ip_pim_v6_secondary_cmd,
6805 "no ip pim send-v6-secondary",
6806 NO_STR
6807 IP_STR
6808 "pim multicast routing\n"
6809 "Send v6 secondary addresses\n")
6810 {
6811 PIM_DECLVAR_CONTEXT(vrf, pim);
6812 pim->send_v6_secondary = 0;
6813
6814 return CMD_SUCCESS;
6815 }
6816
6817 DEFUN (ip_pim_rp,
6818 ip_pim_rp_cmd,
6819 "ip pim rp A.B.C.D [A.B.C.D/M]",
6820 IP_STR
6821 "pim multicast routing\n"
6822 "Rendevous Point\n"
6823 "ip address of RP\n"
6824 "Group Address range to cover\n")
6825 {
6826 PIM_DECLVAR_CONTEXT(vrf, pim);
6827 int idx_ipv4 = 3;
6828
6829 if (argc == (idx_ipv4 + 1))
6830 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
6831 NULL);
6832 else
6833 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
6834 argv[idx_ipv4 + 1]->arg, NULL);
6835 }
6836
6837 DEFUN (ip_pim_rp_prefix_list,
6838 ip_pim_rp_prefix_list_cmd,
6839 "ip pim rp A.B.C.D prefix-list WORD",
6840 IP_STR
6841 "pim multicast routing\n"
6842 "Rendevous Point\n"
6843 "ip address of RP\n"
6844 "group prefix-list filter\n"
6845 "Name of a prefix-list\n")
6846 {
6847 PIM_DECLVAR_CONTEXT(vrf, pim);
6848 return pim_rp_cmd_worker(pim, vty, argv[3]->arg, NULL, argv[5]->arg);
6849 }
6850
6851 static int pim_no_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
6852 const char *rp, const char *group,
6853 const char *plist)
6854 {
6855 int result = pim_rp_del_config(pim, rp, group, plist);
6856
6857 if (result == PIM_GROUP_BAD_ADDRESS) {
6858 vty_out(vty, "%% Bad group address specified: %s\n", group);
6859 return CMD_WARNING_CONFIG_FAILED;
6860 }
6861
6862 if (result == PIM_RP_BAD_ADDRESS) {
6863 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
6864 return CMD_WARNING_CONFIG_FAILED;
6865 }
6866
6867 if (result == PIM_RP_NOT_FOUND) {
6868 vty_out(vty, "%% Unable to find specified RP\n");
6869 return CMD_WARNING_CONFIG_FAILED;
6870 }
6871
6872 return CMD_SUCCESS;
6873 }
6874
6875 DEFUN (no_ip_pim_rp,
6876 no_ip_pim_rp_cmd,
6877 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6878 NO_STR
6879 IP_STR
6880 "pim multicast routing\n"
6881 "Rendevous Point\n"
6882 "ip address of RP\n"
6883 "Group Address range to cover\n")
6884 {
6885 PIM_DECLVAR_CONTEXT(vrf, pim);
6886 int idx_ipv4 = 4, idx_group = 0;
6887
6888 if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
6889 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
6890 argv[idx_group]->arg, NULL);
6891 else
6892 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
6893 NULL);
6894 }
6895
6896 DEFUN (no_ip_pim_rp_prefix_list,
6897 no_ip_pim_rp_prefix_list_cmd,
6898 "no ip pim rp A.B.C.D prefix-list WORD",
6899 NO_STR
6900 IP_STR
6901 "pim multicast routing\n"
6902 "Rendevous Point\n"
6903 "ip address of RP\n"
6904 "group prefix-list filter\n"
6905 "Name of a prefix-list\n")
6906 {
6907 PIM_DECLVAR_CONTEXT(vrf, pim);
6908 return pim_no_rp_cmd_worker(pim, vty, argv[4]->arg, NULL, argv[6]->arg);
6909 }
6910
6911 static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
6912 const char *plist)
6913 {
6914 int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
6915 int ret = CMD_WARNING_CONFIG_FAILED;
6916
6917 if (result == PIM_SSM_ERR_NONE)
6918 return CMD_SUCCESS;
6919
6920 switch (result) {
6921 case PIM_SSM_ERR_NO_VRF:
6922 vty_out(vty, "%% VRF doesn't exist\n");
6923 break;
6924 case PIM_SSM_ERR_DUP:
6925 vty_out(vty, "%% duplicate config\n");
6926 ret = CMD_WARNING;
6927 break;
6928 default:
6929 vty_out(vty, "%% ssm range config failed\n");
6930 }
6931
6932 return ret;
6933 }
6934
6935 DEFUN (ip_pim_ssm_prefix_list,
6936 ip_pim_ssm_prefix_list_cmd,
6937 "ip pim ssm prefix-list WORD",
6938 IP_STR
6939 "pim multicast routing\n"
6940 "Source Specific Multicast\n"
6941 "group range prefix-list filter\n"
6942 "Name of a prefix-list\n")
6943 {
6944 PIM_DECLVAR_CONTEXT(vrf, pim);
6945 return pim_ssm_cmd_worker(pim, vty, argv[4]->arg);
6946 }
6947
6948 DEFUN (no_ip_pim_ssm_prefix_list,
6949 no_ip_pim_ssm_prefix_list_cmd,
6950 "no ip pim ssm prefix-list",
6951 NO_STR
6952 IP_STR
6953 "pim multicast routing\n"
6954 "Source Specific Multicast\n"
6955 "group range prefix-list filter\n")
6956 {
6957 PIM_DECLVAR_CONTEXT(vrf, pim);
6958 return pim_ssm_cmd_worker(pim, vty, NULL);
6959 }
6960
6961 DEFUN (no_ip_pim_ssm_prefix_list_name,
6962 no_ip_pim_ssm_prefix_list_name_cmd,
6963 "no ip pim ssm prefix-list WORD",
6964 NO_STR
6965 IP_STR
6966 "pim multicast routing\n"
6967 "Source Specific Multicast\n"
6968 "group range prefix-list filter\n"
6969 "Name of a prefix-list\n")
6970 {
6971 PIM_DECLVAR_CONTEXT(vrf, pim);
6972 struct pim_ssm *ssm = pim->ssm_info;
6973
6974 if (ssm->plist_name && !strcmp(ssm->plist_name, argv[5]->arg))
6975 return pim_ssm_cmd_worker(pim, vty, NULL);
6976
6977 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
6978
6979 return CMD_WARNING_CONFIG_FAILED;
6980 }
6981
6982 static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
6983 struct vty *vty, bool uj)
6984 {
6985 struct pim_ssm *ssm = pim->ssm_info;
6986 const char *range_str =
6987 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
6988
6989 if (uj) {
6990 json_object *json;
6991 json = json_object_new_object();
6992 json_object_string_add(json, "ssmGroups", range_str);
6993 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6994 json, JSON_C_TO_STRING_PRETTY));
6995 json_object_free(json);
6996 } else
6997 vty_out(vty, "SSM group range : %s\n", range_str);
6998 }
6999
7000 DEFUN (show_ip_pim_ssm_range,
7001 show_ip_pim_ssm_range_cmd,
7002 "show ip pim [vrf NAME] group-type [json]",
7003 SHOW_STR
7004 IP_STR
7005 PIM_STR
7006 VRF_CMD_HELP_STR
7007 "PIM group type\n"
7008 JSON_STR)
7009 {
7010 int idx = 2;
7011 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
7012 bool uj = use_json(argc, argv);
7013
7014 if (!vrf)
7015 return CMD_WARNING;
7016
7017 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
7018
7019 return CMD_SUCCESS;
7020 }
7021
7022 static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
7023 struct vty *vty, bool uj,
7024 const char *group)
7025 {
7026 struct in_addr group_addr;
7027 const char *type_str;
7028 int result;
7029
7030 result = inet_pton(AF_INET, group, &group_addr);
7031 if (result <= 0)
7032 type_str = "invalid";
7033 else {
7034 if (pim_is_group_224_4(group_addr))
7035 type_str =
7036 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
7037 else
7038 type_str = "not-multicast";
7039 }
7040
7041 if (uj) {
7042 json_object *json;
7043 json = json_object_new_object();
7044 json_object_string_add(json, "groupType", type_str);
7045 vty_out(vty, "%s\n", json_object_to_json_string_ext(
7046 json, JSON_C_TO_STRING_PRETTY));
7047 json_object_free(json);
7048 } else
7049 vty_out(vty, "Group type : %s\n", type_str);
7050 }
7051
7052 DEFUN (show_ip_pim_group_type,
7053 show_ip_pim_group_type_cmd,
7054 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
7055 SHOW_STR
7056 IP_STR
7057 PIM_STR
7058 VRF_CMD_HELP_STR
7059 "multicast group type\n"
7060 "group address\n"
7061 JSON_STR)
7062 {
7063 int idx = 2;
7064 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
7065 bool uj = use_json(argc, argv);
7066
7067 if (!vrf)
7068 return CMD_WARNING;
7069
7070 argv_find(argv, argc, "A.B.C.D", &idx);
7071 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
7072
7073 return CMD_SUCCESS;
7074 }
7075
7076 DEFUN (show_ip_pim_bsr,
7077 show_ip_pim_bsr_cmd,
7078 "show ip pim bsr [json]",
7079 SHOW_STR
7080 IP_STR
7081 PIM_STR
7082 "boot-strap router information\n"
7083 JSON_STR)
7084 {
7085 int idx = 2;
7086 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
7087 bool uj = use_json(argc, argv);
7088
7089 if (!vrf)
7090 return CMD_WARNING;
7091
7092 pim_show_bsr(vrf->info, vty, uj);
7093
7094 return CMD_SUCCESS;
7095 }
7096
7097 DEFUN (ip_ssmpingd,
7098 ip_ssmpingd_cmd,
7099 "ip ssmpingd [A.B.C.D]",
7100 IP_STR
7101 CONF_SSMPINGD_STR
7102 "Source address\n")
7103 {
7104 PIM_DECLVAR_CONTEXT(vrf, pim);
7105 int idx_ipv4 = 2;
7106 int result;
7107 struct in_addr source_addr;
7108 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
7109
7110 result = inet_pton(AF_INET, source_str, &source_addr);
7111 if (result <= 0) {
7112 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
7113 source_str, errno, safe_strerror(errno));
7114 return CMD_WARNING_CONFIG_FAILED;
7115 }
7116
7117 result = pim_ssmpingd_start(pim, source_addr);
7118 if (result) {
7119 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
7120 source_str, result);
7121 return CMD_WARNING_CONFIG_FAILED;
7122 }
7123
7124 return CMD_SUCCESS;
7125 }
7126
7127 DEFUN (no_ip_ssmpingd,
7128 no_ip_ssmpingd_cmd,
7129 "no ip ssmpingd [A.B.C.D]",
7130 NO_STR
7131 IP_STR
7132 CONF_SSMPINGD_STR
7133 "Source address\n")
7134 {
7135 PIM_DECLVAR_CONTEXT(vrf, pim);
7136 int idx_ipv4 = 3;
7137 int result;
7138 struct in_addr source_addr;
7139 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
7140
7141 result = inet_pton(AF_INET, source_str, &source_addr);
7142 if (result <= 0) {
7143 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
7144 source_str, errno, safe_strerror(errno));
7145 return CMD_WARNING_CONFIG_FAILED;
7146 }
7147
7148 result = pim_ssmpingd_stop(pim, source_addr);
7149 if (result) {
7150 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
7151 source_str, result);
7152 return CMD_WARNING_CONFIG_FAILED;
7153 }
7154
7155 return CMD_SUCCESS;
7156 }
7157
7158 DEFUN (ip_pim_ecmp,
7159 ip_pim_ecmp_cmd,
7160 "ip pim ecmp",
7161 IP_STR
7162 "pim multicast routing\n"
7163 "Enable PIM ECMP \n")
7164 {
7165 PIM_DECLVAR_CONTEXT(vrf, pim);
7166 pim->ecmp_enable = true;
7167
7168 return CMD_SUCCESS;
7169 }
7170
7171 DEFUN (no_ip_pim_ecmp,
7172 no_ip_pim_ecmp_cmd,
7173 "no ip pim ecmp",
7174 NO_STR
7175 IP_STR
7176 "pim multicast routing\n"
7177 "Disable PIM ECMP \n")
7178 {
7179 PIM_DECLVAR_CONTEXT(vrf, pim);
7180 pim->ecmp_enable = false;
7181
7182 return CMD_SUCCESS;
7183 }
7184
7185 DEFUN (ip_pim_ecmp_rebalance,
7186 ip_pim_ecmp_rebalance_cmd,
7187 "ip pim ecmp rebalance",
7188 IP_STR
7189 "pim multicast routing\n"
7190 "Enable PIM ECMP \n"
7191 "Enable PIM ECMP Rebalance\n")
7192 {
7193 PIM_DECLVAR_CONTEXT(vrf, pim);
7194 pim->ecmp_enable = true;
7195 pim->ecmp_rebalance_enable = true;
7196
7197 return CMD_SUCCESS;
7198 }
7199
7200 DEFUN (no_ip_pim_ecmp_rebalance,
7201 no_ip_pim_ecmp_rebalance_cmd,
7202 "no ip pim ecmp rebalance",
7203 NO_STR
7204 IP_STR
7205 "pim multicast routing\n"
7206 "Disable PIM ECMP \n"
7207 "Disable PIM ECMP Rebalance\n")
7208 {
7209 PIM_DECLVAR_CONTEXT(vrf, pim);
7210 pim->ecmp_rebalance_enable = false;
7211
7212 return CMD_SUCCESS;
7213 }
7214
7215 static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
7216 {
7217 struct pim_interface *pim_ifp;
7218 uint8_t need_startup = 0;
7219
7220 pim_ifp = ifp->info;
7221
7222 if (!pim_ifp) {
7223 (void)pim_if_new(ifp, true, false, false, false);
7224 need_startup = 1;
7225 } else {
7226 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7227 PIM_IF_DO_IGMP(pim_ifp->options);
7228 need_startup = 1;
7229 }
7230 }
7231
7232 /* 'ip igmp' executed multiple times, with need_startup
7233 avoid multiple if add all and membership refresh */
7234 if (need_startup) {
7235 pim_if_addr_add_all(ifp);
7236 pim_if_membership_refresh(ifp);
7237 }
7238
7239 return CMD_SUCCESS;
7240 }
7241
7242 DEFUN (interface_ip_igmp,
7243 interface_ip_igmp_cmd,
7244 "ip igmp",
7245 IP_STR
7246 IFACE_IGMP_STR)
7247 {
7248 VTY_DECLVAR_CONTEXT(interface, ifp);
7249
7250 return pim_cmd_igmp_start(vty, ifp);
7251 }
7252
7253 DEFUN (interface_no_ip_igmp,
7254 interface_no_ip_igmp_cmd,
7255 "no ip igmp",
7256 NO_STR
7257 IP_STR
7258 IFACE_IGMP_STR)
7259 {
7260 VTY_DECLVAR_CONTEXT(interface, ifp);
7261 struct pim_interface *pim_ifp = ifp->info;
7262
7263 if (!pim_ifp)
7264 return CMD_SUCCESS;
7265
7266 PIM_IF_DONT_IGMP(pim_ifp->options);
7267
7268 pim_if_membership_clear(ifp);
7269
7270 pim_if_addr_del_all_igmp(ifp);
7271
7272 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
7273 pim_if_delete(ifp);
7274 }
7275
7276 return CMD_SUCCESS;
7277 }
7278
7279 DEFUN (interface_ip_igmp_join,
7280 interface_ip_igmp_join_cmd,
7281 "ip igmp join A.B.C.D [A.B.C.D]",
7282 IP_STR
7283 IFACE_IGMP_STR
7284 "IGMP join multicast group\n"
7285 "Multicast group address\n"
7286 "Source address\n")
7287 {
7288 VTY_DECLVAR_CONTEXT(interface, ifp);
7289 int idx_ipv4 = 3;
7290 int idx_ipv4_2 = 4;
7291 const char *group_str;
7292 const char *source_str;
7293 struct in_addr group_addr;
7294 struct in_addr source_addr;
7295 int result;
7296
7297 /* Group address */
7298 group_str = argv[idx_ipv4]->arg;
7299 result = inet_pton(AF_INET, group_str, &group_addr);
7300 if (result <= 0) {
7301 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
7302 errno, safe_strerror(errno));
7303 return CMD_WARNING_CONFIG_FAILED;
7304 }
7305
7306 /* Source address */
7307 if (argc == (idx_ipv4_2 + 1)) {
7308 source_str = argv[idx_ipv4_2]->arg;
7309 result = inet_pton(AF_INET, source_str, &source_addr);
7310 if (result <= 0) {
7311 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
7312 source_str, errno, safe_strerror(errno));
7313 return CMD_WARNING_CONFIG_FAILED;
7314 }
7315 /* Reject 0.0.0.0. Reserved for any source. */
7316 if (source_addr.s_addr == INADDR_ANY) {
7317 vty_out(vty, "Bad source address %s\n", source_str);
7318 return CMD_WARNING_CONFIG_FAILED;
7319 }
7320 } else {
7321 source_addr.s_addr = INADDR_ANY;
7322 }
7323
7324 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp, group_addr, source_addr),
7325 "Failure joining IGMP group: $ERR");
7326
7327 return CMD_SUCCESS;
7328 }
7329
7330 DEFUN (interface_no_ip_igmp_join,
7331 interface_no_ip_igmp_join_cmd,
7332 "no ip igmp join A.B.C.D [A.B.C.D]",
7333 NO_STR
7334 IP_STR
7335 IFACE_IGMP_STR
7336 "IGMP join multicast group\n"
7337 "Multicast group address\n"
7338 "Source address\n")
7339 {
7340 VTY_DECLVAR_CONTEXT(interface, ifp);
7341 int idx_ipv4 = 4;
7342 int idx_ipv4_2 = 5;
7343 const char *group_str;
7344 const char *source_str;
7345 struct in_addr group_addr;
7346 struct in_addr source_addr;
7347 int result;
7348
7349 /* Group address */
7350 group_str = argv[idx_ipv4]->arg;
7351 result = inet_pton(AF_INET, group_str, &group_addr);
7352 if (result <= 0) {
7353 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
7354 errno, safe_strerror(errno));
7355 return CMD_WARNING_CONFIG_FAILED;
7356 }
7357
7358 /* Source address */
7359 if (argc == (idx_ipv4_2 + 1)) {
7360 source_str = argv[idx_ipv4_2]->arg;
7361 result = inet_pton(AF_INET, source_str, &source_addr);
7362 if (result <= 0) {
7363 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
7364 source_str, errno, safe_strerror(errno));
7365 return CMD_WARNING_CONFIG_FAILED;
7366 }
7367 /* Reject 0.0.0.0. Reserved for any source. */
7368 if (source_addr.s_addr == INADDR_ANY) {
7369 vty_out(vty, "Bad source address %s\n", source_str);
7370 return CMD_WARNING_CONFIG_FAILED;
7371 }
7372 } else {
7373 source_str = "*";
7374 source_addr.s_addr = INADDR_ANY;
7375 }
7376
7377 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
7378 if (result) {
7379 vty_out(vty,
7380 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7381 group_str, source_str, ifp->name, result);
7382 return CMD_WARNING_CONFIG_FAILED;
7383 }
7384
7385 return CMD_SUCCESS;
7386 }
7387
7388 /*
7389 CLI reconfiguration affects the interface level (struct pim_interface).
7390 This function propagates the reconfiguration to every active socket
7391 for that interface.
7392 */
7393 static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
7394 {
7395 struct interface *ifp;
7396 struct pim_interface *pim_ifp;
7397
7398 zassert(igmp);
7399
7400 /* other querier present? */
7401
7402 if (igmp->t_other_querier_timer)
7403 return;
7404
7405 /* this is the querier */
7406
7407 zassert(igmp->interface);
7408 zassert(igmp->interface->info);
7409
7410 ifp = igmp->interface;
7411 pim_ifp = ifp->info;
7412
7413 if (PIM_DEBUG_IGMP_TRACE) {
7414 char ifaddr_str[INET_ADDRSTRLEN];
7415 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
7416 sizeof(ifaddr_str));
7417 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7418 __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
7419 pim_ifp->igmp_default_query_interval);
7420 }
7421
7422 /*
7423 igmp_startup_mode_on() will reset QQI:
7424
7425 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7426 */
7427 igmp_startup_mode_on(igmp);
7428 }
7429
7430 static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
7431 {
7432 if (igmp->mtrace_only)
7433 return;
7434
7435 if (igmp->t_igmp_query_timer) {
7436 /* other querier present */
7437 zassert(igmp->t_igmp_query_timer);
7438 zassert(!igmp->t_other_querier_timer);
7439
7440 pim_igmp_general_query_off(igmp);
7441 pim_igmp_general_query_on(igmp);
7442
7443 zassert(igmp->t_igmp_query_timer);
7444 zassert(!igmp->t_other_querier_timer);
7445 } else {
7446 /* this is the querier */
7447
7448 zassert(!igmp->t_igmp_query_timer);
7449 zassert(igmp->t_other_querier_timer);
7450
7451 pim_igmp_other_querier_timer_off(igmp);
7452 pim_igmp_other_querier_timer_on(igmp);
7453
7454 zassert(!igmp->t_igmp_query_timer);
7455 zassert(igmp->t_other_querier_timer);
7456 }
7457 }
7458
7459 static void change_query_interval(struct pim_interface *pim_ifp,
7460 int query_interval)
7461 {
7462 struct listnode *sock_node;
7463 struct igmp_sock *igmp;
7464
7465 pim_ifp->igmp_default_query_interval = query_interval;
7466
7467 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7468 igmp_sock_query_interval_reconfig(igmp);
7469 igmp_sock_query_reschedule(igmp);
7470 }
7471 }
7472
7473 static void change_query_max_response_time(struct pim_interface *pim_ifp,
7474 int query_max_response_time_dsec)
7475 {
7476 struct listnode *sock_node;
7477 struct igmp_sock *igmp;
7478
7479 pim_ifp->igmp_query_max_response_time_dsec =
7480 query_max_response_time_dsec;
7481
7482 /*
7483 Below we modify socket/group/source timers in order to quickly
7484 reflect the change. Otherwise, those timers would eventually catch
7485 up.
7486 */
7487
7488 /* scan all sockets */
7489 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7490 struct listnode *grp_node;
7491 struct igmp_group *grp;
7492
7493 /* reschedule socket general query */
7494 igmp_sock_query_reschedule(igmp);
7495
7496 /* scan socket groups */
7497 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
7498 grp)) {
7499 struct listnode *src_node;
7500 struct igmp_source *src;
7501
7502 /* reset group timers for groups in EXCLUDE mode */
7503 if (grp->group_filtermode_isexcl) {
7504 igmp_group_reset_gmi(grp);
7505 }
7506
7507 /* scan group sources */
7508 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
7509 src_node, src)) {
7510
7511 /* reset source timers for sources with running
7512 * timers */
7513 if (src->t_source_timer) {
7514 igmp_source_reset_gmi(igmp, grp, src);
7515 }
7516 }
7517 }
7518 }
7519 }
7520
7521 #define IGMP_QUERY_INTERVAL_MIN (1)
7522 #define IGMP_QUERY_INTERVAL_MAX (1800)
7523
7524 DEFUN (interface_ip_igmp_query_interval,
7525 interface_ip_igmp_query_interval_cmd,
7526 "ip igmp query-interval (1-1800)",
7527 IP_STR
7528 IFACE_IGMP_STR
7529 IFACE_IGMP_QUERY_INTERVAL_STR
7530 "Query interval in seconds\n")
7531 {
7532 VTY_DECLVAR_CONTEXT(interface, ifp);
7533 struct pim_interface *pim_ifp = ifp->info;
7534 int query_interval;
7535 int query_interval_dsec;
7536 int ret;
7537
7538 if (!pim_ifp) {
7539 ret = pim_cmd_igmp_start(vty, ifp);
7540 if (ret != CMD_SUCCESS)
7541 return ret;
7542 pim_ifp = ifp->info;
7543 }
7544
7545 query_interval = atoi(argv[3]->arg);
7546 query_interval_dsec = 10 * query_interval;
7547
7548 /*
7549 It seems we don't need to check bounds since command.c does it
7550 already, but we verify them anyway for extra safety.
7551 */
7552 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
7553 vty_out(vty,
7554 "General query interval %d lower than minimum %d\n",
7555 query_interval, IGMP_QUERY_INTERVAL_MIN);
7556 return CMD_WARNING_CONFIG_FAILED;
7557 }
7558 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
7559 vty_out(vty,
7560 "General query interval %d higher than maximum %d\n",
7561 query_interval, IGMP_QUERY_INTERVAL_MAX);
7562 return CMD_WARNING_CONFIG_FAILED;
7563 }
7564
7565 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
7566 vty_out(vty,
7567 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7568 query_interval_dsec,
7569 pim_ifp->igmp_query_max_response_time_dsec);
7570 return CMD_WARNING_CONFIG_FAILED;
7571 }
7572
7573 change_query_interval(pim_ifp, query_interval);
7574
7575 return CMD_SUCCESS;
7576 }
7577
7578 DEFUN (interface_no_ip_igmp_query_interval,
7579 interface_no_ip_igmp_query_interval_cmd,
7580 "no ip igmp query-interval",
7581 NO_STR
7582 IP_STR
7583 IFACE_IGMP_STR
7584 IFACE_IGMP_QUERY_INTERVAL_STR)
7585 {
7586 VTY_DECLVAR_CONTEXT(interface, ifp);
7587 struct pim_interface *pim_ifp = ifp->info;
7588 int default_query_interval_dsec;
7589
7590 if (!pim_ifp)
7591 return CMD_SUCCESS;
7592
7593 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
7594
7595 if (default_query_interval_dsec
7596 <= pim_ifp->igmp_query_max_response_time_dsec) {
7597 vty_out(vty,
7598 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7599 default_query_interval_dsec,
7600 pim_ifp->igmp_query_max_response_time_dsec);
7601 return CMD_WARNING_CONFIG_FAILED;
7602 }
7603
7604 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
7605
7606 return CMD_SUCCESS;
7607 }
7608
7609 DEFUN (interface_ip_igmp_version,
7610 interface_ip_igmp_version_cmd,
7611 "ip igmp version (2-3)",
7612 IP_STR
7613 IFACE_IGMP_STR
7614 "IGMP version\n"
7615 "IGMP version number\n")
7616 {
7617 VTY_DECLVAR_CONTEXT(interface, ifp);
7618 struct pim_interface *pim_ifp = ifp->info;
7619 int igmp_version, old_version = 0;
7620 int ret;
7621
7622 if (!pim_ifp) {
7623 ret = pim_cmd_igmp_start(vty, ifp);
7624 if (ret != CMD_SUCCESS)
7625 return ret;
7626 pim_ifp = ifp->info;
7627 }
7628
7629 igmp_version = atoi(argv[3]->arg);
7630 old_version = pim_ifp->igmp_version;
7631 pim_ifp->igmp_version = igmp_version;
7632
7633 // Check if IGMP is Enabled otherwise, enable on interface
7634 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7635 PIM_IF_DO_IGMP(pim_ifp->options);
7636 pim_if_addr_add_all(ifp);
7637 pim_if_membership_refresh(ifp);
7638 old_version = igmp_version;
7639 // avoid refreshing membership again.
7640 }
7641 /* Current and new version is different refresh existing
7642 membership. Going from 3 -> 2 or 2 -> 3. */
7643 if (old_version != igmp_version)
7644 pim_if_membership_refresh(ifp);
7645
7646 return CMD_SUCCESS;
7647 }
7648
7649 DEFUN (interface_no_ip_igmp_version,
7650 interface_no_ip_igmp_version_cmd,
7651 "no ip igmp version (2-3)",
7652 NO_STR
7653 IP_STR
7654 IFACE_IGMP_STR
7655 "IGMP version\n"
7656 "IGMP version number\n")
7657 {
7658 VTY_DECLVAR_CONTEXT(interface, ifp);
7659 struct pim_interface *pim_ifp = ifp->info;
7660
7661 if (!pim_ifp)
7662 return CMD_SUCCESS;
7663
7664 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
7665
7666 return CMD_SUCCESS;
7667 }
7668
7669 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7670 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7671
7672 DEFUN (interface_ip_igmp_query_max_response_time,
7673 interface_ip_igmp_query_max_response_time_cmd,
7674 "ip igmp query-max-response-time (10-250)",
7675 IP_STR
7676 IFACE_IGMP_STR
7677 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7678 "Query response value in deci-seconds\n")
7679 {
7680 VTY_DECLVAR_CONTEXT(interface, ifp);
7681 struct pim_interface *pim_ifp = ifp->info;
7682 int query_max_response_time;
7683 int ret;
7684
7685 if (!pim_ifp) {
7686 ret = pim_cmd_igmp_start(vty, ifp);
7687 if (ret != CMD_SUCCESS)
7688 return ret;
7689 pim_ifp = ifp->info;
7690 }
7691
7692 query_max_response_time = atoi(argv[3]->arg);
7693
7694 if (query_max_response_time
7695 >= pim_ifp->igmp_default_query_interval * 10) {
7696 vty_out(vty,
7697 "Can't set query max response time %d sec >= general query interval %d sec\n",
7698 query_max_response_time,
7699 pim_ifp->igmp_default_query_interval);
7700 return CMD_WARNING_CONFIG_FAILED;
7701 }
7702
7703 change_query_max_response_time(pim_ifp, query_max_response_time);
7704
7705 return CMD_SUCCESS;
7706 }
7707
7708 DEFUN (interface_no_ip_igmp_query_max_response_time,
7709 interface_no_ip_igmp_query_max_response_time_cmd,
7710 "no ip igmp query-max-response-time (10-250)",
7711 NO_STR
7712 IP_STR
7713 IFACE_IGMP_STR
7714 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7715 "Time for response in deci-seconds\n")
7716 {
7717 VTY_DECLVAR_CONTEXT(interface, ifp);
7718 struct pim_interface *pim_ifp = ifp->info;
7719
7720 if (!pim_ifp)
7721 return CMD_SUCCESS;
7722
7723 change_query_max_response_time(pim_ifp,
7724 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
7725
7726 return CMD_SUCCESS;
7727 }
7728
7729 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7730 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7731
7732 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
7733 interface_ip_igmp_query_max_response_time_dsec_cmd,
7734 "ip igmp query-max-response-time-dsec (10-250)",
7735 IP_STR
7736 IFACE_IGMP_STR
7737 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7738 "Query response value in deciseconds\n")
7739 {
7740 VTY_DECLVAR_CONTEXT(interface, ifp);
7741 struct pim_interface *pim_ifp = ifp->info;
7742 int query_max_response_time_dsec;
7743 int default_query_interval_dsec;
7744 int ret;
7745
7746 if (!pim_ifp) {
7747 ret = pim_cmd_igmp_start(vty, ifp);
7748 if (ret != CMD_SUCCESS)
7749 return ret;
7750 pim_ifp = ifp->info;
7751 }
7752
7753 query_max_response_time_dsec = atoi(argv[4]->arg);
7754
7755 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
7756
7757 if (query_max_response_time_dsec >= default_query_interval_dsec) {
7758 vty_out(vty,
7759 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7760 query_max_response_time_dsec,
7761 default_query_interval_dsec);
7762 return CMD_WARNING_CONFIG_FAILED;
7763 }
7764
7765 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
7766
7767 return CMD_SUCCESS;
7768 }
7769
7770 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
7771 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
7772 "no ip igmp query-max-response-time-dsec",
7773 NO_STR
7774 IP_STR
7775 IFACE_IGMP_STR
7776 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
7777 {
7778 VTY_DECLVAR_CONTEXT(interface, ifp);
7779 struct pim_interface *pim_ifp = ifp->info;
7780
7781 if (!pim_ifp)
7782 return CMD_SUCCESS;
7783
7784 change_query_max_response_time(pim_ifp,
7785 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
7786
7787 return CMD_SUCCESS;
7788 }
7789
7790 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7791 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7792
7793 DEFUN (interface_ip_igmp_last_member_query_count,
7794 interface_ip_igmp_last_member_query_count_cmd,
7795 "ip igmp last-member-query-count (1-7)",
7796 IP_STR
7797 IFACE_IGMP_STR
7798 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7799 "Last member query count\n")
7800 {
7801 VTY_DECLVAR_CONTEXT(interface, ifp);
7802 struct pim_interface *pim_ifp = ifp->info;
7803 int last_member_query_count;
7804 int ret;
7805
7806 if (!pim_ifp) {
7807 ret = pim_cmd_igmp_start(vty, ifp);
7808 if (ret != CMD_SUCCESS)
7809 return ret;
7810 pim_ifp = ifp->info;
7811 }
7812
7813 last_member_query_count = atoi(argv[3]->arg);
7814
7815 pim_ifp->igmp_last_member_query_count = last_member_query_count;
7816
7817 return CMD_SUCCESS;
7818 }
7819
7820 DEFUN (interface_no_ip_igmp_last_member_query_count,
7821 interface_no_ip_igmp_last_member_query_count_cmd,
7822 "no ip igmp last-member-query-count",
7823 NO_STR
7824 IP_STR
7825 IFACE_IGMP_STR
7826 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR)
7827 {
7828 VTY_DECLVAR_CONTEXT(interface, ifp);
7829 struct pim_interface *pim_ifp = ifp->info;
7830
7831 if (!pim_ifp)
7832 return CMD_SUCCESS;
7833
7834 pim_ifp->igmp_last_member_query_count =
7835 IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
7836
7837 return CMD_SUCCESS;
7838 }
7839
7840 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7841 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7842
7843 DEFUN (interface_ip_igmp_last_member_query_interval,
7844 interface_ip_igmp_last_member_query_interval_cmd,
7845 "ip igmp last-member-query-interval (1-255)",
7846 IP_STR
7847 IFACE_IGMP_STR
7848 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7849 "Last member query interval in deciseconds\n")
7850 {
7851 VTY_DECLVAR_CONTEXT(interface, ifp);
7852 struct pim_interface *pim_ifp = ifp->info;
7853 int last_member_query_interval;
7854 int ret;
7855
7856 if (!pim_ifp) {
7857 ret = pim_cmd_igmp_start(vty, ifp);
7858 if (ret != CMD_SUCCESS)
7859 return ret;
7860 pim_ifp = ifp->info;
7861 }
7862
7863 last_member_query_interval = atoi(argv[3]->arg);
7864 pim_ifp->igmp_specific_query_max_response_time_dsec
7865 = last_member_query_interval;
7866
7867 return CMD_SUCCESS;
7868 }
7869
7870 DEFUN (interface_no_ip_igmp_last_member_query_interval,
7871 interface_no_ip_igmp_last_member_query_interval_cmd,
7872 "no ip igmp last-member-query-interval",
7873 NO_STR
7874 IP_STR
7875 IFACE_IGMP_STR
7876 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR)
7877 {
7878 VTY_DECLVAR_CONTEXT(interface, ifp);
7879 struct pim_interface *pim_ifp = ifp->info;
7880
7881 if (!pim_ifp)
7882 return CMD_SUCCESS;
7883
7884 pim_ifp->igmp_specific_query_max_response_time_dsec =
7885 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
7886
7887 return CMD_SUCCESS;
7888 }
7889
7890 DEFUN (interface_ip_pim_drprio,
7891 interface_ip_pim_drprio_cmd,
7892 "ip pim drpriority (1-4294967295)",
7893 IP_STR
7894 PIM_STR
7895 "Set the Designated Router Election Priority\n"
7896 "Value of the new DR Priority\n")
7897 {
7898 VTY_DECLVAR_CONTEXT(interface, ifp);
7899 int idx_number = 3;
7900 struct pim_interface *pim_ifp = ifp->info;
7901 uint32_t old_dr_prio;
7902
7903 if (!pim_ifp) {
7904 vty_out(vty, "Please enable PIM on interface, first\n");
7905 return CMD_WARNING_CONFIG_FAILED;
7906 }
7907
7908 old_dr_prio = pim_ifp->pim_dr_priority;
7909
7910 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
7911
7912 if (old_dr_prio != pim_ifp->pim_dr_priority) {
7913 pim_if_dr_election(ifp);
7914 pim_hello_restart_now(ifp);
7915 }
7916
7917 return CMD_SUCCESS;
7918 }
7919
7920 DEFUN (interface_no_ip_pim_drprio,
7921 interface_no_ip_pim_drprio_cmd,
7922 "no ip pim drpriority [(1-4294967295)]",
7923 NO_STR
7924 IP_STR
7925 PIM_STR
7926 "Revert the Designated Router Priority to default\n"
7927 "Old Value of the Priority\n")
7928 {
7929 VTY_DECLVAR_CONTEXT(interface, ifp);
7930 struct pim_interface *pim_ifp = ifp->info;
7931
7932 if (!pim_ifp) {
7933 vty_out(vty, "Pim not enabled on this interface\n");
7934 return CMD_WARNING_CONFIG_FAILED;
7935 }
7936
7937 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
7938 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
7939 pim_if_dr_election(ifp);
7940 pim_hello_restart_now(ifp);
7941 }
7942
7943 return CMD_SUCCESS;
7944 }
7945
7946 DEFPY_HIDDEN (interface_ip_igmp_query_generate,
7947 interface_ip_igmp_query_generate_cmd,
7948 "ip igmp generate-query-once [version (2-3)]",
7949 IP_STR
7950 IFACE_IGMP_STR
7951 "Generate igmp general query once\n"
7952 "IGMP version\n"
7953 "IGMP version number\n")
7954 {
7955 VTY_DECLVAR_CONTEXT(interface, ifp);
7956 int igmp_version = 2;
7957
7958 if (!ifp->info) {
7959 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
7960 ifp->name);
7961 return CMD_WARNING_CONFIG_FAILED;
7962 }
7963
7964 if (argc > 3)
7965 igmp_version = atoi(argv[4]->arg);
7966
7967 igmp_send_query_on_intf(ifp, igmp_version);
7968
7969 return CMD_SUCCESS;
7970 }
7971
7972 static int pim_cmd_interface_add(struct interface *ifp)
7973 {
7974 struct pim_interface *pim_ifp = ifp->info;
7975
7976 if (!pim_ifp)
7977 pim_ifp = pim_if_new(ifp, false, true, false, false);
7978 else
7979 PIM_IF_DO_PIM(pim_ifp->options);
7980
7981 pim_if_addr_add_all(ifp);
7982 pim_if_membership_refresh(ifp);
7983
7984 pim_if_create_pimreg(pim_ifp->pim);
7985 return 1;
7986 }
7987
7988 DEFPY_HIDDEN (pim_test_sg_keepalive,
7989 pim_test_sg_keepalive_cmd,
7990 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7991 "Test code\n"
7992 PIM_STR
7993 VRF_CMD_HELP_STR
7994 "Reset the Keepalive Timer\n"
7995 "The Source we are resetting\n"
7996 "The Group we are resetting\n")
7997 {
7998 struct pim_upstream *up;
7999 struct pim_instance *pim;
8000 struct prefix_sg sg;
8001
8002 sg.src = source;
8003 sg.grp = group;
8004
8005 if (!name)
8006 pim = pim_get_pim_instance(VRF_DEFAULT);
8007 else {
8008 struct vrf *vrf = vrf_lookup_by_name(name);
8009
8010 if (!vrf) {
8011 vty_out(vty, "%% Vrf specified: %s does not exist\n",
8012 name);
8013 return CMD_WARNING;
8014 }
8015
8016 pim = pim_get_pim_instance(vrf->vrf_id);
8017 }
8018
8019 if (!pim) {
8020 vty_out(vty, "%% Unable to find pim instance\n");
8021 return CMD_WARNING;
8022 }
8023
8024 up = pim_upstream_find(pim, &sg);
8025 if (!up) {
8026 vty_out(vty, "%% Unable to find %s specified\n",
8027 pim_str_sg_dump(&sg));
8028 return CMD_WARNING;
8029 }
8030
8031 vty_out(vty, "Setting %s to current keep alive time: %d\n",
8032 pim_str_sg_dump(&sg), pim->keep_alive_time);
8033 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
8034
8035 return CMD_SUCCESS;
8036 }
8037
8038 DEFPY_HIDDEN (interface_ip_pim_activeactive,
8039 interface_ip_pim_activeactive_cmd,
8040 "[no$no] ip pim active-active",
8041 NO_STR
8042 IP_STR
8043 PIM_STR
8044 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
8045 {
8046 VTY_DECLVAR_CONTEXT(interface, ifp);
8047 struct pim_interface *pim_ifp;
8048
8049 if (!no && !pim_cmd_interface_add(ifp)) {
8050 vty_out(vty, "Could not enable PIM SM active-active on interface\n");
8051 return CMD_WARNING_CONFIG_FAILED;
8052 }
8053
8054 pim_ifp = ifp->info;
8055 if (no)
8056 pim_if_unconfigure_mlag_dualactive(pim_ifp);
8057 else
8058 pim_if_configure_mlag_dualactive(pim_ifp);
8059
8060 return CMD_SUCCESS;
8061 }
8062
8063 DEFUN_HIDDEN (interface_ip_pim_ssm,
8064 interface_ip_pim_ssm_cmd,
8065 "ip pim ssm",
8066 IP_STR
8067 PIM_STR
8068 IFACE_PIM_STR)
8069 {
8070 VTY_DECLVAR_CONTEXT(interface, ifp);
8071
8072 if (!pim_cmd_interface_add(ifp)) {
8073 vty_out(vty, "Could not enable PIM SM on interface\n");
8074 return CMD_WARNING_CONFIG_FAILED;
8075 }
8076
8077 vty_out(vty,
8078 "WARN: Enabled PIM SM on interface; configure PIM SSM "
8079 "range if needed\n");
8080 return CMD_SUCCESS;
8081 }
8082
8083 static int interface_ip_pim_helper(struct vty *vty)
8084 {
8085 struct pim_interface *pim_ifp;
8086
8087 VTY_DECLVAR_CONTEXT(interface, ifp);
8088
8089 if (!pim_cmd_interface_add(ifp)) {
8090 vty_out(vty, "Could not enable PIM SM on interface\n");
8091 return CMD_WARNING_CONFIG_FAILED;
8092 }
8093
8094 pim_ifp = ifp->info;
8095
8096 pim_if_create_pimreg(pim_ifp->pim);
8097
8098 return CMD_SUCCESS;
8099 }
8100
8101 DEFUN_HIDDEN (interface_ip_pim_sm,
8102 interface_ip_pim_sm_cmd,
8103 "ip pim sm",
8104 IP_STR
8105 PIM_STR
8106 IFACE_PIM_SM_STR)
8107 {
8108 return interface_ip_pim_helper(vty);
8109 }
8110
8111 DEFUN (interface_ip_pim,
8112 interface_ip_pim_cmd,
8113 "ip pim",
8114 IP_STR
8115 PIM_STR)
8116 {
8117 return interface_ip_pim_helper(vty);
8118 }
8119
8120 static int pim_cmd_interface_delete(struct interface *ifp)
8121 {
8122 struct pim_interface *pim_ifp = ifp->info;
8123
8124 if (!pim_ifp)
8125 return 1;
8126
8127 PIM_IF_DONT_PIM(pim_ifp->options);
8128
8129 pim_if_membership_clear(ifp);
8130
8131 /*
8132 pim_sock_delete() removes all neighbors from
8133 pim_ifp->pim_neighbor_list.
8134 */
8135 pim_sock_delete(ifp, "pim unconfigured on interface");
8136
8137 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
8138 pim_if_addr_del_all(ifp);
8139 pim_if_delete(ifp);
8140 }
8141
8142 return 1;
8143 }
8144
8145 static int interface_no_ip_pim_helper(struct vty *vty)
8146 {
8147 VTY_DECLVAR_CONTEXT(interface, ifp);
8148 if (!pim_cmd_interface_delete(ifp)) {
8149 vty_out(vty, "Unable to delete interface information\n");
8150 return CMD_WARNING_CONFIG_FAILED;
8151 }
8152
8153 return CMD_SUCCESS;
8154 }
8155
8156 DEFUN_HIDDEN (interface_no_ip_pim_ssm,
8157 interface_no_ip_pim_ssm_cmd,
8158 "no ip pim ssm",
8159 NO_STR
8160 IP_STR
8161 PIM_STR
8162 IFACE_PIM_STR)
8163 {
8164 return interface_no_ip_pim_helper(vty);
8165 }
8166
8167 DEFUN_HIDDEN (interface_no_ip_pim_sm,
8168 interface_no_ip_pim_sm_cmd,
8169 "no ip pim sm",
8170 NO_STR
8171 IP_STR
8172 PIM_STR
8173 IFACE_PIM_SM_STR)
8174 {
8175 return interface_no_ip_pim_helper(vty);
8176 }
8177
8178 DEFUN (interface_no_ip_pim,
8179 interface_no_ip_pim_cmd,
8180 "no ip pim",
8181 NO_STR
8182 IP_STR
8183 PIM_STR)
8184 {
8185 return interface_no_ip_pim_helper(vty);
8186 }
8187
8188 /* boundaries */
8189 DEFUN(interface_ip_pim_boundary_oil,
8190 interface_ip_pim_boundary_oil_cmd,
8191 "ip multicast boundary oil WORD",
8192 IP_STR
8193 "Generic multicast configuration options\n"
8194 "Define multicast boundary\n"
8195 "Filter OIL by group using prefix list\n"
8196 "Prefix list to filter OIL with\n")
8197 {
8198 VTY_DECLVAR_CONTEXT(interface, iif);
8199 struct pim_interface *pim_ifp;
8200 int idx = 0;
8201
8202 argv_find(argv, argc, "WORD", &idx);
8203
8204 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
8205
8206 if (pim_ifp->boundary_oil_plist)
8207 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
8208
8209 pim_ifp->boundary_oil_plist =
8210 XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
8211
8212 /* Interface will be pruned from OIL on next Join */
8213 return CMD_SUCCESS;
8214 }
8215
8216 DEFUN(interface_no_ip_pim_boundary_oil,
8217 interface_no_ip_pim_boundary_oil_cmd,
8218 "no ip multicast boundary oil [WORD]",
8219 NO_STR
8220 IP_STR
8221 "Generic multicast configuration options\n"
8222 "Define multicast boundary\n"
8223 "Filter OIL by group using prefix list\n"
8224 "Prefix list to filter OIL with\n")
8225 {
8226 VTY_DECLVAR_CONTEXT(interface, iif);
8227 struct pim_interface *pim_ifp;
8228 int idx = 0;
8229
8230 argv_find(argv, argc, "WORD", &idx);
8231
8232 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
8233
8234 if (pim_ifp->boundary_oil_plist)
8235 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
8236
8237 return CMD_SUCCESS;
8238 }
8239
8240 DEFUN (interface_ip_mroute,
8241 interface_ip_mroute_cmd,
8242 "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8243 IP_STR
8244 "Add multicast route\n"
8245 "Outgoing interface name\n"
8246 "Group address\n"
8247 "Source address\n")
8248 {
8249 VTY_DECLVAR_CONTEXT(interface, iif);
8250 struct pim_interface *pim_ifp;
8251 struct pim_instance *pim;
8252 int idx_interface = 2;
8253 int idx_ipv4 = 3;
8254 struct interface *oif;
8255 const char *oifname;
8256 const char *grp_str;
8257 struct in_addr grp_addr;
8258 const char *src_str;
8259 struct in_addr src_addr;
8260 int result;
8261
8262 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
8263 pim = pim_ifp->pim;
8264
8265 oifname = argv[idx_interface]->arg;
8266 oif = if_lookup_by_name(oifname, pim->vrf_id);
8267 if (!oif) {
8268 vty_out(vty, "No such interface name %s\n", oifname);
8269 return CMD_WARNING;
8270 }
8271
8272 grp_str = argv[idx_ipv4]->arg;
8273 result = inet_pton(AF_INET, grp_str, &grp_addr);
8274 if (result <= 0) {
8275 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
8276 errno, safe_strerror(errno));
8277 return CMD_WARNING;
8278 }
8279
8280 if (argc == (idx_ipv4 + 1)) {
8281 src_addr.s_addr = INADDR_ANY;
8282 }
8283 else {
8284 src_str = argv[idx_ipv4 + 1]->arg;
8285 result = inet_pton(AF_INET, src_str, &src_addr);
8286 if (result <= 0) {
8287 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
8288 errno, safe_strerror(errno));
8289 return CMD_WARNING;
8290 }
8291 }
8292
8293 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
8294 vty_out(vty, "Failed to add static mroute\n");
8295 return CMD_WARNING;
8296 }
8297
8298 return CMD_SUCCESS;
8299 }
8300
8301 DEFUN (interface_no_ip_mroute,
8302 interface_no_ip_mroute_cmd,
8303 "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
8304 NO_STR
8305 IP_STR
8306 "Add multicast route\n"
8307 "Outgoing interface name\n"
8308 "Group Address\n"
8309 "Source Address\n")
8310 {
8311 VTY_DECLVAR_CONTEXT(interface, iif);
8312 struct pim_interface *pim_ifp;
8313 struct pim_instance *pim;
8314 int idx_interface = 3;
8315 int idx_ipv4 = 4;
8316 struct interface *oif;
8317 const char *oifname;
8318 const char *grp_str;
8319 struct in_addr grp_addr;
8320 const char *src_str;
8321 struct in_addr src_addr;
8322 int result;
8323
8324 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
8325 pim = pim_ifp->pim;
8326
8327 oifname = argv[idx_interface]->arg;
8328 oif = if_lookup_by_name(oifname, pim->vrf_id);
8329 if (!oif) {
8330 vty_out(vty, "No such interface name %s\n", oifname);
8331 return CMD_WARNING;
8332 }
8333
8334 grp_str = argv[idx_ipv4]->arg;
8335 result = inet_pton(AF_INET, grp_str, &grp_addr);
8336 if (result <= 0) {
8337 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
8338 errno, safe_strerror(errno));
8339 return CMD_WARNING;
8340 }
8341
8342 if (argc == (idx_ipv4 + 1)) {
8343 src_addr.s_addr = INADDR_ANY;
8344 }
8345 else {
8346 src_str = argv[idx_ipv4 + 1]->arg;
8347 result = inet_pton(AF_INET, src_str, &src_addr);
8348 if (result <= 0) {
8349 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
8350 errno, safe_strerror(errno));
8351 return CMD_WARNING;
8352 }
8353 }
8354
8355 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
8356 vty_out(vty, "Failed to remove static mroute\n");
8357 return CMD_WARNING;
8358 }
8359
8360 return CMD_SUCCESS;
8361 }
8362
8363 DEFUN (interface_ip_pim_hello,
8364 interface_ip_pim_hello_cmd,
8365 "ip pim hello (1-180) [(1-180)]",
8366 IP_STR
8367 PIM_STR
8368 IFACE_PIM_HELLO_STR
8369 IFACE_PIM_HELLO_TIME_STR
8370 IFACE_PIM_HELLO_HOLD_STR)
8371 {
8372 VTY_DECLVAR_CONTEXT(interface, ifp);
8373 int idx_time = 3;
8374 int idx_hold = 4;
8375 struct pim_interface *pim_ifp = ifp->info;
8376
8377 if (!pim_ifp) {
8378 if (!pim_cmd_interface_add(ifp)) {
8379 vty_out(vty, "Could not enable PIM SM on interface\n");
8380 return CMD_WARNING_CONFIG_FAILED;
8381 }
8382 }
8383
8384 pim_ifp = ifp->info;
8385 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
8386
8387 if (argc == idx_hold + 1)
8388 pim_ifp->pim_default_holdtime =
8389 strtol(argv[idx_hold]->arg, NULL, 10);
8390
8391 return CMD_SUCCESS;
8392 }
8393
8394 DEFUN (interface_no_ip_pim_hello,
8395 interface_no_ip_pim_hello_cmd,
8396 "no ip pim hello [(1-180) (1-180)]",
8397 NO_STR
8398 IP_STR
8399 PIM_STR
8400 IFACE_PIM_HELLO_STR
8401 IFACE_PIM_HELLO_TIME_STR
8402 IFACE_PIM_HELLO_HOLD_STR)
8403 {
8404 VTY_DECLVAR_CONTEXT(interface, ifp);
8405 struct pim_interface *pim_ifp = ifp->info;
8406
8407 if (!pim_ifp) {
8408 vty_out(vty, "Pim not enabled on this interface\n");
8409 return CMD_WARNING_CONFIG_FAILED;
8410 }
8411
8412 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
8413 pim_ifp->pim_default_holdtime = -1;
8414
8415 return CMD_SUCCESS;
8416 }
8417
8418 DEFUN (debug_igmp,
8419 debug_igmp_cmd,
8420 "debug igmp",
8421 DEBUG_STR
8422 DEBUG_IGMP_STR)
8423 {
8424 PIM_DO_DEBUG_IGMP_EVENTS;
8425 PIM_DO_DEBUG_IGMP_PACKETS;
8426 PIM_DO_DEBUG_IGMP_TRACE;
8427 return CMD_SUCCESS;
8428 }
8429
8430 DEFUN (no_debug_igmp,
8431 no_debug_igmp_cmd,
8432 "no debug igmp",
8433 NO_STR
8434 DEBUG_STR
8435 DEBUG_IGMP_STR)
8436 {
8437 PIM_DONT_DEBUG_IGMP_EVENTS;
8438 PIM_DONT_DEBUG_IGMP_PACKETS;
8439 PIM_DONT_DEBUG_IGMP_TRACE;
8440 return CMD_SUCCESS;
8441 }
8442
8443
8444 DEFUN (debug_igmp_events,
8445 debug_igmp_events_cmd,
8446 "debug igmp events",
8447 DEBUG_STR
8448 DEBUG_IGMP_STR
8449 DEBUG_IGMP_EVENTS_STR)
8450 {
8451 PIM_DO_DEBUG_IGMP_EVENTS;
8452 return CMD_SUCCESS;
8453 }
8454
8455 DEFUN (no_debug_igmp_events,
8456 no_debug_igmp_events_cmd,
8457 "no debug igmp events",
8458 NO_STR
8459 DEBUG_STR
8460 DEBUG_IGMP_STR
8461 DEBUG_IGMP_EVENTS_STR)
8462 {
8463 PIM_DONT_DEBUG_IGMP_EVENTS;
8464 return CMD_SUCCESS;
8465 }
8466
8467
8468 DEFUN (debug_igmp_packets,
8469 debug_igmp_packets_cmd,
8470 "debug igmp packets",
8471 DEBUG_STR
8472 DEBUG_IGMP_STR
8473 DEBUG_IGMP_PACKETS_STR)
8474 {
8475 PIM_DO_DEBUG_IGMP_PACKETS;
8476 return CMD_SUCCESS;
8477 }
8478
8479 DEFUN (no_debug_igmp_packets,
8480 no_debug_igmp_packets_cmd,
8481 "no debug igmp packets",
8482 NO_STR
8483 DEBUG_STR
8484 DEBUG_IGMP_STR
8485 DEBUG_IGMP_PACKETS_STR)
8486 {
8487 PIM_DONT_DEBUG_IGMP_PACKETS;
8488 return CMD_SUCCESS;
8489 }
8490
8491
8492 DEFUN (debug_igmp_trace,
8493 debug_igmp_trace_cmd,
8494 "debug igmp trace",
8495 DEBUG_STR
8496 DEBUG_IGMP_STR
8497 DEBUG_IGMP_TRACE_STR)
8498 {
8499 PIM_DO_DEBUG_IGMP_TRACE;
8500 return CMD_SUCCESS;
8501 }
8502
8503 DEFUN (no_debug_igmp_trace,
8504 no_debug_igmp_trace_cmd,
8505 "no debug igmp trace",
8506 NO_STR
8507 DEBUG_STR
8508 DEBUG_IGMP_STR
8509 DEBUG_IGMP_TRACE_STR)
8510 {
8511 PIM_DONT_DEBUG_IGMP_TRACE;
8512 return CMD_SUCCESS;
8513 }
8514
8515
8516 DEFUN (debug_mroute,
8517 debug_mroute_cmd,
8518 "debug mroute",
8519 DEBUG_STR
8520 DEBUG_MROUTE_STR)
8521 {
8522 PIM_DO_DEBUG_MROUTE;
8523 return CMD_SUCCESS;
8524 }
8525
8526 DEFUN (debug_mroute_detail,
8527 debug_mroute_detail_cmd,
8528 "debug mroute detail",
8529 DEBUG_STR
8530 DEBUG_MROUTE_STR
8531 "detailed\n")
8532 {
8533 PIM_DO_DEBUG_MROUTE_DETAIL;
8534 return CMD_SUCCESS;
8535 }
8536
8537 DEFUN (no_debug_mroute,
8538 no_debug_mroute_cmd,
8539 "no debug mroute",
8540 NO_STR
8541 DEBUG_STR
8542 DEBUG_MROUTE_STR)
8543 {
8544 PIM_DONT_DEBUG_MROUTE;
8545 return CMD_SUCCESS;
8546 }
8547
8548 DEFUN (no_debug_mroute_detail,
8549 no_debug_mroute_detail_cmd,
8550 "no debug mroute detail",
8551 NO_STR
8552 DEBUG_STR
8553 DEBUG_MROUTE_STR
8554 "detailed\n")
8555 {
8556 PIM_DONT_DEBUG_MROUTE_DETAIL;
8557 return CMD_SUCCESS;
8558 }
8559
8560 DEFUN (debug_pim_static,
8561 debug_pim_static_cmd,
8562 "debug pim static",
8563 DEBUG_STR
8564 DEBUG_PIM_STR
8565 DEBUG_STATIC_STR)
8566 {
8567 PIM_DO_DEBUG_STATIC;
8568 return CMD_SUCCESS;
8569 }
8570
8571 DEFUN (no_debug_pim_static,
8572 no_debug_pim_static_cmd,
8573 "no debug pim static",
8574 NO_STR
8575 DEBUG_STR
8576 DEBUG_PIM_STR
8577 DEBUG_STATIC_STR)
8578 {
8579 PIM_DONT_DEBUG_STATIC;
8580 return CMD_SUCCESS;
8581 }
8582
8583
8584 DEFUN (debug_pim,
8585 debug_pim_cmd,
8586 "debug pim",
8587 DEBUG_STR
8588 DEBUG_PIM_STR)
8589 {
8590 PIM_DO_DEBUG_PIM_EVENTS;
8591 PIM_DO_DEBUG_PIM_PACKETS;
8592 PIM_DO_DEBUG_PIM_TRACE;
8593 PIM_DO_DEBUG_MSDP_EVENTS;
8594 PIM_DO_DEBUG_MSDP_PACKETS;
8595 PIM_DO_DEBUG_BSM;
8596 return CMD_SUCCESS;
8597 }
8598
8599 DEFUN (no_debug_pim,
8600 no_debug_pim_cmd,
8601 "no debug pim",
8602 NO_STR
8603 DEBUG_STR
8604 DEBUG_PIM_STR)
8605 {
8606 PIM_DONT_DEBUG_PIM_EVENTS;
8607 PIM_DONT_DEBUG_PIM_PACKETS;
8608 PIM_DONT_DEBUG_PIM_TRACE;
8609 PIM_DONT_DEBUG_MSDP_EVENTS;
8610 PIM_DONT_DEBUG_MSDP_PACKETS;
8611
8612 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8613 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8614 PIM_DONT_DEBUG_BSM;
8615
8616 return CMD_SUCCESS;
8617 }
8618
8619 DEFUN (debug_pim_nht,
8620 debug_pim_nht_cmd,
8621 "debug pim nht",
8622 DEBUG_STR
8623 DEBUG_PIM_STR
8624 "Nexthop Tracking\n")
8625 {
8626 PIM_DO_DEBUG_PIM_NHT;
8627 return CMD_SUCCESS;
8628 }
8629
8630 DEFUN (no_debug_pim_nht,
8631 no_debug_pim_nht_cmd,
8632 "no debug pim nht",
8633 NO_STR
8634 DEBUG_STR
8635 DEBUG_PIM_STR
8636 "Nexthop Tracking\n")
8637 {
8638 PIM_DONT_DEBUG_PIM_NHT;
8639 return CMD_SUCCESS;
8640 }
8641
8642 DEFUN (debug_pim_nht_rp,
8643 debug_pim_nht_rp_cmd,
8644 "debug pim nht rp",
8645 DEBUG_STR
8646 DEBUG_PIM_STR
8647 "Nexthop Tracking\n"
8648 "RP Nexthop Tracking\n")
8649 {
8650 PIM_DO_DEBUG_PIM_NHT_RP;
8651 return CMD_SUCCESS;
8652 }
8653
8654 DEFUN (no_debug_pim_nht_rp,
8655 no_debug_pim_nht_rp_cmd,
8656 "no debug pim nht rp",
8657 NO_STR
8658 DEBUG_STR
8659 DEBUG_PIM_STR
8660 "Nexthop Tracking\n"
8661 "RP Nexthop Tracking\n")
8662 {
8663 PIM_DONT_DEBUG_PIM_NHT_RP;
8664 return CMD_SUCCESS;
8665 }
8666
8667 DEFUN (debug_pim_events,
8668 debug_pim_events_cmd,
8669 "debug pim events",
8670 DEBUG_STR
8671 DEBUG_PIM_STR
8672 DEBUG_PIM_EVENTS_STR)
8673 {
8674 PIM_DO_DEBUG_PIM_EVENTS;
8675 return CMD_SUCCESS;
8676 }
8677
8678 DEFUN (no_debug_pim_events,
8679 no_debug_pim_events_cmd,
8680 "no debug pim events",
8681 NO_STR
8682 DEBUG_STR
8683 DEBUG_PIM_STR
8684 DEBUG_PIM_EVENTS_STR)
8685 {
8686 PIM_DONT_DEBUG_PIM_EVENTS;
8687 return CMD_SUCCESS;
8688 }
8689
8690 DEFUN (debug_pim_packets,
8691 debug_pim_packets_cmd,
8692 "debug pim packets [<hello|joins|register>]",
8693 DEBUG_STR
8694 DEBUG_PIM_STR
8695 DEBUG_PIM_PACKETS_STR
8696 DEBUG_PIM_HELLO_PACKETS_STR
8697 DEBUG_PIM_J_P_PACKETS_STR
8698 DEBUG_PIM_PIM_REG_PACKETS_STR)
8699 {
8700 int idx = 0;
8701 if (argv_find(argv, argc, "hello", &idx)) {
8702 PIM_DO_DEBUG_PIM_HELLO;
8703 vty_out(vty, "PIM Hello debugging is on\n");
8704 } else if (argv_find(argv, argc, "joins", &idx)) {
8705 PIM_DO_DEBUG_PIM_J_P;
8706 vty_out(vty, "PIM Join/Prune debugging is on\n");
8707 } else if (argv_find(argv, argc, "register", &idx)) {
8708 PIM_DO_DEBUG_PIM_REG;
8709 vty_out(vty, "PIM Register debugging is on\n");
8710 } else {
8711 PIM_DO_DEBUG_PIM_PACKETS;
8712 vty_out(vty, "PIM Packet debugging is on \n");
8713 }
8714 return CMD_SUCCESS;
8715 }
8716
8717 DEFUN (no_debug_pim_packets,
8718 no_debug_pim_packets_cmd,
8719 "no debug pim packets [<hello|joins|register>]",
8720 NO_STR
8721 DEBUG_STR
8722 DEBUG_PIM_STR
8723 DEBUG_PIM_PACKETS_STR
8724 DEBUG_PIM_HELLO_PACKETS_STR
8725 DEBUG_PIM_J_P_PACKETS_STR
8726 DEBUG_PIM_PIM_REG_PACKETS_STR)
8727 {
8728 int idx = 0;
8729 if (argv_find(argv, argc, "hello", &idx)) {
8730 PIM_DONT_DEBUG_PIM_HELLO;
8731 vty_out(vty, "PIM Hello debugging is off \n");
8732 } else if (argv_find(argv, argc, "joins", &idx)) {
8733 PIM_DONT_DEBUG_PIM_J_P;
8734 vty_out(vty, "PIM Join/Prune debugging is off \n");
8735 } else if (argv_find(argv, argc, "register", &idx)) {
8736 PIM_DONT_DEBUG_PIM_REG;
8737 vty_out(vty, "PIM Register debugging is off\n");
8738 } else
8739 PIM_DONT_DEBUG_PIM_PACKETS;
8740
8741 return CMD_SUCCESS;
8742 }
8743
8744
8745 DEFUN (debug_pim_packetdump_send,
8746 debug_pim_packetdump_send_cmd,
8747 "debug pim packet-dump send",
8748 DEBUG_STR
8749 DEBUG_PIM_STR
8750 DEBUG_PIM_PACKETDUMP_STR
8751 DEBUG_PIM_PACKETDUMP_SEND_STR)
8752 {
8753 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
8754 return CMD_SUCCESS;
8755 }
8756
8757 DEFUN (no_debug_pim_packetdump_send,
8758 no_debug_pim_packetdump_send_cmd,
8759 "no debug pim packet-dump send",
8760 NO_STR
8761 DEBUG_STR
8762 DEBUG_PIM_STR
8763 DEBUG_PIM_PACKETDUMP_STR
8764 DEBUG_PIM_PACKETDUMP_SEND_STR)
8765 {
8766 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8767 return CMD_SUCCESS;
8768 }
8769
8770 DEFUN (debug_pim_packetdump_recv,
8771 debug_pim_packetdump_recv_cmd,
8772 "debug pim packet-dump receive",
8773 DEBUG_STR
8774 DEBUG_PIM_STR
8775 DEBUG_PIM_PACKETDUMP_STR
8776 DEBUG_PIM_PACKETDUMP_RECV_STR)
8777 {
8778 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
8779 return CMD_SUCCESS;
8780 }
8781
8782 DEFUN (no_debug_pim_packetdump_recv,
8783 no_debug_pim_packetdump_recv_cmd,
8784 "no debug pim packet-dump receive",
8785 NO_STR
8786 DEBUG_STR
8787 DEBUG_PIM_STR
8788 DEBUG_PIM_PACKETDUMP_STR
8789 DEBUG_PIM_PACKETDUMP_RECV_STR)
8790 {
8791 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8792 return CMD_SUCCESS;
8793 }
8794
8795 DEFUN (debug_pim_trace,
8796 debug_pim_trace_cmd,
8797 "debug pim trace",
8798 DEBUG_STR
8799 DEBUG_PIM_STR
8800 DEBUG_PIM_TRACE_STR)
8801 {
8802 PIM_DO_DEBUG_PIM_TRACE;
8803 return CMD_SUCCESS;
8804 }
8805
8806 DEFUN (debug_pim_trace_detail,
8807 debug_pim_trace_detail_cmd,
8808 "debug pim trace detail",
8809 DEBUG_STR
8810 DEBUG_PIM_STR
8811 DEBUG_PIM_TRACE_STR
8812 "Detailed Information\n")
8813 {
8814 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
8815 return CMD_SUCCESS;
8816 }
8817
8818 DEFUN (no_debug_pim_trace,
8819 no_debug_pim_trace_cmd,
8820 "no debug pim trace",
8821 NO_STR
8822 DEBUG_STR
8823 DEBUG_PIM_STR
8824 DEBUG_PIM_TRACE_STR)
8825 {
8826 PIM_DONT_DEBUG_PIM_TRACE;
8827 return CMD_SUCCESS;
8828 }
8829
8830 DEFUN (no_debug_pim_trace_detail,
8831 no_debug_pim_trace_detail_cmd,
8832 "no debug pim trace detail",
8833 NO_STR
8834 DEBUG_STR
8835 DEBUG_PIM_STR
8836 DEBUG_PIM_TRACE_STR
8837 "Detailed Information\n")
8838 {
8839 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
8840 return CMD_SUCCESS;
8841 }
8842
8843 DEFUN (debug_ssmpingd,
8844 debug_ssmpingd_cmd,
8845 "debug ssmpingd",
8846 DEBUG_STR
8847 DEBUG_SSMPINGD_STR)
8848 {
8849 PIM_DO_DEBUG_SSMPINGD;
8850 return CMD_SUCCESS;
8851 }
8852
8853 DEFUN (no_debug_ssmpingd,
8854 no_debug_ssmpingd_cmd,
8855 "no debug ssmpingd",
8856 NO_STR
8857 DEBUG_STR
8858 DEBUG_SSMPINGD_STR)
8859 {
8860 PIM_DONT_DEBUG_SSMPINGD;
8861 return CMD_SUCCESS;
8862 }
8863
8864 DEFUN (debug_pim_zebra,
8865 debug_pim_zebra_cmd,
8866 "debug pim zebra",
8867 DEBUG_STR
8868 DEBUG_PIM_STR
8869 DEBUG_PIM_ZEBRA_STR)
8870 {
8871 PIM_DO_DEBUG_ZEBRA;
8872 return CMD_SUCCESS;
8873 }
8874
8875 DEFUN (no_debug_pim_zebra,
8876 no_debug_pim_zebra_cmd,
8877 "no debug pim zebra",
8878 NO_STR
8879 DEBUG_STR
8880 DEBUG_PIM_STR
8881 DEBUG_PIM_ZEBRA_STR)
8882 {
8883 PIM_DONT_DEBUG_ZEBRA;
8884 return CMD_SUCCESS;
8885 }
8886
8887 DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
8888 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8889 {
8890 PIM_DO_DEBUG_MLAG;
8891 return CMD_SUCCESS;
8892 }
8893
8894 DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
8895 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8896 {
8897 PIM_DONT_DEBUG_MLAG;
8898 return CMD_SUCCESS;
8899 }
8900
8901 DEFUN (debug_pim_vxlan,
8902 debug_pim_vxlan_cmd,
8903 "debug pim vxlan",
8904 DEBUG_STR
8905 DEBUG_PIM_STR
8906 DEBUG_PIM_VXLAN_STR)
8907 {
8908 PIM_DO_DEBUG_VXLAN;
8909 return CMD_SUCCESS;
8910 }
8911
8912 DEFUN (no_debug_pim_vxlan,
8913 no_debug_pim_vxlan_cmd,
8914 "no debug pim vxlan",
8915 NO_STR
8916 DEBUG_STR
8917 DEBUG_PIM_STR
8918 DEBUG_PIM_VXLAN_STR)
8919 {
8920 PIM_DONT_DEBUG_VXLAN;
8921 return CMD_SUCCESS;
8922 }
8923
8924 DEFUN (debug_msdp,
8925 debug_msdp_cmd,
8926 "debug msdp",
8927 DEBUG_STR
8928 DEBUG_MSDP_STR)
8929 {
8930 PIM_DO_DEBUG_MSDP_EVENTS;
8931 PIM_DO_DEBUG_MSDP_PACKETS;
8932 return CMD_SUCCESS;
8933 }
8934
8935 DEFUN (no_debug_msdp,
8936 no_debug_msdp_cmd,
8937 "no debug msdp",
8938 NO_STR
8939 DEBUG_STR
8940 DEBUG_MSDP_STR)
8941 {
8942 PIM_DONT_DEBUG_MSDP_EVENTS;
8943 PIM_DONT_DEBUG_MSDP_PACKETS;
8944 return CMD_SUCCESS;
8945 }
8946
8947 DEFUN (debug_msdp_events,
8948 debug_msdp_events_cmd,
8949 "debug msdp events",
8950 DEBUG_STR
8951 DEBUG_MSDP_STR
8952 DEBUG_MSDP_EVENTS_STR)
8953 {
8954 PIM_DO_DEBUG_MSDP_EVENTS;
8955 return CMD_SUCCESS;
8956 }
8957
8958 DEFUN (no_debug_msdp_events,
8959 no_debug_msdp_events_cmd,
8960 "no debug msdp events",
8961 NO_STR
8962 DEBUG_STR
8963 DEBUG_MSDP_STR
8964 DEBUG_MSDP_EVENTS_STR)
8965 {
8966 PIM_DONT_DEBUG_MSDP_EVENTS;
8967 return CMD_SUCCESS;
8968 }
8969
8970 DEFUN (debug_msdp_packets,
8971 debug_msdp_packets_cmd,
8972 "debug msdp packets",
8973 DEBUG_STR
8974 DEBUG_MSDP_STR
8975 DEBUG_MSDP_PACKETS_STR)
8976 {
8977 PIM_DO_DEBUG_MSDP_PACKETS;
8978 return CMD_SUCCESS;
8979 }
8980
8981 DEFUN (no_debug_msdp_packets,
8982 no_debug_msdp_packets_cmd,
8983 "no debug msdp packets",
8984 NO_STR
8985 DEBUG_STR
8986 DEBUG_MSDP_STR
8987 DEBUG_MSDP_PACKETS_STR)
8988 {
8989 PIM_DONT_DEBUG_MSDP_PACKETS;
8990 return CMD_SUCCESS;
8991 }
8992
8993 DEFUN (debug_mtrace,
8994 debug_mtrace_cmd,
8995 "debug mtrace",
8996 DEBUG_STR
8997 DEBUG_MTRACE_STR)
8998 {
8999 PIM_DO_DEBUG_MTRACE;
9000 return CMD_SUCCESS;
9001 }
9002
9003 DEFUN (no_debug_mtrace,
9004 no_debug_mtrace_cmd,
9005 "no debug mtrace",
9006 NO_STR
9007 DEBUG_STR
9008 DEBUG_MTRACE_STR)
9009 {
9010 PIM_DONT_DEBUG_MTRACE;
9011 return CMD_SUCCESS;
9012 }
9013
9014 DEFUN (debug_bsm,
9015 debug_bsm_cmd,
9016 "debug pim bsm",
9017 DEBUG_STR
9018 DEBUG_PIM_STR
9019 DEBUG_PIM_BSM_STR)
9020 {
9021 PIM_DO_DEBUG_BSM;
9022 return CMD_SUCCESS;
9023 }
9024
9025 DEFUN (no_debug_bsm,
9026 no_debug_bsm_cmd,
9027 "no debug pim bsm",
9028 NO_STR
9029 DEBUG_STR
9030 DEBUG_PIM_STR
9031 DEBUG_PIM_BSM_STR)
9032 {
9033 PIM_DONT_DEBUG_BSM;
9034 return CMD_SUCCESS;
9035 }
9036
9037
9038 DEFUN_NOSH (show_debugging_pim,
9039 show_debugging_pim_cmd,
9040 "show debugging [pim]",
9041 SHOW_STR
9042 DEBUG_STR
9043 PIM_STR)
9044 {
9045 vty_out(vty, "PIM debugging status\n");
9046
9047 pim_debug_config_write(vty);
9048
9049 return CMD_SUCCESS;
9050 }
9051
9052 static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
9053 {
9054 int result;
9055 struct in_addr source_addr;
9056 int ret = CMD_SUCCESS;
9057 VTY_DECLVAR_CONTEXT(interface, ifp);
9058
9059 result = inet_pton(AF_INET, source, &source_addr);
9060 if (result <= 0) {
9061 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
9062 errno, safe_strerror(errno));
9063 return CMD_WARNING_CONFIG_FAILED;
9064 }
9065
9066 result = pim_update_source_set(ifp, source_addr);
9067 switch (result) {
9068 case PIM_SUCCESS:
9069 break;
9070 case PIM_IFACE_NOT_FOUND:
9071 ret = CMD_WARNING_CONFIG_FAILED;
9072 vty_out(vty, "Pim not enabled on this interface\n");
9073 break;
9074 case PIM_UPDATE_SOURCE_DUP:
9075 ret = CMD_WARNING;
9076 vty_out(vty, "%% Source already set to %s\n", source);
9077 break;
9078 default:
9079 ret = CMD_WARNING_CONFIG_FAILED;
9080 vty_out(vty, "%% Source set failed\n");
9081 }
9082
9083 return ret;
9084 }
9085
9086 DEFUN (interface_pim_use_source,
9087 interface_pim_use_source_cmd,
9088 "ip pim use-source A.B.C.D",
9089 IP_STR
9090 PIM_STR
9091 "Configure primary IP address\n"
9092 "source ip address\n")
9093 {
9094 return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
9095 }
9096
9097 DEFUN (interface_no_pim_use_source,
9098 interface_no_pim_use_source_cmd,
9099 "no ip pim use-source [A.B.C.D]",
9100 NO_STR
9101 IP_STR
9102 PIM_STR
9103 "Delete source IP address\n"
9104 "source ip address\n")
9105 {
9106 return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
9107 }
9108
9109 DEFUN (ip_pim_bfd,
9110 ip_pim_bfd_cmd,
9111 "ip pim bfd",
9112 IP_STR
9113 PIM_STR
9114 "Enables BFD support\n")
9115 {
9116 VTY_DECLVAR_CONTEXT(interface, ifp);
9117 struct pim_interface *pim_ifp = ifp->info;
9118 struct bfd_info *bfd_info = NULL;
9119
9120 if (!pim_ifp) {
9121 if (!pim_cmd_interface_add(ifp)) {
9122 vty_out(vty, "Could not enable PIM SM on interface\n");
9123 return CMD_WARNING;
9124 }
9125 }
9126 pim_ifp = ifp->info;
9127
9128 bfd_info = pim_ifp->bfd_info;
9129
9130 if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
9131 pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
9132 BFD_DEF_DETECT_MULT, 1);
9133
9134 return CMD_SUCCESS;
9135 }
9136
9137 DEFUN (no_ip_pim_bfd,
9138 no_ip_pim_bfd_cmd,
9139 "no ip pim bfd",
9140 NO_STR
9141 IP_STR
9142 PIM_STR
9143 "Disables BFD support\n")
9144 {
9145 VTY_DECLVAR_CONTEXT(interface, ifp);
9146 struct pim_interface *pim_ifp = ifp->info;
9147
9148 if (!pim_ifp) {
9149 vty_out(vty, "Pim not enabled on this interface\n");
9150 return CMD_WARNING;
9151 }
9152
9153 if (pim_ifp->bfd_info) {
9154 pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
9155 bfd_info_free(&(pim_ifp->bfd_info));
9156 }
9157
9158 return CMD_SUCCESS;
9159 }
9160
9161 DEFUN (ip_pim_bsm,
9162 ip_pim_bsm_cmd,
9163 "ip pim bsm",
9164 IP_STR
9165 PIM_STR
9166 "Enables BSM support on the interface\n")
9167 {
9168 VTY_DECLVAR_CONTEXT(interface, ifp);
9169 struct pim_interface *pim_ifp = ifp->info;
9170
9171 if (!pim_ifp) {
9172 if (!pim_cmd_interface_add(ifp)) {
9173 vty_out(vty, "Could not enable PIM SM on interface\n");
9174 return CMD_WARNING;
9175 }
9176 }
9177
9178 pim_ifp = ifp->info;
9179 pim_ifp->bsm_enable = true;
9180
9181 return CMD_SUCCESS;
9182 }
9183
9184 DEFUN (no_ip_pim_bsm,
9185 no_ip_pim_bsm_cmd,
9186 "no ip pim bsm",
9187 NO_STR
9188 IP_STR
9189 PIM_STR
9190 "Disables BSM support\n")
9191 {
9192 VTY_DECLVAR_CONTEXT(interface, ifp);
9193 struct pim_interface *pim_ifp = ifp->info;
9194
9195 if (!pim_ifp) {
9196 vty_out(vty, "Pim not enabled on this interface\n");
9197 return CMD_WARNING;
9198 }
9199
9200 pim_ifp->bsm_enable = false;
9201
9202 return CMD_SUCCESS;
9203 }
9204
9205 DEFUN (ip_pim_ucast_bsm,
9206 ip_pim_ucast_bsm_cmd,
9207 "ip pim unicast-bsm",
9208 IP_STR
9209 PIM_STR
9210 "Accept/Send unicast BSM on the interface\n")
9211 {
9212 VTY_DECLVAR_CONTEXT(interface, ifp);
9213 struct pim_interface *pim_ifp = ifp->info;
9214
9215 if (!pim_ifp) {
9216 if (!pim_cmd_interface_add(ifp)) {
9217 vty_out(vty, "Could not enable PIM SM on interface\n");
9218 return CMD_WARNING;
9219 }
9220 }
9221
9222 pim_ifp = ifp->info;
9223 pim_ifp->ucast_bsm_accept = true;
9224
9225 return CMD_SUCCESS;
9226 }
9227
9228 DEFUN (no_ip_pim_ucast_bsm,
9229 no_ip_pim_ucast_bsm_cmd,
9230 "no ip pim unicast-bsm",
9231 NO_STR
9232 IP_STR
9233 PIM_STR
9234 "Block send/receive unicast BSM on this interface\n")
9235 {
9236 VTY_DECLVAR_CONTEXT(interface, ifp);
9237 struct pim_interface *pim_ifp = ifp->info;
9238
9239 if (!pim_ifp) {
9240 vty_out(vty, "Pim not enabled on this interface\n");
9241 return CMD_WARNING;
9242 }
9243
9244 pim_ifp->ucast_bsm_accept = false;
9245
9246 return CMD_SUCCESS;
9247 }
9248
9249 #if HAVE_BFDD > 0
9250 DEFUN_HIDDEN(
9251 ip_pim_bfd_param,
9252 ip_pim_bfd_param_cmd,
9253 "ip pim bfd (2-255) (50-60000) (50-60000)",
9254 IP_STR
9255 PIM_STR
9256 "Enables BFD support\n"
9257 "Detect Multiplier\n"
9258 "Required min receive interval\n"
9259 "Desired min transmit interval\n")
9260 #else
9261 DEFUN(
9262 ip_pim_bfd_param,
9263 ip_pim_bfd_param_cmd,
9264 "ip pim bfd (2-255) (50-60000) (50-60000)",
9265 IP_STR
9266 PIM_STR
9267 "Enables BFD support\n"
9268 "Detect Multiplier\n"
9269 "Required min receive interval\n"
9270 "Desired min transmit interval\n")
9271 #endif /* HAVE_BFDD */
9272 {
9273 VTY_DECLVAR_CONTEXT(interface, ifp);
9274 int idx_number = 3;
9275 int idx_number_2 = 4;
9276 int idx_number_3 = 5;
9277 uint32_t rx_val;
9278 uint32_t tx_val;
9279 uint8_t dm_val;
9280 int ret;
9281 struct pim_interface *pim_ifp = ifp->info;
9282
9283 if (!pim_ifp) {
9284 if (!pim_cmd_interface_add(ifp)) {
9285 vty_out(vty, "Could not enable PIM SM on interface\n");
9286 return CMD_WARNING;
9287 }
9288 }
9289
9290 if ((ret = bfd_validate_param(
9291 vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
9292 argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
9293 != CMD_SUCCESS)
9294 return ret;
9295
9296 pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
9297
9298 return CMD_SUCCESS;
9299 }
9300
9301 #if HAVE_BFDD == 0
9302 ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
9303 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9304 "Enables BFD support\n"
9305 "Detect Multiplier\n"
9306 "Required min receive interval\n"
9307 "Desired min transmit interval\n")
9308 #endif /* !HAVE_BFDD */
9309
9310 static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
9311 const char *peer, const char *local)
9312 {
9313 enum pim_msdp_err result;
9314 struct in_addr peer_addr;
9315 struct in_addr local_addr;
9316 int ret = CMD_SUCCESS;
9317
9318 result = inet_pton(AF_INET, peer, &peer_addr);
9319 if (result <= 0) {
9320 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
9321 errno, safe_strerror(errno));
9322 return CMD_WARNING_CONFIG_FAILED;
9323 }
9324
9325 result = inet_pton(AF_INET, local, &local_addr);
9326 if (result <= 0) {
9327 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
9328 errno, safe_strerror(errno));
9329 return CMD_WARNING_CONFIG_FAILED;
9330 }
9331
9332 result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
9333 NULL /* mp_p */);
9334 switch (result) {
9335 case PIM_MSDP_ERR_NONE:
9336 break;
9337 case PIM_MSDP_ERR_OOM:
9338 ret = CMD_WARNING_CONFIG_FAILED;
9339 vty_out(vty, "%% Out of memory\n");
9340 break;
9341 case PIM_MSDP_ERR_PEER_EXISTS:
9342 ret = CMD_WARNING;
9343 vty_out(vty, "%% Peer exists\n");
9344 break;
9345 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9346 ret = CMD_WARNING_CONFIG_FAILED;
9347 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9348 break;
9349 default:
9350 ret = CMD_WARNING_CONFIG_FAILED;
9351 vty_out(vty, "%% peer add failed\n");
9352 }
9353
9354 return ret;
9355 }
9356
9357 DEFUN_HIDDEN (ip_msdp_peer,
9358 ip_msdp_peer_cmd,
9359 "ip msdp peer A.B.C.D source A.B.C.D",
9360 IP_STR
9361 CFG_MSDP_STR
9362 "Configure MSDP peer\n"
9363 "peer ip address\n"
9364 "Source address for TCP connection\n"
9365 "local ip address\n")
9366 {
9367 PIM_DECLVAR_CONTEXT(vrf, pim);
9368 return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg);
9369 }
9370
9371 static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
9372 const char *peer)
9373 {
9374 enum pim_msdp_err result;
9375 struct in_addr peer_addr;
9376
9377 result = inet_pton(AF_INET, peer, &peer_addr);
9378 if (result <= 0) {
9379 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
9380 errno, safe_strerror(errno));
9381 return CMD_WARNING_CONFIG_FAILED;
9382 }
9383
9384 result = pim_msdp_peer_del(pim, peer_addr);
9385 switch (result) {
9386 case PIM_MSDP_ERR_NONE:
9387 break;
9388 case PIM_MSDP_ERR_NO_PEER:
9389 vty_out(vty, "%% Peer does not exist\n");
9390 break;
9391 default:
9392 vty_out(vty, "%% peer del failed\n");
9393 }
9394
9395 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9396 }
9397
9398 DEFUN_HIDDEN (no_ip_msdp_peer,
9399 no_ip_msdp_peer_cmd,
9400 "no ip msdp peer A.B.C.D",
9401 NO_STR
9402 IP_STR
9403 CFG_MSDP_STR
9404 "Delete MSDP peer\n"
9405 "peer ip address\n")
9406 {
9407 PIM_DECLVAR_CONTEXT(vrf, pim);
9408 return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg);
9409 }
9410
9411 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9412 struct vty *vty, const char *mg,
9413 const char *mbr)
9414 {
9415 enum pim_msdp_err result;
9416 struct in_addr mbr_ip;
9417 int ret = CMD_SUCCESS;
9418
9419 result = inet_pton(AF_INET, mbr, &mbr_ip);
9420 if (result <= 0) {
9421 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9422 errno, safe_strerror(errno));
9423 return CMD_WARNING_CONFIG_FAILED;
9424 }
9425
9426 result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
9427 switch (result) {
9428 case PIM_MSDP_ERR_NONE:
9429 break;
9430 case PIM_MSDP_ERR_OOM:
9431 ret = CMD_WARNING_CONFIG_FAILED;
9432 vty_out(vty, "%% Out of memory\n");
9433 break;
9434 case PIM_MSDP_ERR_MG_MBR_EXISTS:
9435 ret = CMD_WARNING;
9436 vty_out(vty, "%% mesh-group member exists\n");
9437 break;
9438 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9439 ret = CMD_WARNING_CONFIG_FAILED;
9440 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9441 break;
9442 default:
9443 ret = CMD_WARNING_CONFIG_FAILED;
9444 vty_out(vty, "%% member add failed\n");
9445 }
9446
9447 return ret;
9448 }
9449
9450 DEFUN (ip_msdp_mesh_group_member,
9451 ip_msdp_mesh_group_member_cmd,
9452 "ip msdp mesh-group WORD member A.B.C.D",
9453 IP_STR
9454 CFG_MSDP_STR
9455 "Configure MSDP mesh-group\n"
9456 "mesh group name\n"
9457 "mesh group member\n"
9458 "peer ip address\n")
9459 {
9460 PIM_DECLVAR_CONTEXT(vrf, pim);
9461 return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg,
9462 argv[5]->arg);
9463 }
9464
9465 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9466 struct vty *vty,
9467 const char *mg,
9468 const char *mbr)
9469 {
9470 enum pim_msdp_err result;
9471 struct in_addr mbr_ip;
9472
9473 result = inet_pton(AF_INET, mbr, &mbr_ip);
9474 if (result <= 0) {
9475 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9476 errno, safe_strerror(errno));
9477 return CMD_WARNING_CONFIG_FAILED;
9478 }
9479
9480 result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
9481 switch (result) {
9482 case PIM_MSDP_ERR_NONE:
9483 break;
9484 case PIM_MSDP_ERR_NO_MG:
9485 vty_out(vty, "%% mesh-group does not exist\n");
9486 break;
9487 case PIM_MSDP_ERR_NO_MG_MBR:
9488 vty_out(vty, "%% mesh-group member does not exist\n");
9489 break;
9490 default:
9491 vty_out(vty, "%% mesh-group member del failed\n");
9492 }
9493
9494 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9495 }
9496 DEFUN (no_ip_msdp_mesh_group_member,
9497 no_ip_msdp_mesh_group_member_cmd,
9498 "no ip msdp mesh-group WORD member A.B.C.D",
9499 NO_STR
9500 IP_STR
9501 CFG_MSDP_STR
9502 "Delete MSDP mesh-group member\n"
9503 "mesh group name\n"
9504 "mesh group member\n"
9505 "peer ip address\n")
9506 {
9507 PIM_DECLVAR_CONTEXT(vrf, pim);
9508 return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg,
9509 argv[6]->arg);
9510 }
9511
9512 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9513 struct vty *vty, const char *mg,
9514 const char *src)
9515 {
9516 enum pim_msdp_err result;
9517 struct in_addr src_ip;
9518
9519 result = inet_pton(AF_INET, src, &src_ip);
9520 if (result <= 0) {
9521 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
9522 errno, safe_strerror(errno));
9523 return CMD_WARNING_CONFIG_FAILED;
9524 }
9525
9526 result = pim_msdp_mg_src_add(pim, mg, src_ip);
9527 switch (result) {
9528 case PIM_MSDP_ERR_NONE:
9529 break;
9530 case PIM_MSDP_ERR_OOM:
9531 vty_out(vty, "%% Out of memory\n");
9532 break;
9533 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9534 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9535 break;
9536 default:
9537 vty_out(vty, "%% source add failed\n");
9538 }
9539
9540 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9541 }
9542
9543
9544 DEFUN (ip_msdp_mesh_group_source,
9545 ip_msdp_mesh_group_source_cmd,
9546 "ip msdp mesh-group WORD source A.B.C.D",
9547 IP_STR
9548 CFG_MSDP_STR
9549 "Configure MSDP mesh-group\n"
9550 "mesh group name\n"
9551 "mesh group local address\n"
9552 "source ip address for the TCP connection\n")
9553 {
9554 PIM_DECLVAR_CONTEXT(vrf, pim);
9555 return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg,
9556 argv[5]->arg);
9557 }
9558
9559 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9560 struct vty *vty,
9561 const char *mg)
9562 {
9563 enum pim_msdp_err result;
9564
9565 result = pim_msdp_mg_src_del(pim, mg);
9566 switch (result) {
9567 case PIM_MSDP_ERR_NONE:
9568 break;
9569 case PIM_MSDP_ERR_NO_MG:
9570 vty_out(vty, "%% mesh-group does not exist\n");
9571 break;
9572 default:
9573 vty_out(vty, "%% mesh-group source del failed\n");
9574 }
9575
9576 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9577 }
9578
9579 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
9580 struct vty *vty, const char *mg)
9581 {
9582 enum pim_msdp_err result;
9583
9584 result = pim_msdp_mg_del(pim, mg);
9585 switch (result) {
9586 case PIM_MSDP_ERR_NONE:
9587 break;
9588 case PIM_MSDP_ERR_NO_MG:
9589 vty_out(vty, "%% mesh-group does not exist\n");
9590 break;
9591 default:
9592 vty_out(vty, "%% mesh-group source del failed\n");
9593 }
9594
9595 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9596 }
9597
9598 DEFUN (no_ip_msdp_mesh_group_source,
9599 no_ip_msdp_mesh_group_source_cmd,
9600 "no ip msdp mesh-group WORD source [A.B.C.D]",
9601 NO_STR
9602 IP_STR
9603 CFG_MSDP_STR
9604 "Delete MSDP mesh-group source\n"
9605 "mesh group name\n"
9606 "mesh group source\n"
9607 "mesh group local address\n")
9608 {
9609 PIM_DECLVAR_CONTEXT(vrf, pim);
9610 if (argc == 7)
9611 return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[6]->arg);
9612 else
9613 return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty,
9614 argv[4]->arg);
9615 }
9616
9617 static void print_empty_json_obj(struct vty *vty)
9618 {
9619 json_object *json;
9620 json = json_object_new_object();
9621 vty_out(vty, "%s\n",
9622 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
9623 json_object_free(json);
9624 }
9625
9626 static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
9627 bool uj)
9628 {
9629 struct listnode *mbrnode;
9630 struct pim_msdp_mg_mbr *mbr;
9631 struct pim_msdp_mg *mg = pim->msdp.mg;
9632 char mbr_str[INET_ADDRSTRLEN];
9633 char src_str[INET_ADDRSTRLEN];
9634 char state_str[PIM_MSDP_STATE_STRLEN];
9635 enum pim_msdp_peer_state state;
9636 json_object *json = NULL;
9637 json_object *json_mg_row = NULL;
9638 json_object *json_members = NULL;
9639 json_object *json_row = NULL;
9640
9641 if (!mg) {
9642 if (uj)
9643 print_empty_json_obj(vty);
9644 return;
9645 }
9646
9647 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
9648 if (uj) {
9649 json = json_object_new_object();
9650 /* currently there is only one mesh group but we should still
9651 * make
9652 * it a dict with mg-name as key */
9653 json_mg_row = json_object_new_object();
9654 json_object_string_add(json_mg_row, "name",
9655 mg->mesh_group_name);
9656 json_object_string_add(json_mg_row, "source", src_str);
9657 } else {
9658 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
9659 vty_out(vty, " Source : %s\n", src_str);
9660 vty_out(vty, " Member State\n");
9661 }
9662
9663 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
9664 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
9665 if (mbr->mp) {
9666 state = mbr->mp->state;
9667 } else {
9668 state = PIM_MSDP_DISABLED;
9669 }
9670 pim_msdp_state_dump(state, state_str, sizeof(state_str));
9671 if (uj) {
9672 json_row = json_object_new_object();
9673 json_object_string_add(json_row, "member", mbr_str);
9674 json_object_string_add(json_row, "state", state_str);
9675 if (!json_members) {
9676 json_members = json_object_new_object();
9677 json_object_object_add(json_mg_row, "members",
9678 json_members);
9679 }
9680 json_object_object_add(json_members, mbr_str, json_row);
9681 } else {
9682 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
9683 }
9684 }
9685
9686 if (uj) {
9687 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
9688 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9689 json, JSON_C_TO_STRING_PRETTY));
9690 json_object_free(json);
9691 }
9692 }
9693
9694 DEFUN (show_ip_msdp_mesh_group,
9695 show_ip_msdp_mesh_group_cmd,
9696 "show ip msdp [vrf NAME] mesh-group [json]",
9697 SHOW_STR
9698 IP_STR
9699 MSDP_STR
9700 VRF_CMD_HELP_STR
9701 "MSDP mesh-group information\n"
9702 JSON_STR)
9703 {
9704 bool uj = use_json(argc, argv);
9705 int idx = 2;
9706 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9707
9708 if (!vrf)
9709 return CMD_WARNING;
9710
9711 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9712
9713 return CMD_SUCCESS;
9714 }
9715
9716 DEFUN (show_ip_msdp_mesh_group_vrf_all,
9717 show_ip_msdp_mesh_group_vrf_all_cmd,
9718 "show ip msdp vrf all mesh-group [json]",
9719 SHOW_STR
9720 IP_STR
9721 MSDP_STR
9722 VRF_CMD_HELP_STR
9723 "MSDP mesh-group information\n"
9724 JSON_STR)
9725 {
9726 bool uj = use_json(argc, argv);
9727 struct vrf *vrf;
9728 bool first = true;
9729
9730 if (uj)
9731 vty_out(vty, "{ ");
9732 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9733 if (uj) {
9734 if (!first)
9735 vty_out(vty, ", ");
9736 vty_out(vty, " \"%s\": ", vrf->name);
9737 first = false;
9738 } else
9739 vty_out(vty, "VRF: %s\n", vrf->name);
9740 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9741 }
9742 if (uj)
9743 vty_out(vty, "}\n");
9744
9745 return CMD_SUCCESS;
9746 }
9747
9748 static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
9749 bool uj)
9750 {
9751 struct listnode *mpnode;
9752 struct pim_msdp_peer *mp;
9753 char peer_str[INET_ADDRSTRLEN];
9754 char local_str[INET_ADDRSTRLEN];
9755 char state_str[PIM_MSDP_STATE_STRLEN];
9756 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9757 int64_t now;
9758 json_object *json = NULL;
9759 json_object *json_row = NULL;
9760
9761
9762 if (uj) {
9763 json = json_object_new_object();
9764 } else {
9765 vty_out(vty,
9766 "Peer Local State Uptime SaCnt\n");
9767 }
9768
9769 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
9770 if (mp->state == PIM_MSDP_ESTABLISHED) {
9771 now = pim_time_monotonic_sec();
9772 pim_time_uptime(timebuf, sizeof(timebuf),
9773 now - mp->uptime);
9774 } else {
9775 strlcpy(timebuf, "-", sizeof(timebuf));
9776 }
9777 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9778 pim_inet4_dump("<local?>", mp->local, local_str,
9779 sizeof(local_str));
9780 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9781 if (uj) {
9782 json_row = json_object_new_object();
9783 json_object_string_add(json_row, "peer", peer_str);
9784 json_object_string_add(json_row, "local", local_str);
9785 json_object_string_add(json_row, "state", state_str);
9786 json_object_string_add(json_row, "upTime", timebuf);
9787 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9788 json_object_object_add(json, peer_str, json_row);
9789 } else {
9790 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
9791 local_str, state_str, timebuf, mp->sa_cnt);
9792 }
9793 }
9794
9795 if (uj) {
9796 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9797 json, JSON_C_TO_STRING_PRETTY));
9798 json_object_free(json);
9799 }
9800 }
9801
9802 static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
9803 const char *peer, bool uj)
9804 {
9805 struct listnode *mpnode;
9806 struct pim_msdp_peer *mp;
9807 char peer_str[INET_ADDRSTRLEN];
9808 char local_str[INET_ADDRSTRLEN];
9809 char state_str[PIM_MSDP_STATE_STRLEN];
9810 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9811 char katimer[PIM_MSDP_TIMER_STRLEN];
9812 char crtimer[PIM_MSDP_TIMER_STRLEN];
9813 char holdtimer[PIM_MSDP_TIMER_STRLEN];
9814 int64_t now;
9815 json_object *json = NULL;
9816 json_object *json_row = NULL;
9817
9818 if (uj) {
9819 json = json_object_new_object();
9820 }
9821
9822 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
9823 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9824 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
9825 continue;
9826
9827 if (mp->state == PIM_MSDP_ESTABLISHED) {
9828 now = pim_time_monotonic_sec();
9829 pim_time_uptime(timebuf, sizeof(timebuf),
9830 now - mp->uptime);
9831 } else {
9832 strlcpy(timebuf, "-", sizeof(timebuf));
9833 }
9834 pim_inet4_dump("<local?>", mp->local, local_str,
9835 sizeof(local_str));
9836 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9837 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
9838 mp->ka_timer);
9839 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
9840 mp->cr_timer);
9841 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
9842 mp->hold_timer);
9843
9844 if (uj) {
9845 json_row = json_object_new_object();
9846 json_object_string_add(json_row, "peer", peer_str);
9847 json_object_string_add(json_row, "local", local_str);
9848 json_object_string_add(json_row, "meshGroupName",
9849 mp->mesh_group_name);
9850 json_object_string_add(json_row, "state", state_str);
9851 json_object_string_add(json_row, "upTime", timebuf);
9852 json_object_string_add(json_row, "keepAliveTimer",
9853 katimer);
9854 json_object_string_add(json_row, "connRetryTimer",
9855 crtimer);
9856 json_object_string_add(json_row, "holdTimer",
9857 holdtimer);
9858 json_object_string_add(json_row, "lastReset",
9859 mp->last_reset);
9860 json_object_int_add(json_row, "connAttempts",
9861 mp->conn_attempts);
9862 json_object_int_add(json_row, "establishedChanges",
9863 mp->est_flaps);
9864 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9865 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
9866 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
9867 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
9868 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
9869 json_object_object_add(json, peer_str, json_row);
9870 } else {
9871 vty_out(vty, "Peer : %s\n", peer_str);
9872 vty_out(vty, " Local : %s\n", local_str);
9873 vty_out(vty, " Mesh Group : %s\n",
9874 mp->mesh_group_name);
9875 vty_out(vty, " State : %s\n", state_str);
9876 vty_out(vty, " Uptime : %s\n", timebuf);
9877
9878 vty_out(vty, " Keepalive Timer : %s\n", katimer);
9879 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
9880 vty_out(vty, " Hold Timer : %s\n", holdtimer);
9881 vty_out(vty, " Last Reset : %s\n",
9882 mp->last_reset);
9883 vty_out(vty, " Conn Attempts : %d\n",
9884 mp->conn_attempts);
9885 vty_out(vty, " Established Changes : %d\n",
9886 mp->est_flaps);
9887 vty_out(vty, " SA Count : %d\n",
9888 mp->sa_cnt);
9889 vty_out(vty, " Statistics :\n");
9890 vty_out(vty,
9891 " Sent Rcvd\n");
9892 vty_out(vty, " Keepalives : %10d %10d\n",
9893 mp->ka_tx_cnt, mp->ka_rx_cnt);
9894 vty_out(vty, " SAs : %10d %10d\n",
9895 mp->sa_tx_cnt, mp->sa_rx_cnt);
9896 vty_out(vty, "\n");
9897 }
9898 }
9899
9900 if (uj) {
9901 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9902 json, JSON_C_TO_STRING_PRETTY));
9903 json_object_free(json);
9904 }
9905 }
9906
9907 DEFUN (show_ip_msdp_peer_detail,
9908 show_ip_msdp_peer_detail_cmd,
9909 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9910 SHOW_STR
9911 IP_STR
9912 MSDP_STR
9913 VRF_CMD_HELP_STR
9914 "MSDP peer information\n"
9915 "Detailed output\n"
9916 "peer ip address\n"
9917 JSON_STR)
9918 {
9919 bool uj = use_json(argc, argv);
9920 int idx = 2;
9921 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9922
9923 if (!vrf)
9924 return CMD_WARNING;
9925
9926 char *arg = NULL;
9927
9928 if (argv_find(argv, argc, "detail", &idx))
9929 arg = argv[idx]->text;
9930 else if (argv_find(argv, argc, "A.B.C.D", &idx))
9931 arg = argv[idx]->arg;
9932
9933 if (arg)
9934 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
9935 else
9936 ip_msdp_show_peers(vrf->info, vty, uj);
9937
9938 return CMD_SUCCESS;
9939 }
9940
9941 DEFUN (show_ip_msdp_peer_detail_vrf_all,
9942 show_ip_msdp_peer_detail_vrf_all_cmd,
9943 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9944 SHOW_STR
9945 IP_STR
9946 MSDP_STR
9947 VRF_CMD_HELP_STR
9948 "MSDP peer information\n"
9949 "Detailed output\n"
9950 "peer ip address\n"
9951 JSON_STR)
9952 {
9953 int idx = 2;
9954 bool uj = use_json(argc, argv);
9955 struct vrf *vrf;
9956 bool first = true;
9957
9958 if (uj)
9959 vty_out(vty, "{ ");
9960 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9961 if (uj) {
9962 if (!first)
9963 vty_out(vty, ", ");
9964 vty_out(vty, " \"%s\": ", vrf->name);
9965 first = false;
9966 } else
9967 vty_out(vty, "VRF: %s\n", vrf->name);
9968 if (argv_find(argv, argc, "detail", &idx)
9969 || argv_find(argv, argc, "A.B.C.D", &idx))
9970 ip_msdp_show_peers_detail(vrf->info, vty,
9971 argv[idx]->arg, uj);
9972 else
9973 ip_msdp_show_peers(vrf->info, vty, uj);
9974 }
9975 if (uj)
9976 vty_out(vty, "}\n");
9977
9978 return CMD_SUCCESS;
9979 }
9980
9981 static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
9982 {
9983 struct listnode *sanode;
9984 struct pim_msdp_sa *sa;
9985 char src_str[INET_ADDRSTRLEN];
9986 char grp_str[INET_ADDRSTRLEN];
9987 char rp_str[INET_ADDRSTRLEN];
9988 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9989 char spt_str[8];
9990 char local_str[8];
9991 int64_t now;
9992 json_object *json = NULL;
9993 json_object *json_group = NULL;
9994 json_object *json_row = NULL;
9995
9996 if (uj) {
9997 json = json_object_new_object();
9998 } else {
9999 vty_out(vty,
10000 "Source Group RP Local SPT Uptime\n");
10001 }
10002
10003 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
10004 now = pim_time_monotonic_sec();
10005 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
10006 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
10007 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
10008 if (sa->flags & PIM_MSDP_SAF_PEER) {
10009 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
10010 if (sa->up) {
10011 strlcpy(spt_str, "yes", sizeof(spt_str));
10012 } else {
10013 strlcpy(spt_str, "no", sizeof(spt_str));
10014 }
10015 } else {
10016 strlcpy(rp_str, "-", sizeof(rp_str));
10017 strlcpy(spt_str, "-", sizeof(spt_str));
10018 }
10019 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
10020 strlcpy(local_str, "yes", sizeof(local_str));
10021 } else {
10022 strlcpy(local_str, "no", sizeof(local_str));
10023 }
10024 if (uj) {
10025 json_object_object_get_ex(json, grp_str, &json_group);
10026
10027 if (!json_group) {
10028 json_group = json_object_new_object();
10029 json_object_object_add(json, grp_str,
10030 json_group);
10031 }
10032
10033 json_row = json_object_new_object();
10034 json_object_string_add(json_row, "source", src_str);
10035 json_object_string_add(json_row, "group", grp_str);
10036 json_object_string_add(json_row, "rp", rp_str);
10037 json_object_string_add(json_row, "local", local_str);
10038 json_object_string_add(json_row, "sptSetup", spt_str);
10039 json_object_string_add(json_row, "upTime", timebuf);
10040 json_object_object_add(json_group, src_str, json_row);
10041 } else {
10042 vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
10043 src_str, grp_str, rp_str, local_str[0],
10044 spt_str[0], timebuf);
10045 }
10046 }
10047
10048 if (uj) {
10049 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10050 json, JSON_C_TO_STRING_PRETTY));
10051 json_object_free(json);
10052 }
10053 }
10054
10055 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
10056 const char *src_str,
10057 const char *grp_str, struct vty *vty,
10058 bool uj, json_object *json)
10059 {
10060 char rp_str[INET_ADDRSTRLEN];
10061 char peer_str[INET_ADDRSTRLEN];
10062 char timebuf[PIM_MSDP_UPTIME_STRLEN];
10063 char spt_str[8];
10064 char local_str[8];
10065 char statetimer[PIM_MSDP_TIMER_STRLEN];
10066 int64_t now;
10067 json_object *json_group = NULL;
10068 json_object *json_row = NULL;
10069
10070 now = pim_time_monotonic_sec();
10071 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
10072 if (sa->flags & PIM_MSDP_SAF_PEER) {
10073 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
10074 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
10075 if (sa->up) {
10076 strlcpy(spt_str, "yes", sizeof(spt_str));
10077 } else {
10078 strlcpy(spt_str, "no", sizeof(spt_str));
10079 }
10080 } else {
10081 strlcpy(rp_str, "-", sizeof(rp_str));
10082 strlcpy(peer_str, "-", sizeof(peer_str));
10083 strlcpy(spt_str, "-", sizeof(spt_str));
10084 }
10085 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
10086 strlcpy(local_str, "yes", sizeof(local_str));
10087 } else {
10088 strlcpy(local_str, "no", sizeof(local_str));
10089 }
10090 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
10091 sa->sa_state_timer);
10092 if (uj) {
10093 json_object_object_get_ex(json, grp_str, &json_group);
10094
10095 if (!json_group) {
10096 json_group = json_object_new_object();
10097 json_object_object_add(json, grp_str, json_group);
10098 }
10099
10100 json_row = json_object_new_object();
10101 json_object_string_add(json_row, "source", src_str);
10102 json_object_string_add(json_row, "group", grp_str);
10103 json_object_string_add(json_row, "rp", rp_str);
10104 json_object_string_add(json_row, "local", local_str);
10105 json_object_string_add(json_row, "sptSetup", spt_str);
10106 json_object_string_add(json_row, "upTime", timebuf);
10107 json_object_string_add(json_row, "stateTimer", statetimer);
10108 json_object_object_add(json_group, src_str, json_row);
10109 } else {
10110 vty_out(vty, "SA : %s\n", sa->sg_str);
10111 vty_out(vty, " RP : %s\n", rp_str);
10112 vty_out(vty, " Peer : %s\n", peer_str);
10113 vty_out(vty, " Local : %s\n", local_str);
10114 vty_out(vty, " SPT Setup : %s\n", spt_str);
10115 vty_out(vty, " Uptime : %s\n", timebuf);
10116 vty_out(vty, " State Timer : %s\n", statetimer);
10117 vty_out(vty, "\n");
10118 }
10119 }
10120
10121 static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
10122 bool uj)
10123 {
10124 struct listnode *sanode;
10125 struct pim_msdp_sa *sa;
10126 char src_str[INET_ADDRSTRLEN];
10127 char grp_str[INET_ADDRSTRLEN];
10128 json_object *json = NULL;
10129
10130 if (uj) {
10131 json = json_object_new_object();
10132 }
10133
10134 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
10135 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
10136 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
10137 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
10138 json);
10139 }
10140
10141 if (uj) {
10142 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10143 json, JSON_C_TO_STRING_PRETTY));
10144 json_object_free(json);
10145 }
10146 }
10147
10148 DEFUN (show_ip_msdp_sa_detail,
10149 show_ip_msdp_sa_detail_cmd,
10150 "show ip msdp [vrf NAME] sa detail [json]",
10151 SHOW_STR
10152 IP_STR
10153 MSDP_STR
10154 VRF_CMD_HELP_STR
10155 "MSDP active-source information\n"
10156 "Detailed output\n"
10157 JSON_STR)
10158 {
10159 bool uj = use_json(argc, argv);
10160 int idx = 2;
10161 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10162
10163 if (!vrf)
10164 return CMD_WARNING;
10165
10166 ip_msdp_show_sa_detail(vrf->info, vty, uj);
10167
10168 return CMD_SUCCESS;
10169 }
10170
10171 DEFUN (show_ip_msdp_sa_detail_vrf_all,
10172 show_ip_msdp_sa_detail_vrf_all_cmd,
10173 "show ip msdp vrf all sa detail [json]",
10174 SHOW_STR
10175 IP_STR
10176 MSDP_STR
10177 VRF_CMD_HELP_STR
10178 "MSDP active-source information\n"
10179 "Detailed output\n"
10180 JSON_STR)
10181 {
10182 bool uj = use_json(argc, argv);
10183 struct vrf *vrf;
10184 bool first = true;
10185
10186 if (uj)
10187 vty_out(vty, "{ ");
10188 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
10189 if (uj) {
10190 if (!first)
10191 vty_out(vty, ", ");
10192 vty_out(vty, " \"%s\": ", vrf->name);
10193 first = false;
10194 } else
10195 vty_out(vty, "VRF: %s\n", vrf->name);
10196 ip_msdp_show_sa_detail(vrf->info, vty, uj);
10197 }
10198 if (uj)
10199 vty_out(vty, "}\n");
10200
10201 return CMD_SUCCESS;
10202 }
10203
10204 static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
10205 const char *addr, bool uj)
10206 {
10207 struct listnode *sanode;
10208 struct pim_msdp_sa *sa;
10209 char src_str[INET_ADDRSTRLEN];
10210 char grp_str[INET_ADDRSTRLEN];
10211 json_object *json = NULL;
10212
10213 if (uj) {
10214 json = json_object_new_object();
10215 }
10216
10217 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
10218 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
10219 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
10220 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
10221 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
10222 uj, json);
10223 }
10224 }
10225
10226 if (uj) {
10227 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10228 json, JSON_C_TO_STRING_PRETTY));
10229 json_object_free(json);
10230 }
10231 }
10232
10233 static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
10234 const char *src, const char *grp, bool uj)
10235 {
10236 struct listnode *sanode;
10237 struct pim_msdp_sa *sa;
10238 char src_str[INET_ADDRSTRLEN];
10239 char grp_str[INET_ADDRSTRLEN];
10240 json_object *json = NULL;
10241
10242 if (uj) {
10243 json = json_object_new_object();
10244 }
10245
10246 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
10247 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
10248 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
10249 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
10250 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
10251 uj, json);
10252 }
10253 }
10254
10255 if (uj) {
10256 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10257 json, JSON_C_TO_STRING_PRETTY));
10258 json_object_free(json);
10259 }
10260 }
10261
10262 DEFUN (show_ip_msdp_sa_sg,
10263 show_ip_msdp_sa_sg_cmd,
10264 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
10265 SHOW_STR
10266 IP_STR
10267 MSDP_STR
10268 VRF_CMD_HELP_STR
10269 "MSDP active-source information\n"
10270 "source or group ip\n"
10271 "group ip\n"
10272 JSON_STR)
10273 {
10274 bool uj = use_json(argc, argv);
10275 struct vrf *vrf;
10276 int idx = 2;
10277
10278 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10279
10280 if (!vrf)
10281 return CMD_WARNING;
10282
10283 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
10284 : NULL;
10285 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
10286 ? argv[idx]->arg
10287 : NULL;
10288
10289 if (src_ip && grp_ip)
10290 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
10291 else if (src_ip)
10292 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
10293 else
10294 ip_msdp_show_sa(vrf->info, vty, uj);
10295
10296 return CMD_SUCCESS;
10297 }
10298
10299 DEFUN (show_ip_msdp_sa_sg_vrf_all,
10300 show_ip_msdp_sa_sg_vrf_all_cmd,
10301 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10302 SHOW_STR
10303 IP_STR
10304 MSDP_STR
10305 VRF_CMD_HELP_STR
10306 "MSDP active-source information\n"
10307 "source or group ip\n"
10308 "group ip\n"
10309 JSON_STR)
10310 {
10311 bool uj = use_json(argc, argv);
10312 struct vrf *vrf;
10313 bool first = true;
10314 int idx = 2;
10315
10316 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
10317 : NULL;
10318 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
10319 ? argv[idx]->arg
10320 : NULL;
10321
10322 if (uj)
10323 vty_out(vty, "{ ");
10324 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
10325 if (uj) {
10326 if (!first)
10327 vty_out(vty, ", ");
10328 vty_out(vty, " \"%s\": ", vrf->name);
10329 first = false;
10330 } else
10331 vty_out(vty, "VRF: %s\n", vrf->name);
10332
10333 if (src_ip && grp_ip)
10334 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
10335 else if (src_ip)
10336 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
10337 else
10338 ip_msdp_show_sa(vrf->info, vty, uj);
10339 }
10340 if (uj)
10341 vty_out(vty, "}\n");
10342
10343 return CMD_SUCCESS;
10344 }
10345
10346 struct pim_sg_cache_walk_data {
10347 struct vty *vty;
10348 json_object *json;
10349 json_object *json_group;
10350 struct in_addr addr;
10351 bool addr_match;
10352 };
10353
10354 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
10355 struct pim_sg_cache_walk_data *cwd)
10356 {
10357 struct vty *vty = cwd->vty;
10358 json_object *json = cwd->json;
10359 char src_str[INET_ADDRSTRLEN];
10360 char grp_str[INET_ADDRSTRLEN];
10361 json_object *json_row;
10362 bool installed = (vxlan_sg->up) ? true : false;
10363 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10364 const char *oif_name;
10365
10366 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10367 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10368 else
10369 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10370
10371 if (cwd->addr_match && (vxlan_sg->sg.src.s_addr != cwd->addr.s_addr) &&
10372 (vxlan_sg->sg.grp.s_addr != cwd->addr.s_addr)) {
10373 return;
10374 }
10375 pim_inet4_dump("<src?>", vxlan_sg->sg.src, src_str, sizeof(src_str));
10376 pim_inet4_dump("<grp?>", vxlan_sg->sg.grp, grp_str, sizeof(grp_str));
10377 if (json) {
10378 json_object_object_get_ex(json, grp_str, &cwd->json_group);
10379
10380 if (!cwd->json_group) {
10381 cwd->json_group = json_object_new_object();
10382 json_object_object_add(json, grp_str,
10383 cwd->json_group);
10384 }
10385
10386 json_row = json_object_new_object();
10387 json_object_string_add(json_row, "source", src_str);
10388 json_object_string_add(json_row, "group", grp_str);
10389 json_object_string_add(json_row, "input", iif_name);
10390 json_object_string_add(json_row, "output", oif_name);
10391 if (installed)
10392 json_object_boolean_true_add(json_row, "installed");
10393 else
10394 json_object_boolean_false_add(json_row, "installed");
10395 json_object_object_add(cwd->json_group, src_str, json_row);
10396 } else {
10397 vty_out(vty, "%-15s %-15s %-15s %-15s %-5s\n",
10398 src_str, grp_str, iif_name, oif_name,
10399 installed?"I":"");
10400 }
10401 }
10402
10403 static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *backet, void *arg)
10404 {
10405 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)backet->data,
10406 (struct pim_sg_cache_walk_data *)arg);
10407 }
10408
10409 static void pim_show_vxlan_sg(struct pim_instance *pim,
10410 struct vty *vty, bool uj)
10411 {
10412 json_object *json = NULL;
10413 struct pim_sg_cache_walk_data cwd;
10414
10415 if (uj) {
10416 json = json_object_new_object();
10417 } else {
10418 vty_out(vty, "Codes: I -> installed\n");
10419 vty_out(vty,
10420 "Source Group Input Output Flags\n");
10421 }
10422
10423 memset(&cwd, 0, sizeof(cwd));
10424 cwd.vty = vty;
10425 cwd.json = json;
10426 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10427
10428 if (uj) {
10429 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10430 json, JSON_C_TO_STRING_PRETTY));
10431 json_object_free(json);
10432 }
10433 }
10434
10435 static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
10436 struct vty *vty, char *addr_str, bool uj)
10437 {
10438 json_object *json = NULL;
10439 struct pim_sg_cache_walk_data cwd;
10440 int result = 0;
10441
10442 memset(&cwd, 0, sizeof(cwd));
10443 result = inet_pton(AF_INET, addr_str, &cwd.addr);
10444 if (result <= 0) {
10445 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
10446 errno, safe_strerror(errno));
10447 return;
10448 }
10449
10450 if (uj) {
10451 json = json_object_new_object();
10452 } else {
10453 vty_out(vty, "Codes: I -> installed\n");
10454 vty_out(vty,
10455 "Source Group Input Output Flags\n");
10456 }
10457
10458 cwd.vty = vty;
10459 cwd.json = json;
10460 cwd.addr_match = true;
10461 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10462
10463 if (uj) {
10464 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10465 json, JSON_C_TO_STRING_PRETTY));
10466 json_object_free(json);
10467 }
10468 }
10469
10470 static void pim_show_vxlan_sg_one(struct pim_instance *pim,
10471 struct vty *vty, char *src_str, char *grp_str, bool uj)
10472 {
10473 json_object *json = NULL;
10474 struct prefix_sg sg;
10475 int result = 0;
10476 struct pim_vxlan_sg *vxlan_sg;
10477 const char *iif_name;
10478 bool installed;
10479 const char *oif_name;
10480
10481 result = inet_pton(AF_INET, src_str, &sg.src);
10482 if (result <= 0) {
10483 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
10484 errno, safe_strerror(errno));
10485 return;
10486 }
10487 result = inet_pton(AF_INET, grp_str, &sg.grp);
10488 if (result <= 0) {
10489 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
10490 errno, safe_strerror(errno));
10491 return;
10492 }
10493
10494 sg.family = AF_INET;
10495 sg.prefixlen = IPV4_MAX_BITLEN;
10496 if (uj)
10497 json = json_object_new_object();
10498
10499 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
10500 if (vxlan_sg) {
10501 installed = (vxlan_sg->up) ? true : false;
10502 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10503
10504 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10505 oif_name =
10506 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10507 else
10508 oif_name =
10509 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10510
10511 if (uj) {
10512 json_object_string_add(json, "source", src_str);
10513 json_object_string_add(json, "group", grp_str);
10514 json_object_string_add(json, "input", iif_name);
10515 json_object_string_add(json, "output", oif_name);
10516 if (installed)
10517 json_object_boolean_true_add(json, "installed");
10518 else
10519 json_object_boolean_false_add(json,
10520 "installed");
10521 } else {
10522 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
10523 vty_out(vty, " Input : %s\n", iif_name);
10524 vty_out(vty, " Output : %s\n", oif_name);
10525 vty_out(vty, " installed : %s\n",
10526 installed?"yes":"no");
10527 }
10528 }
10529
10530 if (uj) {
10531 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10532 json, JSON_C_TO_STRING_PRETTY));
10533 json_object_free(json);
10534 }
10535 }
10536
10537 DEFUN (show_ip_pim_vxlan_sg,
10538 show_ip_pim_vxlan_sg_cmd,
10539 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10540 SHOW_STR
10541 IP_STR
10542 PIM_STR
10543 VRF_CMD_HELP_STR
10544 "VxLAN BUM groups\n"
10545 "source or group ip\n"
10546 "group ip\n"
10547 JSON_STR)
10548 {
10549 bool uj = use_json(argc, argv);
10550 struct vrf *vrf;
10551 int idx = 2;
10552
10553 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10554
10555 if (!vrf)
10556 return CMD_WARNING;
10557
10558 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
10559 argv[idx++]->arg:NULL;
10560 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
10561 argv[idx]->arg:NULL;
10562
10563 if (src_ip && grp_ip)
10564 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
10565 else if (src_ip)
10566 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
10567 else
10568 pim_show_vxlan_sg(vrf->info, vty, uj);
10569
10570 return CMD_SUCCESS;
10571 }
10572
10573 static void pim_show_vxlan_sg_work(struct pim_instance *pim,
10574 struct vty *vty, bool uj)
10575 {
10576 json_object *json = NULL;
10577 struct pim_sg_cache_walk_data cwd;
10578 struct listnode *node;
10579 struct pim_vxlan_sg *vxlan_sg;
10580
10581 if (uj) {
10582 json = json_object_new_object();
10583 } else {
10584 vty_out(vty, "Codes: I -> installed\n");
10585 vty_out(vty,
10586 "Source Group Input Flags\n");
10587 }
10588
10589 memset(&cwd, 0, sizeof(cwd));
10590 cwd.vty = vty;
10591 cwd.json = json;
10592 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
10593 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
10594
10595 if (uj) {
10596 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10597 json, JSON_C_TO_STRING_PRETTY));
10598 json_object_free(json);
10599 }
10600 }
10601
10602 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
10603 show_ip_pim_vxlan_sg_work_cmd,
10604 "show ip pim [vrf NAME] vxlan-work [json]",
10605 SHOW_STR
10606 IP_STR
10607 PIM_STR
10608 VRF_CMD_HELP_STR
10609 "VxLAN work list\n"
10610 JSON_STR)
10611 {
10612 bool uj = use_json(argc, argv);
10613 struct vrf *vrf;
10614 int idx = 2;
10615
10616 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10617
10618 if (!vrf)
10619 return CMD_WARNING;
10620
10621 pim_show_vxlan_sg_work(vrf->info, vty, uj);
10622
10623 return CMD_SUCCESS;
10624 }
10625
10626 DEFUN_HIDDEN (no_ip_pim_mlag,
10627 no_ip_pim_mlag_cmd,
10628 "no ip pim mlag",
10629 NO_STR
10630 IP_STR
10631 PIM_STR
10632 "MLAG\n")
10633 {
10634 struct in_addr addr;
10635
10636 addr.s_addr = 0;
10637 pim_vxlan_mlag_update(true/*mlag_enable*/,
10638 false/*peer_state*/, MLAG_ROLE_NONE,
10639 NULL/*peerlink*/, &addr);
10640
10641 return CMD_SUCCESS;
10642 }
10643
10644 DEFUN_HIDDEN (ip_pim_mlag,
10645 ip_pim_mlag_cmd,
10646 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10647 IP_STR
10648 PIM_STR
10649 "MLAG\n"
10650 "peerlink sub interface\n"
10651 "MLAG role\n"
10652 "MLAG role primary\n"
10653 "MLAG role secondary\n"
10654 "peer session state\n"
10655 "peer session state up\n"
10656 "peer session state down\n"
10657 "configure PIP\n"
10658 "unique ip address\n")
10659 {
10660 struct interface *ifp;
10661 const char *peerlink;
10662 uint32_t role;
10663 int idx;
10664 bool peer_state;
10665 int result;
10666 struct in_addr reg_addr;
10667
10668 idx = 3;
10669 peerlink = argv[idx]->arg;
10670 ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
10671 if (!ifp) {
10672 vty_out(vty, "No such interface name %s\n", peerlink);
10673 return CMD_WARNING;
10674 }
10675
10676 idx += 2;
10677 if (!strcmp(argv[idx]->arg, "primary")) {
10678 role = MLAG_ROLE_PRIMARY;
10679 } else if (!strcmp(argv[idx]->arg, "secondary")) {
10680 role = MLAG_ROLE_SECONDARY;
10681 } else {
10682 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
10683 return CMD_WARNING;
10684 }
10685
10686 idx += 2;
10687 if (!strcmp(argv[idx]->arg, "up")) {
10688 peer_state = true;
10689 } else if (strcmp(argv[idx]->arg, "down")) {
10690 peer_state = false;
10691 } else {
10692 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
10693 return CMD_WARNING;
10694 }
10695
10696 idx += 2;
10697 result = inet_pton(AF_INET, argv[idx]->arg, &reg_addr);
10698 if (result <= 0) {
10699 vty_out(vty, "%% Bad reg address %s: errno=%d: %s\n",
10700 argv[idx]->arg,
10701 errno, safe_strerror(errno));
10702 return CMD_WARNING_CONFIG_FAILED;
10703 }
10704 pim_vxlan_mlag_update(true, peer_state, role, ifp, &reg_addr);
10705
10706 return CMD_SUCCESS;
10707 }
10708
10709 void pim_cmd_init(void)
10710 {
10711 install_node(&interface_node,
10712 pim_interface_config_write); /* INTERFACE_NODE */
10713 if_cmd_init();
10714
10715 install_node(&debug_node, pim_debug_config_write);
10716
10717 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
10718
10719 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
10720 install_element(VRF_NODE, &ip_pim_rp_cmd);
10721 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
10722 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
10723 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
10724 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
10725 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
10726 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
10727 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
10728 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
10729 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
10730 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
10731 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
10732 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
10733 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
10734 install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
10735 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
10736 install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
10737 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
10738 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
10739 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
10740 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
10741 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
10742 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
10743 install_element(CONFIG_NODE,
10744 &no_ip_pim_spt_switchover_infinity_plist_cmd);
10745 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
10746 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
10747 install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
10748 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
10749 install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
10750 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
10751 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
10752 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
10753 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
10754 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
10755 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
10756 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
10757 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
10758 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
10759 install_element(VRF_NODE, &ip_pim_packets_cmd);
10760 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
10761 install_element(VRF_NODE, &no_ip_pim_packets_cmd);
10762 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
10763 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
10764 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
10765 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
10766 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
10767 install_element(VRF_NODE, &ip_ssmpingd_cmd);
10768 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
10769 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
10770 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
10771 install_element(VRF_NODE, &ip_msdp_peer_cmd);
10772 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
10773 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
10774 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
10775 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
10776 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
10777 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
10778 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
10779 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
10780 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
10781 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
10782 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
10783 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
10784
10785 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
10786 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
10787 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
10788 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
10789 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
10790 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
10791 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
10792 install_element(INTERFACE_NODE,
10793 &interface_no_ip_igmp_query_interval_cmd);
10794 install_element(INTERFACE_NODE,
10795 &interface_ip_igmp_query_max_response_time_cmd);
10796 install_element(INTERFACE_NODE,
10797 &interface_no_ip_igmp_query_max_response_time_cmd);
10798 install_element(INTERFACE_NODE,
10799 &interface_ip_igmp_query_max_response_time_dsec_cmd);
10800 install_element(INTERFACE_NODE,
10801 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
10802 install_element(INTERFACE_NODE,
10803 &interface_ip_igmp_last_member_query_count_cmd);
10804 install_element(INTERFACE_NODE,
10805 &interface_no_ip_igmp_last_member_query_count_cmd);
10806 install_element(INTERFACE_NODE,
10807 &interface_ip_igmp_last_member_query_interval_cmd);
10808 install_element(INTERFACE_NODE,
10809 &interface_no_ip_igmp_last_member_query_interval_cmd);
10810 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
10811 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
10812 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
10813 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
10814 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
10815 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
10816 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
10817 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
10818 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
10819 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
10820 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
10821 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
10822 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
10823 install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
10824
10825 // Static mroutes NEB
10826 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
10827 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
10828
10829 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
10830 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
10831 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
10832 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
10833 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
10834 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
10835 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
10836 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
10837 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
10838 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
10839 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
10840 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
10841 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
10842 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
10843 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
10844 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
10845 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
10846 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
10847 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
10848 install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
10849 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
10850 install_element(VIEW_NODE, &show_ip_pim_mlag_summary_cmd);
10851 install_element(VIEW_NODE, &show_ip_pim_mlag_up_cmd);
10852 install_element(VIEW_NODE, &show_ip_pim_mlag_up_vrf_all_cmd);
10853 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
10854 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
10855 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
10856 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
10857 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
10858 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
10859 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
10860 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
10861 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
10862 install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
10863 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
10864 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
10865 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
10866 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
10867 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
10868 install_element(VIEW_NODE, &show_ip_multicast_cmd);
10869 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
10870 install_element(VIEW_NODE, &show_ip_mroute_cmd);
10871 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
10872 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
10873 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
10874 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
10875 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
10876 install_element(VIEW_NODE, &show_ip_rib_cmd);
10877 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
10878 install_element(VIEW_NODE, &show_debugging_pim_cmd);
10879 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
10880 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
10881 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
10882 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
10883 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
10884
10885 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
10886 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
10887 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
10888 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
10889 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
10890 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
10891 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
10892 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
10893
10894 install_element(ENABLE_NODE, &debug_igmp_cmd);
10895 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
10896 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
10897 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
10898 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
10899 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
10900 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
10901 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
10902 install_element(ENABLE_NODE, &debug_mroute_cmd);
10903 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
10904 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
10905 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
10906 install_element(ENABLE_NODE, &debug_pim_static_cmd);
10907 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
10908 install_element(ENABLE_NODE, &debug_pim_cmd);
10909 install_element(ENABLE_NODE, &no_debug_pim_cmd);
10910 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
10911 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
10912 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
10913 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
10914 install_element(ENABLE_NODE, &debug_pim_events_cmd);
10915 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
10916 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
10917 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
10918 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
10919 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
10920 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
10921 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
10922 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
10923 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
10924 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
10925 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
10926 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
10927 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
10928 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
10929 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
10930 install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
10931 install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
10932 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
10933 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
10934 install_element(ENABLE_NODE, &debug_msdp_cmd);
10935 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
10936 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
10937 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
10938 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
10939 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
10940 install_element(ENABLE_NODE, &debug_mtrace_cmd);
10941 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
10942 install_element(ENABLE_NODE, &debug_bsm_cmd);
10943 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
10944
10945 install_element(CONFIG_NODE, &debug_igmp_cmd);
10946 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
10947 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
10948 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
10949 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
10950 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
10951 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
10952 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
10953 install_element(CONFIG_NODE, &debug_mroute_cmd);
10954 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
10955 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
10956 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
10957 install_element(CONFIG_NODE, &debug_pim_static_cmd);
10958 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
10959 install_element(CONFIG_NODE, &debug_pim_cmd);
10960 install_element(CONFIG_NODE, &no_debug_pim_cmd);
10961 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
10962 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
10963 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
10964 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
10965 install_element(CONFIG_NODE, &debug_pim_events_cmd);
10966 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
10967 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
10968 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
10969 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
10970 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
10971 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
10972 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
10973 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
10974 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
10975 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
10976 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
10977 install_element(CONFIG_NODE, &debug_pim_mlag_cmd);
10978 install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd);
10979 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
10980 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
10981 install_element(CONFIG_NODE, &debug_msdp_cmd);
10982 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
10983 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
10984 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
10985 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
10986 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
10987 install_element(CONFIG_NODE, &debug_mtrace_cmd);
10988 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
10989 install_element(CONFIG_NODE, &debug_bsm_cmd);
10990 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
10991
10992 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
10993 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
10994 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
10995 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
10996 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
10997 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
10998 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
10999 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
11000 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
11001 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
11002 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
11003 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
11004 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
11005 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
11006 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
11007 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
11008 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
11009 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
11010 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
11011 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
11012 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
11013 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
11014 /* Install BSM command */
11015 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
11016 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
11017 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
11018 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
11019 /* Install BFD command */
11020 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
11021 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
11022 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
11023 #if HAVE_BFDD == 0
11024 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
11025 #endif /* !HAVE_BFDD */
11026 }