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