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