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