Coverage Report

Created: 2025-10-23 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/pimd/pim_cmd.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * PIM for Quagga
4
 * Copyright (C) 2008  Everton da Silva Marques
5
 */
6
7
#include <zebra.h>
8
9
#include "lib/json.h"
10
#include "command.h"
11
#include "if.h"
12
#include "prefix.h"
13
#include "zclient.h"
14
#include "plist.h"
15
#include "hash.h"
16
#include "nexthop.h"
17
#include "vrf.h"
18
#include "ferr.h"
19
20
#include "pimd.h"
21
#include "pim_mroute.h"
22
#include "pim_cmd.h"
23
#include "pim_iface.h"
24
#include "pim_vty.h"
25
#include "pim_mroute.h"
26
#include "pim_str.h"
27
#include "pim_igmp.h"
28
#include "pim_igmpv3.h"
29
#include "pim_sock.h"
30
#include "pim_time.h"
31
#include "pim_util.h"
32
#include "pim_oil.h"
33
#include "pim_neighbor.h"
34
#include "pim_pim.h"
35
#include "pim_ifchannel.h"
36
#include "pim_hello.h"
37
#include "pim_msg.h"
38
#include "pim_upstream.h"
39
#include "pim_rpf.h"
40
#include "pim_macro.h"
41
#include "pim_ssmpingd.h"
42
#include "pim_zebra.h"
43
#include "pim_static.h"
44
#include "pim_rp.h"
45
#include "pim_zlookup.h"
46
#include "pim_msdp.h"
47
#include "pim_ssm.h"
48
#include "pim_nht.h"
49
#include "pim_bfd.h"
50
#include "pim_vxlan.h"
51
#include "pim_mlag.h"
52
#include "bfd.h"
53
#include "pim_bsm.h"
54
#include "lib/northbound_cli.h"
55
#include "pim_errors.h"
56
#include "pim_nb.h"
57
#include "pim_addr.h"
58
#include "pim_cmd_common.h"
59
60
#include "pimd/pim_cmd_clippy.c"
61
62
static struct cmd_node debug_node = {
63
  .name = "debug",
64
  .node = DEBUG_NODE,
65
  .prompt = "",
66
  .config_write = pim_debug_config_write,
67
};
68
69
static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
70
              const int argc, int *idx, bool uj)
71
0
{
72
0
  struct vrf *vrf;
73
74
0
  if (argv_find(argv, argc, "NAME", idx))
75
0
    vrf = vrf_lookup_by_name(argv[*idx]->arg);
76
0
  else
77
0
    vrf = vrf_lookup_by_id(VRF_DEFAULT);
78
79
0
  if (!vrf) {
80
0
    if (uj)
81
0
      vty_json_empty(vty);
82
0
    else
83
0
      vty_out(vty, "Specified VRF: %s does not exist\n",
84
0
        argv[*idx]->arg);
85
0
  }
86
87
0
  return vrf;
88
0
}
89
90
static void pim_show_assert_helper(struct vty *vty,
91
           struct pim_interface *pim_ifp,
92
           struct pim_ifchannel *ch, time_t now)
93
0
{
94
0
  char winner_str[INET_ADDRSTRLEN];
95
0
  struct in_addr ifaddr;
96
0
  char uptime[10];
97
0
  char timer[10];
98
0
  char buf[PREFIX_STRLEN];
99
100
0
  ifaddr = pim_ifp->primary_address;
101
102
0
  pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
103
0
           sizeof(winner_str));
104
105
0
  pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
106
0
  pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
107
108
0
  vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-6s %-15s %-8s %-5s\n",
109
0
    ch->interface->name,
110
0
    inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
111
0
    &ch->sg.grp, pim_ifchannel_ifassert_name(ch->ifassert_state),
112
0
    winner_str, uptime, timer);
113
0
}
114
115
static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
116
0
{
117
0
  struct pim_interface *pim_ifp;
118
0
  struct pim_ifchannel *ch;
119
0
  struct interface *ifp;
120
0
  time_t now;
121
122
0
  now = pim_time_monotonic_sec();
123
124
0
  vty_out(vty,
125
0
    "Interface        Address         Source          Group           State  Winner          Uptime   Timer\n");
126
127
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
128
0
    pim_ifp = ifp->info;
129
0
    if (!pim_ifp)
130
0
      continue;
131
132
0
    RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
133
0
      if (ch->ifassert_state == PIM_IFASSERT_NOINFO)
134
0
        continue;
135
136
0
      pim_show_assert_helper(vty, pim_ifp, ch, now);
137
0
    } /* scan interface channels */
138
0
  }
139
0
}
140
141
static void pim_show_assert_internal_helper(struct vty *vty,
142
              struct pim_interface *pim_ifp,
143
              struct pim_ifchannel *ch)
144
0
{
145
0
  struct in_addr ifaddr;
146
0
  char buf[PREFIX_STRLEN];
147
148
0
  ifaddr = pim_ifp->primary_address;
149
150
0
  vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-3s %-3s %-4s\n",
151
0
    ch->interface->name,
152
0
    inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
153
0
    &ch->sg.grp,
154
0
    PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
155
0
    pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
156
0
    PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
157
0
    : "no",
158
0
    pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
159
0
}
160
161
static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
162
0
{
163
0
  struct pim_interface *pim_ifp;
164
0
  struct pim_ifchannel *ch;
165
0
  struct interface *ifp;
166
167
0
  vty_out(vty,
168
0
    "CA:   CouldAssert\n"
169
0
    "ECA:  Evaluate CouldAssert\n"
170
0
    "ATD:  AssertTrackingDesired\n"
171
0
    "eATD: Evaluate AssertTrackingDesired\n\n");
172
173
0
  vty_out(vty,
174
0
    "Interface        Address         Source          Group           CA  eCA ATD eATD\n");
175
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
176
0
    pim_ifp = ifp->info;
177
0
    if (!pim_ifp)
178
0
      continue;
179
180
0
    RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
181
0
      pim_show_assert_internal_helper(vty, pim_ifp, ch);
182
0
    } /* scan interface channels */
183
0
  }
184
0
}
185
186
static void pim_show_assert_metric_helper(struct vty *vty,
187
            struct pim_interface *pim_ifp,
188
            struct pim_ifchannel *ch)
189
0
{
190
0
  char addr_str[INET_ADDRSTRLEN];
191
0
  struct pim_assert_metric am;
192
0
  struct in_addr ifaddr;
193
0
  char buf[PREFIX_STRLEN];
194
195
0
  ifaddr = pim_ifp->primary_address;
196
197
0
  am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
198
0
           pim_ifp->primary_address);
199
200
0
  pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
201
202
0
  vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %4u %6u %-15s\n",
203
0
    ch->interface->name,
204
0
    inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
205
0
    &ch->sg.grp, am.rpt_bit_flag ? "yes" : "no",
206
0
    am.metric_preference, am.route_metric, addr_str);
207
0
}
208
209
static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
210
0
{
211
0
  struct pim_interface *pim_ifp;
212
0
  struct pim_ifchannel *ch;
213
0
  struct interface *ifp;
214
215
0
  vty_out(vty,
216
0
    "Interface        Address         Source          Group           RPT Pref Metric Address        \n");
217
218
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
219
0
    pim_ifp = ifp->info;
220
0
    if (!pim_ifp)
221
0
      continue;
222
223
0
    RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
224
0
      pim_show_assert_metric_helper(vty, pim_ifp, ch);
225
0
    } /* scan interface channels */
226
0
  }
227
0
}
228
229
static void pim_show_assert_winner_metric_helper(struct vty *vty,
230
             struct pim_interface *pim_ifp,
231
             struct pim_ifchannel *ch)
232
0
{
233
0
  char addr_str[INET_ADDRSTRLEN];
234
0
  struct pim_assert_metric *am;
235
0
  struct in_addr ifaddr;
236
0
  char pref_str[16];
237
0
  char metr_str[16];
238
0
  char buf[PREFIX_STRLEN];
239
240
0
  ifaddr = pim_ifp->primary_address;
241
242
0
  am = &ch->ifassert_winner_metric;
243
244
0
  pim_inet4_dump("<addr?>", am->ip_address, addr_str, sizeof(addr_str));
245
246
0
  if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
247
0
    snprintf(pref_str, sizeof(pref_str), "INFI");
248
0
  else
249
0
    snprintf(pref_str, sizeof(pref_str), "%4u",
250
0
       am->metric_preference);
251
252
0
  if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
253
0
    snprintf(metr_str, sizeof(metr_str), "INFI");
254
0
  else
255
0
    snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
256
257
0
  vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-4s %-6s %-15s\n",
258
0
    ch->interface->name,
259
0
    inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
260
0
    &ch->sg.grp, am->rpt_bit_flag ? "yes" : "no", pref_str,
261
0
    metr_str, addr_str);
262
0
}
263
264
static void pim_show_assert_winner_metric(struct pim_instance *pim,
265
            struct vty *vty)
266
0
{
267
0
  struct pim_interface *pim_ifp;
268
0
  struct pim_ifchannel *ch;
269
0
  struct interface *ifp;
270
271
0
  vty_out(vty,
272
0
    "Interface        Address         Source          Group           RPT Pref Metric Address        \n");
273
274
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
275
0
    pim_ifp = ifp->info;
276
0
    if (!pim_ifp)
277
0
      continue;
278
279
0
    RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
280
0
      pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
281
0
    } /* scan interface channels */
282
0
  }
283
0
}
284
285
static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
286
         bool uj)
287
0
{
288
0
  struct interface *ifp;
289
0
  time_t now;
290
0
  char buf[PREFIX_STRLEN];
291
0
  json_object *json = NULL;
292
0
  json_object *json_row = NULL;
293
294
0
  now = pim_time_monotonic_sec();
295
296
0
  if (uj)
297
0
    json = json_object_new_object();
298
0
  else
299
0
    vty_out(vty,
300
0
      "Interface         State          Address  V  Querier          QuerierIp  Query Timer    Uptime\n");
301
302
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
303
0
    struct pim_interface *pim_ifp;
304
0
    struct listnode *sock_node;
305
0
    struct gm_sock *igmp;
306
307
0
    pim_ifp = ifp->info;
308
309
0
    if (!pim_ifp)
310
0
      continue;
311
312
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
313
0
            igmp)) {
314
0
      char uptime[10];
315
0
      char query_hhmmss[10];
316
317
0
      pim_time_uptime(uptime, sizeof(uptime),
318
0
          now - igmp->sock_creation);
319
0
      pim_time_timer_to_hhmmss(query_hhmmss,
320
0
             sizeof(query_hhmmss),
321
0
             igmp->t_igmp_query_timer);
322
323
0
      if (uj) {
324
0
        json_row = json_object_new_object();
325
0
        json_object_pim_ifp_add(json_row, ifp);
326
0
        json_object_string_add(json_row, "upTime",
327
0
                   uptime);
328
0
        json_object_int_add(json_row, "version",
329
0
                pim_ifp->igmp_version);
330
331
0
        if (igmp->t_igmp_query_timer) {
332
0
          json_object_boolean_true_add(json_row,
333
0
                     "querier");
334
0
          json_object_string_add(json_row,
335
0
                     "queryTimer",
336
0
                     query_hhmmss);
337
0
        }
338
0
        json_object_string_addf(json_row, "querierIp",
339
0
              "%pI4",
340
0
              &igmp->querier_addr);
341
342
0
        json_object_object_add(json, ifp->name,
343
0
                   json_row);
344
345
0
        if (igmp->mtrace_only) {
346
0
          json_object_boolean_true_add(
347
0
            json_row, "mtraceOnly");
348
0
        }
349
0
      } else {
350
0
        vty_out(vty,
351
0
          "%-16s  %5s  %15s  %d  %7s  %17pI4  %11s  %8s\n",
352
0
          ifp->name,
353
0
          if_is_up(ifp)
354
0
            ? (igmp->mtrace_only ? "mtrc"
355
0
                     : "up")
356
0
            : "down",
357
0
          inet_ntop(AF_INET, &igmp->ifaddr, buf,
358
0
              sizeof(buf)),
359
0
          pim_ifp->igmp_version,
360
0
          igmp->t_igmp_query_timer ? "local"
361
0
                 : "other",
362
0
          &igmp->querier_addr, query_hhmmss,
363
0
          uptime);
364
0
      }
365
0
    }
366
0
  }
367
368
0
  if (uj)
369
0
    vty_json(vty, json);
370
0
}
371
372
static void igmp_show_interfaces_single(struct pim_instance *pim,
373
          struct vty *vty, const char *ifname,
374
          bool uj)
375
0
{
376
0
  struct gm_sock *igmp;
377
0
  struct interface *ifp;
378
0
  struct listnode *sock_node;
379
0
  struct pim_interface *pim_ifp;
380
0
  char uptime[10];
381
0
  char query_hhmmss[10];
382
0
  char other_hhmmss[10];
383
0
  int found_ifname = 0;
384
0
  int sqi;
385
0
  long gmi_msec; /* Group Membership Interval */
386
0
  long lmqt_msec;
387
0
  long ohpi_msec;
388
0
  long oqpi_msec; /* Other Querier Present Interval */
389
0
  long qri_msec;
390
0
  time_t now;
391
0
  int lmqc;
392
393
0
  json_object *json = NULL;
394
0
  json_object *json_row = NULL;
395
396
0
  if (uj)
397
0
    json = json_object_new_object();
398
399
0
  now = pim_time_monotonic_sec();
400
401
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
402
0
    pim_ifp = ifp->info;
403
404
0
    if (!pim_ifp)
405
0
      continue;
406
407
0
    if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
408
0
      continue;
409
410
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
411
0
            igmp)) {
412
0
      found_ifname = 1;
413
0
      pim_time_uptime(uptime, sizeof(uptime),
414
0
          now - igmp->sock_creation);
415
0
      pim_time_timer_to_hhmmss(query_hhmmss,
416
0
             sizeof(query_hhmmss),
417
0
             igmp->t_igmp_query_timer);
418
0
      pim_time_timer_to_hhmmss(other_hhmmss,
419
0
             sizeof(other_hhmmss),
420
0
             igmp->t_other_querier_timer);
421
422
0
      gmi_msec = PIM_IGMP_GMI_MSEC(
423
0
        igmp->querier_robustness_variable,
424
0
        igmp->querier_query_interval,
425
0
        pim_ifp->gm_query_max_response_time_dsec);
426
427
0
      sqi = PIM_IGMP_SQI(pim_ifp->gm_default_query_interval);
428
429
0
      oqpi_msec = PIM_IGMP_OQPI_MSEC(
430
0
        igmp->querier_robustness_variable,
431
0
        igmp->querier_query_interval,
432
0
        pim_ifp->gm_query_max_response_time_dsec);
433
434
0
      lmqt_msec = PIM_IGMP_LMQT_MSEC(
435
0
        pim_ifp->gm_specific_query_max_response_time_dsec,
436
0
        pim_ifp->gm_last_member_query_count);
437
438
0
      ohpi_msec =
439
0
        PIM_IGMP_OHPI_DSEC(
440
0
          igmp->querier_robustness_variable,
441
0
          igmp->querier_query_interval,
442
0
          pim_ifp->gm_query_max_response_time_dsec) *
443
0
        100;
444
445
0
      qri_msec =
446
0
        pim_ifp->gm_query_max_response_time_dsec * 100;
447
0
      lmqc = pim_ifp->gm_last_member_query_count;
448
449
0
      if (uj) {
450
0
        json_row = json_object_new_object();
451
0
        json_object_pim_ifp_add(json_row, ifp);
452
0
        json_object_string_add(json_row, "upTime",
453
0
                   uptime);
454
0
        json_object_string_add(json_row, "querier",
455
0
                   igmp->t_igmp_query_timer
456
0
                   ? "local"
457
0
                   : "other");
458
0
        json_object_string_addf(json_row, "querierIp",
459
0
              "%pI4",
460
0
              &igmp->querier_addr);
461
0
        json_object_int_add(json_row, "queryStartCount",
462
0
                igmp->startup_query_count);
463
0
        json_object_string_add(json_row,
464
0
                   "queryQueryTimer",
465
0
                   query_hhmmss);
466
0
        json_object_string_add(json_row,
467
0
                   "queryOtherTimer",
468
0
                   other_hhmmss);
469
0
        json_object_int_add(json_row, "version",
470
0
                pim_ifp->igmp_version);
471
0
        json_object_int_add(
472
0
          json_row,
473
0
          "timerGroupMembershipIntervalMsec",
474
0
          gmi_msec);
475
0
        json_object_int_add(json_row,
476
0
                "lastMemberQueryCount",
477
0
                lmqc);
478
0
        json_object_int_add(json_row,
479
0
                "timerLastMemberQueryMsec",
480
0
                lmqt_msec);
481
0
        json_object_int_add(
482
0
          json_row,
483
0
          "timerOlderHostPresentIntervalMsec",
484
0
          ohpi_msec);
485
0
        json_object_int_add(
486
0
          json_row,
487
0
          "timerOtherQuerierPresentIntervalMsec",
488
0
          oqpi_msec);
489
0
        json_object_int_add(
490
0
          json_row, "timerQueryInterval",
491
0
          igmp->querier_query_interval);
492
0
        json_object_int_add(
493
0
          json_row,
494
0
          "timerQueryResponseIntervalMsec",
495
0
          qri_msec);
496
0
        json_object_int_add(
497
0
          json_row, "timerRobustnessVariable",
498
0
          igmp->querier_robustness_variable);
499
0
        json_object_int_add(json_row,
500
0
                "timerStartupQueryInterval",
501
0
                sqi);
502
503
0
        json_object_object_add(json, ifp->name,
504
0
                   json_row);
505
506
0
        if (igmp->mtrace_only) {
507
0
          json_object_boolean_true_add(
508
0
            json_row, "mtraceOnly");
509
0
        }
510
0
      } else {
511
0
        vty_out(vty, "Interface : %s\n", ifp->name);
512
0
        vty_out(vty, "State     : %s\n",
513
0
          if_is_up(ifp) ? (igmp->mtrace_only ?
514
0
               "mtrace"
515
0
               : "up")
516
0
          : "down");
517
0
        vty_out(vty, "Address   : %pI4\n",
518
0
          &pim_ifp->primary_address);
519
0
        vty_out(vty, "Uptime    : %s\n", uptime);
520
0
        vty_out(vty, "Version   : %d\n",
521
0
          pim_ifp->igmp_version);
522
0
        vty_out(vty, "\n");
523
0
        vty_out(vty, "\n");
524
525
0
        vty_out(vty, "Querier\n");
526
0
        vty_out(vty, "-------\n");
527
0
        vty_out(vty, "Querier     : %s\n",
528
0
          igmp->t_igmp_query_timer ? "local"
529
0
          : "other");
530
0
        vty_out(vty, "QuerierIp   : %pI4",
531
0
          &igmp->querier_addr);
532
0
        if (pim_ifp->primary_address.s_addr
533
0
            == igmp->querier_addr.s_addr)
534
0
          vty_out(vty, " (this router)\n");
535
0
        else
536
0
          vty_out(vty, "\n");
537
538
0
        vty_out(vty, "Start Count : %d\n",
539
0
          igmp->startup_query_count);
540
0
        vty_out(vty, "Query Timer : %s\n",
541
0
          query_hhmmss);
542
0
        vty_out(vty, "Other Timer : %s\n",
543
0
          other_hhmmss);
544
0
        vty_out(vty, "\n");
545
0
        vty_out(vty, "\n");
546
547
0
        vty_out(vty, "Timers\n");
548
0
        vty_out(vty, "------\n");
549
0
        vty_out(vty,
550
0
          "Group Membership Interval      : %lis\n",
551
0
          gmi_msec / 1000);
552
0
        vty_out(vty,
553
0
          "Last Member Query Count        : %d\n",
554
0
          lmqc);
555
0
        vty_out(vty,
556
0
          "Last Member Query Time         : %lis\n",
557
0
          lmqt_msec / 1000);
558
0
        vty_out(vty,
559
0
          "Older Host Present Interval    : %lis\n",
560
0
          ohpi_msec / 1000);
561
0
        vty_out(vty,
562
0
          "Other Querier Present Interval : %lis\n",
563
0
          oqpi_msec / 1000);
564
0
        vty_out(vty,
565
0
          "Query Interval                 : %ds\n",
566
0
          igmp->querier_query_interval);
567
0
        vty_out(vty,
568
0
          "Query Response Interval        : %lis\n",
569
0
          qri_msec / 1000);
570
0
        vty_out(vty,
571
0
          "Robustness Variable            : %d\n",
572
0
          igmp->querier_robustness_variable);
573
0
        vty_out(vty,
574
0
          "Startup Query Interval         : %ds\n",
575
0
          sqi);
576
0
        vty_out(vty, "\n");
577
0
        vty_out(vty, "\n");
578
579
0
        pim_print_ifp_flags(vty, ifp);
580
0
      }
581
0
    }
582
0
  }
583
584
0
  if (uj)
585
0
    vty_json(vty, json);
586
0
  else if (!found_ifname)
587
0
    vty_out(vty, "%% No such interface\n");
588
0
}
589
590
static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty,
591
             bool uj)
592
0
{
593
0
  struct interface *ifp;
594
0
  time_t now;
595
0
  json_object *json = NULL;
596
0
  json_object *json_iface = NULL;
597
0
  json_object *json_grp = NULL;
598
0
  json_object *json_grp_arr = NULL;
599
600
0
  now = pim_time_monotonic_sec();
601
602
0
  if (uj) {
603
0
    json = json_object_new_object();
604
0
    json_object_string_add(json, "vrf",
605
0
               vrf_id_to_name(pim->vrf->vrf_id));
606
0
  } else {
607
0
    vty_out(vty,
608
0
      "Interface        Address         Source          Group           Socket Uptime  \n");
609
0
  }
610
611
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
612
0
    struct pim_interface *pim_ifp;
613
0
    struct listnode *join_node;
614
0
    struct gm_join *ij;
615
0
    struct in_addr pri_addr;
616
0
    char pri_addr_str[INET_ADDRSTRLEN];
617
618
0
    pim_ifp = ifp->info;
619
620
0
    if (!pim_ifp)
621
0
      continue;
622
623
0
    if (!pim_ifp->gm_join_list)
624
0
      continue;
625
626
0
    pri_addr = pim_find_primary_addr(ifp);
627
0
    pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
628
0
             sizeof(pri_addr_str));
629
630
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_join_list, join_node,
631
0
            ij)) {
632
0
      char group_str[INET_ADDRSTRLEN];
633
0
      char source_str[INET_ADDRSTRLEN];
634
0
      char uptime[10];
635
636
0
      pim_time_uptime(uptime, sizeof(uptime),
637
0
          now - ij->sock_creation);
638
0
      pim_inet4_dump("<grp?>", ij->group_addr, group_str,
639
0
               sizeof(group_str));
640
0
      pim_inet4_dump("<src?>", ij->source_addr, source_str,
641
0
               sizeof(source_str));
642
643
0
      if (uj) {
644
0
        json_object_object_get_ex(json, ifp->name,
645
0
                &json_iface);
646
647
0
        if (!json_iface) {
648
0
          json_iface = json_object_new_object();
649
0
          json_object_string_add(
650
0
            json_iface, "name", ifp->name);
651
0
          json_object_object_add(json, ifp->name,
652
0
                     json_iface);
653
0
          json_grp_arr = json_object_new_array();
654
0
          json_object_object_add(json_iface,
655
0
                     "groups",
656
0
                     json_grp_arr);
657
0
        }
658
659
0
        json_grp = json_object_new_object();
660
0
        json_object_string_add(json_grp, "source",
661
0
                   source_str);
662
0
        json_object_string_add(json_grp, "group",
663
0
                   group_str);
664
0
        json_object_string_add(json_grp, "primaryAddr",
665
0
                   pri_addr_str);
666
0
        json_object_int_add(json_grp, "sockFd",
667
0
                ij->sock_fd);
668
0
        json_object_string_add(json_grp, "upTime",
669
0
                   uptime);
670
0
        json_object_array_add(json_grp_arr, json_grp);
671
0
      } else {
672
0
        vty_out(vty,
673
0
          "%-16s %-15s %-15s %-15s %6d %8s\n",
674
0
          ifp->name, pri_addr_str, source_str,
675
0
          group_str, ij->sock_fd, uptime);
676
0
      }
677
0
    } /* for (pim_ifp->gm_join_list) */
678
679
0
  } /* for (iflist) */
680
681
0
  if (uj)
682
0
    vty_json(vty, json);
683
0
}
684
685
static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
686
         const char *ifname, bool uj)
687
0
{
688
0
  struct interface *ifp;
689
0
  struct igmp_stats igmp_stats;
690
0
  bool found_ifname = false;
691
0
  json_object *json = NULL;
692
693
0
  igmp_stats_init(&igmp_stats);
694
695
0
  if (uj)
696
0
    json = json_object_new_object();
697
698
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
699
0
    struct pim_interface *pim_ifp;
700
0
    struct listnode *sock_node, *source_node, *group_node;
701
0
    struct gm_sock *igmp;
702
0
    struct gm_group *group;
703
0
    struct gm_source *src;
704
705
0
    pim_ifp = ifp->info;
706
707
0
    if (!pim_ifp)
708
0
      continue;
709
710
0
    if (ifname && strcmp(ifname, ifp->name))
711
0
      continue;
712
713
0
    found_ifname = true;
714
715
0
    igmp_stats.joins_failed += pim_ifp->igmp_ifstat_joins_failed;
716
0
    igmp_stats.joins_sent += pim_ifp->igmp_ifstat_joins_sent;
717
0
    igmp_stats.total_groups +=
718
0
      pim_ifp->gm_group_list
719
0
        ? listcount(pim_ifp->gm_group_list)
720
0
        : 0;
721
0
    igmp_stats.peak_groups += pim_ifp->igmp_peak_group_count;
722
723
724
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, group_node,
725
0
            group)) {
726
0
      for (ALL_LIST_ELEMENTS_RO(group->group_source_list,
727
0
              source_node, src)) {
728
0
        if (pim_addr_is_any(src->source_addr))
729
0
          continue;
730
731
0
        igmp_stats.total_source_groups++;
732
0
      }
733
0
    }
734
735
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
736
0
            igmp)) {
737
0
      igmp_stats_add(&igmp_stats, &igmp->igmp_stats);
738
0
    }
739
0
  }
740
741
0
  if (!found_ifname) {
742
0
    if (uj)
743
0
      vty_json(vty, json);
744
0
    else
745
0
      vty_out(vty, "%% No such interface\n");
746
0
    return;
747
0
  }
748
749
0
  if (uj) {
750
0
    json_object *json_row = json_object_new_object();
751
752
0
    json_object_string_add(json_row, "name",
753
0
               ifname ? ifname : "global");
754
0
    json_object_int_add(json_row, "queryV1", igmp_stats.query_v1);
755
0
    json_object_int_add(json_row, "queryV2", igmp_stats.query_v2);
756
0
    json_object_int_add(json_row, "queryV3", igmp_stats.query_v3);
757
0
    json_object_int_add(json_row, "leaveV2", igmp_stats.leave_v2);
758
0
    json_object_int_add(json_row, "reportV1", igmp_stats.report_v1);
759
0
    json_object_int_add(json_row, "reportV2", igmp_stats.report_v2);
760
0
    json_object_int_add(json_row, "reportV3", igmp_stats.report_v3);
761
0
    json_object_int_add(json_row, "mtraceResponse",
762
0
            igmp_stats.mtrace_rsp);
763
0
    json_object_int_add(json_row, "mtraceRequest",
764
0
            igmp_stats.mtrace_req);
765
0
    json_object_int_add(json_row, "unsupported",
766
0
            igmp_stats.unsupported);
767
0
    json_object_int_add(json_row, "totalReceivedMessages",
768
0
            igmp_stats.total_recv_messages);
769
0
    json_object_int_add(json_row, "peakGroups",
770
0
            igmp_stats.peak_groups);
771
0
    json_object_int_add(json_row, "totalGroups",
772
0
            igmp_stats.total_groups);
773
0
    json_object_int_add(json_row, "totalSourceGroups",
774
0
            igmp_stats.total_source_groups);
775
0
    json_object_int_add(json_row, "joinsFailed",
776
0
            igmp_stats.joins_failed);
777
0
    json_object_int_add(json_row, "joinsSent",
778
0
            igmp_stats.joins_sent);
779
0
    json_object_int_add(json_row, "generalQueriesSent",
780
0
            igmp_stats.general_queries_sent);
781
0
    json_object_int_add(json_row, "groupQueriesSent",
782
0
            igmp_stats.group_queries_sent);
783
0
    json_object_object_add(json, ifname ? ifname : "global",
784
0
               json_row);
785
0
    vty_json(vty, json);
786
0
  } else {
787
0
    vty_out(vty, "IGMP statistics\n");
788
0
    vty_out(vty, "Interface               : %s\n",
789
0
      ifname ? ifname : "global");
790
0
    vty_out(vty, "V1 query                : %u\n",
791
0
      igmp_stats.query_v1);
792
0
    vty_out(vty, "V2 query                : %u\n",
793
0
      igmp_stats.query_v2);
794
0
    vty_out(vty, "V3 query                : %u\n",
795
0
      igmp_stats.query_v3);
796
0
    vty_out(vty, "V2 leave                : %u\n",
797
0
      igmp_stats.leave_v2);
798
0
    vty_out(vty, "V1 report               : %u\n",
799
0
      igmp_stats.report_v1);
800
0
    vty_out(vty, "V2 report               : %u\n",
801
0
      igmp_stats.report_v2);
802
0
    vty_out(vty, "V3 report               : %u\n",
803
0
      igmp_stats.report_v3);
804
0
    vty_out(vty, "mtrace response         : %u\n",
805
0
      igmp_stats.mtrace_rsp);
806
0
    vty_out(vty, "mtrace request          : %u\n",
807
0
      igmp_stats.mtrace_req);
808
0
    vty_out(vty, "unsupported             : %u\n",
809
0
      igmp_stats.unsupported);
810
0
    vty_out(vty, "total received messages : %u\n",
811
0
      igmp_stats.total_recv_messages);
812
0
    vty_out(vty, "joins failed            : %u\n",
813
0
      igmp_stats.joins_failed);
814
0
    vty_out(vty, "joins sent              : %u\n",
815
0
      igmp_stats.joins_sent);
816
0
    vty_out(vty, "general queries sent    : %u\n",
817
0
      igmp_stats.general_queries_sent);
818
0
    vty_out(vty, "group queries sent      : %u\n",
819
0
      igmp_stats.group_queries_sent);
820
0
    vty_out(vty, "peak groups             : %u\n",
821
0
      igmp_stats.peak_groups);
822
0
    vty_out(vty, "total groups            : %u\n",
823
0
      igmp_stats.total_groups);
824
0
    vty_out(vty, "total source groups     : %u\n",
825
0
      igmp_stats.total_source_groups);
826
0
  }
827
0
}
828
829
static void igmp_source_json_helper(struct gm_source *src,
830
            json_object *json_sources, char *source_str,
831
            char *mmss, char *uptime)
832
0
{
833
0
  json_object *json_source = NULL;
834
835
0
  json_source = json_object_new_object();
836
0
  if (!json_source)
837
0
    return;
838
839
0
  json_object_string_add(json_source, "source", source_str);
840
0
  json_object_string_add(json_source, "timer", mmss);
841
0
  json_object_boolean_add(json_source, "forwarded",
842
0
        IGMP_SOURCE_TEST_FORWARDING(src->source_flags));
843
0
  json_object_string_add(json_source, "uptime", uptime);
844
0
  json_object_array_add(json_sources, json_source);
845
0
}
846
847
static void igmp_group_print(struct interface *ifp, struct vty *vty, bool uj,
848
           json_object *json, struct gm_group *grp,
849
           time_t now, bool detail)
850
0
{
851
0
  json_object *json_iface = NULL;
852
0
  json_object *json_group = NULL;
853
0
  json_object *json_groups = NULL;
854
0
  char group_str[INET_ADDRSTRLEN];
855
0
  char hhmmss[PIM_TIME_STRLEN];
856
0
  char uptime[PIM_TIME_STRLEN];
857
858
0
  pim_inet4_dump("<group?>", grp->group_addr, group_str,
859
0
           sizeof(group_str));
860
0
  pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
861
0
  pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
862
863
0
  if (uj) {
864
0
    json_object_object_get_ex(json, ifp->name, &json_iface);
865
0
    if (!json_iface) {
866
0
      json_iface = json_object_new_object();
867
0
      if (!json_iface)
868
0
        return;
869
0
      json_object_pim_ifp_add(json_iface, ifp);
870
0
      json_object_object_add(json, ifp->name, json_iface);
871
0
      json_groups = json_object_new_array();
872
0
      if (!json_groups)
873
0
        return;
874
0
      json_object_object_add(json_iface, "groups",
875
0
                 json_groups);
876
0
    }
877
878
0
    json_object_object_get_ex(json_iface, "groups", &json_groups);
879
0
    if (json_groups) {
880
0
      json_group = json_object_new_object();
881
0
      if (!json_group)
882
0
        return;
883
884
0
      json_object_string_add(json_group, "group", group_str);
885
0
      if (grp->igmp_version == IGMP_DEFAULT_VERSION)
886
0
        json_object_string_add(
887
0
          json_group, "mode",
888
0
          grp->group_filtermode_isexcl
889
0
            ? "EXCLUDE"
890
0
            : "INCLUDE");
891
892
0
      json_object_string_add(json_group, "timer", hhmmss);
893
0
      json_object_int_add(
894
0
        json_group, "sourcesCount",
895
0
        grp->group_source_list
896
0
          ? listcount(grp->group_source_list)
897
0
          : 0);
898
0
      json_object_int_add(json_group, "version",
899
0
              grp->igmp_version);
900
0
      json_object_string_add(json_group, "uptime", uptime);
901
0
      json_object_array_add(json_groups, json_group);
902
903
0
      if (detail) {
904
0
        struct listnode *srcnode;
905
0
        struct gm_source *src;
906
0
        json_object *json_sources = NULL;
907
908
0
        json_sources = json_object_new_array();
909
0
        if (!json_sources)
910
0
          return;
911
912
0
        json_object_object_add(json_group, "sources",
913
0
                   json_sources);
914
915
0
        for (ALL_LIST_ELEMENTS_RO(
916
0
               grp->group_source_list, srcnode,
917
0
               src)) {
918
0
          char source_str[INET_ADDRSTRLEN];
919
0
          char mmss[PIM_TIME_STRLEN];
920
0
          char src_uptime[PIM_TIME_STRLEN];
921
922
0
          pim_inet4_dump(
923
0
            "<source?>", src->source_addr,
924
0
            source_str, sizeof(source_str));
925
0
          pim_time_timer_to_mmss(
926
0
            mmss, sizeof(mmss),
927
0
            src->t_source_timer);
928
0
          pim_time_uptime(
929
0
            src_uptime, sizeof(src_uptime),
930
0
            now - src->source_creation);
931
932
0
          igmp_source_json_helper(
933
0
            src, json_sources, source_str,
934
0
            mmss, src_uptime);
935
0
        }
936
0
      }
937
0
    }
938
0
  } else {
939
0
    if (detail) {
940
0
      struct listnode *srcnode;
941
0
      struct gm_source *src;
942
943
0
      for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
944
0
              srcnode, src)) {
945
0
        char source_str[INET_ADDRSTRLEN];
946
947
0
        pim_inet4_dump("<source?>", src->source_addr,
948
0
                 source_str, sizeof(source_str));
949
950
0
        vty_out(vty,
951
0
          "%-16s %-15s %4s %8s %-15s %d %8s\n",
952
0
          ifp->name, group_str,
953
0
          grp->igmp_version == 3
954
0
            ? (grp->group_filtermode_isexcl
955
0
                 ? "EXCL"
956
0
                 : "INCL")
957
0
            : "----",
958
0
          hhmmss, source_str, grp->igmp_version,
959
0
          uptime);
960
0
      }
961
0
      return;
962
0
    }
963
964
0
    vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n", ifp->name,
965
0
      group_str,
966
0
      grp->igmp_version == 3
967
0
        ? (grp->group_filtermode_isexcl ? "EXCL"
968
0
                : "INCL")
969
0
        : "----",
970
0
      hhmmss,
971
0
      grp->group_source_list
972
0
        ? listcount(grp->group_source_list)
973
0
        : 0,
974
0
      grp->igmp_version, uptime);
975
0
  }
976
0
}
977
978
static void igmp_show_groups_interface_single(struct pim_instance *pim,
979
                struct vty *vty, bool uj,
980
                const char *ifname,
981
                const char *grp_str, bool detail)
982
0
{
983
0
  struct interface *ifp;
984
0
  time_t now;
985
0
  json_object *json = NULL;
986
0
  struct pim_interface *pim_ifp = NULL;
987
0
  struct gm_group *grp;
988
989
0
  now = pim_time_monotonic_sec();
990
991
0
  if (uj) {
992
0
    json = json_object_new_object();
993
0
    if (!json)
994
0
      return;
995
0
    json_object_int_add(json, "totalGroups", pim->gm_group_count);
996
0
    json_object_int_add(json, "watermarkLimit",
997
0
            pim->gm_watermark_limit);
998
0
  } else {
999
0
    vty_out(vty, "Total IGMP groups: %u\n", pim->gm_group_count);
1000
0
    vty_out(vty, "Watermark warn limit(%s): %u\n",
1001
0
      pim->gm_watermark_limit ? "Set" : "Not Set",
1002
0
      pim->gm_watermark_limit);
1003
1004
0
    if (!detail)
1005
0
      vty_out(vty,
1006
0
        "Interface        Group           Mode Timer    Srcs V Uptime\n");
1007
0
    else
1008
0
      vty_out(vty,
1009
0
        "Interface        Group           Mode Timer    Source          V Uptime\n");
1010
0
  }
1011
1012
0
  ifp = if_lookup_by_name(ifname, pim->vrf->vrf_id);
1013
0
  if (!ifp) {
1014
0
    if (uj)
1015
0
      vty_json(vty, json);
1016
0
    return;
1017
0
  }
1018
1019
0
  pim_ifp = ifp->info;
1020
0
  if (!pim_ifp) {
1021
0
    if (uj)
1022
0
      vty_json(vty, json);
1023
0
    return;
1024
0
  }
1025
1026
0
  if (grp_str) {
1027
0
    struct in_addr group_addr;
1028
0
    struct gm_sock *igmp;
1029
1030
0
    if (inet_pton(AF_INET, grp_str, &group_addr) == 1) {
1031
0
      igmp = pim_igmp_sock_lookup_ifaddr(
1032
0
        pim_ifp->gm_socket_list,
1033
0
        pim_ifp->primary_address);
1034
0
      if (igmp) {
1035
0
        grp = find_group_by_addr(igmp, group_addr);
1036
0
        if (grp)
1037
0
          igmp_group_print(ifp, vty, uj, json,
1038
0
               grp, now, detail);
1039
0
      }
1040
0
    }
1041
0
  } else {
1042
0
    struct listnode *grpnode;
1043
1044
    /* scan igmp groups */
1045
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode, grp))
1046
0
      igmp_group_print(ifp, vty, uj, json, grp, now, detail);
1047
0
  }
1048
1049
0
  if (uj) {
1050
0
    if (detail)
1051
0
      vty_json_no_pretty(vty, json);
1052
0
    else
1053
0
      vty_json(vty, json);
1054
0
  }
1055
0
}
1056
1057
static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj,
1058
           const char *grp_str, bool detail)
1059
0
{
1060
0
  struct interface *ifp;
1061
0
  time_t now;
1062
0
  json_object *json = NULL;
1063
1064
0
  now = pim_time_monotonic_sec();
1065
1066
0
  if (uj) {
1067
0
    json = json_object_new_object();
1068
0
    if (!json)
1069
0
      return;
1070
0
    json_object_int_add(json, "totalGroups", pim->gm_group_count);
1071
0
    json_object_int_add(json, "watermarkLimit",
1072
0
            pim->gm_watermark_limit);
1073
0
  } else {
1074
0
    vty_out(vty, "Total IGMP groups: %u\n", pim->gm_group_count);
1075
0
    vty_out(vty, "Watermark warn limit(%s): %u\n",
1076
0
      pim->gm_watermark_limit ? "Set" : "Not Set",
1077
0
      pim->gm_watermark_limit);
1078
0
    if (!detail)
1079
0
      vty_out(vty,
1080
0
        "Interface        Group           Mode Timer    Srcs V Uptime\n");
1081
0
    else
1082
0
      vty_out(vty,
1083
0
        "Interface        Group           Mode Timer    Source          V Uptime\n");
1084
0
  }
1085
1086
  /* scan interfaces */
1087
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
1088
0
    struct pim_interface *pim_ifp = ifp->info;
1089
0
    struct listnode *grpnode;
1090
0
    struct gm_group *grp;
1091
1092
0
    if (!pim_ifp)
1093
0
      continue;
1094
1095
0
    if (grp_str) {
1096
0
      struct in_addr group_addr;
1097
0
      struct gm_sock *igmp;
1098
1099
0
      if (inet_pton(AF_INET, grp_str, &group_addr) == 1) {
1100
0
        igmp = pim_igmp_sock_lookup_ifaddr(
1101
0
          pim_ifp->gm_socket_list,
1102
0
          pim_ifp->primary_address);
1103
0
        if (igmp) {
1104
0
          grp = find_group_by_addr(igmp,
1105
0
                 group_addr);
1106
0
          if (grp)
1107
0
            igmp_group_print(ifp, vty, uj,
1108
0
                 json, grp, now,
1109
0
                 detail);
1110
0
        }
1111
0
      }
1112
0
    } else {
1113
      /* scan igmp groups */
1114
0
      for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list,
1115
0
              grpnode, grp))
1116
0
        igmp_group_print(ifp, vty, uj, json, grp, now,
1117
0
             detail);
1118
0
    }
1119
0
  } /* scan interfaces */
1120
1121
0
  if (uj) {
1122
0
    if (detail)
1123
0
      vty_json_no_pretty(vty, json);
1124
0
    else
1125
0
      vty_json(vty, json);
1126
0
  }
1127
0
}
1128
1129
static void igmp_show_group_retransmission(struct pim_instance *pim,
1130
             struct vty *vty)
1131
0
{
1132
0
  struct interface *ifp;
1133
1134
0
  vty_out(vty,
1135
0
    "Interface        Group           RetTimer Counter RetSrcs\n");
1136
1137
  /* scan interfaces */
1138
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
1139
0
    struct pim_interface *pim_ifp = ifp->info;
1140
0
    struct listnode *grpnode;
1141
0
    struct gm_group *grp;
1142
1143
0
    if (!pim_ifp)
1144
0
      continue;
1145
1146
    /* scan igmp groups */
1147
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
1148
0
            grp)) {
1149
0
      char group_str[INET_ADDRSTRLEN];
1150
0
      char grp_retr_mmss[10];
1151
0
      struct listnode *src_node;
1152
0
      struct gm_source *src;
1153
0
      int grp_retr_sources = 0;
1154
1155
0
      pim_inet4_dump("<group?>", grp->group_addr, group_str,
1156
0
               sizeof(group_str));
1157
0
      pim_time_timer_to_mmss(
1158
0
        grp_retr_mmss, sizeof(grp_retr_mmss),
1159
0
        grp->t_group_query_retransmit_timer);
1160
1161
1162
      /* count group sources with retransmission state
1163
       */
1164
0
      for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
1165
0
              src_node, src)) {
1166
0
        if (src->source_query_retransmit_count > 0) {
1167
0
          ++grp_retr_sources;
1168
0
        }
1169
0
      }
1170
1171
0
      vty_out(vty, "%-16s %-15s %-8s %7d %7d\n", ifp->name,
1172
0
        group_str, grp_retr_mmss,
1173
0
        grp->group_specific_query_retransmit_count,
1174
0
        grp_retr_sources);
1175
1176
0
    } /* scan igmp groups */
1177
0
  }   /* scan interfaces */
1178
0
}
1179
1180
static void igmp_sources_print(struct interface *ifp, char *group_str,
1181
             struct gm_source *src, time_t now,
1182
             json_object *json, struct vty *vty, bool uj)
1183
0
{
1184
0
  json_object *json_iface = NULL;
1185
0
  json_object *json_group = NULL;
1186
0
  json_object *json_sources = NULL;
1187
0
  char source_str[INET_ADDRSTRLEN];
1188
0
  char mmss[PIM_TIME_STRLEN];
1189
0
  char uptime[PIM_TIME_STRLEN];
1190
1191
0
  pim_inet4_dump("<source?>", src->source_addr, source_str,
1192
0
           sizeof(source_str));
1193
0
  pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
1194
0
  pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
1195
1196
0
  if (uj) {
1197
0
    json_object_object_get_ex(json, ifp->name, &json_iface);
1198
0
    if (!json_iface) {
1199
0
      json_iface = json_object_new_object();
1200
0
      if (!json_iface)
1201
0
        return;
1202
0
      json_object_string_add(json_iface, "name", ifp->name);
1203
0
      json_object_object_add(json, ifp->name, json_iface);
1204
0
    }
1205
1206
0
    json_object_object_get_ex(json_iface, group_str, &json_group);
1207
0
    if (!json_group) {
1208
0
      json_group = json_object_new_object();
1209
0
      if (!json_group)
1210
0
        return;
1211
0
      json_object_string_add(json_group, "group", group_str);
1212
0
      json_object_object_add(json_iface, group_str,
1213
0
                 json_group);
1214
0
      json_sources = json_object_new_array();
1215
0
      if (!json_sources)
1216
0
        return;
1217
0
      json_object_object_add(json_group, "sources",
1218
0
                 json_sources);
1219
0
    }
1220
1221
0
    json_object_object_get_ex(json_group, "sources", &json_sources);
1222
0
    if (json_sources)
1223
0
      igmp_source_json_helper(src, json_sources, source_str,
1224
0
            mmss, uptime);
1225
0
  } else {
1226
0
    vty_out(vty, "%-16s %-15s %-15s %5s %3s %8s\n", ifp->name,
1227
0
      group_str, source_str, mmss,
1228
0
      IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y"
1229
0
                       : "N",
1230
0
      uptime);
1231
0
  }
1232
0
}
1233
1234
static void igmp_show_sources_interface_single(struct pim_instance *pim,
1235
                 struct vty *vty, bool uj,
1236
                 const char *ifname,
1237
                 const char *grp_str)
1238
0
{
1239
0
  struct interface *ifp;
1240
0
  time_t now;
1241
0
  json_object *json = NULL;
1242
0
  struct pim_interface *pim_ifp;
1243
0
  struct gm_group *grp;
1244
1245
0
  now = pim_time_monotonic_sec();
1246
1247
0
  if (uj) {
1248
0
    json = json_object_new_object();
1249
0
    if (!json)
1250
0
      return;
1251
0
  } else {
1252
0
    vty_out(vty,
1253
0
      "Interface        Group           Source          Timer Fwd Uptime  \n");
1254
0
  }
1255
1256
0
  ifp = if_lookup_by_name(ifname, pim->vrf->vrf_id);
1257
0
  if (!ifp) {
1258
0
    if (uj)
1259
0
      vty_json(vty, json);
1260
0
    return;
1261
0
  }
1262
1263
0
  pim_ifp = ifp->info;
1264
0
  if (!pim_ifp) {
1265
0
    if (uj)
1266
0
      vty_json(vty, json);
1267
0
    return;
1268
0
  }
1269
1270
0
  if (grp_str) {
1271
0
    struct in_addr group_addr;
1272
0
    struct gm_sock *igmp;
1273
0
    struct listnode *srcnode;
1274
0
    struct gm_source *src;
1275
0
    char group_str[INET_ADDRSTRLEN];
1276
0
    int res;
1277
1278
0
    res = inet_pton(AF_INET, grp_str, &group_addr);
1279
0
    if (res <= 0) {
1280
0
      if (uj)
1281
0
        vty_json(vty, json);
1282
0
      return;
1283
0
    }
1284
1285
0
    igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->gm_socket_list,
1286
0
               pim_ifp->primary_address);
1287
0
    if (!igmp) {
1288
0
      if (uj)
1289
0
        vty_json(vty, json);
1290
0
      return;
1291
0
    }
1292
1293
0
    grp = find_group_by_addr(igmp, group_addr);
1294
0
    if (!grp) {
1295
0
      if (uj)
1296
0
        vty_json(vty, json);
1297
0
      return;
1298
0
    }
1299
0
    pim_inet4_dump("<group?>", grp->group_addr, group_str,
1300
0
             sizeof(group_str));
1301
1302
    /* scan group sources */
1303
0
    for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src))
1304
0
      igmp_sources_print(ifp, group_str, src, now, json, vty,
1305
0
             uj);
1306
0
  } else {
1307
0
    struct listnode *grpnode;
1308
1309
    /* scan igmp groups */
1310
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
1311
0
            grp)) {
1312
0
      char group_str[INET_ADDRSTRLEN];
1313
0
      struct listnode *srcnode;
1314
0
      struct gm_source *src;
1315
1316
0
      pim_inet4_dump("<group?>", grp->group_addr, group_str,
1317
0
               sizeof(group_str));
1318
1319
      /* scan group sources */
1320
0
      for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
1321
0
              srcnode, src))
1322
0
        igmp_sources_print(ifp, group_str, src, now,
1323
0
               json, vty, uj);
1324
1325
0
    } /* scan igmp groups */
1326
0
  }
1327
1328
0
  if (uj)
1329
0
    vty_json(vty, json);
1330
0
}
1331
1332
static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
1333
            bool uj)
1334
0
{
1335
0
  struct interface *ifp;
1336
0
  time_t now;
1337
0
  json_object *json = NULL;
1338
1339
0
  now = pim_time_monotonic_sec();
1340
1341
0
  if (uj) {
1342
0
    json = json_object_new_object();
1343
0
    if (!json)
1344
0
      return;
1345
0
  } else {
1346
0
    vty_out(vty,
1347
0
      "Interface        Group           Source          Timer Fwd Uptime\n");
1348
0
  }
1349
1350
  /* scan interfaces */
1351
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
1352
0
    struct pim_interface *pim_ifp = ifp->info;
1353
0
    struct listnode *grpnode;
1354
0
    struct gm_group *grp;
1355
1356
0
    if (!pim_ifp)
1357
0
      continue;
1358
1359
    /* scan igmp groups */
1360
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
1361
0
            grp)) {
1362
0
      char group_str[INET_ADDRSTRLEN];
1363
0
      struct listnode *srcnode;
1364
0
      struct gm_source *src;
1365
1366
0
      pim_inet4_dump("<group?>", grp->group_addr, group_str,
1367
0
               sizeof(group_str));
1368
1369
      /* scan group sources */
1370
0
      for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
1371
0
              srcnode, src))
1372
0
        igmp_sources_print(ifp, group_str, src, now,
1373
0
               json, vty, uj);
1374
0
    }  /* scan igmp groups */
1375
0
  }     /* scan interfaces */
1376
1377
0
  if (uj)
1378
0
    vty_json(vty, json);
1379
0
}
1380
1381
static void igmp_show_source_retransmission(struct pim_instance *pim,
1382
              struct vty *vty)
1383
0
{
1384
0
  struct interface *ifp;
1385
1386
0
  vty_out(vty,
1387
0
    "Interface        Group           Source          Counter\n");
1388
1389
  /* scan interfaces */
1390
0
  FOR_ALL_INTERFACES (pim->vrf, ifp) {
1391
0
    struct pim_interface *pim_ifp = ifp->info;
1392
0
    struct listnode *grpnode;
1393
0
    struct gm_group *grp;
1394
1395
0
    if (!pim_ifp)
1396
0
      continue;
1397
1398
    /* scan igmp groups */
1399
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
1400
0
            grp)) {
1401
0
      char group_str[INET_ADDRSTRLEN];
1402
0
      struct listnode *srcnode;
1403
0
      struct gm_source *src;
1404
1405
0
      pim_inet4_dump("<group?>", grp->group_addr, group_str,
1406
0
               sizeof(group_str));
1407
1408
      /* scan group sources */
1409
0
      for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
1410
0
              srcnode, src)) {
1411
0
        char source_str[INET_ADDRSTRLEN];
1412
1413
0
        pim_inet4_dump("<source?>", src->source_addr,
1414
0
                 source_str, sizeof(source_str));
1415
1416
0
        vty_out(vty, "%-16s %-15s %-15s %7d\n",
1417
0
          ifp->name, group_str, source_str,
1418
0
          src->source_query_retransmit_count);
1419
1420
0
      } /* scan group sources */
1421
0
    }  /* scan igmp groups */
1422
0
  }     /* scan interfaces */
1423
0
}
1424
1425
static void clear_igmp_interfaces(struct pim_instance *pim)
1426
0
{
1427
0
  struct interface *ifp;
1428
1429
0
  FOR_ALL_INTERFACES (pim->vrf, ifp)
1430
0
    pim_if_addr_del_all_igmp(ifp);
1431
1432
0
  FOR_ALL_INTERFACES (pim->vrf, ifp)
1433
0
    pim_if_addr_add_all(ifp);
1434
0
}
1435
1436
static void clear_interfaces(struct pim_instance *pim)
1437
0
{
1438
0
  clear_igmp_interfaces(pim);
1439
0
  clear_pim_interfaces(pim);
1440
0
}
1441
1442
#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp)       \
1443
  pim_ifp = ifp->info;            \
1444
  if (!pim_ifp) {             \
1445
    vty_out(vty,            \
1446
      "%% Enable PIM and/or IGMP on this interface first\n"); \
1447
    return CMD_WARNING_CONFIG_FAILED;     \
1448
  }
1449
1450
/**
1451
 * Compatibility function to keep the legacy mesh group CLI behavior:
1452
 * Delete group when there are no more configurations in it.
1453
 *
1454
 * NOTE:
1455
 * Don't forget to call `nb_cli_apply_changes` after this.
1456
 */
1457
static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
1458
                 const char *gname)
1459
0
{
1460
0
  const char *vrfname;
1461
0
  char xpath_value[XPATH_MAXLEN];
1462
0
  char xpath_member_value[XPATH_MAXLEN];
1463
0
  const struct lyd_node *member_dnode;
1464
1465
0
  vrfname = pim_cli_get_vrf_name(vty);
1466
0
  if (vrfname == NULL)
1467
0
    return;
1468
1469
  /* Get mesh group base XPath. */
1470
0
  snprintf(xpath_value, sizeof(xpath_value),
1471
0
     FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
1472
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
1473
  /* Group must exists, otherwise just quit. */
1474
0
  if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
1475
0
    return;
1476
1477
  /* Group members check: */
1478
0
  strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
1479
0
  strlcat(xpath_member_value, "/members", sizeof(xpath_member_value));
1480
0
  if (yang_dnode_exists(vty->candidate_config->dnode,
1481
0
            xpath_member_value)) {
1482
0
    member_dnode = yang_dnode_get(vty->candidate_config->dnode,
1483
0
                xpath_member_value);
1484
0
    if (!member_dnode || !yang_is_last_list_dnode(member_dnode))
1485
0
      return;
1486
0
  }
1487
1488
  /* Source address check: */
1489
0
  strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
1490
0
  strlcat(xpath_member_value, "/source", sizeof(xpath_member_value));
1491
0
  if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value))
1492
0
    return;
1493
1494
  /* No configurations found: delete it. */
1495
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
1496
0
}
1497
1498
DEFUN (clear_ip_interfaces,
1499
       clear_ip_interfaces_cmd,
1500
       "clear ip interfaces [vrf NAME]",
1501
       CLEAR_STR
1502
       IP_STR
1503
       "Reset interfaces\n"
1504
       VRF_CMD_HELP_STR)
1505
0
{
1506
0
  int idx = 2;
1507
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
1508
1509
0
  if (!vrf)
1510
0
    return CMD_WARNING;
1511
1512
0
  clear_interfaces(vrf->info);
1513
1514
0
  return CMD_SUCCESS;
1515
0
}
1516
1517
DEFUN (clear_ip_igmp_interfaces,
1518
       clear_ip_igmp_interfaces_cmd,
1519
       "clear ip igmp [vrf NAME] interfaces",
1520
       CLEAR_STR
1521
       IP_STR
1522
       CLEAR_IP_IGMP_STR
1523
       VRF_CMD_HELP_STR
1524
       "Reset IGMP interfaces\n")
1525
0
{
1526
0
  int idx = 2;
1527
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
1528
1529
0
  if (!vrf)
1530
0
    return CMD_WARNING;
1531
1532
0
  clear_igmp_interfaces(vrf->info);
1533
1534
0
  return CMD_SUCCESS;
1535
0
}
1536
1537
DEFPY (clear_ip_pim_statistics,
1538
       clear_ip_pim_statistics_cmd,
1539
       "clear ip pim statistics [vrf NAME]$name",
1540
       CLEAR_STR
1541
       IP_STR
1542
       CLEAR_IP_PIM_STR
1543
       VRF_CMD_HELP_STR
1544
       "Reset PIM statistics\n")
1545
0
{
1546
0
  struct vrf *v = pim_cmd_lookup(vty, name);
1547
1548
0
  if (!v)
1549
0
    return CMD_WARNING;
1550
1551
0
  clear_pim_statistics(v->info);
1552
1553
0
  return CMD_SUCCESS;
1554
0
}
1555
1556
DEFPY (clear_ip_mroute,
1557
       clear_ip_mroute_cmd,
1558
       "clear ip mroute [vrf NAME]$name",
1559
       CLEAR_STR
1560
       IP_STR
1561
       MROUTE_STR
1562
       VRF_CMD_HELP_STR)
1563
0
{
1564
0
  struct vrf *v = pim_cmd_lookup(vty, name);
1565
1566
0
  if (!v)
1567
0
    return CMD_WARNING;
1568
1569
0
  clear_mroute(v->info);
1570
1571
0
  return CMD_SUCCESS;
1572
0
}
1573
1574
DEFPY (clear_ip_pim_interfaces,
1575
       clear_ip_pim_interfaces_cmd,
1576
       "clear ip pim [vrf NAME] interfaces",
1577
       CLEAR_STR
1578
       IP_STR
1579
       CLEAR_IP_PIM_STR
1580
       VRF_CMD_HELP_STR
1581
       "Reset PIM interfaces\n")
1582
0
{
1583
0
  struct vrf *v = pim_cmd_lookup(vty, vrf);
1584
1585
0
  if (!v)
1586
0
    return CMD_WARNING;
1587
1588
0
  clear_pim_interfaces(v->info);
1589
1590
0
  return CMD_SUCCESS;
1591
0
}
1592
1593
DEFPY (clear_ip_pim_interface_traffic,
1594
       clear_ip_pim_interface_traffic_cmd,
1595
       "clear ip pim [vrf NAME] interface traffic",
1596
       CLEAR_STR
1597
       IP_STR
1598
       CLEAR_IP_PIM_STR
1599
       VRF_CMD_HELP_STR
1600
       "Reset PIM interfaces\n"
1601
       "Reset Protocol Packet counters\n")
1602
0
{
1603
0
  return clear_pim_interface_traffic(vrf, vty);
1604
0
}
1605
1606
DEFPY (clear_ip_pim_oil,
1607
       clear_ip_pim_oil_cmd,
1608
       "clear ip pim [vrf NAME]$name oil",
1609
       CLEAR_STR
1610
       IP_STR
1611
       CLEAR_IP_PIM_STR
1612
       VRF_CMD_HELP_STR
1613
       "Rescan PIM OIL (output interface list)\n")
1614
0
{
1615
0
  struct vrf *v = pim_cmd_lookup(vty, name);
1616
1617
0
  if (!v)
1618
0
    return CMD_WARNING;
1619
1620
0
  pim_scan_oil(v->info);
1621
1622
0
  return CMD_SUCCESS;
1623
0
}
1624
1625
DEFUN (clear_ip_pim_bsr_db,
1626
       clear_ip_pim_bsr_db_cmd,
1627
       "clear ip pim [vrf NAME] bsr-data",
1628
       CLEAR_STR
1629
       IP_STR
1630
       CLEAR_IP_PIM_STR
1631
       VRF_CMD_HELP_STR
1632
       "Reset pim bsr data\n")
1633
0
{
1634
0
  int idx = 2;
1635
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
1636
1637
0
  if (!vrf)
1638
0
    return CMD_WARNING;
1639
1640
0
  pim_bsm_clear(vrf->info);
1641
1642
0
  return CMD_SUCCESS;
1643
0
}
1644
1645
DEFUN (show_ip_igmp_interface,
1646
       show_ip_igmp_interface_cmd,
1647
       "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
1648
       SHOW_STR
1649
       IP_STR
1650
       IGMP_STR
1651
       VRF_CMD_HELP_STR
1652
       "IGMP interface information\n"
1653
       "Detailed output\n"
1654
       "interface name\n"
1655
       JSON_STR)
1656
0
{
1657
0
  int idx = 2;
1658
0
  bool uj = use_json(argc, argv);
1659
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
1660
1661
0
  if (!vrf)
1662
0
    return CMD_WARNING;
1663
1664
0
  if (argv_find(argv, argc, "detail", &idx)
1665
0
      || argv_find(argv, argc, "WORD", &idx))
1666
0
    igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
1667
0
  else
1668
0
    igmp_show_interfaces(vrf->info, vty, uj);
1669
1670
0
  return CMD_SUCCESS;
1671
0
}
1672
1673
DEFUN (show_ip_igmp_interface_vrf_all,
1674
       show_ip_igmp_interface_vrf_all_cmd,
1675
       "show ip igmp vrf all interface [detail|WORD] [json]",
1676
       SHOW_STR
1677
       IP_STR
1678
       IGMP_STR
1679
       VRF_CMD_HELP_STR
1680
       "IGMP interface information\n"
1681
       "Detailed output\n"
1682
       "interface name\n"
1683
       JSON_STR)
1684
0
{
1685
0
  int idx = 2;
1686
0
  bool uj = use_json(argc, argv);
1687
0
  struct vrf *vrf;
1688
0
  bool first = true;
1689
1690
0
  if (uj)
1691
0
    vty_out(vty, "{ ");
1692
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1693
0
    if (uj) {
1694
0
      if (!first)
1695
0
        vty_out(vty, ", ");
1696
0
      vty_out(vty, " \"%s\": ", vrf->name);
1697
0
      first = false;
1698
0
    } else
1699
0
      vty_out(vty, "VRF: %s\n", vrf->name);
1700
0
    if (argv_find(argv, argc, "detail", &idx)
1701
0
        || argv_find(argv, argc, "WORD", &idx))
1702
0
      igmp_show_interfaces_single(vrf->info, vty,
1703
0
                argv[idx]->arg, uj);
1704
0
    else
1705
0
      igmp_show_interfaces(vrf->info, vty, uj);
1706
0
  }
1707
0
  if (uj)
1708
0
    vty_out(vty, "}\n");
1709
1710
0
  return CMD_SUCCESS;
1711
0
}
1712
1713
DEFUN (show_ip_igmp_join,
1714
       show_ip_igmp_join_cmd,
1715
       "show ip igmp [vrf NAME] join [json]",
1716
       SHOW_STR
1717
       IP_STR
1718
       IGMP_STR
1719
       VRF_CMD_HELP_STR
1720
       "IGMP static join information\n"
1721
       JSON_STR)
1722
0
{
1723
0
  int idx = 2;
1724
0
  bool uj = use_json(argc, argv);
1725
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
1726
1727
0
  if (!vrf)
1728
0
    return CMD_WARNING;
1729
1730
0
  igmp_show_interface_join(vrf->info, vty, uj);
1731
1732
0
  return CMD_SUCCESS;
1733
0
}
1734
1735
DEFUN (show_ip_igmp_join_vrf_all,
1736
       show_ip_igmp_join_vrf_all_cmd,
1737
       "show ip igmp vrf all join [json]",
1738
       SHOW_STR
1739
       IP_STR
1740
       IGMP_STR
1741
       VRF_CMD_HELP_STR
1742
       "IGMP static join information\n"
1743
       JSON_STR)
1744
0
{
1745
0
  bool uj = use_json(argc, argv);
1746
0
  struct vrf *vrf;
1747
0
  bool first = true;
1748
1749
0
  if (uj)
1750
0
    vty_out(vty, "{ ");
1751
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1752
0
    if (uj) {
1753
0
      if (!first)
1754
0
        vty_out(vty, ", ");
1755
0
      vty_out(vty, " \"%s\": ", vrf->name);
1756
0
      first = false;
1757
0
    } else
1758
0
      vty_out(vty, "VRF: %s\n", vrf->name);
1759
0
    igmp_show_interface_join(vrf->info, vty, uj);
1760
0
  }
1761
0
  if (uj)
1762
0
    vty_out(vty, "}\n");
1763
1764
0
  return CMD_SUCCESS;
1765
0
}
1766
1767
DEFPY(show_ip_igmp_groups,
1768
      show_ip_igmp_groups_cmd,
1769
      "show ip igmp [vrf NAME$vrf_name] groups [INTERFACE$ifname [GROUP$grp_str]] [detail$detail] [json$json]",
1770
      SHOW_STR
1771
      IP_STR
1772
      IGMP_STR
1773
      VRF_CMD_HELP_STR
1774
      IGMP_GROUP_STR
1775
      "Interface name\n"
1776
      "Group address\n"
1777
      "Detailed Information\n"
1778
      JSON_STR)
1779
0
{
1780
0
  int idx = 2;
1781
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, !!json);
1782
1783
0
  if (!vrf)
1784
0
    return CMD_WARNING;
1785
1786
0
  if (ifname)
1787
0
    igmp_show_groups_interface_single(vrf->info, vty, !!json,
1788
0
              ifname, grp_str, !!detail);
1789
0
  else
1790
0
    igmp_show_groups(vrf->info, vty, !!json, NULL, !!detail);
1791
1792
0
  return CMD_SUCCESS;
1793
0
}
1794
1795
DEFPY(show_ip_igmp_groups_vrf_all,
1796
      show_ip_igmp_groups_vrf_all_cmd,
1797
      "show ip igmp vrf all groups [GROUP$grp_str] [detail$detail] [json$json]",
1798
      SHOW_STR
1799
      IP_STR
1800
      IGMP_STR
1801
      VRF_CMD_HELP_STR
1802
      IGMP_GROUP_STR
1803
      "Group address\n"
1804
      "Detailed Information\n"
1805
      JSON_STR)
1806
0
{
1807
0
  bool uj = !!json;
1808
0
  struct vrf *vrf;
1809
0
  bool first = true;
1810
1811
0
  if (uj)
1812
0
    vty_out(vty, "{ ");
1813
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1814
0
    if (uj) {
1815
0
      if (!first)
1816
0
        vty_out(vty, ", ");
1817
0
      vty_out(vty, " \"%s\": ", vrf->name);
1818
0
      first = false;
1819
0
    } else
1820
0
      vty_out(vty, "VRF: %s\n", vrf->name);
1821
0
    igmp_show_groups(vrf->info, vty, uj, grp_str, !!detail);
1822
0
  }
1823
0
  if (uj)
1824
0
    vty_out(vty, "}\n");
1825
1826
0
  return CMD_SUCCESS;
1827
0
}
1828
1829
DEFUN (show_ip_igmp_groups_retransmissions,
1830
       show_ip_igmp_groups_retransmissions_cmd,
1831
       "show ip igmp [vrf NAME] groups retransmissions",
1832
       SHOW_STR
1833
       IP_STR
1834
       IGMP_STR
1835
       VRF_CMD_HELP_STR
1836
       IGMP_GROUP_STR
1837
       "IGMP group retransmissions\n")
1838
0
{
1839
0
  int idx = 2;
1840
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
1841
1842
0
  if (!vrf)
1843
0
    return CMD_WARNING;
1844
1845
0
  igmp_show_group_retransmission(vrf->info, vty);
1846
1847
0
  return CMD_SUCCESS;
1848
0
}
1849
1850
DEFPY(show_ip_igmp_sources,
1851
      show_ip_igmp_sources_cmd,
1852
      "show ip igmp [vrf NAME$vrf_name] sources [INTERFACE$ifname [GROUP$grp_str]] [json$json]",
1853
      SHOW_STR
1854
      IP_STR
1855
      IGMP_STR
1856
      VRF_CMD_HELP_STR
1857
      IGMP_SOURCE_STR
1858
      "Interface name\n"
1859
      "Group address\n"
1860
      JSON_STR)
1861
0
{
1862
0
  int idx = 2;
1863
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, !!json);
1864
1865
0
  if (!vrf)
1866
0
    return CMD_WARNING;
1867
1868
0
  if (ifname)
1869
0
    igmp_show_sources_interface_single(vrf->info, vty, !!json,
1870
0
               ifname, grp_str);
1871
0
  else
1872
0
    igmp_show_sources(vrf->info, vty, !!json);
1873
1874
0
  return CMD_SUCCESS;
1875
0
}
1876
1877
DEFUN (show_ip_igmp_sources_retransmissions,
1878
       show_ip_igmp_sources_retransmissions_cmd,
1879
       "show ip igmp [vrf NAME] sources retransmissions",
1880
       SHOW_STR
1881
       IP_STR
1882
       IGMP_STR
1883
       VRF_CMD_HELP_STR
1884
       IGMP_SOURCE_STR
1885
       "IGMP source retransmissions\n")
1886
0
{
1887
0
  int idx = 2;
1888
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
1889
1890
0
  if (!vrf)
1891
0
    return CMD_WARNING;
1892
1893
0
  igmp_show_source_retransmission(vrf->info, vty);
1894
1895
0
  return CMD_SUCCESS;
1896
0
}
1897
1898
DEFUN (show_ip_igmp_statistics,
1899
       show_ip_igmp_statistics_cmd,
1900
       "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
1901
       SHOW_STR
1902
       IP_STR
1903
       IGMP_STR
1904
       VRF_CMD_HELP_STR
1905
       "IGMP statistics\n"
1906
       "interface\n"
1907
       "IGMP interface\n"
1908
       JSON_STR)
1909
0
{
1910
0
  int idx = 2;
1911
0
  bool uj = use_json(argc, argv);
1912
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
1913
1914
0
  if (!vrf)
1915
0
    return CMD_WARNING;
1916
1917
0
  if (argv_find(argv, argc, "WORD", &idx))
1918
0
    igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
1919
0
  else
1920
0
    igmp_show_statistics(vrf->info, vty, NULL, uj);
1921
1922
0
  return CMD_SUCCESS;
1923
0
}
1924
1925
DEFUN (show_ip_pim_mlag_summary,
1926
       show_ip_pim_mlag_summary_cmd,
1927
       "show ip pim mlag summary [json]",
1928
       SHOW_STR
1929
       IP_STR
1930
       PIM_STR
1931
       "MLAG\n"
1932
       "status and stats\n"
1933
       JSON_STR)
1934
0
{
1935
0
  bool uj = use_json(argc, argv);
1936
0
  char role_buf[MLAG_ROLE_STRSIZE];
1937
0
  char addr_buf[INET_ADDRSTRLEN];
1938
1939
0
  if (uj) {
1940
0
    json_object *json = NULL;
1941
0
    json_object *json_stat = NULL;
1942
1943
0
    json = json_object_new_object();
1944
0
    if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
1945
0
      json_object_boolean_true_add(json, "mlagConnUp");
1946
0
    if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
1947
0
      json_object_boolean_true_add(json, "mlagPeerConnUp");
1948
0
    if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
1949
0
      json_object_boolean_true_add(json, "mlagPeerZebraUp");
1950
0
    json_object_string_add(json, "mlagRole",
1951
0
               mlag_role2str(router->mlag_role,
1952
0
                 role_buf, sizeof(role_buf)));
1953
0
    inet_ntop(AF_INET, &router->local_vtep_ip,
1954
0
        addr_buf, INET_ADDRSTRLEN);
1955
0
    json_object_string_add(json, "localVtepIp", addr_buf);
1956
0
    inet_ntop(AF_INET, &router->anycast_vtep_ip,
1957
0
        addr_buf, INET_ADDRSTRLEN);
1958
0
    json_object_string_add(json, "anycastVtepIp", addr_buf);
1959
0
    json_object_string_add(json, "peerlinkRif",
1960
0
               router->peerlink_rif);
1961
1962
0
    json_stat = json_object_new_object();
1963
0
    json_object_int_add(json_stat, "mlagConnFlaps",
1964
0
            router->mlag_stats.mlagd_session_downs);
1965
0
    json_object_int_add(json_stat, "mlagPeerConnFlaps",
1966
0
            router->mlag_stats.peer_session_downs);
1967
0
    json_object_int_add(json_stat, "mlagPeerZebraFlaps",
1968
0
            router->mlag_stats.peer_zebra_downs);
1969
0
    json_object_int_add(json_stat, "mrouteAddRx",
1970
0
            router->mlag_stats.msg.mroute_add_rx);
1971
0
    json_object_int_add(json_stat, "mrouteAddTx",
1972
0
            router->mlag_stats.msg.mroute_add_tx);
1973
0
    json_object_int_add(json_stat, "mrouteDelRx",
1974
0
            router->mlag_stats.msg.mroute_del_rx);
1975
0
    json_object_int_add(json_stat, "mrouteDelTx",
1976
0
            router->mlag_stats.msg.mroute_del_tx);
1977
0
    json_object_int_add(json_stat, "mlagStatusUpdates",
1978
0
            router->mlag_stats.msg.mlag_status_updates);
1979
0
    json_object_int_add(json_stat, "peerZebraStatusUpdates",
1980
0
            router->mlag_stats.msg.peer_zebra_status_updates);
1981
0
    json_object_int_add(json_stat, "pimStatusUpdates",
1982
0
            router->mlag_stats.msg.pim_status_updates);
1983
0
    json_object_int_add(json_stat, "vxlanUpdates",
1984
0
            router->mlag_stats.msg.vxlan_updates);
1985
0
    json_object_object_add(json, "connStats", json_stat);
1986
1987
0
    vty_json(vty, json);
1988
0
    return CMD_SUCCESS;
1989
0
  }
1990
1991
0
  vty_out(vty, "MLAG daemon connection: %s\n",
1992
0
    (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
1993
0
    ? "up" : "down");
1994
0
  vty_out(vty, "MLAG peer state: %s\n",
1995
0
    (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
1996
0
    ? "up" : "down");
1997
0
  vty_out(vty, "Zebra peer state: %s\n",
1998
0
    (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
1999
0
    ? "up" : "down");
2000
0
  vty_out(vty, "MLAG role: %s\n",
2001
0
    mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
2002
0
  inet_ntop(AF_INET, &router->local_vtep_ip,
2003
0
      addr_buf, INET_ADDRSTRLEN);
2004
0
  vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
2005
0
  inet_ntop(AF_INET, &router->anycast_vtep_ip,
2006
0
      addr_buf, INET_ADDRSTRLEN);
2007
0
  vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
2008
0
  vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
2009
0
  vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
2010
0
    router->mlag_stats.mlagd_session_downs,
2011
0
    router->mlag_stats.peer_session_downs,
2012
0
    router->mlag_stats.peer_zebra_downs);
2013
0
  vty_out(vty, "Message Statistics:\n");
2014
0
  vty_out(vty, "  mroute adds: rx: %d, tx: %d\n",
2015
0
    router->mlag_stats.msg.mroute_add_rx,
2016
0
    router->mlag_stats.msg.mroute_add_tx);
2017
0
  vty_out(vty, "  mroute dels: rx: %d, tx: %d\n",
2018
0
    router->mlag_stats.msg.mroute_del_rx,
2019
0
    router->mlag_stats.msg.mroute_del_tx);
2020
0
  vty_out(vty, "  peer zebra status updates: %d\n",
2021
0
    router->mlag_stats.msg.peer_zebra_status_updates);
2022
0
  vty_out(vty, "  PIM status updates: %d\n",
2023
0
    router->mlag_stats.msg.pim_status_updates);
2024
0
  vty_out(vty, "  VxLAN updates: %d\n",
2025
0
    router->mlag_stats.msg.vxlan_updates);
2026
2027
0
  return CMD_SUCCESS;
2028
0
}
2029
2030
DEFUN (show_ip_pim_assert,
2031
       show_ip_pim_assert_cmd,
2032
       "show ip pim [vrf NAME] assert",
2033
       SHOW_STR
2034
       IP_STR
2035
       PIM_STR
2036
       VRF_CMD_HELP_STR
2037
       "PIM interface assert\n")
2038
0
{
2039
0
  int idx = 2;
2040
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
2041
2042
0
  if (!vrf)
2043
0
    return CMD_WARNING;
2044
2045
0
  pim_show_assert(vrf->info, vty);
2046
2047
0
  return CMD_SUCCESS;
2048
0
}
2049
2050
DEFUN (show_ip_pim_assert_internal,
2051
       show_ip_pim_assert_internal_cmd,
2052
       "show ip pim [vrf NAME] assert-internal",
2053
       SHOW_STR
2054
       IP_STR
2055
       PIM_STR
2056
       VRF_CMD_HELP_STR
2057
       "PIM interface internal assert state\n")
2058
0
{
2059
0
  int idx = 2;
2060
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
2061
2062
0
  if (!vrf)
2063
0
    return CMD_WARNING;
2064
2065
0
  pim_show_assert_internal(vrf->info, vty);
2066
2067
0
  return CMD_SUCCESS;
2068
0
}
2069
2070
DEFUN (show_ip_pim_assert_metric,
2071
       show_ip_pim_assert_metric_cmd,
2072
       "show ip pim [vrf NAME] assert-metric",
2073
       SHOW_STR
2074
       IP_STR
2075
       PIM_STR
2076
       VRF_CMD_HELP_STR
2077
       "PIM interface assert metric\n")
2078
0
{
2079
0
  int idx = 2;
2080
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
2081
2082
0
  if (!vrf)
2083
0
    return CMD_WARNING;
2084
2085
0
  pim_show_assert_metric(vrf->info, vty);
2086
2087
0
  return CMD_SUCCESS;
2088
0
}
2089
2090
DEFUN (show_ip_pim_assert_winner_metric,
2091
       show_ip_pim_assert_winner_metric_cmd,
2092
       "show ip pim [vrf NAME] assert-winner-metric",
2093
       SHOW_STR
2094
       IP_STR
2095
       PIM_STR
2096
       VRF_CMD_HELP_STR
2097
       "PIM interface assert winner metric\n")
2098
0
{
2099
0
  int idx = 2;
2100
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
2101
2102
0
  if (!vrf)
2103
0
    return CMD_WARNING;
2104
2105
0
  pim_show_assert_winner_metric(vrf->info, vty);
2106
2107
0
  return CMD_SUCCESS;
2108
0
}
2109
2110
DEFPY (show_ip_pim_interface,
2111
       show_ip_pim_interface_cmd,
2112
       "show ip pim [mlag$mlag] [vrf NAME] interface [detail|WORD]$interface [json$json]",
2113
       SHOW_STR
2114
       IP_STR
2115
       PIM_STR
2116
       "MLAG\n"
2117
       VRF_CMD_HELP_STR
2118
       "PIM interface information\n"
2119
       "Detailed output\n"
2120
       "interface name\n"
2121
       JSON_STR)
2122
0
{
2123
0
  return pim_show_interface_cmd_helper(vrf, vty, !!json, !!mlag,
2124
0
               interface);
2125
0
}
2126
2127
DEFPY (show_ip_pim_interface_vrf_all,
2128
       show_ip_pim_interface_vrf_all_cmd,
2129
       "show ip pim [mlag$mlag] vrf all interface [detail|WORD]$interface [json$json]",
2130
       SHOW_STR
2131
       IP_STR
2132
       PIM_STR
2133
       "MLAG\n"
2134
       VRF_CMD_HELP_STR
2135
       "PIM interface information\n"
2136
       "Detailed output\n"
2137
       "interface name\n"
2138
       JSON_STR)
2139
0
{
2140
0
  return pim_show_interface_vrf_all_cmd_helper(vty, !!json, !!mlag,
2141
0
                 interface);
2142
0
}
2143
2144
DEFPY (show_ip_pim_join,
2145
       show_ip_pim_join_cmd,
2146
       "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
2147
       SHOW_STR
2148
       IP_STR
2149
       PIM_STR
2150
       VRF_CMD_HELP_STR
2151
       "PIM interface join information\n"
2152
       "The Source or Group\n"
2153
       "The Group\n"
2154
       JSON_STR)
2155
0
{
2156
0
  return pim_show_join_cmd_helper(vrf, vty, s_or_g, g, json);
2157
0
}
2158
2159
DEFPY (show_ip_pim_join_vrf_all,
2160
       show_ip_pim_join_vrf_all_cmd,
2161
       "show ip pim vrf all join [json$json]",
2162
       SHOW_STR
2163
       IP_STR
2164
       PIM_STR
2165
       VRF_CMD_HELP_STR
2166
       "PIM interface join information\n"
2167
       JSON_STR)
2168
0
{
2169
0
  return pim_show_join_vrf_all_cmd_helper(vty, json);
2170
0
}
2171
2172
DEFPY (show_ip_pim_jp_agg,
2173
       show_ip_pim_jp_agg_cmd,
2174
       "show ip pim [vrf NAME] jp-agg",
2175
       SHOW_STR
2176
       IP_STR
2177
       PIM_STR
2178
       VRF_CMD_HELP_STR
2179
       "join prune aggregation list\n")
2180
0
{
2181
0
  return pim_show_jp_agg_list_cmd_helper(vrf, vty);
2182
0
}
2183
2184
DEFPY (show_ip_pim_local_membership,
2185
       show_ip_pim_local_membership_cmd,
2186
       "show ip pim [vrf NAME] local-membership [json$json]",
2187
       SHOW_STR
2188
       IP_STR
2189
       PIM_STR
2190
       VRF_CMD_HELP_STR
2191
       "PIM interface local-membership\n"
2192
       JSON_STR)
2193
0
{
2194
0
  return pim_show_membership_cmd_helper(vrf, vty, !!json);
2195
0
}
2196
2197
static void pim_show_mlag_up_entry_detail(struct vrf *vrf,
2198
            struct vty *vty,
2199
            struct pim_upstream *up,
2200
            char *src_str, char *grp_str,
2201
            json_object *json)
2202
0
{
2203
0
  if (json) {
2204
0
    json_object *json_row = NULL;
2205
0
    json_object *own_list = NULL;
2206
0
    json_object *json_group = NULL;
2207
2208
2209
0
    json_object_object_get_ex(json, grp_str, &json_group);
2210
0
    if (!json_group) {
2211
0
      json_group = json_object_new_object();
2212
0
      json_object_object_add(json, grp_str,
2213
0
                 json_group);
2214
0
    }
2215
2216
0
    json_row = json_object_new_object();
2217
0
    json_object_string_add(json_row, "source", src_str);
2218
0
    json_object_string_add(json_row, "group", grp_str);
2219
2220
0
    own_list = json_object_new_array();
2221
0
    if (pim_up_mlag_is_local(up))
2222
0
      json_object_array_add(own_list,
2223
0
                json_object_new_string("local"));
2224
0
    if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
2225
0
      json_object_array_add(own_list,
2226
0
                json_object_new_string("peer"));
2227
0
    if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
2228
0
      json_object_array_add(
2229
0
        own_list, json_object_new_string("Interface"));
2230
0
    json_object_object_add(json_row, "owners", own_list);
2231
2232
0
    json_object_int_add(json_row, "localCost",
2233
0
            pim_up_mlag_local_cost(up));
2234
0
    json_object_int_add(json_row, "peerCost",
2235
0
            pim_up_mlag_peer_cost(up));
2236
0
    if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
2237
0
      json_object_boolean_false_add(json_row, "df");
2238
0
    else
2239
0
      json_object_boolean_true_add(json_row, "df");
2240
0
    json_object_object_add(json_group, src_str, json_row);
2241
0
  } else {
2242
0
    char own_str[6];
2243
2244
0
    own_str[0] = '\0';
2245
0
    if (pim_up_mlag_is_local(up))
2246
0
      strlcat(own_str, "L", sizeof(own_str));
2247
0
    if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
2248
0
      strlcat(own_str, "P", sizeof(own_str));
2249
0
    if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
2250
0
      strlcat(own_str, "I", sizeof(own_str));
2251
    /* XXX - fixup, print paragraph output */
2252
0
    vty_out(vty,
2253
0
      "%-15s %-15s %-6s %-11u %-10d %2s\n",
2254
0
      src_str, grp_str, own_str,
2255
0
      pim_up_mlag_local_cost(up),
2256
0
      pim_up_mlag_peer_cost(up),
2257
0
      PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
2258
0
      ? "n" : "y");
2259
0
  }
2260
0
}
2261
2262
static void pim_show_mlag_up_detail(struct vrf *vrf,
2263
            struct vty *vty, const char *src_or_group,
2264
            const char *group, bool uj)
2265
0
{
2266
0
  char src_str[PIM_ADDRSTRLEN];
2267
0
  char grp_str[PIM_ADDRSTRLEN];
2268
0
  struct pim_upstream *up;
2269
0
  struct pim_instance *pim = vrf->info;
2270
0
  json_object *json = NULL;
2271
2272
0
  if (uj)
2273
0
    json = json_object_new_object();
2274
0
  else
2275
0
    vty_out(vty,
2276
0
      "Source          Group           Owner  Local-cost  Peer-cost  DF\n");
2277
2278
0
  frr_each (rb_pim_upstream, &pim->upstream_head, up) {
2279
0
    if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
2280
0
        && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
2281
0
        && !pim_up_mlag_is_local(up))
2282
0
      continue;
2283
2284
0
    snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
2285
0
    snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
2286
2287
    /* XXX: strcmps are clearly inefficient. we should do uint comps
2288
     * here instead.
2289
     */
2290
0
    if (group) {
2291
0
      if (strcmp(src_str, src_or_group) ||
2292
0
          strcmp(grp_str, group))
2293
0
        continue;
2294
0
    } else {
2295
0
      if (strcmp(src_str, src_or_group) &&
2296
0
          strcmp(grp_str, src_or_group))
2297
0
        continue;
2298
0
    }
2299
0
    pim_show_mlag_up_entry_detail(vrf, vty, up,
2300
0
                src_str, grp_str, json);
2301
0
  }
2302
2303
0
  if (uj)
2304
0
    vty_json(vty, json);
2305
0
}
2306
2307
static void pim_show_mlag_up_vrf(struct vrf *vrf, struct vty *vty, bool uj)
2308
0
{
2309
0
  json_object *json = NULL;
2310
0
  json_object *json_row;
2311
0
  struct pim_upstream *up;
2312
0
  struct pim_instance *pim = vrf->info;
2313
0
  json_object *json_group = NULL;
2314
2315
0
  if (uj) {
2316
0
    json = json_object_new_object();
2317
0
  } else {
2318
0
    vty_out(vty,
2319
0
      "Source          Group           Owner  Local-cost  Peer-cost  DF\n");
2320
0
  }
2321
2322
0
  frr_each (rb_pim_upstream, &pim->upstream_head, up) {
2323
0
    if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
2324
0
        && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
2325
0
        && !pim_up_mlag_is_local(up))
2326
0
      continue;
2327
0
    if (uj) {
2328
0
      char src_str[PIM_ADDRSTRLEN];
2329
0
      char grp_str[PIM_ADDRSTRLEN];
2330
0
      json_object *own_list = NULL;
2331
2332
0
      snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
2333
0
           &up->sg.grp);
2334
0
      snprintfrr(src_str, sizeof(src_str), "%pPAs",
2335
0
           &up->sg.src);
2336
2337
0
      json_object_object_get_ex(json, grp_str, &json_group);
2338
0
      if (!json_group) {
2339
0
        json_group = json_object_new_object();
2340
0
        json_object_object_add(json, grp_str,
2341
0
                   json_group);
2342
0
      }
2343
2344
0
      json_row = json_object_new_object();
2345
0
      json_object_string_add(json_row, "vrf", vrf->name);
2346
0
      json_object_string_add(json_row, "source", src_str);
2347
0
      json_object_string_add(json_row, "group", grp_str);
2348
2349
0
      own_list = json_object_new_array();
2350
0
      if (pim_up_mlag_is_local(up)) {
2351
2352
0
        json_object_array_add(own_list,
2353
0
                  json_object_new_string(
2354
0
                    "local"));
2355
0
      }
2356
0
      if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)) {
2357
0
        json_object_array_add(own_list,
2358
0
                  json_object_new_string(
2359
0
                    "peer"));
2360
0
      }
2361
0
      json_object_object_add(json_row, "owners", own_list);
2362
2363
0
      json_object_int_add(json_row, "localCost",
2364
0
              pim_up_mlag_local_cost(up));
2365
0
      json_object_int_add(json_row, "peerCost",
2366
0
              pim_up_mlag_peer_cost(up));
2367
0
      if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
2368
0
        json_object_boolean_false_add(json_row, "df");
2369
0
      else
2370
0
        json_object_boolean_true_add(json_row, "df");
2371
0
      json_object_object_add(json_group, src_str, json_row);
2372
0
    } else {
2373
0
      char own_str[6];
2374
2375
0
      own_str[0] = '\0';
2376
0
      if (pim_up_mlag_is_local(up))
2377
0
        strlcat(own_str, "L", sizeof(own_str));
2378
0
      if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
2379
0
        strlcat(own_str, "P", sizeof(own_str));
2380
0
      if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
2381
0
        strlcat(own_str, "I", sizeof(own_str));
2382
0
      vty_out(vty,
2383
0
        "%-15pPAs %-15pPAs %-6s %-11u %-10u %2s\n",
2384
0
        &up->sg.src, &up->sg.grp, own_str,
2385
0
        pim_up_mlag_local_cost(up),
2386
0
        pim_up_mlag_peer_cost(up),
2387
0
        PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
2388
0
        ? "n" : "y");
2389
0
    }
2390
0
  }
2391
0
  if (uj)
2392
0
    vty_json(vty, json);
2393
0
}
2394
2395
static void pim_show_mlag_help_string(struct vty *vty, bool uj)
2396
0
{
2397
0
  if (!uj) {
2398
0
    vty_out(vty, "Owner codes:\n");
2399
0
    vty_out(vty,
2400
0
      "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
2401
0
  }
2402
0
}
2403
2404
2405
DEFUN(show_ip_pim_mlag_up, show_ip_pim_mlag_up_cmd,
2406
      "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
2407
      SHOW_STR
2408
      IP_STR
2409
      PIM_STR
2410
      VRF_CMD_HELP_STR
2411
      "MLAG\n"
2412
      "upstream\n"
2413
      "Unicast or Multicast address\n"
2414
      "Multicast address\n" JSON_STR)
2415
0
{
2416
0
  const char *src_or_group = NULL;
2417
0
  const char *group = NULL;
2418
0
  int idx = 2;
2419
0
  bool uj = use_json(argc, argv);
2420
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
2421
2422
0
  if (!vrf || !vrf->info) {
2423
0
    vty_out(vty, "%s: VRF or Info missing\n", __func__);
2424
0
    return CMD_WARNING;
2425
0
  }
2426
2427
0
  if (uj)
2428
0
    argc--;
2429
2430
0
  if (argv_find(argv, argc, "A.B.C.D", &idx)) {
2431
0
    src_or_group = argv[idx]->arg;
2432
0
    if (idx + 1 < argc)
2433
0
      group = argv[idx + 1]->arg;
2434
0
  }
2435
2436
0
  pim_show_mlag_help_string(vty, uj);
2437
2438
0
  if (src_or_group)
2439
0
    pim_show_mlag_up_detail(vrf, vty, src_or_group, group, uj);
2440
0
  else
2441
0
    pim_show_mlag_up_vrf(vrf, vty, uj);
2442
2443
0
  return CMD_SUCCESS;
2444
0
}
2445
2446
2447
DEFUN(show_ip_pim_mlag_up_vrf_all, show_ip_pim_mlag_up_vrf_all_cmd,
2448
      "show ip pim vrf all mlag upstream [json]",
2449
      SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
2450
      "MLAG\n"
2451
      "upstream\n" JSON_STR)
2452
0
{
2453
0
  struct vrf *vrf;
2454
0
  bool uj = use_json(argc, argv);
2455
2456
0
  pim_show_mlag_help_string(vty, uj);
2457
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2458
0
    pim_show_mlag_up_vrf(vrf, vty, uj);
2459
0
  }
2460
2461
0
  return CMD_SUCCESS;
2462
0
}
2463
2464
DEFPY (show_ip_pim_neighbor,
2465
       show_ip_pim_neighbor_cmd,
2466
       "show ip pim [vrf NAME] neighbor [detail|WORD]$interface [json$json]",
2467
       SHOW_STR
2468
       IP_STR
2469
       PIM_STR
2470
       VRF_CMD_HELP_STR
2471
       "PIM neighbor information\n"
2472
       "Detailed output\n"
2473
       "Name of interface or neighbor\n"
2474
       JSON_STR)
2475
0
{
2476
0
  return pim_show_neighbors_cmd_helper(vrf, vty, json, interface);
2477
0
}
2478
2479
DEFPY (show_ip_pim_neighbor_vrf_all,
2480
       show_ip_pim_neighbor_vrf_all_cmd,
2481
       "show ip pim vrf all neighbor [detail|WORD]$interface [json$json]",
2482
       SHOW_STR
2483
       IP_STR
2484
       PIM_STR
2485
       VRF_CMD_HELP_STR
2486
       "PIM neighbor information\n"
2487
       "Detailed output\n"
2488
       "Name of interface or neighbor\n"
2489
       JSON_STR)
2490
0
{
2491
0
  return pim_show_neighbors_vrf_all_cmd_helper(vty, json, interface);
2492
0
}
2493
2494
DEFPY (show_ip_pim_secondary,
2495
       show_ip_pim_secondary_cmd,
2496
       "show ip pim [vrf NAME] secondary",
2497
       SHOW_STR
2498
       IP_STR
2499
       PIM_STR
2500
       VRF_CMD_HELP_STR
2501
       "PIM neighbor addresses\n")
2502
0
{
2503
0
  return pim_show_secondary_helper(vrf, vty);
2504
0
}
2505
2506
DEFPY (show_ip_pim_state,
2507
       show_ip_pim_state_cmd,
2508
       "show ip pim [vrf NAME] state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
2509
       SHOW_STR
2510
       IP_STR
2511
       PIM_STR
2512
       VRF_CMD_HELP_STR
2513
       "PIM state information\n"
2514
       "Unicast or Multicast address\n"
2515
       "Multicast address\n"
2516
       JSON_STR)
2517
0
{
2518
0
  return pim_show_state_helper(vrf, vty, s_or_g_str, g_str, !!json);
2519
0
}
2520
2521
DEFPY (show_ip_pim_state_vrf_all,
2522
       show_ip_pim_state_vrf_all_cmd,
2523
       "show ip pim vrf all state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
2524
       SHOW_STR
2525
       IP_STR
2526
       PIM_STR
2527
       VRF_CMD_HELP_STR
2528
       "PIM state information\n"
2529
       "Unicast or Multicast address\n"
2530
       "Multicast address\n"
2531
       JSON_STR)
2532
0
{
2533
0
  return pim_show_state_vrf_all_helper(vty, s_or_g_str, g_str, !!json);
2534
0
}
2535
2536
DEFPY (show_ip_pim_upstream,
2537
       show_ip_pim_upstream_cmd,
2538
       "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
2539
       SHOW_STR
2540
       IP_STR
2541
       PIM_STR
2542
       VRF_CMD_HELP_STR
2543
       "PIM upstream information\n"
2544
       "The Source or Group\n"
2545
       "The Group\n"
2546
       JSON_STR)
2547
0
{
2548
0
  return pim_show_upstream_helper(vrf, vty, s_or_g, g, !!json);
2549
0
}
2550
2551
DEFPY (show_ip_pim_upstream_vrf_all,
2552
       show_ip_pim_upstream_vrf_all_cmd,
2553
       "show ip pim vrf all upstream [json$json]",
2554
       SHOW_STR
2555
       IP_STR
2556
       PIM_STR
2557
       VRF_CMD_HELP_STR
2558
       "PIM upstream information\n"
2559
       JSON_STR)
2560
0
{
2561
0
  return pim_show_upstream_vrf_all_helper(vty, !!json);
2562
0
}
2563
2564
DEFPY (show_ip_pim_channel,
2565
       show_ip_pim_channel_cmd,
2566
       "show ip pim [vrf NAME] channel [json$json]",
2567
       SHOW_STR
2568
       IP_STR
2569
       PIM_STR
2570
       VRF_CMD_HELP_STR
2571
       "PIM downstream channel info\n"
2572
       JSON_STR)
2573
0
{
2574
0
  return pim_show_channel_cmd_helper(vrf, vty, !!json);
2575
0
}
2576
2577
DEFPY (show_ip_pim_upstream_join_desired,
2578
       show_ip_pim_upstream_join_desired_cmd,
2579
       "show ip pim [vrf NAME] upstream-join-desired [json$json]",
2580
       SHOW_STR
2581
       IP_STR
2582
       PIM_STR
2583
       VRF_CMD_HELP_STR
2584
       "PIM upstream join-desired\n"
2585
       JSON_STR)
2586
0
{
2587
0
  return pim_show_upstream_join_desired_helper(vrf, vty, !!json);
2588
0
}
2589
2590
DEFPY (show_ip_pim_upstream_rpf,
2591
       show_ip_pim_upstream_rpf_cmd,
2592
       "show ip pim [vrf NAME] upstream-rpf [json$json]",
2593
       SHOW_STR
2594
       IP_STR
2595
       PIM_STR
2596
       VRF_CMD_HELP_STR
2597
       "PIM upstream source rpf\n"
2598
       JSON_STR)
2599
0
{
2600
0
  return pim_show_upstream_rpf_helper(vrf, vty, !!json);
2601
0
}
2602
2603
DEFPY (show_ip_pim_rp,
2604
       show_ip_pim_rp_cmd,
2605
       "show ip pim [vrf NAME] rp-info [A.B.C.D/M$group] [json$json]",
2606
       SHOW_STR
2607
       IP_STR
2608
       PIM_STR
2609
       VRF_CMD_HELP_STR
2610
       "PIM RP information\n"
2611
       "Multicast Group range\n"
2612
       JSON_STR)
2613
0
{
2614
0
  return pim_show_rp_helper(vrf, vty, group_str, (struct prefix *)group,
2615
0
          !!json);
2616
0
}
2617
2618
DEFPY (show_ip_pim_rp_vrf_all,
2619
       show_ip_pim_rp_vrf_all_cmd,
2620
       "show ip pim vrf all rp-info [A.B.C.D/M$group] [json$json]",
2621
       SHOW_STR
2622
       IP_STR
2623
       PIM_STR
2624
       VRF_CMD_HELP_STR
2625
       "PIM RP information\n"
2626
       "Multicast Group range\n"
2627
       JSON_STR)
2628
0
{
2629
0
  return pim_show_rp_vrf_all_helper(vty, group_str,
2630
0
            (struct prefix *)group, !!json);
2631
0
}
2632
2633
DEFPY (show_ip_pim_rpf,
2634
       show_ip_pim_rpf_cmd,
2635
       "show ip pim [vrf NAME] rpf [json$json]",
2636
       SHOW_STR
2637
       IP_STR
2638
       PIM_STR
2639
       VRF_CMD_HELP_STR
2640
       "PIM cached source rpf information\n"
2641
       JSON_STR)
2642
0
{
2643
0
  return pim_show_rpf_helper(vrf, vty, !!json);
2644
0
}
2645
2646
DEFPY (show_ip_pim_rpf_vrf_all,
2647
       show_ip_pim_rpf_vrf_all_cmd,
2648
       "show ip pim vrf all rpf [json$json]",
2649
       SHOW_STR
2650
       IP_STR
2651
       PIM_STR
2652
       VRF_CMD_HELP_STR
2653
       "PIM cached source rpf information\n"
2654
       JSON_STR)
2655
0
{
2656
0
  return pim_show_rpf_vrf_all_helper(vty, !!json);
2657
0
}
2658
2659
DEFPY (show_ip_pim_nexthop,
2660
       show_ip_pim_nexthop_cmd,
2661
       "show ip pim [vrf NAME] nexthop [json$json]",
2662
       SHOW_STR
2663
       IP_STR
2664
       PIM_STR
2665
       VRF_CMD_HELP_STR
2666
       "PIM cached nexthop rpf information\n"
2667
       JSON_STR)
2668
0
{
2669
0
  return pim_show_nexthop_cmd_helper(vrf, vty, !!json);
2670
0
}
2671
2672
DEFPY (show_ip_pim_nexthop_lookup,
2673
       show_ip_pim_nexthop_lookup_cmd,
2674
       "show ip pim [vrf NAME] nexthop-lookup A.B.C.D$source A.B.C.D$group",
2675
       SHOW_STR
2676
       IP_STR
2677
       PIM_STR
2678
       VRF_CMD_HELP_STR
2679
       "PIM cached nexthop rpf lookup\n"
2680
       "Source/RP address\n"
2681
       "Multicast Group address\n")
2682
0
{
2683
0
  return pim_show_nexthop_lookup_cmd_helper(vrf, vty, source, group);
2684
0
}
2685
2686
DEFPY (show_ip_pim_interface_traffic,
2687
       show_ip_pim_interface_traffic_cmd,
2688
       "show ip pim [vrf NAME] interface traffic [WORD$if_name] [json$json]",
2689
       SHOW_STR
2690
       IP_STR
2691
       PIM_STR
2692
       VRF_CMD_HELP_STR
2693
       "PIM interface information\n"
2694
       "Protocol Packet counters\n"
2695
       "Interface name\n"
2696
       JSON_STR)
2697
0
{
2698
0
  return pim_show_interface_traffic_helper(vrf, if_name, vty, !!json);
2699
0
}
2700
2701
DEFPY (show_ip_pim_bsm_db,
2702
       show_ip_pim_bsm_db_cmd,
2703
       "show ip pim bsm-database [vrf NAME] [json$json]",
2704
       SHOW_STR
2705
       IP_STR
2706
       PIM_STR
2707
       "PIM cached bsm packets information\n"
2708
       VRF_CMD_HELP_STR
2709
       JSON_STR)
2710
0
{
2711
0
  return pim_show_bsm_db_helper(vrf, vty, !!json);
2712
0
}
2713
2714
DEFPY (show_ip_pim_bsrp,
2715
       show_ip_pim_bsrp_cmd,
2716
       "show ip pim bsrp-info [vrf NAME] [json$json]",
2717
       SHOW_STR
2718
       IP_STR
2719
       PIM_STR
2720
       "PIM cached group-rp mappings information\n"
2721
       VRF_CMD_HELP_STR
2722
       JSON_STR)
2723
0
{
2724
0
  return pim_show_group_rp_mappings_info_helper(vrf, vty, !!json);
2725
0
}
2726
2727
DEFPY (show_ip_pim_statistics,
2728
       show_ip_pim_statistics_cmd,
2729
       "show ip pim [vrf NAME] statistics [interface WORD$word] [json$json]",
2730
       SHOW_STR
2731
       IP_STR
2732
       PIM_STR
2733
       VRF_CMD_HELP_STR
2734
       "PIM statistics\n"
2735
       INTERFACE_STR
2736
       "PIM interface\n"
2737
       JSON_STR)
2738
0
{
2739
0
  return pim_show_statistics_helper(vrf, vty, word, !!json);
2740
0
}
2741
2742
DEFPY (show_ip_multicast,
2743
       show_ip_multicast_cmd,
2744
       "show ip multicast [vrf NAME]",
2745
       SHOW_STR
2746
       IP_STR
2747
       "Multicast global information\n"
2748
       VRF_CMD_HELP_STR)
2749
0
{
2750
0
  return pim_show_multicast_helper(vrf, vty);
2751
0
}
2752
2753
DEFPY (show_ip_multicast_vrf_all,
2754
       show_ip_multicast_vrf_all_cmd,
2755
       "show ip multicast vrf all",
2756
       SHOW_STR
2757
       IP_STR
2758
       "Multicast global information\n"
2759
       VRF_CMD_HELP_STR)
2760
0
{
2761
0
  return pim_show_multicast_vrf_all_helper(vty);
2762
0
}
2763
2764
DEFPY (show_ip_multicast_count,
2765
       show_ip_multicast_count_cmd,
2766
       "show ip multicast count [vrf NAME] [json$json]",
2767
       SHOW_STR
2768
       IP_STR
2769
       "Multicast global information\n"
2770
       "Data packet count\n"
2771
       VRF_CMD_HELP_STR
2772
       JSON_STR)
2773
0
{
2774
0
  return pim_show_multicast_count_helper(vrf, vty, !!json);
2775
0
}
2776
2777
DEFPY (show_ip_multicast_count_vrf_all,
2778
       show_ip_multicast_count_vrf_all_cmd,
2779
       "show ip multicast count vrf all [json$json]",
2780
       SHOW_STR
2781
       IP_STR
2782
       "Multicast global information\n"
2783
       "Data packet count\n"
2784
       VRF_CMD_HELP_STR
2785
       JSON_STR)
2786
0
{
2787
0
  return pim_show_multicast_count_vrf_all_helper(vty, !!json);
2788
0
}
2789
2790
DEFPY (show_ip_mroute,
2791
       show_ip_mroute_cmd,
2792
       "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
2793
       SHOW_STR
2794
       IP_STR
2795
       MROUTE_STR
2796
       VRF_CMD_HELP_STR
2797
       "The Source or Group\n"
2798
       "The Group\n"
2799
       "Fill in Assumed data\n"
2800
       JSON_STR)
2801
0
{
2802
0
  return pim_show_mroute_helper(vrf, vty, s_or_g, g, !!fill, !!json);
2803
0
}
2804
2805
DEFPY (show_ip_mroute_vrf_all,
2806
       show_ip_mroute_vrf_all_cmd,
2807
       "show ip mroute vrf all [fill$fill] [json$json]",
2808
       SHOW_STR
2809
       IP_STR
2810
       MROUTE_STR
2811
       VRF_CMD_HELP_STR
2812
       "Fill in Assumed data\n"
2813
       JSON_STR)
2814
0
{
2815
0
  return pim_show_mroute_vrf_all_helper(vty, !!fill, !!json);
2816
0
}
2817
2818
DEFPY (clear_ip_mroute_count,
2819
       clear_ip_mroute_count_cmd,
2820
       "clear ip mroute [vrf NAME]$name count",
2821
       CLEAR_STR
2822
       IP_STR
2823
       MROUTE_STR
2824
       VRF_CMD_HELP_STR
2825
       "Route and packet count data\n")
2826
0
{
2827
0
  return clear_ip_mroute_count_command(vty, name);
2828
0
}
2829
2830
DEFPY (show_ip_mroute_count,
2831
       show_ip_mroute_count_cmd,
2832
       "show ip mroute [vrf NAME] count [json$json]",
2833
       SHOW_STR
2834
       IP_STR
2835
       MROUTE_STR
2836
       VRF_CMD_HELP_STR
2837
       "Route and packet count data\n"
2838
       JSON_STR)
2839
0
{
2840
0
  return pim_show_mroute_count_helper(vrf, vty, !!json);
2841
0
}
2842
2843
DEFPY (show_ip_mroute_count_vrf_all,
2844
       show_ip_mroute_count_vrf_all_cmd,
2845
       "show ip mroute vrf all count [json$json]",
2846
       SHOW_STR
2847
       IP_STR
2848
       MROUTE_STR
2849
       VRF_CMD_HELP_STR
2850
       "Route and packet count data\n"
2851
       JSON_STR)
2852
0
{
2853
0
  return pim_show_mroute_count_vrf_all_helper(vty, !!json);
2854
0
}
2855
2856
DEFPY (show_ip_mroute_summary,
2857
       show_ip_mroute_summary_cmd,
2858
       "show ip mroute [vrf NAME] summary [json$json]",
2859
       SHOW_STR
2860
       IP_STR
2861
       MROUTE_STR
2862
       VRF_CMD_HELP_STR
2863
       "Summary of all mroutes\n"
2864
       JSON_STR)
2865
0
{
2866
0
  return pim_show_mroute_summary_helper(vrf, vty, !!json);
2867
0
}
2868
2869
DEFPY (show_ip_mroute_summary_vrf_all,
2870
       show_ip_mroute_summary_vrf_all_cmd,
2871
       "show ip mroute vrf all summary [json$json]",
2872
       SHOW_STR
2873
       IP_STR
2874
       MROUTE_STR
2875
       VRF_CMD_HELP_STR
2876
       "Summary of all mroutes\n"
2877
       JSON_STR)
2878
0
{
2879
0
  return pim_show_mroute_summary_vrf_all_helper(vty, !!json);
2880
0
}
2881
2882
DEFUN (show_ip_rib,
2883
       show_ip_rib_cmd,
2884
       "show ip rib [vrf NAME] A.B.C.D",
2885
       SHOW_STR
2886
       IP_STR
2887
       RIB_STR
2888
       VRF_CMD_HELP_STR
2889
       "Unicast address\n")
2890
0
{
2891
0
  int idx = 2;
2892
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
2893
0
  struct in_addr addr;
2894
0
  const char *addr_str;
2895
0
  struct pim_nexthop nexthop;
2896
0
  int result;
2897
2898
0
  if (!vrf)
2899
0
    return CMD_WARNING;
2900
2901
0
  memset(&nexthop, 0, sizeof(nexthop));
2902
0
  argv_find(argv, argc, "A.B.C.D", &idx);
2903
0
  addr_str = argv[idx]->arg;
2904
0
  result = inet_pton(AF_INET, addr_str, &addr);
2905
0
  if (result <= 0) {
2906
0
    vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
2907
0
      errno, safe_strerror(errno));
2908
0
    return CMD_WARNING;
2909
0
  }
2910
2911
0
  if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
2912
0
    vty_out(vty,
2913
0
      "Failure querying RIB nexthop for unicast address %s\n",
2914
0
      addr_str);
2915
0
    return CMD_WARNING;
2916
0
  }
2917
2918
0
  vty_out(vty,
2919
0
    "Address         NextHop         Interface Metric Preference\n");
2920
2921
0
  vty_out(vty, "%-15s %-15pPAs %-9s %6d %10d\n", addr_str,
2922
0
    &nexthop.mrib_nexthop_addr,
2923
0
    nexthop.interface ? nexthop.interface->name : "<ifname?>",
2924
0
    nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
2925
2926
0
  return CMD_SUCCESS;
2927
0
}
2928
2929
static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
2930
0
{
2931
0
  struct listnode *node;
2932
0
  struct ssmpingd_sock *ss;
2933
0
  time_t now;
2934
2935
0
  vty_out(vty,
2936
0
    "Source          Socket Address          Port Uptime   Requests\n");
2937
2938
0
  if (!pim->ssmpingd_list)
2939
0
    return;
2940
2941
0
  now = pim_time_monotonic_sec();
2942
2943
0
  for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
2944
0
    char source_str[INET_ADDRSTRLEN];
2945
0
    char ss_uptime[10];
2946
0
    struct sockaddr_in bind_addr;
2947
0
    socklen_t len = sizeof(bind_addr);
2948
0
    char bind_addr_str[INET_ADDRSTRLEN];
2949
2950
0
    pim_inet4_dump("<src?>", ss->source_addr, source_str,
2951
0
             sizeof(source_str));
2952
2953
0
    if (pim_socket_getsockname(
2954
0
          ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
2955
0
      vty_out(vty,
2956
0
        "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
2957
0
        source_str, ss->sock_fd);
2958
0
    }
2959
2960
0
    pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
2961
0
             sizeof(bind_addr_str));
2962
0
    pim_time_uptime(ss_uptime, sizeof(ss_uptime),
2963
0
        now - ss->creation);
2964
2965
0
    vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
2966
0
      ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
2967
0
      ss_uptime, (long long)ss->requests);
2968
0
  }
2969
0
}
2970
2971
DEFUN (show_ip_ssmpingd,
2972
       show_ip_ssmpingd_cmd,
2973
       "show ip ssmpingd [vrf NAME]",
2974
       SHOW_STR
2975
       IP_STR
2976
       SHOW_SSMPINGD_STR
2977
       VRF_CMD_HELP_STR)
2978
0
{
2979
0
  int idx = 2;
2980
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, false);
2981
2982
0
  if (!vrf)
2983
0
    return CMD_WARNING;
2984
2985
0
  show_ssmpingd(vrf->info, vty);
2986
0
  return CMD_SUCCESS;
2987
0
}
2988
2989
DEFUN (ip_pim_spt_switchover_infinity,
2990
       ip_pim_spt_switchover_infinity_cmd,
2991
       "ip pim spt-switchover infinity-and-beyond",
2992
       IP_STR
2993
       PIM_STR
2994
       "SPT-Switchover\n"
2995
       "Never switch to SPT Tree\n")
2996
0
{
2997
0
  return pim_process_spt_switchover_infinity_cmd(vty);
2998
0
}
2999
3000
DEFPY (ip_pim_spt_switchover_infinity_plist,
3001
       ip_pim_spt_switchover_infinity_plist_cmd,
3002
       "ip pim spt-switchover infinity-and-beyond prefix-list WORD$plist",
3003
       IP_STR
3004
       PIM_STR
3005
       "SPT-Switchover\n"
3006
       "Never switch to SPT Tree\n"
3007
       "Prefix-List to control which groups to switch\n"
3008
       "Prefix-List name\n")
3009
0
{
3010
0
  return pim_process_spt_switchover_prefixlist_cmd(vty, plist);
3011
0
}
3012
3013
DEFUN (no_ip_pim_spt_switchover_infinity,
3014
       no_ip_pim_spt_switchover_infinity_cmd,
3015
       "no ip pim spt-switchover infinity-and-beyond",
3016
       NO_STR
3017
       IP_STR
3018
       PIM_STR
3019
       "SPT_Switchover\n"
3020
       "Never switch to SPT Tree\n")
3021
0
{
3022
0
  return pim_process_no_spt_switchover_cmd(vty);
3023
0
}
3024
3025
DEFUN (no_ip_pim_spt_switchover_infinity_plist,
3026
       no_ip_pim_spt_switchover_infinity_plist_cmd,
3027
       "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
3028
       NO_STR
3029
       IP_STR
3030
       PIM_STR
3031
       "SPT_Switchover\n"
3032
       "Never switch to SPT Tree\n"
3033
       "Prefix-List to control which groups to switch\n"
3034
       "Prefix-List name\n")
3035
0
{
3036
0
  return pim_process_no_spt_switchover_cmd(vty);
3037
0
}
3038
3039
DEFPY (pim_register_accept_list,
3040
       pim_register_accept_list_cmd,
3041
       "[no] ip pim register-accept-list WORD$word",
3042
       NO_STR
3043
       IP_STR
3044
       PIM_STR
3045
       "Only accept registers from a specific source prefix list\n"
3046
       "Prefix-List name\n")
3047
0
{
3048
0
  const char *vrfname;
3049
0
  char reg_alist_xpath[XPATH_MAXLEN];
3050
3051
0
  vrfname = pim_cli_get_vrf_name(vty);
3052
0
  if (vrfname == NULL)
3053
0
    return CMD_WARNING_CONFIG_FAILED;
3054
3055
0
  snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
3056
0
     FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
3057
0
     "frr-routing:ipv4");
3058
0
  strlcat(reg_alist_xpath, "/register-accept-list",
3059
0
    sizeof(reg_alist_xpath));
3060
3061
0
  if (no)
3062
0
    nb_cli_enqueue_change(vty, reg_alist_xpath,
3063
0
              NB_OP_DESTROY, NULL);
3064
0
  else
3065
0
    nb_cli_enqueue_change(vty, reg_alist_xpath,
3066
0
              NB_OP_MODIFY, word);
3067
3068
0
  return nb_cli_apply_changes(vty, NULL);
3069
0
}
3070
3071
DEFPY (ip_pim_joinprune_time,
3072
       ip_pim_joinprune_time_cmd,
3073
       "ip pim join-prune-interval (1-65535)$jpi",
3074
       IP_STR
3075
       "pim multicast routing\n"
3076
       "Join Prune Send Interval\n"
3077
       "Seconds\n")
3078
0
{
3079
0
  return pim_process_join_prune_cmd(vty, jpi_str);
3080
0
}
3081
3082
DEFUN (no_ip_pim_joinprune_time,
3083
       no_ip_pim_joinprune_time_cmd,
3084
       "no ip pim join-prune-interval [(1-65535)]",
3085
       NO_STR
3086
       IP_STR
3087
       "pim multicast routing\n"
3088
       "Join Prune Send Interval\n"
3089
       IGNORED_IN_NO_STR)
3090
0
{
3091
0
  return pim_process_no_join_prune_cmd(vty);
3092
0
}
3093
3094
DEFPY (ip_pim_register_suppress,
3095
       ip_pim_register_suppress_cmd,
3096
       "ip pim register-suppress-time (1-65535)$rst",
3097
       IP_STR
3098
       "pim multicast routing\n"
3099
       "Register Suppress Timer\n"
3100
       "Seconds\n")
3101
0
{
3102
0
  return pim_process_register_suppress_cmd(vty, rst_str);
3103
0
}
3104
3105
DEFUN (no_ip_pim_register_suppress,
3106
       no_ip_pim_register_suppress_cmd,
3107
       "no ip pim register-suppress-time [(1-65535)]",
3108
       NO_STR
3109
       IP_STR
3110
       "pim multicast routing\n"
3111
       "Register Suppress Timer\n"
3112
       IGNORED_IN_NO_STR)
3113
0
{
3114
0
  return pim_process_no_register_suppress_cmd(vty);
3115
0
}
3116
3117
DEFPY (ip_pim_rp_keep_alive,
3118
       ip_pim_rp_keep_alive_cmd,
3119
       "ip pim rp keep-alive-timer (1-65535)$kat",
3120
       IP_STR
3121
       "pim multicast routing\n"
3122
       "Rendezvous Point\n"
3123
       "Keep alive Timer\n"
3124
       "Seconds\n")
3125
0
{
3126
0
  return pim_process_rp_kat_cmd(vty, kat_str);
3127
0
}
3128
3129
DEFUN (no_ip_pim_rp_keep_alive,
3130
       no_ip_pim_rp_keep_alive_cmd,
3131
       "no ip pim rp keep-alive-timer [(1-65535)]",
3132
       NO_STR
3133
       IP_STR
3134
       "pim multicast routing\n"
3135
       "Rendezvous Point\n"
3136
       "Keep alive Timer\n"
3137
       IGNORED_IN_NO_STR)
3138
0
{
3139
0
  return pim_process_no_rp_kat_cmd(vty);
3140
0
}
3141
3142
DEFPY (ip_pim_keep_alive,
3143
       ip_pim_keep_alive_cmd,
3144
       "ip pim keep-alive-timer (1-65535)$kat",
3145
       IP_STR
3146
       "pim multicast routing\n"
3147
       "Keep alive Timer\n"
3148
       "Seconds\n")
3149
0
{
3150
0
  return pim_process_keepalivetimer_cmd(vty, kat_str);
3151
0
}
3152
3153
DEFUN (no_ip_pim_keep_alive,
3154
       no_ip_pim_keep_alive_cmd,
3155
       "no ip pim keep-alive-timer [(1-65535)]",
3156
       NO_STR
3157
       IP_STR
3158
       "pim multicast routing\n"
3159
       "Keep alive Timer\n"
3160
       IGNORED_IN_NO_STR)
3161
0
{
3162
0
  return pim_process_no_keepalivetimer_cmd(vty);
3163
0
}
3164
3165
DEFPY (ip_pim_packets,
3166
       ip_pim_packets_cmd,
3167
       "ip pim packets (1-255)",
3168
       IP_STR
3169
       "pim multicast routing\n"
3170
       "packets to process at one time per fd\n"
3171
       "Number of packets\n")
3172
0
{
3173
0
  return pim_process_pim_packet_cmd(vty, packets_str);
3174
0
}
3175
3176
DEFUN (no_ip_pim_packets,
3177
       no_ip_pim_packets_cmd,
3178
       "no ip pim packets [(1-255)]",
3179
       NO_STR
3180
       IP_STR
3181
       "pim multicast routing\n"
3182
       "packets to process at one time per fd\n"
3183
       IGNORED_IN_NO_STR)
3184
0
{
3185
0
  return pim_process_no_pim_packet_cmd(vty);
3186
0
}
3187
3188
DEFPY (ip_igmp_group_watermark,
3189
       ip_igmp_group_watermark_cmd,
3190
       "ip igmp watermark-warn (1-65535)$limit",
3191
       IP_STR
3192
       IGMP_STR
3193
       "Configure group limit for watermark warning\n"
3194
       "Group count to generate watermark warning\n")
3195
0
{
3196
0
  PIM_DECLVAR_CONTEXT_VRF(vrf, pim);
3197
0
  pim->gm_watermark_limit = limit;
3198
3199
0
  return CMD_SUCCESS;
3200
0
}
3201
3202
DEFPY (no_ip_igmp_group_watermark,
3203
       no_ip_igmp_group_watermark_cmd,
3204
       "no ip igmp watermark-warn [(1-65535)$limit]",
3205
       NO_STR
3206
       IP_STR
3207
       IGMP_STR
3208
       "Unconfigure group limit for watermark warning\n"
3209
       IGNORED_IN_NO_STR)
3210
0
{
3211
0
  PIM_DECLVAR_CONTEXT_VRF(vrf, pim);
3212
0
  pim->gm_watermark_limit = 0;
3213
3214
0
  return CMD_SUCCESS;
3215
0
}
3216
3217
DEFUN (ip_pim_v6_secondary,
3218
       ip_pim_v6_secondary_cmd,
3219
       "ip pim send-v6-secondary",
3220
       IP_STR
3221
       "pim multicast routing\n"
3222
       "Send v6 secondary addresses\n")
3223
0
{
3224
0
  const char *vrfname;
3225
0
  char send_v6_secondary_xpath[XPATH_MAXLEN];
3226
3227
0
  vrfname = pim_cli_get_vrf_name(vty);
3228
0
  if (vrfname == NULL)
3229
0
    return CMD_WARNING_CONFIG_FAILED;
3230
3231
0
  snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
3232
0
     FRR_PIM_VRF_XPATH,
3233
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3234
0
  strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
3235
0
    sizeof(send_v6_secondary_xpath));
3236
3237
0
  nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
3238
0
            "true");
3239
3240
0
  return nb_cli_apply_changes(vty, NULL);
3241
0
}
3242
3243
DEFUN (no_ip_pim_v6_secondary,
3244
       no_ip_pim_v6_secondary_cmd,
3245
       "no ip pim send-v6-secondary",
3246
       NO_STR
3247
       IP_STR
3248
       "pim multicast routing\n"
3249
       "Send v6 secondary addresses\n")
3250
0
{
3251
0
  const char *vrfname;
3252
0
  char send_v6_secondary_xpath[XPATH_MAXLEN];
3253
3254
0
  vrfname = pim_cli_get_vrf_name(vty);
3255
0
  if (vrfname == NULL)
3256
0
    return CMD_WARNING_CONFIG_FAILED;
3257
3258
0
  snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
3259
0
     FRR_PIM_VRF_XPATH,
3260
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3261
0
  strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
3262
0
    sizeof(send_v6_secondary_xpath));
3263
3264
0
  nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
3265
0
            "false");
3266
3267
0
  return nb_cli_apply_changes(vty, NULL);
3268
0
}
3269
3270
DEFPY (ip_pim_rp,
3271
       ip_pim_rp_cmd,
3272
       "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
3273
       IP_STR
3274
       "pim multicast routing\n"
3275
       "Rendezvous Point\n"
3276
       "ip address of RP\n"
3277
       "Group Address range to cover\n")
3278
0
{
3279
0
  const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
3280
3281
0
  return pim_process_rp_cmd(vty, rp_str, group_str);
3282
0
}
3283
3284
DEFPY (ip_pim_rp_prefix_list,
3285
       ip_pim_rp_prefix_list_cmd,
3286
       "ip pim rp A.B.C.D$rp prefix-list WORD$plist",
3287
       IP_STR
3288
       "pim multicast routing\n"
3289
       "Rendezvous Point\n"
3290
       "ip address of RP\n"
3291
       "group prefix-list filter\n"
3292
       "Name of a prefix-list\n")
3293
0
{
3294
0
  return pim_process_rp_plist_cmd(vty, rp_str, plist);
3295
0
}
3296
3297
DEFPY (no_ip_pim_rp,
3298
       no_ip_pim_rp_cmd,
3299
       "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
3300
       NO_STR
3301
       IP_STR
3302
       "pim multicast routing\n"
3303
       "Rendezvous Point\n"
3304
       "ip address of RP\n"
3305
       "Group Address range to cover\n")
3306
0
{
3307
0
  const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
3308
3309
0
  return pim_process_no_rp_cmd(vty, rp_str, group_str);
3310
0
}
3311
3312
DEFPY (no_ip_pim_rp_prefix_list,
3313
       no_ip_pim_rp_prefix_list_cmd,
3314
       "no ip pim rp A.B.C.D$rp prefix-list WORD$plist",
3315
       NO_STR
3316
       IP_STR
3317
       "pim multicast routing\n"
3318
       "Rendezvous Point\n"
3319
       "ip address of RP\n"
3320
       "group prefix-list filter\n"
3321
       "Name of a prefix-list\n")
3322
0
{
3323
0
  return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
3324
0
}
3325
3326
DEFUN (ip_pim_ssm_prefix_list,
3327
       ip_pim_ssm_prefix_list_cmd,
3328
       "ip pim ssm prefix-list WORD",
3329
       IP_STR
3330
       "pim multicast routing\n"
3331
       "Source Specific Multicast\n"
3332
       "group range prefix-list filter\n"
3333
       "Name of a prefix-list\n")
3334
0
{
3335
0
  const char *vrfname;
3336
0
  char ssm_plist_xpath[XPATH_MAXLEN];
3337
3338
0
  vrfname = pim_cli_get_vrf_name(vty);
3339
0
  if (vrfname == NULL)
3340
0
    return CMD_WARNING_CONFIG_FAILED;
3341
3342
0
  snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_VRF_XPATH,
3343
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3344
0
  strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
3345
3346
0
  nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg);
3347
3348
0
  return nb_cli_apply_changes(vty, NULL);
3349
0
}
3350
3351
DEFUN (no_ip_pim_ssm_prefix_list,
3352
       no_ip_pim_ssm_prefix_list_cmd,
3353
       "no ip pim ssm prefix-list",
3354
       NO_STR
3355
       IP_STR
3356
       "pim multicast routing\n"
3357
       "Source Specific Multicast\n"
3358
       "group range prefix-list filter\n")
3359
0
{
3360
0
  const char *vrfname;
3361
0
  char ssm_plist_xpath[XPATH_MAXLEN];
3362
3363
0
  vrfname = pim_cli_get_vrf_name(vty);
3364
0
  if (vrfname == NULL)
3365
0
    return CMD_WARNING_CONFIG_FAILED;
3366
3367
0
  snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
3368
0
     FRR_PIM_VRF_XPATH,
3369
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3370
0
  strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
3371
3372
0
  nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
3373
3374
0
  return nb_cli_apply_changes(vty, NULL);
3375
0
}
3376
3377
DEFUN (no_ip_pim_ssm_prefix_list_name,
3378
       no_ip_pim_ssm_prefix_list_name_cmd,
3379
       "no ip pim ssm prefix-list WORD",
3380
       NO_STR
3381
       IP_STR
3382
       "pim multicast routing\n"
3383
       "Source Specific Multicast\n"
3384
       "group range prefix-list filter\n"
3385
       "Name of a prefix-list\n")
3386
0
{
3387
0
  const char *vrfname;
3388
0
  const struct lyd_node *ssm_plist_dnode;
3389
0
  char ssm_plist_xpath[XPATH_MAXLEN];
3390
0
  const char *ssm_plist_name;
3391
3392
0
  vrfname = pim_cli_get_vrf_name(vty);
3393
0
  if (vrfname == NULL)
3394
0
    return CMD_WARNING_CONFIG_FAILED;
3395
3396
0
  snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
3397
0
     FRR_PIM_VRF_XPATH,
3398
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3399
0
  strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
3400
0
  ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
3401
0
           ssm_plist_xpath);
3402
3403
0
  if (!ssm_plist_dnode) {
3404
0
    vty_out(vty,
3405
0
      "%% pim ssm prefix-list %s doesn't exist\n",
3406
0
      argv[5]->arg);
3407
0
    return CMD_WARNING_CONFIG_FAILED;
3408
0
  }
3409
3410
0
  ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
3411
3412
0
  if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) {
3413
0
    nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY,
3414
0
              NULL);
3415
3416
0
    return nb_cli_apply_changes(vty, NULL);
3417
0
  }
3418
3419
0
  vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
3420
3421
0
  return CMD_WARNING_CONFIG_FAILED;
3422
0
}
3423
3424
DEFUN (show_ip_pim_ssm_range,
3425
       show_ip_pim_ssm_range_cmd,
3426
       "show ip pim [vrf NAME] group-type [json]",
3427
       SHOW_STR
3428
       IP_STR
3429
       PIM_STR
3430
       VRF_CMD_HELP_STR
3431
       "PIM group type\n"
3432
       JSON_STR)
3433
0
{
3434
0
  int idx = 2;
3435
0
  bool uj = use_json(argc, argv);
3436
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
3437
3438
0
  if (!vrf)
3439
0
    return CMD_WARNING;
3440
3441
0
  ip_pim_ssm_show_group_range(vrf->info, vty, uj);
3442
3443
0
  return CMD_SUCCESS;
3444
0
}
3445
3446
static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
3447
               struct vty *vty, bool uj,
3448
               const char *group)
3449
0
{
3450
0
  struct in_addr group_addr;
3451
0
  const char *type_str;
3452
0
  int result;
3453
3454
0
  result = inet_pton(AF_INET, group, &group_addr);
3455
0
  if (result <= 0)
3456
0
    type_str = "invalid";
3457
0
  else {
3458
0
    if (pim_is_group_224_4(group_addr))
3459
0
      type_str =
3460
0
        pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
3461
0
    else
3462
0
      type_str = "not-multicast";
3463
0
  }
3464
3465
0
  if (uj) {
3466
0
    json_object *json;
3467
0
    json = json_object_new_object();
3468
0
    json_object_string_add(json, "groupType", type_str);
3469
0
    vty_json(vty, json);
3470
0
  } else
3471
0
    vty_out(vty, "Group type : %s\n", type_str);
3472
0
}
3473
3474
DEFUN (show_ip_pim_group_type,
3475
       show_ip_pim_group_type_cmd,
3476
       "show ip pim [vrf NAME] group-type A.B.C.D [json]",
3477
       SHOW_STR
3478
       IP_STR
3479
       PIM_STR
3480
       VRF_CMD_HELP_STR
3481
       "multicast group type\n"
3482
       "group address\n"
3483
       JSON_STR)
3484
0
{
3485
0
  int idx = 2;
3486
0
  bool uj = use_json(argc, argv);
3487
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
3488
3489
0
  if (!vrf)
3490
0
    return CMD_WARNING;
3491
3492
0
  argv_find(argv, argc, "A.B.C.D", &idx);
3493
0
  ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
3494
3495
0
  return CMD_SUCCESS;
3496
0
}
3497
3498
DEFPY (show_ip_pim_bsr,
3499
       show_ip_pim_bsr_cmd,
3500
       "show ip pim bsr [vrf NAME] [json$json]",
3501
       SHOW_STR
3502
       IP_STR
3503
       PIM_STR
3504
       "boot-strap router information\n"
3505
       VRF_CMD_HELP_STR
3506
       JSON_STR)
3507
0
{
3508
0
  return pim_show_bsr_helper(vrf, vty, !!json);
3509
0
}
3510
3511
DEFUN (ip_ssmpingd,
3512
       ip_ssmpingd_cmd,
3513
       "ip ssmpingd [A.B.C.D]",
3514
       IP_STR
3515
       CONF_SSMPINGD_STR
3516
       "Source address\n")
3517
0
{
3518
0
  int idx_ipv4 = 2;
3519
0
  const char *src_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
3520
3521
0
  return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
3522
0
}
3523
3524
DEFUN (no_ip_ssmpingd,
3525
       no_ip_ssmpingd_cmd,
3526
       "no ip ssmpingd [A.B.C.D]",
3527
       NO_STR
3528
       IP_STR
3529
       CONF_SSMPINGD_STR
3530
       "Source address\n")
3531
0
{
3532
0
  int idx_ipv4 = 3;
3533
0
  const char *src_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
3534
3535
0
  return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
3536
0
}
3537
3538
DEFUN (ip_pim_ecmp,
3539
       ip_pim_ecmp_cmd,
3540
       "ip pim ecmp",
3541
       IP_STR
3542
       "pim multicast routing\n"
3543
       "Enable PIM ECMP \n")
3544
0
{
3545
0
  const char *vrfname;
3546
0
  char ecmp_xpath[XPATH_MAXLEN];
3547
3548
0
  vrfname = pim_cli_get_vrf_name(vty);
3549
0
  if (vrfname == NULL)
3550
0
    return CMD_WARNING_CONFIG_FAILED;
3551
3552
0
  snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
3553
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3554
0
  strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
3555
3556
0
  nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
3557
0
  return nb_cli_apply_changes(vty, NULL);
3558
0
}
3559
3560
DEFUN (no_ip_pim_ecmp,
3561
       no_ip_pim_ecmp_cmd,
3562
       "no ip pim ecmp",
3563
       NO_STR
3564
       IP_STR
3565
       "pim multicast routing\n"
3566
       "Disable PIM ECMP \n")
3567
0
{
3568
0
  const char *vrfname;
3569
0
  char ecmp_xpath[XPATH_MAXLEN];
3570
3571
0
  vrfname = pim_cli_get_vrf_name(vty);
3572
0
  if (vrfname == NULL)
3573
0
    return CMD_WARNING_CONFIG_FAILED;
3574
3575
0
  snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
3576
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3577
0
  strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
3578
3579
0
  nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false");
3580
3581
0
  return nb_cli_apply_changes(vty, NULL);
3582
0
}
3583
3584
DEFUN (ip_pim_ecmp_rebalance,
3585
       ip_pim_ecmp_rebalance_cmd,
3586
       "ip pim ecmp rebalance",
3587
       IP_STR
3588
       "pim multicast routing\n"
3589
       "Enable PIM ECMP \n"
3590
       "Enable PIM ECMP Rebalance\n")
3591
0
{
3592
0
  const char *vrfname;
3593
0
  char ecmp_xpath[XPATH_MAXLEN];
3594
0
  char ecmp_rebalance_xpath[XPATH_MAXLEN];
3595
3596
0
  vrfname = pim_cli_get_vrf_name(vty);
3597
0
  if (vrfname == NULL)
3598
0
    return CMD_WARNING_CONFIG_FAILED;
3599
3600
0
  snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
3601
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3602
0
  strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
3603
0
  snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
3604
0
     FRR_PIM_VRF_XPATH,
3605
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3606
0
  strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
3607
0
    sizeof(ecmp_rebalance_xpath));
3608
3609
0
  nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
3610
0
  nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true");
3611
3612
0
  return nb_cli_apply_changes(vty, NULL);
3613
0
}
3614
3615
DEFUN (no_ip_pim_ecmp_rebalance,
3616
       no_ip_pim_ecmp_rebalance_cmd,
3617
       "no ip pim ecmp rebalance",
3618
       NO_STR
3619
       IP_STR
3620
       "pim multicast routing\n"
3621
       "Disable PIM ECMP \n"
3622
       "Disable PIM ECMP Rebalance\n")
3623
0
{
3624
0
  const char *vrfname;
3625
0
  char ecmp_rebalance_xpath[XPATH_MAXLEN];
3626
3627
0
  vrfname = pim_cli_get_vrf_name(vty);
3628
0
  if (vrfname == NULL)
3629
0
    return CMD_WARNING_CONFIG_FAILED;
3630
3631
0
  snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
3632
0
     FRR_PIM_VRF_XPATH,
3633
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
3634
0
  strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
3635
0
    sizeof(ecmp_rebalance_xpath));
3636
3637
0
  nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false");
3638
3639
0
  return nb_cli_apply_changes(vty, NULL);
3640
0
}
3641
3642
DEFUN (interface_ip_igmp,
3643
       interface_ip_igmp_cmd,
3644
       "ip igmp",
3645
       IP_STR
3646
       IFACE_IGMP_STR)
3647
0
{
3648
0
  nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
3649
3650
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3651
0
            "frr-routing:ipv4");
3652
0
}
3653
3654
DEFUN (interface_no_ip_igmp,
3655
       interface_no_ip_igmp_cmd,
3656
       "no ip igmp",
3657
       NO_STR
3658
       IP_STR
3659
       IFACE_IGMP_STR)
3660
0
{
3661
0
  const struct lyd_node *pim_enable_dnode;
3662
0
  char pim_if_xpath[XPATH_MAXLEN];
3663
3664
0
  int printed =
3665
0
    snprintf(pim_if_xpath, sizeof(pim_if_xpath),
3666
0
       "%s/frr-pim:pim/address-family[address-family='%s']",
3667
0
       VTY_CURR_XPATH, "frr-routing:ipv4");
3668
3669
0
  if (printed >= (int)(sizeof(pim_if_xpath))) {
3670
0
    vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
3671
0
      XPATH_MAXLEN);
3672
0
    return CMD_WARNING_CONFIG_FAILED;
3673
0
  }
3674
3675
0
  pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
3676
0
             FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
3677
0
             "frr-routing:ipv4");
3678
0
  if (!pim_enable_dnode) {
3679
0
    nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY, NULL);
3680
0
    nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
3681
0
  } else {
3682
0
    if (!yang_dnode_get_bool(pim_enable_dnode, ".")) {
3683
0
      nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY,
3684
0
                NULL);
3685
0
      nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
3686
0
    } else
3687
0
      nb_cli_enqueue_change(vty, "./enable",
3688
0
                NB_OP_MODIFY, "false");
3689
0
  }
3690
3691
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3692
0
            "frr-routing:ipv4");
3693
0
}
3694
3695
DEFUN (interface_ip_igmp_join,
3696
       interface_ip_igmp_join_cmd,
3697
       "ip igmp join A.B.C.D [A.B.C.D]",
3698
       IP_STR
3699
       IFACE_IGMP_STR
3700
       "IGMP join multicast group\n"
3701
       "Multicast group address\n"
3702
       "Source address\n")
3703
0
{
3704
0
  int idx_group = 3;
3705
0
  int idx_source = 4;
3706
0
  const char *source_str;
3707
0
  char xpath[XPATH_MAXLEN];
3708
3709
0
  if (argc == 5) {
3710
0
    source_str = argv[idx_source]->arg;
3711
3712
0
    if (strcmp(source_str, "0.0.0.0") == 0) {
3713
0
      vty_out(vty, "Bad source address %s\n",
3714
0
        argv[idx_source]->arg);
3715
0
      return CMD_WARNING_CONFIG_FAILED;
3716
0
    }
3717
0
  } else
3718
0
    source_str = "0.0.0.0";
3719
3720
0
  snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
3721
0
     "frr-routing:ipv4", argv[idx_group]->arg, source_str);
3722
3723
0
  nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
3724
3725
0
  return nb_cli_apply_changes(vty, NULL);
3726
0
}
3727
3728
DEFUN (interface_no_ip_igmp_join,
3729
       interface_no_ip_igmp_join_cmd,
3730
       "no ip igmp join A.B.C.D [A.B.C.D]",
3731
       NO_STR
3732
       IP_STR
3733
       IFACE_IGMP_STR
3734
       "IGMP join multicast group\n"
3735
       "Multicast group address\n"
3736
       "Source address\n")
3737
0
{
3738
0
  int idx_group = 4;
3739
0
  int idx_source = 5;
3740
0
  const char *source_str;
3741
0
  char xpath[XPATH_MAXLEN];
3742
3743
0
  if (argc == 6) {
3744
0
    source_str = argv[idx_source]->arg;
3745
3746
0
    if (strcmp(source_str, "0.0.0.0") == 0) {
3747
0
      vty_out(vty, "Bad source address %s\n",
3748
0
        argv[idx_source]->arg);
3749
0
      return CMD_WARNING_CONFIG_FAILED;
3750
0
    }
3751
0
  } else
3752
0
    source_str = "0.0.0.0";
3753
3754
0
  snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
3755
0
     "frr-routing:ipv4", argv[idx_group]->arg, source_str);
3756
3757
0
  nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
3758
3759
0
  return nb_cli_apply_changes(vty, NULL);
3760
0
}
3761
3762
DEFUN (interface_ip_igmp_query_interval,
3763
       interface_ip_igmp_query_interval_cmd,
3764
       "ip igmp query-interval (1-65535)",
3765
       IP_STR
3766
       IFACE_IGMP_STR
3767
       IFACE_IGMP_QUERY_INTERVAL_STR
3768
       "Query interval in seconds\n")
3769
0
{
3770
0
  const struct lyd_node *pim_enable_dnode;
3771
3772
0
  pim_enable_dnode =
3773
0
    yang_dnode_getf(vty->candidate_config->dnode,
3774
0
        FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
3775
0
        "frr-routing:ipv4");
3776
0
  if (!pim_enable_dnode) {
3777
0
    nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
3778
0
              "true");
3779
0
  } else {
3780
0
    if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3781
0
      nb_cli_enqueue_change(vty, "./enable",
3782
0
                NB_OP_MODIFY, "true");
3783
0
  }
3784
3785
0
  nb_cli_enqueue_change(vty, "./query-interval", NB_OP_MODIFY,
3786
0
            argv[3]->arg);
3787
3788
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3789
0
            "frr-routing:ipv4");
3790
0
}
3791
3792
DEFUN (interface_no_ip_igmp_query_interval,
3793
       interface_no_ip_igmp_query_interval_cmd,
3794
       "no ip igmp query-interval [(1-65535)]",
3795
       NO_STR
3796
       IP_STR
3797
       IFACE_IGMP_STR
3798
       IFACE_IGMP_QUERY_INTERVAL_STR
3799
       IGNORED_IN_NO_STR)
3800
0
{
3801
0
  nb_cli_enqueue_change(vty, "./query-interval", NB_OP_DESTROY, NULL);
3802
3803
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3804
0
            "frr-routing:ipv4");
3805
0
}
3806
3807
DEFUN (interface_ip_igmp_version,
3808
       interface_ip_igmp_version_cmd,
3809
       "ip igmp version (2-3)",
3810
       IP_STR
3811
       IFACE_IGMP_STR
3812
       "IGMP version\n"
3813
       "IGMP version number\n")
3814
0
{
3815
0
  nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
3816
0
            "true");
3817
0
  nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_MODIFY,
3818
0
            argv[3]->arg);
3819
3820
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3821
0
            "frr-routing:ipv4");
3822
0
}
3823
3824
DEFUN (interface_no_ip_igmp_version,
3825
       interface_no_ip_igmp_version_cmd,
3826
       "no ip igmp version (2-3)",
3827
       NO_STR
3828
       IP_STR
3829
       IFACE_IGMP_STR
3830
       "IGMP version\n"
3831
       "IGMP version number\n")
3832
0
{
3833
0
  nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_DESTROY, NULL);
3834
3835
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3836
0
            "frr-routing:ipv4");
3837
0
}
3838
3839
DEFPY (interface_ip_igmp_query_max_response_time,
3840
       interface_ip_igmp_query_max_response_time_cmd,
3841
       "ip igmp query-max-response-time (1-65535)$qmrt",
3842
       IP_STR
3843
       IFACE_IGMP_STR
3844
       IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
3845
       "Query response value in deci-seconds\n")
3846
0
{
3847
0
  return gm_process_query_max_response_time_cmd(vty, qmrt_str);
3848
0
}
3849
3850
DEFUN (interface_no_ip_igmp_query_max_response_time,
3851
       interface_no_ip_igmp_query_max_response_time_cmd,
3852
       "no ip igmp query-max-response-time [(1-65535)]",
3853
       NO_STR
3854
       IP_STR
3855
       IFACE_IGMP_STR
3856
       IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
3857
       IGNORED_IN_NO_STR)
3858
0
{
3859
0
  return gm_process_no_query_max_response_time_cmd(vty);
3860
0
}
3861
3862
DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
3863
        interface_ip_igmp_query_max_response_time_dsec_cmd,
3864
        "ip igmp query-max-response-time-dsec (1-65535)",
3865
        IP_STR
3866
        IFACE_IGMP_STR
3867
        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3868
        "Query response value in deciseconds\n")
3869
0
{
3870
0
  const struct lyd_node *pim_enable_dnode;
3871
3872
0
  pim_enable_dnode =
3873
0
    yang_dnode_getf(vty->candidate_config->dnode,
3874
0
        FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
3875
0
        "frr-routing:ipv4");
3876
0
  if (!pim_enable_dnode) {
3877
0
    nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
3878
0
              "true");
3879
0
  } else {
3880
0
    if (!yang_dnode_get_bool(pim_enable_dnode, "."))
3881
0
      nb_cli_enqueue_change(vty, "./enable",
3882
0
                NB_OP_MODIFY, "true");
3883
0
  }
3884
3885
0
  nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
3886
0
            argv[3]->arg);
3887
3888
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3889
0
            "frr-routing:ipv4");
3890
0
}
3891
3892
DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
3893
        interface_no_ip_igmp_query_max_response_time_dsec_cmd,
3894
        "no ip igmp query-max-response-time-dsec [(1-65535)]",
3895
        NO_STR
3896
        IP_STR
3897
        IFACE_IGMP_STR
3898
        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
3899
        IGNORED_IN_NO_STR)
3900
0
{
3901
0
  nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
3902
0
            NULL);
3903
3904
0
  return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
3905
0
            "frr-routing:ipv4");
3906
0
}
3907
3908
DEFPY (interface_ip_igmp_last_member_query_count,
3909
       interface_ip_igmp_last_member_query_count_cmd,
3910
       "ip igmp last-member-query-count (1-255)$lmqc",
3911
       IP_STR
3912
       IFACE_IGMP_STR
3913
       IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
3914
       "Last member query count\n")
3915
0
{
3916
0
  return gm_process_last_member_query_count_cmd(vty, lmqc_str);
3917
0
}
3918
3919
DEFUN (interface_no_ip_igmp_last_member_query_count,
3920
       interface_no_ip_igmp_last_member_query_count_cmd,
3921
       "no ip igmp last-member-query-count [(1-255)]",
3922
       NO_STR
3923
       IP_STR
3924
       IFACE_IGMP_STR
3925
       IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
3926
       IGNORED_IN_NO_STR)
3927
0
{
3928
0
  return gm_process_no_last_member_query_count_cmd(vty);
3929
0
}
3930
3931
DEFPY (interface_ip_igmp_last_member_query_interval,
3932
       interface_ip_igmp_last_member_query_interval_cmd,
3933
       "ip igmp last-member-query-interval (1-65535)$lmqi",
3934
       IP_STR
3935
       IFACE_IGMP_STR
3936
       IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
3937
       "Last member query interval in deciseconds\n")
3938
0
{
3939
0
  return gm_process_last_member_query_interval_cmd(vty, lmqi_str);
3940
0
}
3941
3942
DEFUN (interface_no_ip_igmp_last_member_query_interval,
3943
       interface_no_ip_igmp_last_member_query_interval_cmd,
3944
       "no ip igmp last-member-query-interval [(1-65535)]",
3945
       NO_STR
3946
       IP_STR
3947
       IFACE_IGMP_STR
3948
       IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
3949
       IGNORED_IN_NO_STR)
3950
0
{
3951
0
  return gm_process_no_last_member_query_interval_cmd(vty);
3952
0
}
3953
3954
DEFUN (interface_ip_pim_drprio,
3955
       interface_ip_pim_drprio_cmd,
3956
       "ip pim drpriority (1-4294967295)",
3957
       IP_STR
3958
       PIM_STR
3959
       "Set the Designated Router Election Priority\n"
3960
       "Value of the new DR Priority\n")
3961
0
{
3962
0
  int idx_number = 3;
3963
3964
0
  return pim_process_ip_pim_drprio_cmd(vty, argv[idx_number]->arg);
3965
0
}
3966
3967
DEFUN (interface_no_ip_pim_drprio,
3968
       interface_no_ip_pim_drprio_cmd,
3969
       "no ip pim drpriority [(1-4294967295)]",
3970
       NO_STR
3971
       IP_STR
3972
       PIM_STR
3973
       "Revert the Designated Router Priority to default\n"
3974
       "Old Value of the Priority\n")
3975
0
{
3976
0
  return pim_process_no_ip_pim_drprio_cmd(vty);
3977
0
}
3978
3979
DEFPY_HIDDEN (interface_ip_igmp_query_generate,
3980
        interface_ip_igmp_query_generate_cmd,
3981
        "ip igmp generate-query-once [version (2-3)]",
3982
        IP_STR
3983
        IFACE_IGMP_STR
3984
        "Generate igmp general query once\n"
3985
        "IGMP version\n"
3986
        "IGMP version number\n")
3987
0
{
3988
0
#if PIM_IPV == 4
3989
0
  VTY_DECLVAR_CONTEXT(interface, ifp);
3990
0
  int igmp_version;
3991
0
  struct pim_interface *pim_ifp = ifp->info;
3992
3993
0
  if (!ifp->info) {
3994
0
    vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
3995
0
      ifp->name);
3996
0
    return CMD_WARNING_CONFIG_FAILED;
3997
0
  }
3998
3999
  /* It takes the igmp version configured on the interface as default */
4000
0
  igmp_version = pim_ifp->igmp_version;
4001
4002
0
  if (argc > 3)
4003
0
    igmp_version = atoi(argv[4]->arg);
4004
4005
0
  igmp_send_query_on_intf(ifp, igmp_version);
4006
0
#endif
4007
0
  return CMD_SUCCESS;
4008
0
}
4009
4010
DEFPY_HIDDEN (pim_test_sg_keepalive,
4011
        pim_test_sg_keepalive_cmd,
4012
        "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
4013
        "Test code\n"
4014
        PIM_STR
4015
        VRF_CMD_HELP_STR
4016
        "Reset the Keepalive Timer\n"
4017
        "The Source we are resetting\n"
4018
        "The Group we are resetting\n")
4019
0
{
4020
0
  struct pim_upstream *up;
4021
0
  struct vrf *vrf;
4022
0
  struct pim_instance *pim;
4023
0
  pim_sgaddr sg;
4024
4025
0
  sg.src = source;
4026
0
  sg.grp = group;
4027
4028
0
  vrf = vrf_lookup_by_name(name ? name : VRF_DEFAULT_NAME);
4029
0
  if (!vrf) {
4030
0
    vty_out(vty, "%% Vrf specified: %s does not exist\n", name);
4031
0
    return CMD_WARNING;
4032
0
  }
4033
4034
0
  pim = vrf->info;
4035
4036
0
  if (!pim) {
4037
0
    vty_out(vty, "%% Unable to find pim instance\n");
4038
0
    return CMD_WARNING;
4039
0
  }
4040
4041
0
  up = pim_upstream_find(pim, &sg);
4042
0
  if (!up) {
4043
0
    vty_out(vty, "%% Unable to find %pSG specified\n", &sg);
4044
0
    return CMD_WARNING;
4045
0
  }
4046
4047
0
  vty_out(vty, "Setting %pSG to current keep alive time: %d\n", &sg,
4048
0
    pim->keep_alive_time);
4049
0
  pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
4050
4051
0
  return CMD_SUCCESS;
4052
0
}
4053
4054
DEFPY (interface_ip_pim_activeactive,
4055
       interface_ip_pim_activeactive_cmd,
4056
       "[no$no] ip pim active-active",
4057
       NO_STR
4058
       IP_STR
4059
       PIM_STR
4060
       "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
4061
0
{
4062
0
  return pim_process_ip_pim_activeactive_cmd(vty, no);
4063
0
}
4064
4065
DEFUN_HIDDEN (interface_ip_pim_ssm,
4066
        interface_ip_pim_ssm_cmd,
4067
        "ip pim ssm",
4068
        IP_STR
4069
        PIM_STR
4070
        IFACE_PIM_STR)
4071
0
{
4072
0
  int ret;
4073
4074
0
  ret = pim_process_ip_pim_cmd(vty);
4075
4076
0
  if (ret != NB_OK)
4077
0
    return ret;
4078
4079
0
  vty_out(vty,
4080
0
    "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
4081
4082
0
  return NB_OK;
4083
0
}
4084
4085
DEFUN_HIDDEN (interface_ip_pim_sm,
4086
        interface_ip_pim_sm_cmd,
4087
        "ip pim sm",
4088
        IP_STR
4089
        PIM_STR
4090
        IFACE_PIM_SM_STR)
4091
0
{
4092
0
  return pim_process_ip_pim_cmd(vty);
4093
0
}
4094
4095
DEFPY (interface_ip_pim,
4096
       interface_ip_pim_cmd,
4097
       "ip pim [passive$passive]",
4098
       IP_STR
4099
       PIM_STR
4100
       "Disable exchange of protocol packets\n")
4101
0
{
4102
0
  int ret;
4103
4104
0
  ret = pim_process_ip_pim_cmd(vty);
4105
4106
0
  if (ret != NB_OK)
4107
0
    return ret;
4108
4109
0
  if (passive)
4110
0
    return pim_process_ip_pim_passive_cmd(vty, true);
4111
4112
0
  return CMD_SUCCESS;
4113
0
}
4114
4115
DEFUN_HIDDEN (interface_no_ip_pim_ssm,
4116
        interface_no_ip_pim_ssm_cmd,
4117
        "no ip pim ssm",
4118
        NO_STR
4119
        IP_STR
4120
        PIM_STR
4121
        IFACE_PIM_STR)
4122
0
{
4123
0
  return pim_process_no_ip_pim_cmd(vty);
4124
0
}
4125
4126
DEFUN_HIDDEN (interface_no_ip_pim_sm,
4127
        interface_no_ip_pim_sm_cmd,
4128
        "no ip pim sm",
4129
        NO_STR
4130
        IP_STR
4131
        PIM_STR
4132
        IFACE_PIM_SM_STR)
4133
0
{
4134
0
  return pim_process_no_ip_pim_cmd(vty);
4135
0
}
4136
4137
DEFPY (interface_no_ip_pim,
4138
       interface_no_ip_pim_cmd,
4139
       "no ip pim [passive$passive]",
4140
       NO_STR
4141
       IP_STR
4142
       PIM_STR
4143
       "Disable exchange of protocol packets\n")
4144
0
{
4145
0
  if (passive)
4146
0
    return pim_process_ip_pim_passive_cmd(vty, false);
4147
4148
0
  return pim_process_no_ip_pim_cmd(vty);
4149
0
}
4150
4151
/* boundaries */
4152
DEFUN(interface_ip_pim_boundary_oil,
4153
      interface_ip_pim_boundary_oil_cmd,
4154
      "ip multicast boundary oil WORD",
4155
      IP_STR
4156
      "Generic multicast configuration options\n"
4157
      "Define multicast boundary\n"
4158
      "Filter OIL by group using prefix list\n"
4159
      "Prefix list to filter OIL with\n")
4160
0
{
4161
0
  return pim_process_ip_pim_boundary_oil_cmd(vty, argv[4]->arg);
4162
0
}
4163
4164
DEFUN(interface_no_ip_pim_boundary_oil,
4165
      interface_no_ip_pim_boundary_oil_cmd,
4166
      "no ip multicast boundary oil [WORD]",
4167
      NO_STR
4168
      IP_STR
4169
      "Generic multicast configuration options\n"
4170
      "Define multicast boundary\n"
4171
      "Filter OIL by group using prefix list\n"
4172
      "Prefix list to filter OIL with\n")
4173
0
{
4174
0
  return pim_process_no_ip_pim_boundary_oil_cmd(vty);
4175
0
}
4176
4177
DEFUN (interface_ip_mroute,
4178
       interface_ip_mroute_cmd,
4179
       "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
4180
       IP_STR
4181
       "Add multicast route\n"
4182
       "Outgoing interface name\n"
4183
       "Group address\n"
4184
       "Source address\n")
4185
0
{
4186
0
  int idx_interface = 2;
4187
0
  int idx_ipv4 = 3;
4188
0
  const char *source_str;
4189
4190
0
  if (argc == (idx_ipv4 + 1))
4191
0
    source_str = "0.0.0.0";
4192
0
  else
4193
0
    source_str = argv[idx_ipv4 + 1]->arg;
4194
4195
0
  return pim_process_ip_mroute_cmd(vty, argv[idx_interface]->arg,
4196
0
           argv[idx_ipv4]->arg, source_str);
4197
0
}
4198
4199
DEFUN (interface_no_ip_mroute,
4200
       interface_no_ip_mroute_cmd,
4201
       "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
4202
       NO_STR
4203
       IP_STR
4204
       "Add multicast route\n"
4205
       "Outgoing interface name\n"
4206
       "Group Address\n"
4207
       "Source Address\n")
4208
0
{
4209
0
  int idx_interface = 3;
4210
0
  int idx_ipv4 = 4;
4211
0
  const char *source_str;
4212
4213
0
  if (argc == (idx_ipv4 + 1))
4214
0
    source_str = "0.0.0.0";
4215
0
  else
4216
0
    source_str = argv[idx_ipv4 + 1]->arg;
4217
4218
0
  return pim_process_no_ip_mroute_cmd(vty, argv[idx_interface]->arg,
4219
0
              argv[idx_ipv4]->arg, source_str);
4220
0
}
4221
4222
DEFUN (interface_ip_pim_hello,
4223
       interface_ip_pim_hello_cmd,
4224
       "ip pim hello (1-65535) [(1-65535)]",
4225
       IP_STR
4226
       PIM_STR
4227
       IFACE_PIM_HELLO_STR
4228
       IFACE_PIM_HELLO_TIME_STR
4229
       IFACE_PIM_HELLO_HOLD_STR)
4230
0
{
4231
0
  int idx_time = 3;
4232
0
  int idx_hold = 4;
4233
4234
0
  if (argc == idx_hold + 1)
4235
0
    return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
4236
0
                argv[idx_hold]->arg);
4237
4238
0
  else
4239
0
    return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
4240
0
                NULL);
4241
0
}
4242
4243
DEFUN (interface_no_ip_pim_hello,
4244
       interface_no_ip_pim_hello_cmd,
4245
       "no ip pim hello [(1-65535) [(1-65535)]]",
4246
       NO_STR
4247
       IP_STR
4248
       PIM_STR
4249
       IFACE_PIM_HELLO_STR
4250
       IGNORED_IN_NO_STR
4251
       IGNORED_IN_NO_STR)
4252
0
{
4253
0
  return pim_process_no_ip_pim_hello_cmd(vty);
4254
0
}
4255
4256
DEFUN (debug_igmp,
4257
       debug_igmp_cmd,
4258
       "debug igmp",
4259
       DEBUG_STR
4260
       DEBUG_IGMP_STR)
4261
0
{
4262
0
  PIM_DO_DEBUG_GM_EVENTS;
4263
0
  PIM_DO_DEBUG_GM_PACKETS;
4264
0
  PIM_DO_DEBUG_GM_TRACE;
4265
0
  return CMD_SUCCESS;
4266
0
}
4267
4268
DEFUN (no_debug_igmp,
4269
       no_debug_igmp_cmd,
4270
       "no debug igmp",
4271
       NO_STR
4272
       DEBUG_STR
4273
       DEBUG_IGMP_STR)
4274
0
{
4275
0
  PIM_DONT_DEBUG_GM_EVENTS;
4276
0
  PIM_DONT_DEBUG_GM_PACKETS;
4277
0
  PIM_DONT_DEBUG_GM_TRACE;
4278
0
  return CMD_SUCCESS;
4279
0
}
4280
4281
4282
DEFUN (debug_igmp_events,
4283
       debug_igmp_events_cmd,
4284
       "debug igmp events",
4285
       DEBUG_STR
4286
       DEBUG_IGMP_STR
4287
       DEBUG_IGMP_EVENTS_STR)
4288
0
{
4289
0
  PIM_DO_DEBUG_GM_EVENTS;
4290
0
  return CMD_SUCCESS;
4291
0
}
4292
4293
DEFUN (no_debug_igmp_events,
4294
       no_debug_igmp_events_cmd,
4295
       "no debug igmp events",
4296
       NO_STR
4297
       DEBUG_STR
4298
       DEBUG_IGMP_STR
4299
       DEBUG_IGMP_EVENTS_STR)
4300
0
{
4301
0
  PIM_DONT_DEBUG_GM_EVENTS;
4302
0
  return CMD_SUCCESS;
4303
0
}
4304
4305
4306
DEFUN (debug_igmp_packets,
4307
       debug_igmp_packets_cmd,
4308
       "debug igmp packets",
4309
       DEBUG_STR
4310
       DEBUG_IGMP_STR
4311
       DEBUG_IGMP_PACKETS_STR)
4312
0
{
4313
0
  PIM_DO_DEBUG_GM_PACKETS;
4314
0
  return CMD_SUCCESS;
4315
0
}
4316
4317
DEFUN (no_debug_igmp_packets,
4318
       no_debug_igmp_packets_cmd,
4319
       "no debug igmp packets",
4320
       NO_STR
4321
       DEBUG_STR
4322
       DEBUG_IGMP_STR
4323
       DEBUG_IGMP_PACKETS_STR)
4324
0
{
4325
0
  PIM_DONT_DEBUG_GM_PACKETS;
4326
0
  return CMD_SUCCESS;
4327
0
}
4328
4329
4330
DEFUN (debug_igmp_trace,
4331
       debug_igmp_trace_cmd,
4332
       "debug igmp trace",
4333
       DEBUG_STR
4334
       DEBUG_IGMP_STR
4335
       DEBUG_IGMP_TRACE_STR)
4336
0
{
4337
0
  PIM_DO_DEBUG_GM_TRACE;
4338
0
  return CMD_SUCCESS;
4339
0
}
4340
4341
DEFUN (no_debug_igmp_trace,
4342
       no_debug_igmp_trace_cmd,
4343
       "no debug igmp trace",
4344
       NO_STR
4345
       DEBUG_STR
4346
       DEBUG_IGMP_STR
4347
       DEBUG_IGMP_TRACE_STR)
4348
0
{
4349
0
  PIM_DONT_DEBUG_GM_TRACE;
4350
0
  return CMD_SUCCESS;
4351
0
}
4352
4353
4354
DEFUN (debug_igmp_trace_detail,
4355
       debug_igmp_trace_detail_cmd,
4356
       "debug igmp trace detail",
4357
       DEBUG_STR
4358
       DEBUG_IGMP_STR
4359
       DEBUG_IGMP_TRACE_STR
4360
       "detailed\n")
4361
0
{
4362
0
  PIM_DO_DEBUG_GM_TRACE_DETAIL;
4363
0
  return CMD_SUCCESS;
4364
0
}
4365
4366
DEFUN (no_debug_igmp_trace_detail,
4367
       no_debug_igmp_trace_detail_cmd,
4368
       "no debug igmp trace detail",
4369
       NO_STR
4370
       DEBUG_STR
4371
       DEBUG_IGMP_STR
4372
       DEBUG_IGMP_TRACE_STR
4373
       "detailed\n")
4374
0
{
4375
0
  PIM_DONT_DEBUG_GM_TRACE_DETAIL;
4376
0
  return CMD_SUCCESS;
4377
0
}
4378
4379
4380
DEFUN (debug_mroute,
4381
       debug_mroute_cmd,
4382
       "debug mroute",
4383
       DEBUG_STR
4384
       DEBUG_MROUTE_STR)
4385
0
{
4386
0
  PIM_DO_DEBUG_MROUTE;
4387
0
  return CMD_SUCCESS;
4388
0
}
4389
4390
DEFUN (debug_mroute_detail,
4391
       debug_mroute_detail_cmd,
4392
       "debug mroute detail",
4393
       DEBUG_STR
4394
       DEBUG_MROUTE_STR
4395
       "detailed\n")
4396
0
{
4397
0
  PIM_DO_DEBUG_MROUTE_DETAIL;
4398
0
  return CMD_SUCCESS;
4399
0
}
4400
4401
DEFUN (no_debug_mroute,
4402
       no_debug_mroute_cmd,
4403
       "no debug mroute",
4404
       NO_STR
4405
       DEBUG_STR
4406
       DEBUG_MROUTE_STR)
4407
0
{
4408
0
  PIM_DONT_DEBUG_MROUTE;
4409
0
  return CMD_SUCCESS;
4410
0
}
4411
4412
DEFUN (no_debug_mroute_detail,
4413
       no_debug_mroute_detail_cmd,
4414
       "no debug mroute detail",
4415
       NO_STR
4416
       DEBUG_STR
4417
       DEBUG_MROUTE_STR
4418
       "detailed\n")
4419
0
{
4420
0
  PIM_DONT_DEBUG_MROUTE_DETAIL;
4421
0
  return CMD_SUCCESS;
4422
0
}
4423
4424
DEFUN (debug_pim_static,
4425
       debug_pim_static_cmd,
4426
       "debug pim static",
4427
       DEBUG_STR
4428
       DEBUG_PIM_STR
4429
       DEBUG_STATIC_STR)
4430
0
{
4431
0
  PIM_DO_DEBUG_STATIC;
4432
0
  return CMD_SUCCESS;
4433
0
}
4434
4435
DEFUN (no_debug_pim_static,
4436
       no_debug_pim_static_cmd,
4437
       "no debug pim static",
4438
       NO_STR
4439
       DEBUG_STR
4440
       DEBUG_PIM_STR
4441
       DEBUG_STATIC_STR)
4442
0
{
4443
0
  PIM_DONT_DEBUG_STATIC;
4444
0
  return CMD_SUCCESS;
4445
0
}
4446
4447
4448
DEFPY (debug_pim,
4449
       debug_pim_cmd,
4450
       "[no] debug pim",
4451
       NO_STR
4452
       DEBUG_STR
4453
       DEBUG_PIM_STR)
4454
0
{
4455
0
  if (!no)
4456
0
    return pim_debug_pim_cmd();
4457
0
  else
4458
0
    return pim_no_debug_pim_cmd();
4459
0
}
4460
4461
DEFPY (debug_pim_nht,
4462
       debug_pim_nht_cmd,
4463
       "[no] debug pim nht",
4464
       NO_STR
4465
       DEBUG_STR
4466
       DEBUG_PIM_STR
4467
       "Nexthop Tracking\n")
4468
0
{
4469
0
  if (!no)
4470
0
    PIM_DO_DEBUG_PIM_NHT;
4471
0
  else
4472
0
    PIM_DONT_DEBUG_PIM_NHT;
4473
0
  return CMD_SUCCESS;
4474
0
}
4475
4476
DEFPY (debug_pim_nht_det,
4477
       debug_pim_nht_det_cmd,
4478
       "[no] debug pim nht detail",
4479
       NO_STR
4480
       DEBUG_STR
4481
       DEBUG_PIM_STR
4482
       "Nexthop Tracking\n"
4483
       "Detailed Information\n")
4484
0
{
4485
0
  if (!no)
4486
0
    PIM_DO_DEBUG_PIM_NHT_DETAIL;
4487
0
  else
4488
0
    PIM_DONT_DEBUG_PIM_NHT_DETAIL;
4489
0
  return CMD_SUCCESS;
4490
0
}
4491
4492
DEFUN (debug_pim_nht_rp,
4493
       debug_pim_nht_rp_cmd,
4494
       "debug pim nht rp",
4495
       DEBUG_STR
4496
       DEBUG_PIM_STR
4497
       "Nexthop Tracking\n"
4498
       "RP Nexthop Tracking\n")
4499
0
{
4500
0
  PIM_DO_DEBUG_PIM_NHT_RP;
4501
0
  return CMD_SUCCESS;
4502
0
}
4503
4504
DEFUN (no_debug_pim_nht_rp,
4505
       no_debug_pim_nht_rp_cmd,
4506
       "no debug pim nht rp",
4507
       NO_STR
4508
       DEBUG_STR
4509
       DEBUG_PIM_STR
4510
       "Nexthop Tracking\n"
4511
       "RP Nexthop Tracking\n")
4512
0
{
4513
0
  PIM_DONT_DEBUG_PIM_NHT_RP;
4514
0
  return CMD_SUCCESS;
4515
0
}
4516
4517
DEFPY (debug_pim_events,
4518
       debug_pim_events_cmd,
4519
       "[no] debug pim events",
4520
       NO_STR
4521
       DEBUG_STR
4522
       DEBUG_PIM_STR
4523
       DEBUG_PIM_EVENTS_STR)
4524
0
{
4525
0
  if (!no)
4526
0
    PIM_DO_DEBUG_PIM_EVENTS;
4527
0
  else
4528
0
    PIM_DONT_DEBUG_PIM_EVENTS;
4529
0
  return CMD_SUCCESS;
4530
0
}
4531
4532
DEFPY (debug_pim_packets,
4533
       debug_pim_packets_cmd,
4534
       "[no] debug pim packets [<hello$hello|joins$joins|register$registers>]",
4535
       NO_STR DEBUG_STR
4536
       DEBUG_PIM_STR
4537
       DEBUG_PIM_PACKETS_STR
4538
       DEBUG_PIM_HELLO_PACKETS_STR
4539
       DEBUG_PIM_J_P_PACKETS_STR
4540
       DEBUG_PIM_PIM_REG_PACKETS_STR)
4541
0
{
4542
0
  if (!no)
4543
0
    return pim_debug_pim_packets_cmd(hello, joins, registers, vty);
4544
0
  else
4545
0
    return pim_no_debug_pim_packets_cmd(hello, joins, registers,
4546
0
                vty);
4547
0
}
4548
4549
DEFPY (debug_pim_packetdump_send,
4550
       debug_pim_packetdump_send_cmd,
4551
       "[no] debug pim packet-dump send",
4552
       NO_STR
4553
       DEBUG_STR
4554
       DEBUG_PIM_STR
4555
       DEBUG_PIM_PACKETDUMP_STR
4556
       DEBUG_PIM_PACKETDUMP_SEND_STR)
4557
0
{
4558
0
  if (!no)
4559
0
    PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
4560
0
  else
4561
0
    PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
4562
0
  return CMD_SUCCESS;
4563
0
}
4564
4565
DEFPY (debug_pim_packetdump_recv,
4566
       debug_pim_packetdump_recv_cmd,
4567
       "[no] debug pim packet-dump receive",
4568
       NO_STR
4569
       DEBUG_STR
4570
       DEBUG_PIM_STR
4571
       DEBUG_PIM_PACKETDUMP_STR
4572
       DEBUG_PIM_PACKETDUMP_RECV_STR)
4573
0
{
4574
0
  if (!no)
4575
0
    PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
4576
0
  else
4577
0
    PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
4578
0
  return CMD_SUCCESS;
4579
0
}
4580
4581
DEFPY (debug_pim_trace,
4582
       debug_pim_trace_cmd,
4583
       "[no] debug pim trace",
4584
       NO_STR
4585
       DEBUG_STR
4586
       DEBUG_PIM_STR
4587
       DEBUG_PIM_TRACE_STR)
4588
0
{
4589
0
  if (!no)
4590
0
    PIM_DO_DEBUG_PIM_TRACE;
4591
0
  else
4592
0
    PIM_DONT_DEBUG_PIM_TRACE;
4593
0
  return CMD_SUCCESS;
4594
0
}
4595
4596
DEFPY (debug_pim_trace_detail,
4597
       debug_pim_trace_detail_cmd,
4598
       "[no] debug pim trace detail",
4599
       NO_STR
4600
       DEBUG_STR
4601
       DEBUG_PIM_STR
4602
       DEBUG_PIM_TRACE_STR
4603
       "Detailed Information\n")
4604
0
{
4605
0
  if (!no)
4606
0
    PIM_DO_DEBUG_PIM_TRACE_DETAIL;
4607
0
  else
4608
0
    PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
4609
0
  return CMD_SUCCESS;
4610
0
}
4611
4612
DEFUN (debug_ssmpingd,
4613
       debug_ssmpingd_cmd,
4614
       "debug ssmpingd",
4615
       DEBUG_STR
4616
       DEBUG_SSMPINGD_STR)
4617
0
{
4618
0
  PIM_DO_DEBUG_SSMPINGD;
4619
0
  return CMD_SUCCESS;
4620
0
}
4621
4622
DEFUN (no_debug_ssmpingd,
4623
       no_debug_ssmpingd_cmd,
4624
       "no debug ssmpingd",
4625
       NO_STR
4626
       DEBUG_STR
4627
       DEBUG_SSMPINGD_STR)
4628
0
{
4629
0
  PIM_DONT_DEBUG_SSMPINGD;
4630
0
  return CMD_SUCCESS;
4631
0
}
4632
4633
DEFPY (debug_pim_zebra,
4634
       debug_pim_zebra_cmd,
4635
       "[no] debug pim zebra",
4636
       NO_STR
4637
       DEBUG_STR
4638
       DEBUG_PIM_STR
4639
       DEBUG_PIM_ZEBRA_STR)
4640
0
{
4641
0
  if (!no)
4642
0
    PIM_DO_DEBUG_ZEBRA;
4643
0
  else
4644
0
    PIM_DONT_DEBUG_ZEBRA;
4645
0
  return CMD_SUCCESS;
4646
0
}
4647
4648
DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
4649
      DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
4650
0
{
4651
0
  PIM_DO_DEBUG_MLAG;
4652
0
  return CMD_SUCCESS;
4653
0
}
4654
4655
DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
4656
      NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
4657
0
{
4658
0
  PIM_DONT_DEBUG_MLAG;
4659
0
  return CMD_SUCCESS;
4660
0
}
4661
4662
DEFUN (debug_pim_vxlan,
4663
       debug_pim_vxlan_cmd,
4664
       "debug pim vxlan",
4665
       DEBUG_STR
4666
       DEBUG_PIM_STR
4667
       DEBUG_PIM_VXLAN_STR)
4668
0
{
4669
0
  PIM_DO_DEBUG_VXLAN;
4670
0
  return CMD_SUCCESS;
4671
0
}
4672
4673
DEFUN (no_debug_pim_vxlan,
4674
       no_debug_pim_vxlan_cmd,
4675
       "no debug pim vxlan",
4676
       NO_STR
4677
       DEBUG_STR
4678
       DEBUG_PIM_STR
4679
       DEBUG_PIM_VXLAN_STR)
4680
0
{
4681
0
  PIM_DONT_DEBUG_VXLAN;
4682
0
  return CMD_SUCCESS;
4683
0
}
4684
4685
DEFUN (debug_msdp,
4686
       debug_msdp_cmd,
4687
       "debug msdp",
4688
       DEBUG_STR
4689
       DEBUG_MSDP_STR)
4690
0
{
4691
0
  PIM_DO_DEBUG_MSDP_EVENTS;
4692
0
  PIM_DO_DEBUG_MSDP_PACKETS;
4693
0
  return CMD_SUCCESS;
4694
0
}
4695
4696
DEFUN (no_debug_msdp,
4697
       no_debug_msdp_cmd,
4698
       "no debug msdp",
4699
       NO_STR
4700
       DEBUG_STR
4701
       DEBUG_MSDP_STR)
4702
0
{
4703
0
  PIM_DONT_DEBUG_MSDP_EVENTS;
4704
0
  PIM_DONT_DEBUG_MSDP_PACKETS;
4705
0
  return CMD_SUCCESS;
4706
0
}
4707
4708
DEFUN (debug_msdp_events,
4709
       debug_msdp_events_cmd,
4710
       "debug msdp events",
4711
       DEBUG_STR
4712
       DEBUG_MSDP_STR
4713
       DEBUG_MSDP_EVENTS_STR)
4714
0
{
4715
0
  PIM_DO_DEBUG_MSDP_EVENTS;
4716
0
  return CMD_SUCCESS;
4717
0
}
4718
4719
DEFUN (no_debug_msdp_events,
4720
       no_debug_msdp_events_cmd,
4721
       "no debug msdp events",
4722
       NO_STR
4723
       DEBUG_STR
4724
       DEBUG_MSDP_STR
4725
       DEBUG_MSDP_EVENTS_STR)
4726
0
{
4727
0
  PIM_DONT_DEBUG_MSDP_EVENTS;
4728
0
  return CMD_SUCCESS;
4729
0
}
4730
4731
DEFUN (debug_msdp_packets,
4732
       debug_msdp_packets_cmd,
4733
       "debug msdp packets",
4734
       DEBUG_STR
4735
       DEBUG_MSDP_STR
4736
       DEBUG_MSDP_PACKETS_STR)
4737
0
{
4738
0
  PIM_DO_DEBUG_MSDP_PACKETS;
4739
0
  return CMD_SUCCESS;
4740
0
}
4741
4742
DEFUN (no_debug_msdp_packets,
4743
       no_debug_msdp_packets_cmd,
4744
       "no debug msdp packets",
4745
       NO_STR
4746
       DEBUG_STR
4747
       DEBUG_MSDP_STR
4748
       DEBUG_MSDP_PACKETS_STR)
4749
0
{
4750
0
  PIM_DONT_DEBUG_MSDP_PACKETS;
4751
0
  return CMD_SUCCESS;
4752
0
}
4753
4754
DEFUN (debug_mtrace,
4755
       debug_mtrace_cmd,
4756
       "debug mtrace",
4757
       DEBUG_STR
4758
       DEBUG_MTRACE_STR)
4759
0
{
4760
0
  PIM_DO_DEBUG_MTRACE;
4761
0
  return CMD_SUCCESS;
4762
0
}
4763
4764
DEFUN (no_debug_mtrace,
4765
       no_debug_mtrace_cmd,
4766
       "no debug mtrace",
4767
       NO_STR
4768
       DEBUG_STR
4769
       DEBUG_MTRACE_STR)
4770
0
{
4771
0
  PIM_DONT_DEBUG_MTRACE;
4772
0
  return CMD_SUCCESS;
4773
0
}
4774
4775
DEFUN (debug_bsm,
4776
       debug_bsm_cmd,
4777
       "debug pim bsm",
4778
       DEBUG_STR
4779
       DEBUG_PIM_STR
4780
       DEBUG_PIM_BSM_STR)
4781
0
{
4782
0
  PIM_DO_DEBUG_BSM;
4783
0
  return CMD_SUCCESS;
4784
0
}
4785
4786
DEFUN (no_debug_bsm,
4787
       no_debug_bsm_cmd,
4788
       "no debug pim bsm",
4789
       NO_STR
4790
       DEBUG_STR
4791
       DEBUG_PIM_STR
4792
       DEBUG_PIM_BSM_STR)
4793
0
{
4794
0
  PIM_DONT_DEBUG_BSM;
4795
0
  return CMD_SUCCESS;
4796
0
}
4797
4798
4799
DEFUN_NOSH (show_debugging_pim,
4800
      show_debugging_pim_cmd,
4801
      "show debugging [pim]",
4802
      SHOW_STR
4803
      DEBUG_STR
4804
      PIM_STR)
4805
0
{
4806
0
  vty_out(vty, "PIM debugging status\n");
4807
4808
0
  pim_debug_config_write(vty);
4809
4810
0
  cmd_show_lib_debugs(vty);
4811
0
  return CMD_SUCCESS;
4812
0
}
4813
4814
DEFUN (interface_pim_use_source,
4815
       interface_pim_use_source_cmd,
4816
       "ip pim use-source A.B.C.D",
4817
       IP_STR
4818
       PIM_STR
4819
       "Configure primary IP address\n"
4820
       "source ip address\n")
4821
0
{
4822
0
  nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, argv[3]->arg);
4823
4824
0
  return nb_cli_apply_changes(vty,
4825
0
            FRR_PIM_INTERFACE_XPATH,
4826
0
            "frr-routing:ipv4");
4827
0
}
4828
4829
DEFUN (interface_no_pim_use_source,
4830
       interface_no_pim_use_source_cmd,
4831
       "no ip pim use-source [A.B.C.D]",
4832
       NO_STR
4833
       IP_STR
4834
       PIM_STR
4835
       "Delete source IP address\n"
4836
       "source ip address\n")
4837
0
{
4838
0
  nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, "0.0.0.0");
4839
4840
0
  return nb_cli_apply_changes(vty,
4841
0
            FRR_PIM_INTERFACE_XPATH,
4842
0
            "frr-routing:ipv4");
4843
0
}
4844
4845
DEFPY (ip_pim_bfd,
4846
       ip_pim_bfd_cmd,
4847
       "ip pim bfd [profile BFDPROF$prof]",
4848
       IP_STR
4849
       PIM_STR
4850
       "Enables BFD support\n"
4851
       "Use BFD profile\n"
4852
       "Use BFD profile name\n")
4853
0
{
4854
0
  const struct lyd_node *igmp_enable_dnode;
4855
4856
0
  igmp_enable_dnode =
4857
0
    yang_dnode_getf(vty->candidate_config->dnode,
4858
0
        FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
4859
0
        "frr-routing:ipv4");
4860
0
  if (!igmp_enable_dnode)
4861
0
    nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4862
0
              "true");
4863
0
  else {
4864
0
    if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
4865
0
      nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4866
0
                "true");
4867
0
  }
4868
4869
0
  nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
4870
0
  if (prof)
4871
0
    nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_MODIFY, prof);
4872
4873
0
  return nb_cli_apply_changes(vty,
4874
0
            FRR_PIM_INTERFACE_XPATH,
4875
0
            "frr-routing:ipv4");
4876
0
}
4877
4878
DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
4879
      "no ip pim bfd profile [BFDPROF]",
4880
      NO_STR
4881
      IP_STR
4882
      PIM_STR
4883
      "Enables BFD support\n"
4884
      "Disable BFD profile\n"
4885
      "BFD Profile name\n")
4886
0
{
4887
0
  nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_DESTROY, NULL);
4888
4889
0
  return nb_cli_apply_changes(vty,
4890
0
      FRR_PIM_INTERFACE_XPATH,
4891
0
      "frr-routing:ipv4");
4892
0
}
4893
4894
DEFUN (no_ip_pim_bfd,
4895
       no_ip_pim_bfd_cmd,
4896
       "no ip pim bfd",
4897
       NO_STR
4898
       IP_STR
4899
       PIM_STR
4900
       "Disables BFD support\n")
4901
0
{
4902
0
  nb_cli_enqueue_change(vty, "./bfd", NB_OP_DESTROY, NULL);
4903
4904
0
  return nb_cli_apply_changes(vty,
4905
0
      FRR_PIM_INTERFACE_XPATH,
4906
0
      "frr-routing:ipv4");
4907
0
}
4908
4909
DEFUN (ip_pim_bsm,
4910
       ip_pim_bsm_cmd,
4911
       "ip pim bsm",
4912
       IP_STR
4913
       PIM_STR
4914
       "Enable BSM support on the interface\n")
4915
0
{
4916
0
  return pim_process_bsm_cmd(vty);
4917
0
}
4918
DEFUN (no_ip_pim_bsm,
4919
       no_ip_pim_bsm_cmd,
4920
       "no ip pim bsm",
4921
       NO_STR
4922
       IP_STR
4923
       PIM_STR
4924
       "Enable BSM support on the interface\n")
4925
0
{
4926
0
  return pim_process_no_bsm_cmd(vty);
4927
0
}
4928
4929
DEFUN (ip_pim_ucast_bsm,
4930
       ip_pim_ucast_bsm_cmd,
4931
       "ip pim unicast-bsm",
4932
       IP_STR
4933
       PIM_STR
4934
       "Accept/Send unicast BSM on the interface\n")
4935
0
{
4936
0
  return pim_process_unicast_bsm_cmd(vty);
4937
0
}
4938
4939
DEFUN (no_ip_pim_ucast_bsm,
4940
       no_ip_pim_ucast_bsm_cmd,
4941
       "no ip pim unicast-bsm",
4942
       NO_STR
4943
       IP_STR
4944
       PIM_STR
4945
       "Accept/Send unicast BSM on the interface\n")
4946
0
{
4947
0
  return pim_process_no_unicast_bsm_cmd(vty);
4948
0
}
4949
4950
#if HAVE_BFDD > 0
4951
DEFUN_HIDDEN (
4952
  ip_pim_bfd_param,
4953
  ip_pim_bfd_param_cmd,
4954
  "ip pim bfd (2-255) (1-65535) (1-65535)",
4955
  IP_STR
4956
  PIM_STR
4957
  "Enables BFD support\n"
4958
  "Detect Multiplier\n"
4959
  "Required min receive interval\n"
4960
  "Desired min transmit interval\n")
4961
#else
4962
  DEFUN(
4963
    ip_pim_bfd_param,
4964
    ip_pim_bfd_param_cmd,
4965
    "ip pim bfd (2-255) (1-65535) (1-65535)",
4966
    IP_STR
4967
    PIM_STR
4968
    "Enables BFD support\n"
4969
    "Detect Multiplier\n"
4970
    "Required min receive interval\n"
4971
    "Desired min transmit interval\n")
4972
#endif /* HAVE_BFDD */
4973
0
{
4974
0
  int idx_number = 3;
4975
0
  int idx_number_2 = 4;
4976
0
  int idx_number_3 = 5;
4977
0
  const struct lyd_node *igmp_enable_dnode;
4978
4979
0
  igmp_enable_dnode =
4980
0
    yang_dnode_getf(vty->candidate_config->dnode,
4981
0
        FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
4982
0
        "frr-routing:ipv4");
4983
0
  if (!igmp_enable_dnode)
4984
0
    nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4985
0
              "true");
4986
0
  else {
4987
0
    if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
4988
0
      nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
4989
0
                "true");
4990
0
  }
4991
4992
0
  nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
4993
0
  nb_cli_enqueue_change(vty, "./bfd/min-rx-interval", NB_OP_MODIFY,
4994
0
            argv[idx_number_2]->arg);
4995
0
  nb_cli_enqueue_change(vty, "./bfd/min-tx-interval", NB_OP_MODIFY,
4996
0
            argv[idx_number_3]->arg);
4997
0
  nb_cli_enqueue_change(vty, "./bfd/detect_mult", NB_OP_MODIFY,
4998
0
            argv[idx_number]->arg);
4999
5000
0
  return nb_cli_apply_changes(vty,
5001
0
      FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
5002
0
}
5003
5004
#if HAVE_BFDD == 0
5005
ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
5006
      "no ip pim bfd (2-255) (1-65535) (1-65535)",
5007
      NO_STR
5008
      IP_STR
5009
      PIM_STR
5010
      "Enables BFD support\n"
5011
      "Detect Multiplier\n"
5012
      "Required min receive interval\n"
5013
      "Desired min transmit interval\n")
5014
#endif /* !HAVE_BFDD */
5015
5016
DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
5017
      "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
5018
      IP_STR
5019
      CFG_MSDP_STR
5020
      "Configure MSDP peer\n"
5021
      "Peer IP address\n"
5022
      "Source address for TCP connection\n"
5023
      "Local IP address\n")
5024
0
{
5025
0
  const char *vrfname;
5026
0
  char temp_xpath[XPATH_MAXLEN];
5027
0
  char msdp_peer_source_xpath[XPATH_MAXLEN];
5028
5029
0
  vrfname = pim_cli_get_vrf_name(vty);
5030
0
  if (vrfname == NULL)
5031
0
    return CMD_WARNING_CONFIG_FAILED;
5032
5033
0
  snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
5034
0
     FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
5035
0
     "frr-routing:ipv4");
5036
0
  snprintf(temp_xpath, sizeof(temp_xpath),
5037
0
     "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
5038
0
  strlcat(msdp_peer_source_xpath, temp_xpath,
5039
0
    sizeof(msdp_peer_source_xpath));
5040
5041
0
  nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
5042
0
            source_str);
5043
5044
0
  return nb_cli_apply_changes(vty,
5045
0
      FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
5046
0
}
5047
5048
DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
5049
      "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
5050
      IP_STR
5051
      CFG_MSDP_STR
5052
      "MSDP timers configuration\n"
5053
      "Keep alive period (in seconds)\n"
5054
      "Hold time period (in seconds)\n"
5055
      "Connection retry period (in seconds)\n")
5056
0
{
5057
0
  const char *vrfname;
5058
5059
0
  vrfname = pim_cli_get_vrf_name(vty);
5060
0
  if (vrfname == NULL)
5061
0
    return CMD_WARNING_CONFIG_FAILED;
5062
5063
0
  nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
5064
0
  nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
5065
0
  if (connretry_str)
5066
0
    nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
5067
0
              connretry_str);
5068
0
  else
5069
0
    nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
5070
0
              NULL);
5071
5072
0
  nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
5073
0
           vrfname, "frr-routing:ipv4");
5074
0
  return CMD_SUCCESS;
5075
0
}
5076
5077
DEFPY(no_ip_msdp_timers, no_ip_msdp_timers_cmd,
5078
      "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
5079
      NO_STR
5080
      IP_STR
5081
      CFG_MSDP_STR
5082
      "MSDP timers configuration\n"
5083
      IGNORED_IN_NO_STR
5084
      IGNORED_IN_NO_STR
5085
      IGNORED_IN_NO_STR)
5086
0
{
5087
0
  const char *vrfname;
5088
5089
0
  vrfname = pim_cli_get_vrf_name(vty);
5090
0
  if (vrfname == NULL)
5091
0
    return CMD_WARNING_CONFIG_FAILED;
5092
5093
0
  nb_cli_enqueue_change(vty, "./hold-time", NB_OP_DESTROY, NULL);
5094
0
  nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_DESTROY, NULL);
5095
0
  nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, NULL);
5096
5097
0
  nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
5098
0
           vrfname, "frr-routing:ipv4");
5099
5100
0
  return CMD_SUCCESS;
5101
0
}
5102
5103
DEFUN (no_ip_msdp_peer,
5104
       no_ip_msdp_peer_cmd,
5105
       "no ip msdp peer A.B.C.D",
5106
       NO_STR
5107
       IP_STR
5108
       CFG_MSDP_STR
5109
       "Delete MSDP peer\n"
5110
       "peer ip address\n")
5111
0
{
5112
0
  const char *vrfname;
5113
0
  char msdp_peer_xpath[XPATH_MAXLEN];
5114
0
  char temp_xpath[XPATH_MAXLEN];
5115
5116
0
  vrfname = pim_cli_get_vrf_name(vty);
5117
0
  if (vrfname == NULL)
5118
0
    return CMD_WARNING_CONFIG_FAILED;
5119
5120
0
  snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
5121
0
     FRR_PIM_VRF_XPATH,
5122
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
5123
0
  snprintf(temp_xpath, sizeof(temp_xpath),
5124
0
     "/msdp-peer[peer-ip='%s']",
5125
0
     argv[4]->arg);
5126
5127
0
  strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath));
5128
5129
0
  nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
5130
5131
0
  return nb_cli_apply_changes(vty, NULL);
5132
0
}
5133
5134
DEFPY(ip_msdp_mesh_group_member,
5135
      ip_msdp_mesh_group_member_cmd,
5136
      "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
5137
      IP_STR
5138
      CFG_MSDP_STR
5139
      "Configure MSDP mesh-group\n"
5140
      "Mesh group name\n"
5141
      "Mesh group member\n"
5142
      "Peer IP address\n")
5143
0
{
5144
0
  const char *vrfname;
5145
0
  char xpath_value[XPATH_MAXLEN];
5146
5147
0
  vrfname = pim_cli_get_vrf_name(vty);
5148
0
  if (vrfname == NULL)
5149
0
    return CMD_WARNING_CONFIG_FAILED;
5150
5151
  /* Create mesh group. */
5152
0
  snprintf(xpath_value, sizeof(xpath_value),
5153
0
     FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
5154
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
5155
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
5156
5157
  /* Create mesh group member. */
5158
0
  strlcat(xpath_value, "/members[address='", sizeof(xpath_value));
5159
0
  strlcat(xpath_value, maddr_str, sizeof(xpath_value));
5160
0
  strlcat(xpath_value, "']", sizeof(xpath_value));
5161
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
5162
5163
0
  return nb_cli_apply_changes(vty, NULL);
5164
0
}
5165
5166
DEFPY(no_ip_msdp_mesh_group_member,
5167
      no_ip_msdp_mesh_group_member_cmd,
5168
      "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
5169
      NO_STR
5170
      IP_STR
5171
      CFG_MSDP_STR
5172
      "Delete MSDP mesh-group member\n"
5173
      "Mesh group name\n"
5174
      "Mesh group member\n"
5175
      "Peer IP address\n")
5176
0
{
5177
0
  const char *vrfname;
5178
0
  char xpath_value[XPATH_MAXLEN];
5179
0
  char xpath_member_value[XPATH_MAXLEN];
5180
5181
0
  vrfname = pim_cli_get_vrf_name(vty);
5182
0
  if (vrfname == NULL)
5183
0
    return CMD_WARNING_CONFIG_FAILED;
5184
5185
  /* Get mesh group base XPath. */
5186
0
  snprintf(xpath_value, sizeof(xpath_value),
5187
0
     FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
5188
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
5189
5190
0
  if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
5191
0
    vty_out(vty, "%% mesh-group does not exist\n");
5192
0
    return CMD_WARNING_CONFIG_FAILED;
5193
0
  }
5194
5195
  /* Remove mesh group member. */
5196
0
  strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
5197
0
  strlcat(xpath_member_value, "/members[address='",
5198
0
    sizeof(xpath_member_value));
5199
0
  strlcat(xpath_member_value, maddr_str, sizeof(xpath_member_value));
5200
0
  strlcat(xpath_member_value, "']", sizeof(xpath_member_value));
5201
0
  if (!yang_dnode_exists(vty->candidate_config->dnode,
5202
0
             xpath_member_value)) {
5203
0
    vty_out(vty, "%% mesh-group member does not exist\n");
5204
0
    return CMD_WARNING_CONFIG_FAILED;
5205
0
  }
5206
5207
0
  nb_cli_enqueue_change(vty, xpath_member_value, NB_OP_DESTROY, NULL);
5208
5209
  /*
5210
   * If this is the last member, then we must remove the group altogether
5211
   * to not break legacy CLI behaviour.
5212
   */
5213
0
  pim_cli_legacy_mesh_group_behavior(vty, gname);
5214
5215
0
  return nb_cli_apply_changes(vty, NULL);
5216
0
}
5217
5218
DEFPY(ip_msdp_mesh_group_source,
5219
      ip_msdp_mesh_group_source_cmd,
5220
      "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
5221
      IP_STR
5222
      CFG_MSDP_STR
5223
      "Configure MSDP mesh-group\n"
5224
      "Mesh group name\n"
5225
      "Mesh group local address\n"
5226
      "Source IP address for the TCP connection\n")
5227
0
{
5228
0
  const char *vrfname;
5229
0
  char xpath_value[XPATH_MAXLEN];
5230
5231
0
  vrfname = pim_cli_get_vrf_name(vty);
5232
0
  if (vrfname == NULL)
5233
0
    return CMD_WARNING_CONFIG_FAILED;
5234
5235
  /* Create mesh group. */
5236
0
  snprintf(xpath_value, sizeof(xpath_value),
5237
0
     FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
5238
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
5239
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
5240
5241
  /* Create mesh group source. */
5242
0
  strlcat(xpath_value, "/source", sizeof(xpath_value));
5243
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
5244
5245
0
  return nb_cli_apply_changes(vty, NULL);
5246
0
}
5247
5248
DEFPY(no_ip_msdp_mesh_group_source,
5249
      no_ip_msdp_mesh_group_source_cmd,
5250
      "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
5251
      NO_STR
5252
      IP_STR
5253
      CFG_MSDP_STR
5254
      "Delete MSDP mesh-group source\n"
5255
      "Mesh group name\n"
5256
      "Mesh group source\n"
5257
      "Mesh group local address\n")
5258
0
{
5259
0
  const char *vrfname;
5260
0
  char xpath_value[XPATH_MAXLEN];
5261
5262
0
  vrfname = pim_cli_get_vrf_name(vty);
5263
0
  if (vrfname == NULL)
5264
0
    return CMD_WARNING_CONFIG_FAILED;
5265
5266
  /* Get mesh group base XPath. */
5267
0
  snprintf(xpath_value, sizeof(xpath_value),
5268
0
     FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
5269
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
5270
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
5271
5272
  /* Create mesh group source. */
5273
0
  strlcat(xpath_value, "/source", sizeof(xpath_value));
5274
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
5275
5276
  /*
5277
   * If this is the last member, then we must remove the group altogether
5278
   * to not break legacy CLI behaviour.
5279
   */
5280
0
  pim_cli_legacy_mesh_group_behavior(vty, gname);
5281
5282
0
  return nb_cli_apply_changes(vty, NULL);
5283
0
}
5284
5285
DEFPY(no_ip_msdp_mesh_group,
5286
      no_ip_msdp_mesh_group_cmd,
5287
      "no ip msdp mesh-group WORD$gname",
5288
      NO_STR
5289
      IP_STR
5290
      CFG_MSDP_STR
5291
      "Delete MSDP mesh-group\n"
5292
      "Mesh group name\n")
5293
0
{
5294
0
  const char *vrfname;
5295
0
  char xpath_value[XPATH_MAXLEN];
5296
5297
0
  vrfname = pim_cli_get_vrf_name(vty);
5298
0
  if (vrfname == NULL)
5299
0
    return CMD_WARNING_CONFIG_FAILED;
5300
5301
  /* Get mesh group base XPath. */
5302
0
  snprintf(xpath_value, sizeof(xpath_value),
5303
0
     FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
5304
0
     "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
5305
0
  if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
5306
0
    return CMD_SUCCESS;
5307
5308
0
  nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
5309
0
  return nb_cli_apply_changes(vty, NULL);
5310
0
}
5311
5312
static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
5313
            struct json_object *json)
5314
0
{
5315
0
  struct listnode *mbrnode;
5316
0
  struct pim_msdp_mg_mbr *mbr;
5317
0
  char mbr_str[INET_ADDRSTRLEN];
5318
0
  char src_str[INET_ADDRSTRLEN];
5319
0
  char state_str[PIM_MSDP_STATE_STRLEN];
5320
0
  enum pim_msdp_peer_state state;
5321
0
  json_object *json_mg_row = NULL;
5322
0
  json_object *json_members = NULL;
5323
0
  json_object *json_row = NULL;
5324
5325
0
  pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
5326
0
  if (json) {
5327
    /* currently there is only one mesh group but we should still
5328
     * make
5329
     * it a dict with mg-name as key */
5330
0
    json_mg_row = json_object_new_object();
5331
0
    json_object_string_add(json_mg_row, "name",
5332
0
               mg->mesh_group_name);
5333
0
    json_object_string_add(json_mg_row, "source", src_str);
5334
0
  } else {
5335
0
    vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
5336
0
    vty_out(vty, "  Source : %s\n", src_str);
5337
0
    vty_out(vty, "  Member                 State\n");
5338
0
  }
5339
5340
0
  for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
5341
0
    pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
5342
0
    if (mbr->mp) {
5343
0
      state = mbr->mp->state;
5344
0
    } else {
5345
0
      state = PIM_MSDP_DISABLED;
5346
0
    }
5347
0
    pim_msdp_state_dump(state, state_str, sizeof(state_str));
5348
0
    if (json) {
5349
0
      json_row = json_object_new_object();
5350
0
      json_object_string_add(json_row, "member", mbr_str);
5351
0
      json_object_string_add(json_row, "state", state_str);
5352
0
      if (!json_members) {
5353
0
        json_members = json_object_new_object();
5354
0
        json_object_object_add(json_mg_row, "members",
5355
0
                   json_members);
5356
0
      }
5357
0
      json_object_object_add(json_members, mbr_str, json_row);
5358
0
    } else {
5359
0
      vty_out(vty, "  %-15s  %11s\n", mbr_str, state_str);
5360
0
    }
5361
0
  }
5362
5363
0
  if (json)
5364
0
    json_object_object_add(json, mg->mesh_group_name, json_mg_row);
5365
0
}
5366
5367
DEFUN (show_ip_msdp_mesh_group,
5368
       show_ip_msdp_mesh_group_cmd,
5369
       "show ip msdp [vrf NAME] mesh-group [json]",
5370
       SHOW_STR
5371
       IP_STR
5372
       MSDP_STR
5373
       VRF_CMD_HELP_STR
5374
       "MSDP mesh-group information\n"
5375
       JSON_STR)
5376
0
{
5377
0
  bool uj = use_json(argc, argv);
5378
0
  int idx = 2;
5379
0
  struct pim_msdp_mg *mg;
5380
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
5381
0
  struct pim_instance *pim;
5382
0
  struct json_object *json = NULL;
5383
5384
0
  if (!vrf)
5385
0
    return CMD_WARNING;
5386
5387
0
  pim = vrf->info;
5388
  /* Quick case: list is empty. */
5389
0
  if (SLIST_EMPTY(&pim->msdp.mglist)) {
5390
0
    if (uj)
5391
0
      vty_out(vty, "{}\n");
5392
5393
0
    return CMD_SUCCESS;
5394
0
  }
5395
5396
0
  if (uj)
5397
0
    json = json_object_new_object();
5398
5399
0
  SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
5400
0
    ip_msdp_show_mesh_group(vty, mg, json);
5401
5402
0
  if (uj)
5403
0
    vty_json(vty, json);
5404
5405
0
  return CMD_SUCCESS;
5406
0
}
5407
5408
DEFUN (show_ip_msdp_mesh_group_vrf_all,
5409
       show_ip_msdp_mesh_group_vrf_all_cmd,
5410
       "show ip msdp vrf all mesh-group [json]",
5411
       SHOW_STR
5412
       IP_STR
5413
       MSDP_STR
5414
       VRF_CMD_HELP_STR
5415
       "MSDP mesh-group information\n"
5416
       JSON_STR)
5417
0
{
5418
0
  bool uj = use_json(argc, argv);
5419
0
  struct json_object *json = NULL, *vrf_json = NULL;
5420
0
  struct pim_instance *pim;
5421
0
  struct pim_msdp_mg *mg;
5422
0
  struct vrf *vrf;
5423
5424
0
  if (uj)
5425
0
    json = json_object_new_object();
5426
5427
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5428
0
    if (uj) {
5429
0
      vrf_json = json_object_new_object();
5430
0
      json_object_object_add(json, vrf->name, vrf_json);
5431
0
    } else
5432
0
      vty_out(vty, "VRF: %s\n", vrf->name);
5433
5434
0
    pim = vrf->info;
5435
0
    SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
5436
0
      ip_msdp_show_mesh_group(vty, mg, vrf_json);
5437
0
  }
5438
5439
0
  if (uj)
5440
0
    vty_json(vty, json);
5441
5442
5443
0
  return CMD_SUCCESS;
5444
0
}
5445
5446
static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
5447
             bool uj)
5448
0
{
5449
0
  struct listnode *mpnode;
5450
0
  struct pim_msdp_peer *mp;
5451
0
  char peer_str[INET_ADDRSTRLEN];
5452
0
  char local_str[INET_ADDRSTRLEN];
5453
0
  char state_str[PIM_MSDP_STATE_STRLEN];
5454
0
  char timebuf[PIM_MSDP_UPTIME_STRLEN];
5455
0
  int64_t now;
5456
0
  json_object *json = NULL;
5457
0
  json_object *json_row = NULL;
5458
5459
5460
0
  if (uj) {
5461
0
    json = json_object_new_object();
5462
0
  } else {
5463
0
    vty_out(vty,
5464
0
      "Peer                       Local        State    Uptime   SaCnt\n");
5465
0
  }
5466
5467
0
  for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
5468
0
    if (mp->state == PIM_MSDP_ESTABLISHED) {
5469
0
      now = pim_time_monotonic_sec();
5470
0
      pim_time_uptime(timebuf, sizeof(timebuf),
5471
0
          now - mp->uptime);
5472
0
    } else {
5473
0
      strlcpy(timebuf, "-", sizeof(timebuf));
5474
0
    }
5475
0
    pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5476
0
    pim_inet4_dump("<local?>", mp->local, local_str,
5477
0
             sizeof(local_str));
5478
0
    pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5479
0
    if (uj) {
5480
0
      json_row = json_object_new_object();
5481
0
      json_object_string_add(json_row, "peer", peer_str);
5482
0
      json_object_string_add(json_row, "local", local_str);
5483
0
      json_object_string_add(json_row, "state", state_str);
5484
0
      json_object_string_add(json_row, "upTime", timebuf);
5485
0
      json_object_int_add(json_row, "saCount", mp->sa_cnt);
5486
0
      json_object_object_add(json, peer_str, json_row);
5487
0
    } else {
5488
0
      vty_out(vty, "%-15s  %15s  %11s  %8s  %6d\n", peer_str,
5489
0
        local_str, state_str, timebuf, mp->sa_cnt);
5490
0
    }
5491
0
  }
5492
5493
0
  if (uj)
5494
0
    vty_json(vty, json);
5495
0
}
5496
5497
static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
5498
              const char *peer, bool uj)
5499
0
{
5500
0
  struct listnode *mpnode;
5501
0
  struct pim_msdp_peer *mp;
5502
0
  char peer_str[INET_ADDRSTRLEN];
5503
0
  char local_str[INET_ADDRSTRLEN];
5504
0
  char state_str[PIM_MSDP_STATE_STRLEN];
5505
0
  char timebuf[PIM_MSDP_UPTIME_STRLEN];
5506
0
  char katimer[PIM_MSDP_TIMER_STRLEN];
5507
0
  char crtimer[PIM_MSDP_TIMER_STRLEN];
5508
0
  char holdtimer[PIM_MSDP_TIMER_STRLEN];
5509
0
  int64_t now;
5510
0
  json_object *json = NULL;
5511
0
  json_object *json_row = NULL;
5512
5513
0
  if (uj) {
5514
0
    json = json_object_new_object();
5515
0
  }
5516
5517
0
  for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
5518
0
    pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
5519
0
    if (strcmp(peer, "detail") && strcmp(peer, peer_str))
5520
0
      continue;
5521
5522
0
    if (mp->state == PIM_MSDP_ESTABLISHED) {
5523
0
      now = pim_time_monotonic_sec();
5524
0
      pim_time_uptime(timebuf, sizeof(timebuf),
5525
0
          now - mp->uptime);
5526
0
    } else {
5527
0
      strlcpy(timebuf, "-", sizeof(timebuf));
5528
0
    }
5529
0
    pim_inet4_dump("<local?>", mp->local, local_str,
5530
0
             sizeof(local_str));
5531
0
    pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
5532
0
    pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
5533
0
           mp->ka_timer);
5534
0
    pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
5535
0
           mp->cr_timer);
5536
0
    pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
5537
0
           mp->hold_timer);
5538
5539
0
    if (uj) {
5540
0
      json_row = json_object_new_object();
5541
0
      json_object_string_add(json_row, "peer", peer_str);
5542
0
      json_object_string_add(json_row, "local", local_str);
5543
0
      if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
5544
0
        json_object_string_add(json_row,
5545
0
                   "meshGroupName",
5546
0
                   mp->mesh_group_name);
5547
0
      json_object_string_add(json_row, "state", state_str);
5548
0
      json_object_string_add(json_row, "upTime", timebuf);
5549
0
      json_object_string_add(json_row, "keepAliveTimer",
5550
0
                 katimer);
5551
0
      json_object_string_add(json_row, "connRetryTimer",
5552
0
                 crtimer);
5553
0
      json_object_string_add(json_row, "holdTimer",
5554
0
                 holdtimer);
5555
0
      json_object_string_add(json_row, "lastReset",
5556
0
                 mp->last_reset);
5557
0
      json_object_int_add(json_row, "connAttempts",
5558
0
              mp->conn_attempts);
5559
0
      json_object_int_add(json_row, "establishedChanges",
5560
0
              mp->est_flaps);
5561
0
      json_object_int_add(json_row, "saCount", mp->sa_cnt);
5562
0
      json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
5563
0
      json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
5564
0
      json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
5565
0
      json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
5566
0
      json_object_object_add(json, peer_str, json_row);
5567
0
    } else {
5568
0
      vty_out(vty, "Peer : %s\n", peer_str);
5569
0
      vty_out(vty, "  Local               : %s\n", local_str);
5570
0
      if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
5571
0
        vty_out(vty, "  Mesh Group          : %s\n",
5572
0
          mp->mesh_group_name);
5573
0
      vty_out(vty, "  State               : %s\n", state_str);
5574
0
      vty_out(vty, "  Uptime              : %s\n", timebuf);
5575
5576
0
      vty_out(vty, "  Keepalive Timer     : %s\n", katimer);
5577
0
      vty_out(vty, "  Conn Retry Timer    : %s\n", crtimer);
5578
0
      vty_out(vty, "  Hold Timer          : %s\n", holdtimer);
5579
0
      vty_out(vty, "  Last Reset          : %s\n",
5580
0
        mp->last_reset);
5581
0
      vty_out(vty, "  Conn Attempts       : %d\n",
5582
0
        mp->conn_attempts);
5583
0
      vty_out(vty, "  Established Changes : %d\n",
5584
0
        mp->est_flaps);
5585
0
      vty_out(vty, "  SA Count            : %d\n",
5586
0
        mp->sa_cnt);
5587
0
      vty_out(vty, "  Statistics          :\n");
5588
0
      vty_out(vty,
5589
0
        "                       Sent       Rcvd\n");
5590
0
      vty_out(vty, "    Keepalives : %10d %10d\n",
5591
0
        mp->ka_tx_cnt, mp->ka_rx_cnt);
5592
0
      vty_out(vty, "    SAs        : %10d %10d\n",
5593
0
        mp->sa_tx_cnt, mp->sa_rx_cnt);
5594
0
      vty_out(vty, "\n");
5595
0
    }
5596
0
  }
5597
5598
0
  if (uj)
5599
0
    vty_json(vty, json);
5600
0
}
5601
5602
DEFUN (show_ip_msdp_peer_detail,
5603
       show_ip_msdp_peer_detail_cmd,
5604
       "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
5605
       SHOW_STR
5606
       IP_STR
5607
       MSDP_STR
5608
       VRF_CMD_HELP_STR
5609
       "MSDP peer information\n"
5610
       "Detailed output\n"
5611
       "peer ip address\n"
5612
       JSON_STR)
5613
0
{
5614
0
  bool uj = use_json(argc, argv);
5615
0
  int idx = 2;
5616
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
5617
5618
0
  if (!vrf)
5619
0
    return CMD_WARNING;
5620
5621
0
  char *arg = NULL;
5622
5623
0
  if (argv_find(argv, argc, "detail", &idx))
5624
0
    arg = argv[idx]->text;
5625
0
  else if (argv_find(argv, argc, "A.B.C.D", &idx))
5626
0
    arg = argv[idx]->arg;
5627
5628
0
  if (arg)
5629
0
    ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
5630
0
  else
5631
0
    ip_msdp_show_peers(vrf->info, vty, uj);
5632
5633
0
  return CMD_SUCCESS;
5634
0
}
5635
5636
DEFUN (show_ip_msdp_peer_detail_vrf_all,
5637
       show_ip_msdp_peer_detail_vrf_all_cmd,
5638
       "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
5639
       SHOW_STR
5640
       IP_STR
5641
       MSDP_STR
5642
       VRF_CMD_HELP_STR
5643
       "MSDP peer information\n"
5644
       "Detailed output\n"
5645
       "peer ip address\n"
5646
       JSON_STR)
5647
0
{
5648
0
  int idx = 2;
5649
0
  bool uj = use_json(argc, argv);
5650
0
  struct vrf *vrf;
5651
0
  bool first = true;
5652
5653
0
  if (uj)
5654
0
    vty_out(vty, "{ ");
5655
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5656
0
    if (uj) {
5657
0
      if (!first)
5658
0
        vty_out(vty, ", ");
5659
0
      vty_out(vty, " \"%s\": ", vrf->name);
5660
0
      first = false;
5661
0
    } else
5662
0
      vty_out(vty, "VRF: %s\n", vrf->name);
5663
0
    if (argv_find(argv, argc, "detail", &idx)
5664
0
        || argv_find(argv, argc, "A.B.C.D", &idx))
5665
0
      ip_msdp_show_peers_detail(vrf->info, vty,
5666
0
              argv[idx]->arg, uj);
5667
0
    else
5668
0
      ip_msdp_show_peers(vrf->info, vty, uj);
5669
0
  }
5670
0
  if (uj)
5671
0
    vty_out(vty, "}\n");
5672
5673
0
  return CMD_SUCCESS;
5674
0
}
5675
5676
static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
5677
0
{
5678
0
  struct listnode *sanode;
5679
0
  struct pim_msdp_sa *sa;
5680
0
  char rp_str[INET_ADDRSTRLEN];
5681
0
  char timebuf[PIM_MSDP_UPTIME_STRLEN];
5682
0
  char spt_str[8];
5683
0
  char local_str[8];
5684
0
  int64_t now;
5685
0
  json_object *json = NULL;
5686
0
  json_object *json_group = NULL;
5687
0
  json_object *json_row = NULL;
5688
5689
0
  if (uj) {
5690
0
    json = json_object_new_object();
5691
0
  } else {
5692
0
    vty_out(vty,
5693
0
      "Source                     Group               RP  Local  SPT    Uptime\n");
5694
0
  }
5695
5696
0
  for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5697
0
    now = pim_time_monotonic_sec();
5698
0
    pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
5699
0
    if (sa->flags & PIM_MSDP_SAF_PEER) {
5700
0
      pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
5701
0
      if (sa->up) {
5702
0
        strlcpy(spt_str, "yes", sizeof(spt_str));
5703
0
      } else {
5704
0
        strlcpy(spt_str, "no", sizeof(spt_str));
5705
0
      }
5706
0
    } else {
5707
0
      strlcpy(rp_str, "-", sizeof(rp_str));
5708
0
      strlcpy(spt_str, "-", sizeof(spt_str));
5709
0
    }
5710
0
    if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5711
0
      strlcpy(local_str, "yes", sizeof(local_str));
5712
0
    } else {
5713
0
      strlcpy(local_str, "no", sizeof(local_str));
5714
0
    }
5715
0
    if (uj) {
5716
0
      char src_str[PIM_ADDRSTRLEN];
5717
0
      char grp_str[PIM_ADDRSTRLEN];
5718
5719
0
      snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
5720
0
           &sa->sg.grp);
5721
0
      snprintfrr(src_str, sizeof(src_str), "%pPAs",
5722
0
           &sa->sg.src);
5723
5724
0
      json_object_object_get_ex(json, grp_str, &json_group);
5725
5726
0
      if (!json_group) {
5727
0
        json_group = json_object_new_object();
5728
0
        json_object_object_add(json, grp_str,
5729
0
                   json_group);
5730
0
      }
5731
5732
0
      json_row = json_object_new_object();
5733
0
      json_object_string_add(json_row, "source", src_str);
5734
0
      json_object_string_add(json_row, "group", grp_str);
5735
0
      json_object_string_add(json_row, "rp", rp_str);
5736
0
      json_object_string_add(json_row, "local", local_str);
5737
0
      json_object_string_add(json_row, "sptSetup", spt_str);
5738
0
      json_object_string_add(json_row, "upTime", timebuf);
5739
0
      json_object_object_add(json_group, src_str, json_row);
5740
0
    } else {
5741
0
      vty_out(vty, "%-15pPAs  %15pPAs  %15s  %5c  %3c  %8s\n",
5742
0
        &sa->sg.src, &sa->sg.grp, rp_str, local_str[0],
5743
0
        spt_str[0], timebuf);
5744
0
    }
5745
0
  }
5746
5747
0
  if (uj)
5748
0
    vty_json(vty, json);
5749
0
}
5750
5751
static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
5752
           const char *src_str,
5753
           const char *grp_str, struct vty *vty,
5754
           bool uj, json_object *json)
5755
0
{
5756
0
  char rp_str[INET_ADDRSTRLEN];
5757
0
  char peer_str[INET_ADDRSTRLEN];
5758
0
  char timebuf[PIM_MSDP_UPTIME_STRLEN];
5759
0
  char spt_str[8];
5760
0
  char local_str[8];
5761
0
  char statetimer[PIM_MSDP_TIMER_STRLEN];
5762
0
  int64_t now;
5763
0
  json_object *json_group = NULL;
5764
0
  json_object *json_row = NULL;
5765
5766
0
  now = pim_time_monotonic_sec();
5767
0
  pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
5768
0
  if (sa->flags & PIM_MSDP_SAF_PEER) {
5769
0
    pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
5770
0
    pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
5771
0
    if (sa->up) {
5772
0
      strlcpy(spt_str, "yes", sizeof(spt_str));
5773
0
    } else {
5774
0
      strlcpy(spt_str, "no", sizeof(spt_str));
5775
0
    }
5776
0
  } else {
5777
0
    strlcpy(rp_str, "-", sizeof(rp_str));
5778
0
    strlcpy(peer_str, "-", sizeof(peer_str));
5779
0
    strlcpy(spt_str, "-", sizeof(spt_str));
5780
0
  }
5781
0
  if (sa->flags & PIM_MSDP_SAF_LOCAL) {
5782
0
    strlcpy(local_str, "yes", sizeof(local_str));
5783
0
  } else {
5784
0
    strlcpy(local_str, "no", sizeof(local_str));
5785
0
  }
5786
0
  pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
5787
0
         sa->sa_state_timer);
5788
0
  if (uj) {
5789
0
    json_object_object_get_ex(json, grp_str, &json_group);
5790
5791
0
    if (!json_group) {
5792
0
      json_group = json_object_new_object();
5793
0
      json_object_object_add(json, grp_str, json_group);
5794
0
    }
5795
5796
0
    json_row = json_object_new_object();
5797
0
    json_object_string_add(json_row, "source", src_str);
5798
0
    json_object_string_add(json_row, "group", grp_str);
5799
0
    json_object_string_add(json_row, "rp", rp_str);
5800
0
    json_object_string_add(json_row, "local", local_str);
5801
0
    json_object_string_add(json_row, "sptSetup", spt_str);
5802
0
    json_object_string_add(json_row, "upTime", timebuf);
5803
0
    json_object_string_add(json_row, "stateTimer", statetimer);
5804
0
    json_object_object_add(json_group, src_str, json_row);
5805
0
  } else {
5806
0
    vty_out(vty, "SA : %s\n", sa->sg_str);
5807
0
    vty_out(vty, "  RP          : %s\n", rp_str);
5808
0
    vty_out(vty, "  Peer        : %s\n", peer_str);
5809
0
    vty_out(vty, "  Local       : %s\n", local_str);
5810
0
    vty_out(vty, "  SPT Setup   : %s\n", spt_str);
5811
0
    vty_out(vty, "  Uptime      : %s\n", timebuf);
5812
0
    vty_out(vty, "  State Timer : %s\n", statetimer);
5813
0
    vty_out(vty, "\n");
5814
0
  }
5815
0
}
5816
5817
static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
5818
           bool uj)
5819
0
{
5820
0
  struct listnode *sanode;
5821
0
  struct pim_msdp_sa *sa;
5822
0
  json_object *json = NULL;
5823
5824
0
  if (uj) {
5825
0
    json = json_object_new_object();
5826
0
  }
5827
5828
0
  for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5829
0
    char src_str[PIM_ADDRSTRLEN];
5830
0
    char grp_str[PIM_ADDRSTRLEN];
5831
5832
0
    snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
5833
0
    snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
5834
5835
0
    ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
5836
0
               json);
5837
0
  }
5838
5839
0
  if (uj)
5840
0
    vty_json(vty, json);
5841
0
}
5842
5843
DEFUN (show_ip_msdp_sa_detail,
5844
       show_ip_msdp_sa_detail_cmd,
5845
       "show ip msdp [vrf NAME] sa detail [json]",
5846
       SHOW_STR
5847
       IP_STR
5848
       MSDP_STR
5849
       VRF_CMD_HELP_STR
5850
       "MSDP active-source information\n"
5851
       "Detailed output\n"
5852
       JSON_STR)
5853
0
{
5854
0
  bool uj = use_json(argc, argv);
5855
0
  int idx = 2;
5856
0
  struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
5857
5858
0
  if (!vrf)
5859
0
    return CMD_WARNING;
5860
5861
0
  ip_msdp_show_sa_detail(vrf->info, vty, uj);
5862
5863
0
  return CMD_SUCCESS;
5864
0
}
5865
5866
DEFUN (show_ip_msdp_sa_detail_vrf_all,
5867
       show_ip_msdp_sa_detail_vrf_all_cmd,
5868
       "show ip msdp vrf all sa detail [json]",
5869
       SHOW_STR
5870
       IP_STR
5871
       MSDP_STR
5872
       VRF_CMD_HELP_STR
5873
       "MSDP active-source information\n"
5874
       "Detailed output\n"
5875
       JSON_STR)
5876
0
{
5877
0
  bool uj = use_json(argc, argv);
5878
0
  struct vrf *vrf;
5879
0
  bool first = true;
5880
5881
0
  if (uj)
5882
0
    vty_out(vty, "{ ");
5883
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
5884
0
    if (uj) {
5885
0
      if (!first)
5886
0
        vty_out(vty, ", ");
5887
0
      vty_out(vty, " \"%s\": ", vrf->name);
5888
0
      first = false;
5889
0
    } else
5890
0
      vty_out(vty, "VRF: %s\n", vrf->name);
5891
0
    ip_msdp_show_sa_detail(vrf->info, vty, uj);
5892
0
  }
5893
0
  if (uj)
5894
0
    vty_out(vty, "}\n");
5895
5896
0
  return CMD_SUCCESS;
5897
0
}
5898
5899
static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
5900
         const char *addr, bool uj)
5901
0
{
5902
0
  struct listnode *sanode;
5903
0
  struct pim_msdp_sa *sa;
5904
0
  json_object *json = NULL;
5905
5906
0
  if (uj) {
5907
0
    json = json_object_new_object();
5908
0
  }
5909
5910
0
  for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5911
0
    char src_str[PIM_ADDRSTRLEN];
5912
0
    char grp_str[PIM_ADDRSTRLEN];
5913
5914
0
    snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
5915
0
    snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
5916
5917
0
    if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
5918
0
      ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
5919
0
                 uj, json);
5920
0
    }
5921
0
  }
5922
5923
0
  if (uj)
5924
0
    vty_json(vty, json);
5925
0
}
5926
5927
static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
5928
             const char *src, const char *grp, bool uj)
5929
0
{
5930
0
  struct listnode *sanode;
5931
0
  struct pim_msdp_sa *sa;
5932
0
  json_object *json = NULL;
5933
5934
0
  if (uj) {
5935
0
    json = json_object_new_object();
5936
0
  }
5937
5938
0
  for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
5939
0
    char src_str[PIM_ADDRSTRLEN];
5940
0
    char grp_str[PIM_ADDRSTRLEN];
5941
5942
0
    snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
5943
0
    snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
5944
5945
0
    if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
5946
0
      ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
5947
0
                 uj, json);
5948
0
    }
5949
0
  }
5950
5951
0
  if (uj)
5952
0
    vty_json(vty, json);
5953
0
}
5954
5955
DEFUN (show_ip_msdp_sa_sg,
5956
       show_ip_msdp_sa_sg_cmd,
5957
       "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
5958
       SHOW_STR
5959
       IP_STR
5960
       MSDP_STR
5961
       VRF_CMD_HELP_STR
5962
       "MSDP active-source information\n"
5963
       "source or group ip\n"
5964
       "group ip\n"
5965
       JSON_STR)
5966
0
{
5967
0
  bool uj = use_json(argc, argv);
5968
0
  struct vrf *vrf;
5969
0
  int idx = 2;
5970
5971
0
  vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
5972
5973
0
  if (!vrf)
5974
0
    return CMD_WARNING;
5975
5976
0
  char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
5977
0
    : NULL;
5978
0
  char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
5979
0
    ? argv[idx]->arg
5980
0
    : NULL;
5981
5982
0
  if (src_ip && grp_ip)
5983
0
    ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
5984
0
  else if (src_ip)
5985
0
    ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
5986
0
  else
5987
0
    ip_msdp_show_sa(vrf->info, vty, uj);
5988
5989
0
  return CMD_SUCCESS;
5990
0
}
5991
5992
DEFUN (show_ip_msdp_sa_sg_vrf_all,
5993
       show_ip_msdp_sa_sg_vrf_all_cmd,
5994
       "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
5995
       SHOW_STR
5996
       IP_STR
5997
       MSDP_STR
5998
       VRF_CMD_HELP_STR
5999
       "MSDP active-source information\n"
6000
       "source or group ip\n"
6001
       "group ip\n"
6002
       JSON_STR)
6003
0
{
6004
0
  bool uj = use_json(argc, argv);
6005
0
  struct vrf *vrf;
6006
0
  bool first = true;
6007
0
  int idx = 2;
6008
6009
0
  char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
6010
0
    : NULL;
6011
0
  char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
6012
0
    ? argv[idx]->arg
6013
0
    : NULL;
6014
6015
0
  if (uj)
6016
0
    vty_out(vty, "{ ");
6017
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
6018
0
    if (uj) {
6019
0
      if (!first)
6020
0
        vty_out(vty, ", ");
6021
0
      vty_out(vty, " \"%s\": ", vrf->name);
6022
0
      first = false;
6023
0
    } else
6024
0
      vty_out(vty, "VRF: %s\n", vrf->name);
6025
6026
0
    if (src_ip && grp_ip)
6027
0
      ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
6028
0
    else if (src_ip)
6029
0
      ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
6030
0
    else
6031
0
      ip_msdp_show_sa(vrf->info, vty, uj);
6032
0
  }
6033
0
  if (uj)
6034
0
    vty_out(vty, "}\n");
6035
6036
0
  return CMD_SUCCESS;
6037
0
}
6038
6039
struct pim_sg_cache_walk_data {
6040
  struct vty *vty;
6041
  json_object *json;
6042
  json_object *json_group;
6043
  struct in_addr addr;
6044
  bool addr_match;
6045
};
6046
6047
static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
6048
            struct pim_sg_cache_walk_data *cwd)
6049
0
{
6050
0
  struct vty *vty = cwd->vty;
6051
0
  json_object *json = cwd->json;
6052
0
  json_object *json_row;
6053
0
  bool installed = (vxlan_sg->up) ? true : false;
6054
0
  const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
6055
0
  const char *oif_name;
6056
6057
0
  if (pim_vxlan_is_orig_mroute(vxlan_sg))
6058
0
    oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
6059
0
  else
6060
0
    oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
6061
6062
0
  if (cwd->addr_match && pim_addr_cmp(vxlan_sg->sg.src, cwd->addr) &&
6063
0
      pim_addr_cmp(vxlan_sg->sg.grp, cwd->addr)) {
6064
0
    return;
6065
0
  }
6066
0
  if (json) {
6067
0
    char src_str[PIM_ADDRSTRLEN];
6068
0
    char grp_str[PIM_ADDRSTRLEN];
6069
6070
0
    snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
6071
0
         &vxlan_sg->sg.grp);
6072
0
    snprintfrr(src_str, sizeof(src_str), "%pPAs",
6073
0
         &vxlan_sg->sg.src);
6074
6075
0
    json_object_object_get_ex(json, grp_str, &cwd->json_group);
6076
6077
0
    if (!cwd->json_group) {
6078
0
      cwd->json_group = json_object_new_object();
6079
0
      json_object_object_add(json, grp_str,
6080
0
                 cwd->json_group);
6081
0
    }
6082
6083
0
    json_row = json_object_new_object();
6084
0
    json_object_string_add(json_row, "source", src_str);
6085
0
    json_object_string_add(json_row, "group", grp_str);
6086
0
    json_object_string_add(json_row, "input", iif_name);
6087
0
    json_object_string_add(json_row, "output", oif_name);
6088
0
    if (installed)
6089
0
      json_object_boolean_true_add(json_row, "installed");
6090
0
    else
6091
0
      json_object_boolean_false_add(json_row, "installed");
6092
0
    json_object_object_add(cwd->json_group, src_str, json_row);
6093
0
  } else {
6094
0
    vty_out(vty, "%-15pPAs %-15pPAs %-15s %-15s %-5s\n",
6095
0
      &vxlan_sg->sg.src, &vxlan_sg->sg.grp, iif_name,
6096
0
      oif_name, installed ? "I" : "");
6097
0
  }
6098
0
}
6099
6100
static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *bucket, void *arg)
6101
0
{
6102
0
  pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)bucket->data,
6103
0
        (struct pim_sg_cache_walk_data *)arg);
6104
0
}
6105
6106
static void pim_show_vxlan_sg(struct pim_instance *pim,
6107
            struct vty *vty, bool uj)
6108
0
{
6109
0
  json_object *json = NULL;
6110
0
  struct pim_sg_cache_walk_data cwd;
6111
6112
0
  if (uj) {
6113
0
    json = json_object_new_object();
6114
0
  } else {
6115
0
    vty_out(vty, "Codes: I -> installed\n");
6116
0
    vty_out(vty,
6117
0
      "Source          Group           Input           Output          Flags\n");
6118
0
  }
6119
6120
0
  memset(&cwd, 0, sizeof(cwd));
6121
0
  cwd.vty = vty;
6122
0
  cwd.json = json;
6123
0
  hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
6124
6125
0
  if (uj)
6126
0
    vty_json(vty, json);
6127
0
}
6128
6129
static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
6130
           struct vty *vty, char *addr_str,
6131
           bool uj)
6132
0
{
6133
0
  json_object *json = NULL;
6134
0
  struct pim_sg_cache_walk_data cwd;
6135
0
  int result = 0;
6136
6137
0
  memset(&cwd, 0, sizeof(cwd));
6138
0
  result = inet_pton(AF_INET, addr_str, &cwd.addr);
6139
0
  if (result <= 0) {
6140
0
    vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
6141
0
      errno, safe_strerror(errno));
6142
0
    return;
6143
0
  }
6144
6145
0
  if (uj) {
6146
0
    json = json_object_new_object();
6147
0
  } else {
6148
0
    vty_out(vty, "Codes: I -> installed\n");
6149
0
    vty_out(vty,
6150
0
      "Source          Group           Input           Output          Flags\n");
6151
0
  }
6152
6153
0
  cwd.vty = vty;
6154
0
  cwd.json = json;
6155
0
  cwd.addr_match = true;
6156
0
  hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
6157
6158
0
  if (uj)
6159
0
    vty_json(vty, json);
6160
0
}
6161
6162
static void pim_show_vxlan_sg_one(struct pim_instance *pim,
6163
          struct vty *vty, char *src_str, char *grp_str,
6164
          bool uj)
6165
0
{
6166
0
  json_object *json = NULL;
6167
0
  pim_sgaddr sg;
6168
0
  int result = 0;
6169
0
  struct pim_vxlan_sg *vxlan_sg;
6170
0
  const char *iif_name;
6171
0
  bool installed;
6172
0
  const char *oif_name;
6173
6174
0
  result = inet_pton(AF_INET, src_str, &sg.src);
6175
0
  if (result <= 0) {
6176
0
    vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
6177
0
      errno, safe_strerror(errno));
6178
0
    return;
6179
0
  }
6180
0
  result = inet_pton(AF_INET, grp_str, &sg.grp);
6181
0
  if (result <= 0) {
6182
0
    vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
6183
0
      errno, safe_strerror(errno));
6184
0
    return;
6185
0
  }
6186
6187
0
  if (uj)
6188
0
    json = json_object_new_object();
6189
6190
0
  vxlan_sg = pim_vxlan_sg_find(pim, &sg);
6191
0
  if (vxlan_sg) {
6192
0
    installed = (vxlan_sg->up) ? true : false;
6193
0
    iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
6194
6195
0
    if (pim_vxlan_is_orig_mroute(vxlan_sg))
6196
0
      oif_name =
6197
0
        vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
6198
0
    else
6199
0
      oif_name =
6200
0
        vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
6201
6202
0
    if (uj) {
6203
0
      json_object_string_add(json, "source", src_str);
6204
0
      json_object_string_add(json, "group", grp_str);
6205
0
      json_object_string_add(json, "input", iif_name);
6206
0
      json_object_string_add(json, "output", oif_name);
6207
0
      if (installed)
6208
0
        json_object_boolean_true_add(json, "installed");
6209
0
      else
6210
0
        json_object_boolean_false_add(json,
6211
0
                    "installed");
6212
0
    } else {
6213
0
      vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
6214
0
      vty_out(vty, "  Input     : %s\n", iif_name);
6215
0
      vty_out(vty, "  Output    : %s\n", oif_name);
6216
0
      vty_out(vty, "  installed : %s\n",
6217
0
        installed?"yes":"no");
6218
0
    }
6219
0
  }
6220
6221
0
  if (uj)
6222
0
    vty_json(vty, json);
6223
0
}
6224
6225
DEFUN (show_ip_pim_vxlan_sg,
6226
       show_ip_pim_vxlan_sg_cmd,
6227
       "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
6228
       SHOW_STR
6229
       IP_STR
6230
       PIM_STR
6231
       VRF_CMD_HELP_STR
6232
       "VxLAN BUM groups\n"
6233
       "source or group ip\n"
6234
       "group ip\n"
6235
       JSON_STR)
6236
0
{
6237
0
  bool uj = use_json(argc, argv);
6238
0
  struct vrf *vrf;
6239
0
  int idx = 2;
6240
6241
0
  vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
6242
6243
0
  if (!vrf)
6244
0
    return CMD_WARNING;
6245
6246
0
  char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
6247
0
    argv[idx++]->arg:NULL;
6248
0
  char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
6249
0
    argv[idx]->arg:NULL;
6250
6251
0
  if (src_ip && grp_ip)
6252
0
    pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
6253
0
  else if (src_ip)
6254
0
    pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
6255
0
  else
6256
0
    pim_show_vxlan_sg(vrf->info, vty, uj);
6257
6258
0
  return CMD_SUCCESS;
6259
0
}
6260
6261
static void pim_show_vxlan_sg_work(struct pim_instance *pim,
6262
           struct vty *vty, bool uj)
6263
0
{
6264
0
  json_object *json = NULL;
6265
0
  struct pim_sg_cache_walk_data cwd;
6266
0
  struct listnode *node;
6267
0
  struct pim_vxlan_sg *vxlan_sg;
6268
6269
0
  if (uj) {
6270
0
    json = json_object_new_object();
6271
0
  } else {
6272
0
    vty_out(vty, "Codes: I -> installed\n");
6273
0
    vty_out(vty,
6274
0
      "Source          Group           Input           Flags\n");
6275
0
  }
6276
6277
0
  memset(&cwd, 0, sizeof(cwd));
6278
0
  cwd.vty = vty;
6279
0
  cwd.json = json;
6280
0
  for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
6281
0
    pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
6282
6283
0
  if (uj)
6284
0
    vty_json(vty, json);
6285
0
}
6286
6287
DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
6288
              show_ip_pim_vxlan_sg_work_cmd,
6289
              "show ip pim [vrf NAME] vxlan-work [json]",
6290
              SHOW_STR
6291
              IP_STR
6292
              PIM_STR
6293
              VRF_CMD_HELP_STR
6294
              "VxLAN work list\n"
6295
              JSON_STR)
6296
0
{
6297
0
  bool uj = use_json(argc, argv);
6298
0
  struct vrf *vrf;
6299
0
  int idx = 2;
6300
6301
0
  vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx, uj);
6302
6303
0
  if (!vrf)
6304
0
    return CMD_WARNING;
6305
6306
0
  pim_show_vxlan_sg_work(vrf->info, vty, uj);
6307
6308
0
  return CMD_SUCCESS;
6309
0
}
6310
6311
DEFUN_HIDDEN (no_ip_pim_mlag,
6312
        no_ip_pim_mlag_cmd,
6313
        "no ip pim mlag",
6314
        NO_STR
6315
        IP_STR
6316
        PIM_STR
6317
        "MLAG\n")
6318
0
{
6319
0
  char mlag_xpath[XPATH_MAXLEN];
6320
6321
0
  snprintf(mlag_xpath, sizeof(mlag_xpath), FRR_PIM_VRF_XPATH,
6322
0
     "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6323
0
  strlcat(mlag_xpath, "/mlag", sizeof(mlag_xpath));
6324
6325
0
  nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL);
6326
6327
6328
0
  return nb_cli_apply_changes(vty, NULL);
6329
0
}
6330
6331
DEFUN_HIDDEN (ip_pim_mlag,
6332
        ip_pim_mlag_cmd,
6333
        "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
6334
        IP_STR
6335
        PIM_STR
6336
        "MLAG\n"
6337
        "peerlink sub interface\n"
6338
        "MLAG role\n"
6339
        "MLAG role primary\n"
6340
        "MLAG role secondary\n"
6341
        "peer session state\n"
6342
        "peer session state up\n"
6343
        "peer session state down\n"
6344
        "configure PIP\n"
6345
        "unique ip address\n")
6346
0
{
6347
0
  int idx;
6348
0
  char mlag_peerlink_rif_xpath[XPATH_MAXLEN];
6349
0
  char mlag_my_role_xpath[XPATH_MAXLEN];
6350
0
  char mlag_peer_state_xpath[XPATH_MAXLEN];
6351
0
  char mlag_reg_address_xpath[XPATH_MAXLEN];
6352
6353
0
  snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath),
6354
0
     FRR_PIM_VRF_XPATH,
6355
0
     "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6356
0
  strlcat(mlag_peerlink_rif_xpath, "/mlag/peerlink-rif",
6357
0
    sizeof(mlag_peerlink_rif_xpath));
6358
6359
0
  idx = 3;
6360
0
  nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY,
6361
0
            argv[idx]->arg);
6362
6363
0
  snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath),
6364
0
     FRR_PIM_VRF_XPATH,
6365
0
     "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6366
0
  strlcat(mlag_my_role_xpath, "/mlag/my-role",
6367
0
    sizeof(mlag_my_role_xpath));
6368
6369
0
  idx += 2;
6370
0
  if (!strcmp(argv[idx]->arg, "primary")) {
6371
0
    nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
6372
0
              "MLAG_ROLE_PRIMARY");
6373
6374
0
  } else if (!strcmp(argv[idx]->arg, "secondary")) {
6375
0
    nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
6376
0
              "MLAG_ROLE_SECONDARY");
6377
6378
0
  } else {
6379
0
    vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
6380
0
    return CMD_WARNING;
6381
0
  }
6382
6383
0
  snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath),
6384
0
     FRR_PIM_VRF_XPATH,
6385
0
     "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6386
0
  strlcat(mlag_peer_state_xpath, "/mlag/peer-state",
6387
0
    sizeof(mlag_peer_state_xpath));
6388
6389
0
  idx += 2;
6390
0
  if (!strcmp(argv[idx]->arg, "up")) {
6391
0
    nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
6392
0
              "true");
6393
6394
0
  } else if (strcmp(argv[idx]->arg, "down")) {
6395
0
    nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
6396
0
              "false");
6397
6398
0
  } else {
6399
0
    vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
6400
0
    return CMD_WARNING;
6401
0
  }
6402
6403
0
  snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath),
6404
0
     FRR_PIM_VRF_XPATH,
6405
0
     "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
6406
0
  strlcat(mlag_reg_address_xpath, "/mlag/reg-address",
6407
0
    sizeof(mlag_reg_address_xpath));
6408
6409
0
  idx += 2;
6410
0
  nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY,
6411
0
            argv[idx]->arg);
6412
6413
0
  return nb_cli_apply_changes(vty, NULL);
6414
0
}
6415
6416
void pim_cmd_init(void)
6417
1
{
6418
1
  if_cmd_init(pim_interface_config_write);
6419
6420
1
  install_node(&debug_node);
6421
6422
1
  install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
6423
6424
1
  install_element(CONFIG_NODE, &ip_pim_rp_cmd);
6425
1
  install_element(VRF_NODE, &ip_pim_rp_cmd);
6426
1
  install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
6427
1
  install_element(VRF_NODE, &no_ip_pim_rp_cmd);
6428
1
  install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
6429
1
  install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
6430
1
  install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
6431
1
  install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
6432
1
  install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
6433
1
  install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
6434
1
  install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
6435
1
  install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
6436
1
  install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
6437
1
  install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
6438
1
  install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
6439
1
  install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
6440
1
  install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
6441
1
  install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
6442
1
  install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
6443
1
  install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
6444
1
  install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
6445
1
  install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
6446
1
  install_element(CONFIG_NODE,
6447
1
      &no_ip_pim_spt_switchover_infinity_plist_cmd);
6448
1
  install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
6449
1
  install_element(CONFIG_NODE, &pim_register_accept_list_cmd);
6450
1
  install_element(VRF_NODE, &pim_register_accept_list_cmd);
6451
1
  install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
6452
1
  install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
6453
1
  install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
6454
1
  install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
6455
1
  install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
6456
1
  install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
6457
1
  install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
6458
1
  install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
6459
1
  install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
6460
1
  install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
6461
1
  install_element(CONFIG_NODE, &ip_pim_packets_cmd);
6462
1
  install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
6463
1
  install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
6464
1
  install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
6465
1
  install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
6466
1
  install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
6467
1
  install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
6468
1
  install_element(VRF_NODE, &ip_ssmpingd_cmd);
6469
1
  install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
6470
1
  install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
6471
1
  install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
6472
1
  install_element(VRF_NODE, &ip_msdp_peer_cmd);
6473
1
  install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
6474
1
  install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
6475
1
  install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
6476
1
  install_element(VRF_NODE, &ip_pim_ecmp_cmd);
6477
1
  install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
6478
1
  install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
6479
1
  install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
6480
1
  install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
6481
1
  install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
6482
1
  install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
6483
1
  install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
6484
1
  install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
6485
1
  install_element(CONFIG_NODE, &ip_igmp_group_watermark_cmd);
6486
1
  install_element(VRF_NODE, &ip_igmp_group_watermark_cmd);
6487
1
  install_element(CONFIG_NODE, &no_ip_igmp_group_watermark_cmd);
6488
1
  install_element(VRF_NODE, &no_ip_igmp_group_watermark_cmd);
6489
6490
1
  install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
6491
1
  install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
6492
1
  install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
6493
1
  install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
6494
1
  install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
6495
1
  install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
6496
1
  install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
6497
1
  install_element(INTERFACE_NODE,
6498
1
      &interface_no_ip_igmp_query_interval_cmd);
6499
1
  install_element(INTERFACE_NODE,
6500
1
      &interface_ip_igmp_query_max_response_time_cmd);
6501
1
  install_element(INTERFACE_NODE,
6502
1
      &interface_no_ip_igmp_query_max_response_time_cmd);
6503
1
  install_element(INTERFACE_NODE,
6504
1
      &interface_ip_igmp_query_max_response_time_dsec_cmd);
6505
1
  install_element(INTERFACE_NODE,
6506
1
      &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
6507
1
  install_element(INTERFACE_NODE,
6508
1
      &interface_ip_igmp_last_member_query_count_cmd);
6509
1
  install_element(INTERFACE_NODE,
6510
1
      &interface_no_ip_igmp_last_member_query_count_cmd);
6511
1
  install_element(INTERFACE_NODE,
6512
1
      &interface_ip_igmp_last_member_query_interval_cmd);
6513
1
  install_element(INTERFACE_NODE,
6514
1
      &interface_no_ip_igmp_last_member_query_interval_cmd);
6515
1
  install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
6516
1
  install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
6517
1
  install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
6518
1
  install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
6519
1
  install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
6520
1
  install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
6521
1
  install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
6522
1
  install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
6523
1
  install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
6524
1
  install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
6525
1
  install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
6526
1
  install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
6527
1
  install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
6528
1
  install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
6529
6530
  // Static mroutes NEB
6531
1
  install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
6532
1
  install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
6533
6534
1
  install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
6535
1
  install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
6536
1
  install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
6537
1
  install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
6538
1
  install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
6539
1
  install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
6540
1
  install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
6541
1
  install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
6542
1
  install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
6543
1
  install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
6544
1
  install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
6545
1
  install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
6546
1
  install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
6547
1
  install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
6548
1
  install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
6549
1
  install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
6550
1
  install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
6551
1
  install_element(VIEW_NODE, &show_ip_pim_join_cmd);
6552
1
  install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
6553
1
  install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
6554
1
  install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
6555
1
  install_element(VIEW_NODE, &show_ip_pim_mlag_summary_cmd);
6556
1
  install_element(VIEW_NODE, &show_ip_pim_mlag_up_cmd);
6557
1
  install_element(VIEW_NODE, &show_ip_pim_mlag_up_vrf_all_cmd);
6558
1
  install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
6559
1
  install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
6560
1
  install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
6561
1
  install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
6562
1
  install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
6563
1
  install_element(VIEW_NODE, &show_ip_pim_state_cmd);
6564
1
  install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
6565
1
  install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
6566
1
  install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
6567
1
  install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
6568
1
  install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
6569
1
  install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
6570
1
  install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
6571
1
  install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
6572
1
  install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
6573
1
  install_element(VIEW_NODE, &show_ip_multicast_cmd);
6574
1
  install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
6575
1
  install_element(VIEW_NODE, &show_ip_multicast_count_cmd);
6576
1
  install_element(VIEW_NODE, &show_ip_multicast_count_vrf_all_cmd);
6577
1
  install_element(VIEW_NODE, &show_ip_mroute_cmd);
6578
1
  install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
6579
1
  install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
6580
1
  install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
6581
1
  install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
6582
1
  install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
6583
1
  install_element(VIEW_NODE, &show_ip_rib_cmd);
6584
1
  install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
6585
1
  install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
6586
1
  install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
6587
1
  install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
6588
1
  install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
6589
1
  install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
6590
6591
1
  install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
6592
1
  install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
6593
1
  install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
6594
1
  install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
6595
1
  install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
6596
1
  install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
6597
1
  install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
6598
1
  install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
6599
1
  install_element(ENABLE_NODE, &clear_ip_pim_bsr_db_cmd);
6600
6601
1
  install_element(ENABLE_NODE, &show_debugging_pim_cmd);
6602
6603
1
  install_element(ENABLE_NODE, &debug_igmp_cmd);
6604
1
  install_element(ENABLE_NODE, &no_debug_igmp_cmd);
6605
1
  install_element(ENABLE_NODE, &debug_igmp_events_cmd);
6606
1
  install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
6607
1
  install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
6608
1
  install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
6609
1
  install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
6610
1
  install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
6611
1
  install_element(ENABLE_NODE, &debug_igmp_trace_detail_cmd);
6612
1
  install_element(ENABLE_NODE, &no_debug_igmp_trace_detail_cmd);
6613
1
  install_element(ENABLE_NODE, &debug_mroute_cmd);
6614
1
  install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
6615
1
  install_element(ENABLE_NODE, &no_debug_mroute_cmd);
6616
1
  install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
6617
1
  install_element(ENABLE_NODE, &debug_pim_static_cmd);
6618
1
  install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
6619
1
  install_element(ENABLE_NODE, &debug_pim_cmd);
6620
1
  install_element(ENABLE_NODE, &debug_pim_nht_cmd);
6621
1
  install_element(ENABLE_NODE, &debug_pim_nht_det_cmd);
6622
1
  install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
6623
1
  install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
6624
1
  install_element(ENABLE_NODE, &debug_pim_events_cmd);
6625
1
  install_element(ENABLE_NODE, &debug_pim_packets_cmd);
6626
1
  install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
6627
1
  install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
6628
1
  install_element(ENABLE_NODE, &debug_pim_trace_cmd);
6629
1
  install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
6630
1
  install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
6631
1
  install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
6632
1
  install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
6633
1
  install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
6634
1
  install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
6635
1
  install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
6636
1
  install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
6637
1
  install_element(ENABLE_NODE, &debug_msdp_cmd);
6638
1
  install_element(ENABLE_NODE, &no_debug_msdp_cmd);
6639
1
  install_element(ENABLE_NODE, &debug_msdp_events_cmd);
6640
1
  install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
6641
1
  install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
6642
1
  install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
6643
1
  install_element(ENABLE_NODE, &debug_mtrace_cmd);
6644
1
  install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
6645
1
  install_element(ENABLE_NODE, &debug_bsm_cmd);
6646
1
  install_element(ENABLE_NODE, &no_debug_bsm_cmd);
6647
6648
1
  install_element(CONFIG_NODE, &debug_igmp_cmd);
6649
1
  install_element(CONFIG_NODE, &no_debug_igmp_cmd);
6650
1
  install_element(CONFIG_NODE, &debug_igmp_events_cmd);
6651
1
  install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
6652
1
  install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
6653
1
  install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
6654
1
  install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
6655
1
  install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
6656
1
  install_element(CONFIG_NODE, &debug_igmp_trace_detail_cmd);
6657
1
  install_element(CONFIG_NODE, &no_debug_igmp_trace_detail_cmd);
6658
1
  install_element(CONFIG_NODE, &debug_mroute_cmd);
6659
1
  install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
6660
1
  install_element(CONFIG_NODE, &no_debug_mroute_cmd);
6661
1
  install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
6662
1
  install_element(CONFIG_NODE, &debug_pim_static_cmd);
6663
1
  install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
6664
1
  install_element(CONFIG_NODE, &debug_pim_cmd);
6665
1
  install_element(CONFIG_NODE, &debug_pim_nht_cmd);
6666
1
  install_element(CONFIG_NODE, &debug_pim_nht_det_cmd);
6667
1
  install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
6668
1
  install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
6669
1
  install_element(CONFIG_NODE, &debug_pim_events_cmd);
6670
1
  install_element(CONFIG_NODE, &debug_pim_packets_cmd);
6671
1
  install_element(CONFIG_NODE, &debug_pim_packetdump_send_cmd);
6672
1
  install_element(CONFIG_NODE, &debug_pim_packetdump_recv_cmd);
6673
1
  install_element(CONFIG_NODE, &debug_pim_trace_cmd);
6674
1
  install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
6675
1
  install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
6676
1
  install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
6677
1
  install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
6678
1
  install_element(CONFIG_NODE, &debug_pim_mlag_cmd);
6679
1
  install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd);
6680
1
  install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
6681
1
  install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
6682
1
  install_element(CONFIG_NODE, &debug_msdp_cmd);
6683
1
  install_element(CONFIG_NODE, &no_debug_msdp_cmd);
6684
1
  install_element(CONFIG_NODE, &debug_msdp_events_cmd);
6685
1
  install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
6686
1
  install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
6687
1
  install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
6688
1
  install_element(CONFIG_NODE, &debug_mtrace_cmd);
6689
1
  install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
6690
1
  install_element(CONFIG_NODE, &debug_bsm_cmd);
6691
1
  install_element(CONFIG_NODE, &no_debug_bsm_cmd);
6692
6693
1
  install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
6694
1
  install_element(VRF_NODE, &ip_msdp_timers_cmd);
6695
1
  install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd);
6696
1
  install_element(VRF_NODE, &no_ip_msdp_timers_cmd);
6697
1
  install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
6698
1
  install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
6699
1
  install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
6700
1
  install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
6701
1
  install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
6702
1
  install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
6703
1
  install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
6704
1
  install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
6705
1
  install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd);
6706
1
  install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd);
6707
1
  install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
6708
1
  install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
6709
1
  install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
6710
1
  install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
6711
1
  install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
6712
1
  install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
6713
1
  install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
6714
1
  install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
6715
1
  install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
6716
1
  install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
6717
1
  install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
6718
1
  install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
6719
1
  install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
6720
1
  install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
6721
  /* Install BSM command */
6722
1
  install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
6723
1
  install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
6724
1
  install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
6725
1
  install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
6726
  /* Install BFD command */
6727
1
  install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
6728
1
  install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
6729
1
  install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd);
6730
1
  install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
6731
#if HAVE_BFDD == 0
6732
  install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
6733
#endif /* !HAVE_BFDD */
6734
1
}