]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_cmd.c
Merge pull request #5498 from mjstapp/sharp_with_labels
[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, M -> Muted");
1993 vty_out(vty,
1994 "\nActive Source Group RPT 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 bool isRpt;
2005 first_oif = 1;
2006
2007 if ((c_oil->up &&
2008 PIM_UPSTREAM_FLAG_TEST_USE_RPT(c_oil->up->flags)) ||
2009 c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
2010 isRpt = true;
2011 else
2012 isRpt = false;
2013
2014 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
2015 sizeof(grp_str));
2016 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
2017 sizeof(src_str));
2018 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
2019
2020 if (ifp_in)
2021 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
2022 else
2023 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
2024
2025 if (src_or_group) {
2026 if (strcmp(src_or_group, src_str)
2027 && strcmp(src_or_group, grp_str))
2028 continue;
2029
2030 if (group && strcmp(group, grp_str))
2031 continue;
2032 }
2033
2034 if (uj) {
2035
2036 /* Find the group, create it if it doesn't exist */
2037 json_object_object_get_ex(json, grp_str, &json_group);
2038
2039 if (!json_group) {
2040 json_group = json_object_new_object();
2041 json_object_object_add(json, grp_str,
2042 json_group);
2043 }
2044
2045 /* Find the source nested under the group, create it if
2046 * it doesn't exist */
2047 json_object_object_get_ex(json_group, src_str,
2048 &json_source);
2049
2050 if (!json_source) {
2051 json_source = json_object_new_object();
2052 json_object_object_add(json_group, src_str,
2053 json_source);
2054 }
2055
2056 /* Find the inbound interface nested under the source,
2057 * create it if it doesn't exist */
2058 json_object_object_get_ex(json_source, in_ifname,
2059 &json_ifp_in);
2060
2061 if (!json_ifp_in) {
2062 json_ifp_in = json_object_new_object();
2063 json_object_object_add(json_source, in_ifname,
2064 json_ifp_in);
2065 json_object_int_add(json_source, "Installed",
2066 c_oil->installed);
2067 if (isRpt)
2068 json_object_boolean_true_add(
2069 json_source, "isRpt");
2070 else
2071 json_object_boolean_false_add(
2072 json_source, "isRpt");
2073 json_object_int_add(json_source, "RefCount",
2074 c_oil->oil_ref_count);
2075 json_object_int_add(json_source, "OilListSize",
2076 c_oil->oil_size);
2077 json_object_int_add(
2078 json_source, "OilRescan",
2079 c_oil->oil_inherited_rescan);
2080 json_object_int_add(json_source, "LastUsed",
2081 c_oil->cc.lastused);
2082 json_object_int_add(json_source, "PacketCount",
2083 c_oil->cc.pktcnt);
2084 json_object_int_add(json_source, "ByteCount",
2085 c_oil->cc.bytecnt);
2086 json_object_int_add(json_source,
2087 "WrongInterface",
2088 c_oil->cc.wrong_if);
2089 }
2090 } else {
2091 vty_out(vty, "%-6d %-15s %-15s %-3s %-16s ",
2092 c_oil->installed, src_str, grp_str,
2093 isRpt ? "y" : "n", in_ifname);
2094 }
2095
2096 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
2097 ++oif_vif_index) {
2098 struct interface *ifp_out;
2099 char oif_uptime[10];
2100 int ttl;
2101
2102 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
2103 if (ttl < 1)
2104 continue;
2105
2106 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
2107 pim_time_uptime(
2108 oif_uptime, sizeof(oif_uptime),
2109 now - c_oil->oif_creation[oif_vif_index]);
2110
2111 if (ifp_out)
2112 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
2113 else
2114 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
2115
2116 if (uj) {
2117 json_ifp_out = json_object_new_object();
2118 json_object_string_add(json_ifp_out, "source",
2119 src_str);
2120 json_object_string_add(json_ifp_out, "group",
2121 grp_str);
2122 json_object_string_add(json_ifp_out,
2123 "inboundInterface",
2124 in_ifname);
2125 json_object_string_add(json_ifp_out,
2126 "outboundInterface",
2127 out_ifname);
2128 json_object_int_add(json_ifp_out, "installed",
2129 c_oil->installed);
2130
2131 json_object_object_add(json_ifp_in, out_ifname,
2132 json_ifp_out);
2133 } else {
2134 if (first_oif) {
2135 first_oif = 0;
2136 vty_out(vty, "%s(%c%c%c%c%c)",
2137 out_ifname,
2138 (c_oil->oif_flags[oif_vif_index]
2139 & PIM_OIF_FLAG_PROTO_IGMP)
2140 ? 'I'
2141 : ' ',
2142 (c_oil->oif_flags[oif_vif_index]
2143 & PIM_OIF_FLAG_PROTO_PIM)
2144 ? 'J'
2145 : ' ',
2146 (c_oil->oif_flags[oif_vif_index]
2147 & PIM_OIF_FLAG_PROTO_VXLAN)
2148 ? 'V'
2149 : ' ',
2150 (c_oil->oif_flags[oif_vif_index]
2151 & PIM_OIF_FLAG_PROTO_STAR)
2152 ? '*'
2153 : ' ',
2154 (c_oil->oif_flags[oif_vif_index]
2155 & PIM_OIF_FLAG_MUTE)
2156 ? 'M'
2157 : ' ');
2158 } else
2159 vty_out(vty, ", %s(%c%c%c%c%c)",
2160 out_ifname,
2161 (c_oil->oif_flags[oif_vif_index]
2162 & PIM_OIF_FLAG_PROTO_IGMP)
2163 ? 'I'
2164 : ' ',
2165 (c_oil->oif_flags[oif_vif_index]
2166 & PIM_OIF_FLAG_PROTO_PIM)
2167 ? 'J'
2168 : ' ',
2169 (c_oil->oif_flags[oif_vif_index]
2170 & PIM_OIF_FLAG_PROTO_VXLAN)
2171 ? 'V'
2172 : ' ',
2173 (c_oil->oif_flags[oif_vif_index]
2174 & PIM_OIF_FLAG_PROTO_STAR)
2175 ? '*'
2176 : ' ',
2177 (c_oil->oif_flags[oif_vif_index]
2178 & PIM_OIF_FLAG_MUTE)
2179 ? 'M'
2180 : ' ');
2181 }
2182 }
2183
2184 if (!uj)
2185 vty_out(vty, "\n");
2186 }
2187
2188
2189 if (uj) {
2190 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2191 json, JSON_C_TO_STRING_PRETTY));
2192 json_object_free(json);
2193 } else {
2194 vty_out(vty, "\n");
2195 }
2196 }
2197
2198 static void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
2199 bool uj)
2200 {
2201 struct listnode *neighnode;
2202 struct interface *ifp;
2203 struct pim_interface *pim_ifp;
2204 struct pim_neighbor *neigh;
2205 time_t now;
2206 char uptime[10];
2207 char expire[10];
2208 char neigh_src_str[INET_ADDRSTRLEN];
2209 json_object *json = NULL;
2210 json_object *json_ifp_rows = NULL;
2211 json_object *json_row = NULL;
2212
2213 now = pim_time_monotonic_sec();
2214
2215 if (uj) {
2216 json = json_object_new_object();
2217 } else {
2218 vty_out(vty,
2219 "Interface Neighbor Uptime Holdtime DR Pri\n");
2220 }
2221
2222 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2223 pim_ifp = ifp->info;
2224
2225 if (!pim_ifp)
2226 continue;
2227
2228 if (pim_ifp->pim_sock_fd < 0)
2229 continue;
2230
2231 if (uj)
2232 json_ifp_rows = json_object_new_object();
2233
2234 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2235 neigh)) {
2236 pim_inet4_dump("<src?>", neigh->source_addr,
2237 neigh_src_str, sizeof(neigh_src_str));
2238 pim_time_uptime(uptime, sizeof(uptime),
2239 now - neigh->creation);
2240 pim_time_timer_to_hhmmss(expire, sizeof(expire),
2241 neigh->t_expire_timer);
2242
2243 if (uj) {
2244 json_row = json_object_new_object();
2245 json_object_string_add(json_row, "interface",
2246 ifp->name);
2247 json_object_string_add(json_row, "neighbor",
2248 neigh_src_str);
2249 json_object_string_add(json_row, "upTime",
2250 uptime);
2251 json_object_string_add(json_row, "holdTime",
2252 expire);
2253 json_object_int_add(json_row, "holdTimeMax",
2254 neigh->holdtime);
2255 json_object_int_add(json_row, "drPriority",
2256 neigh->dr_priority);
2257 json_object_object_add(json_ifp_rows,
2258 neigh_src_str, json_row);
2259
2260 } else {
2261 vty_out(vty, "%-16s %15s %8s %8s %6d\n",
2262 ifp->name, neigh_src_str, uptime,
2263 expire, neigh->dr_priority);
2264 }
2265 }
2266
2267 if (uj) {
2268 json_object_object_add(json, ifp->name, json_ifp_rows);
2269 json_ifp_rows = NULL;
2270 }
2271 }
2272
2273 if (uj) {
2274 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2275 json, JSON_C_TO_STRING_PRETTY));
2276 json_object_free(json);
2277 }
2278 }
2279
2280 static void pim_show_neighbors_secondary(struct pim_instance *pim,
2281 struct vty *vty)
2282 {
2283 struct interface *ifp;
2284
2285 vty_out(vty,
2286 "Interface Address Neighbor Secondary \n");
2287
2288 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2289 struct pim_interface *pim_ifp;
2290 struct in_addr ifaddr;
2291 struct listnode *neighnode;
2292 struct pim_neighbor *neigh;
2293
2294 pim_ifp = ifp->info;
2295
2296 if (!pim_ifp)
2297 continue;
2298
2299 if (pim_ifp->pim_sock_fd < 0)
2300 continue;
2301
2302 ifaddr = pim_ifp->primary_address;
2303
2304 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
2305 neigh)) {
2306 char neigh_src_str[INET_ADDRSTRLEN];
2307 struct listnode *prefix_node;
2308 struct prefix *p;
2309
2310 if (!neigh->prefix_list)
2311 continue;
2312
2313 pim_inet4_dump("<src?>", neigh->source_addr,
2314 neigh_src_str, sizeof(neigh_src_str));
2315
2316 for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
2317 prefix_node, p)) {
2318 char neigh_sec_str[PREFIX2STR_BUFFER];
2319
2320 prefix2str(p, neigh_sec_str,
2321 sizeof(neigh_sec_str));
2322
2323 vty_out(vty, "%-16s %-15s %-15s %-15s\n",
2324 ifp->name, inet_ntoa(ifaddr),
2325 neigh_src_str, neigh_sec_str);
2326 }
2327 }
2328 }
2329 }
2330
2331 static void json_object_pim_upstream_add(json_object *json,
2332 struct pim_upstream *up)
2333 {
2334 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
2335 json_object_boolean_true_add(json, "drJoinDesired");
2336
2337 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
2338 json_object_boolean_true_add(json, "drJoinDesiredUpdated");
2339
2340 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
2341 json_object_boolean_true_add(json, "firstHopRouter");
2342
2343 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
2344 json_object_boolean_true_add(json, "sourceIgmp");
2345
2346 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
2347 json_object_boolean_true_add(json, "sourcePim");
2348
2349 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
2350 json_object_boolean_true_add(json, "sourceStream");
2351
2352 /* XXX: need to print ths flag in the plain text display as well */
2353 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
2354 json_object_boolean_true_add(json, "sourceMsdp");
2355
2356 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SEND_SG_RPT_PRUNE)
2357 json_object_boolean_true_add(json, "sendSGRptPrune");
2358
2359 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
2360 json_object_boolean_true_add(json, "lastHopRouter");
2361
2362 if (up->flags & PIM_UPSTREAM_FLAG_MASK_DISABLE_KAT_EXPIRY)
2363 json_object_boolean_true_add(json, "disableKATExpiry");
2364
2365 if (up->flags & PIM_UPSTREAM_FLAG_MASK_STATIC_IIF)
2366 json_object_boolean_true_add(json, "staticIncomingInterface");
2367
2368 if (up->flags & PIM_UPSTREAM_FLAG_MASK_ALLOW_IIF_IN_OIL)
2369 json_object_boolean_true_add(json,
2370 "allowIncomingInterfaceinOil");
2371
2372 if (up->flags & PIM_UPSTREAM_FLAG_MASK_NO_PIMREG_DATA)
2373 json_object_boolean_true_add(json, "noPimRegistrationData");
2374
2375 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FORCE_PIMREG)
2376 json_object_boolean_true_add(json, "forcePimRegistration");
2377
2378 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG)
2379 json_object_boolean_true_add(json, "sourceVxlanOrigination");
2380
2381 if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
2382 json_object_boolean_true_add(json, "sourceVxlanTermination");
2383
2384 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
2385 json_object_boolean_true_add(json, "mlagVxlan");
2386
2387 if (up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
2388 json_object_boolean_true_add(json,
2389 "mlagNonDesignatedForwarder");
2390 }
2391
2392 static const char *
2393 pim_upstream_state2brief_str(enum pim_upstream_state join_state,
2394 char *state_str, size_t state_str_len)
2395 {
2396 switch (join_state) {
2397 case PIM_UPSTREAM_NOTJOINED:
2398 strlcpy(state_str, "NotJ", state_str_len);
2399 break;
2400 case PIM_UPSTREAM_JOINED:
2401 strlcpy(state_str, "J", state_str_len);
2402 break;
2403 default:
2404 strlcpy(state_str, "Unk", state_str_len);
2405 }
2406 return state_str;
2407 }
2408
2409 static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
2410 char *state_str, size_t state_str_len)
2411 {
2412 switch (reg_state) {
2413 case PIM_REG_NOINFO:
2414 strlcpy(state_str, "RegNI", state_str_len);
2415 break;
2416 case PIM_REG_JOIN:
2417 strlcpy(state_str, "RegJ", state_str_len);
2418 break;
2419 case PIM_REG_JOIN_PENDING:
2420 case PIM_REG_PRUNE:
2421 strlcpy(state_str, "RegP", state_str_len);
2422 break;
2423 default:
2424 strlcpy(state_str, "Unk", state_str_len);
2425 }
2426 return state_str;
2427 }
2428
2429 static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
2430 struct prefix_sg *sg, bool uj)
2431 {
2432 struct listnode *upnode;
2433 struct pim_upstream *up;
2434 time_t now;
2435 json_object *json = NULL;
2436 json_object *json_group = NULL;
2437 json_object *json_row = NULL;
2438
2439 now = pim_time_monotonic_sec();
2440
2441 if (uj)
2442 json = json_object_new_object();
2443 else
2444 vty_out(vty,
2445 "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
2446
2447 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
2448 char src_str[INET_ADDRSTRLEN];
2449 char grp_str[INET_ADDRSTRLEN];
2450 char uptime[10];
2451 char join_timer[10];
2452 char rs_timer[10];
2453 char ka_timer[10];
2454 char msdp_reg_timer[10];
2455 char state_str[PIM_REG_STATE_STR_LEN];
2456
2457 if (sg->grp.s_addr != 0 && sg->grp.s_addr != up->sg.grp.s_addr)
2458 continue;
2459 if (sg->src.s_addr != 0 && sg->src.s_addr != up->sg.src.s_addr)
2460 continue;
2461
2462 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2463 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2464 pim_time_uptime(uptime, sizeof(uptime),
2465 now - up->state_transition);
2466 pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
2467 up->t_join_timer);
2468
2469 /*
2470 * If the upstream is not dummy and it has a J/P timer for the
2471 * neighbor display that
2472 */
2473 if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
2474 struct pim_neighbor *nbr;
2475
2476 nbr = pim_neighbor_find(
2477 up->rpf.source_nexthop.interface,
2478 up->rpf.rpf_addr.u.prefix4);
2479 if (nbr)
2480 pim_time_timer_to_hhmmss(join_timer,
2481 sizeof(join_timer),
2482 nbr->jp_timer);
2483 }
2484
2485 pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
2486 up->t_rs_timer);
2487 pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
2488 up->t_ka_timer);
2489 pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
2490 up->t_msdp_reg_timer);
2491
2492 pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str));
2493 if (up->reg_state != PIM_REG_NOINFO) {
2494 char tmp_str[PIM_REG_STATE_STR_LEN];
2495
2496 sprintf(state_str + strlen(state_str), ",%s",
2497 pim_reg_state2brief_str(up->reg_state, tmp_str,
2498 sizeof(tmp_str)));
2499 }
2500
2501 if (uj) {
2502 json_object_object_get_ex(json, grp_str, &json_group);
2503
2504 if (!json_group) {
2505 json_group = json_object_new_object();
2506 json_object_object_add(json, grp_str,
2507 json_group);
2508 }
2509
2510 json_row = json_object_new_object();
2511 json_object_pim_upstream_add(json_row, up);
2512 json_object_string_add(
2513 json_row, "inboundInterface",
2514 up->rpf.source_nexthop.interface
2515 ? up->rpf.source_nexthop.interface->name
2516 : "Unknown");
2517
2518 /*
2519 * The RPF address we use is slightly different
2520 * based upon what we are looking up.
2521 * If we have a S, list that unless
2522 * we are the FHR, else we just put
2523 * the RP as the rpfAddress
2524 */
2525 if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR
2526 || up->sg.src.s_addr == INADDR_ANY) {
2527 char rpf[PREFIX_STRLEN];
2528 struct pim_rpf *rpg;
2529
2530 rpg = RP(pim, up->sg.grp);
2531 pim_inet4_dump("<rpf?>",
2532 rpg->rpf_addr.u.prefix4, rpf,
2533 sizeof(rpf));
2534 json_object_string_add(json_row, "rpfAddress",
2535 rpf);
2536 } else {
2537 json_object_string_add(json_row, "rpfAddress",
2538 src_str);
2539 }
2540
2541 json_object_string_add(json_row, "source", src_str);
2542 json_object_string_add(json_row, "group", grp_str);
2543 json_object_string_add(json_row, "state", state_str);
2544 json_object_string_add(
2545 json_row, "joinState",
2546 pim_upstream_state2str(up->join_state));
2547 json_object_string_add(
2548 json_row, "regState",
2549 pim_reg_state2str(up->reg_state, state_str, sizeof(state_str)));
2550 json_object_string_add(json_row, "upTime", uptime);
2551 json_object_string_add(json_row, "joinTimer",
2552 join_timer);
2553 json_object_string_add(json_row, "resetTimer",
2554 rs_timer);
2555 json_object_string_add(json_row, "keepaliveTimer",
2556 ka_timer);
2557 json_object_string_add(json_row, "msdpRegTimer",
2558 msdp_reg_timer);
2559 json_object_int_add(json_row, "refCount",
2560 up->ref_count);
2561 json_object_int_add(json_row, "sptBit", up->sptbit);
2562 json_object_object_add(json_group, src_str, json_row);
2563 } else {
2564 vty_out(vty,
2565 "%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
2566 up->rpf.source_nexthop.interface
2567 ? up->rpf.source_nexthop.interface->name
2568 : "Unknown",
2569 src_str, grp_str, state_str, uptime, join_timer,
2570 rs_timer, ka_timer, up->ref_count);
2571 }
2572 }
2573
2574 if (uj) {
2575 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2576 json, JSON_C_TO_STRING_PRETTY));
2577 json_object_free(json);
2578 }
2579 }
2580
2581 static void pim_show_channel_helper(struct pim_instance *pim,
2582 struct vty *vty,
2583 struct pim_interface *pim_ifp,
2584 struct pim_ifchannel *ch,
2585 json_object *json, bool uj)
2586 {
2587 struct pim_upstream *up = ch->upstream;
2588 json_object *json_group = NULL;
2589 char src_str[INET_ADDRSTRLEN];
2590 char grp_str[INET_ADDRSTRLEN];
2591 json_object *json_row = NULL;
2592
2593 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2594 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2595
2596 if (uj) {
2597 json_object_object_get_ex(json, grp_str, &json_group);
2598
2599 if (!json_group) {
2600 json_group = json_object_new_object();
2601 json_object_object_add(json, grp_str, json_group);
2602 }
2603
2604 json_row = json_object_new_object();
2605 json_object_pim_upstream_add(json_row, up);
2606 json_object_string_add(json_row, "interface",
2607 ch->interface->name);
2608 json_object_string_add(json_row, "source", src_str);
2609 json_object_string_add(json_row, "group", grp_str);
2610
2611 if (pim_macro_ch_lost_assert(ch))
2612 json_object_boolean_true_add(json_row, "lostAssert");
2613
2614 if (pim_macro_chisin_joins(ch))
2615 json_object_boolean_true_add(json_row, "joins");
2616
2617 if (pim_macro_chisin_pim_include(ch))
2618 json_object_boolean_true_add(json_row, "pimInclude");
2619
2620 if (pim_upstream_evaluate_join_desired(pim, up))
2621 json_object_boolean_true_add(json_row,
2622 "evaluateJoinDesired");
2623
2624 json_object_object_add(json_group, src_str, json_row);
2625
2626 } else {
2627 vty_out(vty, "%-16s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
2628 ch->interface->name, src_str, grp_str,
2629 pim_macro_ch_lost_assert(ch) ? "yes" : "no",
2630 pim_macro_chisin_joins(ch) ? "yes" : "no",
2631 pim_macro_chisin_pim_include(ch) ? "yes" : "no",
2632 PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags)
2633 ? "yes"
2634 : "no",
2635 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2636 : "no");
2637 }
2638 }
2639
2640 static void pim_show_channel(struct pim_instance *pim, struct vty *vty,
2641 bool uj)
2642 {
2643 struct pim_interface *pim_ifp;
2644 struct pim_ifchannel *ch;
2645 struct interface *ifp;
2646
2647 json_object *json = NULL;
2648
2649 if (uj)
2650 json = json_object_new_object();
2651 else
2652 vty_out(vty,
2653 "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
2654
2655 /* scan per-interface (S,G) state */
2656 FOR_ALL_INTERFACES (pim->vrf, ifp) {
2657 pim_ifp = ifp->info;
2658 if (!pim_ifp)
2659 continue;
2660
2661
2662 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
2663 /* scan all interfaces */
2664 pim_show_channel_helper(pim, vty, pim_ifp, ch,
2665 json, uj);
2666 }
2667 }
2668
2669 if (uj) {
2670 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2671 json, JSON_C_TO_STRING_PRETTY));
2672 json_object_free(json);
2673 }
2674 }
2675
2676 static void pim_show_join_desired_helper(struct pim_instance *pim,
2677 struct vty *vty,
2678 struct pim_upstream *up,
2679 json_object *json, bool uj)
2680 {
2681 json_object *json_group = NULL;
2682 char src_str[INET_ADDRSTRLEN];
2683 char grp_str[INET_ADDRSTRLEN];
2684 json_object *json_row = NULL;
2685
2686 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2687 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2688
2689 if (uj) {
2690 json_object_object_get_ex(json, grp_str, &json_group);
2691
2692 if (!json_group) {
2693 json_group = json_object_new_object();
2694 json_object_object_add(json, grp_str, json_group);
2695 }
2696
2697 json_row = json_object_new_object();
2698 json_object_pim_upstream_add(json_row, up);
2699 json_object_string_add(json_row, "source", src_str);
2700 json_object_string_add(json_row, "group", grp_str);
2701
2702 if (pim_upstream_evaluate_join_desired(pim, up))
2703 json_object_boolean_true_add(json_row,
2704 "evaluateJoinDesired");
2705
2706 json_object_object_add(json_group, src_str, json_row);
2707
2708 } else {
2709 vty_out(vty, "%-15s %-15s %-6s\n",
2710 src_str, grp_str,
2711 pim_upstream_evaluate_join_desired(pim, up) ? "yes"
2712 : "no");
2713 }
2714 }
2715
2716 static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
2717 bool uj)
2718 {
2719 struct listnode *upnode;
2720 struct pim_upstream *up;
2721
2722 json_object *json = NULL;
2723
2724 if (uj)
2725 json = json_object_new_object();
2726 else
2727 vty_out(vty,
2728 "Source Group EvalJD\n");
2729
2730 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
2731 /* scan all interfaces */
2732 pim_show_join_desired_helper(pim, vty, up,
2733 json, uj);
2734 }
2735
2736 if (uj) {
2737 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2738 json, JSON_C_TO_STRING_PRETTY));
2739 json_object_free(json);
2740 }
2741 }
2742
2743 static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
2744 bool uj)
2745 {
2746 struct listnode *upnode;
2747 struct pim_upstream *up;
2748 json_object *json = NULL;
2749 json_object *json_group = NULL;
2750 json_object *json_row = NULL;
2751
2752 if (uj)
2753 json = json_object_new_object();
2754 else
2755 vty_out(vty,
2756 "Source Group RpfIface RibNextHop RpfAddress \n");
2757
2758 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
2759 char src_str[INET_ADDRSTRLEN];
2760 char grp_str[INET_ADDRSTRLEN];
2761 char rpf_nexthop_str[PREFIX_STRLEN];
2762 char rpf_addr_str[PREFIX_STRLEN];
2763 struct pim_rpf *rpf;
2764 const char *rpf_ifname;
2765
2766 rpf = &up->rpf;
2767
2768 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2769 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2770 pim_addr_dump("<nexthop?>",
2771 &rpf->source_nexthop.mrib_nexthop_addr,
2772 rpf_nexthop_str, sizeof(rpf_nexthop_str));
2773 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2774 sizeof(rpf_addr_str));
2775
2776 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
2777
2778 if (uj) {
2779 json_object_object_get_ex(json, grp_str, &json_group);
2780
2781 if (!json_group) {
2782 json_group = json_object_new_object();
2783 json_object_object_add(json, grp_str,
2784 json_group);
2785 }
2786
2787 json_row = json_object_new_object();
2788 json_object_pim_upstream_add(json_row, up);
2789 json_object_string_add(json_row, "source", src_str);
2790 json_object_string_add(json_row, "group", grp_str);
2791 json_object_string_add(json_row, "rpfInterface",
2792 rpf_ifname);
2793 json_object_string_add(json_row, "ribNexthop",
2794 rpf_nexthop_str);
2795 json_object_string_add(json_row, "rpfAddress",
2796 rpf_addr_str);
2797 json_object_object_add(json_group, src_str, json_row);
2798 } else {
2799 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s\n", src_str,
2800 grp_str, rpf_ifname, rpf_nexthop_str,
2801 rpf_addr_str);
2802 }
2803 }
2804
2805 if (uj) {
2806 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2807 json, JSON_C_TO_STRING_PRETTY));
2808 json_object_free(json);
2809 }
2810 }
2811
2812 static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
2813 time_t now, json_object *json)
2814 {
2815 char refresh_uptime[10];
2816
2817 pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
2818 pim->rpf_cache_refresh_last);
2819
2820 if (json) {
2821 json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
2822 router->rpf_cache_refresh_delay_msec);
2823 json_object_int_add(
2824 json, "rpfCacheRefreshTimer",
2825 pim_time_timer_remain_msec(pim->rpf_cache_refresher));
2826 json_object_int_add(json, "rpfCacheRefreshRequests",
2827 pim->rpf_cache_refresh_requests);
2828 json_object_int_add(json, "rpfCacheRefreshEvents",
2829 pim->rpf_cache_refresh_events);
2830 json_object_string_add(json, "rpfCacheRefreshLast",
2831 refresh_uptime);
2832 json_object_int_add(json, "nexthopLookups",
2833 pim->nexthop_lookups);
2834 json_object_int_add(json, "nexthopLookupsAvoided",
2835 pim->nexthop_lookups_avoided);
2836 } else {
2837 vty_out(vty,
2838 "RPF Cache Refresh Delay: %ld msecs\n"
2839 "RPF Cache Refresh Timer: %ld msecs\n"
2840 "RPF Cache Refresh Requests: %lld\n"
2841 "RPF Cache Refresh Events: %lld\n"
2842 "RPF Cache Refresh Last: %s\n"
2843 "Nexthop Lookups: %lld\n"
2844 "Nexthop Lookups Avoided: %lld\n",
2845 router->rpf_cache_refresh_delay_msec,
2846 pim_time_timer_remain_msec(pim->rpf_cache_refresher),
2847 (long long)pim->rpf_cache_refresh_requests,
2848 (long long)pim->rpf_cache_refresh_events,
2849 refresh_uptime, (long long)pim->nexthop_lookups,
2850 (long long)pim->nexthop_lookups_avoided);
2851 }
2852 }
2853
2854 static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
2855 time_t now)
2856 {
2857 char uptime_scan_oil[10];
2858 char uptime_mroute_add[10];
2859 char uptime_mroute_del[10];
2860
2861 pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
2862 pim->scan_oil_last);
2863 pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
2864 pim->mroute_add_last);
2865 pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
2866 pim->mroute_del_last);
2867
2868 vty_out(vty,
2869 "Scan OIL - Last: %s Events: %lld\n"
2870 "MFC Add - Last: %s Events: %lld\n"
2871 "MFC Del - Last: %s Events: %lld\n",
2872 uptime_scan_oil, (long long)pim->scan_oil_events,
2873 uptime_mroute_add, (long long)pim->mroute_add_events,
2874 uptime_mroute_del, (long long)pim->mroute_del_events);
2875 }
2876
2877 static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
2878 {
2879 struct listnode *up_node;
2880 struct pim_upstream *up;
2881 time_t now = pim_time_monotonic_sec();
2882 json_object *json = NULL;
2883 json_object *json_group = NULL;
2884 json_object *json_row = NULL;
2885
2886 if (uj) {
2887 json = json_object_new_object();
2888 show_rpf_refresh_stats(vty, pim, now, json);
2889 } else {
2890 show_rpf_refresh_stats(vty, pim, now, json);
2891 vty_out(vty, "\n");
2892 vty_out(vty,
2893 "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
2894 }
2895
2896 for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
2897 char src_str[INET_ADDRSTRLEN];
2898 char grp_str[INET_ADDRSTRLEN];
2899 char rpf_addr_str[PREFIX_STRLEN];
2900 char rib_nexthop_str[PREFIX_STRLEN];
2901 const char *rpf_ifname;
2902 struct pim_rpf *rpf = &up->rpf;
2903
2904 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
2905 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
2906 pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
2907 sizeof(rpf_addr_str));
2908 pim_addr_dump("<nexthop?>",
2909 &rpf->source_nexthop.mrib_nexthop_addr,
2910 rib_nexthop_str, sizeof(rib_nexthop_str));
2911
2912 rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
2913
2914 if (uj) {
2915 json_object_object_get_ex(json, grp_str, &json_group);
2916
2917 if (!json_group) {
2918 json_group = json_object_new_object();
2919 json_object_object_add(json, grp_str,
2920 json_group);
2921 }
2922
2923 json_row = json_object_new_object();
2924 json_object_string_add(json_row, "source", src_str);
2925 json_object_string_add(json_row, "group", grp_str);
2926 json_object_string_add(json_row, "rpfInterface",
2927 rpf_ifname);
2928 json_object_string_add(json_row, "rpfAddress",
2929 rpf_addr_str);
2930 json_object_string_add(json_row, "ribNexthop",
2931 rib_nexthop_str);
2932 json_object_int_add(
2933 json_row, "routeMetric",
2934 rpf->source_nexthop.mrib_route_metric);
2935 json_object_int_add(
2936 json_row, "routePreference",
2937 rpf->source_nexthop.mrib_metric_preference);
2938 json_object_object_add(json_group, src_str, json_row);
2939
2940 } else {
2941 vty_out(vty, "%-15s %-15s %-16s %-15s %-15s %6d %4d\n",
2942 src_str, grp_str, rpf_ifname, rpf_addr_str,
2943 rib_nexthop_str,
2944 rpf->source_nexthop.mrib_route_metric,
2945 rpf->source_nexthop.mrib_metric_preference);
2946 }
2947 }
2948
2949 if (uj) {
2950 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2951 json, JSON_C_TO_STRING_PRETTY));
2952 json_object_free(json);
2953 }
2954 }
2955
2956 struct pnc_cache_walk_data {
2957 struct vty *vty;
2958 struct pim_instance *pim;
2959 };
2960
2961 static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
2962 {
2963 struct pim_nexthop_cache *pnc = bucket->data;
2964 struct pnc_cache_walk_data *cwd = arg;
2965 struct vty *vty = cwd->vty;
2966 struct pim_instance *pim = cwd->pim;
2967 struct nexthop *nh_node = NULL;
2968 ifindex_t first_ifindex;
2969 struct interface *ifp = NULL;
2970
2971 for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
2972 first_ifindex = nh_node->ifindex;
2973 ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
2974
2975 vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
2976 vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
2977 vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
2978 vty_out(vty, "\n");
2979 }
2980 return CMD_SUCCESS;
2981 }
2982
2983 static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
2984 {
2985 struct pnc_cache_walk_data cwd;
2986
2987 cwd.vty = vty;
2988 cwd.pim = pim;
2989 vty_out(vty, "Number of registered addresses: %lu\n",
2990 pim->rpf_hash->count);
2991 vty_out(vty, "Address Interface Nexthop\n");
2992 vty_out(vty, "---------------------------------------------\n");
2993
2994 hash_walk(pim->rpf_hash, pim_print_pnc_cache_walkcb, &cwd);
2995 }
2996
2997 /* Display the bsm database details */
2998 static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
2999 {
3000 struct listnode *bsmnode;
3001 int count = 0;
3002 int fragment = 1;
3003 struct bsm_info *bsm;
3004 json_object *json = NULL;
3005 json_object *json_group = NULL;
3006 json_object *json_row = NULL;
3007
3008 count = pim->global_scope.bsm_list->count;
3009
3010 if (uj) {
3011 json = json_object_new_object();
3012 json_object_int_add(json, "Number of the fragments", count);
3013 } else {
3014 vty_out(vty, "Scope Zone: Global\n");
3015 vty_out(vty, "Number of the fragments: %d\n", count);
3016 vty_out(vty, "\n");
3017 }
3018
3019 for (ALL_LIST_ELEMENTS_RO(pim->global_scope.bsm_list, bsmnode, bsm)) {
3020 char grp_str[INET_ADDRSTRLEN];
3021 char rp_str[INET_ADDRSTRLEN];
3022 char bsr_str[INET_ADDRSTRLEN];
3023 struct bsmmsg_grpinfo *group;
3024 struct bsmmsg_rpinfo *rpaddr;
3025 struct prefix grp;
3026 struct bsm_hdr *hdr;
3027 uint32_t offset = 0;
3028 uint8_t *buf;
3029 uint32_t len = 0;
3030 uint32_t frag_rp_cnt = 0;
3031
3032 buf = bsm->bsm;
3033 len = bsm->size;
3034
3035 /* skip pim header */
3036 buf += PIM_MSG_HEADER_LEN;
3037 len -= PIM_MSG_HEADER_LEN;
3038
3039 hdr = (struct bsm_hdr *)buf;
3040
3041 /* BSM starts with bsr header */
3042 buf += sizeof(struct bsm_hdr);
3043 len -= sizeof(struct bsm_hdr);
3044
3045 pim_inet4_dump("<BSR Address?>", hdr->bsr_addr.addr, bsr_str,
3046 sizeof(bsr_str));
3047
3048
3049 if (uj) {
3050 json_object_string_add(json, "BSR address", bsr_str);
3051 json_object_int_add(json, "BSR priority",
3052 hdr->bsr_prio);
3053 json_object_int_add(json, "Hashmask Length",
3054 hdr->hm_len);
3055 json_object_int_add(json, "Fragment Tag",
3056 ntohs(hdr->frag_tag));
3057 } else {
3058 vty_out(vty, "BSM Fragment : %d\n", fragment);
3059 vty_out(vty, "------------------\n");
3060 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
3061 "BSR-Priority", "Hashmask-len", "Fragment-Tag");
3062 vty_out(vty, "%-15s %-15d %-15d %-15d\n", bsr_str,
3063 hdr->bsr_prio, hdr->hm_len,
3064 ntohs(hdr->frag_tag));
3065 }
3066
3067 vty_out(vty, "\n");
3068
3069 while (offset < len) {
3070 group = (struct bsmmsg_grpinfo *)buf;
3071
3072 if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
3073 grp.family = AF_INET;
3074
3075 grp.prefixlen = group->group.mask;
3076 grp.u.prefix4.s_addr = group->group.addr.s_addr;
3077
3078 prefix2str(&grp, grp_str, sizeof(grp_str));
3079
3080 buf += sizeof(struct bsmmsg_grpinfo);
3081 offset += sizeof(struct bsmmsg_grpinfo);
3082
3083 if (uj) {
3084 json_object_object_get_ex(json, grp_str,
3085 &json_group);
3086 if (!json_group) {
3087 json_group = json_object_new_object();
3088 json_object_int_add(json_group,
3089 "Rp Count",
3090 group->rp_count);
3091 json_object_int_add(
3092 json_group, "Fragment Rp count",
3093 group->frag_rp_count);
3094 json_object_object_add(json, grp_str,
3095 json_group);
3096 }
3097 } else {
3098 vty_out(vty, "Group : %s\n", grp_str);
3099 vty_out(vty, "-------------------\n");
3100 vty_out(vty, "Rp Count:%d\n", group->rp_count);
3101 vty_out(vty, "Fragment Rp Count : %d\n",
3102 group->frag_rp_count);
3103 }
3104
3105 frag_rp_cnt = group->frag_rp_count;
3106
3107 if (!frag_rp_cnt)
3108 continue;
3109
3110 if (!uj)
3111 vty_out(vty,
3112 "RpAddress HoldTime Priority\n");
3113
3114 while (frag_rp_cnt--) {
3115 rpaddr = (struct bsmmsg_rpinfo *)buf;
3116
3117 buf += sizeof(struct bsmmsg_rpinfo);
3118 offset += sizeof(struct bsmmsg_rpinfo);
3119
3120 pim_inet4_dump("<Rp addr?>",
3121 rpaddr->rpaddr.addr, rp_str,
3122 sizeof(rp_str));
3123
3124 if (uj) {
3125 json_row = json_object_new_object();
3126 json_object_string_add(
3127 json_row, "Rp Address", rp_str);
3128 json_object_int_add(
3129 json_row, "Rp HoldTime",
3130 ntohs(rpaddr->rp_holdtime));
3131 json_object_int_add(json_row,
3132 "Rp Priority",
3133 rpaddr->rp_pri);
3134 json_object_object_add(
3135 json_group, rp_str, json_row);
3136 } else {
3137 vty_out(vty, "%-15s %-12d %d\n", rp_str,
3138 ntohs(rpaddr->rp_holdtime),
3139 rpaddr->rp_pri);
3140 }
3141 }
3142 vty_out(vty, "\n");
3143 }
3144
3145 fragment++;
3146 }
3147
3148 if (uj) {
3149 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3150 json, JSON_C_TO_STRING_PRETTY));
3151 json_object_free(json);
3152 }
3153 }
3154
3155 /*Display the group-rp mappings */
3156 static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
3157 struct vty *vty, bool uj)
3158 {
3159 struct bsgrp_node *bsgrp;
3160 struct listnode *rpnode;
3161 struct bsm_rpinfo *bsm_rp;
3162 struct route_node *rn;
3163 char bsr_str[INET_ADDRSTRLEN];
3164 json_object *json = NULL;
3165 json_object *json_group = NULL;
3166 json_object *json_row = NULL;
3167
3168 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY)
3169 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
3170
3171 else
3172 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr, bsr_str,
3173 sizeof(bsr_str));
3174
3175 if (uj) {
3176 json = json_object_new_object();
3177 json_object_string_add(json, "BSR Address", bsr_str);
3178 } else {
3179 vty_out(vty, "BSR Address %s\n", bsr_str);
3180 }
3181
3182 for (rn = route_top(pim->global_scope.bsrp_table); rn;
3183 rn = route_next(rn)) {
3184 bsgrp = (struct bsgrp_node *)rn->info;
3185
3186 if (!bsgrp)
3187 continue;
3188
3189 char grp_str[INET_ADDRSTRLEN];
3190
3191 prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
3192
3193 if (uj) {
3194 json_object_object_get_ex(json, grp_str, &json_group);
3195 if (!json_group) {
3196 json_group = json_object_new_object();
3197 json_object_object_add(json, grp_str,
3198 json_group);
3199 }
3200 } else {
3201 vty_out(vty, "Group Address %s\n", grp_str);
3202 vty_out(vty, "--------------------------\n");
3203 vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
3204 "priority", "Holdtime", "Hash");
3205
3206 vty_out(vty, "(ACTIVE)\n");
3207 }
3208
3209 if (bsgrp->bsrp_list) {
3210 for (ALL_LIST_ELEMENTS_RO(bsgrp->bsrp_list, rpnode,
3211 bsm_rp)) {
3212 char rp_str[INET_ADDRSTRLEN];
3213
3214 pim_inet4_dump("<Rp Address?>",
3215 bsm_rp->rp_address, rp_str,
3216 sizeof(rp_str));
3217
3218 if (uj) {
3219 json_row = json_object_new_object();
3220 json_object_string_add(
3221 json_row, "Rp Address", rp_str);
3222 json_object_int_add(
3223 json_row, "Rp HoldTime",
3224 bsm_rp->rp_holdtime);
3225 json_object_int_add(json_row,
3226 "Rp Priority",
3227 bsm_rp->rp_prio);
3228 json_object_int_add(json_row,
3229 "Hash Val",
3230 bsm_rp->hash);
3231 json_object_object_add(
3232 json_group, rp_str, json_row);
3233
3234 } else {
3235 vty_out(vty,
3236 "%-15s %-15u %-15u %-15u\n",
3237 rp_str, bsm_rp->rp_prio,
3238 bsm_rp->rp_holdtime,
3239 bsm_rp->hash);
3240 }
3241 }
3242 if (!bsgrp->bsrp_list->count && !uj)
3243 vty_out(vty, "Active List is empty.\n");
3244 }
3245
3246 if (uj) {
3247 json_object_int_add(json_group, "Pending RP count",
3248 bsgrp->pend_rp_cnt);
3249 } else {
3250 vty_out(vty, "(PENDING)\n");
3251 vty_out(vty, "Pending RP count :%d\n",
3252 bsgrp->pend_rp_cnt);
3253 if (bsgrp->pend_rp_cnt)
3254 vty_out(vty, "%-15s %-15s %-15s %-15s\n",
3255 "Rp Address", "priority", "Holdtime",
3256 "Hash");
3257 }
3258
3259 if (bsgrp->partial_bsrp_list) {
3260 for (ALL_LIST_ELEMENTS_RO(bsgrp->partial_bsrp_list,
3261 rpnode, bsm_rp)) {
3262 char rp_str[INET_ADDRSTRLEN];
3263
3264 pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address,
3265 rp_str, sizeof(rp_str));
3266
3267 if (uj) {
3268 json_row = json_object_new_object();
3269 json_object_string_add(
3270 json_row, "Rp Address", rp_str);
3271 json_object_int_add(
3272 json_row, "Rp HoldTime",
3273 bsm_rp->rp_holdtime);
3274 json_object_int_add(json_row,
3275 "Rp Priority",
3276 bsm_rp->rp_prio);
3277 json_object_int_add(json_row,
3278 "Hash Val",
3279 bsm_rp->hash);
3280 json_object_object_add(
3281 json_group, rp_str, json_row);
3282 } else {
3283 vty_out(vty,
3284 "%-15s %-15u %-15u %-15u\n",
3285 rp_str, bsm_rp->rp_prio,
3286 bsm_rp->rp_holdtime,
3287 bsm_rp->hash);
3288 }
3289 }
3290 if (!bsgrp->partial_bsrp_list->count && !uj)
3291 vty_out(vty, "Partial List is empty\n");
3292 }
3293
3294 if (!uj)
3295 vty_out(vty, "\n");
3296 }
3297
3298 if (uj) {
3299 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3300 json, JSON_C_TO_STRING_PRETTY));
3301 json_object_free(json);
3302 }
3303 }
3304
3305 /* pim statistics - just adding only bsm related now.
3306 * We can continue to add all pim related stats here.
3307 */
3308 static void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
3309 const char *ifname, bool uj)
3310 {
3311 json_object *json = NULL;
3312 struct interface *ifp;
3313
3314 if (uj) {
3315 json = json_object_new_object();
3316 json_object_int_add(json, "Number of Received BSMs",
3317 pim->bsm_rcvd);
3318 json_object_int_add(json, "Number of Forwared BSMs",
3319 pim->bsm_sent);
3320 json_object_int_add(json, "Number of Dropped BSMs",
3321 pim->bsm_dropped);
3322 } else {
3323 vty_out(vty, "BSM Statistics :\n");
3324 vty_out(vty, "----------------\n");
3325 vty_out(vty, "Number of Received BSMs : %" PRIu64 "\n",
3326 pim->bsm_rcvd);
3327 vty_out(vty, "Number of Forwared BSMs : %" PRIu64 "\n",
3328 pim->bsm_sent);
3329 vty_out(vty, "Number of Dropped BSMs : %" PRIu64 "\n",
3330 pim->bsm_dropped);
3331 }
3332
3333 vty_out(vty, "\n");
3334
3335 /* scan interfaces */
3336 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3337 struct pim_interface *pim_ifp = ifp->info;
3338
3339 if (ifname && strcmp(ifname, ifp->name))
3340 continue;
3341
3342 if (!pim_ifp)
3343 continue;
3344
3345 if (!uj) {
3346 vty_out(vty, "Interface : %s\n", ifp->name);
3347 vty_out(vty, "-------------------\n");
3348 vty_out(vty,
3349 "Number of BSMs dropped due to config miss : %u\n",
3350 pim_ifp->pim_ifstat_bsm_cfg_miss);
3351 vty_out(vty, "Number of unicast BSMs dropped : %u\n",
3352 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3353 vty_out(vty,
3354 "Number of BSMs dropped due to invalid scope zone : %u\n",
3355 pim_ifp->pim_ifstat_bsm_invalid_sz);
3356 } else {
3357
3358 json_object *json_row = NULL;
3359
3360 json_row = json_object_new_object();
3361
3362 json_object_string_add(json_row, "If Name", ifp->name);
3363 json_object_int_add(
3364 json_row,
3365 "Number of BSMs dropped due to config miss",
3366 pim_ifp->pim_ifstat_bsm_cfg_miss);
3367 json_object_int_add(
3368 json_row, "Number of unicast BSMs dropped",
3369 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss);
3370 json_object_int_add(json_row,
3371 "Number of BSMs dropped due to invalid scope zone",
3372 pim_ifp->pim_ifstat_bsm_invalid_sz);
3373 json_object_object_add(json, ifp->name, json_row);
3374 }
3375 vty_out(vty, "\n");
3376 }
3377
3378 if (uj) {
3379 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3380 json, JSON_C_TO_STRING_PRETTY));
3381 json_object_free(json);
3382 }
3383 }
3384
3385 static void clear_pim_statistics(struct pim_instance *pim)
3386 {
3387 struct interface *ifp;
3388
3389 pim->bsm_rcvd = 0;
3390 pim->bsm_sent = 0;
3391 pim->bsm_dropped = 0;
3392
3393 /* scan interfaces */
3394 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3395 struct pim_interface *pim_ifp = ifp->info;
3396
3397 if (!pim_ifp)
3398 continue;
3399
3400 pim_ifp->pim_ifstat_bsm_cfg_miss = 0;
3401 pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0;
3402 pim_ifp->pim_ifstat_bsm_invalid_sz = 0;
3403 }
3404 }
3405
3406 static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
3407 {
3408 struct interface *ifp;
3409 time_t now;
3410 json_object *json = NULL;
3411 json_object *json_iface = NULL;
3412 json_object *json_row = NULL;
3413
3414 now = pim_time_monotonic_sec();
3415
3416 if (uj)
3417 json = json_object_new_object();
3418 else
3419 vty_out(vty,
3420 "Interface Address Group Mode Timer Srcs V Uptime \n");
3421
3422 /* scan interfaces */
3423 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3424 struct pim_interface *pim_ifp = ifp->info;
3425 struct listnode *sock_node;
3426 struct igmp_sock *igmp;
3427
3428 if (!pim_ifp)
3429 continue;
3430
3431 /* scan igmp sockets */
3432 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3433 igmp)) {
3434 char ifaddr_str[INET_ADDRSTRLEN];
3435 struct listnode *grpnode;
3436 struct igmp_group *grp;
3437
3438 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3439 sizeof(ifaddr_str));
3440
3441 /* scan igmp groups */
3442 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3443 grpnode, grp)) {
3444 char group_str[INET_ADDRSTRLEN];
3445 char hhmmss[10];
3446 char uptime[10];
3447
3448 pim_inet4_dump("<group?>", grp->group_addr,
3449 group_str, sizeof(group_str));
3450 pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
3451 grp->t_group_timer);
3452 pim_time_uptime(uptime, sizeof(uptime),
3453 now - grp->group_creation);
3454
3455 if (uj) {
3456 json_object_object_get_ex(
3457 json, ifp->name, &json_iface);
3458
3459 if (!json_iface) {
3460 json_iface =
3461 json_object_new_object();
3462 json_object_pim_ifp_add(
3463 json_iface, ifp);
3464 json_object_object_add(
3465 json, ifp->name,
3466 json_iface);
3467 }
3468
3469 json_row = json_object_new_object();
3470 json_object_string_add(
3471 json_row, "source", ifaddr_str);
3472 json_object_string_add(
3473 json_row, "group", group_str);
3474
3475 if (grp->igmp_version == 3)
3476 json_object_string_add(
3477 json_row, "mode",
3478 grp->group_filtermode_isexcl
3479 ? "EXCLUDE"
3480 : "INCLUDE");
3481
3482 json_object_string_add(json_row,
3483 "timer", hhmmss);
3484 json_object_int_add(
3485 json_row, "sourcesCount",
3486 grp->group_source_list
3487 ? listcount(
3488 grp->group_source_list)
3489 : 0);
3490 json_object_int_add(json_row, "version",
3491 grp->igmp_version);
3492 json_object_string_add(
3493 json_row, "uptime", uptime);
3494 json_object_object_add(json_iface,
3495 group_str,
3496 json_row);
3497
3498 } else {
3499 vty_out(vty,
3500 "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
3501 ifp->name, ifaddr_str,
3502 group_str,
3503 grp->igmp_version == 3
3504 ? (grp->group_filtermode_isexcl
3505 ? "EXCL"
3506 : "INCL")
3507 : "----",
3508 hhmmss,
3509 grp->group_source_list
3510 ? listcount(
3511 grp->group_source_list)
3512 : 0,
3513 grp->igmp_version, uptime);
3514 }
3515 } /* scan igmp groups */
3516 } /* scan igmp sockets */
3517 } /* scan interfaces */
3518
3519 if (uj) {
3520 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3521 json, JSON_C_TO_STRING_PRETTY));
3522 json_object_free(json);
3523 }
3524 }
3525
3526 static void igmp_show_group_retransmission(struct pim_instance *pim,
3527 struct vty *vty)
3528 {
3529 struct interface *ifp;
3530
3531 vty_out(vty,
3532 "Interface Address Group RetTimer Counter RetSrcs\n");
3533
3534 /* scan interfaces */
3535 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3536 struct pim_interface *pim_ifp = ifp->info;
3537 struct listnode *sock_node;
3538 struct igmp_sock *igmp;
3539
3540 if (!pim_ifp)
3541 continue;
3542
3543 /* scan igmp sockets */
3544 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3545 igmp)) {
3546 char ifaddr_str[INET_ADDRSTRLEN];
3547 struct listnode *grpnode;
3548 struct igmp_group *grp;
3549
3550 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3551 sizeof(ifaddr_str));
3552
3553 /* scan igmp groups */
3554 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3555 grpnode, grp)) {
3556 char group_str[INET_ADDRSTRLEN];
3557 char grp_retr_mmss[10];
3558 struct listnode *src_node;
3559 struct igmp_source *src;
3560 int grp_retr_sources = 0;
3561
3562 pim_inet4_dump("<group?>", grp->group_addr,
3563 group_str, sizeof(group_str));
3564 pim_time_timer_to_mmss(
3565 grp_retr_mmss, sizeof(grp_retr_mmss),
3566 grp->t_group_query_retransmit_timer);
3567
3568
3569 /* count group sources with retransmission state
3570 */
3571 for (ALL_LIST_ELEMENTS_RO(
3572 grp->group_source_list, src_node,
3573 src)) {
3574 if (src->source_query_retransmit_count
3575 > 0) {
3576 ++grp_retr_sources;
3577 }
3578 }
3579
3580 vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
3581 ifp->name, ifaddr_str, group_str,
3582 grp_retr_mmss,
3583 grp->group_specific_query_retransmit_count,
3584 grp_retr_sources);
3585
3586 } /* scan igmp groups */
3587 } /* scan igmp sockets */
3588 } /* scan interfaces */
3589 }
3590
3591 static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
3592 {
3593 struct interface *ifp;
3594 time_t now;
3595
3596 now = pim_time_monotonic_sec();
3597
3598 vty_out(vty,
3599 "Interface Address Group Source Timer Fwd Uptime \n");
3600
3601 /* scan interfaces */
3602 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3603 struct pim_interface *pim_ifp = ifp->info;
3604 struct listnode *sock_node;
3605 struct igmp_sock *igmp;
3606
3607 if (!pim_ifp)
3608 continue;
3609
3610 /* scan igmp sockets */
3611 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3612 igmp)) {
3613 char ifaddr_str[INET_ADDRSTRLEN];
3614 struct listnode *grpnode;
3615 struct igmp_group *grp;
3616
3617 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3618 sizeof(ifaddr_str));
3619
3620 /* scan igmp groups */
3621 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3622 grpnode, grp)) {
3623 char group_str[INET_ADDRSTRLEN];
3624 struct listnode *srcnode;
3625 struct igmp_source *src;
3626
3627 pim_inet4_dump("<group?>", grp->group_addr,
3628 group_str, sizeof(group_str));
3629
3630 /* scan group sources */
3631 for (ALL_LIST_ELEMENTS_RO(
3632 grp->group_source_list, srcnode,
3633 src)) {
3634 char source_str[INET_ADDRSTRLEN];
3635 char mmss[10];
3636 char uptime[10];
3637
3638 pim_inet4_dump(
3639 "<source?>", src->source_addr,
3640 source_str, sizeof(source_str));
3641
3642 pim_time_timer_to_mmss(
3643 mmss, sizeof(mmss),
3644 src->t_source_timer);
3645
3646 pim_time_uptime(
3647 uptime, sizeof(uptime),
3648 now - src->source_creation);
3649
3650 vty_out(vty,
3651 "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
3652 ifp->name, ifaddr_str,
3653 group_str, source_str, mmss,
3654 IGMP_SOURCE_TEST_FORWARDING(
3655 src->source_flags)
3656 ? "Y"
3657 : "N",
3658 uptime);
3659
3660 } /* scan group sources */
3661 } /* scan igmp groups */
3662 } /* scan igmp sockets */
3663 } /* scan interfaces */
3664 }
3665
3666 static void igmp_show_source_retransmission(struct pim_instance *pim,
3667 struct vty *vty)
3668 {
3669 struct interface *ifp;
3670
3671 vty_out(vty,
3672 "Interface Address Group Source Counter\n");
3673
3674 /* scan interfaces */
3675 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3676 struct pim_interface *pim_ifp = ifp->info;
3677 struct listnode *sock_node;
3678 struct igmp_sock *igmp;
3679
3680 if (!pim_ifp)
3681 continue;
3682
3683 /* scan igmp sockets */
3684 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3685 igmp)) {
3686 char ifaddr_str[INET_ADDRSTRLEN];
3687 struct listnode *grpnode;
3688 struct igmp_group *grp;
3689
3690 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
3691 sizeof(ifaddr_str));
3692
3693 /* scan igmp groups */
3694 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
3695 grpnode, grp)) {
3696 char group_str[INET_ADDRSTRLEN];
3697 struct listnode *srcnode;
3698 struct igmp_source *src;
3699
3700 pim_inet4_dump("<group?>", grp->group_addr,
3701 group_str, sizeof(group_str));
3702
3703 /* scan group sources */
3704 for (ALL_LIST_ELEMENTS_RO(
3705 grp->group_source_list, srcnode,
3706 src)) {
3707 char source_str[INET_ADDRSTRLEN];
3708
3709 pim_inet4_dump(
3710 "<source?>", src->source_addr,
3711 source_str, sizeof(source_str));
3712
3713 vty_out(vty,
3714 "%-16s %-15s %-15s %-15s %7d\n",
3715 ifp->name, ifaddr_str,
3716 group_str, source_str,
3717 src->source_query_retransmit_count);
3718
3719 } /* scan group sources */
3720 } /* scan igmp groups */
3721 } /* scan igmp sockets */
3722 } /* scan interfaces */
3723 }
3724
3725 static void pim_show_bsr(struct pim_instance *pim,
3726 struct vty *vty,
3727 bool uj)
3728 {
3729 char uptime[10];
3730 char last_bsm_seen[10];
3731 time_t now;
3732 char bsr_state[20];
3733 char bsr_str[PREFIX_STRLEN];
3734 json_object *json = NULL;
3735
3736 vty_out(vty, "PIMv2 Bootstrap information\n");
3737
3738 if (pim->global_scope.current_bsr.s_addr == INADDR_ANY) {
3739 strlcpy(bsr_str, "0.0.0.0", sizeof(bsr_str));
3740 pim_time_uptime(uptime, sizeof(uptime),
3741 pim->global_scope.current_bsr_first_ts);
3742 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3743 pim->global_scope.current_bsr_last_ts);
3744 }
3745
3746 else {
3747 pim_inet4_dump("<bsr?>", pim->global_scope.current_bsr,
3748 bsr_str, sizeof(bsr_str));
3749 now = pim_time_monotonic_sec();
3750 pim_time_uptime(uptime, sizeof(uptime),
3751 (now - pim->global_scope.current_bsr_first_ts));
3752 pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
3753 now - pim->global_scope.current_bsr_last_ts);
3754 }
3755
3756 switch (pim->global_scope.state) {
3757 case NO_INFO:
3758 strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
3759 break;
3760 case ACCEPT_ANY:
3761 strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
3762 break;
3763 case ACCEPT_PREFERRED:
3764 strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
3765 break;
3766 default:
3767 strlcpy(bsr_state, "", sizeof(bsr_state));
3768 }
3769
3770 if (uj) {
3771 json = json_object_new_object();
3772 json_object_string_add(json, "bsr", bsr_str);
3773 json_object_int_add(json, "priority",
3774 pim->global_scope.current_bsr_prio);
3775 json_object_int_add(json, "fragment_tag",
3776 pim->global_scope.bsm_frag_tag);
3777 json_object_string_add(json, "state", bsr_state);
3778 json_object_string_add(json, "upTime", uptime);
3779 json_object_string_add(json, "last_bsm_seen", last_bsm_seen);
3780 }
3781
3782 else {
3783 vty_out(vty, "Current preferred BSR address: %s\n", bsr_str);
3784 vty_out(vty,
3785 "Priority Fragment-Tag State UpTime\n");
3786 vty_out(vty, " %-12d %-12d %-13s %7s\n",
3787 pim->global_scope.current_bsr_prio,
3788 pim->global_scope.bsm_frag_tag,
3789 bsr_state,
3790 uptime);
3791 vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
3792 }
3793
3794 if (uj) {
3795 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3796 json, JSON_C_TO_STRING_PRETTY));
3797 json_object_free(json);
3798 }
3799 }
3800
3801 static void clear_igmp_interfaces(struct pim_instance *pim)
3802 {
3803 struct interface *ifp;
3804
3805 FOR_ALL_INTERFACES (pim->vrf, ifp)
3806 pim_if_addr_del_all_igmp(ifp);
3807
3808 FOR_ALL_INTERFACES (pim->vrf, ifp)
3809 pim_if_addr_add_all(ifp);
3810 }
3811
3812 static void clear_pim_interfaces(struct pim_instance *pim)
3813 {
3814 struct interface *ifp;
3815
3816 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3817 if (ifp->info) {
3818 pim_neighbor_delete_all(ifp, "interface cleared");
3819 }
3820 }
3821 }
3822
3823 static void clear_interfaces(struct pim_instance *pim)
3824 {
3825 clear_igmp_interfaces(pim);
3826 clear_pim_interfaces(pim);
3827 }
3828
3829 #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
3830 pim_ifp = ifp->info; \
3831 if (!pim_ifp) { \
3832 vty_out(vty, \
3833 "%% Enable PIM and/or IGMP on this interface first\n"); \
3834 return CMD_WARNING_CONFIG_FAILED; \
3835 }
3836
3837 DEFUN (clear_ip_interfaces,
3838 clear_ip_interfaces_cmd,
3839 "clear ip interfaces [vrf NAME]",
3840 CLEAR_STR
3841 IP_STR
3842 "Reset interfaces\n"
3843 VRF_CMD_HELP_STR)
3844 {
3845 int idx = 2;
3846 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3847
3848 if (!vrf)
3849 return CMD_WARNING;
3850
3851 clear_interfaces(vrf->info);
3852
3853 return CMD_SUCCESS;
3854 }
3855
3856 DEFUN (clear_ip_igmp_interfaces,
3857 clear_ip_igmp_interfaces_cmd,
3858 "clear ip igmp [vrf NAME] interfaces",
3859 CLEAR_STR
3860 IP_STR
3861 CLEAR_IP_IGMP_STR
3862 VRF_CMD_HELP_STR
3863 "Reset IGMP interfaces\n")
3864 {
3865 int idx = 2;
3866 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3867
3868 if (!vrf)
3869 return CMD_WARNING;
3870
3871 clear_igmp_interfaces(vrf->info);
3872
3873 return CMD_SUCCESS;
3874 }
3875
3876 DEFUN (clear_ip_pim_statistics,
3877 clear_ip_pim_statistics_cmd,
3878 "clear ip pim statistics [vrf NAME]",
3879 CLEAR_STR
3880 IP_STR
3881 CLEAR_IP_PIM_STR
3882 VRF_CMD_HELP_STR
3883 "Reset PIM statistics\n")
3884 {
3885 int idx = 2;
3886 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3887
3888 if (!vrf)
3889 return CMD_WARNING;
3890
3891 clear_pim_statistics(vrf->info);
3892 return CMD_SUCCESS;
3893 }
3894
3895 static void clear_mroute(struct pim_instance *pim)
3896 {
3897 struct pim_upstream *up;
3898 struct interface *ifp;
3899
3900 /* scan interfaces */
3901 FOR_ALL_INTERFACES (pim->vrf, ifp) {
3902 struct pim_interface *pim_ifp = ifp->info;
3903 struct listnode *sock_node;
3904 struct igmp_sock *igmp;
3905 struct pim_ifchannel *ch;
3906
3907 if (!pim_ifp)
3908 continue;
3909
3910 /* deleting all ifchannels */
3911 while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
3912 ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
3913
3914 pim_ifchannel_delete(ch);
3915 }
3916
3917 /* clean up all igmp groups */
3918 /* scan igmp sockets */
3919 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
3920 igmp)) {
3921
3922 struct igmp_group *grp;
3923
3924 if (igmp->igmp_group_list) {
3925 while (igmp->igmp_group_list->count) {
3926 grp = listnode_head(
3927 igmp->igmp_group_list);
3928 igmp_group_delete(grp);
3929 }
3930 }
3931
3932 }
3933 }
3934
3935 /* clean up all upstreams*/
3936 if (pim->upstream_list) {
3937 while (pim->upstream_list->count) {
3938 up = listnode_head(pim->upstream_list);
3939 pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
3940 }
3941 }
3942 }
3943
3944 DEFUN (clear_ip_mroute,
3945 clear_ip_mroute_cmd,
3946 "clear ip mroute [vrf NAME]",
3947 CLEAR_STR
3948 IP_STR
3949 "Reset multicast routes\n"
3950 VRF_CMD_HELP_STR)
3951 {
3952 int idx = 2;
3953 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3954
3955 if (!vrf)
3956 return CMD_WARNING;
3957
3958 clear_mroute(vrf->info);
3959
3960 return CMD_SUCCESS;
3961 }
3962
3963 DEFUN (clear_ip_pim_interfaces,
3964 clear_ip_pim_interfaces_cmd,
3965 "clear ip pim [vrf NAME] interfaces",
3966 CLEAR_STR
3967 IP_STR
3968 CLEAR_IP_PIM_STR
3969 VRF_CMD_HELP_STR
3970 "Reset PIM interfaces\n")
3971 {
3972 int idx = 2;
3973 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3974
3975 if (!vrf)
3976 return CMD_WARNING;
3977
3978 clear_pim_interfaces(vrf->info);
3979
3980 return CMD_SUCCESS;
3981 }
3982
3983 DEFUN (clear_ip_pim_interface_traffic,
3984 clear_ip_pim_interface_traffic_cmd,
3985 "clear ip pim [vrf NAME] interface traffic",
3986 "Reset functions\n"
3987 "IP information\n"
3988 "PIM clear commands\n"
3989 VRF_CMD_HELP_STR
3990 "Reset PIM interfaces\n"
3991 "Reset Protocol Packet counters\n")
3992 {
3993 int idx = 2;
3994 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
3995 struct interface *ifp = NULL;
3996 struct pim_interface *pim_ifp = NULL;
3997
3998 if (!vrf)
3999 return CMD_WARNING;
4000
4001 FOR_ALL_INTERFACES (vrf, ifp) {
4002 pim_ifp = ifp->info;
4003
4004 if (!pim_ifp)
4005 continue;
4006
4007 pim_ifp->pim_ifstat_hello_recv = 0;
4008 pim_ifp->pim_ifstat_hello_sent = 0;
4009 pim_ifp->pim_ifstat_join_recv = 0;
4010 pim_ifp->pim_ifstat_join_send = 0;
4011 pim_ifp->pim_ifstat_prune_recv = 0;
4012 pim_ifp->pim_ifstat_prune_send = 0;
4013 pim_ifp->pim_ifstat_reg_recv = 0;
4014 pim_ifp->pim_ifstat_reg_send = 0;
4015 pim_ifp->pim_ifstat_reg_stop_recv = 0;
4016 pim_ifp->pim_ifstat_reg_stop_send = 0;
4017 pim_ifp->pim_ifstat_assert_recv = 0;
4018 pim_ifp->pim_ifstat_assert_send = 0;
4019 pim_ifp->pim_ifstat_bsm_rx = 0;
4020 pim_ifp->pim_ifstat_bsm_tx = 0;
4021 }
4022
4023 return CMD_SUCCESS;
4024 }
4025
4026 DEFUN (clear_ip_pim_oil,
4027 clear_ip_pim_oil_cmd,
4028 "clear ip pim [vrf NAME] oil",
4029 CLEAR_STR
4030 IP_STR
4031 CLEAR_IP_PIM_STR
4032 VRF_CMD_HELP_STR
4033 "Rescan PIM OIL (output interface list)\n")
4034 {
4035 int idx = 2;
4036 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4037
4038 if (!vrf)
4039 return CMD_WARNING;
4040
4041 pim_scan_oil(vrf->info);
4042
4043 return CMD_SUCCESS;
4044 }
4045
4046 DEFUN (show_ip_igmp_interface,
4047 show_ip_igmp_interface_cmd,
4048 "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
4049 SHOW_STR
4050 IP_STR
4051 IGMP_STR
4052 VRF_CMD_HELP_STR
4053 "IGMP interface information\n"
4054 "Detailed output\n"
4055 "interface name\n"
4056 JSON_STR)
4057 {
4058 int idx = 2;
4059 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4060 bool uj = use_json(argc, argv);
4061
4062 if (!vrf)
4063 return CMD_WARNING;
4064
4065 if (argv_find(argv, argc, "detail", &idx)
4066 || argv_find(argv, argc, "WORD", &idx))
4067 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
4068 else
4069 igmp_show_interfaces(vrf->info, vty, uj);
4070
4071 return CMD_SUCCESS;
4072 }
4073
4074 DEFUN (show_ip_igmp_interface_vrf_all,
4075 show_ip_igmp_interface_vrf_all_cmd,
4076 "show ip igmp vrf all interface [detail|WORD] [json]",
4077 SHOW_STR
4078 IP_STR
4079 IGMP_STR
4080 VRF_CMD_HELP_STR
4081 "IGMP interface information\n"
4082 "Detailed output\n"
4083 "interface name\n"
4084 JSON_STR)
4085 {
4086 int idx = 2;
4087 bool uj = use_json(argc, argv);
4088 struct vrf *vrf;
4089 bool first = true;
4090
4091 if (uj)
4092 vty_out(vty, "{ ");
4093 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4094 if (uj) {
4095 if (!first)
4096 vty_out(vty, ", ");
4097 vty_out(vty, " \"%s\": ", vrf->name);
4098 first = false;
4099 } else
4100 vty_out(vty, "VRF: %s\n", vrf->name);
4101 if (argv_find(argv, argc, "detail", &idx)
4102 || argv_find(argv, argc, "WORD", &idx))
4103 igmp_show_interfaces_single(vrf->info, vty,
4104 argv[idx]->arg, uj);
4105 else
4106 igmp_show_interfaces(vrf->info, vty, uj);
4107 }
4108 if (uj)
4109 vty_out(vty, "}\n");
4110
4111 return CMD_SUCCESS;
4112 }
4113
4114 DEFUN (show_ip_igmp_join,
4115 show_ip_igmp_join_cmd,
4116 "show ip igmp [vrf NAME] join",
4117 SHOW_STR
4118 IP_STR
4119 IGMP_STR
4120 VRF_CMD_HELP_STR
4121 "IGMP static join information\n")
4122 {
4123 int idx = 2;
4124 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4125
4126 if (!vrf)
4127 return CMD_WARNING;
4128
4129 igmp_show_interface_join(vrf->info, vty);
4130
4131 return CMD_SUCCESS;
4132 }
4133
4134 DEFUN (show_ip_igmp_join_vrf_all,
4135 show_ip_igmp_join_vrf_all_cmd,
4136 "show ip igmp vrf all join",
4137 SHOW_STR
4138 IP_STR
4139 IGMP_STR
4140 VRF_CMD_HELP_STR
4141 "IGMP static join information\n")
4142 {
4143 bool uj = use_json(argc, argv);
4144 struct vrf *vrf;
4145 bool first = true;
4146
4147 if (uj)
4148 vty_out(vty, "{ ");
4149 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4150 if (uj) {
4151 if (!first)
4152 vty_out(vty, ", ");
4153 vty_out(vty, " \"%s\": ", vrf->name);
4154 first = false;
4155 } else
4156 vty_out(vty, "VRF: %s\n", vrf->name);
4157 igmp_show_interface_join(vrf->info, vty);
4158 }
4159 if (uj)
4160 vty_out(vty, "}\n");
4161
4162 return CMD_SUCCESS;
4163 }
4164
4165 DEFUN (show_ip_igmp_groups,
4166 show_ip_igmp_groups_cmd,
4167 "show ip igmp [vrf NAME] groups [json]",
4168 SHOW_STR
4169 IP_STR
4170 IGMP_STR
4171 VRF_CMD_HELP_STR
4172 IGMP_GROUP_STR
4173 JSON_STR)
4174 {
4175 int idx = 2;
4176 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4177 bool uj = use_json(argc, argv);
4178
4179 if (!vrf)
4180 return CMD_WARNING;
4181
4182 igmp_show_groups(vrf->info, vty, uj);
4183
4184 return CMD_SUCCESS;
4185 }
4186
4187 DEFUN (show_ip_igmp_groups_vrf_all,
4188 show_ip_igmp_groups_vrf_all_cmd,
4189 "show ip igmp vrf all groups [json]",
4190 SHOW_STR
4191 IP_STR
4192 IGMP_STR
4193 VRF_CMD_HELP_STR
4194 IGMP_GROUP_STR
4195 JSON_STR)
4196 {
4197 bool uj = use_json(argc, argv);
4198 struct vrf *vrf;
4199 bool first = true;
4200
4201 if (uj)
4202 vty_out(vty, "{ ");
4203 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4204 if (uj) {
4205 if (!first)
4206 vty_out(vty, ", ");
4207 vty_out(vty, " \"%s\": ", vrf->name);
4208 first = false;
4209 } else
4210 vty_out(vty, "VRF: %s\n", vrf->name);
4211 igmp_show_groups(vrf->info, vty, uj);
4212 }
4213 if (uj)
4214 vty_out(vty, "}\n");
4215
4216 return CMD_SUCCESS;
4217 }
4218
4219 DEFUN (show_ip_igmp_groups_retransmissions,
4220 show_ip_igmp_groups_retransmissions_cmd,
4221 "show ip igmp [vrf NAME] groups retransmissions",
4222 SHOW_STR
4223 IP_STR
4224 IGMP_STR
4225 VRF_CMD_HELP_STR
4226 IGMP_GROUP_STR
4227 "IGMP group retransmissions\n")
4228 {
4229 int idx = 2;
4230 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4231
4232 if (!vrf)
4233 return CMD_WARNING;
4234
4235 igmp_show_group_retransmission(vrf->info, vty);
4236
4237 return CMD_SUCCESS;
4238 }
4239
4240 DEFUN (show_ip_igmp_sources,
4241 show_ip_igmp_sources_cmd,
4242 "show ip igmp [vrf NAME] sources",
4243 SHOW_STR
4244 IP_STR
4245 IGMP_STR
4246 VRF_CMD_HELP_STR
4247 IGMP_SOURCE_STR)
4248 {
4249 int idx = 2;
4250 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4251
4252 if (!vrf)
4253 return CMD_WARNING;
4254
4255 igmp_show_sources(vrf->info, vty);
4256
4257 return CMD_SUCCESS;
4258 }
4259
4260 DEFUN (show_ip_igmp_sources_retransmissions,
4261 show_ip_igmp_sources_retransmissions_cmd,
4262 "show ip igmp [vrf NAME] sources retransmissions",
4263 SHOW_STR
4264 IP_STR
4265 IGMP_STR
4266 VRF_CMD_HELP_STR
4267 IGMP_SOURCE_STR
4268 "IGMP source retransmissions\n")
4269 {
4270 int idx = 2;
4271 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4272
4273 if (!vrf)
4274 return CMD_WARNING;
4275
4276 igmp_show_source_retransmission(vrf->info, vty);
4277
4278 return CMD_SUCCESS;
4279 }
4280
4281 DEFUN (show_ip_igmp_statistics,
4282 show_ip_igmp_statistics_cmd,
4283 "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
4284 SHOW_STR
4285 IP_STR
4286 IGMP_STR
4287 VRF_CMD_HELP_STR
4288 "IGMP statistics\n"
4289 "interface\n"
4290 "IGMP interface\n"
4291 JSON_STR)
4292 {
4293 int idx = 2;
4294 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4295 bool uj = use_json(argc, argv);
4296
4297 if (!vrf)
4298 return CMD_WARNING;
4299
4300 if (argv_find(argv, argc, "WORD", &idx))
4301 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
4302 else
4303 igmp_show_statistics(vrf->info, vty, NULL, uj);
4304
4305 return CMD_SUCCESS;
4306 }
4307
4308 DEFUN (show_ip_pim_assert,
4309 show_ip_pim_assert_cmd,
4310 "show ip pim [vrf NAME] assert",
4311 SHOW_STR
4312 IP_STR
4313 PIM_STR
4314 VRF_CMD_HELP_STR
4315 "PIM interface assert\n")
4316 {
4317 int idx = 2;
4318 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4319
4320 if (!vrf)
4321 return CMD_WARNING;
4322
4323 pim_show_assert(vrf->info, vty);
4324
4325 return CMD_SUCCESS;
4326 }
4327
4328 DEFUN (show_ip_pim_assert_internal,
4329 show_ip_pim_assert_internal_cmd,
4330 "show ip pim [vrf NAME] assert-internal",
4331 SHOW_STR
4332 IP_STR
4333 PIM_STR
4334 VRF_CMD_HELP_STR
4335 "PIM interface internal assert state\n")
4336 {
4337 int idx = 2;
4338 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4339
4340 if (!vrf)
4341 return CMD_WARNING;
4342
4343 pim_show_assert_internal(vrf->info, vty);
4344
4345 return CMD_SUCCESS;
4346 }
4347
4348 DEFUN (show_ip_pim_assert_metric,
4349 show_ip_pim_assert_metric_cmd,
4350 "show ip pim [vrf NAME] assert-metric",
4351 SHOW_STR
4352 IP_STR
4353 PIM_STR
4354 VRF_CMD_HELP_STR
4355 "PIM interface assert metric\n")
4356 {
4357 int idx = 2;
4358 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4359
4360 if (!vrf)
4361 return CMD_WARNING;
4362
4363 pim_show_assert_metric(vrf->info, vty);
4364
4365 return CMD_SUCCESS;
4366 }
4367
4368 DEFUN (show_ip_pim_assert_winner_metric,
4369 show_ip_pim_assert_winner_metric_cmd,
4370 "show ip pim [vrf NAME] assert-winner-metric",
4371 SHOW_STR
4372 IP_STR
4373 PIM_STR
4374 VRF_CMD_HELP_STR
4375 "PIM interface assert winner metric\n")
4376 {
4377 int idx = 2;
4378 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4379
4380 if (!vrf)
4381 return CMD_WARNING;
4382
4383 pim_show_assert_winner_metric(vrf->info, vty);
4384
4385 return CMD_SUCCESS;
4386 }
4387
4388 DEFUN (show_ip_pim_interface,
4389 show_ip_pim_interface_cmd,
4390 "show ip pim [vrf NAME] interface [detail|WORD] [json]",
4391 SHOW_STR
4392 IP_STR
4393 PIM_STR
4394 VRF_CMD_HELP_STR
4395 "PIM interface information\n"
4396 "Detailed output\n"
4397 "interface name\n"
4398 JSON_STR)
4399 {
4400 int idx = 2;
4401 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4402 bool uj = use_json(argc, argv);
4403
4404 if (!vrf)
4405 return CMD_WARNING;
4406
4407 if (argv_find(argv, argc, "WORD", &idx)
4408 || argv_find(argv, argc, "detail", &idx))
4409 pim_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
4410 else
4411 pim_show_interfaces(vrf->info, vty, uj);
4412
4413 return CMD_SUCCESS;
4414 }
4415
4416 DEFUN (show_ip_pim_interface_vrf_all,
4417 show_ip_pim_interface_vrf_all_cmd,
4418 "show ip pim vrf all interface [detail|WORD] [json]",
4419 SHOW_STR
4420 IP_STR
4421 PIM_STR
4422 VRF_CMD_HELP_STR
4423 "PIM interface information\n"
4424 "Detailed output\n"
4425 "interface name\n"
4426 JSON_STR)
4427 {
4428 int idx = 6;
4429 bool uj = use_json(argc, argv);
4430 struct vrf *vrf;
4431 bool first = true;
4432
4433 if (uj)
4434 vty_out(vty, "{ ");
4435 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4436 if (uj) {
4437 if (!first)
4438 vty_out(vty, ", ");
4439 vty_out(vty, " \"%s\": ", vrf->name);
4440 first = false;
4441 } else
4442 vty_out(vty, "VRF: %s\n", vrf->name);
4443 if (argv_find(argv, argc, "WORD", &idx)
4444 || argv_find(argv, argc, "detail", &idx))
4445 pim_show_interfaces_single(vrf->info, vty,
4446 argv[idx]->arg, uj);
4447 else
4448 pim_show_interfaces(vrf->info, vty, uj);
4449 }
4450 if (uj)
4451 vty_out(vty, "}\n");
4452
4453 return CMD_SUCCESS;
4454 }
4455
4456 DEFPY (show_ip_pim_join,
4457 show_ip_pim_join_cmd,
4458 "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4459 SHOW_STR
4460 IP_STR
4461 PIM_STR
4462 VRF_CMD_HELP_STR
4463 "PIM interface join information\n"
4464 "The Source or Group\n"
4465 "The Group\n"
4466 JSON_STR)
4467 {
4468 struct prefix_sg sg = {0};
4469 struct vrf *v;
4470 bool uj = !!json;
4471 struct pim_instance *pim;
4472
4473 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4474
4475 if (!v) {
4476 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4477 return CMD_WARNING;
4478 }
4479 pim = pim_get_pim_instance(v->vrf_id);
4480
4481 if (!pim) {
4482 vty_out(vty, "%% Unable to find pim instance\n");
4483 return CMD_WARNING;
4484 }
4485
4486 if (s_or_g.s_addr != 0) {
4487 if (g.s_addr != 0) {
4488 sg.src = s_or_g;
4489 sg.grp = g;
4490 } else
4491 sg.grp = s_or_g;
4492 }
4493
4494 pim_show_join(pim, vty, &sg, uj);
4495
4496 return CMD_SUCCESS;
4497 }
4498
4499 DEFUN (show_ip_pim_join_vrf_all,
4500 show_ip_pim_join_vrf_all_cmd,
4501 "show ip pim vrf all join [json]",
4502 SHOW_STR
4503 IP_STR
4504 PIM_STR
4505 VRF_CMD_HELP_STR
4506 "PIM interface join information\n"
4507 JSON_STR)
4508 {
4509 struct prefix_sg sg = {0};
4510 bool uj = use_json(argc, argv);
4511 struct vrf *vrf;
4512 bool first = true;
4513
4514 if (uj)
4515 vty_out(vty, "{ ");
4516 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4517 if (uj) {
4518 if (!first)
4519 vty_out(vty, ", ");
4520 vty_out(vty, " \"%s\": ", vrf->name);
4521 first = false;
4522 } else
4523 vty_out(vty, "VRF: %s\n", vrf->name);
4524 pim_show_join(vrf->info, vty, &sg, uj);
4525 }
4526 if (uj)
4527 vty_out(vty, "}\n");
4528
4529 return CMD_WARNING;
4530 }
4531
4532 static void pim_show_jp_agg_helper(struct vty *vty,
4533 struct interface *ifp,
4534 struct pim_neighbor *neigh,
4535 struct pim_upstream *up,
4536 int is_join)
4537 {
4538 char src_str[INET_ADDRSTRLEN];
4539 char grp_str[INET_ADDRSTRLEN];
4540 char rpf_str[INET_ADDRSTRLEN];
4541
4542 pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
4543 pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
4544 /* pius->address.s_addr */
4545 pim_inet4_dump("<rpf?>", neigh->source_addr, rpf_str, sizeof(rpf_str));
4546
4547 vty_out(vty, "%-16s %-15s %-15s %-15s %5s\n",
4548 ifp->name, rpf_str, src_str,
4549 grp_str, is_join?"J":"P");
4550 }
4551
4552 static void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
4553 {
4554 struct interface *ifp;
4555 struct pim_interface *pim_ifp;
4556 struct listnode *n_node;
4557 struct pim_neighbor *neigh;
4558 struct listnode *jag_node;
4559 struct pim_jp_agg_group *jag;
4560 struct listnode *js_node;
4561 struct pim_jp_sources *js;
4562
4563 vty_out(vty,
4564 "Interface RPF Nbr Source Group State\n");
4565
4566 FOR_ALL_INTERFACES (pim->vrf, ifp) {
4567 pim_ifp = ifp->info;
4568 if (!pim_ifp)
4569 continue;
4570
4571 for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
4572 n_node, neigh)) {
4573 for (ALL_LIST_ELEMENTS_RO(neigh->upstream_jp_agg,
4574 jag_node, jag)) {
4575 for (ALL_LIST_ELEMENTS_RO(jag->sources,
4576 js_node, js)) {
4577 pim_show_jp_agg_helper(vty,
4578 ifp, neigh, js->up,
4579 js->is_join);
4580 }
4581 }
4582 }
4583 }
4584 }
4585
4586 DEFPY (show_ip_pim_jp_agg,
4587 show_ip_pim_jp_agg_cmd,
4588 "show ip pim [vrf NAME] jp-agg",
4589 SHOW_STR
4590 IP_STR
4591 PIM_STR
4592 VRF_CMD_HELP_STR
4593 "join prune aggregation list\n")
4594 {
4595 struct vrf *v;
4596 struct pim_instance *pim;
4597
4598 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4599
4600 if (!v) {
4601 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4602 return CMD_WARNING;
4603 }
4604 pim = pim_get_pim_instance(v->vrf_id);
4605
4606 if (!pim) {
4607 vty_out(vty, "%% Unable to find pim instance\n");
4608 return CMD_WARNING;
4609 }
4610
4611 pim_show_jp_agg_list(pim, vty);
4612
4613 return CMD_SUCCESS;
4614 }
4615
4616 DEFUN (show_ip_pim_local_membership,
4617 show_ip_pim_local_membership_cmd,
4618 "show ip pim [vrf NAME] local-membership [json]",
4619 SHOW_STR
4620 IP_STR
4621 PIM_STR
4622 VRF_CMD_HELP_STR
4623 "PIM interface local-membership\n"
4624 JSON_STR)
4625 {
4626 int idx = 2;
4627 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4628 bool uj = use_json(argc, argv);
4629
4630 if (!vrf)
4631 return CMD_WARNING;
4632
4633 pim_show_membership(vrf->info, vty, uj);
4634
4635 return CMD_SUCCESS;
4636 }
4637
4638 DEFUN (show_ip_pim_neighbor,
4639 show_ip_pim_neighbor_cmd,
4640 "show ip pim [vrf NAME] neighbor [detail|WORD] [json]",
4641 SHOW_STR
4642 IP_STR
4643 PIM_STR
4644 VRF_CMD_HELP_STR
4645 "PIM neighbor information\n"
4646 "Detailed output\n"
4647 "Name of interface or neighbor\n"
4648 JSON_STR)
4649 {
4650 int idx = 2;
4651 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4652 bool uj = use_json(argc, argv);
4653
4654 if (!vrf)
4655 return CMD_WARNING;
4656
4657 if (argv_find(argv, argc, "detail", &idx)
4658 || argv_find(argv, argc, "WORD", &idx))
4659 pim_show_neighbors_single(vrf->info, vty, argv[idx]->arg, uj);
4660 else
4661 pim_show_neighbors(vrf->info, vty, uj);
4662
4663 return CMD_SUCCESS;
4664 }
4665
4666 DEFUN (show_ip_pim_neighbor_vrf_all,
4667 show_ip_pim_neighbor_vrf_all_cmd,
4668 "show ip pim vrf all neighbor [detail|WORD] [json]",
4669 SHOW_STR
4670 IP_STR
4671 PIM_STR
4672 VRF_CMD_HELP_STR
4673 "PIM neighbor information\n"
4674 "Detailed output\n"
4675 "Name of interface or neighbor\n"
4676 JSON_STR)
4677 {
4678 int idx = 2;
4679 bool uj = use_json(argc, argv);
4680 struct vrf *vrf;
4681 bool first = true;
4682
4683 if (uj)
4684 vty_out(vty, "{ ");
4685 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4686 if (uj) {
4687 if (!first)
4688 vty_out(vty, ", ");
4689 vty_out(vty, " \"%s\": ", vrf->name);
4690 first = false;
4691 } else
4692 vty_out(vty, "VRF: %s\n", vrf->name);
4693 if (argv_find(argv, argc, "detail", &idx)
4694 || argv_find(argv, argc, "WORD", &idx))
4695 pim_show_neighbors_single(vrf->info, vty,
4696 argv[idx]->arg, uj);
4697 else
4698 pim_show_neighbors(vrf->info, vty, uj);
4699 }
4700 if (uj)
4701 vty_out(vty, "}\n");
4702
4703 return CMD_SUCCESS;
4704 }
4705
4706 DEFUN (show_ip_pim_secondary,
4707 show_ip_pim_secondary_cmd,
4708 "show ip pim [vrf NAME] secondary",
4709 SHOW_STR
4710 IP_STR
4711 PIM_STR
4712 VRF_CMD_HELP_STR
4713 "PIM neighbor addresses\n")
4714 {
4715 int idx = 2;
4716 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4717
4718 if (!vrf)
4719 return CMD_WARNING;
4720
4721 pim_show_neighbors_secondary(vrf->info, vty);
4722
4723 return CMD_SUCCESS;
4724 }
4725
4726 DEFUN (show_ip_pim_state,
4727 show_ip_pim_state_cmd,
4728 "show ip pim [vrf NAME] state [A.B.C.D [A.B.C.D]] [json]",
4729 SHOW_STR
4730 IP_STR
4731 PIM_STR
4732 VRF_CMD_HELP_STR
4733 "PIM state information\n"
4734 "Unicast or Multicast address\n"
4735 "Multicast address\n"
4736 JSON_STR)
4737 {
4738 const char *src_or_group = NULL;
4739 const char *group = NULL;
4740 int idx = 2;
4741 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4742 bool uj = use_json(argc, argv);
4743
4744 if (!vrf)
4745 return CMD_WARNING;
4746
4747 if (uj)
4748 argc--;
4749
4750 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4751 src_or_group = argv[idx]->arg;
4752 if (idx + 1 < argc)
4753 group = argv[idx + 1]->arg;
4754 }
4755
4756 pim_show_state(vrf->info, vty, src_or_group, group, uj);
4757
4758 return CMD_SUCCESS;
4759 }
4760
4761 DEFUN (show_ip_pim_state_vrf_all,
4762 show_ip_pim_state_vrf_all_cmd,
4763 "show ip pim vrf all state [A.B.C.D [A.B.C.D]] [json]",
4764 SHOW_STR
4765 IP_STR
4766 PIM_STR
4767 VRF_CMD_HELP_STR
4768 "PIM state information\n"
4769 "Unicast or Multicast address\n"
4770 "Multicast address\n"
4771 JSON_STR)
4772 {
4773 const char *src_or_group = NULL;
4774 const char *group = NULL;
4775 int idx = 2;
4776 bool uj = use_json(argc, argv);
4777 struct vrf *vrf;
4778 bool first = true;
4779
4780 if (uj) {
4781 vty_out(vty, "{ ");
4782 argc--;
4783 }
4784
4785 if (argv_find(argv, argc, "A.B.C.D", &idx)) {
4786 src_or_group = argv[idx]->arg;
4787 if (idx + 1 < argc)
4788 group = argv[idx + 1]->arg;
4789 }
4790
4791 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4792 if (uj) {
4793 if (!first)
4794 vty_out(vty, ", ");
4795 vty_out(vty, " \"%s\": ", vrf->name);
4796 first = false;
4797 } else
4798 vty_out(vty, "VRF: %s\n", vrf->name);
4799 pim_show_state(vrf->info, vty, src_or_group, group, uj);
4800 }
4801 if (uj)
4802 vty_out(vty, "}\n");
4803
4804 return CMD_SUCCESS;
4805 }
4806
4807 DEFPY (show_ip_pim_upstream,
4808 show_ip_pim_upstream_cmd,
4809 "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
4810 SHOW_STR
4811 IP_STR
4812 PIM_STR
4813 VRF_CMD_HELP_STR
4814 "PIM upstream information\n"
4815 "The Source or Group\n"
4816 "The Group\n"
4817 JSON_STR)
4818 {
4819 struct prefix_sg sg = {0};
4820 struct vrf *v;
4821 bool uj = !!json;
4822 struct pim_instance *pim;
4823
4824 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
4825
4826 if (!v) {
4827 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
4828 return CMD_WARNING;
4829 }
4830 pim = pim_get_pim_instance(v->vrf_id);
4831
4832 if (!pim) {
4833 vty_out(vty, "%% Unable to find pim instance\n");
4834 return CMD_WARNING;
4835 }
4836
4837 if (s_or_g.s_addr != 0) {
4838 if (g.s_addr != 0) {
4839 sg.src = s_or_g;
4840 sg.grp = g;
4841 } else
4842 sg.grp = s_or_g;
4843 }
4844 pim_show_upstream(pim, vty, &sg, uj);
4845
4846 return CMD_SUCCESS;
4847 }
4848
4849 DEFUN (show_ip_pim_upstream_vrf_all,
4850 show_ip_pim_upstream_vrf_all_cmd,
4851 "show ip pim vrf all upstream [json]",
4852 SHOW_STR
4853 IP_STR
4854 PIM_STR
4855 VRF_CMD_HELP_STR
4856 "PIM upstream information\n"
4857 JSON_STR)
4858 {
4859 struct prefix_sg sg = {0};
4860 bool uj = use_json(argc, argv);
4861 struct vrf *vrf;
4862 bool first = true;
4863
4864 if (uj)
4865 vty_out(vty, "{ ");
4866 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4867 if (uj) {
4868 if (!first)
4869 vty_out(vty, ", ");
4870 vty_out(vty, " \"%s\": ", vrf->name);
4871 first = false;
4872 } else
4873 vty_out(vty, "VRF: %s\n", vrf->name);
4874 pim_show_upstream(vrf->info, vty, &sg, uj);
4875 }
4876
4877 return CMD_SUCCESS;
4878 }
4879
4880 DEFUN (show_ip_pim_channel,
4881 show_ip_pim_channel_cmd,
4882 "show ip pim [vrf NAME] channel [json]",
4883 SHOW_STR
4884 IP_STR
4885 PIM_STR
4886 VRF_CMD_HELP_STR
4887 "PIM downstream channel info\n"
4888 JSON_STR)
4889 {
4890 int idx = 2;
4891 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4892 bool uj = use_json(argc, argv);
4893
4894 if (!vrf)
4895 return CMD_WARNING;
4896
4897 pim_show_channel(vrf->info, vty, uj);
4898
4899 return CMD_SUCCESS;
4900 }
4901
4902 DEFUN (show_ip_pim_upstream_join_desired,
4903 show_ip_pim_upstream_join_desired_cmd,
4904 "show ip pim [vrf NAME] upstream-join-desired [json]",
4905 SHOW_STR
4906 IP_STR
4907 PIM_STR
4908 VRF_CMD_HELP_STR
4909 "PIM upstream join-desired\n"
4910 JSON_STR)
4911 {
4912 int idx = 2;
4913 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4914 bool uj = use_json(argc, argv);
4915
4916 if (!vrf)
4917 return CMD_WARNING;
4918
4919 pim_show_join_desired(vrf->info, vty, uj);
4920
4921 return CMD_SUCCESS;
4922 }
4923
4924 DEFUN (show_ip_pim_upstream_rpf,
4925 show_ip_pim_upstream_rpf_cmd,
4926 "show ip pim [vrf NAME] upstream-rpf [json]",
4927 SHOW_STR
4928 IP_STR
4929 PIM_STR
4930 VRF_CMD_HELP_STR
4931 "PIM upstream source rpf\n"
4932 JSON_STR)
4933 {
4934 int idx = 2;
4935 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4936 bool uj = use_json(argc, argv);
4937
4938 if (!vrf)
4939 return CMD_WARNING;
4940
4941 pim_show_upstream_rpf(vrf->info, vty, uj);
4942
4943 return CMD_SUCCESS;
4944 }
4945
4946 DEFUN (show_ip_pim_rp,
4947 show_ip_pim_rp_cmd,
4948 "show ip pim [vrf NAME] rp-info [json]",
4949 SHOW_STR
4950 IP_STR
4951 PIM_STR
4952 VRF_CMD_HELP_STR
4953 "PIM RP information\n"
4954 JSON_STR)
4955 {
4956 int idx = 2;
4957 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
4958 bool uj = use_json(argc, argv);
4959
4960 if (!vrf)
4961 return CMD_WARNING;
4962
4963 pim_rp_show_information(vrf->info, vty, uj);
4964
4965 return CMD_SUCCESS;
4966 }
4967
4968 DEFUN (show_ip_pim_rp_vrf_all,
4969 show_ip_pim_rp_vrf_all_cmd,
4970 "show ip pim vrf all rp-info [json]",
4971 SHOW_STR
4972 IP_STR
4973 PIM_STR
4974 VRF_CMD_HELP_STR
4975 "PIM RP information\n"
4976 JSON_STR)
4977 {
4978 bool uj = use_json(argc, argv);
4979 struct vrf *vrf;
4980 bool first = true;
4981
4982 if (uj)
4983 vty_out(vty, "{ ");
4984 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
4985 if (uj) {
4986 if (!first)
4987 vty_out(vty, ", ");
4988 vty_out(vty, " \"%s\": ", vrf->name);
4989 first = false;
4990 } else
4991 vty_out(vty, "VRF: %s\n", vrf->name);
4992 pim_rp_show_information(vrf->info, vty, uj);
4993 }
4994 if (uj)
4995 vty_out(vty, "}\n");
4996
4997 return CMD_SUCCESS;
4998 }
4999
5000 DEFUN (show_ip_pim_rpf,
5001 show_ip_pim_rpf_cmd,
5002 "show ip pim [vrf NAME] rpf [json]",
5003 SHOW_STR
5004 IP_STR
5005 PIM_STR
5006 VRF_CMD_HELP_STR
5007 "PIM cached source rpf information\n"
5008 JSON_STR)
5009 {
5010 int idx = 2;
5011 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5012 bool uj = use_json(argc, argv);
5013
5014 if (!vrf)
5015 return CMD_WARNING;
5016
5017 pim_show_rpf(vrf->info, vty, uj);
5018
5019 return CMD_SUCCESS;
5020 }
5021
5022 DEFUN (show_ip_pim_rpf_vrf_all,
5023 show_ip_pim_rpf_vrf_all_cmd,
5024 "show ip pim vrf all rpf [json]",
5025 SHOW_STR
5026 IP_STR
5027 PIM_STR
5028 VRF_CMD_HELP_STR
5029 "PIM cached source rpf information\n"
5030 JSON_STR)
5031 {
5032 bool uj = use_json(argc, argv);
5033 struct vrf *vrf;
5034 bool first = true;
5035
5036 if (uj)
5037 vty_out(vty, "{ ");
5038 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5039 if (uj) {
5040 if (!first)
5041 vty_out(vty, ", ");
5042 vty_out(vty, " \"%s\": ", vrf->name);
5043 first = false;
5044 } else
5045 vty_out(vty, "VRF: %s\n", vrf->name);
5046 pim_show_rpf(vrf->info, vty, uj);
5047 }
5048 if (uj)
5049 vty_out(vty, "}\n");
5050
5051 return CMD_SUCCESS;
5052 }
5053
5054 DEFUN (show_ip_pim_nexthop,
5055 show_ip_pim_nexthop_cmd,
5056 "show ip pim [vrf NAME] nexthop",
5057 SHOW_STR
5058 IP_STR
5059 PIM_STR
5060 VRF_CMD_HELP_STR
5061 "PIM cached nexthop rpf information\n")
5062 {
5063 int idx = 2;
5064 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5065
5066 if (!vrf)
5067 return CMD_WARNING;
5068
5069 pim_show_nexthop(vrf->info, vty);
5070
5071 return CMD_SUCCESS;
5072 }
5073
5074 DEFUN (show_ip_pim_nexthop_lookup,
5075 show_ip_pim_nexthop_lookup_cmd,
5076 "show ip pim [vrf NAME] nexthop-lookup A.B.C.D A.B.C.D",
5077 SHOW_STR
5078 IP_STR
5079 PIM_STR
5080 VRF_CMD_HELP_STR
5081 "PIM cached nexthop rpf lookup\n"
5082 "Source/RP address\n"
5083 "Multicast Group address\n")
5084 {
5085 struct prefix nht_p;
5086 int result = 0;
5087 struct in_addr src_addr, grp_addr;
5088 struct in_addr vif_source;
5089 const char *addr_str, *addr_str1;
5090 struct prefix grp;
5091 struct pim_nexthop nexthop;
5092 char nexthop_addr_str[PREFIX_STRLEN];
5093 char grp_str[PREFIX_STRLEN];
5094 int idx = 2;
5095 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5096
5097 if (!vrf)
5098 return CMD_WARNING;
5099
5100 argv_find(argv, argc, "A.B.C.D", &idx);
5101 addr_str = argv[idx]->arg;
5102 result = inet_pton(AF_INET, addr_str, &src_addr);
5103 if (result <= 0) {
5104 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5105 errno, safe_strerror(errno));
5106 return CMD_WARNING;
5107 }
5108
5109 if (pim_is_group_224_4(src_addr)) {
5110 vty_out(vty,
5111 "Invalid argument. Expected Valid Source Address.\n");
5112 return CMD_WARNING;
5113 }
5114
5115 addr_str1 = argv[idx + 1]->arg;
5116 result = inet_pton(AF_INET, addr_str1, &grp_addr);
5117 if (result <= 0) {
5118 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
5119 errno, safe_strerror(errno));
5120 return CMD_WARNING;
5121 }
5122
5123 if (!pim_is_group_224_4(grp_addr)) {
5124 vty_out(vty,
5125 "Invalid argument. Expected Valid Multicast Group Address.\n");
5126 return CMD_WARNING;
5127 }
5128
5129 if (!pim_rp_set_upstream_addr(vrf->info, &vif_source, src_addr,
5130 grp_addr))
5131 return CMD_SUCCESS;
5132
5133 nht_p.family = AF_INET;
5134 nht_p.prefixlen = IPV4_MAX_BITLEN;
5135 nht_p.u.prefix4 = vif_source;
5136 grp.family = AF_INET;
5137 grp.prefixlen = IPV4_MAX_BITLEN;
5138 grp.u.prefix4 = grp_addr;
5139 memset(&nexthop, 0, sizeof(nexthop));
5140
5141 result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, &nht_p, &grp, 0);
5142
5143 if (!result) {
5144 vty_out(vty,
5145 "Nexthop Lookup failed, no usable routes returned.\n");
5146 return CMD_SUCCESS;
5147 }
5148
5149 pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
5150 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
5151 nexthop_addr_str, sizeof(nexthop_addr_str));
5152 vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
5153 nexthop_addr_str, nexthop.interface->name);
5154
5155 return CMD_SUCCESS;
5156 }
5157
5158 DEFUN (show_ip_pim_interface_traffic,
5159 show_ip_pim_interface_traffic_cmd,
5160 "show ip pim [vrf NAME] interface traffic [WORD] [json]",
5161 SHOW_STR
5162 IP_STR
5163 PIM_STR
5164 VRF_CMD_HELP_STR
5165 "PIM interface information\n"
5166 "Protocol Packet counters\n"
5167 "Interface name\n"
5168 JSON_STR)
5169 {
5170 int idx = 2;
5171 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5172 bool uj = use_json(argc, argv);
5173
5174 if (!vrf)
5175 return CMD_WARNING;
5176
5177 if (argv_find(argv, argc, "WORD", &idx))
5178 pim_show_interface_traffic_single(vrf->info, vty,
5179 argv[idx]->arg, uj);
5180 else
5181 pim_show_interface_traffic(vrf->info, vty, uj);
5182
5183 return CMD_SUCCESS;
5184 }
5185
5186 DEFUN (show_ip_pim_bsm_db,
5187 show_ip_pim_bsm_db_cmd,
5188 "show ip pim bsm-database [vrf NAME] [json]",
5189 SHOW_STR
5190 IP_STR
5191 PIM_STR
5192 "PIM cached bsm packets information\n"
5193 VRF_CMD_HELP_STR
5194 JSON_STR)
5195 {
5196 int idx = 2;
5197 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5198 bool uj = use_json(argc, argv);
5199
5200 if (!vrf)
5201 return CMD_WARNING;
5202
5203 pim_show_bsm_db(vrf->info, vty, uj);
5204 return CMD_SUCCESS;
5205 }
5206
5207 DEFUN (show_ip_pim_bsrp,
5208 show_ip_pim_bsrp_cmd,
5209 "show ip pim bsrp-info [vrf NAME] [json]",
5210 SHOW_STR
5211 IP_STR
5212 PIM_STR
5213 "PIM cached group-rp mappings information\n"
5214 VRF_CMD_HELP_STR
5215 JSON_STR)
5216 {
5217 int idx = 2;
5218 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5219 bool uj = use_json(argc, argv);
5220
5221 if (!vrf)
5222 return CMD_WARNING;
5223
5224 pim_show_group_rp_mappings_info(vrf->info, vty, uj);
5225
5226 return CMD_SUCCESS;
5227 }
5228
5229 DEFUN (show_ip_pim_statistics,
5230 show_ip_pim_statistics_cmd,
5231 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
5232 SHOW_STR
5233 IP_STR
5234 PIM_STR
5235 VRF_CMD_HELP_STR
5236 "PIM statistics\n"
5237 INTERFACE_STR
5238 "PIM interface\n"
5239 JSON_STR)
5240 {
5241 int idx = 2;
5242 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5243 bool uj = use_json(argc, argv);
5244
5245 if (!vrf)
5246 return CMD_WARNING;
5247
5248 if (argv_find(argv, argc, "WORD", &idx))
5249 pim_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
5250 else
5251 pim_show_statistics(vrf->info, vty, NULL, uj);
5252
5253 return CMD_SUCCESS;
5254 }
5255
5256 static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty)
5257 {
5258 struct interface *ifp;
5259
5260 vty_out(vty, "\n");
5261
5262 vty_out(vty,
5263 "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
5264
5265 FOR_ALL_INTERFACES (pim->vrf, ifp) {
5266 struct pim_interface *pim_ifp;
5267 struct in_addr ifaddr;
5268 struct sioc_vif_req vreq;
5269
5270 pim_ifp = ifp->info;
5271
5272 if (!pim_ifp)
5273 continue;
5274
5275 memset(&vreq, 0, sizeof(vreq));
5276 vreq.vifi = pim_ifp->mroute_vif_index;
5277
5278 if (ioctl(pim->mroute_socket, SIOCGETVIFCNT, &vreq)) {
5279 zlog_warn(
5280 "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s",
5281 (unsigned long)SIOCGETVIFCNT, ifp->name,
5282 pim_ifp->mroute_vif_index, errno,
5283 safe_strerror(errno));
5284 }
5285
5286 ifaddr = pim_ifp->primary_address;
5287
5288 vty_out(vty, "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
5289 ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
5290 pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
5291 (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
5292 (unsigned long)vreq.obytes);
5293 }
5294 }
5295
5296 static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
5297 struct vty *vty)
5298 {
5299 struct vrf *vrf = pim->vrf;
5300 time_t now = pim_time_monotonic_sec();
5301 char uptime[10];
5302 char mlag_role[80];
5303
5304 pim = vrf->info;
5305
5306 vty_out(vty, "Router MLAG Role: %s\n",
5307 mlag_role2str(router->role, mlag_role, sizeof(mlag_role)));
5308 vty_out(vty, "Mroute socket descriptor:");
5309
5310 vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
5311
5312 pim_time_uptime(uptime, sizeof(uptime),
5313 now - pim->mroute_socket_creation);
5314 vty_out(vty, "Mroute socket uptime: %s\n", uptime);
5315
5316 vty_out(vty, "\n");
5317
5318 pim_zebra_zclient_update(vty);
5319 pim_zlookup_show_ip_multicast(vty);
5320
5321 vty_out(vty, "\n");
5322 vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
5323
5324 vty_out(vty, "\n");
5325 vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
5326 vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
5327 vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
5328 vty_out(vty, "PIM ECMP Rebalance: %s\n",
5329 pim->ecmp_rebalance_enable ? "Enable" : "Disable");
5330
5331 vty_out(vty, "\n");
5332
5333 show_rpf_refresh_stats(vty, pim, now, NULL);
5334
5335 vty_out(vty, "\n");
5336
5337 show_scan_oil_stats(pim, vty, now);
5338
5339 show_multicast_interfaces(pim, vty);
5340 }
5341
5342 DEFUN (show_ip_multicast,
5343 show_ip_multicast_cmd,
5344 "show ip multicast [vrf NAME]",
5345 SHOW_STR
5346 IP_STR
5347 VRF_CMD_HELP_STR
5348 "Multicast global information\n")
5349 {
5350 int idx = 2;
5351 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5352
5353 if (!vrf)
5354 return CMD_WARNING;
5355
5356 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5357
5358 return CMD_SUCCESS;
5359 }
5360
5361 DEFUN (show_ip_multicast_vrf_all,
5362 show_ip_multicast_vrf_all_cmd,
5363 "show ip multicast vrf all",
5364 SHOW_STR
5365 IP_STR
5366 VRF_CMD_HELP_STR
5367 "Multicast global information\n")
5368 {
5369 bool uj = use_json(argc, argv);
5370 struct vrf *vrf;
5371 bool first = true;
5372
5373 if (uj)
5374 vty_out(vty, "{ ");
5375 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5376 if (uj) {
5377 if (!first)
5378 vty_out(vty, ", ");
5379 vty_out(vty, " \"%s\": ", vrf->name);
5380 first = false;
5381 } else
5382 vty_out(vty, "VRF: %s\n", vrf->name);
5383 pim_cmd_show_ip_multicast_helper(vrf->info, vty);
5384 }
5385 if (uj)
5386 vty_out(vty, "}\n");
5387
5388 return CMD_SUCCESS;
5389 }
5390
5391 static void show_mroute(struct pim_instance *pim, struct vty *vty,
5392 struct prefix_sg *sg, bool fill, bool uj)
5393 {
5394 struct listnode *node;
5395 struct channel_oil *c_oil;
5396 struct static_route *s_route;
5397 time_t now;
5398 json_object *json = NULL;
5399 json_object *json_group = NULL;
5400 json_object *json_source = NULL;
5401 json_object *json_oil = NULL;
5402 json_object *json_ifp_out = NULL;
5403 int found_oif;
5404 int first;
5405 char grp_str[INET_ADDRSTRLEN];
5406 char src_str[INET_ADDRSTRLEN];
5407 char in_ifname[INTERFACE_NAMSIZ + 1];
5408 char out_ifname[INTERFACE_NAMSIZ + 1];
5409 int oif_vif_index;
5410 struct interface *ifp_in;
5411 char proto[100];
5412
5413 if (uj) {
5414 json = json_object_new_object();
5415 } else {
5416 vty_out(vty,
5417 "Source Group Proto Input Output TTL Uptime\n");
5418 }
5419
5420 now = pim_time_monotonic_sec();
5421
5422 /* print list of PIM and IGMP routes */
5423 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
5424 found_oif = 0;
5425 first = 1;
5426 if (!c_oil->installed && !uj)
5427 continue;
5428
5429 if (sg->grp.s_addr != 0 &&
5430 sg->grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr)
5431 continue;
5432 if (sg->src.s_addr != 0 &&
5433 sg->src.s_addr != c_oil->oil.mfcc_origin.s_addr)
5434 continue;
5435
5436 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
5437 sizeof(grp_str));
5438 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
5439 sizeof(src_str));
5440 ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent);
5441
5442 if (ifp_in)
5443 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
5444 else
5445 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
5446
5447 if (uj) {
5448
5449 /* Find the group, create it if it doesn't exist */
5450 json_object_object_get_ex(json, grp_str, &json_group);
5451
5452 if (!json_group) {
5453 json_group = json_object_new_object();
5454 json_object_object_add(json, grp_str,
5455 json_group);
5456 }
5457
5458 /* Find the source nested under the group, create it if
5459 * it doesn't exist */
5460 json_object_object_get_ex(json_group, src_str,
5461 &json_source);
5462
5463 if (!json_source) {
5464 json_source = json_object_new_object();
5465 json_object_object_add(json_group, src_str,
5466 json_source);
5467 }
5468
5469 /* Find the inbound interface nested under the source,
5470 * create it if it doesn't exist */
5471 json_object_int_add(json_source, "installed",
5472 c_oil->installed);
5473 json_object_int_add(json_source, "refCount",
5474 c_oil->oil_ref_count);
5475 json_object_int_add(json_source, "oilSize",
5476 c_oil->oil_size);
5477 json_object_int_add(json_source, "OilInheritedRescan",
5478 c_oil->oil_inherited_rescan);
5479 json_object_string_add(json_source, "iif", in_ifname);
5480 json_oil = NULL;
5481 }
5482
5483 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5484 ++oif_vif_index) {
5485 struct interface *ifp_out;
5486 char mroute_uptime[10];
5487 int ttl;
5488
5489 ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
5490 if (ttl < 1)
5491 continue;
5492
5493 /* do not display muted OIFs */
5494 if (c_oil->oif_flags[oif_vif_index]
5495 & PIM_OIF_FLAG_MUTE)
5496 continue;
5497
5498 if (c_oil->oil.mfcc_parent == oif_vif_index &&
5499 !pim_mroute_allow_iif_in_oil(c_oil,
5500 oif_vif_index))
5501 continue;
5502
5503 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
5504 pim_time_uptime(
5505 mroute_uptime, sizeof(mroute_uptime),
5506 now - c_oil->mroute_creation);
5507 found_oif = 1;
5508
5509 if (ifp_out)
5510 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
5511 else
5512 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
5513
5514 if (uj) {
5515 json_ifp_out = json_object_new_object();
5516 json_object_string_add(json_ifp_out, "source",
5517 src_str);
5518 json_object_string_add(json_ifp_out, "group",
5519 grp_str);
5520
5521 if (c_oil->oif_flags[oif_vif_index]
5522 & PIM_OIF_FLAG_PROTO_PIM)
5523 json_object_boolean_true_add(
5524 json_ifp_out, "protocolPim");
5525
5526 if (c_oil->oif_flags[oif_vif_index]
5527 & PIM_OIF_FLAG_PROTO_IGMP)
5528 json_object_boolean_true_add(
5529 json_ifp_out, "protocolIgmp");
5530
5531 if (c_oil->oif_flags[oif_vif_index]
5532 & PIM_OIF_FLAG_PROTO_VXLAN)
5533 json_object_boolean_true_add(
5534 json_ifp_out, "protocolVxlan");
5535
5536 if (c_oil->oif_flags[oif_vif_index]
5537 & PIM_OIF_FLAG_PROTO_STAR)
5538 json_object_boolean_true_add(
5539 json_ifp_out,
5540 "protocolInherited");
5541
5542 json_object_string_add(json_ifp_out,
5543 "inboundInterface",
5544 in_ifname);
5545 json_object_int_add(json_ifp_out, "iVifI",
5546 c_oil->oil.mfcc_parent);
5547 json_object_string_add(json_ifp_out,
5548 "outboundInterface",
5549 out_ifname);
5550 json_object_int_add(json_ifp_out, "oVifI",
5551 oif_vif_index);
5552 json_object_int_add(json_ifp_out, "ttl", ttl);
5553 json_object_string_add(json_ifp_out, "upTime",
5554 mroute_uptime);
5555 if (!json_oil) {
5556 json_oil = json_object_new_object();
5557 json_object_object_add(json_source,
5558 "oil", json_oil);
5559 }
5560 json_object_object_add(json_oil, out_ifname,
5561 json_ifp_out);
5562 } else {
5563 if (c_oil->oif_flags[oif_vif_index]
5564 & PIM_OIF_FLAG_PROTO_PIM) {
5565 strlcpy(proto, "PIM", sizeof(proto));
5566 }
5567
5568 if (c_oil->oif_flags[oif_vif_index]
5569 & PIM_OIF_FLAG_PROTO_IGMP) {
5570 strlcpy(proto, "IGMP", sizeof(proto));
5571 }
5572
5573 if (c_oil->oif_flags[oif_vif_index]
5574 & PIM_OIF_FLAG_PROTO_VXLAN) {
5575 strlcpy(proto, "VxLAN", sizeof(proto));
5576 }
5577
5578 if (c_oil->oif_flags[oif_vif_index]
5579 & PIM_OIF_FLAG_PROTO_STAR) {
5580 strlcpy(proto, "STAR", sizeof(proto));
5581 }
5582
5583 vty_out(vty,
5584 "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5585 src_str, grp_str, proto, in_ifname,
5586 out_ifname, ttl, mroute_uptime);
5587
5588 if (first) {
5589 src_str[0] = '\0';
5590 grp_str[0] = '\0';
5591 in_ifname[0] = '\0';
5592 first = 0;
5593 }
5594 }
5595 }
5596
5597 if (!uj && !found_oif) {
5598 vty_out(vty, "%-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
5599 src_str, grp_str, "none", in_ifname, "none", 0,
5600 "--:--:--");
5601 }
5602 }
5603
5604 /* Print list of static routes */
5605 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5606 first = 1;
5607
5608 if (!s_route->c_oil.installed)
5609 continue;
5610
5611 pim_inet4_dump("<group?>", s_route->group, grp_str,
5612 sizeof(grp_str));
5613 pim_inet4_dump("<source?>", s_route->source, src_str,
5614 sizeof(src_str));
5615 ifp_in = pim_if_find_by_vif_index(pim, s_route->iif);
5616 found_oif = 0;
5617
5618 if (ifp_in)
5619 strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname));
5620 else
5621 strlcpy(in_ifname, "<iif?>", sizeof(in_ifname));
5622
5623 if (uj) {
5624
5625 /* Find the group, create it if it doesn't exist */
5626 json_object_object_get_ex(json, grp_str, &json_group);
5627
5628 if (!json_group) {
5629 json_group = json_object_new_object();
5630 json_object_object_add(json, grp_str,
5631 json_group);
5632 }
5633
5634 /* Find the source nested under the group, create it if
5635 * it doesn't exist */
5636 json_object_object_get_ex(json_group, src_str,
5637 &json_source);
5638
5639 if (!json_source) {
5640 json_source = json_object_new_object();
5641 json_object_object_add(json_group, src_str,
5642 json_source);
5643 }
5644
5645 json_object_string_add(json_source, "iif", in_ifname);
5646 json_oil = NULL;
5647 } else {
5648 strlcpy(proto, "STATIC", sizeof(proto));
5649 }
5650
5651 for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
5652 ++oif_vif_index) {
5653 struct interface *ifp_out;
5654 char oif_uptime[10];
5655 int ttl;
5656
5657 ttl = s_route->oif_ttls[oif_vif_index];
5658 if (ttl < 1)
5659 continue;
5660
5661 ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
5662 pim_time_uptime(
5663 oif_uptime, sizeof(oif_uptime),
5664 now
5665 - s_route->c_oil
5666 .oif_creation[oif_vif_index]);
5667 found_oif = 1;
5668
5669 if (ifp_out)
5670 strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname));
5671 else
5672 strlcpy(out_ifname, "<oif?>", sizeof(out_ifname));
5673
5674 if (uj) {
5675 json_ifp_out = json_object_new_object();
5676 json_object_string_add(json_ifp_out, "source",
5677 src_str);
5678 json_object_string_add(json_ifp_out, "group",
5679 grp_str);
5680 json_object_boolean_true_add(json_ifp_out,
5681 "protocolStatic");
5682 json_object_string_add(json_ifp_out,
5683 "inboundInterface",
5684 in_ifname);
5685 json_object_int_add(
5686 json_ifp_out, "iVifI",
5687 s_route->c_oil.oil.mfcc_parent);
5688 json_object_string_add(json_ifp_out,
5689 "outboundInterface",
5690 out_ifname);
5691 json_object_int_add(json_ifp_out, "oVifI",
5692 oif_vif_index);
5693 json_object_int_add(json_ifp_out, "ttl", ttl);
5694 json_object_string_add(json_ifp_out, "upTime",
5695 oif_uptime);
5696 if (!json_oil) {
5697 json_oil = json_object_new_object();
5698 json_object_object_add(json_source,
5699 "oil", json_oil);
5700 }
5701 json_object_object_add(json_oil, out_ifname,
5702 json_ifp_out);
5703 } else {
5704 vty_out(vty,
5705 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5706 src_str, grp_str, proto, in_ifname,
5707 out_ifname, ttl, oif_uptime,
5708 pim->vrf->name);
5709 if (first && !fill) {
5710 src_str[0] = '\0';
5711 grp_str[0] = '\0';
5712 in_ifname[0] = '\0';
5713 first = 0;
5714 }
5715 }
5716 }
5717
5718 if (!uj && !found_oif) {
5719 vty_out(vty,
5720 "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
5721 src_str, grp_str, proto, in_ifname, "none", 0,
5722 "--:--:--", pim->vrf->name);
5723 }
5724 }
5725
5726 if (uj) {
5727 vty_out(vty, "%s\n", json_object_to_json_string_ext(
5728 json, JSON_C_TO_STRING_PRETTY));
5729 json_object_free(json);
5730 }
5731 }
5732
5733 DEFPY (show_ip_mroute,
5734 show_ip_mroute_cmd,
5735 "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
5736 SHOW_STR
5737 IP_STR
5738 MROUTE_STR
5739 VRF_CMD_HELP_STR
5740 "The Source or Group\n"
5741 "The Group\n"
5742 "Fill in Assumed data\n"
5743 JSON_STR)
5744 {
5745 struct prefix_sg sg = {0};
5746 struct pim_instance *pim;
5747 struct vrf *v;
5748
5749 v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
5750
5751 if (!v) {
5752 vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
5753 return CMD_WARNING;
5754 }
5755 pim = pim_get_pim_instance(v->vrf_id);
5756
5757 if (!pim) {
5758 vty_out(vty, "%% Unable to find pim instance\n");
5759 return CMD_WARNING;
5760 }
5761
5762 if (s_or_g.s_addr != 0) {
5763 if (g.s_addr != 0) {
5764 sg.src = s_or_g;
5765 sg.grp = g;
5766 } else
5767 sg.grp = s_or_g;
5768 }
5769 show_mroute(pim, vty, &sg, !!fill, !!json);
5770 return CMD_SUCCESS;
5771 }
5772
5773 DEFUN (show_ip_mroute_vrf_all,
5774 show_ip_mroute_vrf_all_cmd,
5775 "show ip mroute vrf all [fill] [json]",
5776 SHOW_STR
5777 IP_STR
5778 MROUTE_STR
5779 VRF_CMD_HELP_STR
5780 "Fill in Assumed data\n"
5781 JSON_STR)
5782 {
5783 struct prefix_sg sg = {0};
5784 bool uj = use_json(argc, argv);
5785 int idx = 4;
5786 struct vrf *vrf;
5787 bool first = true;
5788 bool fill = false;
5789
5790 if (argv_find(argv, argc, "fill", &idx))
5791 fill = true;
5792
5793 if (uj)
5794 vty_out(vty, "{ ");
5795 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5796 if (uj) {
5797 if (!first)
5798 vty_out(vty, ", ");
5799 vty_out(vty, " \"%s\": ", vrf->name);
5800 first = false;
5801 } else
5802 vty_out(vty, "VRF: %s\n", vrf->name);
5803 show_mroute(vrf->info, vty, &sg, fill, uj);
5804 }
5805 if (uj)
5806 vty_out(vty, "}\n");
5807
5808 return CMD_SUCCESS;
5809 }
5810
5811 DEFUN (clear_ip_mroute_count,
5812 clear_ip_mroute_count_cmd,
5813 "clear ip mroute [vrf NAME] count",
5814 CLEAR_STR
5815 IP_STR
5816 MROUTE_STR
5817 VRF_CMD_HELP_STR
5818 "Route and packet count data\n")
5819 {
5820 int idx = 2;
5821 struct listnode *node;
5822 struct channel_oil *c_oil;
5823 struct static_route *sr;
5824 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5825 struct pim_instance *pim;
5826
5827 if (!vrf)
5828 return CMD_WARNING;
5829
5830 pim = vrf->info;
5831 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
5832 if (!c_oil->installed)
5833 continue;
5834
5835 pim_mroute_update_counters(c_oil);
5836 c_oil->cc.origpktcnt = c_oil->cc.pktcnt;
5837 c_oil->cc.origbytecnt = c_oil->cc.bytecnt;
5838 c_oil->cc.origwrong_if = c_oil->cc.wrong_if;
5839 }
5840
5841 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
5842 if (!sr->c_oil.installed)
5843 continue;
5844
5845 pim_mroute_update_counters(&sr->c_oil);
5846
5847 sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt;
5848 sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt;
5849 sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if;
5850 }
5851 return CMD_SUCCESS;
5852 }
5853
5854 static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
5855 {
5856 struct listnode *node;
5857 struct channel_oil *c_oil;
5858 struct static_route *sr;
5859
5860 vty_out(vty, "\n");
5861
5862 vty_out(vty,
5863 "Source Group LastUsed Packets Bytes WrongIf \n");
5864
5865 /* Print PIM and IGMP route counts */
5866 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
5867 char group_str[INET_ADDRSTRLEN];
5868 char source_str[INET_ADDRSTRLEN];
5869
5870 if (!c_oil->installed)
5871 continue;
5872
5873 pim_mroute_update_counters(c_oil);
5874
5875 pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
5876 sizeof(group_str));
5877 pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
5878 sizeof(source_str));
5879
5880 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5881 source_str, group_str, c_oil->cc.lastused / 100,
5882 c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
5883 c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
5884 c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
5885 }
5886
5887 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) {
5888 char group_str[INET_ADDRSTRLEN];
5889 char source_str[INET_ADDRSTRLEN];
5890
5891 if (!sr->c_oil.installed)
5892 continue;
5893
5894 pim_mroute_update_counters(&sr->c_oil);
5895
5896 pim_inet4_dump("<group?>", sr->c_oil.oil.mfcc_mcastgrp,
5897 group_str, sizeof(group_str));
5898 pim_inet4_dump("<source?>", sr->c_oil.oil.mfcc_origin,
5899 source_str, sizeof(source_str));
5900
5901 vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
5902 source_str, group_str, sr->c_oil.cc.lastused,
5903 sr->c_oil.cc.pktcnt - sr->c_oil.cc.origpktcnt,
5904 sr->c_oil.cc.bytecnt - sr->c_oil.cc.origbytecnt,
5905 sr->c_oil.cc.wrong_if - sr->c_oil.cc.origwrong_if);
5906 }
5907 }
5908
5909 DEFUN (show_ip_mroute_count,
5910 show_ip_mroute_count_cmd,
5911 "show ip mroute [vrf NAME] count",
5912 SHOW_STR
5913 IP_STR
5914 MROUTE_STR
5915 VRF_CMD_HELP_STR
5916 "Route and packet count data\n")
5917 {
5918 int idx = 2;
5919 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5920
5921 if (!vrf)
5922 return CMD_WARNING;
5923
5924 show_mroute_count(vrf->info, vty);
5925 return CMD_SUCCESS;
5926 }
5927
5928 DEFUN (show_ip_mroute_count_vrf_all,
5929 show_ip_mroute_count_vrf_all_cmd,
5930 "show ip mroute vrf all count",
5931 SHOW_STR
5932 IP_STR
5933 MROUTE_STR
5934 VRF_CMD_HELP_STR
5935 "Route and packet count data\n")
5936 {
5937 bool uj = use_json(argc, argv);
5938 struct vrf *vrf;
5939 bool first = true;
5940
5941 if (uj)
5942 vty_out(vty, "{ ");
5943 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5944 if (uj) {
5945 if (!first)
5946 vty_out(vty, ", ");
5947 vty_out(vty, " \"%s\": ", vrf->name);
5948 first = false;
5949 } else
5950 vty_out(vty, "VRF: %s\n", vrf->name);
5951 show_mroute_count(vrf->info, vty);
5952 }
5953 if (uj)
5954 vty_out(vty, "}\n");
5955
5956 return CMD_SUCCESS;
5957 }
5958
5959 static void show_mroute_summary(struct pim_instance *pim, struct vty *vty)
5960 {
5961 struct listnode *node;
5962 struct channel_oil *c_oil;
5963 struct static_route *s_route;
5964 uint32_t starg_sw_mroute_cnt = 0;
5965 uint32_t sg_sw_mroute_cnt = 0;
5966 uint32_t starg_hw_mroute_cnt = 0;
5967 uint32_t sg_hw_mroute_cnt = 0;
5968
5969 vty_out(vty, "Mroute Type Installed/Total\n");
5970
5971 for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) {
5972 if (!c_oil->installed) {
5973 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5974 starg_sw_mroute_cnt++;
5975 else
5976 sg_sw_mroute_cnt++;
5977 } else {
5978 if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
5979 starg_hw_mroute_cnt++;
5980 else
5981 sg_hw_mroute_cnt++;
5982 }
5983 }
5984
5985 for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) {
5986 if (!s_route->c_oil.installed) {
5987 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5988 starg_sw_mroute_cnt++;
5989 else
5990 sg_sw_mroute_cnt++;
5991 } else {
5992 if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY)
5993 starg_hw_mroute_cnt++;
5994 else
5995 sg_hw_mroute_cnt++;
5996 }
5997 }
5998
5999 vty_out(vty, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt,
6000 starg_sw_mroute_cnt + starg_hw_mroute_cnt);
6001 vty_out(vty, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt,
6002 sg_sw_mroute_cnt + sg_hw_mroute_cnt);
6003 vty_out(vty, "------\n");
6004 vty_out(vty, "%-20s %d/%d\n", "Total",
6005 (starg_hw_mroute_cnt + sg_hw_mroute_cnt),
6006 (starg_sw_mroute_cnt +
6007 starg_hw_mroute_cnt +
6008 sg_sw_mroute_cnt +
6009 sg_hw_mroute_cnt));
6010 }
6011
6012 DEFUN (show_ip_mroute_summary,
6013 show_ip_mroute_summary_cmd,
6014 "show ip mroute [vrf NAME] summary",
6015 SHOW_STR
6016 IP_STR
6017 MROUTE_STR
6018 VRF_CMD_HELP_STR
6019 "Summary of all mroutes\n")
6020 {
6021 int idx = 2;
6022 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6023
6024 if (!vrf)
6025 return CMD_WARNING;
6026
6027 show_mroute_summary(vrf->info, vty);
6028 return CMD_SUCCESS;
6029 }
6030
6031 DEFUN (show_ip_mroute_summary_vrf_all,
6032 show_ip_mroute_summary_vrf_all_cmd,
6033 "show ip mroute vrf all summary",
6034 SHOW_STR
6035 IP_STR
6036 MROUTE_STR
6037 VRF_CMD_HELP_STR
6038 "Summary of all mroutes\n")
6039 {
6040 struct vrf *vrf;
6041
6042 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
6043 vty_out(vty, "VRF: %s\n", vrf->name);
6044 show_mroute_summary(vrf->info, vty);
6045 }
6046
6047 return CMD_SUCCESS;
6048 }
6049
6050 DEFUN (show_ip_rib,
6051 show_ip_rib_cmd,
6052 "show ip rib [vrf NAME] A.B.C.D",
6053 SHOW_STR
6054 IP_STR
6055 RIB_STR
6056 VRF_CMD_HELP_STR
6057 "Unicast address\n")
6058 {
6059 int idx = 2;
6060 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6061 struct in_addr addr;
6062 const char *addr_str;
6063 struct pim_nexthop nexthop;
6064 char nexthop_addr_str[PREFIX_STRLEN];
6065 int result;
6066
6067 if (!vrf)
6068 return CMD_WARNING;
6069
6070 memset(&nexthop, 0, sizeof(nexthop));
6071 argv_find(argv, argc, "A.B.C.D", &idx);
6072 addr_str = argv[idx]->arg;
6073 result = inet_pton(AF_INET, addr_str, &addr);
6074 if (result <= 0) {
6075 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
6076 errno, safe_strerror(errno));
6077 return CMD_WARNING;
6078 }
6079
6080 if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
6081 vty_out(vty,
6082 "Failure querying RIB nexthop for unicast address %s\n",
6083 addr_str);
6084 return CMD_WARNING;
6085 }
6086
6087 vty_out(vty,
6088 "Address NextHop Interface Metric Preference\n");
6089
6090 pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
6091 nexthop_addr_str, sizeof(nexthop_addr_str));
6092
6093 vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
6094 nexthop.interface ? nexthop.interface->name : "<ifname?>",
6095 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
6096
6097 return CMD_SUCCESS;
6098 }
6099
6100 static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
6101 {
6102 struct listnode *node;
6103 struct ssmpingd_sock *ss;
6104 time_t now;
6105
6106 vty_out(vty,
6107 "Source Socket Address Port Uptime Requests\n");
6108
6109 if (!pim->ssmpingd_list)
6110 return;
6111
6112 now = pim_time_monotonic_sec();
6113
6114 for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
6115 char source_str[INET_ADDRSTRLEN];
6116 char ss_uptime[10];
6117 struct sockaddr_in bind_addr;
6118 socklen_t len = sizeof(bind_addr);
6119 char bind_addr_str[INET_ADDRSTRLEN];
6120
6121 pim_inet4_dump("<src?>", ss->source_addr, source_str,
6122 sizeof(source_str));
6123
6124 if (pim_socket_getsockname(
6125 ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
6126 vty_out(vty,
6127 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
6128 source_str, ss->sock_fd);
6129 }
6130
6131 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
6132 sizeof(bind_addr_str));
6133 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
6134 now - ss->creation);
6135
6136 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
6137 ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
6138 ss_uptime, (long long)ss->requests);
6139 }
6140 }
6141
6142 DEFUN (show_ip_ssmpingd,
6143 show_ip_ssmpingd_cmd,
6144 "show ip ssmpingd [vrf NAME]",
6145 SHOW_STR
6146 IP_STR
6147 SHOW_SSMPINGD_STR
6148 VRF_CMD_HELP_STR)
6149 {
6150 int idx = 2;
6151 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6152
6153 if (!vrf)
6154 return CMD_WARNING;
6155
6156 show_ssmpingd(vrf->info, vty);
6157 return CMD_SUCCESS;
6158 }
6159
6160 static int pim_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
6161 const char *rp, const char *group,
6162 const char *plist)
6163 {
6164 int result;
6165
6166 result = pim_rp_new_config(pim, rp, group, plist);
6167
6168 if (result == PIM_GROUP_BAD_ADDR_MASK_COMBO) {
6169 vty_out(vty, "%% Inconsistent address and mask: %s\n",
6170 group);
6171 return CMD_WARNING_CONFIG_FAILED;
6172 }
6173
6174 if (result == PIM_GROUP_BAD_ADDRESS) {
6175 vty_out(vty, "%% Bad group address specified: %s\n", group);
6176 return CMD_WARNING_CONFIG_FAILED;
6177 }
6178
6179 if (result == PIM_RP_BAD_ADDRESS) {
6180 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
6181 return CMD_WARNING_CONFIG_FAILED;
6182 }
6183
6184 if (result == PIM_RP_NO_PATH) {
6185 vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
6186 return CMD_WARNING;
6187 }
6188
6189 if (result == PIM_GROUP_OVERLAP) {
6190 vty_out(vty,
6191 "%% Group range specified cannot exact match another\n");
6192 return CMD_WARNING_CONFIG_FAILED;
6193 }
6194
6195 if (result == PIM_GROUP_PFXLIST_OVERLAP) {
6196 vty_out(vty,
6197 "%% This group is already covered by a RP prefix-list\n");
6198 return CMD_WARNING_CONFIG_FAILED;
6199 }
6200
6201 if (result == PIM_RP_PFXLIST_IN_USE) {
6202 vty_out(vty,
6203 "%% The same prefix-list cannot be applied to multiple RPs\n");
6204 return CMD_WARNING_CONFIG_FAILED;
6205 }
6206
6207 return CMD_SUCCESS;
6208 }
6209
6210 static int pim_cmd_spt_switchover(struct pim_instance *pim,
6211 enum pim_spt_switchover spt,
6212 const char *plist)
6213 {
6214 pim->spt.switchover = spt;
6215
6216 switch (pim->spt.switchover) {
6217 case PIM_SPT_IMMEDIATE:
6218 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
6219
6220 pim_upstream_add_lhr_star_pimreg(pim);
6221 break;
6222 case PIM_SPT_INFINITY:
6223 pim_upstream_remove_lhr_star_pimreg(pim, plist);
6224
6225 XFREE(MTYPE_PIM_SPT_PLIST_NAME, pim->spt.plist);
6226
6227 if (plist)
6228 pim->spt.plist =
6229 XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
6230 break;
6231 }
6232
6233 return CMD_SUCCESS;
6234 }
6235
6236 DEFUN (ip_pim_spt_switchover_infinity,
6237 ip_pim_spt_switchover_infinity_cmd,
6238 "ip pim spt-switchover infinity-and-beyond",
6239 IP_STR
6240 PIM_STR
6241 "SPT-Switchover\n"
6242 "Never switch to SPT Tree\n")
6243 {
6244 PIM_DECLVAR_CONTEXT(vrf, pim);
6245 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, NULL);
6246 }
6247
6248 DEFUN (ip_pim_spt_switchover_infinity_plist,
6249 ip_pim_spt_switchover_infinity_plist_cmd,
6250 "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6251 IP_STR
6252 PIM_STR
6253 "SPT-Switchover\n"
6254 "Never switch to SPT Tree\n"
6255 "Prefix-List to control which groups to switch\n"
6256 "Prefix-List name\n")
6257 {
6258 PIM_DECLVAR_CONTEXT(vrf, pim);
6259 return pim_cmd_spt_switchover(pim, PIM_SPT_INFINITY, argv[5]->arg);
6260 }
6261
6262 DEFUN (no_ip_pim_spt_switchover_infinity,
6263 no_ip_pim_spt_switchover_infinity_cmd,
6264 "no ip pim spt-switchover infinity-and-beyond",
6265 NO_STR
6266 IP_STR
6267 PIM_STR
6268 "SPT_Switchover\n"
6269 "Never switch to SPT Tree\n")
6270 {
6271 PIM_DECLVAR_CONTEXT(vrf, pim);
6272 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
6273 }
6274
6275 DEFUN (no_ip_pim_spt_switchover_infinity_plist,
6276 no_ip_pim_spt_switchover_infinity_plist_cmd,
6277 "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
6278 NO_STR
6279 IP_STR
6280 PIM_STR
6281 "SPT_Switchover\n"
6282 "Never switch to SPT Tree\n"
6283 "Prefix-List to control which groups to switch\n"
6284 "Prefix-List name\n")
6285 {
6286 PIM_DECLVAR_CONTEXT(vrf, pim);
6287 return pim_cmd_spt_switchover(pim, PIM_SPT_IMMEDIATE, NULL);
6288 }
6289
6290 DEFUN (ip_pim_joinprune_time,
6291 ip_pim_joinprune_time_cmd,
6292 "ip pim join-prune-interval (60-600)",
6293 IP_STR
6294 "pim multicast routing\n"
6295 "Join Prune Send Interval\n"
6296 "Seconds\n")
6297 {
6298 PIM_DECLVAR_CONTEXT(vrf, pim);
6299 router->t_periodic = atoi(argv[3]->arg);
6300 return CMD_SUCCESS;
6301 }
6302
6303 DEFUN (no_ip_pim_joinprune_time,
6304 no_ip_pim_joinprune_time_cmd,
6305 "no ip pim join-prune-interval (60-600)",
6306 NO_STR
6307 IP_STR
6308 "pim multicast routing\n"
6309 "Join Prune Send Interval\n"
6310 "Seconds\n")
6311 {
6312 PIM_DECLVAR_CONTEXT(vrf, pim);
6313 router->t_periodic = PIM_DEFAULT_T_PERIODIC;
6314 return CMD_SUCCESS;
6315 }
6316
6317 DEFUN (ip_pim_register_suppress,
6318 ip_pim_register_suppress_cmd,
6319 "ip pim register-suppress-time (5-60000)",
6320 IP_STR
6321 "pim multicast routing\n"
6322 "Register Suppress Timer\n"
6323 "Seconds\n")
6324 {
6325 PIM_DECLVAR_CONTEXT(vrf, pim);
6326 router->register_suppress_time = atoi(argv[3]->arg);
6327 return CMD_SUCCESS;
6328 }
6329
6330 DEFUN (no_ip_pim_register_suppress,
6331 no_ip_pim_register_suppress_cmd,
6332 "no ip pim register-suppress-time (5-60000)",
6333 NO_STR
6334 IP_STR
6335 "pim multicast routing\n"
6336 "Register Suppress Timer\n"
6337 "Seconds\n")
6338 {
6339 PIM_DECLVAR_CONTEXT(vrf, pim);
6340 router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
6341 return CMD_SUCCESS;
6342 }
6343
6344 DEFUN (ip_pim_rp_keep_alive,
6345 ip_pim_rp_keep_alive_cmd,
6346 "ip pim rp keep-alive-timer (31-60000)",
6347 IP_STR
6348 "pim multicast routing\n"
6349 "Rendevous Point\n"
6350 "Keep alive Timer\n"
6351 "Seconds\n")
6352 {
6353 PIM_DECLVAR_CONTEXT(vrf, pim);
6354 pim->rp_keep_alive_time = atoi(argv[4]->arg);
6355 return CMD_SUCCESS;
6356 }
6357
6358 DEFUN (no_ip_pim_rp_keep_alive,
6359 no_ip_pim_rp_keep_alive_cmd,
6360 "no ip pim rp keep-alive-timer (31-60000)",
6361 NO_STR
6362 IP_STR
6363 "pim multicast routing\n"
6364 "Rendevous Point\n"
6365 "Keep alive Timer\n"
6366 "Seconds\n")
6367 {
6368 PIM_DECLVAR_CONTEXT(vrf, pim);
6369 pim->rp_keep_alive_time = PIM_KEEPALIVE_PERIOD;
6370 return CMD_SUCCESS;
6371 }
6372
6373 DEFUN (ip_pim_keep_alive,
6374 ip_pim_keep_alive_cmd,
6375 "ip pim keep-alive-timer (31-60000)",
6376 IP_STR
6377 "pim multicast routing\n"
6378 "Keep alive Timer\n"
6379 "Seconds\n")
6380 {
6381 PIM_DECLVAR_CONTEXT(vrf, pim);
6382 pim->keep_alive_time = atoi(argv[3]->arg);
6383 return CMD_SUCCESS;
6384 }
6385
6386 DEFUN (no_ip_pim_keep_alive,
6387 no_ip_pim_keep_alive_cmd,
6388 "no ip pim keep-alive-timer (31-60000)",
6389 NO_STR
6390 IP_STR
6391 "pim multicast routing\n"
6392 "Keep alive Timer\n"
6393 "Seconds\n")
6394 {
6395 PIM_DECLVAR_CONTEXT(vrf, pim);
6396 pim->keep_alive_time = PIM_KEEPALIVE_PERIOD;
6397 return CMD_SUCCESS;
6398 }
6399
6400 DEFUN (ip_pim_packets,
6401 ip_pim_packets_cmd,
6402 "ip pim packets (1-100)",
6403 IP_STR
6404 "pim multicast routing\n"
6405 "packets to process at one time per fd\n"
6406 "Number of packets\n")
6407 {
6408 PIM_DECLVAR_CONTEXT(vrf, pim);
6409 router->packet_process = atoi(argv[3]->arg);
6410 return CMD_SUCCESS;
6411 }
6412
6413 DEFUN (no_ip_pim_packets,
6414 no_ip_pim_packets_cmd,
6415 "no ip pim packets (1-100)",
6416 NO_STR
6417 IP_STR
6418 "pim multicast routing\n"
6419 "packets to process at one time per fd\n"
6420 "Number of packets\n")
6421 {
6422 PIM_DECLVAR_CONTEXT(vrf, pim);
6423 router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
6424 return CMD_SUCCESS;
6425 }
6426
6427 DEFUN (ip_pim_v6_secondary,
6428 ip_pim_v6_secondary_cmd,
6429 "ip pim send-v6-secondary",
6430 IP_STR
6431 "pim multicast routing\n"
6432 "Send v6 secondary addresses\n")
6433 {
6434 PIM_DECLVAR_CONTEXT(vrf, pim);
6435 pim->send_v6_secondary = 1;
6436
6437 return CMD_SUCCESS;
6438 }
6439
6440 DEFUN (no_ip_pim_v6_secondary,
6441 no_ip_pim_v6_secondary_cmd,
6442 "no ip pim send-v6-secondary",
6443 NO_STR
6444 IP_STR
6445 "pim multicast routing\n"
6446 "Send v6 secondary addresses\n")
6447 {
6448 PIM_DECLVAR_CONTEXT(vrf, pim);
6449 pim->send_v6_secondary = 0;
6450
6451 return CMD_SUCCESS;
6452 }
6453
6454 DEFUN (ip_pim_rp,
6455 ip_pim_rp_cmd,
6456 "ip pim rp A.B.C.D [A.B.C.D/M]",
6457 IP_STR
6458 "pim multicast routing\n"
6459 "Rendevous Point\n"
6460 "ip address of RP\n"
6461 "Group Address range to cover\n")
6462 {
6463 PIM_DECLVAR_CONTEXT(vrf, pim);
6464 int idx_ipv4 = 3;
6465
6466 if (argc == (idx_ipv4 + 1))
6467 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
6468 NULL);
6469 else
6470 return pim_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
6471 argv[idx_ipv4 + 1]->arg, NULL);
6472 }
6473
6474 DEFUN (ip_pim_rp_prefix_list,
6475 ip_pim_rp_prefix_list_cmd,
6476 "ip pim rp A.B.C.D prefix-list WORD",
6477 IP_STR
6478 "pim multicast routing\n"
6479 "Rendevous Point\n"
6480 "ip address of RP\n"
6481 "group prefix-list filter\n"
6482 "Name of a prefix-list\n")
6483 {
6484 PIM_DECLVAR_CONTEXT(vrf, pim);
6485 return pim_rp_cmd_worker(pim, vty, argv[3]->arg, NULL, argv[5]->arg);
6486 }
6487
6488 static int pim_no_rp_cmd_worker(struct pim_instance *pim, struct vty *vty,
6489 const char *rp, const char *group,
6490 const char *plist)
6491 {
6492 int result = pim_rp_del_config(pim, rp, group, plist);
6493
6494 if (result == PIM_GROUP_BAD_ADDRESS) {
6495 vty_out(vty, "%% Bad group address specified: %s\n", group);
6496 return CMD_WARNING_CONFIG_FAILED;
6497 }
6498
6499 if (result == PIM_RP_BAD_ADDRESS) {
6500 vty_out(vty, "%% Bad RP address specified: %s\n", rp);
6501 return CMD_WARNING_CONFIG_FAILED;
6502 }
6503
6504 if (result == PIM_RP_NOT_FOUND) {
6505 vty_out(vty, "%% Unable to find specified RP\n");
6506 return CMD_WARNING_CONFIG_FAILED;
6507 }
6508
6509 return CMD_SUCCESS;
6510 }
6511
6512 DEFUN (no_ip_pim_rp,
6513 no_ip_pim_rp_cmd,
6514 "no ip pim rp A.B.C.D [A.B.C.D/M]",
6515 NO_STR
6516 IP_STR
6517 "pim multicast routing\n"
6518 "Rendevous Point\n"
6519 "ip address of RP\n"
6520 "Group Address range to cover\n")
6521 {
6522 PIM_DECLVAR_CONTEXT(vrf, pim);
6523 int idx_ipv4 = 4, idx_group = 0;
6524
6525 if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
6526 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg,
6527 argv[idx_group]->arg, NULL);
6528 else
6529 return pim_no_rp_cmd_worker(pim, vty, argv[idx_ipv4]->arg, NULL,
6530 NULL);
6531 }
6532
6533 DEFUN (no_ip_pim_rp_prefix_list,
6534 no_ip_pim_rp_prefix_list_cmd,
6535 "no ip pim rp A.B.C.D prefix-list WORD",
6536 NO_STR
6537 IP_STR
6538 "pim multicast routing\n"
6539 "Rendevous Point\n"
6540 "ip address of RP\n"
6541 "group prefix-list filter\n"
6542 "Name of a prefix-list\n")
6543 {
6544 PIM_DECLVAR_CONTEXT(vrf, pim);
6545 return pim_no_rp_cmd_worker(pim, vty, argv[4]->arg, NULL, argv[6]->arg);
6546 }
6547
6548 static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
6549 const char *plist)
6550 {
6551 int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
6552 int ret = CMD_WARNING_CONFIG_FAILED;
6553
6554 if (result == PIM_SSM_ERR_NONE)
6555 return CMD_SUCCESS;
6556
6557 switch (result) {
6558 case PIM_SSM_ERR_NO_VRF:
6559 vty_out(vty, "%% VRF doesn't exist\n");
6560 break;
6561 case PIM_SSM_ERR_DUP:
6562 vty_out(vty, "%% duplicate config\n");
6563 ret = CMD_WARNING;
6564 break;
6565 default:
6566 vty_out(vty, "%% ssm range config failed\n");
6567 }
6568
6569 return ret;
6570 }
6571
6572 DEFUN (ip_pim_ssm_prefix_list,
6573 ip_pim_ssm_prefix_list_cmd,
6574 "ip pim ssm prefix-list WORD",
6575 IP_STR
6576 "pim multicast routing\n"
6577 "Source Specific Multicast\n"
6578 "group range prefix-list filter\n"
6579 "Name of a prefix-list\n")
6580 {
6581 PIM_DECLVAR_CONTEXT(vrf, pim);
6582 return pim_ssm_cmd_worker(pim, vty, argv[4]->arg);
6583 }
6584
6585 DEFUN (no_ip_pim_ssm_prefix_list,
6586 no_ip_pim_ssm_prefix_list_cmd,
6587 "no ip pim ssm prefix-list",
6588 NO_STR
6589 IP_STR
6590 "pim multicast routing\n"
6591 "Source Specific Multicast\n"
6592 "group range prefix-list filter\n")
6593 {
6594 PIM_DECLVAR_CONTEXT(vrf, pim);
6595 return pim_ssm_cmd_worker(pim, vty, NULL);
6596 }
6597
6598 DEFUN (no_ip_pim_ssm_prefix_list_name,
6599 no_ip_pim_ssm_prefix_list_name_cmd,
6600 "no ip pim ssm prefix-list WORD",
6601 NO_STR
6602 IP_STR
6603 "pim multicast routing\n"
6604 "Source Specific Multicast\n"
6605 "group range prefix-list filter\n"
6606 "Name of a prefix-list\n")
6607 {
6608 PIM_DECLVAR_CONTEXT(vrf, pim);
6609 struct pim_ssm *ssm = pim->ssm_info;
6610
6611 if (ssm->plist_name && !strcmp(ssm->plist_name, argv[5]->arg))
6612 return pim_ssm_cmd_worker(pim, vty, NULL);
6613
6614 vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
6615
6616 return CMD_WARNING_CONFIG_FAILED;
6617 }
6618
6619 static void ip_pim_ssm_show_group_range(struct pim_instance *pim,
6620 struct vty *vty, bool uj)
6621 {
6622 struct pim_ssm *ssm = pim->ssm_info;
6623 const char *range_str =
6624 ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
6625
6626 if (uj) {
6627 json_object *json;
6628 json = json_object_new_object();
6629 json_object_string_add(json, "ssmGroups", range_str);
6630 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6631 json, JSON_C_TO_STRING_PRETTY));
6632 json_object_free(json);
6633 } else
6634 vty_out(vty, "SSM group range : %s\n", range_str);
6635 }
6636
6637 DEFUN (show_ip_pim_ssm_range,
6638 show_ip_pim_ssm_range_cmd,
6639 "show ip pim [vrf NAME] group-type [json]",
6640 SHOW_STR
6641 IP_STR
6642 PIM_STR
6643 VRF_CMD_HELP_STR
6644 "PIM group type\n"
6645 JSON_STR)
6646 {
6647 int idx = 2;
6648 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6649 bool uj = use_json(argc, argv);
6650
6651 if (!vrf)
6652 return CMD_WARNING;
6653
6654 ip_pim_ssm_show_group_range(vrf->info, vty, uj);
6655
6656 return CMD_SUCCESS;
6657 }
6658
6659 static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
6660 struct vty *vty, bool uj,
6661 const char *group)
6662 {
6663 struct in_addr group_addr;
6664 const char *type_str;
6665 int result;
6666
6667 result = inet_pton(AF_INET, group, &group_addr);
6668 if (result <= 0)
6669 type_str = "invalid";
6670 else {
6671 if (pim_is_group_224_4(group_addr))
6672 type_str =
6673 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
6674 else
6675 type_str = "not-multicast";
6676 }
6677
6678 if (uj) {
6679 json_object *json;
6680 json = json_object_new_object();
6681 json_object_string_add(json, "groupType", type_str);
6682 vty_out(vty, "%s\n", json_object_to_json_string_ext(
6683 json, JSON_C_TO_STRING_PRETTY));
6684 json_object_free(json);
6685 } else
6686 vty_out(vty, "Group type : %s\n", type_str);
6687 }
6688
6689 DEFUN (show_ip_pim_group_type,
6690 show_ip_pim_group_type_cmd,
6691 "show ip pim [vrf NAME] group-type A.B.C.D [json]",
6692 SHOW_STR
6693 IP_STR
6694 PIM_STR
6695 VRF_CMD_HELP_STR
6696 "multicast group type\n"
6697 "group address\n"
6698 JSON_STR)
6699 {
6700 int idx = 2;
6701 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6702 bool uj = use_json(argc, argv);
6703
6704 if (!vrf)
6705 return CMD_WARNING;
6706
6707 argv_find(argv, argc, "A.B.C.D", &idx);
6708 ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
6709
6710 return CMD_SUCCESS;
6711 }
6712
6713 DEFUN (show_ip_pim_bsr,
6714 show_ip_pim_bsr_cmd,
6715 "show ip pim bsr [json]",
6716 SHOW_STR
6717 IP_STR
6718 PIM_STR
6719 "boot-strap router information\n"
6720 JSON_STR)
6721 {
6722 int idx = 2;
6723 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
6724 bool uj = use_json(argc, argv);
6725
6726 if (!vrf)
6727 return CMD_WARNING;
6728
6729 pim_show_bsr(vrf->info, vty, uj);
6730
6731 return CMD_SUCCESS;
6732 }
6733
6734 DEFUN (ip_ssmpingd,
6735 ip_ssmpingd_cmd,
6736 "ip ssmpingd [A.B.C.D]",
6737 IP_STR
6738 CONF_SSMPINGD_STR
6739 "Source address\n")
6740 {
6741 PIM_DECLVAR_CONTEXT(vrf, pim);
6742 int idx_ipv4 = 2;
6743 int result;
6744 struct in_addr source_addr;
6745 const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
6746
6747 result = inet_pton(AF_INET, source_str, &source_addr);
6748 if (result <= 0) {
6749 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
6750 source_str, errno, safe_strerror(errno));
6751 return CMD_WARNING_CONFIG_FAILED;
6752 }
6753
6754 result = pim_ssmpingd_start(pim, source_addr);
6755 if (result) {
6756 vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
6757 source_str, result);
6758 return CMD_WARNING_CONFIG_FAILED;
6759 }
6760
6761 return CMD_SUCCESS;
6762 }
6763
6764 DEFUN (no_ip_ssmpingd,
6765 no_ip_ssmpingd_cmd,
6766 "no ip ssmpingd [A.B.C.D]",
6767 NO_STR
6768 IP_STR
6769 CONF_SSMPINGD_STR
6770 "Source address\n")
6771 {
6772 PIM_DECLVAR_CONTEXT(vrf, pim);
6773 int idx_ipv4 = 3;
6774 int result;
6775 struct in_addr source_addr;
6776 const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
6777
6778 result = inet_pton(AF_INET, source_str, &source_addr);
6779 if (result <= 0) {
6780 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
6781 source_str, errno, safe_strerror(errno));
6782 return CMD_WARNING_CONFIG_FAILED;
6783 }
6784
6785 result = pim_ssmpingd_stop(pim, source_addr);
6786 if (result) {
6787 vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
6788 source_str, result);
6789 return CMD_WARNING_CONFIG_FAILED;
6790 }
6791
6792 return CMD_SUCCESS;
6793 }
6794
6795 DEFUN (ip_pim_ecmp,
6796 ip_pim_ecmp_cmd,
6797 "ip pim ecmp",
6798 IP_STR
6799 "pim multicast routing\n"
6800 "Enable PIM ECMP \n")
6801 {
6802 PIM_DECLVAR_CONTEXT(vrf, pim);
6803 pim->ecmp_enable = true;
6804
6805 return CMD_SUCCESS;
6806 }
6807
6808 DEFUN (no_ip_pim_ecmp,
6809 no_ip_pim_ecmp_cmd,
6810 "no ip pim ecmp",
6811 NO_STR
6812 IP_STR
6813 "pim multicast routing\n"
6814 "Disable PIM ECMP \n")
6815 {
6816 PIM_DECLVAR_CONTEXT(vrf, pim);
6817 pim->ecmp_enable = false;
6818
6819 return CMD_SUCCESS;
6820 }
6821
6822 DEFUN (ip_pim_ecmp_rebalance,
6823 ip_pim_ecmp_rebalance_cmd,
6824 "ip pim ecmp rebalance",
6825 IP_STR
6826 "pim multicast routing\n"
6827 "Enable PIM ECMP \n"
6828 "Enable PIM ECMP Rebalance\n")
6829 {
6830 PIM_DECLVAR_CONTEXT(vrf, pim);
6831 pim->ecmp_enable = true;
6832 pim->ecmp_rebalance_enable = true;
6833
6834 return CMD_SUCCESS;
6835 }
6836
6837 DEFUN (no_ip_pim_ecmp_rebalance,
6838 no_ip_pim_ecmp_rebalance_cmd,
6839 "no ip pim ecmp rebalance",
6840 NO_STR
6841 IP_STR
6842 "pim multicast routing\n"
6843 "Disable PIM ECMP \n"
6844 "Disable PIM ECMP Rebalance\n")
6845 {
6846 PIM_DECLVAR_CONTEXT(vrf, pim);
6847 pim->ecmp_rebalance_enable = false;
6848
6849 return CMD_SUCCESS;
6850 }
6851
6852 static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
6853 {
6854 struct pim_interface *pim_ifp;
6855 uint8_t need_startup = 0;
6856
6857 pim_ifp = ifp->info;
6858
6859 if (!pim_ifp) {
6860 (void)pim_if_new(ifp, true, false, false, false);
6861 need_startup = 1;
6862 } else {
6863 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
6864 PIM_IF_DO_IGMP(pim_ifp->options);
6865 need_startup = 1;
6866 }
6867 }
6868
6869 /* 'ip igmp' executed multiple times, with need_startup
6870 avoid multiple if add all and membership refresh */
6871 if (need_startup) {
6872 pim_if_addr_add_all(ifp);
6873 pim_if_membership_refresh(ifp);
6874 }
6875
6876 return CMD_SUCCESS;
6877 }
6878
6879 DEFUN (interface_ip_igmp,
6880 interface_ip_igmp_cmd,
6881 "ip igmp",
6882 IP_STR
6883 IFACE_IGMP_STR)
6884 {
6885 VTY_DECLVAR_CONTEXT(interface, ifp);
6886
6887 return pim_cmd_igmp_start(vty, ifp);
6888 }
6889
6890 DEFUN (interface_no_ip_igmp,
6891 interface_no_ip_igmp_cmd,
6892 "no ip igmp",
6893 NO_STR
6894 IP_STR
6895 IFACE_IGMP_STR)
6896 {
6897 VTY_DECLVAR_CONTEXT(interface, ifp);
6898 struct pim_interface *pim_ifp = ifp->info;
6899
6900 if (!pim_ifp)
6901 return CMD_SUCCESS;
6902
6903 PIM_IF_DONT_IGMP(pim_ifp->options);
6904
6905 pim_if_membership_clear(ifp);
6906
6907 pim_if_addr_del_all_igmp(ifp);
6908
6909 if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
6910 pim_if_delete(ifp);
6911 }
6912
6913 return CMD_SUCCESS;
6914 }
6915
6916 DEFUN (interface_ip_igmp_join,
6917 interface_ip_igmp_join_cmd,
6918 "ip igmp join A.B.C.D A.B.C.D",
6919 IP_STR
6920 IFACE_IGMP_STR
6921 "IGMP join multicast group\n"
6922 "Multicast group address\n"
6923 "Source address\n")
6924 {
6925 VTY_DECLVAR_CONTEXT(interface, ifp);
6926 int idx_ipv4 = 3;
6927 int idx_ipv4_2 = 4;
6928 const char *group_str;
6929 const char *source_str;
6930 struct in_addr group_addr;
6931 struct in_addr source_addr;
6932 int result;
6933
6934 /* Group address */
6935 group_str = argv[idx_ipv4]->arg;
6936 result = inet_pton(AF_INET, group_str, &group_addr);
6937 if (result <= 0) {
6938 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
6939 errno, safe_strerror(errno));
6940 return CMD_WARNING_CONFIG_FAILED;
6941 }
6942
6943 /* Source address */
6944 source_str = argv[idx_ipv4_2]->arg;
6945 result = inet_pton(AF_INET, source_str, &source_addr);
6946 if (result <= 0) {
6947 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
6948 source_str, errno, safe_strerror(errno));
6949 return CMD_WARNING_CONFIG_FAILED;
6950 }
6951
6952 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp, group_addr, source_addr),
6953 "Failure joining IGMP group: $ERR");
6954
6955 return CMD_SUCCESS;
6956 }
6957
6958 DEFUN (interface_no_ip_igmp_join,
6959 interface_no_ip_igmp_join_cmd,
6960 "no ip igmp join A.B.C.D A.B.C.D",
6961 NO_STR
6962 IP_STR
6963 IFACE_IGMP_STR
6964 "IGMP join multicast group\n"
6965 "Multicast group address\n"
6966 "Source address\n")
6967 {
6968 VTY_DECLVAR_CONTEXT(interface, ifp);
6969 int idx_ipv4 = 4;
6970 int idx_ipv4_2 = 5;
6971 const char *group_str;
6972 const char *source_str;
6973 struct in_addr group_addr;
6974 struct in_addr source_addr;
6975 int result;
6976
6977 /* Group address */
6978 group_str = argv[idx_ipv4]->arg;
6979 result = inet_pton(AF_INET, group_str, &group_addr);
6980 if (result <= 0) {
6981 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
6982 errno, safe_strerror(errno));
6983 return CMD_WARNING_CONFIG_FAILED;
6984 }
6985
6986 /* Source address */
6987 source_str = argv[idx_ipv4_2]->arg;
6988 result = inet_pton(AF_INET, source_str, &source_addr);
6989 if (result <= 0) {
6990 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
6991 source_str, errno, safe_strerror(errno));
6992 return CMD_WARNING_CONFIG_FAILED;
6993 }
6994
6995 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
6996 if (result) {
6997 vty_out(vty,
6998 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
6999 group_str, source_str, ifp->name, result);
7000 return CMD_WARNING_CONFIG_FAILED;
7001 }
7002
7003 return CMD_SUCCESS;
7004 }
7005
7006 /*
7007 CLI reconfiguration affects the interface level (struct pim_interface).
7008 This function propagates the reconfiguration to every active socket
7009 for that interface.
7010 */
7011 static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
7012 {
7013 struct interface *ifp;
7014 struct pim_interface *pim_ifp;
7015
7016 zassert(igmp);
7017
7018 /* other querier present? */
7019
7020 if (igmp->t_other_querier_timer)
7021 return;
7022
7023 /* this is the querier */
7024
7025 zassert(igmp->interface);
7026 zassert(igmp->interface->info);
7027
7028 ifp = igmp->interface;
7029 pim_ifp = ifp->info;
7030
7031 if (PIM_DEBUG_IGMP_TRACE) {
7032 char ifaddr_str[INET_ADDRSTRLEN];
7033 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
7034 sizeof(ifaddr_str));
7035 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7036 __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
7037 pim_ifp->igmp_default_query_interval);
7038 }
7039
7040 /*
7041 igmp_startup_mode_on() will reset QQI:
7042
7043 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7044 */
7045 igmp_startup_mode_on(igmp);
7046 }
7047
7048 static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
7049 {
7050 if (igmp->t_igmp_query_timer) {
7051 /* other querier present */
7052 zassert(igmp->t_igmp_query_timer);
7053 zassert(!igmp->t_other_querier_timer);
7054
7055 pim_igmp_general_query_off(igmp);
7056 pim_igmp_general_query_on(igmp);
7057
7058 zassert(igmp->t_igmp_query_timer);
7059 zassert(!igmp->t_other_querier_timer);
7060 } else {
7061 /* this is the querier */
7062
7063 zassert(!igmp->t_igmp_query_timer);
7064 zassert(igmp->t_other_querier_timer);
7065
7066 pim_igmp_other_querier_timer_off(igmp);
7067 pim_igmp_other_querier_timer_on(igmp);
7068
7069 zassert(!igmp->t_igmp_query_timer);
7070 zassert(igmp->t_other_querier_timer);
7071 }
7072 }
7073
7074 static void change_query_interval(struct pim_interface *pim_ifp,
7075 int query_interval)
7076 {
7077 struct listnode *sock_node;
7078 struct igmp_sock *igmp;
7079
7080 pim_ifp->igmp_default_query_interval = query_interval;
7081
7082 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7083 igmp_sock_query_interval_reconfig(igmp);
7084 igmp_sock_query_reschedule(igmp);
7085 }
7086 }
7087
7088 static void change_query_max_response_time(struct pim_interface *pim_ifp,
7089 int query_max_response_time_dsec)
7090 {
7091 struct listnode *sock_node;
7092 struct igmp_sock *igmp;
7093
7094 pim_ifp->igmp_query_max_response_time_dsec =
7095 query_max_response_time_dsec;
7096
7097 /*
7098 Below we modify socket/group/source timers in order to quickly
7099 reflect the change. Otherwise, those timers would eventually catch
7100 up.
7101 */
7102
7103 /* scan all sockets */
7104 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7105 struct listnode *grp_node;
7106 struct igmp_group *grp;
7107
7108 /* reschedule socket general query */
7109 igmp_sock_query_reschedule(igmp);
7110
7111 /* scan socket groups */
7112 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
7113 grp)) {
7114 struct listnode *src_node;
7115 struct igmp_source *src;
7116
7117 /* reset group timers for groups in EXCLUDE mode */
7118 if (grp->group_filtermode_isexcl) {
7119 igmp_group_reset_gmi(grp);
7120 }
7121
7122 /* scan group sources */
7123 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
7124 src_node, src)) {
7125
7126 /* reset source timers for sources with running
7127 * timers */
7128 if (src->t_source_timer) {
7129 igmp_source_reset_gmi(igmp, grp, src);
7130 }
7131 }
7132 }
7133 }
7134 }
7135
7136 #define IGMP_QUERY_INTERVAL_MIN (1)
7137 #define IGMP_QUERY_INTERVAL_MAX (1800)
7138
7139 DEFUN (interface_ip_igmp_query_interval,
7140 interface_ip_igmp_query_interval_cmd,
7141 "ip igmp query-interval (1-1800)",
7142 IP_STR
7143 IFACE_IGMP_STR
7144 IFACE_IGMP_QUERY_INTERVAL_STR
7145 "Query interval in seconds\n")
7146 {
7147 VTY_DECLVAR_CONTEXT(interface, ifp);
7148 struct pim_interface *pim_ifp = ifp->info;
7149 int query_interval;
7150 int query_interval_dsec;
7151 int ret;
7152
7153 if (!pim_ifp) {
7154 ret = pim_cmd_igmp_start(vty, ifp);
7155 if (ret != CMD_SUCCESS)
7156 return ret;
7157 pim_ifp = ifp->info;
7158 }
7159
7160 query_interval = atoi(argv[3]->arg);
7161 query_interval_dsec = 10 * query_interval;
7162
7163 /*
7164 It seems we don't need to check bounds since command.c does it
7165 already, but we verify them anyway for extra safety.
7166 */
7167 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
7168 vty_out(vty,
7169 "General query interval %d lower than minimum %d\n",
7170 query_interval, IGMP_QUERY_INTERVAL_MIN);
7171 return CMD_WARNING_CONFIG_FAILED;
7172 }
7173 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
7174 vty_out(vty,
7175 "General query interval %d higher than maximum %d\n",
7176 query_interval, IGMP_QUERY_INTERVAL_MAX);
7177 return CMD_WARNING_CONFIG_FAILED;
7178 }
7179
7180 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
7181 vty_out(vty,
7182 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7183 query_interval_dsec,
7184 pim_ifp->igmp_query_max_response_time_dsec);
7185 return CMD_WARNING_CONFIG_FAILED;
7186 }
7187
7188 change_query_interval(pim_ifp, query_interval);
7189
7190 return CMD_SUCCESS;
7191 }
7192
7193 DEFUN (interface_no_ip_igmp_query_interval,
7194 interface_no_ip_igmp_query_interval_cmd,
7195 "no ip igmp query-interval",
7196 NO_STR
7197 IP_STR
7198 IFACE_IGMP_STR
7199 IFACE_IGMP_QUERY_INTERVAL_STR)
7200 {
7201 VTY_DECLVAR_CONTEXT(interface, ifp);
7202 struct pim_interface *pim_ifp = ifp->info;
7203 int default_query_interval_dsec;
7204
7205 if (!pim_ifp)
7206 return CMD_SUCCESS;
7207
7208 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
7209
7210 if (default_query_interval_dsec
7211 <= pim_ifp->igmp_query_max_response_time_dsec) {
7212 vty_out(vty,
7213 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7214 default_query_interval_dsec,
7215 pim_ifp->igmp_query_max_response_time_dsec);
7216 return CMD_WARNING_CONFIG_FAILED;
7217 }
7218
7219 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
7220
7221 return CMD_SUCCESS;
7222 }
7223
7224 DEFUN (interface_ip_igmp_version,
7225 interface_ip_igmp_version_cmd,
7226 "ip igmp version (2-3)",
7227 IP_STR
7228 IFACE_IGMP_STR
7229 "IGMP version\n"
7230 "IGMP version number\n")
7231 {
7232 VTY_DECLVAR_CONTEXT(interface, ifp);
7233 struct pim_interface *pim_ifp = ifp->info;
7234 int igmp_version, old_version = 0;
7235 int ret;
7236
7237 if (!pim_ifp) {
7238 ret = pim_cmd_igmp_start(vty, ifp);
7239 if (ret != CMD_SUCCESS)
7240 return ret;
7241 pim_ifp = ifp->info;
7242 }
7243
7244 igmp_version = atoi(argv[3]->arg);
7245 old_version = pim_ifp->igmp_version;
7246 pim_ifp->igmp_version = igmp_version;
7247
7248 // Check if IGMP is Enabled otherwise, enable on interface
7249 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7250 PIM_IF_DO_IGMP(pim_ifp->options);
7251 pim_if_addr_add_all(ifp);
7252 pim_if_membership_refresh(ifp);
7253 old_version = igmp_version;
7254 // avoid refreshing membership again.
7255 }
7256 /* Current and new version is different refresh existing
7257 membership. Going from 3 -> 2 or 2 -> 3. */
7258 if (old_version != igmp_version)
7259 pim_if_membership_refresh(ifp);
7260
7261 return CMD_SUCCESS;
7262 }
7263
7264 DEFUN (interface_no_ip_igmp_version,
7265 interface_no_ip_igmp_version_cmd,
7266 "no ip igmp version (2-3)",
7267 NO_STR
7268 IP_STR
7269 IFACE_IGMP_STR
7270 "IGMP version\n"
7271 "IGMP version number\n")
7272 {
7273 VTY_DECLVAR_CONTEXT(interface, ifp);
7274 struct pim_interface *pim_ifp = ifp->info;
7275
7276 if (!pim_ifp)
7277 return CMD_SUCCESS;
7278
7279 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
7280
7281 return CMD_SUCCESS;
7282 }
7283
7284 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7285 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7286
7287 DEFUN (interface_ip_igmp_query_max_response_time,
7288 interface_ip_igmp_query_max_response_time_cmd,
7289 "ip igmp query-max-response-time (10-250)",
7290 IP_STR
7291 IFACE_IGMP_STR
7292 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7293 "Query response value in deci-seconds\n")
7294 {
7295 VTY_DECLVAR_CONTEXT(interface, ifp);
7296 struct pim_interface *pim_ifp = ifp->info;
7297 int query_max_response_time;
7298 int ret;
7299
7300 if (!pim_ifp) {
7301 ret = pim_cmd_igmp_start(vty, ifp);
7302 if (ret != CMD_SUCCESS)
7303 return ret;
7304 pim_ifp = ifp->info;
7305 }
7306
7307 query_max_response_time = atoi(argv[3]->arg);
7308
7309 if (query_max_response_time
7310 >= pim_ifp->igmp_default_query_interval * 10) {
7311 vty_out(vty,
7312 "Can't set query max response time %d sec >= general query interval %d sec\n",
7313 query_max_response_time,
7314 pim_ifp->igmp_default_query_interval);
7315 return CMD_WARNING_CONFIG_FAILED;
7316 }
7317
7318 change_query_max_response_time(pim_ifp, query_max_response_time);
7319
7320 return CMD_SUCCESS;
7321 }
7322
7323 DEFUN (interface_no_ip_igmp_query_max_response_time,
7324 interface_no_ip_igmp_query_max_response_time_cmd,
7325 "no ip igmp query-max-response-time (10-250)",
7326 NO_STR
7327 IP_STR
7328 IFACE_IGMP_STR
7329 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7330 "Time for response in deci-seconds\n")
7331 {
7332 VTY_DECLVAR_CONTEXT(interface, ifp);
7333 struct pim_interface *pim_ifp = ifp->info;
7334
7335 if (!pim_ifp)
7336 return CMD_SUCCESS;
7337
7338 change_query_max_response_time(pim_ifp,
7339 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
7340
7341 return CMD_SUCCESS;
7342 }
7343
7344 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7345 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7346
7347 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
7348 interface_ip_igmp_query_max_response_time_dsec_cmd,
7349 "ip igmp query-max-response-time-dsec (10-250)",
7350 IP_STR
7351 IFACE_IGMP_STR
7352 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7353 "Query response value in deciseconds\n")
7354 {
7355 VTY_DECLVAR_CONTEXT(interface, ifp);
7356 struct pim_interface *pim_ifp = ifp->info;
7357 int query_max_response_time_dsec;
7358 int default_query_interval_dsec;
7359 int ret;
7360
7361 if (!pim_ifp) {
7362 ret = pim_cmd_igmp_start(vty, ifp);
7363 if (ret != CMD_SUCCESS)
7364 return ret;
7365 pim_ifp = ifp->info;
7366 }
7367
7368 query_max_response_time_dsec = atoi(argv[4]->arg);
7369
7370 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
7371
7372 if (query_max_response_time_dsec >= default_query_interval_dsec) {
7373 vty_out(vty,
7374 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7375 query_max_response_time_dsec,
7376 default_query_interval_dsec);
7377 return CMD_WARNING_CONFIG_FAILED;
7378 }
7379
7380 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
7381
7382 return CMD_SUCCESS;
7383 }
7384
7385 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
7386 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
7387 "no ip igmp query-max-response-time-dsec",
7388 NO_STR
7389 IP_STR
7390 IFACE_IGMP_STR
7391 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
7392 {
7393 VTY_DECLVAR_CONTEXT(interface, ifp);
7394 struct pim_interface *pim_ifp = ifp->info;
7395
7396 if (!pim_ifp)
7397 return CMD_SUCCESS;
7398
7399 change_query_max_response_time(pim_ifp,
7400 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
7401
7402 return CMD_SUCCESS;
7403 }
7404
7405 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7406 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7407
7408 DEFUN (interface_ip_igmp_last_member_query_count,
7409 interface_ip_igmp_last_member_query_count_cmd,
7410 "ip igmp last-member-query-count (1-7)",
7411 IP_STR
7412 IFACE_IGMP_STR
7413 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7414 "Last member query count\n")
7415 {
7416 VTY_DECLVAR_CONTEXT(interface, ifp);
7417 struct pim_interface *pim_ifp = ifp->info;
7418 int last_member_query_count;
7419 int ret;
7420
7421 if (!pim_ifp) {
7422 ret = pim_cmd_igmp_start(vty, ifp);
7423 if (ret != CMD_SUCCESS)
7424 return ret;
7425 pim_ifp = ifp->info;
7426 }
7427
7428 last_member_query_count = atoi(argv[3]->arg);
7429
7430 pim_ifp->igmp_last_member_query_count = last_member_query_count;
7431
7432 return CMD_SUCCESS;
7433 }
7434
7435 DEFUN (interface_no_ip_igmp_last_member_query_count,
7436 interface_no_ip_igmp_last_member_query_count_cmd,
7437 "no ip igmp last-member-query-count",
7438 NO_STR
7439 IP_STR
7440 IFACE_IGMP_STR
7441 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR)
7442 {
7443 VTY_DECLVAR_CONTEXT(interface, ifp);
7444 struct pim_interface *pim_ifp = ifp->info;
7445
7446 if (!pim_ifp)
7447 return CMD_SUCCESS;
7448
7449 pim_ifp->igmp_last_member_query_count =
7450 IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
7451
7452 return CMD_SUCCESS;
7453 }
7454
7455 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7456 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7457
7458 DEFUN (interface_ip_igmp_last_member_query_interval,
7459 interface_ip_igmp_last_member_query_interval_cmd,
7460 "ip igmp last-member-query-interval (1-255)",
7461 IP_STR
7462 IFACE_IGMP_STR
7463 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7464 "Last member query interval in deciseconds\n")
7465 {
7466 VTY_DECLVAR_CONTEXT(interface, ifp);
7467 struct pim_interface *pim_ifp = ifp->info;
7468 int last_member_query_interval;
7469 int ret;
7470
7471 if (!pim_ifp) {
7472 ret = pim_cmd_igmp_start(vty, ifp);
7473 if (ret != CMD_SUCCESS)
7474 return ret;
7475 pim_ifp = ifp->info;
7476 }
7477
7478 last_member_query_interval = atoi(argv[3]->arg);
7479 pim_ifp->igmp_specific_query_max_response_time_dsec
7480 = last_member_query_interval;
7481
7482 return CMD_SUCCESS;
7483 }
7484
7485 DEFUN (interface_no_ip_igmp_last_member_query_interval,
7486 interface_no_ip_igmp_last_member_query_interval_cmd,
7487 "no ip igmp last-member-query-interval",
7488 NO_STR
7489 IP_STR
7490 IFACE_IGMP_STR
7491 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR)
7492 {
7493 VTY_DECLVAR_CONTEXT(interface, ifp);
7494 struct pim_interface *pim_ifp = ifp->info;
7495
7496 if (!pim_ifp)
7497 return CMD_SUCCESS;
7498
7499 pim_ifp->igmp_specific_query_max_response_time_dsec =
7500 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
7501
7502 return CMD_SUCCESS;
7503 }
7504
7505 DEFUN (interface_ip_pim_drprio,
7506 interface_ip_pim_drprio_cmd,
7507 "ip pim drpriority (1-4294967295)",
7508 IP_STR
7509 PIM_STR
7510 "Set the Designated Router Election Priority\n"
7511 "Value of the new DR Priority\n")
7512 {
7513 VTY_DECLVAR_CONTEXT(interface, ifp);
7514 int idx_number = 3;
7515 struct pim_interface *pim_ifp = ifp->info;
7516 uint32_t old_dr_prio;
7517
7518 if (!pim_ifp) {
7519 vty_out(vty, "Please enable PIM on interface, first\n");
7520 return CMD_WARNING_CONFIG_FAILED;
7521 }
7522
7523 old_dr_prio = pim_ifp->pim_dr_priority;
7524
7525 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
7526
7527 if (old_dr_prio != pim_ifp->pim_dr_priority) {
7528 pim_if_dr_election(ifp);
7529 pim_hello_restart_now(ifp);
7530 }
7531
7532 return CMD_SUCCESS;
7533 }
7534
7535 DEFUN (interface_no_ip_pim_drprio,
7536 interface_no_ip_pim_drprio_cmd,
7537 "no ip pim drpriority [(1-4294967295)]",
7538 NO_STR
7539 IP_STR
7540 PIM_STR
7541 "Revert the Designated Router Priority to default\n"
7542 "Old Value of the Priority\n")
7543 {
7544 VTY_DECLVAR_CONTEXT(interface, ifp);
7545 struct pim_interface *pim_ifp = ifp->info;
7546
7547 if (!pim_ifp) {
7548 vty_out(vty, "Pim not enabled on this interface\n");
7549 return CMD_WARNING_CONFIG_FAILED;
7550 }
7551
7552 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
7553 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
7554 pim_if_dr_election(ifp);
7555 pim_hello_restart_now(ifp);
7556 }
7557
7558 return CMD_SUCCESS;
7559 }
7560
7561 DEFPY_HIDDEN (interface_ip_igmp_query_generate,
7562 interface_ip_igmp_query_generate_cmd,
7563 "ip igmp generate-query-once [version (2-3)]",
7564 IP_STR
7565 IFACE_IGMP_STR
7566 "Generate igmp general query once\n"
7567 "IGMP version\n"
7568 "IGMP version number\n")
7569 {
7570 VTY_DECLVAR_CONTEXT(interface, ifp);
7571 int igmp_version = 2;
7572
7573 if (!ifp->info) {
7574 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
7575 ifp->name);
7576 return CMD_WARNING_CONFIG_FAILED;
7577 }
7578
7579 if (argc > 3)
7580 igmp_version = atoi(argv[4]->arg);
7581
7582 igmp_send_query_on_intf(ifp, igmp_version);
7583
7584 return CMD_SUCCESS;
7585 }
7586
7587 static int pim_cmd_interface_add(struct interface *ifp)
7588 {
7589 struct pim_interface *pim_ifp = ifp->info;
7590
7591 if (!pim_ifp)
7592 pim_ifp = pim_if_new(ifp, false, true, false, false);
7593 else
7594 PIM_IF_DO_PIM(pim_ifp->options);
7595
7596 pim_if_addr_add_all(ifp);
7597 pim_if_membership_refresh(ifp);
7598
7599 pim_if_create_pimreg(pim_ifp->pim);
7600 return 1;
7601 }
7602
7603 DEFPY_HIDDEN (pim_test_sg_keepalive,
7604 pim_test_sg_keepalive_cmd,
7605 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7606 "Test code\n"
7607 PIM_STR
7608 VRF_CMD_HELP_STR
7609 "Reset the Keepalive Timer\n"
7610 "The Source we are resetting\n"
7611 "The Group we are resetting\n")
7612 {
7613 struct pim_upstream *up;
7614 struct pim_instance *pim;
7615 struct prefix_sg sg;
7616
7617 sg.src = source;
7618 sg.grp = group;
7619
7620 if (!name)
7621 pim = pim_get_pim_instance(VRF_DEFAULT);
7622 else {
7623 struct vrf *vrf = vrf_lookup_by_name(name);
7624
7625 if (!vrf) {
7626 vty_out(vty, "%% Vrf specified: %s does not exist\n",
7627 name);
7628 return CMD_WARNING;
7629 }
7630
7631 pim = pim_get_pim_instance(vrf->vrf_id);
7632 }
7633
7634 if (!pim) {
7635 vty_out(vty, "%% Unable to find pim instance\n");
7636 return CMD_WARNING;
7637 }
7638
7639 up = pim_upstream_find(pim, &sg);
7640 if (!up) {
7641 vty_out(vty, "%% Unable to find %s specified\n",
7642 pim_str_sg_dump(&sg));
7643 return CMD_WARNING;
7644 }
7645
7646 vty_out(vty, "Setting %s to current keep alive time: %d\n",
7647 pim_str_sg_dump(&sg), pim->keep_alive_time);
7648 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
7649
7650 return CMD_SUCCESS;
7651 }
7652
7653 DEFPY_HIDDEN (interface_ip_pim_activeactive,
7654 interface_ip_pim_activeactive_cmd,
7655 "[no$no] ip pim active-active",
7656 NO_STR
7657 IP_STR
7658 PIM_STR
7659 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7660 {
7661 VTY_DECLVAR_CONTEXT(interface, ifp);
7662 struct pim_interface *pim_ifp;
7663
7664 if (!no && !pim_cmd_interface_add(ifp)) {
7665 vty_out(vty, "Could not enable PIM SM active-active on interface\n");
7666 return CMD_WARNING_CONFIG_FAILED;
7667 }
7668
7669 pim_ifp = ifp->info;
7670 if (no)
7671 pim_if_unconfigure_mlag_dualactive(pim_ifp);
7672 else
7673 pim_if_configure_mlag_dualactive(pim_ifp);
7674
7675 return CMD_SUCCESS;
7676 }
7677
7678 DEFUN_HIDDEN (interface_ip_pim_ssm,
7679 interface_ip_pim_ssm_cmd,
7680 "ip pim ssm",
7681 IP_STR
7682 PIM_STR
7683 IFACE_PIM_STR)
7684 {
7685 VTY_DECLVAR_CONTEXT(interface, ifp);
7686
7687 if (!pim_cmd_interface_add(ifp)) {
7688 vty_out(vty, "Could not enable PIM SM on interface\n");
7689 return CMD_WARNING_CONFIG_FAILED;
7690 }
7691
7692 vty_out(vty,
7693 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7694 "range if needed\n");
7695 return CMD_SUCCESS;
7696 }
7697
7698 static int interface_ip_pim_helper(struct vty *vty)
7699 {
7700 struct pim_interface *pim_ifp;
7701
7702 VTY_DECLVAR_CONTEXT(interface, ifp);
7703
7704 if (!pim_cmd_interface_add(ifp)) {
7705 vty_out(vty, "Could not enable PIM SM on interface\n");
7706 return CMD_WARNING_CONFIG_FAILED;
7707 }
7708
7709 pim_ifp = ifp->info;
7710
7711 pim_if_create_pimreg(pim_ifp->pim);
7712
7713 return CMD_SUCCESS;
7714 }
7715
7716 DEFUN_HIDDEN (interface_ip_pim_sm,
7717 interface_ip_pim_sm_cmd,
7718 "ip pim sm",
7719 IP_STR
7720 PIM_STR
7721 IFACE_PIM_SM_STR)
7722 {
7723 return interface_ip_pim_helper(vty);
7724 }
7725
7726 DEFUN (interface_ip_pim,
7727 interface_ip_pim_cmd,
7728 "ip pim",
7729 IP_STR
7730 PIM_STR)
7731 {
7732 return interface_ip_pim_helper(vty);
7733 }
7734
7735 static int pim_cmd_interface_delete(struct interface *ifp)
7736 {
7737 struct pim_interface *pim_ifp = ifp->info;
7738
7739 if (!pim_ifp)
7740 return 1;
7741
7742 PIM_IF_DONT_PIM(pim_ifp->options);
7743
7744 pim_if_membership_clear(ifp);
7745
7746 /*
7747 pim_sock_delete() removes all neighbors from
7748 pim_ifp->pim_neighbor_list.
7749 */
7750 pim_sock_delete(ifp, "pim unconfigured on interface");
7751
7752 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7753 pim_if_addr_del_all(ifp);
7754 pim_if_delete(ifp);
7755 }
7756
7757 return 1;
7758 }
7759
7760 static int interface_no_ip_pim_helper(struct vty *vty)
7761 {
7762 VTY_DECLVAR_CONTEXT(interface, ifp);
7763 if (!pim_cmd_interface_delete(ifp)) {
7764 vty_out(vty, "Unable to delete interface information\n");
7765 return CMD_WARNING_CONFIG_FAILED;
7766 }
7767
7768 return CMD_SUCCESS;
7769 }
7770
7771 DEFUN_HIDDEN (interface_no_ip_pim_ssm,
7772 interface_no_ip_pim_ssm_cmd,
7773 "no ip pim ssm",
7774 NO_STR
7775 IP_STR
7776 PIM_STR
7777 IFACE_PIM_STR)
7778 {
7779 return interface_no_ip_pim_helper(vty);
7780 }
7781
7782 DEFUN_HIDDEN (interface_no_ip_pim_sm,
7783 interface_no_ip_pim_sm_cmd,
7784 "no ip pim sm",
7785 NO_STR
7786 IP_STR
7787 PIM_STR
7788 IFACE_PIM_SM_STR)
7789 {
7790 return interface_no_ip_pim_helper(vty);
7791 }
7792
7793 DEFUN (interface_no_ip_pim,
7794 interface_no_ip_pim_cmd,
7795 "no ip pim",
7796 NO_STR
7797 IP_STR
7798 PIM_STR)
7799 {
7800 return interface_no_ip_pim_helper(vty);
7801 }
7802
7803 /* boundaries */
7804 DEFUN(interface_ip_pim_boundary_oil,
7805 interface_ip_pim_boundary_oil_cmd,
7806 "ip multicast boundary oil WORD",
7807 IP_STR
7808 "Generic multicast configuration options\n"
7809 "Define multicast boundary\n"
7810 "Filter OIL by group using prefix list\n"
7811 "Prefix list to filter OIL with\n")
7812 {
7813 VTY_DECLVAR_CONTEXT(interface, iif);
7814 struct pim_interface *pim_ifp;
7815 int idx = 0;
7816
7817 argv_find(argv, argc, "WORD", &idx);
7818
7819 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7820
7821 if (pim_ifp->boundary_oil_plist)
7822 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7823
7824 pim_ifp->boundary_oil_plist =
7825 XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
7826
7827 /* Interface will be pruned from OIL on next Join */
7828 return CMD_SUCCESS;
7829 }
7830
7831 DEFUN(interface_no_ip_pim_boundary_oil,
7832 interface_no_ip_pim_boundary_oil_cmd,
7833 "no ip multicast boundary oil [WORD]",
7834 NO_STR
7835 IP_STR
7836 "Generic multicast configuration options\n"
7837 "Define multicast boundary\n"
7838 "Filter OIL by group using prefix list\n"
7839 "Prefix list to filter OIL with\n")
7840 {
7841 VTY_DECLVAR_CONTEXT(interface, iif);
7842 struct pim_interface *pim_ifp;
7843 int idx = 0;
7844
7845 argv_find(argv, argc, "WORD", &idx);
7846
7847 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7848
7849 if (pim_ifp->boundary_oil_plist)
7850 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7851
7852 return CMD_SUCCESS;
7853 }
7854
7855 DEFUN (interface_ip_mroute,
7856 interface_ip_mroute_cmd,
7857 "ip mroute INTERFACE A.B.C.D",
7858 IP_STR
7859 "Add multicast route\n"
7860 "Outgoing interface name\n"
7861 "Group address\n")
7862 {
7863 VTY_DECLVAR_CONTEXT(interface, iif);
7864 struct pim_interface *pim_ifp;
7865 struct pim_instance *pim;
7866 int idx_interface = 2;
7867 int idx_ipv4 = 3;
7868 struct interface *oif;
7869 const char *oifname;
7870 const char *grp_str;
7871 struct in_addr grp_addr;
7872 struct in_addr src_addr;
7873 int result;
7874
7875 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7876 pim = pim_ifp->pim;
7877
7878 oifname = argv[idx_interface]->arg;
7879 oif = if_lookup_by_name(oifname, pim->vrf_id);
7880 if (!oif) {
7881 vty_out(vty, "No such interface name %s\n", oifname);
7882 return CMD_WARNING;
7883 }
7884
7885 grp_str = argv[idx_ipv4]->arg;
7886 result = inet_pton(AF_INET, grp_str, &grp_addr);
7887 if (result <= 0) {
7888 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7889 errno, safe_strerror(errno));
7890 return CMD_WARNING;
7891 }
7892
7893 src_addr.s_addr = INADDR_ANY;
7894
7895 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
7896 vty_out(vty, "Failed to add route\n");
7897 return CMD_WARNING;
7898 }
7899
7900 return CMD_SUCCESS;
7901 }
7902
7903 DEFUN (interface_ip_mroute_source,
7904 interface_ip_mroute_source_cmd,
7905 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7906 IP_STR
7907 "Add multicast route\n"
7908 "Outgoing interface name\n"
7909 "Group address\n"
7910 "Source address\n")
7911 {
7912 VTY_DECLVAR_CONTEXT(interface, iif);
7913 struct pim_interface *pim_ifp;
7914 struct pim_instance *pim;
7915 int idx_interface = 2;
7916 int idx_ipv4 = 3;
7917 int idx_ipv4_2 = 4;
7918 struct interface *oif;
7919 const char *oifname;
7920 const char *grp_str;
7921 struct in_addr grp_addr;
7922 const char *src_str;
7923 struct in_addr src_addr;
7924 int result;
7925
7926 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7927 pim = pim_ifp->pim;
7928
7929 oifname = argv[idx_interface]->arg;
7930 oif = if_lookup_by_name(oifname, pim->vrf_id);
7931 if (!oif) {
7932 vty_out(vty, "No such interface name %s\n", oifname);
7933 return CMD_WARNING;
7934 }
7935
7936 grp_str = argv[idx_ipv4]->arg;
7937 result = inet_pton(AF_INET, grp_str, &grp_addr);
7938 if (result <= 0) {
7939 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7940 errno, safe_strerror(errno));
7941 return CMD_WARNING;
7942 }
7943
7944 src_str = argv[idx_ipv4_2]->arg;
7945 result = inet_pton(AF_INET, src_str, &src_addr);
7946 if (result <= 0) {
7947 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
7948 errno, safe_strerror(errno));
7949 return CMD_WARNING;
7950 }
7951
7952 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
7953 vty_out(vty, "Failed to add route\n");
7954 return CMD_WARNING;
7955 }
7956
7957 return CMD_SUCCESS;
7958 }
7959
7960 DEFUN (interface_no_ip_mroute,
7961 interface_no_ip_mroute_cmd,
7962 "no ip mroute INTERFACE A.B.C.D",
7963 NO_STR
7964 IP_STR
7965 "Add multicast route\n"
7966 "Outgoing interface name\n"
7967 "Group Address\n")
7968 {
7969 VTY_DECLVAR_CONTEXT(interface, iif);
7970 struct pim_interface *pim_ifp;
7971 struct pim_instance *pim;
7972 int idx_interface = 3;
7973 int idx_ipv4 = 4;
7974 struct interface *oif;
7975 const char *oifname;
7976 const char *grp_str;
7977 struct in_addr grp_addr;
7978 struct in_addr src_addr;
7979 int result;
7980
7981 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7982 pim = pim_ifp->pim;
7983
7984 oifname = argv[idx_interface]->arg;
7985 oif = if_lookup_by_name(oifname, pim->vrf_id);
7986 if (!oif) {
7987 vty_out(vty, "No such interface name %s\n", oifname);
7988 return CMD_WARNING;
7989 }
7990
7991 grp_str = argv[idx_ipv4]->arg;
7992 result = inet_pton(AF_INET, grp_str, &grp_addr);
7993 if (result <= 0) {
7994 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7995 errno, safe_strerror(errno));
7996 return CMD_WARNING;
7997 }
7998
7999 src_addr.s_addr = INADDR_ANY;
8000
8001 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
8002 vty_out(vty, "Failed to remove route\n");
8003 return CMD_WARNING;
8004 }
8005
8006 return CMD_SUCCESS;
8007 }
8008
8009 DEFUN (interface_no_ip_mroute_source,
8010 interface_no_ip_mroute_source_cmd,
8011 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
8012 NO_STR
8013 IP_STR
8014 "Add multicast route\n"
8015 "Outgoing interface name\n"
8016 "Group Address\n"
8017 "Source Address\n")
8018 {
8019 VTY_DECLVAR_CONTEXT(interface, iif);
8020 struct pim_interface *pim_ifp;
8021 struct pim_instance *pim;
8022 int idx_interface = 3;
8023 int idx_ipv4 = 4;
8024 int idx_ipv4_2 = 5;
8025 struct interface *oif;
8026 const char *oifname;
8027 const char *grp_str;
8028 struct in_addr grp_addr;
8029 const char *src_str;
8030 struct in_addr src_addr;
8031 int result;
8032
8033 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
8034 pim = pim_ifp->pim;
8035
8036 oifname = argv[idx_interface]->arg;
8037 oif = if_lookup_by_name(oifname, pim->vrf_id);
8038 if (!oif) {
8039 vty_out(vty, "No such interface name %s\n", oifname);
8040 return CMD_WARNING;
8041 }
8042
8043 grp_str = argv[idx_ipv4]->arg;
8044 result = inet_pton(AF_INET, grp_str, &grp_addr);
8045 if (result <= 0) {
8046 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
8047 errno, safe_strerror(errno));
8048 return CMD_WARNING;
8049 }
8050
8051 src_str = argv[idx_ipv4_2]->arg;
8052 result = inet_pton(AF_INET, src_str, &src_addr);
8053 if (result <= 0) {
8054 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
8055 errno, safe_strerror(errno));
8056 return CMD_WARNING;
8057 }
8058
8059 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
8060 vty_out(vty, "Failed to remove route\n");
8061 return CMD_WARNING;
8062 }
8063
8064 return CMD_SUCCESS;
8065 }
8066
8067 DEFUN (interface_ip_pim_hello,
8068 interface_ip_pim_hello_cmd,
8069 "ip pim hello (1-180) [(1-180)]",
8070 IP_STR
8071 PIM_STR
8072 IFACE_PIM_HELLO_STR
8073 IFACE_PIM_HELLO_TIME_STR
8074 IFACE_PIM_HELLO_HOLD_STR)
8075 {
8076 VTY_DECLVAR_CONTEXT(interface, ifp);
8077 int idx_time = 3;
8078 int idx_hold = 4;
8079 struct pim_interface *pim_ifp = ifp->info;
8080
8081 if (!pim_ifp) {
8082 if (!pim_cmd_interface_add(ifp)) {
8083 vty_out(vty, "Could not enable PIM SM on interface\n");
8084 return CMD_WARNING_CONFIG_FAILED;
8085 }
8086 }
8087
8088 pim_ifp = ifp->info;
8089 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
8090
8091 if (argc == idx_hold + 1)
8092 pim_ifp->pim_default_holdtime =
8093 strtol(argv[idx_hold]->arg, NULL, 10);
8094
8095 return CMD_SUCCESS;
8096 }
8097
8098 DEFUN (interface_no_ip_pim_hello,
8099 interface_no_ip_pim_hello_cmd,
8100 "no ip pim hello [(1-180) (1-180)]",
8101 NO_STR
8102 IP_STR
8103 PIM_STR
8104 IFACE_PIM_HELLO_STR
8105 IFACE_PIM_HELLO_TIME_STR
8106 IFACE_PIM_HELLO_HOLD_STR)
8107 {
8108 VTY_DECLVAR_CONTEXT(interface, ifp);
8109 struct pim_interface *pim_ifp = ifp->info;
8110
8111 if (!pim_ifp) {
8112 vty_out(vty, "Pim not enabled on this interface\n");
8113 return CMD_WARNING_CONFIG_FAILED;
8114 }
8115
8116 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
8117 pim_ifp->pim_default_holdtime = -1;
8118
8119 return CMD_SUCCESS;
8120 }
8121
8122 DEFUN (debug_igmp,
8123 debug_igmp_cmd,
8124 "debug igmp",
8125 DEBUG_STR
8126 DEBUG_IGMP_STR)
8127 {
8128 PIM_DO_DEBUG_IGMP_EVENTS;
8129 PIM_DO_DEBUG_IGMP_PACKETS;
8130 PIM_DO_DEBUG_IGMP_TRACE;
8131 return CMD_SUCCESS;
8132 }
8133
8134 DEFUN (no_debug_igmp,
8135 no_debug_igmp_cmd,
8136 "no debug igmp",
8137 NO_STR
8138 DEBUG_STR
8139 DEBUG_IGMP_STR)
8140 {
8141 PIM_DONT_DEBUG_IGMP_EVENTS;
8142 PIM_DONT_DEBUG_IGMP_PACKETS;
8143 PIM_DONT_DEBUG_IGMP_TRACE;
8144 return CMD_SUCCESS;
8145 }
8146
8147
8148 DEFUN (debug_igmp_events,
8149 debug_igmp_events_cmd,
8150 "debug igmp events",
8151 DEBUG_STR
8152 DEBUG_IGMP_STR
8153 DEBUG_IGMP_EVENTS_STR)
8154 {
8155 PIM_DO_DEBUG_IGMP_EVENTS;
8156 return CMD_SUCCESS;
8157 }
8158
8159 DEFUN (no_debug_igmp_events,
8160 no_debug_igmp_events_cmd,
8161 "no debug igmp events",
8162 NO_STR
8163 DEBUG_STR
8164 DEBUG_IGMP_STR
8165 DEBUG_IGMP_EVENTS_STR)
8166 {
8167 PIM_DONT_DEBUG_IGMP_EVENTS;
8168 return CMD_SUCCESS;
8169 }
8170
8171
8172 DEFUN (debug_igmp_packets,
8173 debug_igmp_packets_cmd,
8174 "debug igmp packets",
8175 DEBUG_STR
8176 DEBUG_IGMP_STR
8177 DEBUG_IGMP_PACKETS_STR)
8178 {
8179 PIM_DO_DEBUG_IGMP_PACKETS;
8180 return CMD_SUCCESS;
8181 }
8182
8183 DEFUN (no_debug_igmp_packets,
8184 no_debug_igmp_packets_cmd,
8185 "no debug igmp packets",
8186 NO_STR
8187 DEBUG_STR
8188 DEBUG_IGMP_STR
8189 DEBUG_IGMP_PACKETS_STR)
8190 {
8191 PIM_DONT_DEBUG_IGMP_PACKETS;
8192 return CMD_SUCCESS;
8193 }
8194
8195
8196 DEFUN (debug_igmp_trace,
8197 debug_igmp_trace_cmd,
8198 "debug igmp trace",
8199 DEBUG_STR
8200 DEBUG_IGMP_STR
8201 DEBUG_IGMP_TRACE_STR)
8202 {
8203 PIM_DO_DEBUG_IGMP_TRACE;
8204 return CMD_SUCCESS;
8205 }
8206
8207 DEFUN (no_debug_igmp_trace,
8208 no_debug_igmp_trace_cmd,
8209 "no debug igmp trace",
8210 NO_STR
8211 DEBUG_STR
8212 DEBUG_IGMP_STR
8213 DEBUG_IGMP_TRACE_STR)
8214 {
8215 PIM_DONT_DEBUG_IGMP_TRACE;
8216 return CMD_SUCCESS;
8217 }
8218
8219
8220 DEFUN (debug_mroute,
8221 debug_mroute_cmd,
8222 "debug mroute",
8223 DEBUG_STR
8224 DEBUG_MROUTE_STR)
8225 {
8226 PIM_DO_DEBUG_MROUTE;
8227 return CMD_SUCCESS;
8228 }
8229
8230 DEFUN (debug_mroute_detail,
8231 debug_mroute_detail_cmd,
8232 "debug mroute detail",
8233 DEBUG_STR
8234 DEBUG_MROUTE_STR
8235 "detailed\n")
8236 {
8237 PIM_DO_DEBUG_MROUTE_DETAIL;
8238 return CMD_SUCCESS;
8239 }
8240
8241 DEFUN (no_debug_mroute,
8242 no_debug_mroute_cmd,
8243 "no debug mroute",
8244 NO_STR
8245 DEBUG_STR
8246 DEBUG_MROUTE_STR)
8247 {
8248 PIM_DONT_DEBUG_MROUTE;
8249 return CMD_SUCCESS;
8250 }
8251
8252 DEFUN (no_debug_mroute_detail,
8253 no_debug_mroute_detail_cmd,
8254 "no debug mroute detail",
8255 NO_STR
8256 DEBUG_STR
8257 DEBUG_MROUTE_STR
8258 "detailed\n")
8259 {
8260 PIM_DONT_DEBUG_MROUTE_DETAIL;
8261 return CMD_SUCCESS;
8262 }
8263
8264 DEFUN (debug_pim_static,
8265 debug_pim_static_cmd,
8266 "debug pim static",
8267 DEBUG_STR
8268 DEBUG_PIM_STR
8269 DEBUG_STATIC_STR)
8270 {
8271 PIM_DO_DEBUG_STATIC;
8272 return CMD_SUCCESS;
8273 }
8274
8275 DEFUN (no_debug_pim_static,
8276 no_debug_pim_static_cmd,
8277 "no debug pim static",
8278 NO_STR
8279 DEBUG_STR
8280 DEBUG_PIM_STR
8281 DEBUG_STATIC_STR)
8282 {
8283 PIM_DONT_DEBUG_STATIC;
8284 return CMD_SUCCESS;
8285 }
8286
8287
8288 DEFUN (debug_pim,
8289 debug_pim_cmd,
8290 "debug pim",
8291 DEBUG_STR
8292 DEBUG_PIM_STR)
8293 {
8294 PIM_DO_DEBUG_PIM_EVENTS;
8295 PIM_DO_DEBUG_PIM_PACKETS;
8296 PIM_DO_DEBUG_PIM_TRACE;
8297 PIM_DO_DEBUG_MSDP_EVENTS;
8298 PIM_DO_DEBUG_MSDP_PACKETS;
8299 PIM_DO_DEBUG_BSM;
8300 return CMD_SUCCESS;
8301 }
8302
8303 DEFUN (no_debug_pim,
8304 no_debug_pim_cmd,
8305 "no debug pim",
8306 NO_STR
8307 DEBUG_STR
8308 DEBUG_PIM_STR)
8309 {
8310 PIM_DONT_DEBUG_PIM_EVENTS;
8311 PIM_DONT_DEBUG_PIM_PACKETS;
8312 PIM_DONT_DEBUG_PIM_TRACE;
8313 PIM_DONT_DEBUG_MSDP_EVENTS;
8314 PIM_DONT_DEBUG_MSDP_PACKETS;
8315
8316 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8317 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8318 PIM_DONT_DEBUG_BSM;
8319
8320 return CMD_SUCCESS;
8321 }
8322
8323 DEFUN (debug_pim_nht,
8324 debug_pim_nht_cmd,
8325 "debug pim nht",
8326 DEBUG_STR
8327 DEBUG_PIM_STR
8328 "Nexthop Tracking\n")
8329 {
8330 PIM_DO_DEBUG_PIM_NHT;
8331 return CMD_SUCCESS;
8332 }
8333
8334 DEFUN (no_debug_pim_nht,
8335 no_debug_pim_nht_cmd,
8336 "no debug pim nht",
8337 NO_STR
8338 DEBUG_STR
8339 DEBUG_PIM_STR
8340 "Nexthop Tracking\n")
8341 {
8342 PIM_DONT_DEBUG_PIM_NHT;
8343 return CMD_SUCCESS;
8344 }
8345
8346 DEFUN (debug_pim_nht_rp,
8347 debug_pim_nht_rp_cmd,
8348 "debug pim nht rp",
8349 DEBUG_STR
8350 DEBUG_PIM_STR
8351 "Nexthop Tracking\n"
8352 "RP Nexthop Tracking\n")
8353 {
8354 PIM_DO_DEBUG_PIM_NHT_RP;
8355 return CMD_SUCCESS;
8356 }
8357
8358 DEFUN (no_debug_pim_nht_rp,
8359 no_debug_pim_nht_rp_cmd,
8360 "no debug pim nht rp",
8361 NO_STR
8362 DEBUG_STR
8363 DEBUG_PIM_STR
8364 "Nexthop Tracking\n"
8365 "RP Nexthop Tracking\n")
8366 {
8367 PIM_DONT_DEBUG_PIM_NHT_RP;
8368 return CMD_SUCCESS;
8369 }
8370
8371 DEFUN (debug_pim_events,
8372 debug_pim_events_cmd,
8373 "debug pim events",
8374 DEBUG_STR
8375 DEBUG_PIM_STR
8376 DEBUG_PIM_EVENTS_STR)
8377 {
8378 PIM_DO_DEBUG_PIM_EVENTS;
8379 return CMD_SUCCESS;
8380 }
8381
8382 DEFUN (no_debug_pim_events,
8383 no_debug_pim_events_cmd,
8384 "no debug pim events",
8385 NO_STR
8386 DEBUG_STR
8387 DEBUG_PIM_STR
8388 DEBUG_PIM_EVENTS_STR)
8389 {
8390 PIM_DONT_DEBUG_PIM_EVENTS;
8391 return CMD_SUCCESS;
8392 }
8393
8394 DEFUN (debug_pim_packets,
8395 debug_pim_packets_cmd,
8396 "debug pim packets [<hello|joins|register>]",
8397 DEBUG_STR
8398 DEBUG_PIM_STR
8399 DEBUG_PIM_PACKETS_STR
8400 DEBUG_PIM_HELLO_PACKETS_STR
8401 DEBUG_PIM_J_P_PACKETS_STR
8402 DEBUG_PIM_PIM_REG_PACKETS_STR)
8403 {
8404 int idx = 0;
8405 if (argv_find(argv, argc, "hello", &idx)) {
8406 PIM_DO_DEBUG_PIM_HELLO;
8407 vty_out(vty, "PIM Hello debugging is on\n");
8408 } else if (argv_find(argv, argc, "joins", &idx)) {
8409 PIM_DO_DEBUG_PIM_J_P;
8410 vty_out(vty, "PIM Join/Prune debugging is on\n");
8411 } else if (argv_find(argv, argc, "register", &idx)) {
8412 PIM_DO_DEBUG_PIM_REG;
8413 vty_out(vty, "PIM Register debugging is on\n");
8414 } else {
8415 PIM_DO_DEBUG_PIM_PACKETS;
8416 vty_out(vty, "PIM Packet debugging is on \n");
8417 }
8418 return CMD_SUCCESS;
8419 }
8420
8421 DEFUN (no_debug_pim_packets,
8422 no_debug_pim_packets_cmd,
8423 "no debug pim packets [<hello|joins|register>]",
8424 NO_STR
8425 DEBUG_STR
8426 DEBUG_PIM_STR
8427 DEBUG_PIM_PACKETS_STR
8428 DEBUG_PIM_HELLO_PACKETS_STR
8429 DEBUG_PIM_J_P_PACKETS_STR
8430 DEBUG_PIM_PIM_REG_PACKETS_STR)
8431 {
8432 int idx = 0;
8433 if (argv_find(argv, argc, "hello", &idx)) {
8434 PIM_DONT_DEBUG_PIM_HELLO;
8435 vty_out(vty, "PIM Hello debugging is off \n");
8436 } else if (argv_find(argv, argc, "joins", &idx)) {
8437 PIM_DONT_DEBUG_PIM_J_P;
8438 vty_out(vty, "PIM Join/Prune debugging is off \n");
8439 } else if (argv_find(argv, argc, "register", &idx)) {
8440 PIM_DONT_DEBUG_PIM_REG;
8441 vty_out(vty, "PIM Register debugging is off\n");
8442 } else
8443 PIM_DONT_DEBUG_PIM_PACKETS;
8444
8445 return CMD_SUCCESS;
8446 }
8447
8448
8449 DEFUN (debug_pim_packetdump_send,
8450 debug_pim_packetdump_send_cmd,
8451 "debug pim packet-dump send",
8452 DEBUG_STR
8453 DEBUG_PIM_STR
8454 DEBUG_PIM_PACKETDUMP_STR
8455 DEBUG_PIM_PACKETDUMP_SEND_STR)
8456 {
8457 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
8458 return CMD_SUCCESS;
8459 }
8460
8461 DEFUN (no_debug_pim_packetdump_send,
8462 no_debug_pim_packetdump_send_cmd,
8463 "no debug pim packet-dump send",
8464 NO_STR
8465 DEBUG_STR
8466 DEBUG_PIM_STR
8467 DEBUG_PIM_PACKETDUMP_STR
8468 DEBUG_PIM_PACKETDUMP_SEND_STR)
8469 {
8470 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8471 return CMD_SUCCESS;
8472 }
8473
8474 DEFUN (debug_pim_packetdump_recv,
8475 debug_pim_packetdump_recv_cmd,
8476 "debug pim packet-dump receive",
8477 DEBUG_STR
8478 DEBUG_PIM_STR
8479 DEBUG_PIM_PACKETDUMP_STR
8480 DEBUG_PIM_PACKETDUMP_RECV_STR)
8481 {
8482 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
8483 return CMD_SUCCESS;
8484 }
8485
8486 DEFUN (no_debug_pim_packetdump_recv,
8487 no_debug_pim_packetdump_recv_cmd,
8488 "no debug pim packet-dump receive",
8489 NO_STR
8490 DEBUG_STR
8491 DEBUG_PIM_STR
8492 DEBUG_PIM_PACKETDUMP_STR
8493 DEBUG_PIM_PACKETDUMP_RECV_STR)
8494 {
8495 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8496 return CMD_SUCCESS;
8497 }
8498
8499 DEFUN (debug_pim_trace,
8500 debug_pim_trace_cmd,
8501 "debug pim trace",
8502 DEBUG_STR
8503 DEBUG_PIM_STR
8504 DEBUG_PIM_TRACE_STR)
8505 {
8506 PIM_DO_DEBUG_PIM_TRACE;
8507 return CMD_SUCCESS;
8508 }
8509
8510 DEFUN (debug_pim_trace_detail,
8511 debug_pim_trace_detail_cmd,
8512 "debug pim trace detail",
8513 DEBUG_STR
8514 DEBUG_PIM_STR
8515 DEBUG_PIM_TRACE_STR
8516 "Detailed Information\n")
8517 {
8518 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
8519 return CMD_SUCCESS;
8520 }
8521
8522 DEFUN (no_debug_pim_trace,
8523 no_debug_pim_trace_cmd,
8524 "no debug pim trace",
8525 NO_STR
8526 DEBUG_STR
8527 DEBUG_PIM_STR
8528 DEBUG_PIM_TRACE_STR)
8529 {
8530 PIM_DONT_DEBUG_PIM_TRACE;
8531 return CMD_SUCCESS;
8532 }
8533
8534 DEFUN (no_debug_pim_trace_detail,
8535 no_debug_pim_trace_detail_cmd,
8536 "no debug pim trace detail",
8537 NO_STR
8538 DEBUG_STR
8539 DEBUG_PIM_STR
8540 DEBUG_PIM_TRACE_STR
8541 "Detailed Information\n")
8542 {
8543 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
8544 return CMD_SUCCESS;
8545 }
8546
8547 DEFUN (debug_ssmpingd,
8548 debug_ssmpingd_cmd,
8549 "debug ssmpingd",
8550 DEBUG_STR
8551 DEBUG_SSMPINGD_STR)
8552 {
8553 PIM_DO_DEBUG_SSMPINGD;
8554 return CMD_SUCCESS;
8555 }
8556
8557 DEFUN (no_debug_ssmpingd,
8558 no_debug_ssmpingd_cmd,
8559 "no debug ssmpingd",
8560 NO_STR
8561 DEBUG_STR
8562 DEBUG_SSMPINGD_STR)
8563 {
8564 PIM_DONT_DEBUG_SSMPINGD;
8565 return CMD_SUCCESS;
8566 }
8567
8568 DEFUN (debug_pim_zebra,
8569 debug_pim_zebra_cmd,
8570 "debug pim zebra",
8571 DEBUG_STR
8572 DEBUG_PIM_STR
8573 DEBUG_PIM_ZEBRA_STR)
8574 {
8575 PIM_DO_DEBUG_ZEBRA;
8576 return CMD_SUCCESS;
8577 }
8578
8579 DEFUN (no_debug_pim_zebra,
8580 no_debug_pim_zebra_cmd,
8581 "no debug pim zebra",
8582 NO_STR
8583 DEBUG_STR
8584 DEBUG_PIM_STR
8585 DEBUG_PIM_ZEBRA_STR)
8586 {
8587 PIM_DONT_DEBUG_ZEBRA;
8588 return CMD_SUCCESS;
8589 }
8590
8591 DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
8592 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8593 {
8594 PIM_DO_DEBUG_MLAG;
8595 return CMD_SUCCESS;
8596 }
8597
8598 DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
8599 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8600 {
8601 PIM_DONT_DEBUG_MLAG;
8602 return CMD_SUCCESS;
8603 }
8604
8605 DEFUN (debug_pim_vxlan,
8606 debug_pim_vxlan_cmd,
8607 "debug pim vxlan",
8608 DEBUG_STR
8609 DEBUG_PIM_STR
8610 DEBUG_PIM_VXLAN_STR)
8611 {
8612 PIM_DO_DEBUG_VXLAN;
8613 return CMD_SUCCESS;
8614 }
8615
8616 DEFUN (no_debug_pim_vxlan,
8617 no_debug_pim_vxlan_cmd,
8618 "no debug pim vxlan",
8619 NO_STR
8620 DEBUG_STR
8621 DEBUG_PIM_STR
8622 DEBUG_PIM_VXLAN_STR)
8623 {
8624 PIM_DONT_DEBUG_VXLAN;
8625 return CMD_SUCCESS;
8626 }
8627
8628 DEFUN (debug_msdp,
8629 debug_msdp_cmd,
8630 "debug msdp",
8631 DEBUG_STR
8632 DEBUG_MSDP_STR)
8633 {
8634 PIM_DO_DEBUG_MSDP_EVENTS;
8635 PIM_DO_DEBUG_MSDP_PACKETS;
8636 return CMD_SUCCESS;
8637 }
8638
8639 DEFUN (no_debug_msdp,
8640 no_debug_msdp_cmd,
8641 "no debug msdp",
8642 NO_STR
8643 DEBUG_STR
8644 DEBUG_MSDP_STR)
8645 {
8646 PIM_DONT_DEBUG_MSDP_EVENTS;
8647 PIM_DONT_DEBUG_MSDP_PACKETS;
8648 return CMD_SUCCESS;
8649 }
8650
8651 DEFUN (debug_msdp_events,
8652 debug_msdp_events_cmd,
8653 "debug msdp events",
8654 DEBUG_STR
8655 DEBUG_MSDP_STR
8656 DEBUG_MSDP_EVENTS_STR)
8657 {
8658 PIM_DO_DEBUG_MSDP_EVENTS;
8659 return CMD_SUCCESS;
8660 }
8661
8662 DEFUN (no_debug_msdp_events,
8663 no_debug_msdp_events_cmd,
8664 "no debug msdp events",
8665 NO_STR
8666 DEBUG_STR
8667 DEBUG_MSDP_STR
8668 DEBUG_MSDP_EVENTS_STR)
8669 {
8670 PIM_DONT_DEBUG_MSDP_EVENTS;
8671 return CMD_SUCCESS;
8672 }
8673
8674 DEFUN (debug_msdp_packets,
8675 debug_msdp_packets_cmd,
8676 "debug msdp packets",
8677 DEBUG_STR
8678 DEBUG_MSDP_STR
8679 DEBUG_MSDP_PACKETS_STR)
8680 {
8681 PIM_DO_DEBUG_MSDP_PACKETS;
8682 return CMD_SUCCESS;
8683 }
8684
8685 DEFUN (no_debug_msdp_packets,
8686 no_debug_msdp_packets_cmd,
8687 "no debug msdp packets",
8688 NO_STR
8689 DEBUG_STR
8690 DEBUG_MSDP_STR
8691 DEBUG_MSDP_PACKETS_STR)
8692 {
8693 PIM_DONT_DEBUG_MSDP_PACKETS;
8694 return CMD_SUCCESS;
8695 }
8696
8697 DEFUN (debug_mtrace,
8698 debug_mtrace_cmd,
8699 "debug mtrace",
8700 DEBUG_STR
8701 DEBUG_MTRACE_STR)
8702 {
8703 PIM_DO_DEBUG_MTRACE;
8704 return CMD_SUCCESS;
8705 }
8706
8707 DEFUN (no_debug_mtrace,
8708 no_debug_mtrace_cmd,
8709 "no debug mtrace",
8710 NO_STR
8711 DEBUG_STR
8712 DEBUG_MTRACE_STR)
8713 {
8714 PIM_DONT_DEBUG_MTRACE;
8715 return CMD_SUCCESS;
8716 }
8717
8718 DEFUN (debug_bsm,
8719 debug_bsm_cmd,
8720 "debug pim bsm",
8721 DEBUG_STR
8722 DEBUG_PIM_STR
8723 DEBUG_PIM_BSM_STR)
8724 {
8725 PIM_DO_DEBUG_BSM;
8726 return CMD_SUCCESS;
8727 }
8728
8729 DEFUN (no_debug_bsm,
8730 no_debug_bsm_cmd,
8731 "no debug pim bsm",
8732 NO_STR
8733 DEBUG_STR
8734 DEBUG_PIM_STR
8735 DEBUG_PIM_BSM_STR)
8736 {
8737 PIM_DONT_DEBUG_BSM;
8738 return CMD_SUCCESS;
8739 }
8740
8741
8742 DEFUN_NOSH (show_debugging_pim,
8743 show_debugging_pim_cmd,
8744 "show debugging [pim]",
8745 SHOW_STR
8746 DEBUG_STR
8747 PIM_STR)
8748 {
8749 vty_out(vty, "PIM debugging status\n");
8750
8751 pim_debug_config_write(vty);
8752
8753 return CMD_SUCCESS;
8754 }
8755
8756 static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
8757 {
8758 int result;
8759 struct in_addr source_addr;
8760 int ret = CMD_SUCCESS;
8761 VTY_DECLVAR_CONTEXT(interface, ifp);
8762
8763 result = inet_pton(AF_INET, source, &source_addr);
8764 if (result <= 0) {
8765 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
8766 errno, safe_strerror(errno));
8767 return CMD_WARNING_CONFIG_FAILED;
8768 }
8769
8770 result = pim_update_source_set(ifp, source_addr);
8771 switch (result) {
8772 case PIM_SUCCESS:
8773 break;
8774 case PIM_IFACE_NOT_FOUND:
8775 ret = CMD_WARNING_CONFIG_FAILED;
8776 vty_out(vty, "Pim not enabled on this interface\n");
8777 break;
8778 case PIM_UPDATE_SOURCE_DUP:
8779 ret = CMD_WARNING;
8780 vty_out(vty, "%% Source already set to %s\n", source);
8781 break;
8782 default:
8783 ret = CMD_WARNING_CONFIG_FAILED;
8784 vty_out(vty, "%% Source set failed\n");
8785 }
8786
8787 return ret;
8788 }
8789
8790 DEFUN (interface_pim_use_source,
8791 interface_pim_use_source_cmd,
8792 "ip pim use-source A.B.C.D",
8793 IP_STR
8794 PIM_STR
8795 "Configure primary IP address\n"
8796 "source ip address\n")
8797 {
8798 return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
8799 }
8800
8801 DEFUN (interface_no_pim_use_source,
8802 interface_no_pim_use_source_cmd,
8803 "no ip pim use-source [A.B.C.D]",
8804 NO_STR
8805 IP_STR
8806 PIM_STR
8807 "Delete source IP address\n"
8808 "source ip address\n")
8809 {
8810 return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
8811 }
8812
8813 DEFUN (ip_pim_bfd,
8814 ip_pim_bfd_cmd,
8815 "ip pim bfd",
8816 IP_STR
8817 PIM_STR
8818 "Enables BFD support\n")
8819 {
8820 VTY_DECLVAR_CONTEXT(interface, ifp);
8821 struct pim_interface *pim_ifp = ifp->info;
8822 struct bfd_info *bfd_info = NULL;
8823
8824 if (!pim_ifp) {
8825 if (!pim_cmd_interface_add(ifp)) {
8826 vty_out(vty, "Could not enable PIM SM on interface\n");
8827 return CMD_WARNING;
8828 }
8829 }
8830 pim_ifp = ifp->info;
8831
8832 bfd_info = pim_ifp->bfd_info;
8833
8834 if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
8835 pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
8836 BFD_DEF_DETECT_MULT, 1);
8837
8838 return CMD_SUCCESS;
8839 }
8840
8841 DEFUN (no_ip_pim_bfd,
8842 no_ip_pim_bfd_cmd,
8843 "no ip pim bfd",
8844 NO_STR
8845 IP_STR
8846 PIM_STR
8847 "Disables BFD support\n")
8848 {
8849 VTY_DECLVAR_CONTEXT(interface, ifp);
8850 struct pim_interface *pim_ifp = ifp->info;
8851
8852 if (!pim_ifp) {
8853 vty_out(vty, "Pim not enabled on this interface\n");
8854 return CMD_WARNING;
8855 }
8856
8857 if (pim_ifp->bfd_info) {
8858 pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
8859 bfd_info_free(&(pim_ifp->bfd_info));
8860 }
8861
8862 return CMD_SUCCESS;
8863 }
8864
8865 DEFUN (ip_pim_bsm,
8866 ip_pim_bsm_cmd,
8867 "ip pim bsm",
8868 IP_STR
8869 PIM_STR
8870 "Enables BSM support on the interface\n")
8871 {
8872 VTY_DECLVAR_CONTEXT(interface, ifp);
8873 struct pim_interface *pim_ifp = ifp->info;
8874
8875 if (!pim_ifp) {
8876 if (!pim_cmd_interface_add(ifp)) {
8877 vty_out(vty, "Could not enable PIM SM on interface\n");
8878 return CMD_WARNING;
8879 }
8880 }
8881
8882 pim_ifp = ifp->info;
8883 pim_ifp->bsm_enable = true;
8884
8885 return CMD_SUCCESS;
8886 }
8887
8888 DEFUN (no_ip_pim_bsm,
8889 no_ip_pim_bsm_cmd,
8890 "no ip pim bsm",
8891 NO_STR
8892 IP_STR
8893 PIM_STR
8894 "Disables BSM support\n")
8895 {
8896 VTY_DECLVAR_CONTEXT(interface, ifp);
8897 struct pim_interface *pim_ifp = ifp->info;
8898
8899 if (!pim_ifp) {
8900 vty_out(vty, "Pim not enabled on this interface\n");
8901 return CMD_WARNING;
8902 }
8903
8904 pim_ifp->bsm_enable = false;
8905
8906 return CMD_SUCCESS;
8907 }
8908
8909 DEFUN (ip_pim_ucast_bsm,
8910 ip_pim_ucast_bsm_cmd,
8911 "ip pim unicast-bsm",
8912 IP_STR
8913 PIM_STR
8914 "Accept/Send unicast BSM on the interface\n")
8915 {
8916 VTY_DECLVAR_CONTEXT(interface, ifp);
8917 struct pim_interface *pim_ifp = ifp->info;
8918
8919 if (!pim_ifp) {
8920 if (!pim_cmd_interface_add(ifp)) {
8921 vty_out(vty, "Could not enable PIM SM on interface\n");
8922 return CMD_WARNING;
8923 }
8924 }
8925
8926 pim_ifp = ifp->info;
8927 pim_ifp->ucast_bsm_accept = true;
8928
8929 return CMD_SUCCESS;
8930 }
8931
8932 DEFUN (no_ip_pim_ucast_bsm,
8933 no_ip_pim_ucast_bsm_cmd,
8934 "no ip pim unicast-bsm",
8935 NO_STR
8936 IP_STR
8937 PIM_STR
8938 "Block send/receive unicast BSM on this interface\n")
8939 {
8940 VTY_DECLVAR_CONTEXT(interface, ifp);
8941 struct pim_interface *pim_ifp = ifp->info;
8942
8943 if (!pim_ifp) {
8944 vty_out(vty, "Pim not enabled on this interface\n");
8945 return CMD_WARNING;
8946 }
8947
8948 pim_ifp->ucast_bsm_accept = false;
8949
8950 return CMD_SUCCESS;
8951 }
8952
8953 #if HAVE_BFDD > 0
8954 DEFUN_HIDDEN(
8955 ip_pim_bfd_param,
8956 ip_pim_bfd_param_cmd,
8957 "ip pim bfd (2-255) (50-60000) (50-60000)",
8958 IP_STR
8959 PIM_STR
8960 "Enables BFD support\n"
8961 "Detect Multiplier\n"
8962 "Required min receive interval\n"
8963 "Desired min transmit interval\n")
8964 #else
8965 DEFUN(
8966 ip_pim_bfd_param,
8967 ip_pim_bfd_param_cmd,
8968 "ip pim bfd (2-255) (50-60000) (50-60000)",
8969 IP_STR
8970 PIM_STR
8971 "Enables BFD support\n"
8972 "Detect Multiplier\n"
8973 "Required min receive interval\n"
8974 "Desired min transmit interval\n")
8975 #endif /* HAVE_BFDD */
8976 {
8977 VTY_DECLVAR_CONTEXT(interface, ifp);
8978 int idx_number = 3;
8979 int idx_number_2 = 4;
8980 int idx_number_3 = 5;
8981 uint32_t rx_val;
8982 uint32_t tx_val;
8983 uint8_t dm_val;
8984 int ret;
8985 struct pim_interface *pim_ifp = ifp->info;
8986
8987 if (!pim_ifp) {
8988 if (!pim_cmd_interface_add(ifp)) {
8989 vty_out(vty, "Could not enable PIM SM on interface\n");
8990 return CMD_WARNING;
8991 }
8992 }
8993
8994 if ((ret = bfd_validate_param(
8995 vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
8996 argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
8997 != CMD_SUCCESS)
8998 return ret;
8999
9000 pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
9001
9002 return CMD_SUCCESS;
9003 }
9004
9005 #if HAVE_BFDD == 0
9006 ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
9007 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9008 "Enables BFD support\n"
9009 "Detect Multiplier\n"
9010 "Required min receive interval\n"
9011 "Desired min transmit interval\n")
9012 #endif /* !HAVE_BFDD */
9013
9014 static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
9015 const char *peer, const char *local)
9016 {
9017 enum pim_msdp_err result;
9018 struct in_addr peer_addr;
9019 struct in_addr local_addr;
9020 int ret = CMD_SUCCESS;
9021
9022 result = inet_pton(AF_INET, peer, &peer_addr);
9023 if (result <= 0) {
9024 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
9025 errno, safe_strerror(errno));
9026 return CMD_WARNING_CONFIG_FAILED;
9027 }
9028
9029 result = inet_pton(AF_INET, local, &local_addr);
9030 if (result <= 0) {
9031 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
9032 errno, safe_strerror(errno));
9033 return CMD_WARNING_CONFIG_FAILED;
9034 }
9035
9036 result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
9037 NULL /* mp_p */);
9038 switch (result) {
9039 case PIM_MSDP_ERR_NONE:
9040 break;
9041 case PIM_MSDP_ERR_OOM:
9042 ret = CMD_WARNING_CONFIG_FAILED;
9043 vty_out(vty, "%% Out of memory\n");
9044 break;
9045 case PIM_MSDP_ERR_PEER_EXISTS:
9046 ret = CMD_WARNING;
9047 vty_out(vty, "%% Peer exists\n");
9048 break;
9049 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9050 ret = CMD_WARNING_CONFIG_FAILED;
9051 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9052 break;
9053 default:
9054 ret = CMD_WARNING_CONFIG_FAILED;
9055 vty_out(vty, "%% peer add failed\n");
9056 }
9057
9058 return ret;
9059 }
9060
9061 DEFUN_HIDDEN (ip_msdp_peer,
9062 ip_msdp_peer_cmd,
9063 "ip msdp peer A.B.C.D source A.B.C.D",
9064 IP_STR
9065 CFG_MSDP_STR
9066 "Configure MSDP peer\n"
9067 "peer ip address\n"
9068 "Source address for TCP connection\n"
9069 "local ip address\n")
9070 {
9071 PIM_DECLVAR_CONTEXT(vrf, pim);
9072 return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg);
9073 }
9074
9075 static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
9076 const char *peer)
9077 {
9078 enum pim_msdp_err result;
9079 struct in_addr peer_addr;
9080
9081 result = inet_pton(AF_INET, peer, &peer_addr);
9082 if (result <= 0) {
9083 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
9084 errno, safe_strerror(errno));
9085 return CMD_WARNING_CONFIG_FAILED;
9086 }
9087
9088 result = pim_msdp_peer_del(pim, peer_addr);
9089 switch (result) {
9090 case PIM_MSDP_ERR_NONE:
9091 break;
9092 case PIM_MSDP_ERR_NO_PEER:
9093 vty_out(vty, "%% Peer does not exist\n");
9094 break;
9095 default:
9096 vty_out(vty, "%% peer del failed\n");
9097 }
9098
9099 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9100 }
9101
9102 DEFUN_HIDDEN (no_ip_msdp_peer,
9103 no_ip_msdp_peer_cmd,
9104 "no ip msdp peer A.B.C.D",
9105 NO_STR
9106 IP_STR
9107 CFG_MSDP_STR
9108 "Delete MSDP peer\n"
9109 "peer ip address\n")
9110 {
9111 PIM_DECLVAR_CONTEXT(vrf, pim);
9112 return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg);
9113 }
9114
9115 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9116 struct vty *vty, const char *mg,
9117 const char *mbr)
9118 {
9119 enum pim_msdp_err result;
9120 struct in_addr mbr_ip;
9121 int ret = CMD_SUCCESS;
9122
9123 result = inet_pton(AF_INET, mbr, &mbr_ip);
9124 if (result <= 0) {
9125 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9126 errno, safe_strerror(errno));
9127 return CMD_WARNING_CONFIG_FAILED;
9128 }
9129
9130 result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
9131 switch (result) {
9132 case PIM_MSDP_ERR_NONE:
9133 break;
9134 case PIM_MSDP_ERR_OOM:
9135 ret = CMD_WARNING_CONFIG_FAILED;
9136 vty_out(vty, "%% Out of memory\n");
9137 break;
9138 case PIM_MSDP_ERR_MG_MBR_EXISTS:
9139 ret = CMD_WARNING;
9140 vty_out(vty, "%% mesh-group member exists\n");
9141 break;
9142 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9143 ret = CMD_WARNING_CONFIG_FAILED;
9144 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9145 break;
9146 default:
9147 ret = CMD_WARNING_CONFIG_FAILED;
9148 vty_out(vty, "%% member add failed\n");
9149 }
9150
9151 return ret;
9152 }
9153
9154 DEFUN (ip_msdp_mesh_group_member,
9155 ip_msdp_mesh_group_member_cmd,
9156 "ip msdp mesh-group WORD member A.B.C.D",
9157 IP_STR
9158 CFG_MSDP_STR
9159 "Configure MSDP mesh-group\n"
9160 "mesh group name\n"
9161 "mesh group member\n"
9162 "peer ip address\n")
9163 {
9164 PIM_DECLVAR_CONTEXT(vrf, pim);
9165 return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg,
9166 argv[5]->arg);
9167 }
9168
9169 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9170 struct vty *vty,
9171 const char *mg,
9172 const char *mbr)
9173 {
9174 enum pim_msdp_err result;
9175 struct in_addr mbr_ip;
9176
9177 result = inet_pton(AF_INET, mbr, &mbr_ip);
9178 if (result <= 0) {
9179 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9180 errno, safe_strerror(errno));
9181 return CMD_WARNING_CONFIG_FAILED;
9182 }
9183
9184 result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
9185 switch (result) {
9186 case PIM_MSDP_ERR_NONE:
9187 break;
9188 case PIM_MSDP_ERR_NO_MG:
9189 vty_out(vty, "%% mesh-group does not exist\n");
9190 break;
9191 case PIM_MSDP_ERR_NO_MG_MBR:
9192 vty_out(vty, "%% mesh-group member does not exist\n");
9193 break;
9194 default:
9195 vty_out(vty, "%% mesh-group member del failed\n");
9196 }
9197
9198 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9199 }
9200 DEFUN (no_ip_msdp_mesh_group_member,
9201 no_ip_msdp_mesh_group_member_cmd,
9202 "no ip msdp mesh-group WORD member A.B.C.D",
9203 NO_STR
9204 IP_STR
9205 CFG_MSDP_STR
9206 "Delete MSDP mesh-group member\n"
9207 "mesh group name\n"
9208 "mesh group member\n"
9209 "peer ip address\n")
9210 {
9211 PIM_DECLVAR_CONTEXT(vrf, pim);
9212 return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg,
9213 argv[6]->arg);
9214 }
9215
9216 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9217 struct vty *vty, const char *mg,
9218 const char *src)
9219 {
9220 enum pim_msdp_err result;
9221 struct in_addr src_ip;
9222
9223 result = inet_pton(AF_INET, src, &src_ip);
9224 if (result <= 0) {
9225 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
9226 errno, safe_strerror(errno));
9227 return CMD_WARNING_CONFIG_FAILED;
9228 }
9229
9230 result = pim_msdp_mg_src_add(pim, mg, src_ip);
9231 switch (result) {
9232 case PIM_MSDP_ERR_NONE:
9233 break;
9234 case PIM_MSDP_ERR_OOM:
9235 vty_out(vty, "%% Out of memory\n");
9236 break;
9237 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9238 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9239 break;
9240 default:
9241 vty_out(vty, "%% source add failed\n");
9242 }
9243
9244 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9245 }
9246
9247
9248 DEFUN (ip_msdp_mesh_group_source,
9249 ip_msdp_mesh_group_source_cmd,
9250 "ip msdp mesh-group WORD source A.B.C.D",
9251 IP_STR
9252 CFG_MSDP_STR
9253 "Configure MSDP mesh-group\n"
9254 "mesh group name\n"
9255 "mesh group local address\n"
9256 "source ip address for the TCP connection\n")
9257 {
9258 PIM_DECLVAR_CONTEXT(vrf, pim);
9259 return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg,
9260 argv[5]->arg);
9261 }
9262
9263 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9264 struct vty *vty,
9265 const char *mg)
9266 {
9267 enum pim_msdp_err result;
9268
9269 result = pim_msdp_mg_src_del(pim, mg);
9270 switch (result) {
9271 case PIM_MSDP_ERR_NONE:
9272 break;
9273 case PIM_MSDP_ERR_NO_MG:
9274 vty_out(vty, "%% mesh-group does not exist\n");
9275 break;
9276 default:
9277 vty_out(vty, "%% mesh-group source del failed\n");
9278 }
9279
9280 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9281 }
9282
9283 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
9284 struct vty *vty, const char *mg)
9285 {
9286 enum pim_msdp_err result;
9287
9288 result = pim_msdp_mg_del(pim, mg);
9289 switch (result) {
9290 case PIM_MSDP_ERR_NONE:
9291 break;
9292 case PIM_MSDP_ERR_NO_MG:
9293 vty_out(vty, "%% mesh-group does not exist\n");
9294 break;
9295 default:
9296 vty_out(vty, "%% mesh-group source del failed\n");
9297 }
9298
9299 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9300 }
9301
9302 DEFUN (no_ip_msdp_mesh_group_source,
9303 no_ip_msdp_mesh_group_source_cmd,
9304 "no ip msdp mesh-group WORD source [A.B.C.D]",
9305 NO_STR
9306 IP_STR
9307 CFG_MSDP_STR
9308 "Delete MSDP mesh-group source\n"
9309 "mesh group name\n"
9310 "mesh group source\n"
9311 "mesh group local address\n")
9312 {
9313 PIM_DECLVAR_CONTEXT(vrf, pim);
9314 if (argc == 7)
9315 return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[6]->arg);
9316 else
9317 return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty,
9318 argv[4]->arg);
9319 }
9320
9321 static void print_empty_json_obj(struct vty *vty)
9322 {
9323 json_object *json;
9324 json = json_object_new_object();
9325 vty_out(vty, "%s\n",
9326 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
9327 json_object_free(json);
9328 }
9329
9330 static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
9331 bool uj)
9332 {
9333 struct listnode *mbrnode;
9334 struct pim_msdp_mg_mbr *mbr;
9335 struct pim_msdp_mg *mg = pim->msdp.mg;
9336 char mbr_str[INET_ADDRSTRLEN];
9337 char src_str[INET_ADDRSTRLEN];
9338 char state_str[PIM_MSDP_STATE_STRLEN];
9339 enum pim_msdp_peer_state state;
9340 json_object *json = NULL;
9341 json_object *json_mg_row = NULL;
9342 json_object *json_members = NULL;
9343 json_object *json_row = NULL;
9344
9345 if (!mg) {
9346 if (uj)
9347 print_empty_json_obj(vty);
9348 return;
9349 }
9350
9351 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
9352 if (uj) {
9353 json = json_object_new_object();
9354 /* currently there is only one mesh group but we should still
9355 * make
9356 * it a dict with mg-name as key */
9357 json_mg_row = json_object_new_object();
9358 json_object_string_add(json_mg_row, "name",
9359 mg->mesh_group_name);
9360 json_object_string_add(json_mg_row, "source", src_str);
9361 } else {
9362 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
9363 vty_out(vty, " Source : %s\n", src_str);
9364 vty_out(vty, " Member State\n");
9365 }
9366
9367 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
9368 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
9369 if (mbr->mp) {
9370 state = mbr->mp->state;
9371 } else {
9372 state = PIM_MSDP_DISABLED;
9373 }
9374 pim_msdp_state_dump(state, state_str, sizeof(state_str));
9375 if (uj) {
9376 json_row = json_object_new_object();
9377 json_object_string_add(json_row, "member", mbr_str);
9378 json_object_string_add(json_row, "state", state_str);
9379 if (!json_members) {
9380 json_members = json_object_new_object();
9381 json_object_object_add(json_mg_row, "members",
9382 json_members);
9383 }
9384 json_object_object_add(json_members, mbr_str, json_row);
9385 } else {
9386 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
9387 }
9388 }
9389
9390 if (uj) {
9391 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
9392 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9393 json, JSON_C_TO_STRING_PRETTY));
9394 json_object_free(json);
9395 }
9396 }
9397
9398 DEFUN (show_ip_msdp_mesh_group,
9399 show_ip_msdp_mesh_group_cmd,
9400 "show ip msdp [vrf NAME] mesh-group [json]",
9401 SHOW_STR
9402 IP_STR
9403 MSDP_STR
9404 VRF_CMD_HELP_STR
9405 "MSDP mesh-group information\n"
9406 JSON_STR)
9407 {
9408 bool uj = use_json(argc, argv);
9409 int idx = 2;
9410 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9411
9412 if (!vrf)
9413 return CMD_WARNING;
9414
9415 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9416
9417 return CMD_SUCCESS;
9418 }
9419
9420 DEFUN (show_ip_msdp_mesh_group_vrf_all,
9421 show_ip_msdp_mesh_group_vrf_all_cmd,
9422 "show ip msdp vrf all mesh-group [json]",
9423 SHOW_STR
9424 IP_STR
9425 MSDP_STR
9426 VRF_CMD_HELP_STR
9427 "MSDP mesh-group information\n"
9428 JSON_STR)
9429 {
9430 bool uj = use_json(argc, argv);
9431 struct vrf *vrf;
9432 bool first = true;
9433
9434 if (uj)
9435 vty_out(vty, "{ ");
9436 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9437 if (uj) {
9438 if (!first)
9439 vty_out(vty, ", ");
9440 vty_out(vty, " \"%s\": ", vrf->name);
9441 first = false;
9442 } else
9443 vty_out(vty, "VRF: %s\n", vrf->name);
9444 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9445 }
9446 if (uj)
9447 vty_out(vty, "}\n");
9448
9449 return CMD_SUCCESS;
9450 }
9451
9452 static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
9453 bool uj)
9454 {
9455 struct listnode *mpnode;
9456 struct pim_msdp_peer *mp;
9457 char peer_str[INET_ADDRSTRLEN];
9458 char local_str[INET_ADDRSTRLEN];
9459 char state_str[PIM_MSDP_STATE_STRLEN];
9460 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9461 int64_t now;
9462 json_object *json = NULL;
9463 json_object *json_row = NULL;
9464
9465
9466 if (uj) {
9467 json = json_object_new_object();
9468 } else {
9469 vty_out(vty,
9470 "Peer Local State Uptime SaCnt\n");
9471 }
9472
9473 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
9474 if (mp->state == PIM_MSDP_ESTABLISHED) {
9475 now = pim_time_monotonic_sec();
9476 pim_time_uptime(timebuf, sizeof(timebuf),
9477 now - mp->uptime);
9478 } else {
9479 strlcpy(timebuf, "-", sizeof(timebuf));
9480 }
9481 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9482 pim_inet4_dump("<local?>", mp->local, local_str,
9483 sizeof(local_str));
9484 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9485 if (uj) {
9486 json_row = json_object_new_object();
9487 json_object_string_add(json_row, "peer", peer_str);
9488 json_object_string_add(json_row, "local", local_str);
9489 json_object_string_add(json_row, "state", state_str);
9490 json_object_string_add(json_row, "upTime", timebuf);
9491 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9492 json_object_object_add(json, peer_str, json_row);
9493 } else {
9494 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
9495 local_str, state_str, timebuf, mp->sa_cnt);
9496 }
9497 }
9498
9499 if (uj) {
9500 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9501 json, JSON_C_TO_STRING_PRETTY));
9502 json_object_free(json);
9503 }
9504 }
9505
9506 static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
9507 const char *peer, bool uj)
9508 {
9509 struct listnode *mpnode;
9510 struct pim_msdp_peer *mp;
9511 char peer_str[INET_ADDRSTRLEN];
9512 char local_str[INET_ADDRSTRLEN];
9513 char state_str[PIM_MSDP_STATE_STRLEN];
9514 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9515 char katimer[PIM_MSDP_TIMER_STRLEN];
9516 char crtimer[PIM_MSDP_TIMER_STRLEN];
9517 char holdtimer[PIM_MSDP_TIMER_STRLEN];
9518 int64_t now;
9519 json_object *json = NULL;
9520 json_object *json_row = NULL;
9521
9522 if (uj) {
9523 json = json_object_new_object();
9524 }
9525
9526 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
9527 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9528 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
9529 continue;
9530
9531 if (mp->state == PIM_MSDP_ESTABLISHED) {
9532 now = pim_time_monotonic_sec();
9533 pim_time_uptime(timebuf, sizeof(timebuf),
9534 now - mp->uptime);
9535 } else {
9536 strlcpy(timebuf, "-", sizeof(timebuf));
9537 }
9538 pim_inet4_dump("<local?>", mp->local, local_str,
9539 sizeof(local_str));
9540 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9541 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
9542 mp->ka_timer);
9543 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
9544 mp->cr_timer);
9545 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
9546 mp->hold_timer);
9547
9548 if (uj) {
9549 json_row = json_object_new_object();
9550 json_object_string_add(json_row, "peer", peer_str);
9551 json_object_string_add(json_row, "local", local_str);
9552 json_object_string_add(json_row, "meshGroupName",
9553 mp->mesh_group_name);
9554 json_object_string_add(json_row, "state", state_str);
9555 json_object_string_add(json_row, "upTime", timebuf);
9556 json_object_string_add(json_row, "keepAliveTimer",
9557 katimer);
9558 json_object_string_add(json_row, "connRetryTimer",
9559 crtimer);
9560 json_object_string_add(json_row, "holdTimer",
9561 holdtimer);
9562 json_object_string_add(json_row, "lastReset",
9563 mp->last_reset);
9564 json_object_int_add(json_row, "connAttempts",
9565 mp->conn_attempts);
9566 json_object_int_add(json_row, "establishedChanges",
9567 mp->est_flaps);
9568 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9569 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
9570 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
9571 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
9572 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
9573 json_object_object_add(json, peer_str, json_row);
9574 } else {
9575 vty_out(vty, "Peer : %s\n", peer_str);
9576 vty_out(vty, " Local : %s\n", local_str);
9577 vty_out(vty, " Mesh Group : %s\n",
9578 mp->mesh_group_name);
9579 vty_out(vty, " State : %s\n", state_str);
9580 vty_out(vty, " Uptime : %s\n", timebuf);
9581
9582 vty_out(vty, " Keepalive Timer : %s\n", katimer);
9583 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
9584 vty_out(vty, " Hold Timer : %s\n", holdtimer);
9585 vty_out(vty, " Last Reset : %s\n",
9586 mp->last_reset);
9587 vty_out(vty, " Conn Attempts : %d\n",
9588 mp->conn_attempts);
9589 vty_out(vty, " Established Changes : %d\n",
9590 mp->est_flaps);
9591 vty_out(vty, " SA Count : %d\n",
9592 mp->sa_cnt);
9593 vty_out(vty, " Statistics :\n");
9594 vty_out(vty,
9595 " Sent Rcvd\n");
9596 vty_out(vty, " Keepalives : %10d %10d\n",
9597 mp->ka_tx_cnt, mp->ka_rx_cnt);
9598 vty_out(vty, " SAs : %10d %10d\n",
9599 mp->sa_tx_cnt, mp->sa_rx_cnt);
9600 vty_out(vty, "\n");
9601 }
9602 }
9603
9604 if (uj) {
9605 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9606 json, JSON_C_TO_STRING_PRETTY));
9607 json_object_free(json);
9608 }
9609 }
9610
9611 DEFUN (show_ip_msdp_peer_detail,
9612 show_ip_msdp_peer_detail_cmd,
9613 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9614 SHOW_STR
9615 IP_STR
9616 MSDP_STR
9617 VRF_CMD_HELP_STR
9618 "MSDP peer information\n"
9619 "Detailed output\n"
9620 "peer ip address\n"
9621 JSON_STR)
9622 {
9623 bool uj = use_json(argc, argv);
9624 int idx = 2;
9625 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9626
9627 if (!vrf)
9628 return CMD_WARNING;
9629
9630 char *arg = NULL;
9631
9632 if (argv_find(argv, argc, "detail", &idx))
9633 arg = argv[idx]->text;
9634 else if (argv_find(argv, argc, "A.B.C.D", &idx))
9635 arg = argv[idx]->arg;
9636
9637 if (arg)
9638 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
9639 else
9640 ip_msdp_show_peers(vrf->info, vty, uj);
9641
9642 return CMD_SUCCESS;
9643 }
9644
9645 DEFUN (show_ip_msdp_peer_detail_vrf_all,
9646 show_ip_msdp_peer_detail_vrf_all_cmd,
9647 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9648 SHOW_STR
9649 IP_STR
9650 MSDP_STR
9651 VRF_CMD_HELP_STR
9652 "MSDP peer information\n"
9653 "Detailed output\n"
9654 "peer ip address\n"
9655 JSON_STR)
9656 {
9657 int idx = 2;
9658 bool uj = use_json(argc, argv);
9659 struct vrf *vrf;
9660 bool first = true;
9661
9662 if (uj)
9663 vty_out(vty, "{ ");
9664 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9665 if (uj) {
9666 if (!first)
9667 vty_out(vty, ", ");
9668 vty_out(vty, " \"%s\": ", vrf->name);
9669 first = false;
9670 } else
9671 vty_out(vty, "VRF: %s\n", vrf->name);
9672 if (argv_find(argv, argc, "detail", &idx)
9673 || argv_find(argv, argc, "A.B.C.D", &idx))
9674 ip_msdp_show_peers_detail(vrf->info, vty,
9675 argv[idx]->arg, uj);
9676 else
9677 ip_msdp_show_peers(vrf->info, vty, uj);
9678 }
9679 if (uj)
9680 vty_out(vty, "}\n");
9681
9682 return CMD_SUCCESS;
9683 }
9684
9685 static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
9686 {
9687 struct listnode *sanode;
9688 struct pim_msdp_sa *sa;
9689 char src_str[INET_ADDRSTRLEN];
9690 char grp_str[INET_ADDRSTRLEN];
9691 char rp_str[INET_ADDRSTRLEN];
9692 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9693 char spt_str[8];
9694 char local_str[8];
9695 int64_t now;
9696 json_object *json = NULL;
9697 json_object *json_group = NULL;
9698 json_object *json_row = NULL;
9699
9700 if (uj) {
9701 json = json_object_new_object();
9702 } else {
9703 vty_out(vty,
9704 "Source Group RP Local SPT Uptime\n");
9705 }
9706
9707 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9708 now = pim_time_monotonic_sec();
9709 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9710 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9711 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9712 if (sa->flags & PIM_MSDP_SAF_PEER) {
9713 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9714 if (sa->up) {
9715 strlcpy(spt_str, "yes", sizeof(spt_str));
9716 } else {
9717 strlcpy(spt_str, "no", sizeof(spt_str));
9718 }
9719 } else {
9720 strlcpy(rp_str, "-", sizeof(rp_str));
9721 strlcpy(spt_str, "-", sizeof(spt_str));
9722 }
9723 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
9724 strlcpy(local_str, "yes", sizeof(local_str));
9725 } else {
9726 strlcpy(local_str, "no", sizeof(local_str));
9727 }
9728 if (uj) {
9729 json_object_object_get_ex(json, grp_str, &json_group);
9730
9731 if (!json_group) {
9732 json_group = json_object_new_object();
9733 json_object_object_add(json, grp_str,
9734 json_group);
9735 }
9736
9737 json_row = json_object_new_object();
9738 json_object_string_add(json_row, "source", src_str);
9739 json_object_string_add(json_row, "group", grp_str);
9740 json_object_string_add(json_row, "rp", rp_str);
9741 json_object_string_add(json_row, "local", local_str);
9742 json_object_string_add(json_row, "sptSetup", spt_str);
9743 json_object_string_add(json_row, "upTime", timebuf);
9744 json_object_object_add(json_group, src_str, json_row);
9745 } else {
9746 vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
9747 src_str, grp_str, rp_str, local_str[0],
9748 spt_str[0], timebuf);
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 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
9760 const char *src_str,
9761 const char *grp_str, struct vty *vty,
9762 bool uj, json_object *json)
9763 {
9764 char rp_str[INET_ADDRSTRLEN];
9765 char peer_str[INET_ADDRSTRLEN];
9766 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9767 char spt_str[8];
9768 char local_str[8];
9769 char statetimer[PIM_MSDP_TIMER_STRLEN];
9770 int64_t now;
9771 json_object *json_group = NULL;
9772 json_object *json_row = NULL;
9773
9774 now = pim_time_monotonic_sec();
9775 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9776 if (sa->flags & PIM_MSDP_SAF_PEER) {
9777 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9778 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
9779 if (sa->up) {
9780 strlcpy(spt_str, "yes", sizeof(spt_str));
9781 } else {
9782 strlcpy(spt_str, "no", sizeof(spt_str));
9783 }
9784 } else {
9785 strlcpy(rp_str, "-", sizeof(rp_str));
9786 strlcpy(peer_str, "-", sizeof(peer_str));
9787 strlcpy(spt_str, "-", sizeof(spt_str));
9788 }
9789 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
9790 strlcpy(local_str, "yes", sizeof(local_str));
9791 } else {
9792 strlcpy(local_str, "no", sizeof(local_str));
9793 }
9794 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
9795 sa->sa_state_timer);
9796 if (uj) {
9797 json_object_object_get_ex(json, grp_str, &json_group);
9798
9799 if (!json_group) {
9800 json_group = json_object_new_object();
9801 json_object_object_add(json, grp_str, json_group);
9802 }
9803
9804 json_row = json_object_new_object();
9805 json_object_string_add(json_row, "source", src_str);
9806 json_object_string_add(json_row, "group", grp_str);
9807 json_object_string_add(json_row, "rp", rp_str);
9808 json_object_string_add(json_row, "local", local_str);
9809 json_object_string_add(json_row, "sptSetup", spt_str);
9810 json_object_string_add(json_row, "upTime", timebuf);
9811 json_object_string_add(json_row, "stateTimer", statetimer);
9812 json_object_object_add(json_group, src_str, json_row);
9813 } else {
9814 vty_out(vty, "SA : %s\n", sa->sg_str);
9815 vty_out(vty, " RP : %s\n", rp_str);
9816 vty_out(vty, " Peer : %s\n", peer_str);
9817 vty_out(vty, " Local : %s\n", local_str);
9818 vty_out(vty, " SPT Setup : %s\n", spt_str);
9819 vty_out(vty, " Uptime : %s\n", timebuf);
9820 vty_out(vty, " State Timer : %s\n", statetimer);
9821 vty_out(vty, "\n");
9822 }
9823 }
9824
9825 static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
9826 bool uj)
9827 {
9828 struct listnode *sanode;
9829 struct pim_msdp_sa *sa;
9830 char src_str[INET_ADDRSTRLEN];
9831 char grp_str[INET_ADDRSTRLEN];
9832 json_object *json = NULL;
9833
9834 if (uj) {
9835 json = json_object_new_object();
9836 }
9837
9838 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9839 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9840 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9841 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
9842 json);
9843 }
9844
9845 if (uj) {
9846 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9847 json, JSON_C_TO_STRING_PRETTY));
9848 json_object_free(json);
9849 }
9850 }
9851
9852 DEFUN (show_ip_msdp_sa_detail,
9853 show_ip_msdp_sa_detail_cmd,
9854 "show ip msdp [vrf NAME] sa detail [json]",
9855 SHOW_STR
9856 IP_STR
9857 MSDP_STR
9858 VRF_CMD_HELP_STR
9859 "MSDP active-source information\n"
9860 "Detailed output\n"
9861 JSON_STR)
9862 {
9863 bool uj = use_json(argc, argv);
9864 int idx = 2;
9865 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9866
9867 if (!vrf)
9868 return CMD_WARNING;
9869
9870 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9871
9872 return CMD_SUCCESS;
9873 }
9874
9875 DEFUN (show_ip_msdp_sa_detail_vrf_all,
9876 show_ip_msdp_sa_detail_vrf_all_cmd,
9877 "show ip msdp vrf all sa detail [json]",
9878 SHOW_STR
9879 IP_STR
9880 MSDP_STR
9881 VRF_CMD_HELP_STR
9882 "MSDP active-source information\n"
9883 "Detailed output\n"
9884 JSON_STR)
9885 {
9886 bool uj = use_json(argc, argv);
9887 struct vrf *vrf;
9888 bool first = true;
9889
9890 if (uj)
9891 vty_out(vty, "{ ");
9892 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9893 if (uj) {
9894 if (!first)
9895 vty_out(vty, ", ");
9896 vty_out(vty, " \"%s\": ", vrf->name);
9897 first = false;
9898 } else
9899 vty_out(vty, "VRF: %s\n", vrf->name);
9900 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9901 }
9902 if (uj)
9903 vty_out(vty, "}\n");
9904
9905 return CMD_SUCCESS;
9906 }
9907
9908 static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
9909 const char *addr, bool uj)
9910 {
9911 struct listnode *sanode;
9912 struct pim_msdp_sa *sa;
9913 char src_str[INET_ADDRSTRLEN];
9914 char grp_str[INET_ADDRSTRLEN];
9915 json_object *json = NULL;
9916
9917 if (uj) {
9918 json = json_object_new_object();
9919 }
9920
9921 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9922 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9923 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9924 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
9925 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9926 uj, json);
9927 }
9928 }
9929
9930 if (uj) {
9931 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9932 json, JSON_C_TO_STRING_PRETTY));
9933 json_object_free(json);
9934 }
9935 }
9936
9937 static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
9938 const char *src, const char *grp, bool uj)
9939 {
9940 struct listnode *sanode;
9941 struct pim_msdp_sa *sa;
9942 char src_str[INET_ADDRSTRLEN];
9943 char grp_str[INET_ADDRSTRLEN];
9944 json_object *json = NULL;
9945
9946 if (uj) {
9947 json = json_object_new_object();
9948 }
9949
9950 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9951 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9952 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9953 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
9954 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9955 uj, json);
9956 }
9957 }
9958
9959 if (uj) {
9960 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9961 json, JSON_C_TO_STRING_PRETTY));
9962 json_object_free(json);
9963 }
9964 }
9965
9966 DEFUN (show_ip_msdp_sa_sg,
9967 show_ip_msdp_sa_sg_cmd,
9968 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9969 SHOW_STR
9970 IP_STR
9971 MSDP_STR
9972 VRF_CMD_HELP_STR
9973 "MSDP active-source information\n"
9974 "source or group ip\n"
9975 "group ip\n"
9976 JSON_STR)
9977 {
9978 bool uj = use_json(argc, argv);
9979 struct vrf *vrf;
9980 int idx = 2;
9981
9982 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9983
9984 if (!vrf)
9985 return CMD_WARNING;
9986
9987 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
9988 : NULL;
9989 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
9990 ? argv[idx]->arg
9991 : NULL;
9992
9993 if (src_ip && grp_ip)
9994 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
9995 else if (src_ip)
9996 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
9997 else
9998 ip_msdp_show_sa(vrf->info, vty, uj);
9999
10000 return CMD_SUCCESS;
10001 }
10002
10003 DEFUN (show_ip_msdp_sa_sg_vrf_all,
10004 show_ip_msdp_sa_sg_vrf_all_cmd,
10005 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10006 SHOW_STR
10007 IP_STR
10008 MSDP_STR
10009 VRF_CMD_HELP_STR
10010 "MSDP active-source information\n"
10011 "source or group ip\n"
10012 "group ip\n"
10013 JSON_STR)
10014 {
10015 bool uj = use_json(argc, argv);
10016 struct vrf *vrf;
10017 bool first = true;
10018 int idx = 2;
10019
10020 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
10021 : NULL;
10022 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
10023 ? argv[idx]->arg
10024 : NULL;
10025
10026 if (uj)
10027 vty_out(vty, "{ ");
10028 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
10029 if (uj) {
10030 if (!first)
10031 vty_out(vty, ", ");
10032 vty_out(vty, " \"%s\": ", vrf->name);
10033 first = false;
10034 } else
10035 vty_out(vty, "VRF: %s\n", vrf->name);
10036
10037 if (src_ip && grp_ip)
10038 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
10039 else if (src_ip)
10040 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
10041 else
10042 ip_msdp_show_sa(vrf->info, vty, uj);
10043 }
10044 if (uj)
10045 vty_out(vty, "}\n");
10046
10047 return CMD_SUCCESS;
10048 }
10049
10050 struct pim_sg_cache_walk_data {
10051 struct vty *vty;
10052 json_object *json;
10053 json_object *json_group;
10054 struct in_addr addr;
10055 bool addr_match;
10056 };
10057
10058 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
10059 struct pim_sg_cache_walk_data *cwd)
10060 {
10061 struct vty *vty = cwd->vty;
10062 json_object *json = cwd->json;
10063 char src_str[INET_ADDRSTRLEN];
10064 char grp_str[INET_ADDRSTRLEN];
10065 json_object *json_row;
10066 bool installed = (vxlan_sg->up) ? true : false;
10067 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10068 const char *oif_name;
10069
10070 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10071 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10072 else
10073 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10074
10075 if (cwd->addr_match && (vxlan_sg->sg.src.s_addr != cwd->addr.s_addr) &&
10076 (vxlan_sg->sg.grp.s_addr != cwd->addr.s_addr)) {
10077 return;
10078 }
10079 pim_inet4_dump("<src?>", vxlan_sg->sg.src, src_str, sizeof(src_str));
10080 pim_inet4_dump("<grp?>", vxlan_sg->sg.grp, grp_str, sizeof(grp_str));
10081 if (json) {
10082 json_object_object_get_ex(json, grp_str, &cwd->json_group);
10083
10084 if (!cwd->json_group) {
10085 cwd->json_group = json_object_new_object();
10086 json_object_object_add(json, grp_str,
10087 cwd->json_group);
10088 }
10089
10090 json_row = json_object_new_object();
10091 json_object_string_add(json_row, "source", src_str);
10092 json_object_string_add(json_row, "group", grp_str);
10093 json_object_string_add(json_row, "input", iif_name);
10094 json_object_string_add(json_row, "output", oif_name);
10095 if (installed)
10096 json_object_boolean_true_add(json_row, "installed");
10097 else
10098 json_object_boolean_false_add(json_row, "installed");
10099 json_object_object_add(cwd->json_group, src_str, json_row);
10100 } else {
10101 vty_out(vty, "%-15s %-15s %-15s %-15s %-5s\n",
10102 src_str, grp_str, iif_name, oif_name,
10103 installed?"I":"");
10104 }
10105 }
10106
10107 static void pim_show_vxlan_sg_hash_entry(struct hash_backet *backet, void *arg)
10108 {
10109 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)backet->data,
10110 (struct pim_sg_cache_walk_data *)arg);
10111 }
10112
10113 static void pim_show_vxlan_sg(struct pim_instance *pim,
10114 struct vty *vty, bool uj)
10115 {
10116 json_object *json = NULL;
10117 struct pim_sg_cache_walk_data cwd;
10118
10119 if (uj) {
10120 json = json_object_new_object();
10121 } else {
10122 vty_out(vty, "Codes: I -> installed\n");
10123 vty_out(vty,
10124 "Source Group Input Output Flags\n");
10125 }
10126
10127 memset(&cwd, 0, sizeof(cwd));
10128 cwd.vty = vty;
10129 cwd.json = json;
10130 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10131
10132 if (uj) {
10133 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10134 json, JSON_C_TO_STRING_PRETTY));
10135 json_object_free(json);
10136 }
10137 }
10138
10139 static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
10140 struct vty *vty, char *addr_str, bool uj)
10141 {
10142 json_object *json = NULL;
10143 struct pim_sg_cache_walk_data cwd;
10144 int result = 0;
10145
10146 memset(&cwd, 0, sizeof(cwd));
10147 result = inet_pton(AF_INET, addr_str, &cwd.addr);
10148 if (result <= 0) {
10149 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
10150 errno, safe_strerror(errno));
10151 return;
10152 }
10153
10154 if (uj) {
10155 json = json_object_new_object();
10156 } else {
10157 vty_out(vty, "Codes: I -> installed\n");
10158 vty_out(vty,
10159 "Source Group Input Output Flags\n");
10160 }
10161
10162 cwd.vty = vty;
10163 cwd.json = json;
10164 cwd.addr_match = true;
10165 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10166
10167 if (uj) {
10168 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10169 json, JSON_C_TO_STRING_PRETTY));
10170 json_object_free(json);
10171 }
10172 }
10173
10174 static void pim_show_vxlan_sg_one(struct pim_instance *pim,
10175 struct vty *vty, char *src_str, char *grp_str, bool uj)
10176 {
10177 json_object *json = NULL;
10178 struct prefix_sg sg;
10179 int result = 0;
10180 struct pim_vxlan_sg *vxlan_sg;
10181 const char *iif_name;
10182 bool installed;
10183 const char *oif_name;
10184
10185 result = inet_pton(AF_INET, src_str, &sg.src);
10186 if (result <= 0) {
10187 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
10188 errno, safe_strerror(errno));
10189 return;
10190 }
10191 result = inet_pton(AF_INET, grp_str, &sg.grp);
10192 if (result <= 0) {
10193 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
10194 errno, safe_strerror(errno));
10195 return;
10196 }
10197
10198 sg.family = AF_INET;
10199 sg.prefixlen = IPV4_MAX_BITLEN;
10200 if (uj)
10201 json = json_object_new_object();
10202
10203 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
10204 if (vxlan_sg) {
10205 installed = (vxlan_sg->up) ? true : false;
10206 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10207
10208 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10209 oif_name =
10210 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10211 else
10212 oif_name =
10213 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10214
10215 if (uj) {
10216 json_object_string_add(json, "source", src_str);
10217 json_object_string_add(json, "group", grp_str);
10218 json_object_string_add(json, "input", iif_name);
10219 json_object_string_add(json, "output", oif_name);
10220 if (installed)
10221 json_object_boolean_true_add(json, "installed");
10222 else
10223 json_object_boolean_false_add(json,
10224 "installed");
10225 } else {
10226 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
10227 vty_out(vty, " Input : %s\n", iif_name);
10228 vty_out(vty, " Output : %s\n", oif_name);
10229 vty_out(vty, " installed : %s\n",
10230 installed?"yes":"no");
10231 }
10232 }
10233
10234 if (uj) {
10235 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10236 json, JSON_C_TO_STRING_PRETTY));
10237 json_object_free(json);
10238 }
10239 }
10240
10241 DEFUN (show_ip_pim_vxlan_sg,
10242 show_ip_pim_vxlan_sg_cmd,
10243 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10244 SHOW_STR
10245 IP_STR
10246 PIM_STR
10247 VRF_CMD_HELP_STR
10248 "VxLAN BUM groups\n"
10249 "source or group ip\n"
10250 "group ip\n"
10251 JSON_STR)
10252 {
10253 bool uj = use_json(argc, argv);
10254 struct vrf *vrf;
10255 int idx = 2;
10256
10257 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10258
10259 if (!vrf)
10260 return CMD_WARNING;
10261
10262 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
10263 argv[idx++]->arg:NULL;
10264 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
10265 argv[idx]->arg:NULL;
10266
10267 if (src_ip && grp_ip)
10268 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
10269 else if (src_ip)
10270 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
10271 else
10272 pim_show_vxlan_sg(vrf->info, vty, uj);
10273
10274 return CMD_SUCCESS;
10275 }
10276
10277 static void pim_show_vxlan_sg_work(struct pim_instance *pim,
10278 struct vty *vty, bool uj)
10279 {
10280 json_object *json = NULL;
10281 struct pim_sg_cache_walk_data cwd;
10282 struct listnode *node;
10283 struct pim_vxlan_sg *vxlan_sg;
10284
10285 if (uj) {
10286 json = json_object_new_object();
10287 } else {
10288 vty_out(vty, "Codes: I -> installed\n");
10289 vty_out(vty,
10290 "Source Group Input Flags\n");
10291 }
10292
10293 memset(&cwd, 0, sizeof(cwd));
10294 cwd.vty = vty;
10295 cwd.json = json;
10296 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
10297 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
10298
10299 if (uj) {
10300 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10301 json, JSON_C_TO_STRING_PRETTY));
10302 json_object_free(json);
10303 }
10304 }
10305
10306 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
10307 show_ip_pim_vxlan_sg_work_cmd,
10308 "show ip pim [vrf NAME] vxlan-work [json]",
10309 SHOW_STR
10310 IP_STR
10311 PIM_STR
10312 VRF_CMD_HELP_STR
10313 "VxLAN work list\n"
10314 JSON_STR)
10315 {
10316 bool uj = use_json(argc, argv);
10317 struct vrf *vrf;
10318 int idx = 2;
10319
10320 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10321
10322 if (!vrf)
10323 return CMD_WARNING;
10324
10325 pim_show_vxlan_sg_work(vrf->info, vty, uj);
10326
10327 return CMD_SUCCESS;
10328 }
10329
10330 DEFUN_HIDDEN (no_ip_pim_mlag,
10331 no_ip_pim_mlag_cmd,
10332 "no ip pim mlag",
10333 NO_STR
10334 IP_STR
10335 PIM_STR
10336 "MLAG\n")
10337 {
10338 struct in_addr addr;
10339
10340 addr.s_addr = 0;
10341 pim_vxlan_mlag_update(true/*mlag_enable*/,
10342 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY,
10343 NULL/*peerlink*/, &addr);
10344
10345 return CMD_SUCCESS;
10346 }
10347
10348 DEFUN_HIDDEN (ip_pim_mlag,
10349 ip_pim_mlag_cmd,
10350 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10351 IP_STR
10352 PIM_STR
10353 "MLAG\n"
10354 "peerlink sub interface\n"
10355 "MLAG role\n"
10356 "MLAG role primary\n"
10357 "MLAG role secondary\n"
10358 "peer session state\n"
10359 "peer session state up\n"
10360 "peer session state down\n"
10361 "configure PIP\n"
10362 "unique ip address\n")
10363 {
10364 struct interface *ifp;
10365 const char *peerlink;
10366 uint32_t role;
10367 int idx;
10368 bool peer_state;
10369 int result;
10370 struct in_addr reg_addr;
10371
10372 idx = 3;
10373 peerlink = argv[idx]->arg;
10374 ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
10375 if (!ifp) {
10376 vty_out(vty, "No such interface name %s\n", peerlink);
10377 return CMD_WARNING;
10378 }
10379
10380 idx += 2;
10381 if (!strcmp(argv[idx]->arg, "primary")) {
10382 role = PIM_VXLAN_MLAG_ROLE_PRIMARY;
10383 } else if (!strcmp(argv[idx]->arg, "secondary")) {
10384 role = PIM_VXLAN_MLAG_ROLE_SECONDARY;
10385 } else {
10386 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
10387 return CMD_WARNING;
10388 }
10389
10390 idx += 2;
10391 if (!strcmp(argv[idx]->arg, "up")) {
10392 peer_state = true;
10393 } else if (strcmp(argv[idx]->arg, "down")) {
10394 peer_state = false;
10395 } else {
10396 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
10397 return CMD_WARNING;
10398 }
10399
10400 idx += 2;
10401 result = inet_pton(AF_INET, argv[idx]->arg, &reg_addr);
10402 if (result <= 0) {
10403 vty_out(vty, "%% Bad reg address %s: errno=%d: %s\n",
10404 argv[idx]->arg,
10405 errno, safe_strerror(errno));
10406 return CMD_WARNING_CONFIG_FAILED;
10407 }
10408 pim_vxlan_mlag_update(true, peer_state, role, ifp, &reg_addr);
10409
10410 return CMD_SUCCESS;
10411 }
10412
10413 void pim_cmd_init(void)
10414 {
10415 install_node(&interface_node,
10416 pim_interface_config_write); /* INTERFACE_NODE */
10417 if_cmd_init();
10418
10419 install_node(&debug_node, pim_debug_config_write);
10420
10421 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
10422
10423 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
10424 install_element(VRF_NODE, &ip_pim_rp_cmd);
10425 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
10426 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
10427 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
10428 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
10429 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
10430 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
10431 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
10432 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
10433 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
10434 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
10435 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
10436 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
10437 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
10438 install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
10439 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
10440 install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
10441 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
10442 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
10443 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
10444 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
10445 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
10446 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
10447 install_element(CONFIG_NODE,
10448 &no_ip_pim_spt_switchover_infinity_plist_cmd);
10449 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
10450 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
10451 install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
10452 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
10453 install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
10454 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
10455 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
10456 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
10457 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
10458 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
10459 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
10460 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
10461 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
10462 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
10463 install_element(VRF_NODE, &ip_pim_packets_cmd);
10464 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
10465 install_element(VRF_NODE, &no_ip_pim_packets_cmd);
10466 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
10467 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
10468 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
10469 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
10470 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
10471 install_element(VRF_NODE, &ip_ssmpingd_cmd);
10472 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
10473 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
10474 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
10475 install_element(VRF_NODE, &ip_msdp_peer_cmd);
10476 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
10477 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
10478 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
10479 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
10480 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
10481 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
10482 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
10483 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
10484 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
10485 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
10486 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
10487 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
10488
10489 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
10490 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
10491 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
10492 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
10493 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
10494 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
10495 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
10496 install_element(INTERFACE_NODE,
10497 &interface_no_ip_igmp_query_interval_cmd);
10498 install_element(INTERFACE_NODE,
10499 &interface_ip_igmp_query_max_response_time_cmd);
10500 install_element(INTERFACE_NODE,
10501 &interface_no_ip_igmp_query_max_response_time_cmd);
10502 install_element(INTERFACE_NODE,
10503 &interface_ip_igmp_query_max_response_time_dsec_cmd);
10504 install_element(INTERFACE_NODE,
10505 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
10506 install_element(INTERFACE_NODE,
10507 &interface_ip_igmp_last_member_query_count_cmd);
10508 install_element(INTERFACE_NODE,
10509 &interface_no_ip_igmp_last_member_query_count_cmd);
10510 install_element(INTERFACE_NODE,
10511 &interface_ip_igmp_last_member_query_interval_cmd);
10512 install_element(INTERFACE_NODE,
10513 &interface_no_ip_igmp_last_member_query_interval_cmd);
10514 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
10515 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
10516 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
10517 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
10518 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
10519 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
10520 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
10521 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
10522 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
10523 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
10524 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
10525 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
10526 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
10527 install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
10528
10529 // Static mroutes NEB
10530 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
10531 install_element(INTERFACE_NODE, &interface_ip_mroute_source_cmd);
10532 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
10533 install_element(INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
10534
10535 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
10536 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
10537 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
10538 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
10539 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
10540 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
10541 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
10542 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
10543 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
10544 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
10545 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
10546 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
10547 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
10548 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
10549 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
10550 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
10551 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
10552 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
10553 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
10554 install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
10555 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
10556 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
10557 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
10558 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
10559 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
10560 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
10561 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
10562 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
10563 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
10564 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
10565 install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
10566 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
10567 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
10568 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
10569 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
10570 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
10571 install_element(VIEW_NODE, &show_ip_multicast_cmd);
10572 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
10573 install_element(VIEW_NODE, &show_ip_mroute_cmd);
10574 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
10575 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
10576 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
10577 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
10578 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
10579 install_element(VIEW_NODE, &show_ip_rib_cmd);
10580 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
10581 install_element(VIEW_NODE, &show_debugging_pim_cmd);
10582 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
10583 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
10584 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
10585 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
10586 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
10587
10588 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
10589 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
10590 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
10591 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
10592 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
10593 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
10594 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
10595 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
10596
10597 install_element(ENABLE_NODE, &debug_igmp_cmd);
10598 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
10599 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
10600 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
10601 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
10602 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
10603 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
10604 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
10605 install_element(ENABLE_NODE, &debug_mroute_cmd);
10606 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
10607 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
10608 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
10609 install_element(ENABLE_NODE, &debug_pim_static_cmd);
10610 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
10611 install_element(ENABLE_NODE, &debug_pim_cmd);
10612 install_element(ENABLE_NODE, &no_debug_pim_cmd);
10613 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
10614 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
10615 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
10616 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
10617 install_element(ENABLE_NODE, &debug_pim_events_cmd);
10618 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
10619 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
10620 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
10621 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
10622 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
10623 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
10624 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
10625 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
10626 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
10627 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
10628 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
10629 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
10630 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
10631 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
10632 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
10633 install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
10634 install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
10635 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
10636 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
10637 install_element(ENABLE_NODE, &debug_msdp_cmd);
10638 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
10639 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
10640 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
10641 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
10642 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
10643 install_element(ENABLE_NODE, &debug_mtrace_cmd);
10644 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
10645 install_element(ENABLE_NODE, &debug_bsm_cmd);
10646 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
10647
10648 install_element(CONFIG_NODE, &debug_igmp_cmd);
10649 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
10650 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
10651 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
10652 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
10653 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
10654 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
10655 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
10656 install_element(CONFIG_NODE, &debug_mroute_cmd);
10657 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
10658 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
10659 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
10660 install_element(CONFIG_NODE, &debug_pim_static_cmd);
10661 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
10662 install_element(CONFIG_NODE, &debug_pim_cmd);
10663 install_element(CONFIG_NODE, &no_debug_pim_cmd);
10664 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
10665 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
10666 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
10667 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
10668 install_element(CONFIG_NODE, &debug_pim_events_cmd);
10669 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
10670 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
10671 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
10672 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
10673 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
10674 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
10675 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
10676 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
10677 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
10678 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
10679 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
10680 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
10681 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
10682 install_element(CONFIG_NODE, &debug_msdp_cmd);
10683 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
10684 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
10685 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
10686 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
10687 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
10688 install_element(CONFIG_NODE, &debug_mtrace_cmd);
10689 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
10690 install_element(CONFIG_NODE, &debug_bsm_cmd);
10691 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
10692
10693 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
10694 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
10695 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
10696 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
10697 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
10698 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
10699 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
10700 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
10701 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
10702 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
10703 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
10704 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
10705 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
10706 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
10707 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
10708 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
10709 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
10710 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
10711 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
10712 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
10713 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
10714 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
10715 /* Install BSM command */
10716 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
10717 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
10718 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
10719 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
10720 /* Install BFD command */
10721 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
10722 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
10723 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
10724 #if HAVE_BFDD == 0
10725 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
10726 #endif /* !HAVE_BFDD */
10727 }