]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_cmd.c
Merge pull request #5567 from opensourcerouting/bring-them-back
[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 if (argc == (idx_ipv4_2 + 1)) {
6945 source_str = argv[idx_ipv4_2]->arg;
6946 result = inet_pton(AF_INET, source_str, &source_addr);
6947 if (result <= 0) {
6948 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
6949 source_str, errno, safe_strerror(errno));
6950 return CMD_WARNING_CONFIG_FAILED;
6951 }
6952 /* Reject 0.0.0.0. Reserved for any source. */
6953 if (source_addr.s_addr == INADDR_ANY) {
6954 vty_out(vty, "Bad source address %s\n", source_str);
6955 return CMD_WARNING_CONFIG_FAILED;
6956 }
6957 } else {
6958 source_addr.s_addr = INADDR_ANY;
6959 }
6960
6961 CMD_FERR_RETURN(pim_if_igmp_join_add(ifp, group_addr, source_addr),
6962 "Failure joining IGMP group: $ERR");
6963
6964 return CMD_SUCCESS;
6965 }
6966
6967 DEFUN (interface_no_ip_igmp_join,
6968 interface_no_ip_igmp_join_cmd,
6969 "no ip igmp join A.B.C.D [A.B.C.D]",
6970 NO_STR
6971 IP_STR
6972 IFACE_IGMP_STR
6973 "IGMP join multicast group\n"
6974 "Multicast group address\n"
6975 "Source address\n")
6976 {
6977 VTY_DECLVAR_CONTEXT(interface, ifp);
6978 int idx_ipv4 = 4;
6979 int idx_ipv4_2 = 5;
6980 const char *group_str;
6981 const char *source_str;
6982 struct in_addr group_addr;
6983 struct in_addr source_addr;
6984 int result;
6985
6986 /* Group address */
6987 group_str = argv[idx_ipv4]->arg;
6988 result = inet_pton(AF_INET, group_str, &group_addr);
6989 if (result <= 0) {
6990 vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
6991 errno, safe_strerror(errno));
6992 return CMD_WARNING_CONFIG_FAILED;
6993 }
6994
6995 /* Source address */
6996 if (argc == (idx_ipv4_2 + 1)) {
6997 source_str = argv[idx_ipv4_2]->arg;
6998 result = inet_pton(AF_INET, source_str, &source_addr);
6999 if (result <= 0) {
7000 vty_out(vty, "Bad source address %s: errno=%d: %s\n",
7001 source_str, errno, safe_strerror(errno));
7002 return CMD_WARNING_CONFIG_FAILED;
7003 }
7004 /* Reject 0.0.0.0. Reserved for any source. */
7005 if (source_addr.s_addr == INADDR_ANY) {
7006 vty_out(vty, "Bad source address %s\n", source_str);
7007 return CMD_WARNING_CONFIG_FAILED;
7008 }
7009 } else {
7010 source_str = "*";
7011 source_addr.s_addr = INADDR_ANY;
7012 }
7013
7014 result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
7015 if (result) {
7016 vty_out(vty,
7017 "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
7018 group_str, source_str, ifp->name, result);
7019 return CMD_WARNING_CONFIG_FAILED;
7020 }
7021
7022 return CMD_SUCCESS;
7023 }
7024
7025 /*
7026 CLI reconfiguration affects the interface level (struct pim_interface).
7027 This function propagates the reconfiguration to every active socket
7028 for that interface.
7029 */
7030 static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
7031 {
7032 struct interface *ifp;
7033 struct pim_interface *pim_ifp;
7034
7035 zassert(igmp);
7036
7037 /* other querier present? */
7038
7039 if (igmp->t_other_querier_timer)
7040 return;
7041
7042 /* this is the querier */
7043
7044 zassert(igmp->interface);
7045 zassert(igmp->interface->info);
7046
7047 ifp = igmp->interface;
7048 pim_ifp = ifp->info;
7049
7050 if (PIM_DEBUG_IGMP_TRACE) {
7051 char ifaddr_str[INET_ADDRSTRLEN];
7052 pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
7053 sizeof(ifaddr_str));
7054 zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
7055 __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
7056 pim_ifp->igmp_default_query_interval);
7057 }
7058
7059 /*
7060 igmp_startup_mode_on() will reset QQI:
7061
7062 igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
7063 */
7064 igmp_startup_mode_on(igmp);
7065 }
7066
7067 static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
7068 {
7069 if (igmp->t_igmp_query_timer) {
7070 /* other querier present */
7071 zassert(igmp->t_igmp_query_timer);
7072 zassert(!igmp->t_other_querier_timer);
7073
7074 pim_igmp_general_query_off(igmp);
7075 pim_igmp_general_query_on(igmp);
7076
7077 zassert(igmp->t_igmp_query_timer);
7078 zassert(!igmp->t_other_querier_timer);
7079 } else {
7080 /* this is the querier */
7081
7082 zassert(!igmp->t_igmp_query_timer);
7083 zassert(igmp->t_other_querier_timer);
7084
7085 pim_igmp_other_querier_timer_off(igmp);
7086 pim_igmp_other_querier_timer_on(igmp);
7087
7088 zassert(!igmp->t_igmp_query_timer);
7089 zassert(igmp->t_other_querier_timer);
7090 }
7091 }
7092
7093 static void change_query_interval(struct pim_interface *pim_ifp,
7094 int query_interval)
7095 {
7096 struct listnode *sock_node;
7097 struct igmp_sock *igmp;
7098
7099 pim_ifp->igmp_default_query_interval = query_interval;
7100
7101 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7102 igmp_sock_query_interval_reconfig(igmp);
7103 igmp_sock_query_reschedule(igmp);
7104 }
7105 }
7106
7107 static void change_query_max_response_time(struct pim_interface *pim_ifp,
7108 int query_max_response_time_dsec)
7109 {
7110 struct listnode *sock_node;
7111 struct igmp_sock *igmp;
7112
7113 pim_ifp->igmp_query_max_response_time_dsec =
7114 query_max_response_time_dsec;
7115
7116 /*
7117 Below we modify socket/group/source timers in order to quickly
7118 reflect the change. Otherwise, those timers would eventually catch
7119 up.
7120 */
7121
7122 /* scan all sockets */
7123 for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
7124 struct listnode *grp_node;
7125 struct igmp_group *grp;
7126
7127 /* reschedule socket general query */
7128 igmp_sock_query_reschedule(igmp);
7129
7130 /* scan socket groups */
7131 for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
7132 grp)) {
7133 struct listnode *src_node;
7134 struct igmp_source *src;
7135
7136 /* reset group timers for groups in EXCLUDE mode */
7137 if (grp->group_filtermode_isexcl) {
7138 igmp_group_reset_gmi(grp);
7139 }
7140
7141 /* scan group sources */
7142 for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
7143 src_node, src)) {
7144
7145 /* reset source timers for sources with running
7146 * timers */
7147 if (src->t_source_timer) {
7148 igmp_source_reset_gmi(igmp, grp, src);
7149 }
7150 }
7151 }
7152 }
7153 }
7154
7155 #define IGMP_QUERY_INTERVAL_MIN (1)
7156 #define IGMP_QUERY_INTERVAL_MAX (1800)
7157
7158 DEFUN (interface_ip_igmp_query_interval,
7159 interface_ip_igmp_query_interval_cmd,
7160 "ip igmp query-interval (1-1800)",
7161 IP_STR
7162 IFACE_IGMP_STR
7163 IFACE_IGMP_QUERY_INTERVAL_STR
7164 "Query interval in seconds\n")
7165 {
7166 VTY_DECLVAR_CONTEXT(interface, ifp);
7167 struct pim_interface *pim_ifp = ifp->info;
7168 int query_interval;
7169 int query_interval_dsec;
7170 int ret;
7171
7172 if (!pim_ifp) {
7173 ret = pim_cmd_igmp_start(vty, ifp);
7174 if (ret != CMD_SUCCESS)
7175 return ret;
7176 pim_ifp = ifp->info;
7177 }
7178
7179 query_interval = atoi(argv[3]->arg);
7180 query_interval_dsec = 10 * query_interval;
7181
7182 /*
7183 It seems we don't need to check bounds since command.c does it
7184 already, but we verify them anyway for extra safety.
7185 */
7186 if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
7187 vty_out(vty,
7188 "General query interval %d lower than minimum %d\n",
7189 query_interval, IGMP_QUERY_INTERVAL_MIN);
7190 return CMD_WARNING_CONFIG_FAILED;
7191 }
7192 if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
7193 vty_out(vty,
7194 "General query interval %d higher than maximum %d\n",
7195 query_interval, IGMP_QUERY_INTERVAL_MAX);
7196 return CMD_WARNING_CONFIG_FAILED;
7197 }
7198
7199 if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
7200 vty_out(vty,
7201 "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
7202 query_interval_dsec,
7203 pim_ifp->igmp_query_max_response_time_dsec);
7204 return CMD_WARNING_CONFIG_FAILED;
7205 }
7206
7207 change_query_interval(pim_ifp, query_interval);
7208
7209 return CMD_SUCCESS;
7210 }
7211
7212 DEFUN (interface_no_ip_igmp_query_interval,
7213 interface_no_ip_igmp_query_interval_cmd,
7214 "no ip igmp query-interval",
7215 NO_STR
7216 IP_STR
7217 IFACE_IGMP_STR
7218 IFACE_IGMP_QUERY_INTERVAL_STR)
7219 {
7220 VTY_DECLVAR_CONTEXT(interface, ifp);
7221 struct pim_interface *pim_ifp = ifp->info;
7222 int default_query_interval_dsec;
7223
7224 if (!pim_ifp)
7225 return CMD_SUCCESS;
7226
7227 default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
7228
7229 if (default_query_interval_dsec
7230 <= pim_ifp->igmp_query_max_response_time_dsec) {
7231 vty_out(vty,
7232 "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
7233 default_query_interval_dsec,
7234 pim_ifp->igmp_query_max_response_time_dsec);
7235 return CMD_WARNING_CONFIG_FAILED;
7236 }
7237
7238 change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
7239
7240 return CMD_SUCCESS;
7241 }
7242
7243 DEFUN (interface_ip_igmp_version,
7244 interface_ip_igmp_version_cmd,
7245 "ip igmp version (2-3)",
7246 IP_STR
7247 IFACE_IGMP_STR
7248 "IGMP version\n"
7249 "IGMP version number\n")
7250 {
7251 VTY_DECLVAR_CONTEXT(interface, ifp);
7252 struct pim_interface *pim_ifp = ifp->info;
7253 int igmp_version, old_version = 0;
7254 int ret;
7255
7256 if (!pim_ifp) {
7257 ret = pim_cmd_igmp_start(vty, ifp);
7258 if (ret != CMD_SUCCESS)
7259 return ret;
7260 pim_ifp = ifp->info;
7261 }
7262
7263 igmp_version = atoi(argv[3]->arg);
7264 old_version = pim_ifp->igmp_version;
7265 pim_ifp->igmp_version = igmp_version;
7266
7267 // Check if IGMP is Enabled otherwise, enable on interface
7268 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7269 PIM_IF_DO_IGMP(pim_ifp->options);
7270 pim_if_addr_add_all(ifp);
7271 pim_if_membership_refresh(ifp);
7272 old_version = igmp_version;
7273 // avoid refreshing membership again.
7274 }
7275 /* Current and new version is different refresh existing
7276 membership. Going from 3 -> 2 or 2 -> 3. */
7277 if (old_version != igmp_version)
7278 pim_if_membership_refresh(ifp);
7279
7280 return CMD_SUCCESS;
7281 }
7282
7283 DEFUN (interface_no_ip_igmp_version,
7284 interface_no_ip_igmp_version_cmd,
7285 "no ip igmp version (2-3)",
7286 NO_STR
7287 IP_STR
7288 IFACE_IGMP_STR
7289 "IGMP version\n"
7290 "IGMP version number\n")
7291 {
7292 VTY_DECLVAR_CONTEXT(interface, ifp);
7293 struct pim_interface *pim_ifp = ifp->info;
7294
7295 if (!pim_ifp)
7296 return CMD_SUCCESS;
7297
7298 pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
7299
7300 return CMD_SUCCESS;
7301 }
7302
7303 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7304 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7305
7306 DEFUN (interface_ip_igmp_query_max_response_time,
7307 interface_ip_igmp_query_max_response_time_cmd,
7308 "ip igmp query-max-response-time (10-250)",
7309 IP_STR
7310 IFACE_IGMP_STR
7311 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7312 "Query response value in deci-seconds\n")
7313 {
7314 VTY_DECLVAR_CONTEXT(interface, ifp);
7315 struct pim_interface *pim_ifp = ifp->info;
7316 int query_max_response_time;
7317 int ret;
7318
7319 if (!pim_ifp) {
7320 ret = pim_cmd_igmp_start(vty, ifp);
7321 if (ret != CMD_SUCCESS)
7322 return ret;
7323 pim_ifp = ifp->info;
7324 }
7325
7326 query_max_response_time = atoi(argv[3]->arg);
7327
7328 if (query_max_response_time
7329 >= pim_ifp->igmp_default_query_interval * 10) {
7330 vty_out(vty,
7331 "Can't set query max response time %d sec >= general query interval %d sec\n",
7332 query_max_response_time,
7333 pim_ifp->igmp_default_query_interval);
7334 return CMD_WARNING_CONFIG_FAILED;
7335 }
7336
7337 change_query_max_response_time(pim_ifp, query_max_response_time);
7338
7339 return CMD_SUCCESS;
7340 }
7341
7342 DEFUN (interface_no_ip_igmp_query_max_response_time,
7343 interface_no_ip_igmp_query_max_response_time_cmd,
7344 "no ip igmp query-max-response-time (10-250)",
7345 NO_STR
7346 IP_STR
7347 IFACE_IGMP_STR
7348 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
7349 "Time for response in deci-seconds\n")
7350 {
7351 VTY_DECLVAR_CONTEXT(interface, ifp);
7352 struct pim_interface *pim_ifp = ifp->info;
7353
7354 if (!pim_ifp)
7355 return CMD_SUCCESS;
7356
7357 change_query_max_response_time(pim_ifp,
7358 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
7359
7360 return CMD_SUCCESS;
7361 }
7362
7363 #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
7364 #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
7365
7366 DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
7367 interface_ip_igmp_query_max_response_time_dsec_cmd,
7368 "ip igmp query-max-response-time-dsec (10-250)",
7369 IP_STR
7370 IFACE_IGMP_STR
7371 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
7372 "Query response value in deciseconds\n")
7373 {
7374 VTY_DECLVAR_CONTEXT(interface, ifp);
7375 struct pim_interface *pim_ifp = ifp->info;
7376 int query_max_response_time_dsec;
7377 int default_query_interval_dsec;
7378 int ret;
7379
7380 if (!pim_ifp) {
7381 ret = pim_cmd_igmp_start(vty, ifp);
7382 if (ret != CMD_SUCCESS)
7383 return ret;
7384 pim_ifp = ifp->info;
7385 }
7386
7387 query_max_response_time_dsec = atoi(argv[4]->arg);
7388
7389 default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
7390
7391 if (query_max_response_time_dsec >= default_query_interval_dsec) {
7392 vty_out(vty,
7393 "Can't set query max response time %d dsec >= general query interval %d dsec\n",
7394 query_max_response_time_dsec,
7395 default_query_interval_dsec);
7396 return CMD_WARNING_CONFIG_FAILED;
7397 }
7398
7399 change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
7400
7401 return CMD_SUCCESS;
7402 }
7403
7404 DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
7405 interface_no_ip_igmp_query_max_response_time_dsec_cmd,
7406 "no ip igmp query-max-response-time-dsec",
7407 NO_STR
7408 IP_STR
7409 IFACE_IGMP_STR
7410 IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
7411 {
7412 VTY_DECLVAR_CONTEXT(interface, ifp);
7413 struct pim_interface *pim_ifp = ifp->info;
7414
7415 if (!pim_ifp)
7416 return CMD_SUCCESS;
7417
7418 change_query_max_response_time(pim_ifp,
7419 IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
7420
7421 return CMD_SUCCESS;
7422 }
7423
7424 #define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1)
7425 #define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7)
7426
7427 DEFUN (interface_ip_igmp_last_member_query_count,
7428 interface_ip_igmp_last_member_query_count_cmd,
7429 "ip igmp last-member-query-count (1-7)",
7430 IP_STR
7431 IFACE_IGMP_STR
7432 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
7433 "Last member query count\n")
7434 {
7435 VTY_DECLVAR_CONTEXT(interface, ifp);
7436 struct pim_interface *pim_ifp = ifp->info;
7437 int last_member_query_count;
7438 int ret;
7439
7440 if (!pim_ifp) {
7441 ret = pim_cmd_igmp_start(vty, ifp);
7442 if (ret != CMD_SUCCESS)
7443 return ret;
7444 pim_ifp = ifp->info;
7445 }
7446
7447 last_member_query_count = atoi(argv[3]->arg);
7448
7449 pim_ifp->igmp_last_member_query_count = last_member_query_count;
7450
7451 return CMD_SUCCESS;
7452 }
7453
7454 DEFUN (interface_no_ip_igmp_last_member_query_count,
7455 interface_no_ip_igmp_last_member_query_count_cmd,
7456 "no ip igmp last-member-query-count",
7457 NO_STR
7458 IP_STR
7459 IFACE_IGMP_STR
7460 IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR)
7461 {
7462 VTY_DECLVAR_CONTEXT(interface, ifp);
7463 struct pim_interface *pim_ifp = ifp->info;
7464
7465 if (!pim_ifp)
7466 return CMD_SUCCESS;
7467
7468 pim_ifp->igmp_last_member_query_count =
7469 IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
7470
7471 return CMD_SUCCESS;
7472 }
7473
7474 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1)
7475 #define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255)
7476
7477 DEFUN (interface_ip_igmp_last_member_query_interval,
7478 interface_ip_igmp_last_member_query_interval_cmd,
7479 "ip igmp last-member-query-interval (1-255)",
7480 IP_STR
7481 IFACE_IGMP_STR
7482 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
7483 "Last member query interval in deciseconds\n")
7484 {
7485 VTY_DECLVAR_CONTEXT(interface, ifp);
7486 struct pim_interface *pim_ifp = ifp->info;
7487 int last_member_query_interval;
7488 int ret;
7489
7490 if (!pim_ifp) {
7491 ret = pim_cmd_igmp_start(vty, ifp);
7492 if (ret != CMD_SUCCESS)
7493 return ret;
7494 pim_ifp = ifp->info;
7495 }
7496
7497 last_member_query_interval = atoi(argv[3]->arg);
7498 pim_ifp->igmp_specific_query_max_response_time_dsec
7499 = last_member_query_interval;
7500
7501 return CMD_SUCCESS;
7502 }
7503
7504 DEFUN (interface_no_ip_igmp_last_member_query_interval,
7505 interface_no_ip_igmp_last_member_query_interval_cmd,
7506 "no ip igmp last-member-query-interval",
7507 NO_STR
7508 IP_STR
7509 IFACE_IGMP_STR
7510 IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR)
7511 {
7512 VTY_DECLVAR_CONTEXT(interface, ifp);
7513 struct pim_interface *pim_ifp = ifp->info;
7514
7515 if (!pim_ifp)
7516 return CMD_SUCCESS;
7517
7518 pim_ifp->igmp_specific_query_max_response_time_dsec =
7519 IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
7520
7521 return CMD_SUCCESS;
7522 }
7523
7524 DEFUN (interface_ip_pim_drprio,
7525 interface_ip_pim_drprio_cmd,
7526 "ip pim drpriority (1-4294967295)",
7527 IP_STR
7528 PIM_STR
7529 "Set the Designated Router Election Priority\n"
7530 "Value of the new DR Priority\n")
7531 {
7532 VTY_DECLVAR_CONTEXT(interface, ifp);
7533 int idx_number = 3;
7534 struct pim_interface *pim_ifp = ifp->info;
7535 uint32_t old_dr_prio;
7536
7537 if (!pim_ifp) {
7538 vty_out(vty, "Please enable PIM on interface, first\n");
7539 return CMD_WARNING_CONFIG_FAILED;
7540 }
7541
7542 old_dr_prio = pim_ifp->pim_dr_priority;
7543
7544 pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
7545
7546 if (old_dr_prio != pim_ifp->pim_dr_priority) {
7547 pim_if_dr_election(ifp);
7548 pim_hello_restart_now(ifp);
7549 }
7550
7551 return CMD_SUCCESS;
7552 }
7553
7554 DEFUN (interface_no_ip_pim_drprio,
7555 interface_no_ip_pim_drprio_cmd,
7556 "no ip pim drpriority [(1-4294967295)]",
7557 NO_STR
7558 IP_STR
7559 PIM_STR
7560 "Revert the Designated Router Priority to default\n"
7561 "Old Value of the Priority\n")
7562 {
7563 VTY_DECLVAR_CONTEXT(interface, ifp);
7564 struct pim_interface *pim_ifp = ifp->info;
7565
7566 if (!pim_ifp) {
7567 vty_out(vty, "Pim not enabled on this interface\n");
7568 return CMD_WARNING_CONFIG_FAILED;
7569 }
7570
7571 if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
7572 pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
7573 pim_if_dr_election(ifp);
7574 pim_hello_restart_now(ifp);
7575 }
7576
7577 return CMD_SUCCESS;
7578 }
7579
7580 DEFPY_HIDDEN (interface_ip_igmp_query_generate,
7581 interface_ip_igmp_query_generate_cmd,
7582 "ip igmp generate-query-once [version (2-3)]",
7583 IP_STR
7584 IFACE_IGMP_STR
7585 "Generate igmp general query once\n"
7586 "IGMP version\n"
7587 "IGMP version number\n")
7588 {
7589 VTY_DECLVAR_CONTEXT(interface, ifp);
7590 int igmp_version = 2;
7591
7592 if (!ifp->info) {
7593 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
7594 ifp->name);
7595 return CMD_WARNING_CONFIG_FAILED;
7596 }
7597
7598 if (argc > 3)
7599 igmp_version = atoi(argv[4]->arg);
7600
7601 igmp_send_query_on_intf(ifp, igmp_version);
7602
7603 return CMD_SUCCESS;
7604 }
7605
7606 static int pim_cmd_interface_add(struct interface *ifp)
7607 {
7608 struct pim_interface *pim_ifp = ifp->info;
7609
7610 if (!pim_ifp)
7611 pim_ifp = pim_if_new(ifp, false, true, false, false);
7612 else
7613 PIM_IF_DO_PIM(pim_ifp->options);
7614
7615 pim_if_addr_add_all(ifp);
7616 pim_if_membership_refresh(ifp);
7617
7618 pim_if_create_pimreg(pim_ifp->pim);
7619 return 1;
7620 }
7621
7622 DEFPY_HIDDEN (pim_test_sg_keepalive,
7623 pim_test_sg_keepalive_cmd,
7624 "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
7625 "Test code\n"
7626 PIM_STR
7627 VRF_CMD_HELP_STR
7628 "Reset the Keepalive Timer\n"
7629 "The Source we are resetting\n"
7630 "The Group we are resetting\n")
7631 {
7632 struct pim_upstream *up;
7633 struct pim_instance *pim;
7634 struct prefix_sg sg;
7635
7636 sg.src = source;
7637 sg.grp = group;
7638
7639 if (!name)
7640 pim = pim_get_pim_instance(VRF_DEFAULT);
7641 else {
7642 struct vrf *vrf = vrf_lookup_by_name(name);
7643
7644 if (!vrf) {
7645 vty_out(vty, "%% Vrf specified: %s does not exist\n",
7646 name);
7647 return CMD_WARNING;
7648 }
7649
7650 pim = pim_get_pim_instance(vrf->vrf_id);
7651 }
7652
7653 if (!pim) {
7654 vty_out(vty, "%% Unable to find pim instance\n");
7655 return CMD_WARNING;
7656 }
7657
7658 up = pim_upstream_find(pim, &sg);
7659 if (!up) {
7660 vty_out(vty, "%% Unable to find %s specified\n",
7661 pim_str_sg_dump(&sg));
7662 return CMD_WARNING;
7663 }
7664
7665 vty_out(vty, "Setting %s to current keep alive time: %d\n",
7666 pim_str_sg_dump(&sg), pim->keep_alive_time);
7667 pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
7668
7669 return CMD_SUCCESS;
7670 }
7671
7672 DEFPY_HIDDEN (interface_ip_pim_activeactive,
7673 interface_ip_pim_activeactive_cmd,
7674 "[no$no] ip pim active-active",
7675 NO_STR
7676 IP_STR
7677 PIM_STR
7678 "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
7679 {
7680 VTY_DECLVAR_CONTEXT(interface, ifp);
7681 struct pim_interface *pim_ifp;
7682
7683 if (!no && !pim_cmd_interface_add(ifp)) {
7684 vty_out(vty, "Could not enable PIM SM active-active on interface\n");
7685 return CMD_WARNING_CONFIG_FAILED;
7686 }
7687
7688 pim_ifp = ifp->info;
7689 if (no)
7690 pim_if_unconfigure_mlag_dualactive(pim_ifp);
7691 else
7692 pim_if_configure_mlag_dualactive(pim_ifp);
7693
7694 return CMD_SUCCESS;
7695 }
7696
7697 DEFUN_HIDDEN (interface_ip_pim_ssm,
7698 interface_ip_pim_ssm_cmd,
7699 "ip pim ssm",
7700 IP_STR
7701 PIM_STR
7702 IFACE_PIM_STR)
7703 {
7704 VTY_DECLVAR_CONTEXT(interface, ifp);
7705
7706 if (!pim_cmd_interface_add(ifp)) {
7707 vty_out(vty, "Could not enable PIM SM on interface\n");
7708 return CMD_WARNING_CONFIG_FAILED;
7709 }
7710
7711 vty_out(vty,
7712 "WARN: Enabled PIM SM on interface; configure PIM SSM "
7713 "range if needed\n");
7714 return CMD_SUCCESS;
7715 }
7716
7717 static int interface_ip_pim_helper(struct vty *vty)
7718 {
7719 struct pim_interface *pim_ifp;
7720
7721 VTY_DECLVAR_CONTEXT(interface, ifp);
7722
7723 if (!pim_cmd_interface_add(ifp)) {
7724 vty_out(vty, "Could not enable PIM SM on interface\n");
7725 return CMD_WARNING_CONFIG_FAILED;
7726 }
7727
7728 pim_ifp = ifp->info;
7729
7730 pim_if_create_pimreg(pim_ifp->pim);
7731
7732 return CMD_SUCCESS;
7733 }
7734
7735 DEFUN_HIDDEN (interface_ip_pim_sm,
7736 interface_ip_pim_sm_cmd,
7737 "ip pim sm",
7738 IP_STR
7739 PIM_STR
7740 IFACE_PIM_SM_STR)
7741 {
7742 return interface_ip_pim_helper(vty);
7743 }
7744
7745 DEFUN (interface_ip_pim,
7746 interface_ip_pim_cmd,
7747 "ip pim",
7748 IP_STR
7749 PIM_STR)
7750 {
7751 return interface_ip_pim_helper(vty);
7752 }
7753
7754 static int pim_cmd_interface_delete(struct interface *ifp)
7755 {
7756 struct pim_interface *pim_ifp = ifp->info;
7757
7758 if (!pim_ifp)
7759 return 1;
7760
7761 PIM_IF_DONT_PIM(pim_ifp->options);
7762
7763 pim_if_membership_clear(ifp);
7764
7765 /*
7766 pim_sock_delete() removes all neighbors from
7767 pim_ifp->pim_neighbor_list.
7768 */
7769 pim_sock_delete(ifp, "pim unconfigured on interface");
7770
7771 if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
7772 pim_if_addr_del_all(ifp);
7773 pim_if_delete(ifp);
7774 }
7775
7776 return 1;
7777 }
7778
7779 static int interface_no_ip_pim_helper(struct vty *vty)
7780 {
7781 VTY_DECLVAR_CONTEXT(interface, ifp);
7782 if (!pim_cmd_interface_delete(ifp)) {
7783 vty_out(vty, "Unable to delete interface information\n");
7784 return CMD_WARNING_CONFIG_FAILED;
7785 }
7786
7787 return CMD_SUCCESS;
7788 }
7789
7790 DEFUN_HIDDEN (interface_no_ip_pim_ssm,
7791 interface_no_ip_pim_ssm_cmd,
7792 "no ip pim ssm",
7793 NO_STR
7794 IP_STR
7795 PIM_STR
7796 IFACE_PIM_STR)
7797 {
7798 return interface_no_ip_pim_helper(vty);
7799 }
7800
7801 DEFUN_HIDDEN (interface_no_ip_pim_sm,
7802 interface_no_ip_pim_sm_cmd,
7803 "no ip pim sm",
7804 NO_STR
7805 IP_STR
7806 PIM_STR
7807 IFACE_PIM_SM_STR)
7808 {
7809 return interface_no_ip_pim_helper(vty);
7810 }
7811
7812 DEFUN (interface_no_ip_pim,
7813 interface_no_ip_pim_cmd,
7814 "no ip pim",
7815 NO_STR
7816 IP_STR
7817 PIM_STR)
7818 {
7819 return interface_no_ip_pim_helper(vty);
7820 }
7821
7822 /* boundaries */
7823 DEFUN(interface_ip_pim_boundary_oil,
7824 interface_ip_pim_boundary_oil_cmd,
7825 "ip multicast boundary oil WORD",
7826 IP_STR
7827 "Generic multicast configuration options\n"
7828 "Define multicast boundary\n"
7829 "Filter OIL by group using prefix list\n"
7830 "Prefix list to filter OIL with\n")
7831 {
7832 VTY_DECLVAR_CONTEXT(interface, iif);
7833 struct pim_interface *pim_ifp;
7834 int idx = 0;
7835
7836 argv_find(argv, argc, "WORD", &idx);
7837
7838 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7839
7840 if (pim_ifp->boundary_oil_plist)
7841 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7842
7843 pim_ifp->boundary_oil_plist =
7844 XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
7845
7846 /* Interface will be pruned from OIL on next Join */
7847 return CMD_SUCCESS;
7848 }
7849
7850 DEFUN(interface_no_ip_pim_boundary_oil,
7851 interface_no_ip_pim_boundary_oil_cmd,
7852 "no ip multicast boundary oil [WORD]",
7853 NO_STR
7854 IP_STR
7855 "Generic multicast configuration options\n"
7856 "Define multicast boundary\n"
7857 "Filter OIL by group using prefix list\n"
7858 "Prefix list to filter OIL with\n")
7859 {
7860 VTY_DECLVAR_CONTEXT(interface, iif);
7861 struct pim_interface *pim_ifp;
7862 int idx = 0;
7863
7864 argv_find(argv, argc, "WORD", &idx);
7865
7866 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7867
7868 if (pim_ifp->boundary_oil_plist)
7869 XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
7870
7871 return CMD_SUCCESS;
7872 }
7873
7874 DEFUN (interface_ip_mroute,
7875 interface_ip_mroute_cmd,
7876 "ip mroute INTERFACE A.B.C.D",
7877 IP_STR
7878 "Add multicast route\n"
7879 "Outgoing interface name\n"
7880 "Group address\n")
7881 {
7882 VTY_DECLVAR_CONTEXT(interface, iif);
7883 struct pim_interface *pim_ifp;
7884 struct pim_instance *pim;
7885 int idx_interface = 2;
7886 int idx_ipv4 = 3;
7887 struct interface *oif;
7888 const char *oifname;
7889 const char *grp_str;
7890 struct in_addr grp_addr;
7891 struct in_addr src_addr;
7892 int result;
7893
7894 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7895 pim = pim_ifp->pim;
7896
7897 oifname = argv[idx_interface]->arg;
7898 oif = if_lookup_by_name(oifname, pim->vrf_id);
7899 if (!oif) {
7900 vty_out(vty, "No such interface name %s\n", oifname);
7901 return CMD_WARNING;
7902 }
7903
7904 grp_str = argv[idx_ipv4]->arg;
7905 result = inet_pton(AF_INET, grp_str, &grp_addr);
7906 if (result <= 0) {
7907 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7908 errno, safe_strerror(errno));
7909 return CMD_WARNING;
7910 }
7911
7912 src_addr.s_addr = INADDR_ANY;
7913
7914 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
7915 vty_out(vty, "Failed to add route\n");
7916 return CMD_WARNING;
7917 }
7918
7919 return CMD_SUCCESS;
7920 }
7921
7922 DEFUN (interface_ip_mroute_source,
7923 interface_ip_mroute_source_cmd,
7924 "ip mroute INTERFACE A.B.C.D A.B.C.D",
7925 IP_STR
7926 "Add multicast route\n"
7927 "Outgoing interface name\n"
7928 "Group address\n"
7929 "Source address\n")
7930 {
7931 VTY_DECLVAR_CONTEXT(interface, iif);
7932 struct pim_interface *pim_ifp;
7933 struct pim_instance *pim;
7934 int idx_interface = 2;
7935 int idx_ipv4 = 3;
7936 int idx_ipv4_2 = 4;
7937 struct interface *oif;
7938 const char *oifname;
7939 const char *grp_str;
7940 struct in_addr grp_addr;
7941 const char *src_str;
7942 struct in_addr src_addr;
7943 int result;
7944
7945 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
7946 pim = pim_ifp->pim;
7947
7948 oifname = argv[idx_interface]->arg;
7949 oif = if_lookup_by_name(oifname, pim->vrf_id);
7950 if (!oif) {
7951 vty_out(vty, "No such interface name %s\n", oifname);
7952 return CMD_WARNING;
7953 }
7954
7955 grp_str = argv[idx_ipv4]->arg;
7956 result = inet_pton(AF_INET, grp_str, &grp_addr);
7957 if (result <= 0) {
7958 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
7959 errno, safe_strerror(errno));
7960 return CMD_WARNING;
7961 }
7962
7963 src_str = argv[idx_ipv4_2]->arg;
7964 result = inet_pton(AF_INET, src_str, &src_addr);
7965 if (result <= 0) {
7966 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
7967 errno, safe_strerror(errno));
7968 return CMD_WARNING;
7969 }
7970
7971 if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
7972 vty_out(vty, "Failed to add route\n");
7973 return CMD_WARNING;
7974 }
7975
7976 return CMD_SUCCESS;
7977 }
7978
7979 DEFUN (interface_no_ip_mroute,
7980 interface_no_ip_mroute_cmd,
7981 "no ip mroute INTERFACE A.B.C.D",
7982 NO_STR
7983 IP_STR
7984 "Add multicast route\n"
7985 "Outgoing interface name\n"
7986 "Group Address\n")
7987 {
7988 VTY_DECLVAR_CONTEXT(interface, iif);
7989 struct pim_interface *pim_ifp;
7990 struct pim_instance *pim;
7991 int idx_interface = 3;
7992 int idx_ipv4 = 4;
7993 struct interface *oif;
7994 const char *oifname;
7995 const char *grp_str;
7996 struct in_addr grp_addr;
7997 struct in_addr src_addr;
7998 int result;
7999
8000 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
8001 pim = pim_ifp->pim;
8002
8003 oifname = argv[idx_interface]->arg;
8004 oif = if_lookup_by_name(oifname, pim->vrf_id);
8005 if (!oif) {
8006 vty_out(vty, "No such interface name %s\n", oifname);
8007 return CMD_WARNING;
8008 }
8009
8010 grp_str = argv[idx_ipv4]->arg;
8011 result = inet_pton(AF_INET, grp_str, &grp_addr);
8012 if (result <= 0) {
8013 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
8014 errno, safe_strerror(errno));
8015 return CMD_WARNING;
8016 }
8017
8018 src_addr.s_addr = INADDR_ANY;
8019
8020 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
8021 vty_out(vty, "Failed to remove route\n");
8022 return CMD_WARNING;
8023 }
8024
8025 return CMD_SUCCESS;
8026 }
8027
8028 DEFUN (interface_no_ip_mroute_source,
8029 interface_no_ip_mroute_source_cmd,
8030 "no ip mroute INTERFACE A.B.C.D A.B.C.D",
8031 NO_STR
8032 IP_STR
8033 "Add multicast route\n"
8034 "Outgoing interface name\n"
8035 "Group Address\n"
8036 "Source Address\n")
8037 {
8038 VTY_DECLVAR_CONTEXT(interface, iif);
8039 struct pim_interface *pim_ifp;
8040 struct pim_instance *pim;
8041 int idx_interface = 3;
8042 int idx_ipv4 = 4;
8043 int idx_ipv4_2 = 5;
8044 struct interface *oif;
8045 const char *oifname;
8046 const char *grp_str;
8047 struct in_addr grp_addr;
8048 const char *src_str;
8049 struct in_addr src_addr;
8050 int result;
8051
8052 PIM_GET_PIM_INTERFACE(pim_ifp, iif);
8053 pim = pim_ifp->pim;
8054
8055 oifname = argv[idx_interface]->arg;
8056 oif = if_lookup_by_name(oifname, pim->vrf_id);
8057 if (!oif) {
8058 vty_out(vty, "No such interface name %s\n", oifname);
8059 return CMD_WARNING;
8060 }
8061
8062 grp_str = argv[idx_ipv4]->arg;
8063 result = inet_pton(AF_INET, grp_str, &grp_addr);
8064 if (result <= 0) {
8065 vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
8066 errno, safe_strerror(errno));
8067 return CMD_WARNING;
8068 }
8069
8070 src_str = argv[idx_ipv4_2]->arg;
8071 result = inet_pton(AF_INET, src_str, &src_addr);
8072 if (result <= 0) {
8073 vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
8074 errno, safe_strerror(errno));
8075 return CMD_WARNING;
8076 }
8077
8078 if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
8079 vty_out(vty, "Failed to remove route\n");
8080 return CMD_WARNING;
8081 }
8082
8083 return CMD_SUCCESS;
8084 }
8085
8086 DEFUN (interface_ip_pim_hello,
8087 interface_ip_pim_hello_cmd,
8088 "ip pim hello (1-180) [(1-180)]",
8089 IP_STR
8090 PIM_STR
8091 IFACE_PIM_HELLO_STR
8092 IFACE_PIM_HELLO_TIME_STR
8093 IFACE_PIM_HELLO_HOLD_STR)
8094 {
8095 VTY_DECLVAR_CONTEXT(interface, ifp);
8096 int idx_time = 3;
8097 int idx_hold = 4;
8098 struct pim_interface *pim_ifp = ifp->info;
8099
8100 if (!pim_ifp) {
8101 if (!pim_cmd_interface_add(ifp)) {
8102 vty_out(vty, "Could not enable PIM SM on interface\n");
8103 return CMD_WARNING_CONFIG_FAILED;
8104 }
8105 }
8106
8107 pim_ifp = ifp->info;
8108 pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
8109
8110 if (argc == idx_hold + 1)
8111 pim_ifp->pim_default_holdtime =
8112 strtol(argv[idx_hold]->arg, NULL, 10);
8113
8114 return CMD_SUCCESS;
8115 }
8116
8117 DEFUN (interface_no_ip_pim_hello,
8118 interface_no_ip_pim_hello_cmd,
8119 "no ip pim hello [(1-180) (1-180)]",
8120 NO_STR
8121 IP_STR
8122 PIM_STR
8123 IFACE_PIM_HELLO_STR
8124 IFACE_PIM_HELLO_TIME_STR
8125 IFACE_PIM_HELLO_HOLD_STR)
8126 {
8127 VTY_DECLVAR_CONTEXT(interface, ifp);
8128 struct pim_interface *pim_ifp = ifp->info;
8129
8130 if (!pim_ifp) {
8131 vty_out(vty, "Pim not enabled on this interface\n");
8132 return CMD_WARNING_CONFIG_FAILED;
8133 }
8134
8135 pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
8136 pim_ifp->pim_default_holdtime = -1;
8137
8138 return CMD_SUCCESS;
8139 }
8140
8141 DEFUN (debug_igmp,
8142 debug_igmp_cmd,
8143 "debug igmp",
8144 DEBUG_STR
8145 DEBUG_IGMP_STR)
8146 {
8147 PIM_DO_DEBUG_IGMP_EVENTS;
8148 PIM_DO_DEBUG_IGMP_PACKETS;
8149 PIM_DO_DEBUG_IGMP_TRACE;
8150 return CMD_SUCCESS;
8151 }
8152
8153 DEFUN (no_debug_igmp,
8154 no_debug_igmp_cmd,
8155 "no debug igmp",
8156 NO_STR
8157 DEBUG_STR
8158 DEBUG_IGMP_STR)
8159 {
8160 PIM_DONT_DEBUG_IGMP_EVENTS;
8161 PIM_DONT_DEBUG_IGMP_PACKETS;
8162 PIM_DONT_DEBUG_IGMP_TRACE;
8163 return CMD_SUCCESS;
8164 }
8165
8166
8167 DEFUN (debug_igmp_events,
8168 debug_igmp_events_cmd,
8169 "debug igmp events",
8170 DEBUG_STR
8171 DEBUG_IGMP_STR
8172 DEBUG_IGMP_EVENTS_STR)
8173 {
8174 PIM_DO_DEBUG_IGMP_EVENTS;
8175 return CMD_SUCCESS;
8176 }
8177
8178 DEFUN (no_debug_igmp_events,
8179 no_debug_igmp_events_cmd,
8180 "no debug igmp events",
8181 NO_STR
8182 DEBUG_STR
8183 DEBUG_IGMP_STR
8184 DEBUG_IGMP_EVENTS_STR)
8185 {
8186 PIM_DONT_DEBUG_IGMP_EVENTS;
8187 return CMD_SUCCESS;
8188 }
8189
8190
8191 DEFUN (debug_igmp_packets,
8192 debug_igmp_packets_cmd,
8193 "debug igmp packets",
8194 DEBUG_STR
8195 DEBUG_IGMP_STR
8196 DEBUG_IGMP_PACKETS_STR)
8197 {
8198 PIM_DO_DEBUG_IGMP_PACKETS;
8199 return CMD_SUCCESS;
8200 }
8201
8202 DEFUN (no_debug_igmp_packets,
8203 no_debug_igmp_packets_cmd,
8204 "no debug igmp packets",
8205 NO_STR
8206 DEBUG_STR
8207 DEBUG_IGMP_STR
8208 DEBUG_IGMP_PACKETS_STR)
8209 {
8210 PIM_DONT_DEBUG_IGMP_PACKETS;
8211 return CMD_SUCCESS;
8212 }
8213
8214
8215 DEFUN (debug_igmp_trace,
8216 debug_igmp_trace_cmd,
8217 "debug igmp trace",
8218 DEBUG_STR
8219 DEBUG_IGMP_STR
8220 DEBUG_IGMP_TRACE_STR)
8221 {
8222 PIM_DO_DEBUG_IGMP_TRACE;
8223 return CMD_SUCCESS;
8224 }
8225
8226 DEFUN (no_debug_igmp_trace,
8227 no_debug_igmp_trace_cmd,
8228 "no debug igmp trace",
8229 NO_STR
8230 DEBUG_STR
8231 DEBUG_IGMP_STR
8232 DEBUG_IGMP_TRACE_STR)
8233 {
8234 PIM_DONT_DEBUG_IGMP_TRACE;
8235 return CMD_SUCCESS;
8236 }
8237
8238
8239 DEFUN (debug_mroute,
8240 debug_mroute_cmd,
8241 "debug mroute",
8242 DEBUG_STR
8243 DEBUG_MROUTE_STR)
8244 {
8245 PIM_DO_DEBUG_MROUTE;
8246 return CMD_SUCCESS;
8247 }
8248
8249 DEFUN (debug_mroute_detail,
8250 debug_mroute_detail_cmd,
8251 "debug mroute detail",
8252 DEBUG_STR
8253 DEBUG_MROUTE_STR
8254 "detailed\n")
8255 {
8256 PIM_DO_DEBUG_MROUTE_DETAIL;
8257 return CMD_SUCCESS;
8258 }
8259
8260 DEFUN (no_debug_mroute,
8261 no_debug_mroute_cmd,
8262 "no debug mroute",
8263 NO_STR
8264 DEBUG_STR
8265 DEBUG_MROUTE_STR)
8266 {
8267 PIM_DONT_DEBUG_MROUTE;
8268 return CMD_SUCCESS;
8269 }
8270
8271 DEFUN (no_debug_mroute_detail,
8272 no_debug_mroute_detail_cmd,
8273 "no debug mroute detail",
8274 NO_STR
8275 DEBUG_STR
8276 DEBUG_MROUTE_STR
8277 "detailed\n")
8278 {
8279 PIM_DONT_DEBUG_MROUTE_DETAIL;
8280 return CMD_SUCCESS;
8281 }
8282
8283 DEFUN (debug_pim_static,
8284 debug_pim_static_cmd,
8285 "debug pim static",
8286 DEBUG_STR
8287 DEBUG_PIM_STR
8288 DEBUG_STATIC_STR)
8289 {
8290 PIM_DO_DEBUG_STATIC;
8291 return CMD_SUCCESS;
8292 }
8293
8294 DEFUN (no_debug_pim_static,
8295 no_debug_pim_static_cmd,
8296 "no debug pim static",
8297 NO_STR
8298 DEBUG_STR
8299 DEBUG_PIM_STR
8300 DEBUG_STATIC_STR)
8301 {
8302 PIM_DONT_DEBUG_STATIC;
8303 return CMD_SUCCESS;
8304 }
8305
8306
8307 DEFUN (debug_pim,
8308 debug_pim_cmd,
8309 "debug pim",
8310 DEBUG_STR
8311 DEBUG_PIM_STR)
8312 {
8313 PIM_DO_DEBUG_PIM_EVENTS;
8314 PIM_DO_DEBUG_PIM_PACKETS;
8315 PIM_DO_DEBUG_PIM_TRACE;
8316 PIM_DO_DEBUG_MSDP_EVENTS;
8317 PIM_DO_DEBUG_MSDP_PACKETS;
8318 PIM_DO_DEBUG_BSM;
8319 return CMD_SUCCESS;
8320 }
8321
8322 DEFUN (no_debug_pim,
8323 no_debug_pim_cmd,
8324 "no debug pim",
8325 NO_STR
8326 DEBUG_STR
8327 DEBUG_PIM_STR)
8328 {
8329 PIM_DONT_DEBUG_PIM_EVENTS;
8330 PIM_DONT_DEBUG_PIM_PACKETS;
8331 PIM_DONT_DEBUG_PIM_TRACE;
8332 PIM_DONT_DEBUG_MSDP_EVENTS;
8333 PIM_DONT_DEBUG_MSDP_PACKETS;
8334
8335 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8336 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8337 PIM_DONT_DEBUG_BSM;
8338
8339 return CMD_SUCCESS;
8340 }
8341
8342 DEFUN (debug_pim_nht,
8343 debug_pim_nht_cmd,
8344 "debug pim nht",
8345 DEBUG_STR
8346 DEBUG_PIM_STR
8347 "Nexthop Tracking\n")
8348 {
8349 PIM_DO_DEBUG_PIM_NHT;
8350 return CMD_SUCCESS;
8351 }
8352
8353 DEFUN (no_debug_pim_nht,
8354 no_debug_pim_nht_cmd,
8355 "no debug pim nht",
8356 NO_STR
8357 DEBUG_STR
8358 DEBUG_PIM_STR
8359 "Nexthop Tracking\n")
8360 {
8361 PIM_DONT_DEBUG_PIM_NHT;
8362 return CMD_SUCCESS;
8363 }
8364
8365 DEFUN (debug_pim_nht_rp,
8366 debug_pim_nht_rp_cmd,
8367 "debug pim nht rp",
8368 DEBUG_STR
8369 DEBUG_PIM_STR
8370 "Nexthop Tracking\n"
8371 "RP Nexthop Tracking\n")
8372 {
8373 PIM_DO_DEBUG_PIM_NHT_RP;
8374 return CMD_SUCCESS;
8375 }
8376
8377 DEFUN (no_debug_pim_nht_rp,
8378 no_debug_pim_nht_rp_cmd,
8379 "no debug pim nht rp",
8380 NO_STR
8381 DEBUG_STR
8382 DEBUG_PIM_STR
8383 "Nexthop Tracking\n"
8384 "RP Nexthop Tracking\n")
8385 {
8386 PIM_DONT_DEBUG_PIM_NHT_RP;
8387 return CMD_SUCCESS;
8388 }
8389
8390 DEFUN (debug_pim_events,
8391 debug_pim_events_cmd,
8392 "debug pim events",
8393 DEBUG_STR
8394 DEBUG_PIM_STR
8395 DEBUG_PIM_EVENTS_STR)
8396 {
8397 PIM_DO_DEBUG_PIM_EVENTS;
8398 return CMD_SUCCESS;
8399 }
8400
8401 DEFUN (no_debug_pim_events,
8402 no_debug_pim_events_cmd,
8403 "no debug pim events",
8404 NO_STR
8405 DEBUG_STR
8406 DEBUG_PIM_STR
8407 DEBUG_PIM_EVENTS_STR)
8408 {
8409 PIM_DONT_DEBUG_PIM_EVENTS;
8410 return CMD_SUCCESS;
8411 }
8412
8413 DEFUN (debug_pim_packets,
8414 debug_pim_packets_cmd,
8415 "debug pim packets [<hello|joins|register>]",
8416 DEBUG_STR
8417 DEBUG_PIM_STR
8418 DEBUG_PIM_PACKETS_STR
8419 DEBUG_PIM_HELLO_PACKETS_STR
8420 DEBUG_PIM_J_P_PACKETS_STR
8421 DEBUG_PIM_PIM_REG_PACKETS_STR)
8422 {
8423 int idx = 0;
8424 if (argv_find(argv, argc, "hello", &idx)) {
8425 PIM_DO_DEBUG_PIM_HELLO;
8426 vty_out(vty, "PIM Hello debugging is on\n");
8427 } else if (argv_find(argv, argc, "joins", &idx)) {
8428 PIM_DO_DEBUG_PIM_J_P;
8429 vty_out(vty, "PIM Join/Prune debugging is on\n");
8430 } else if (argv_find(argv, argc, "register", &idx)) {
8431 PIM_DO_DEBUG_PIM_REG;
8432 vty_out(vty, "PIM Register debugging is on\n");
8433 } else {
8434 PIM_DO_DEBUG_PIM_PACKETS;
8435 vty_out(vty, "PIM Packet debugging is on \n");
8436 }
8437 return CMD_SUCCESS;
8438 }
8439
8440 DEFUN (no_debug_pim_packets,
8441 no_debug_pim_packets_cmd,
8442 "no debug pim packets [<hello|joins|register>]",
8443 NO_STR
8444 DEBUG_STR
8445 DEBUG_PIM_STR
8446 DEBUG_PIM_PACKETS_STR
8447 DEBUG_PIM_HELLO_PACKETS_STR
8448 DEBUG_PIM_J_P_PACKETS_STR
8449 DEBUG_PIM_PIM_REG_PACKETS_STR)
8450 {
8451 int idx = 0;
8452 if (argv_find(argv, argc, "hello", &idx)) {
8453 PIM_DONT_DEBUG_PIM_HELLO;
8454 vty_out(vty, "PIM Hello debugging is off \n");
8455 } else if (argv_find(argv, argc, "joins", &idx)) {
8456 PIM_DONT_DEBUG_PIM_J_P;
8457 vty_out(vty, "PIM Join/Prune debugging is off \n");
8458 } else if (argv_find(argv, argc, "register", &idx)) {
8459 PIM_DONT_DEBUG_PIM_REG;
8460 vty_out(vty, "PIM Register debugging is off\n");
8461 } else
8462 PIM_DONT_DEBUG_PIM_PACKETS;
8463
8464 return CMD_SUCCESS;
8465 }
8466
8467
8468 DEFUN (debug_pim_packetdump_send,
8469 debug_pim_packetdump_send_cmd,
8470 "debug pim packet-dump send",
8471 DEBUG_STR
8472 DEBUG_PIM_STR
8473 DEBUG_PIM_PACKETDUMP_STR
8474 DEBUG_PIM_PACKETDUMP_SEND_STR)
8475 {
8476 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
8477 return CMD_SUCCESS;
8478 }
8479
8480 DEFUN (no_debug_pim_packetdump_send,
8481 no_debug_pim_packetdump_send_cmd,
8482 "no debug pim packet-dump send",
8483 NO_STR
8484 DEBUG_STR
8485 DEBUG_PIM_STR
8486 DEBUG_PIM_PACKETDUMP_STR
8487 DEBUG_PIM_PACKETDUMP_SEND_STR)
8488 {
8489 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
8490 return CMD_SUCCESS;
8491 }
8492
8493 DEFUN (debug_pim_packetdump_recv,
8494 debug_pim_packetdump_recv_cmd,
8495 "debug pim packet-dump receive",
8496 DEBUG_STR
8497 DEBUG_PIM_STR
8498 DEBUG_PIM_PACKETDUMP_STR
8499 DEBUG_PIM_PACKETDUMP_RECV_STR)
8500 {
8501 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
8502 return CMD_SUCCESS;
8503 }
8504
8505 DEFUN (no_debug_pim_packetdump_recv,
8506 no_debug_pim_packetdump_recv_cmd,
8507 "no debug pim packet-dump receive",
8508 NO_STR
8509 DEBUG_STR
8510 DEBUG_PIM_STR
8511 DEBUG_PIM_PACKETDUMP_STR
8512 DEBUG_PIM_PACKETDUMP_RECV_STR)
8513 {
8514 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
8515 return CMD_SUCCESS;
8516 }
8517
8518 DEFUN (debug_pim_trace,
8519 debug_pim_trace_cmd,
8520 "debug pim trace",
8521 DEBUG_STR
8522 DEBUG_PIM_STR
8523 DEBUG_PIM_TRACE_STR)
8524 {
8525 PIM_DO_DEBUG_PIM_TRACE;
8526 return CMD_SUCCESS;
8527 }
8528
8529 DEFUN (debug_pim_trace_detail,
8530 debug_pim_trace_detail_cmd,
8531 "debug pim trace detail",
8532 DEBUG_STR
8533 DEBUG_PIM_STR
8534 DEBUG_PIM_TRACE_STR
8535 "Detailed Information\n")
8536 {
8537 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
8538 return CMD_SUCCESS;
8539 }
8540
8541 DEFUN (no_debug_pim_trace,
8542 no_debug_pim_trace_cmd,
8543 "no debug pim trace",
8544 NO_STR
8545 DEBUG_STR
8546 DEBUG_PIM_STR
8547 DEBUG_PIM_TRACE_STR)
8548 {
8549 PIM_DONT_DEBUG_PIM_TRACE;
8550 return CMD_SUCCESS;
8551 }
8552
8553 DEFUN (no_debug_pim_trace_detail,
8554 no_debug_pim_trace_detail_cmd,
8555 "no debug pim trace detail",
8556 NO_STR
8557 DEBUG_STR
8558 DEBUG_PIM_STR
8559 DEBUG_PIM_TRACE_STR
8560 "Detailed Information\n")
8561 {
8562 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
8563 return CMD_SUCCESS;
8564 }
8565
8566 DEFUN (debug_ssmpingd,
8567 debug_ssmpingd_cmd,
8568 "debug ssmpingd",
8569 DEBUG_STR
8570 DEBUG_SSMPINGD_STR)
8571 {
8572 PIM_DO_DEBUG_SSMPINGD;
8573 return CMD_SUCCESS;
8574 }
8575
8576 DEFUN (no_debug_ssmpingd,
8577 no_debug_ssmpingd_cmd,
8578 "no debug ssmpingd",
8579 NO_STR
8580 DEBUG_STR
8581 DEBUG_SSMPINGD_STR)
8582 {
8583 PIM_DONT_DEBUG_SSMPINGD;
8584 return CMD_SUCCESS;
8585 }
8586
8587 DEFUN (debug_pim_zebra,
8588 debug_pim_zebra_cmd,
8589 "debug pim zebra",
8590 DEBUG_STR
8591 DEBUG_PIM_STR
8592 DEBUG_PIM_ZEBRA_STR)
8593 {
8594 PIM_DO_DEBUG_ZEBRA;
8595 return CMD_SUCCESS;
8596 }
8597
8598 DEFUN (no_debug_pim_zebra,
8599 no_debug_pim_zebra_cmd,
8600 "no debug pim zebra",
8601 NO_STR
8602 DEBUG_STR
8603 DEBUG_PIM_STR
8604 DEBUG_PIM_ZEBRA_STR)
8605 {
8606 PIM_DONT_DEBUG_ZEBRA;
8607 return CMD_SUCCESS;
8608 }
8609
8610 DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
8611 DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8612 {
8613 PIM_DO_DEBUG_MLAG;
8614 return CMD_SUCCESS;
8615 }
8616
8617 DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
8618 NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
8619 {
8620 PIM_DONT_DEBUG_MLAG;
8621 return CMD_SUCCESS;
8622 }
8623
8624 DEFUN (debug_pim_vxlan,
8625 debug_pim_vxlan_cmd,
8626 "debug pim vxlan",
8627 DEBUG_STR
8628 DEBUG_PIM_STR
8629 DEBUG_PIM_VXLAN_STR)
8630 {
8631 PIM_DO_DEBUG_VXLAN;
8632 return CMD_SUCCESS;
8633 }
8634
8635 DEFUN (no_debug_pim_vxlan,
8636 no_debug_pim_vxlan_cmd,
8637 "no debug pim vxlan",
8638 NO_STR
8639 DEBUG_STR
8640 DEBUG_PIM_STR
8641 DEBUG_PIM_VXLAN_STR)
8642 {
8643 PIM_DONT_DEBUG_VXLAN;
8644 return CMD_SUCCESS;
8645 }
8646
8647 DEFUN (debug_msdp,
8648 debug_msdp_cmd,
8649 "debug msdp",
8650 DEBUG_STR
8651 DEBUG_MSDP_STR)
8652 {
8653 PIM_DO_DEBUG_MSDP_EVENTS;
8654 PIM_DO_DEBUG_MSDP_PACKETS;
8655 return CMD_SUCCESS;
8656 }
8657
8658 DEFUN (no_debug_msdp,
8659 no_debug_msdp_cmd,
8660 "no debug msdp",
8661 NO_STR
8662 DEBUG_STR
8663 DEBUG_MSDP_STR)
8664 {
8665 PIM_DONT_DEBUG_MSDP_EVENTS;
8666 PIM_DONT_DEBUG_MSDP_PACKETS;
8667 return CMD_SUCCESS;
8668 }
8669
8670 DEFUN (debug_msdp_events,
8671 debug_msdp_events_cmd,
8672 "debug msdp events",
8673 DEBUG_STR
8674 DEBUG_MSDP_STR
8675 DEBUG_MSDP_EVENTS_STR)
8676 {
8677 PIM_DO_DEBUG_MSDP_EVENTS;
8678 return CMD_SUCCESS;
8679 }
8680
8681 DEFUN (no_debug_msdp_events,
8682 no_debug_msdp_events_cmd,
8683 "no debug msdp events",
8684 NO_STR
8685 DEBUG_STR
8686 DEBUG_MSDP_STR
8687 DEBUG_MSDP_EVENTS_STR)
8688 {
8689 PIM_DONT_DEBUG_MSDP_EVENTS;
8690 return CMD_SUCCESS;
8691 }
8692
8693 DEFUN (debug_msdp_packets,
8694 debug_msdp_packets_cmd,
8695 "debug msdp packets",
8696 DEBUG_STR
8697 DEBUG_MSDP_STR
8698 DEBUG_MSDP_PACKETS_STR)
8699 {
8700 PIM_DO_DEBUG_MSDP_PACKETS;
8701 return CMD_SUCCESS;
8702 }
8703
8704 DEFUN (no_debug_msdp_packets,
8705 no_debug_msdp_packets_cmd,
8706 "no debug msdp packets",
8707 NO_STR
8708 DEBUG_STR
8709 DEBUG_MSDP_STR
8710 DEBUG_MSDP_PACKETS_STR)
8711 {
8712 PIM_DONT_DEBUG_MSDP_PACKETS;
8713 return CMD_SUCCESS;
8714 }
8715
8716 DEFUN (debug_mtrace,
8717 debug_mtrace_cmd,
8718 "debug mtrace",
8719 DEBUG_STR
8720 DEBUG_MTRACE_STR)
8721 {
8722 PIM_DO_DEBUG_MTRACE;
8723 return CMD_SUCCESS;
8724 }
8725
8726 DEFUN (no_debug_mtrace,
8727 no_debug_mtrace_cmd,
8728 "no debug mtrace",
8729 NO_STR
8730 DEBUG_STR
8731 DEBUG_MTRACE_STR)
8732 {
8733 PIM_DONT_DEBUG_MTRACE;
8734 return CMD_SUCCESS;
8735 }
8736
8737 DEFUN (debug_bsm,
8738 debug_bsm_cmd,
8739 "debug pim bsm",
8740 DEBUG_STR
8741 DEBUG_PIM_STR
8742 DEBUG_PIM_BSM_STR)
8743 {
8744 PIM_DO_DEBUG_BSM;
8745 return CMD_SUCCESS;
8746 }
8747
8748 DEFUN (no_debug_bsm,
8749 no_debug_bsm_cmd,
8750 "no debug pim bsm",
8751 NO_STR
8752 DEBUG_STR
8753 DEBUG_PIM_STR
8754 DEBUG_PIM_BSM_STR)
8755 {
8756 PIM_DONT_DEBUG_BSM;
8757 return CMD_SUCCESS;
8758 }
8759
8760
8761 DEFUN_NOSH (show_debugging_pim,
8762 show_debugging_pim_cmd,
8763 "show debugging [pim]",
8764 SHOW_STR
8765 DEBUG_STR
8766 PIM_STR)
8767 {
8768 vty_out(vty, "PIM debugging status\n");
8769
8770 pim_debug_config_write(vty);
8771
8772 return CMD_SUCCESS;
8773 }
8774
8775 static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
8776 {
8777 int result;
8778 struct in_addr source_addr;
8779 int ret = CMD_SUCCESS;
8780 VTY_DECLVAR_CONTEXT(interface, ifp);
8781
8782 result = inet_pton(AF_INET, source, &source_addr);
8783 if (result <= 0) {
8784 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
8785 errno, safe_strerror(errno));
8786 return CMD_WARNING_CONFIG_FAILED;
8787 }
8788
8789 result = pim_update_source_set(ifp, source_addr);
8790 switch (result) {
8791 case PIM_SUCCESS:
8792 break;
8793 case PIM_IFACE_NOT_FOUND:
8794 ret = CMD_WARNING_CONFIG_FAILED;
8795 vty_out(vty, "Pim not enabled on this interface\n");
8796 break;
8797 case PIM_UPDATE_SOURCE_DUP:
8798 ret = CMD_WARNING;
8799 vty_out(vty, "%% Source already set to %s\n", source);
8800 break;
8801 default:
8802 ret = CMD_WARNING_CONFIG_FAILED;
8803 vty_out(vty, "%% Source set failed\n");
8804 }
8805
8806 return ret;
8807 }
8808
8809 DEFUN (interface_pim_use_source,
8810 interface_pim_use_source_cmd,
8811 "ip pim use-source A.B.C.D",
8812 IP_STR
8813 PIM_STR
8814 "Configure primary IP address\n"
8815 "source ip address\n")
8816 {
8817 return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
8818 }
8819
8820 DEFUN (interface_no_pim_use_source,
8821 interface_no_pim_use_source_cmd,
8822 "no ip pim use-source [A.B.C.D]",
8823 NO_STR
8824 IP_STR
8825 PIM_STR
8826 "Delete source IP address\n"
8827 "source ip address\n")
8828 {
8829 return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
8830 }
8831
8832 DEFUN (ip_pim_bfd,
8833 ip_pim_bfd_cmd,
8834 "ip pim bfd",
8835 IP_STR
8836 PIM_STR
8837 "Enables BFD support\n")
8838 {
8839 VTY_DECLVAR_CONTEXT(interface, ifp);
8840 struct pim_interface *pim_ifp = ifp->info;
8841 struct bfd_info *bfd_info = NULL;
8842
8843 if (!pim_ifp) {
8844 if (!pim_cmd_interface_add(ifp)) {
8845 vty_out(vty, "Could not enable PIM SM on interface\n");
8846 return CMD_WARNING;
8847 }
8848 }
8849 pim_ifp = ifp->info;
8850
8851 bfd_info = pim_ifp->bfd_info;
8852
8853 if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
8854 pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
8855 BFD_DEF_DETECT_MULT, 1);
8856
8857 return CMD_SUCCESS;
8858 }
8859
8860 DEFUN (no_ip_pim_bfd,
8861 no_ip_pim_bfd_cmd,
8862 "no ip pim bfd",
8863 NO_STR
8864 IP_STR
8865 PIM_STR
8866 "Disables BFD support\n")
8867 {
8868 VTY_DECLVAR_CONTEXT(interface, ifp);
8869 struct pim_interface *pim_ifp = ifp->info;
8870
8871 if (!pim_ifp) {
8872 vty_out(vty, "Pim not enabled on this interface\n");
8873 return CMD_WARNING;
8874 }
8875
8876 if (pim_ifp->bfd_info) {
8877 pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
8878 bfd_info_free(&(pim_ifp->bfd_info));
8879 }
8880
8881 return CMD_SUCCESS;
8882 }
8883
8884 DEFUN (ip_pim_bsm,
8885 ip_pim_bsm_cmd,
8886 "ip pim bsm",
8887 IP_STR
8888 PIM_STR
8889 "Enables BSM support on the interface\n")
8890 {
8891 VTY_DECLVAR_CONTEXT(interface, ifp);
8892 struct pim_interface *pim_ifp = ifp->info;
8893
8894 if (!pim_ifp) {
8895 if (!pim_cmd_interface_add(ifp)) {
8896 vty_out(vty, "Could not enable PIM SM on interface\n");
8897 return CMD_WARNING;
8898 }
8899 }
8900
8901 pim_ifp = ifp->info;
8902 pim_ifp->bsm_enable = true;
8903
8904 return CMD_SUCCESS;
8905 }
8906
8907 DEFUN (no_ip_pim_bsm,
8908 no_ip_pim_bsm_cmd,
8909 "no ip pim bsm",
8910 NO_STR
8911 IP_STR
8912 PIM_STR
8913 "Disables BSM support\n")
8914 {
8915 VTY_DECLVAR_CONTEXT(interface, ifp);
8916 struct pim_interface *pim_ifp = ifp->info;
8917
8918 if (!pim_ifp) {
8919 vty_out(vty, "Pim not enabled on this interface\n");
8920 return CMD_WARNING;
8921 }
8922
8923 pim_ifp->bsm_enable = false;
8924
8925 return CMD_SUCCESS;
8926 }
8927
8928 DEFUN (ip_pim_ucast_bsm,
8929 ip_pim_ucast_bsm_cmd,
8930 "ip pim unicast-bsm",
8931 IP_STR
8932 PIM_STR
8933 "Accept/Send unicast BSM on the interface\n")
8934 {
8935 VTY_DECLVAR_CONTEXT(interface, ifp);
8936 struct pim_interface *pim_ifp = ifp->info;
8937
8938 if (!pim_ifp) {
8939 if (!pim_cmd_interface_add(ifp)) {
8940 vty_out(vty, "Could not enable PIM SM on interface\n");
8941 return CMD_WARNING;
8942 }
8943 }
8944
8945 pim_ifp = ifp->info;
8946 pim_ifp->ucast_bsm_accept = true;
8947
8948 return CMD_SUCCESS;
8949 }
8950
8951 DEFUN (no_ip_pim_ucast_bsm,
8952 no_ip_pim_ucast_bsm_cmd,
8953 "no ip pim unicast-bsm",
8954 NO_STR
8955 IP_STR
8956 PIM_STR
8957 "Block send/receive unicast BSM on this interface\n")
8958 {
8959 VTY_DECLVAR_CONTEXT(interface, ifp);
8960 struct pim_interface *pim_ifp = ifp->info;
8961
8962 if (!pim_ifp) {
8963 vty_out(vty, "Pim not enabled on this interface\n");
8964 return CMD_WARNING;
8965 }
8966
8967 pim_ifp->ucast_bsm_accept = false;
8968
8969 return CMD_SUCCESS;
8970 }
8971
8972 #if HAVE_BFDD > 0
8973 DEFUN_HIDDEN(
8974 ip_pim_bfd_param,
8975 ip_pim_bfd_param_cmd,
8976 "ip pim bfd (2-255) (50-60000) (50-60000)",
8977 IP_STR
8978 PIM_STR
8979 "Enables BFD support\n"
8980 "Detect Multiplier\n"
8981 "Required min receive interval\n"
8982 "Desired min transmit interval\n")
8983 #else
8984 DEFUN(
8985 ip_pim_bfd_param,
8986 ip_pim_bfd_param_cmd,
8987 "ip pim bfd (2-255) (50-60000) (50-60000)",
8988 IP_STR
8989 PIM_STR
8990 "Enables BFD support\n"
8991 "Detect Multiplier\n"
8992 "Required min receive interval\n"
8993 "Desired min transmit interval\n")
8994 #endif /* HAVE_BFDD */
8995 {
8996 VTY_DECLVAR_CONTEXT(interface, ifp);
8997 int idx_number = 3;
8998 int idx_number_2 = 4;
8999 int idx_number_3 = 5;
9000 uint32_t rx_val;
9001 uint32_t tx_val;
9002 uint8_t dm_val;
9003 int ret;
9004 struct pim_interface *pim_ifp = ifp->info;
9005
9006 if (!pim_ifp) {
9007 if (!pim_cmd_interface_add(ifp)) {
9008 vty_out(vty, "Could not enable PIM SM on interface\n");
9009 return CMD_WARNING;
9010 }
9011 }
9012
9013 if ((ret = bfd_validate_param(
9014 vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
9015 argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
9016 != CMD_SUCCESS)
9017 return ret;
9018
9019 pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
9020
9021 return CMD_SUCCESS;
9022 }
9023
9024 #if HAVE_BFDD == 0
9025 ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
9026 "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
9027 "Enables BFD support\n"
9028 "Detect Multiplier\n"
9029 "Required min receive interval\n"
9030 "Desired min transmit interval\n")
9031 #endif /* !HAVE_BFDD */
9032
9033 static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
9034 const char *peer, const char *local)
9035 {
9036 enum pim_msdp_err result;
9037 struct in_addr peer_addr;
9038 struct in_addr local_addr;
9039 int ret = CMD_SUCCESS;
9040
9041 result = inet_pton(AF_INET, peer, &peer_addr);
9042 if (result <= 0) {
9043 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
9044 errno, safe_strerror(errno));
9045 return CMD_WARNING_CONFIG_FAILED;
9046 }
9047
9048 result = inet_pton(AF_INET, local, &local_addr);
9049 if (result <= 0) {
9050 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
9051 errno, safe_strerror(errno));
9052 return CMD_WARNING_CONFIG_FAILED;
9053 }
9054
9055 result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
9056 NULL /* mp_p */);
9057 switch (result) {
9058 case PIM_MSDP_ERR_NONE:
9059 break;
9060 case PIM_MSDP_ERR_OOM:
9061 ret = CMD_WARNING_CONFIG_FAILED;
9062 vty_out(vty, "%% Out of memory\n");
9063 break;
9064 case PIM_MSDP_ERR_PEER_EXISTS:
9065 ret = CMD_WARNING;
9066 vty_out(vty, "%% Peer exists\n");
9067 break;
9068 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9069 ret = CMD_WARNING_CONFIG_FAILED;
9070 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9071 break;
9072 default:
9073 ret = CMD_WARNING_CONFIG_FAILED;
9074 vty_out(vty, "%% peer add failed\n");
9075 }
9076
9077 return ret;
9078 }
9079
9080 DEFUN_HIDDEN (ip_msdp_peer,
9081 ip_msdp_peer_cmd,
9082 "ip msdp peer A.B.C.D source A.B.C.D",
9083 IP_STR
9084 CFG_MSDP_STR
9085 "Configure MSDP peer\n"
9086 "peer ip address\n"
9087 "Source address for TCP connection\n"
9088 "local ip address\n")
9089 {
9090 PIM_DECLVAR_CONTEXT(vrf, pim);
9091 return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg);
9092 }
9093
9094 static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
9095 const char *peer)
9096 {
9097 enum pim_msdp_err result;
9098 struct in_addr peer_addr;
9099
9100 result = inet_pton(AF_INET, peer, &peer_addr);
9101 if (result <= 0) {
9102 vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
9103 errno, safe_strerror(errno));
9104 return CMD_WARNING_CONFIG_FAILED;
9105 }
9106
9107 result = pim_msdp_peer_del(pim, peer_addr);
9108 switch (result) {
9109 case PIM_MSDP_ERR_NONE:
9110 break;
9111 case PIM_MSDP_ERR_NO_PEER:
9112 vty_out(vty, "%% Peer does not exist\n");
9113 break;
9114 default:
9115 vty_out(vty, "%% peer del failed\n");
9116 }
9117
9118 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9119 }
9120
9121 DEFUN_HIDDEN (no_ip_msdp_peer,
9122 no_ip_msdp_peer_cmd,
9123 "no ip msdp peer A.B.C.D",
9124 NO_STR
9125 IP_STR
9126 CFG_MSDP_STR
9127 "Delete MSDP peer\n"
9128 "peer ip address\n")
9129 {
9130 PIM_DECLVAR_CONTEXT(vrf, pim);
9131 return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg);
9132 }
9133
9134 static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9135 struct vty *vty, const char *mg,
9136 const char *mbr)
9137 {
9138 enum pim_msdp_err result;
9139 struct in_addr mbr_ip;
9140 int ret = CMD_SUCCESS;
9141
9142 result = inet_pton(AF_INET, mbr, &mbr_ip);
9143 if (result <= 0) {
9144 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9145 errno, safe_strerror(errno));
9146 return CMD_WARNING_CONFIG_FAILED;
9147 }
9148
9149 result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
9150 switch (result) {
9151 case PIM_MSDP_ERR_NONE:
9152 break;
9153 case PIM_MSDP_ERR_OOM:
9154 ret = CMD_WARNING_CONFIG_FAILED;
9155 vty_out(vty, "%% Out of memory\n");
9156 break;
9157 case PIM_MSDP_ERR_MG_MBR_EXISTS:
9158 ret = CMD_WARNING;
9159 vty_out(vty, "%% mesh-group member exists\n");
9160 break;
9161 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9162 ret = CMD_WARNING_CONFIG_FAILED;
9163 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9164 break;
9165 default:
9166 ret = CMD_WARNING_CONFIG_FAILED;
9167 vty_out(vty, "%% member add failed\n");
9168 }
9169
9170 return ret;
9171 }
9172
9173 DEFUN (ip_msdp_mesh_group_member,
9174 ip_msdp_mesh_group_member_cmd,
9175 "ip msdp mesh-group WORD member A.B.C.D",
9176 IP_STR
9177 CFG_MSDP_STR
9178 "Configure MSDP mesh-group\n"
9179 "mesh group name\n"
9180 "mesh group member\n"
9181 "peer ip address\n")
9182 {
9183 PIM_DECLVAR_CONTEXT(vrf, pim);
9184 return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg,
9185 argv[5]->arg);
9186 }
9187
9188 static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
9189 struct vty *vty,
9190 const char *mg,
9191 const char *mbr)
9192 {
9193 enum pim_msdp_err result;
9194 struct in_addr mbr_ip;
9195
9196 result = inet_pton(AF_INET, mbr, &mbr_ip);
9197 if (result <= 0) {
9198 vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
9199 errno, safe_strerror(errno));
9200 return CMD_WARNING_CONFIG_FAILED;
9201 }
9202
9203 result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
9204 switch (result) {
9205 case PIM_MSDP_ERR_NONE:
9206 break;
9207 case PIM_MSDP_ERR_NO_MG:
9208 vty_out(vty, "%% mesh-group does not exist\n");
9209 break;
9210 case PIM_MSDP_ERR_NO_MG_MBR:
9211 vty_out(vty, "%% mesh-group member does not exist\n");
9212 break;
9213 default:
9214 vty_out(vty, "%% mesh-group member del failed\n");
9215 }
9216
9217 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9218 }
9219 DEFUN (no_ip_msdp_mesh_group_member,
9220 no_ip_msdp_mesh_group_member_cmd,
9221 "no ip msdp mesh-group WORD member A.B.C.D",
9222 NO_STR
9223 IP_STR
9224 CFG_MSDP_STR
9225 "Delete MSDP mesh-group member\n"
9226 "mesh group name\n"
9227 "mesh group member\n"
9228 "peer ip address\n")
9229 {
9230 PIM_DECLVAR_CONTEXT(vrf, pim);
9231 return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg,
9232 argv[6]->arg);
9233 }
9234
9235 static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9236 struct vty *vty, const char *mg,
9237 const char *src)
9238 {
9239 enum pim_msdp_err result;
9240 struct in_addr src_ip;
9241
9242 result = inet_pton(AF_INET, src, &src_ip);
9243 if (result <= 0) {
9244 vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
9245 errno, safe_strerror(errno));
9246 return CMD_WARNING_CONFIG_FAILED;
9247 }
9248
9249 result = pim_msdp_mg_src_add(pim, mg, src_ip);
9250 switch (result) {
9251 case PIM_MSDP_ERR_NONE:
9252 break;
9253 case PIM_MSDP_ERR_OOM:
9254 vty_out(vty, "%% Out of memory\n");
9255 break;
9256 case PIM_MSDP_ERR_MAX_MESH_GROUPS:
9257 vty_out(vty, "%% Only one mesh-group allowed currently\n");
9258 break;
9259 default:
9260 vty_out(vty, "%% source add failed\n");
9261 }
9262
9263 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9264 }
9265
9266
9267 DEFUN (ip_msdp_mesh_group_source,
9268 ip_msdp_mesh_group_source_cmd,
9269 "ip msdp mesh-group WORD source A.B.C.D",
9270 IP_STR
9271 CFG_MSDP_STR
9272 "Configure MSDP mesh-group\n"
9273 "mesh group name\n"
9274 "mesh group local address\n"
9275 "source ip address for the TCP connection\n")
9276 {
9277 PIM_DECLVAR_CONTEXT(vrf, pim);
9278 return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg,
9279 argv[5]->arg);
9280 }
9281
9282 static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
9283 struct vty *vty,
9284 const char *mg)
9285 {
9286 enum pim_msdp_err result;
9287
9288 result = pim_msdp_mg_src_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 static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
9303 struct vty *vty, const char *mg)
9304 {
9305 enum pim_msdp_err result;
9306
9307 result = pim_msdp_mg_del(pim, mg);
9308 switch (result) {
9309 case PIM_MSDP_ERR_NONE:
9310 break;
9311 case PIM_MSDP_ERR_NO_MG:
9312 vty_out(vty, "%% mesh-group does not exist\n");
9313 break;
9314 default:
9315 vty_out(vty, "%% mesh-group source del failed\n");
9316 }
9317
9318 return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
9319 }
9320
9321 DEFUN (no_ip_msdp_mesh_group_source,
9322 no_ip_msdp_mesh_group_source_cmd,
9323 "no ip msdp mesh-group WORD source [A.B.C.D]",
9324 NO_STR
9325 IP_STR
9326 CFG_MSDP_STR
9327 "Delete MSDP mesh-group source\n"
9328 "mesh group name\n"
9329 "mesh group source\n"
9330 "mesh group local address\n")
9331 {
9332 PIM_DECLVAR_CONTEXT(vrf, pim);
9333 if (argc == 7)
9334 return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[6]->arg);
9335 else
9336 return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty,
9337 argv[4]->arg);
9338 }
9339
9340 static void print_empty_json_obj(struct vty *vty)
9341 {
9342 json_object *json;
9343 json = json_object_new_object();
9344 vty_out(vty, "%s\n",
9345 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
9346 json_object_free(json);
9347 }
9348
9349 static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
9350 bool uj)
9351 {
9352 struct listnode *mbrnode;
9353 struct pim_msdp_mg_mbr *mbr;
9354 struct pim_msdp_mg *mg = pim->msdp.mg;
9355 char mbr_str[INET_ADDRSTRLEN];
9356 char src_str[INET_ADDRSTRLEN];
9357 char state_str[PIM_MSDP_STATE_STRLEN];
9358 enum pim_msdp_peer_state state;
9359 json_object *json = NULL;
9360 json_object *json_mg_row = NULL;
9361 json_object *json_members = NULL;
9362 json_object *json_row = NULL;
9363
9364 if (!mg) {
9365 if (uj)
9366 print_empty_json_obj(vty);
9367 return;
9368 }
9369
9370 pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
9371 if (uj) {
9372 json = json_object_new_object();
9373 /* currently there is only one mesh group but we should still
9374 * make
9375 * it a dict with mg-name as key */
9376 json_mg_row = json_object_new_object();
9377 json_object_string_add(json_mg_row, "name",
9378 mg->mesh_group_name);
9379 json_object_string_add(json_mg_row, "source", src_str);
9380 } else {
9381 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
9382 vty_out(vty, " Source : %s\n", src_str);
9383 vty_out(vty, " Member State\n");
9384 }
9385
9386 for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
9387 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
9388 if (mbr->mp) {
9389 state = mbr->mp->state;
9390 } else {
9391 state = PIM_MSDP_DISABLED;
9392 }
9393 pim_msdp_state_dump(state, state_str, sizeof(state_str));
9394 if (uj) {
9395 json_row = json_object_new_object();
9396 json_object_string_add(json_row, "member", mbr_str);
9397 json_object_string_add(json_row, "state", state_str);
9398 if (!json_members) {
9399 json_members = json_object_new_object();
9400 json_object_object_add(json_mg_row, "members",
9401 json_members);
9402 }
9403 json_object_object_add(json_members, mbr_str, json_row);
9404 } else {
9405 vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
9406 }
9407 }
9408
9409 if (uj) {
9410 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
9411 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9412 json, JSON_C_TO_STRING_PRETTY));
9413 json_object_free(json);
9414 }
9415 }
9416
9417 DEFUN (show_ip_msdp_mesh_group,
9418 show_ip_msdp_mesh_group_cmd,
9419 "show ip msdp [vrf NAME] mesh-group [json]",
9420 SHOW_STR
9421 IP_STR
9422 MSDP_STR
9423 VRF_CMD_HELP_STR
9424 "MSDP mesh-group information\n"
9425 JSON_STR)
9426 {
9427 bool uj = use_json(argc, argv);
9428 int idx = 2;
9429 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9430
9431 if (!vrf)
9432 return CMD_WARNING;
9433
9434 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9435
9436 return CMD_SUCCESS;
9437 }
9438
9439 DEFUN (show_ip_msdp_mesh_group_vrf_all,
9440 show_ip_msdp_mesh_group_vrf_all_cmd,
9441 "show ip msdp vrf all mesh-group [json]",
9442 SHOW_STR
9443 IP_STR
9444 MSDP_STR
9445 VRF_CMD_HELP_STR
9446 "MSDP mesh-group information\n"
9447 JSON_STR)
9448 {
9449 bool uj = use_json(argc, argv);
9450 struct vrf *vrf;
9451 bool first = true;
9452
9453 if (uj)
9454 vty_out(vty, "{ ");
9455 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9456 if (uj) {
9457 if (!first)
9458 vty_out(vty, ", ");
9459 vty_out(vty, " \"%s\": ", vrf->name);
9460 first = false;
9461 } else
9462 vty_out(vty, "VRF: %s\n", vrf->name);
9463 ip_msdp_show_mesh_group(vrf->info, vty, uj);
9464 }
9465 if (uj)
9466 vty_out(vty, "}\n");
9467
9468 return CMD_SUCCESS;
9469 }
9470
9471 static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
9472 bool uj)
9473 {
9474 struct listnode *mpnode;
9475 struct pim_msdp_peer *mp;
9476 char peer_str[INET_ADDRSTRLEN];
9477 char local_str[INET_ADDRSTRLEN];
9478 char state_str[PIM_MSDP_STATE_STRLEN];
9479 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9480 int64_t now;
9481 json_object *json = NULL;
9482 json_object *json_row = NULL;
9483
9484
9485 if (uj) {
9486 json = json_object_new_object();
9487 } else {
9488 vty_out(vty,
9489 "Peer Local State Uptime SaCnt\n");
9490 }
9491
9492 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
9493 if (mp->state == PIM_MSDP_ESTABLISHED) {
9494 now = pim_time_monotonic_sec();
9495 pim_time_uptime(timebuf, sizeof(timebuf),
9496 now - mp->uptime);
9497 } else {
9498 strlcpy(timebuf, "-", sizeof(timebuf));
9499 }
9500 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9501 pim_inet4_dump("<local?>", mp->local, local_str,
9502 sizeof(local_str));
9503 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9504 if (uj) {
9505 json_row = json_object_new_object();
9506 json_object_string_add(json_row, "peer", peer_str);
9507 json_object_string_add(json_row, "local", local_str);
9508 json_object_string_add(json_row, "state", state_str);
9509 json_object_string_add(json_row, "upTime", timebuf);
9510 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9511 json_object_object_add(json, peer_str, json_row);
9512 } else {
9513 vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
9514 local_str, state_str, timebuf, mp->sa_cnt);
9515 }
9516 }
9517
9518 if (uj) {
9519 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9520 json, JSON_C_TO_STRING_PRETTY));
9521 json_object_free(json);
9522 }
9523 }
9524
9525 static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
9526 const char *peer, bool uj)
9527 {
9528 struct listnode *mpnode;
9529 struct pim_msdp_peer *mp;
9530 char peer_str[INET_ADDRSTRLEN];
9531 char local_str[INET_ADDRSTRLEN];
9532 char state_str[PIM_MSDP_STATE_STRLEN];
9533 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9534 char katimer[PIM_MSDP_TIMER_STRLEN];
9535 char crtimer[PIM_MSDP_TIMER_STRLEN];
9536 char holdtimer[PIM_MSDP_TIMER_STRLEN];
9537 int64_t now;
9538 json_object *json = NULL;
9539 json_object *json_row = NULL;
9540
9541 if (uj) {
9542 json = json_object_new_object();
9543 }
9544
9545 for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
9546 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
9547 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
9548 continue;
9549
9550 if (mp->state == PIM_MSDP_ESTABLISHED) {
9551 now = pim_time_monotonic_sec();
9552 pim_time_uptime(timebuf, sizeof(timebuf),
9553 now - mp->uptime);
9554 } else {
9555 strlcpy(timebuf, "-", sizeof(timebuf));
9556 }
9557 pim_inet4_dump("<local?>", mp->local, local_str,
9558 sizeof(local_str));
9559 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
9560 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
9561 mp->ka_timer);
9562 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
9563 mp->cr_timer);
9564 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
9565 mp->hold_timer);
9566
9567 if (uj) {
9568 json_row = json_object_new_object();
9569 json_object_string_add(json_row, "peer", peer_str);
9570 json_object_string_add(json_row, "local", local_str);
9571 json_object_string_add(json_row, "meshGroupName",
9572 mp->mesh_group_name);
9573 json_object_string_add(json_row, "state", state_str);
9574 json_object_string_add(json_row, "upTime", timebuf);
9575 json_object_string_add(json_row, "keepAliveTimer",
9576 katimer);
9577 json_object_string_add(json_row, "connRetryTimer",
9578 crtimer);
9579 json_object_string_add(json_row, "holdTimer",
9580 holdtimer);
9581 json_object_string_add(json_row, "lastReset",
9582 mp->last_reset);
9583 json_object_int_add(json_row, "connAttempts",
9584 mp->conn_attempts);
9585 json_object_int_add(json_row, "establishedChanges",
9586 mp->est_flaps);
9587 json_object_int_add(json_row, "saCount", mp->sa_cnt);
9588 json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
9589 json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
9590 json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
9591 json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
9592 json_object_object_add(json, peer_str, json_row);
9593 } else {
9594 vty_out(vty, "Peer : %s\n", peer_str);
9595 vty_out(vty, " Local : %s\n", local_str);
9596 vty_out(vty, " Mesh Group : %s\n",
9597 mp->mesh_group_name);
9598 vty_out(vty, " State : %s\n", state_str);
9599 vty_out(vty, " Uptime : %s\n", timebuf);
9600
9601 vty_out(vty, " Keepalive Timer : %s\n", katimer);
9602 vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
9603 vty_out(vty, " Hold Timer : %s\n", holdtimer);
9604 vty_out(vty, " Last Reset : %s\n",
9605 mp->last_reset);
9606 vty_out(vty, " Conn Attempts : %d\n",
9607 mp->conn_attempts);
9608 vty_out(vty, " Established Changes : %d\n",
9609 mp->est_flaps);
9610 vty_out(vty, " SA Count : %d\n",
9611 mp->sa_cnt);
9612 vty_out(vty, " Statistics :\n");
9613 vty_out(vty,
9614 " Sent Rcvd\n");
9615 vty_out(vty, " Keepalives : %10d %10d\n",
9616 mp->ka_tx_cnt, mp->ka_rx_cnt);
9617 vty_out(vty, " SAs : %10d %10d\n",
9618 mp->sa_tx_cnt, mp->sa_rx_cnt);
9619 vty_out(vty, "\n");
9620 }
9621 }
9622
9623 if (uj) {
9624 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9625 json, JSON_C_TO_STRING_PRETTY));
9626 json_object_free(json);
9627 }
9628 }
9629
9630 DEFUN (show_ip_msdp_peer_detail,
9631 show_ip_msdp_peer_detail_cmd,
9632 "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
9633 SHOW_STR
9634 IP_STR
9635 MSDP_STR
9636 VRF_CMD_HELP_STR
9637 "MSDP peer information\n"
9638 "Detailed output\n"
9639 "peer ip address\n"
9640 JSON_STR)
9641 {
9642 bool uj = use_json(argc, argv);
9643 int idx = 2;
9644 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9645
9646 if (!vrf)
9647 return CMD_WARNING;
9648
9649 char *arg = NULL;
9650
9651 if (argv_find(argv, argc, "detail", &idx))
9652 arg = argv[idx]->text;
9653 else if (argv_find(argv, argc, "A.B.C.D", &idx))
9654 arg = argv[idx]->arg;
9655
9656 if (arg)
9657 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
9658 else
9659 ip_msdp_show_peers(vrf->info, vty, uj);
9660
9661 return CMD_SUCCESS;
9662 }
9663
9664 DEFUN (show_ip_msdp_peer_detail_vrf_all,
9665 show_ip_msdp_peer_detail_vrf_all_cmd,
9666 "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
9667 SHOW_STR
9668 IP_STR
9669 MSDP_STR
9670 VRF_CMD_HELP_STR
9671 "MSDP peer information\n"
9672 "Detailed output\n"
9673 "peer ip address\n"
9674 JSON_STR)
9675 {
9676 int idx = 2;
9677 bool uj = use_json(argc, argv);
9678 struct vrf *vrf;
9679 bool first = true;
9680
9681 if (uj)
9682 vty_out(vty, "{ ");
9683 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9684 if (uj) {
9685 if (!first)
9686 vty_out(vty, ", ");
9687 vty_out(vty, " \"%s\": ", vrf->name);
9688 first = false;
9689 } else
9690 vty_out(vty, "VRF: %s\n", vrf->name);
9691 if (argv_find(argv, argc, "detail", &idx)
9692 || argv_find(argv, argc, "A.B.C.D", &idx))
9693 ip_msdp_show_peers_detail(vrf->info, vty,
9694 argv[idx]->arg, uj);
9695 else
9696 ip_msdp_show_peers(vrf->info, vty, uj);
9697 }
9698 if (uj)
9699 vty_out(vty, "}\n");
9700
9701 return CMD_SUCCESS;
9702 }
9703
9704 static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
9705 {
9706 struct listnode *sanode;
9707 struct pim_msdp_sa *sa;
9708 char src_str[INET_ADDRSTRLEN];
9709 char grp_str[INET_ADDRSTRLEN];
9710 char rp_str[INET_ADDRSTRLEN];
9711 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9712 char spt_str[8];
9713 char local_str[8];
9714 int64_t now;
9715 json_object *json = NULL;
9716 json_object *json_group = NULL;
9717 json_object *json_row = NULL;
9718
9719 if (uj) {
9720 json = json_object_new_object();
9721 } else {
9722 vty_out(vty,
9723 "Source Group RP Local SPT Uptime\n");
9724 }
9725
9726 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9727 now = pim_time_monotonic_sec();
9728 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9729 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9730 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9731 if (sa->flags & PIM_MSDP_SAF_PEER) {
9732 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9733 if (sa->up) {
9734 strlcpy(spt_str, "yes", sizeof(spt_str));
9735 } else {
9736 strlcpy(spt_str, "no", sizeof(spt_str));
9737 }
9738 } else {
9739 strlcpy(rp_str, "-", sizeof(rp_str));
9740 strlcpy(spt_str, "-", sizeof(spt_str));
9741 }
9742 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
9743 strlcpy(local_str, "yes", sizeof(local_str));
9744 } else {
9745 strlcpy(local_str, "no", sizeof(local_str));
9746 }
9747 if (uj) {
9748 json_object_object_get_ex(json, grp_str, &json_group);
9749
9750 if (!json_group) {
9751 json_group = json_object_new_object();
9752 json_object_object_add(json, grp_str,
9753 json_group);
9754 }
9755
9756 json_row = json_object_new_object();
9757 json_object_string_add(json_row, "source", src_str);
9758 json_object_string_add(json_row, "group", grp_str);
9759 json_object_string_add(json_row, "rp", rp_str);
9760 json_object_string_add(json_row, "local", local_str);
9761 json_object_string_add(json_row, "sptSetup", spt_str);
9762 json_object_string_add(json_row, "upTime", timebuf);
9763 json_object_object_add(json_group, src_str, json_row);
9764 } else {
9765 vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
9766 src_str, grp_str, rp_str, local_str[0],
9767 spt_str[0], timebuf);
9768 }
9769 }
9770
9771 if (uj) {
9772 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9773 json, JSON_C_TO_STRING_PRETTY));
9774 json_object_free(json);
9775 }
9776 }
9777
9778 static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
9779 const char *src_str,
9780 const char *grp_str, struct vty *vty,
9781 bool uj, json_object *json)
9782 {
9783 char rp_str[INET_ADDRSTRLEN];
9784 char peer_str[INET_ADDRSTRLEN];
9785 char timebuf[PIM_MSDP_UPTIME_STRLEN];
9786 char spt_str[8];
9787 char local_str[8];
9788 char statetimer[PIM_MSDP_TIMER_STRLEN];
9789 int64_t now;
9790 json_object *json_group = NULL;
9791 json_object *json_row = NULL;
9792
9793 now = pim_time_monotonic_sec();
9794 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
9795 if (sa->flags & PIM_MSDP_SAF_PEER) {
9796 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
9797 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
9798 if (sa->up) {
9799 strlcpy(spt_str, "yes", sizeof(spt_str));
9800 } else {
9801 strlcpy(spt_str, "no", sizeof(spt_str));
9802 }
9803 } else {
9804 strlcpy(rp_str, "-", sizeof(rp_str));
9805 strlcpy(peer_str, "-", sizeof(peer_str));
9806 strlcpy(spt_str, "-", sizeof(spt_str));
9807 }
9808 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
9809 strlcpy(local_str, "yes", sizeof(local_str));
9810 } else {
9811 strlcpy(local_str, "no", sizeof(local_str));
9812 }
9813 pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
9814 sa->sa_state_timer);
9815 if (uj) {
9816 json_object_object_get_ex(json, grp_str, &json_group);
9817
9818 if (!json_group) {
9819 json_group = json_object_new_object();
9820 json_object_object_add(json, grp_str, json_group);
9821 }
9822
9823 json_row = json_object_new_object();
9824 json_object_string_add(json_row, "source", src_str);
9825 json_object_string_add(json_row, "group", grp_str);
9826 json_object_string_add(json_row, "rp", rp_str);
9827 json_object_string_add(json_row, "local", local_str);
9828 json_object_string_add(json_row, "sptSetup", spt_str);
9829 json_object_string_add(json_row, "upTime", timebuf);
9830 json_object_string_add(json_row, "stateTimer", statetimer);
9831 json_object_object_add(json_group, src_str, json_row);
9832 } else {
9833 vty_out(vty, "SA : %s\n", sa->sg_str);
9834 vty_out(vty, " RP : %s\n", rp_str);
9835 vty_out(vty, " Peer : %s\n", peer_str);
9836 vty_out(vty, " Local : %s\n", local_str);
9837 vty_out(vty, " SPT Setup : %s\n", spt_str);
9838 vty_out(vty, " Uptime : %s\n", timebuf);
9839 vty_out(vty, " State Timer : %s\n", statetimer);
9840 vty_out(vty, "\n");
9841 }
9842 }
9843
9844 static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
9845 bool uj)
9846 {
9847 struct listnode *sanode;
9848 struct pim_msdp_sa *sa;
9849 char src_str[INET_ADDRSTRLEN];
9850 char grp_str[INET_ADDRSTRLEN];
9851 json_object *json = NULL;
9852
9853 if (uj) {
9854 json = json_object_new_object();
9855 }
9856
9857 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9858 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9859 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9860 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
9861 json);
9862 }
9863
9864 if (uj) {
9865 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9866 json, JSON_C_TO_STRING_PRETTY));
9867 json_object_free(json);
9868 }
9869 }
9870
9871 DEFUN (show_ip_msdp_sa_detail,
9872 show_ip_msdp_sa_detail_cmd,
9873 "show ip msdp [vrf NAME] sa detail [json]",
9874 SHOW_STR
9875 IP_STR
9876 MSDP_STR
9877 VRF_CMD_HELP_STR
9878 "MSDP active-source information\n"
9879 "Detailed output\n"
9880 JSON_STR)
9881 {
9882 bool uj = use_json(argc, argv);
9883 int idx = 2;
9884 struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
9885
9886 if (!vrf)
9887 return CMD_WARNING;
9888
9889 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9890
9891 return CMD_SUCCESS;
9892 }
9893
9894 DEFUN (show_ip_msdp_sa_detail_vrf_all,
9895 show_ip_msdp_sa_detail_vrf_all_cmd,
9896 "show ip msdp vrf all sa detail [json]",
9897 SHOW_STR
9898 IP_STR
9899 MSDP_STR
9900 VRF_CMD_HELP_STR
9901 "MSDP active-source information\n"
9902 "Detailed output\n"
9903 JSON_STR)
9904 {
9905 bool uj = use_json(argc, argv);
9906 struct vrf *vrf;
9907 bool first = true;
9908
9909 if (uj)
9910 vty_out(vty, "{ ");
9911 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
9912 if (uj) {
9913 if (!first)
9914 vty_out(vty, ", ");
9915 vty_out(vty, " \"%s\": ", vrf->name);
9916 first = false;
9917 } else
9918 vty_out(vty, "VRF: %s\n", vrf->name);
9919 ip_msdp_show_sa_detail(vrf->info, vty, uj);
9920 }
9921 if (uj)
9922 vty_out(vty, "}\n");
9923
9924 return CMD_SUCCESS;
9925 }
9926
9927 static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
9928 const char *addr, bool uj)
9929 {
9930 struct listnode *sanode;
9931 struct pim_msdp_sa *sa;
9932 char src_str[INET_ADDRSTRLEN];
9933 char grp_str[INET_ADDRSTRLEN];
9934 json_object *json = NULL;
9935
9936 if (uj) {
9937 json = json_object_new_object();
9938 }
9939
9940 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9941 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9942 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9943 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
9944 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9945 uj, json);
9946 }
9947 }
9948
9949 if (uj) {
9950 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9951 json, JSON_C_TO_STRING_PRETTY));
9952 json_object_free(json);
9953 }
9954 }
9955
9956 static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
9957 const char *src, const char *grp, bool uj)
9958 {
9959 struct listnode *sanode;
9960 struct pim_msdp_sa *sa;
9961 char src_str[INET_ADDRSTRLEN];
9962 char grp_str[INET_ADDRSTRLEN];
9963 json_object *json = NULL;
9964
9965 if (uj) {
9966 json = json_object_new_object();
9967 }
9968
9969 for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
9970 pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
9971 pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
9972 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
9973 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
9974 uj, json);
9975 }
9976 }
9977
9978 if (uj) {
9979 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9980 json, JSON_C_TO_STRING_PRETTY));
9981 json_object_free(json);
9982 }
9983 }
9984
9985 DEFUN (show_ip_msdp_sa_sg,
9986 show_ip_msdp_sa_sg_cmd,
9987 "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
9988 SHOW_STR
9989 IP_STR
9990 MSDP_STR
9991 VRF_CMD_HELP_STR
9992 "MSDP active-source information\n"
9993 "source or group ip\n"
9994 "group ip\n"
9995 JSON_STR)
9996 {
9997 bool uj = use_json(argc, argv);
9998 struct vrf *vrf;
9999 int idx = 2;
10000
10001 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10002
10003 if (!vrf)
10004 return CMD_WARNING;
10005
10006 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
10007 : NULL;
10008 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
10009 ? argv[idx]->arg
10010 : NULL;
10011
10012 if (src_ip && grp_ip)
10013 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
10014 else if (src_ip)
10015 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
10016 else
10017 ip_msdp_show_sa(vrf->info, vty, uj);
10018
10019 return CMD_SUCCESS;
10020 }
10021
10022 DEFUN (show_ip_msdp_sa_sg_vrf_all,
10023 show_ip_msdp_sa_sg_vrf_all_cmd,
10024 "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
10025 SHOW_STR
10026 IP_STR
10027 MSDP_STR
10028 VRF_CMD_HELP_STR
10029 "MSDP active-source information\n"
10030 "source or group ip\n"
10031 "group ip\n"
10032 JSON_STR)
10033 {
10034 bool uj = use_json(argc, argv);
10035 struct vrf *vrf;
10036 bool first = true;
10037 int idx = 2;
10038
10039 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
10040 : NULL;
10041 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
10042 ? argv[idx]->arg
10043 : NULL;
10044
10045 if (uj)
10046 vty_out(vty, "{ ");
10047 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
10048 if (uj) {
10049 if (!first)
10050 vty_out(vty, ", ");
10051 vty_out(vty, " \"%s\": ", vrf->name);
10052 first = false;
10053 } else
10054 vty_out(vty, "VRF: %s\n", vrf->name);
10055
10056 if (src_ip && grp_ip)
10057 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
10058 else if (src_ip)
10059 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
10060 else
10061 ip_msdp_show_sa(vrf->info, vty, uj);
10062 }
10063 if (uj)
10064 vty_out(vty, "}\n");
10065
10066 return CMD_SUCCESS;
10067 }
10068
10069 struct pim_sg_cache_walk_data {
10070 struct vty *vty;
10071 json_object *json;
10072 json_object *json_group;
10073 struct in_addr addr;
10074 bool addr_match;
10075 };
10076
10077 static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
10078 struct pim_sg_cache_walk_data *cwd)
10079 {
10080 struct vty *vty = cwd->vty;
10081 json_object *json = cwd->json;
10082 char src_str[INET_ADDRSTRLEN];
10083 char grp_str[INET_ADDRSTRLEN];
10084 json_object *json_row;
10085 bool installed = (vxlan_sg->up) ? true : false;
10086 const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10087 const char *oif_name;
10088
10089 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10090 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10091 else
10092 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10093
10094 if (cwd->addr_match && (vxlan_sg->sg.src.s_addr != cwd->addr.s_addr) &&
10095 (vxlan_sg->sg.grp.s_addr != cwd->addr.s_addr)) {
10096 return;
10097 }
10098 pim_inet4_dump("<src?>", vxlan_sg->sg.src, src_str, sizeof(src_str));
10099 pim_inet4_dump("<grp?>", vxlan_sg->sg.grp, grp_str, sizeof(grp_str));
10100 if (json) {
10101 json_object_object_get_ex(json, grp_str, &cwd->json_group);
10102
10103 if (!cwd->json_group) {
10104 cwd->json_group = json_object_new_object();
10105 json_object_object_add(json, grp_str,
10106 cwd->json_group);
10107 }
10108
10109 json_row = json_object_new_object();
10110 json_object_string_add(json_row, "source", src_str);
10111 json_object_string_add(json_row, "group", grp_str);
10112 json_object_string_add(json_row, "input", iif_name);
10113 json_object_string_add(json_row, "output", oif_name);
10114 if (installed)
10115 json_object_boolean_true_add(json_row, "installed");
10116 else
10117 json_object_boolean_false_add(json_row, "installed");
10118 json_object_object_add(cwd->json_group, src_str, json_row);
10119 } else {
10120 vty_out(vty, "%-15s %-15s %-15s %-15s %-5s\n",
10121 src_str, grp_str, iif_name, oif_name,
10122 installed?"I":"");
10123 }
10124 }
10125
10126 static void pim_show_vxlan_sg_hash_entry(struct hash_backet *backet, void *arg)
10127 {
10128 pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)backet->data,
10129 (struct pim_sg_cache_walk_data *)arg);
10130 }
10131
10132 static void pim_show_vxlan_sg(struct pim_instance *pim,
10133 struct vty *vty, bool uj)
10134 {
10135 json_object *json = NULL;
10136 struct pim_sg_cache_walk_data cwd;
10137
10138 if (uj) {
10139 json = json_object_new_object();
10140 } else {
10141 vty_out(vty, "Codes: I -> installed\n");
10142 vty_out(vty,
10143 "Source Group Input Output Flags\n");
10144 }
10145
10146 memset(&cwd, 0, sizeof(cwd));
10147 cwd.vty = vty;
10148 cwd.json = json;
10149 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10150
10151 if (uj) {
10152 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10153 json, JSON_C_TO_STRING_PRETTY));
10154 json_object_free(json);
10155 }
10156 }
10157
10158 static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
10159 struct vty *vty, char *addr_str, bool uj)
10160 {
10161 json_object *json = NULL;
10162 struct pim_sg_cache_walk_data cwd;
10163 int result = 0;
10164
10165 memset(&cwd, 0, sizeof(cwd));
10166 result = inet_pton(AF_INET, addr_str, &cwd.addr);
10167 if (result <= 0) {
10168 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
10169 errno, safe_strerror(errno));
10170 return;
10171 }
10172
10173 if (uj) {
10174 json = json_object_new_object();
10175 } else {
10176 vty_out(vty, "Codes: I -> installed\n");
10177 vty_out(vty,
10178 "Source Group Input Output Flags\n");
10179 }
10180
10181 cwd.vty = vty;
10182 cwd.json = json;
10183 cwd.addr_match = true;
10184 hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
10185
10186 if (uj) {
10187 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10188 json, JSON_C_TO_STRING_PRETTY));
10189 json_object_free(json);
10190 }
10191 }
10192
10193 static void pim_show_vxlan_sg_one(struct pim_instance *pim,
10194 struct vty *vty, char *src_str, char *grp_str, bool uj)
10195 {
10196 json_object *json = NULL;
10197 struct prefix_sg sg;
10198 int result = 0;
10199 struct pim_vxlan_sg *vxlan_sg;
10200 const char *iif_name;
10201 bool installed;
10202 const char *oif_name;
10203
10204 result = inet_pton(AF_INET, src_str, &sg.src);
10205 if (result <= 0) {
10206 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
10207 errno, safe_strerror(errno));
10208 return;
10209 }
10210 result = inet_pton(AF_INET, grp_str, &sg.grp);
10211 if (result <= 0) {
10212 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
10213 errno, safe_strerror(errno));
10214 return;
10215 }
10216
10217 sg.family = AF_INET;
10218 sg.prefixlen = IPV4_MAX_BITLEN;
10219 if (uj)
10220 json = json_object_new_object();
10221
10222 vxlan_sg = pim_vxlan_sg_find(pim, &sg);
10223 if (vxlan_sg) {
10224 installed = (vxlan_sg->up) ? true : false;
10225 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
10226
10227 if (pim_vxlan_is_orig_mroute(vxlan_sg))
10228 oif_name =
10229 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
10230 else
10231 oif_name =
10232 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
10233
10234 if (uj) {
10235 json_object_string_add(json, "source", src_str);
10236 json_object_string_add(json, "group", grp_str);
10237 json_object_string_add(json, "input", iif_name);
10238 json_object_string_add(json, "output", oif_name);
10239 if (installed)
10240 json_object_boolean_true_add(json, "installed");
10241 else
10242 json_object_boolean_false_add(json,
10243 "installed");
10244 } else {
10245 vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
10246 vty_out(vty, " Input : %s\n", iif_name);
10247 vty_out(vty, " Output : %s\n", oif_name);
10248 vty_out(vty, " installed : %s\n",
10249 installed?"yes":"no");
10250 }
10251 }
10252
10253 if (uj) {
10254 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10255 json, JSON_C_TO_STRING_PRETTY));
10256 json_object_free(json);
10257 }
10258 }
10259
10260 DEFUN (show_ip_pim_vxlan_sg,
10261 show_ip_pim_vxlan_sg_cmd,
10262 "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
10263 SHOW_STR
10264 IP_STR
10265 PIM_STR
10266 VRF_CMD_HELP_STR
10267 "VxLAN BUM groups\n"
10268 "source or group ip\n"
10269 "group ip\n"
10270 JSON_STR)
10271 {
10272 bool uj = use_json(argc, argv);
10273 struct vrf *vrf;
10274 int idx = 2;
10275
10276 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10277
10278 if (!vrf)
10279 return CMD_WARNING;
10280
10281 char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
10282 argv[idx++]->arg:NULL;
10283 char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
10284 argv[idx]->arg:NULL;
10285
10286 if (src_ip && grp_ip)
10287 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
10288 else if (src_ip)
10289 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
10290 else
10291 pim_show_vxlan_sg(vrf->info, vty, uj);
10292
10293 return CMD_SUCCESS;
10294 }
10295
10296 static void pim_show_vxlan_sg_work(struct pim_instance *pim,
10297 struct vty *vty, bool uj)
10298 {
10299 json_object *json = NULL;
10300 struct pim_sg_cache_walk_data cwd;
10301 struct listnode *node;
10302 struct pim_vxlan_sg *vxlan_sg;
10303
10304 if (uj) {
10305 json = json_object_new_object();
10306 } else {
10307 vty_out(vty, "Codes: I -> installed\n");
10308 vty_out(vty,
10309 "Source Group Input Flags\n");
10310 }
10311
10312 memset(&cwd, 0, sizeof(cwd));
10313 cwd.vty = vty;
10314 cwd.json = json;
10315 for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
10316 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
10317
10318 if (uj) {
10319 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10320 json, JSON_C_TO_STRING_PRETTY));
10321 json_object_free(json);
10322 }
10323 }
10324
10325 DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
10326 show_ip_pim_vxlan_sg_work_cmd,
10327 "show ip pim [vrf NAME] vxlan-work [json]",
10328 SHOW_STR
10329 IP_STR
10330 PIM_STR
10331 VRF_CMD_HELP_STR
10332 "VxLAN work list\n"
10333 JSON_STR)
10334 {
10335 bool uj = use_json(argc, argv);
10336 struct vrf *vrf;
10337 int idx = 2;
10338
10339 vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
10340
10341 if (!vrf)
10342 return CMD_WARNING;
10343
10344 pim_show_vxlan_sg_work(vrf->info, vty, uj);
10345
10346 return CMD_SUCCESS;
10347 }
10348
10349 DEFUN_HIDDEN (no_ip_pim_mlag,
10350 no_ip_pim_mlag_cmd,
10351 "no ip pim mlag",
10352 NO_STR
10353 IP_STR
10354 PIM_STR
10355 "MLAG\n")
10356 {
10357 struct in_addr addr;
10358
10359 addr.s_addr = 0;
10360 pim_vxlan_mlag_update(true/*mlag_enable*/,
10361 false/*peer_state*/, PIM_VXLAN_MLAG_ROLE_SECONDARY,
10362 NULL/*peerlink*/, &addr);
10363
10364 return CMD_SUCCESS;
10365 }
10366
10367 DEFUN_HIDDEN (ip_pim_mlag,
10368 ip_pim_mlag_cmd,
10369 "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
10370 IP_STR
10371 PIM_STR
10372 "MLAG\n"
10373 "peerlink sub interface\n"
10374 "MLAG role\n"
10375 "MLAG role primary\n"
10376 "MLAG role secondary\n"
10377 "peer session state\n"
10378 "peer session state up\n"
10379 "peer session state down\n"
10380 "configure PIP\n"
10381 "unique ip address\n")
10382 {
10383 struct interface *ifp;
10384 const char *peerlink;
10385 uint32_t role;
10386 int idx;
10387 bool peer_state;
10388 int result;
10389 struct in_addr reg_addr;
10390
10391 idx = 3;
10392 peerlink = argv[idx]->arg;
10393 ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
10394 if (!ifp) {
10395 vty_out(vty, "No such interface name %s\n", peerlink);
10396 return CMD_WARNING;
10397 }
10398
10399 idx += 2;
10400 if (!strcmp(argv[idx]->arg, "primary")) {
10401 role = PIM_VXLAN_MLAG_ROLE_PRIMARY;
10402 } else if (!strcmp(argv[idx]->arg, "secondary")) {
10403 role = PIM_VXLAN_MLAG_ROLE_SECONDARY;
10404 } else {
10405 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
10406 return CMD_WARNING;
10407 }
10408
10409 idx += 2;
10410 if (!strcmp(argv[idx]->arg, "up")) {
10411 peer_state = true;
10412 } else if (strcmp(argv[idx]->arg, "down")) {
10413 peer_state = false;
10414 } else {
10415 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
10416 return CMD_WARNING;
10417 }
10418
10419 idx += 2;
10420 result = inet_pton(AF_INET, argv[idx]->arg, &reg_addr);
10421 if (result <= 0) {
10422 vty_out(vty, "%% Bad reg address %s: errno=%d: %s\n",
10423 argv[idx]->arg,
10424 errno, safe_strerror(errno));
10425 return CMD_WARNING_CONFIG_FAILED;
10426 }
10427 pim_vxlan_mlag_update(true, peer_state, role, ifp, &reg_addr);
10428
10429 return CMD_SUCCESS;
10430 }
10431
10432 void pim_cmd_init(void)
10433 {
10434 install_node(&interface_node,
10435 pim_interface_config_write); /* INTERFACE_NODE */
10436 if_cmd_init();
10437
10438 install_node(&debug_node, pim_debug_config_write);
10439
10440 install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
10441
10442 install_element(CONFIG_NODE, &ip_pim_rp_cmd);
10443 install_element(VRF_NODE, &ip_pim_rp_cmd);
10444 install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
10445 install_element(VRF_NODE, &no_ip_pim_rp_cmd);
10446 install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
10447 install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
10448 install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
10449 install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
10450 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
10451 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
10452 install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
10453 install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
10454 install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
10455 install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
10456 install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
10457 install_element(VRF_NODE, &ip_pim_register_suppress_cmd);
10458 install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
10459 install_element(VRF_NODE, &no_ip_pim_register_suppress_cmd);
10460 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
10461 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
10462 install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
10463 install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
10464 install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
10465 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
10466 install_element(CONFIG_NODE,
10467 &no_ip_pim_spt_switchover_infinity_plist_cmd);
10468 install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
10469 install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
10470 install_element(VRF_NODE, &ip_pim_joinprune_time_cmd);
10471 install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
10472 install_element(VRF_NODE, &no_ip_pim_joinprune_time_cmd);
10473 install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
10474 install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
10475 install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
10476 install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
10477 install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
10478 install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
10479 install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
10480 install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
10481 install_element(CONFIG_NODE, &ip_pim_packets_cmd);
10482 install_element(VRF_NODE, &ip_pim_packets_cmd);
10483 install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
10484 install_element(VRF_NODE, &no_ip_pim_packets_cmd);
10485 install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
10486 install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
10487 install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
10488 install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
10489 install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
10490 install_element(VRF_NODE, &ip_ssmpingd_cmd);
10491 install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
10492 install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
10493 install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
10494 install_element(VRF_NODE, &ip_msdp_peer_cmd);
10495 install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
10496 install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
10497 install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
10498 install_element(VRF_NODE, &ip_pim_ecmp_cmd);
10499 install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
10500 install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
10501 install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
10502 install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
10503 install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
10504 install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
10505 install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
10506 install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
10507
10508 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
10509 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
10510 install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
10511 install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
10512 install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
10513 install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
10514 install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
10515 install_element(INTERFACE_NODE,
10516 &interface_no_ip_igmp_query_interval_cmd);
10517 install_element(INTERFACE_NODE,
10518 &interface_ip_igmp_query_max_response_time_cmd);
10519 install_element(INTERFACE_NODE,
10520 &interface_no_ip_igmp_query_max_response_time_cmd);
10521 install_element(INTERFACE_NODE,
10522 &interface_ip_igmp_query_max_response_time_dsec_cmd);
10523 install_element(INTERFACE_NODE,
10524 &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
10525 install_element(INTERFACE_NODE,
10526 &interface_ip_igmp_last_member_query_count_cmd);
10527 install_element(INTERFACE_NODE,
10528 &interface_no_ip_igmp_last_member_query_count_cmd);
10529 install_element(INTERFACE_NODE,
10530 &interface_ip_igmp_last_member_query_interval_cmd);
10531 install_element(INTERFACE_NODE,
10532 &interface_no_ip_igmp_last_member_query_interval_cmd);
10533 install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
10534 install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
10535 install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
10536 install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
10537 install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
10538 install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
10539 install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
10540 install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
10541 install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
10542 install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
10543 install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
10544 install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
10545 install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
10546 install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
10547
10548 // Static mroutes NEB
10549 install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
10550 install_element(INTERFACE_NODE, &interface_ip_mroute_source_cmd);
10551 install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
10552 install_element(INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
10553
10554 install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
10555 install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
10556 install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
10557 install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
10558 install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
10559 install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
10560 install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
10561 install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
10562 install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
10563 install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
10564 install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
10565 install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
10566 install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
10567 install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
10568 install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
10569 install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
10570 install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
10571 install_element(VIEW_NODE, &show_ip_pim_join_cmd);
10572 install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
10573 install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
10574 install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
10575 install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
10576 install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
10577 install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
10578 install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
10579 install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
10580 install_element(VIEW_NODE, &show_ip_pim_state_cmd);
10581 install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
10582 install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
10583 install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
10584 install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
10585 install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
10586 install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
10587 install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
10588 install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
10589 install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
10590 install_element(VIEW_NODE, &show_ip_multicast_cmd);
10591 install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
10592 install_element(VIEW_NODE, &show_ip_mroute_cmd);
10593 install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
10594 install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
10595 install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
10596 install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
10597 install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
10598 install_element(VIEW_NODE, &show_ip_rib_cmd);
10599 install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
10600 install_element(VIEW_NODE, &show_debugging_pim_cmd);
10601 install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
10602 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
10603 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
10604 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
10605 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
10606
10607 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
10608 install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
10609 install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
10610 install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
10611 install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
10612 install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
10613 install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
10614 install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
10615
10616 install_element(ENABLE_NODE, &debug_igmp_cmd);
10617 install_element(ENABLE_NODE, &no_debug_igmp_cmd);
10618 install_element(ENABLE_NODE, &debug_igmp_events_cmd);
10619 install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
10620 install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
10621 install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
10622 install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
10623 install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
10624 install_element(ENABLE_NODE, &debug_mroute_cmd);
10625 install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
10626 install_element(ENABLE_NODE, &no_debug_mroute_cmd);
10627 install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
10628 install_element(ENABLE_NODE, &debug_pim_static_cmd);
10629 install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
10630 install_element(ENABLE_NODE, &debug_pim_cmd);
10631 install_element(ENABLE_NODE, &no_debug_pim_cmd);
10632 install_element(ENABLE_NODE, &debug_pim_nht_cmd);
10633 install_element(ENABLE_NODE, &no_debug_pim_nht_cmd);
10634 install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
10635 install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
10636 install_element(ENABLE_NODE, &debug_pim_events_cmd);
10637 install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
10638 install_element(ENABLE_NODE, &debug_pim_packets_cmd);
10639 install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
10640 install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
10641 install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
10642 install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
10643 install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
10644 install_element(ENABLE_NODE, &debug_pim_trace_cmd);
10645 install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
10646 install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
10647 install_element(ENABLE_NODE, &no_debug_pim_trace_detail_cmd);
10648 install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
10649 install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
10650 install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
10651 install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
10652 install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
10653 install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
10654 install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
10655 install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
10656 install_element(ENABLE_NODE, &debug_msdp_cmd);
10657 install_element(ENABLE_NODE, &no_debug_msdp_cmd);
10658 install_element(ENABLE_NODE, &debug_msdp_events_cmd);
10659 install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
10660 install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
10661 install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
10662 install_element(ENABLE_NODE, &debug_mtrace_cmd);
10663 install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
10664 install_element(ENABLE_NODE, &debug_bsm_cmd);
10665 install_element(ENABLE_NODE, &no_debug_bsm_cmd);
10666
10667 install_element(CONFIG_NODE, &debug_igmp_cmd);
10668 install_element(CONFIG_NODE, &no_debug_igmp_cmd);
10669 install_element(CONFIG_NODE, &debug_igmp_events_cmd);
10670 install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
10671 install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
10672 install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
10673 install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
10674 install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
10675 install_element(CONFIG_NODE, &debug_mroute_cmd);
10676 install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
10677 install_element(CONFIG_NODE, &no_debug_mroute_cmd);
10678 install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
10679 install_element(CONFIG_NODE, &debug_pim_static_cmd);
10680 install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
10681 install_element(CONFIG_NODE, &debug_pim_cmd);
10682 install_element(CONFIG_NODE, &no_debug_pim_cmd);
10683 install_element(CONFIG_NODE, &debug_pim_nht_cmd);
10684 install_element(CONFIG_NODE, &no_debug_pim_nht_cmd);
10685 install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
10686 install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
10687 install_element(CONFIG_NODE, &debug_pim_events_cmd);
10688 install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
10689 install_element(CONFIG_NODE, &debug_pim_packets_cmd);
10690 install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
10691 install_element(CONFIG_NODE, &debug_pim_trace_cmd);
10692 install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
10693 install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
10694 install_element(CONFIG_NODE, &no_debug_pim_trace_detail_cmd);
10695 install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
10696 install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
10697 install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
10698 install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
10699 install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
10700 install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
10701 install_element(CONFIG_NODE, &debug_msdp_cmd);
10702 install_element(CONFIG_NODE, &no_debug_msdp_cmd);
10703 install_element(CONFIG_NODE, &debug_msdp_events_cmd);
10704 install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
10705 install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
10706 install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
10707 install_element(CONFIG_NODE, &debug_mtrace_cmd);
10708 install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
10709 install_element(CONFIG_NODE, &debug_bsm_cmd);
10710 install_element(CONFIG_NODE, &no_debug_bsm_cmd);
10711
10712 install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
10713 install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
10714 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
10715 install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
10716 install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
10717 install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
10718 install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
10719 install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
10720 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
10721 install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
10722 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
10723 install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
10724 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
10725 install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
10726 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
10727 install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
10728 install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
10729 install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
10730 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
10731 install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
10732 install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
10733 install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
10734 /* Install BSM command */
10735 install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
10736 install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
10737 install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
10738 install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
10739 /* Install BFD command */
10740 install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
10741 install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
10742 install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
10743 #if HAVE_BFDD == 0
10744 install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
10745 #endif /* !HAVE_BFDD */
10746 }