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