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