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