Coverage Report

Created: 2025-11-11 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/bgpd/rfp-example/librfp/rfp_example.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 *
4
 * Copyright 2015-2016, LabN Consulting, L.L.C.
5
 *
6
 */
7
8
#ifdef HAVE_CONFIG_H
9
#include "config.h"
10
#endif
11
12
/* stub rfp */
13
#include "rfp_internal.h"
14
#include "bgpd/rfapi/rfapi.h"
15
#include "lib/command.h"
16
17
struct rfp_instance_t {
18
  struct rfapi_rfp_cfg rfapi_config;
19
  struct rfapi_rfp_cb_methods rfapi_callbacks;
20
  struct event_loop *master;
21
  uint32_t config_var;
22
};
23
24
struct rfp_instance_t
25
  global_rfi; /* dynamically allocate in full implementation */
26
27
/***********************************************************************
28
 * Sample VTY / internal function
29
 **********************************************************************/
30
#define RFP_SHOW_STR "RFP information\n"
31
DEFUN (rfp_example_config_value,
32
       rfp_example_config_value_cmd,
33
       "rfp example-config-value VALUE",
34
       RFP_SHOW_STR
35
       "Example value to be configured\n"
36
       "Value to display\n")
37
0
{
38
0
  uint32_t value = 0;
39
0
  struct rfp_instance_t *rfi = NULL;
40
0
  rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
41
0
  assert(rfi != NULL);
42
43
0
  value = strtoul(argv[2]->arg, NULL, 10);
44
0
  if (rfi)
45
0
    rfi->config_var = value;
46
0
  return CMD_SUCCESS;
47
0
}
48
49
DEFUN (rfp_holddown_factor,
50
       rfp_holddown_factor_cmd,
51
       "rfp holddown-factor (0-4294967295)",
52
       RFP_SHOW_STR
53
       "Set Hold-Down Factor as a percentage of registration lifetime.\n"
54
       "Percentage of registration lifetime\n")
55
0
{
56
0
  struct rfp_instance_t *rfi;
57
0
  uint32_t value = 0;
58
59
0
  value = strtoul((argv[--argc]->arg), NULL, 10);
60
0
  rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
61
0
  if (!rfi) {
62
0
    vty_out(vty, "VNC not configured\n");
63
0
    return CMD_WARNING;
64
0
  }
65
0
  rfi->rfapi_config.holddown_factor = value;
66
0
  rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config);
67
0
  return CMD_SUCCESS;
68
0
}
69
70
71
DEFUN (rfp_full_table_download,
72
       rfp_full_table_download_cmd,
73
       "rfp full-table-download <on|off>",
74
       RFP_SHOW_STR
75
       "RFP full table download support (default=on)\n"
76
       "Enable RFP full table download\n"
77
       "Disable RFP full table download\n")
78
0
{
79
0
  struct rfp_instance_t *rfi;
80
0
  rfapi_rfp_download_type old;
81
82
0
  rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
83
0
  if (!rfi) {
84
0
    vty_out(vty, "VNC not configured\n");
85
0
    return CMD_WARNING;
86
0
  }
87
0
  old = rfi->rfapi_config.download_type;
88
0
  if (argv[--argc]->arg[1] == 'n' || argv[argc]->arg[1] == 'N')
89
0
    rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_FULL;
90
0
  else
91
0
    rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL;
92
0
  if (old != rfi->rfapi_config.download_type)
93
0
    rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config);
94
0
  return CMD_SUCCESS;
95
0
}
96
97
static void rfp_vty_install(void)
98
1
{
99
1
  static int installed = 0;
100
1
  if (installed) /* do this only once */
101
0
    return;
102
1
  installed = 1;
103
  /* example of new cli command */
104
1
  install_element(BGP_NODE, &rfp_example_config_value_cmd);
105
1
  install_element(BGP_NODE, &rfp_holddown_factor_cmd);
106
1
  install_element(BGP_NODE, &rfp_full_table_download_cmd);
107
1
}
108
109
/***********************************************************************
110
 * RFAPI Callbacks
111
 **********************************************************************/
112
113
/*------------------------------------------
114
 * rfp_response_cb
115
 *
116
 * Callbacks of this type are used to provide asynchronous
117
 * route updates from RFAPI to the RFP client.
118
 *
119
 * response_cb
120
 *  called to notify the rfp client that a next hop list
121
 *  that has previously been provided in response to an
122
 *  rfapi_query call has been updated. Deleted routes are indicated
123
 *  with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME.
124
 *
125
 *  By default, the routes an NVE receives via this callback include
126
 *  its own routes (that it has registered). However, these may be
127
 *  filtered out if the global BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP
128
 *  flag is set.
129
 *
130
 * input:
131
 *  next_hops a list of possible next hops.
132
 *      This is a linked list allocated within the
133
 *      rfapi. The response_cb callback function is responsible
134
 *      for freeing this memory via rfapi_free_next_hop_list()
135
 *      in order to avoid memory leaks.
136
 *
137
 *  userdata  value (cookie) originally specified in call to
138
 *      rfapi_open()
139
 *
140
 *------------------------------------------*/
141
static void rfp_response_cb(struct rfapi_next_hop_entry *next_hops,
142
          void *userdata)
143
0
{
144
  /*
145
   * Identify NVE based on userdata, which is a value passed
146
   * to RFAPI in the rfapi_open call
147
   */
148
149
  /* process list of next_hops */
150
151
  /* free next hops */
152
0
  rfapi_free_next_hop_list(next_hops);
153
0
  return;
154
0
}
155
156
/*------------------------------------------
157
 * rfp_local_cb
158
 *
159
 * Callbacks of this type are used to provide asynchronous
160
 * route updates from RFAPI to the RFP client.
161
 *
162
 * local_cb
163
 *  called to notify the rfp client that a local route
164
 *  has been added or deleted. Deleted routes are indicated
165
 *  with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME.
166
 *
167
 * input:
168
 *  next_hops a list of possible next hops.
169
 *      This is a linked list allocated within the
170
 *      rfapi. The local_cb callback function is responsible
171
 *      for freeing this memory via rfapi_free_next_hop_list()
172
 *      in order to avoid memory leaks.
173
 *
174
 *  userdata  value (cookie) originally specified in call to
175
 *      rfapi_open()
176
 *
177
 *------------------------------------------*/
178
static void rfp_local_cb(struct rfapi_next_hop_entry *next_hops, void *userdata)
179
0
{
180
  /*
181
   * Identify NVE based on userdata, which is a value passed
182
   * to RFAPI in the rfapi_open call
183
   */
184
185
  /* process list of local next_hops */
186
187
  /* free next hops */
188
0
  rfapi_free_next_hop_list(next_hops);
189
0
  return;
190
0
}
191
192
/*------------------------------------------
193
 * rfp_close_cb
194
 *
195
 * Callbacks used to provide asynchronous
196
 * notification that an rfapi_handle was invalidated
197
 *
198
 * input:
199
 *  pHandle   Firmerly valid rfapi_handle returned to
200
 *      client via rfapi_open().
201
 *
202
 *  reason    EIDRM handle administratively closed (clear nve ...)
203
 *      ESTALE  handle invalidated by configuration change
204
 *
205
 *------------------------------------------*/
206
static void rfp_close_cb(rfapi_handle pHandle, int reason)
207
0
{
208
  /* close / invalidate NVE with the pHandle returned by the rfapi_open
209
   * call */
210
0
  return;
211
0
}
212
213
/*------------------------------------------
214
 * rfp_cfg_write_cb
215
 *
216
 * This callback is used to generate output for any config parameters
217
 * that may supported by RFP  via RFP defined vty commands at the bgp
218
 * level.  See loglevel as an example.
219
 *
220
 * input:
221
 *    vty           -- quagga vty context
222
 *    rfp_start_val -- value returned by rfp_start
223
 *
224
 * output:
225
 *    to vty, rfp related configuration
226
 *
227
 * return value:
228
 *    lines written
229
--------------------------------------------*/
230
static int rfp_cfg_write_cb(struct vty *vty, void *rfp_start_val)
231
0
{
232
0
  struct rfp_instance_t *rfi = rfp_start_val;
233
0
  int write = 0;
234
0
  assert(rfp_start_val != NULL);
235
0
  if (rfi->config_var != 0) {
236
0
    vty_out(vty, " rfp example-config-value %u", rfi->config_var);
237
0
    vty_out(vty, "\n");
238
0
    write++;
239
0
  }
240
0
  if (rfi->rfapi_config.holddown_factor != 0) {
241
0
    vty_out(vty, " rfp holddown-factor %u\n",
242
0
      rfi->rfapi_config.holddown_factor);
243
0
    write++;
244
0
  }
245
0
  if (rfi->rfapi_config.download_type == RFAPI_RFP_DOWNLOAD_FULL) {
246
0
    vty_out(vty, " rfp full-table-download on\n");
247
0
    write++;
248
0
  }
249
0
  return write;
250
0
}
251
252
/***********************************************************************
253
 * RFAPI required functions
254
 **********************************************************************/
255
256
/*------------------------------------------
257
 * rfp_start
258
 *
259
 * This function will start the RFP code
260
 *
261
 * input:
262
 *    master    quagga thread_master to tie into bgpd threads
263
 *
264
 * output:
265
 *    cfgp      Pointer to rfapi_rfp_cfg (null = use defaults),
266
 *              copied by caller, updated via rfp_set_configuration
267
 *    cbmp      Pointer to rfapi_rfp_cb_methods, may be null
268
 *              copied by caller, updated via rfapi_rfp_set_cb_methods
269
 *
270
 * return value:
271
 *    rfp_start_val rfp returned value passed on rfp_stop and rfp_cfg_write
272
 *
273
--------------------------------------------*/
274
void *rfp_start(struct event_loop *master, struct rfapi_rfp_cfg **cfgp,
275
    struct rfapi_rfp_cb_methods **cbmp)
276
1
{
277
1
  memset(&global_rfi, 0, sizeof(global_rfi));
278
1
  global_rfi.master = master; /* for BGPD threads */
279
280
  /* initilize struct rfapi_rfp_cfg, see rfapi.h */
281
1
  global_rfi.rfapi_config.download_type =
282
1
    RFAPI_RFP_DOWNLOAD_PARTIAL; /* default=partial */
283
1
  global_rfi.rfapi_config.ftd_advertisement_interval =
284
1
    RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL;
285
1
  global_rfi.rfapi_config.holddown_factor =
286
1
    0; /* default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR */
287
1
  global_rfi.rfapi_config.use_updated_response = 1; /* 0=no */
288
1
  global_rfi.rfapi_config.use_removes = 1;    /* 0=no */
289
290
291
  /* initilize structrfapi_rfp_cb_methods , see rfapi.h */
292
1
  global_rfi.rfapi_callbacks.cfg_cb = rfp_cfg_write_cb;
293
  /* no group config */
294
1
  global_rfi.rfapi_callbacks.response_cb = rfp_response_cb;
295
1
  global_rfi.rfapi_callbacks.local_cb = rfp_local_cb;
296
1
  global_rfi.rfapi_callbacks.close_cb = rfp_close_cb;
297
298
1
  if (cfgp != NULL)
299
1
    *cfgp = &global_rfi.rfapi_config;
300
1
  if (cbmp != NULL)
301
1
    *cbmp = &global_rfi.rfapi_callbacks;
302
303
1
  rfp_vty_install();
304
305
1
  return &global_rfi;
306
1
}
307
308
/*------------------------------------------
309
 * rfp_stop
310
 *
311
 * This function is called on shutdown to trigger RFP cleanup
312
 *
313
 * input:
314
 *    none
315
 *
316
 * output:
317
 *    none
318
 *
319
 * return value:
320
 *    rfp_start_val
321
--------------------------------------------*/
322
void rfp_stop(void *rfp_start_val)
323
0
{
324
0
  assert(rfp_start_val != NULL);
325
0
}
326
327
/* TO BE REMOVED */
328
void rfp_clear_vnc_nve_all(void)
329
0
{
330
0
  return;
331
0
}