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