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