Coverage Report

Created: 2025-10-23 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/pimd/pim_vty.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 "if.h"
10
#include "linklist.h"
11
#include "prefix.h"
12
#include "vty.h"
13
#include "vrf.h"
14
#include "plist.h"
15
16
#include "pimd.h"
17
#include "pim_vty.h"
18
#include "pim_iface.h"
19
#include "pim_str.h"
20
#include "pim_ssmpingd.h"
21
#include "pim_pim.h"
22
#include "pim_oil.h"
23
#include "pim_static.h"
24
#include "pim_rp.h"
25
#include "pim_msdp.h"
26
#include "pim_ssm.h"
27
#include "pim_bfd.h"
28
#include "pim_bsm.h"
29
#include "pim_vxlan.h"
30
#include "pim6_mld.h"
31
32
int pim_debug_config_write(struct vty *vty)
33
0
{
34
0
  int writes = 0;
35
36
0
  if (PIM_DEBUG_MSDP_EVENTS) {
37
0
    vty_out(vty, "debug msdp events\n");
38
0
    ++writes;
39
0
  }
40
0
  if (PIM_DEBUG_MSDP_PACKETS) {
41
0
    vty_out(vty, "debug msdp packets\n");
42
0
    ++writes;
43
0
  }
44
0
  if (PIM_DEBUG_MSDP_INTERNAL) {
45
0
    vty_out(vty, "debug msdp internal\n");
46
0
    ++writes;
47
0
  }
48
0
  if (PIM_DEBUG_GM_EVENTS) {
49
0
    vty_out(vty, "debug " GM_AF_DBG " events\n");
50
0
    ++writes;
51
0
  }
52
0
  if (PIM_DEBUG_GM_PACKETS) {
53
0
    vty_out(vty, "debug " GM_AF_DBG " packets\n");
54
0
    ++writes;
55
0
  }
56
  /* PIM_DEBUG_GM_TRACE catches _DETAIL too */
57
0
  if (router->debugs & PIM_MASK_GM_TRACE) {
58
0
    vty_out(vty, "debug " GM_AF_DBG " trace\n");
59
0
    ++writes;
60
0
  }
61
0
  if (PIM_DEBUG_GM_TRACE_DETAIL) {
62
0
    vty_out(vty, "debug " GM_AF_DBG " trace detail\n");
63
0
    ++writes;
64
0
  }
65
66
  /* PIM_DEBUG_MROUTE catches _DETAIL too */
67
0
  if (router->debugs & PIM_MASK_MROUTE) {
68
0
    vty_out(vty, "debug " PIM_MROUTE_DBG "\n");
69
0
    ++writes;
70
0
  }
71
0
  if (PIM_DEBUG_MROUTE_DETAIL) {
72
0
    vty_out(vty, "debug " PIM_MROUTE_DBG " detail\n");
73
0
    ++writes;
74
0
  }
75
76
0
  if (PIM_DEBUG_MTRACE) {
77
0
    vty_out(vty, "debug mtrace\n");
78
0
    ++writes;
79
0
  }
80
81
0
  if (PIM_DEBUG_PIM_EVENTS) {
82
0
    vty_out(vty, "debug " PIM_AF_DBG " events\n");
83
0
    ++writes;
84
0
  }
85
0
  if (PIM_DEBUG_PIM_PACKETS) {
86
0
    vty_out(vty, "debug " PIM_AF_DBG " packets\n");
87
0
    ++writes;
88
0
  }
89
0
  if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
90
0
    vty_out(vty, "debug " PIM_AF_DBG " packet-dump send\n");
91
0
    ++writes;
92
0
  }
93
0
  if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
94
0
    vty_out(vty, "debug " PIM_AF_DBG " packet-dump receive\n");
95
0
    ++writes;
96
0
  }
97
98
  /* PIM_DEBUG_PIM_TRACE catches _DETAIL too */
99
0
  if (router->debugs & PIM_MASK_PIM_TRACE) {
100
0
    vty_out(vty, "debug " PIM_AF_DBG " trace\n");
101
0
    ++writes;
102
0
  }
103
0
  if (PIM_DEBUG_PIM_TRACE_DETAIL) {
104
0
    vty_out(vty, "debug " PIM_AF_DBG " trace detail\n");
105
0
    ++writes;
106
0
  }
107
108
0
  if (PIM_DEBUG_ZEBRA) {
109
0
    vty_out(vty, "debug " PIM_AF_DBG " zebra\n");
110
0
    ++writes;
111
0
  }
112
113
0
        if (PIM_DEBUG_MLAG) {
114
0
                vty_out(vty, "debug pim mlag\n");
115
0
                ++writes;
116
0
        }
117
118
0
  if (PIM_DEBUG_BSM) {
119
0
    vty_out(vty, "debug " PIM_AF_DBG " bsm\n");
120
0
    ++writes;
121
0
  }
122
123
0
  if (PIM_DEBUG_VXLAN) {
124
0
    vty_out(vty, "debug " PIM_AF_DBG " vxlan\n");
125
0
    ++writes;
126
0
  }
127
128
0
  if (PIM_DEBUG_SSMPINGD) {
129
0
    vty_out(vty, "debug ssmpingd\n");
130
0
    ++writes;
131
0
  }
132
133
0
  if (PIM_DEBUG_PIM_HELLO) {
134
0
    vty_out(vty, "debug " PIM_AF_DBG " packets hello\n");
135
0
    ++writes;
136
0
  }
137
138
0
  if (PIM_DEBUG_PIM_J_P) {
139
0
    vty_out(vty, "debug " PIM_AF_DBG " packets joins\n");
140
0
    ++writes;
141
0
  }
142
143
0
  if (PIM_DEBUG_PIM_REG) {
144
0
    vty_out(vty, "debug " PIM_AF_DBG " packets register\n");
145
0
    ++writes;
146
0
  }
147
148
0
  if (PIM_DEBUG_STATIC) {
149
0
    vty_out(vty, "debug pim static\n");
150
0
    ++writes;
151
0
  }
152
153
0
  if (PIM_DEBUG_PIM_NHT) {
154
0
    vty_out(vty, "debug " PIM_AF_DBG " nht\n");
155
0
    ++writes;
156
0
  }
157
158
0
  if (PIM_DEBUG_PIM_NHT_RP) {
159
0
    vty_out(vty, "debug pim nht rp\n");
160
0
    ++writes;
161
0
  }
162
163
0
  if (PIM_DEBUG_PIM_NHT_DETAIL) {
164
0
    vty_out(vty, "debug " PIM_AF_DBG " nht detail\n");
165
0
    ++writes;
166
0
  }
167
168
0
  return writes;
169
0
}
170
171
int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
172
0
{
173
0
  int writes = 0;
174
0
  struct pim_ssm *ssm = pim->ssm_info;
175
0
  char spaces[10];
176
177
0
  if (pim->vrf->vrf_id == VRF_DEFAULT)
178
0
    snprintf(spaces, sizeof(spaces), "%s", "");
179
0
  else
180
0
    snprintf(spaces, sizeof(spaces), "%s", " ");
181
182
0
  writes += pim_msdp_peer_config_write(vty, pim, spaces);
183
0
  writes += pim_msdp_config_write(pim, vty, spaces);
184
185
0
  if (!pim->send_v6_secondary) {
186
0
    vty_out(vty, "%sno ip pim send-v6-secondary\n", spaces);
187
0
    ++writes;
188
0
  }
189
190
0
  writes += pim_rp_config_write(pim, vty, spaces);
191
192
0
  if (pim->vrf->vrf_id == VRF_DEFAULT) {
193
0
    if (router->register_suppress_time
194
0
        != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT) {
195
0
      vty_out(vty, "%s" PIM_AF_NAME " pim register-suppress-time %d\n",
196
0
        spaces, router->register_suppress_time);
197
0
      ++writes;
198
0
    }
199
0
    if (router->t_periodic != PIM_DEFAULT_T_PERIODIC) {
200
0
      vty_out(vty, "%s" PIM_AF_NAME " pim join-prune-interval %d\n",
201
0
        spaces, router->t_periodic);
202
0
      ++writes;
203
0
    }
204
205
0
    if (router->packet_process != PIM_DEFAULT_PACKET_PROCESS) {
206
0
      vty_out(vty, "%s" PIM_AF_NAME " pim packets %d\n", spaces,
207
0
        router->packet_process);
208
0
      ++writes;
209
0
    }
210
0
  }
211
0
  if (pim->keep_alive_time != PIM_KEEPALIVE_PERIOD) {
212
0
    vty_out(vty, "%s" PIM_AF_NAME " pim keep-alive-timer %d\n",
213
0
      spaces, pim->keep_alive_time);
214
0
    ++writes;
215
0
  }
216
0
  if (pim->rp_keep_alive_time != (unsigned int)PIM_RP_KEEPALIVE_PERIOD) {
217
0
    vty_out(vty, "%s" PIM_AF_NAME " pim rp keep-alive-timer %d\n",
218
0
      spaces, pim->rp_keep_alive_time);
219
0
    ++writes;
220
0
  }
221
0
  if (ssm->plist_name) {
222
0
    vty_out(vty, "%sip pim ssm prefix-list %s\n", spaces,
223
0
      ssm->plist_name);
224
0
    ++writes;
225
0
  }
226
0
  if (pim->register_plist) {
227
0
    vty_out(vty, "%sip pim register-accept-list %s\n", spaces,
228
0
      pim->register_plist);
229
0
    ++writes;
230
0
  }
231
0
  if (pim->spt.switchover == PIM_SPT_INFINITY) {
232
0
    if (pim->spt.plist)
233
0
      vty_out(vty,
234
0
        "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond prefix-list %s\n",
235
0
        spaces, pim->spt.plist);
236
0
    else
237
0
      vty_out(vty,
238
0
        "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond\n",
239
0
        spaces);
240
0
    ++writes;
241
0
  }
242
0
  if (pim->ecmp_rebalance_enable) {
243
0
    vty_out(vty, "%sip pim ecmp rebalance\n", spaces);
244
0
    ++writes;
245
0
  } else if (pim->ecmp_enable) {
246
0
    vty_out(vty, "%sip pim ecmp\n", spaces);
247
0
    ++writes;
248
0
  }
249
250
0
  if (pim->gm_watermark_limit != 0) {
251
0
#if PIM_IPV == 4
252
0
    vty_out(vty, "%s" PIM_AF_NAME " igmp watermark-warn %u\n",
253
0
      spaces, pim->gm_watermark_limit);
254
#else
255
    vty_out(vty, "%s" PIM_AF_NAME " mld watermark-warn %u\n",
256
      spaces, pim->gm_watermark_limit);
257
#endif
258
0
    ++writes;
259
0
  }
260
261
0
  if (pim->ssmpingd_list) {
262
0
    struct listnode *node;
263
0
    struct ssmpingd_sock *ss;
264
0
    ++writes;
265
0
    for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
266
0
      vty_out(vty, "%s" PIM_AF_NAME " ssmpingd %pPA\n",
267
0
        spaces, &ss->source_addr);
268
0
      ++writes;
269
0
    }
270
0
  }
271
272
0
  if (pim->msdp.hold_time != PIM_MSDP_PEER_HOLD_TIME
273
0
      || pim->msdp.keep_alive != PIM_MSDP_PEER_KA_TIME
274
0
      || pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) {
275
0
    vty_out(vty, "%sip msdp timers %u %u", spaces,
276
0
      pim->msdp.hold_time, pim->msdp.keep_alive);
277
0
    if (pim->msdp.connection_retry
278
0
        != PIM_MSDP_PEER_CONNECT_RETRY_TIME)
279
0
      vty_out(vty, " %u", pim->msdp.connection_retry);
280
0
    vty_out(vty, "\n");
281
0
  }
282
283
0
  return writes;
284
0
}
285
286
#if PIM_IPV == 4
287
static int gm_config_write(struct vty *vty, int writes,
288
         struct pim_interface *pim_ifp)
289
0
{
290
  /* IF ip igmp */
291
0
  if (pim_ifp->gm_enable) {
292
0
    vty_out(vty, " ip igmp\n");
293
0
    ++writes;
294
0
  }
295
296
  /* ip igmp version */
297
0
  if (pim_ifp->igmp_version != IGMP_DEFAULT_VERSION) {
298
0
    vty_out(vty, " ip igmp version %d\n", pim_ifp->igmp_version);
299
0
    ++writes;
300
0
  }
301
302
  /* IF ip igmp query-max-response-time */
303
0
  if (pim_ifp->gm_query_max_response_time_dsec !=
304
0
      GM_QUERY_MAX_RESPONSE_TIME_DSEC) {
305
0
    vty_out(vty, " ip igmp query-max-response-time %d\n",
306
0
      pim_ifp->gm_query_max_response_time_dsec);
307
0
    ++writes;
308
0
  }
309
310
  /* IF ip igmp query-interval */
311
0
  if (pim_ifp->gm_default_query_interval != GM_GENERAL_QUERY_INTERVAL) {
312
0
    vty_out(vty, " ip igmp query-interval %d\n",
313
0
      pim_ifp->gm_default_query_interval);
314
0
    ++writes;
315
0
  }
316
317
  /* IF ip igmp last-member_query-count */
318
0
  if (pim_ifp->gm_last_member_query_count !=
319
0
      GM_DEFAULT_ROBUSTNESS_VARIABLE) {
320
0
    vty_out(vty, " ip igmp last-member-query-count %d\n",
321
0
      pim_ifp->gm_last_member_query_count);
322
0
    ++writes;
323
0
  }
324
325
  /* IF ip igmp last-member_query-interval */
326
0
  if (pim_ifp->gm_specific_query_max_response_time_dsec !=
327
0
      GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC) {
328
0
    vty_out(vty, " ip igmp last-member-query-interval %d\n",
329
0
      pim_ifp->gm_specific_query_max_response_time_dsec);
330
0
    ++writes;
331
0
  }
332
333
  /* IF ip igmp join */
334
0
  if (pim_ifp->gm_join_list) {
335
0
    struct listnode *node;
336
0
    struct gm_join *ij;
337
0
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_join_list, node, ij)) {
338
0
      if (pim_addr_is_any(ij->source_addr))
339
0
        vty_out(vty, " ip igmp join %pPAs\n",
340
0
          &ij->group_addr);
341
0
      else
342
0
        vty_out(vty, " ip igmp join %pPAs %pPAs\n",
343
0
          &ij->group_addr, &ij->source_addr);
344
0
      ++writes;
345
0
    }
346
0
  }
347
348
0
  return writes;
349
0
}
350
#else
351
static int gm_config_write(struct vty *vty, int writes,
352
         struct pim_interface *pim_ifp)
353
{
354
  /* IF ipv6 mld */
355
  if (pim_ifp->gm_enable) {
356
    vty_out(vty, " ipv6 mld\n");
357
    ++writes;
358
  }
359
360
  if (pim_ifp->mld_version != MLD_DEFAULT_VERSION)
361
    vty_out(vty, " ipv6 mld version %d\n", pim_ifp->mld_version);
362
363
  /* IF ipv6 mld query-max-response-time */
364
  if (pim_ifp->gm_query_max_response_time_dsec !=
365
      GM_QUERY_MAX_RESPONSE_TIME_DSEC)
366
    vty_out(vty, " ipv6 mld query-max-response-time %d\n",
367
      pim_ifp->gm_query_max_response_time_dsec);
368
369
  if (pim_ifp->gm_default_query_interval != GM_GENERAL_QUERY_INTERVAL)
370
    vty_out(vty, " ipv6 mld query-interval %d\n",
371
      pim_ifp->gm_default_query_interval);
372
373
  /* IF ipv6 mld last-member_query-count */
374
  if (pim_ifp->gm_last_member_query_count !=
375
      GM_DEFAULT_ROBUSTNESS_VARIABLE)
376
    vty_out(vty, " ipv6 mld last-member-query-count %d\n",
377
      pim_ifp->gm_last_member_query_count);
378
379
  /* IF ipv6 mld last-member_query-interval */
380
  if (pim_ifp->gm_specific_query_max_response_time_dsec !=
381
      GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC)
382
    vty_out(vty, " ipv6 mld last-member-query-interval %d\n",
383
      pim_ifp->gm_specific_query_max_response_time_dsec);
384
385
  /* IF ipv6 mld join */
386
  if (pim_ifp->gm_join_list) {
387
    struct listnode *node;
388
    struct gm_join *ij;
389
    for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_join_list, node, ij)) {
390
      if (pim_addr_is_any(ij->source_addr))
391
        vty_out(vty, " ipv6 mld join %pPAs\n",
392
          &ij->group_addr);
393
      else
394
        vty_out(vty, " ipv6 mld join %pPAs %pPAs\n",
395
          &ij->group_addr, &ij->source_addr);
396
      ++writes;
397
    }
398
  }
399
400
  return writes;
401
}
402
#endif
403
404
int pim_config_write(struct vty *vty, int writes, struct interface *ifp,
405
         struct pim_instance *pim)
406
0
{
407
0
  struct pim_interface *pim_ifp = ifp->info;
408
409
0
  if (pim_ifp->pim_enable) {
410
0
    vty_out(vty, " " PIM_AF_NAME " pim\n");
411
0
    ++writes;
412
0
  }
413
414
  /* IF ip pim drpriority */
415
0
  if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
416
0
    vty_out(vty, " " PIM_AF_NAME " pim drpriority %u\n",
417
0
      pim_ifp->pim_dr_priority);
418
0
    ++writes;
419
0
  }
420
421
  /* IF ip pim hello */
422
0
  if (pim_ifp->pim_hello_period != PIM_DEFAULT_HELLO_PERIOD) {
423
0
    vty_out(vty, " " PIM_AF_NAME " pim hello %d", pim_ifp->pim_hello_period);
424
0
    if (pim_ifp->pim_default_holdtime != -1)
425
0
      vty_out(vty, " %d", pim_ifp->pim_default_holdtime);
426
0
    vty_out(vty, "\n");
427
0
    ++writes;
428
0
  }
429
430
0
  writes += gm_config_write(vty, writes, pim_ifp);
431
432
  /* update source */
433
0
  if (!pim_addr_is_any(pim_ifp->update_source)) {
434
0
    vty_out(vty, " " PIM_AF_NAME " pim use-source %pPA\n",
435
0
      &pim_ifp->update_source);
436
0
    ++writes;
437
0
  }
438
439
0
  if (pim_ifp->activeactive)
440
0
    vty_out(vty, " " PIM_AF_NAME " pim active-active\n");
441
442
  /* boundary */
443
0
  if (pim_ifp->boundary_oil_plist) {
444
0
    vty_out(vty, " " PIM_AF_NAME " multicast boundary oil %s\n",
445
0
      pim_ifp->boundary_oil_plist);
446
0
    ++writes;
447
0
  }
448
449
0
  if (pim_ifp->pim_passive_enable) {
450
0
    vty_out(vty, " " PIM_AF_NAME " pim passive\n");
451
0
    ++writes;
452
0
  }
453
454
0
  writes += pim_static_write_mroute(pim, vty, ifp);
455
0
  pim_bsm_write_config(vty, ifp);
456
0
  ++writes;
457
0
  pim_bfd_write_config(vty, ifp);
458
0
  ++writes;
459
460
0
  return writes;
461
0
}
462
463
int pim_interface_config_write(struct vty *vty)
464
0
{
465
0
  struct pim_instance *pim;
466
0
  struct interface *ifp;
467
0
  struct vrf *vrf;
468
0
  int writes = 0;
469
470
0
  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
471
0
    pim = vrf->info;
472
0
    if (!pim)
473
0
      continue;
474
475
0
    FOR_ALL_INTERFACES (pim->vrf, ifp) {
476
      /* pim is enabled internally/implicitly on the vxlan
477
       * termination device ipmr-lo. skip displaying that
478
       * config to avoid confusion
479
       */
480
0
      if (pim_vxlan_is_term_dev_cfg(pim, ifp))
481
0
        continue;
482
483
      /* IF name */
484
0
      if_vty_config_start(vty, ifp);
485
486
0
      ++writes;
487
488
0
      if (ifp->desc) {
489
0
        vty_out(vty, " description %s\n", ifp->desc);
490
0
        ++writes;
491
0
      }
492
493
0
      if (ifp->info) {
494
0
        pim_config_write(vty, writes, ifp, pim);
495
0
      }
496
0
      if_vty_config_end(vty);
497
498
0
      ++writes;
499
0
    }
500
0
  }
501
502
0
  return writes;
503
0
}