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