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