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