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