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