1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright 2015-2016, LabN Consulting, L.L.C.
13 #include "rfp_internal.h"
14 #include "bgpd/rfapi/rfapi.h"
15 #include "lib/command.h"
17 struct rfp_instance_t
{
18 struct rfapi_rfp_cfg rfapi_config
;
19 struct rfapi_rfp_cb_methods rfapi_callbacks
;
20 struct thread_master
*master
;
25 global_rfi
; /* dynamically allocate in full implementation */
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",
35 "Example value to be configured\n"
39 struct rfp_instance_t
*rfi
= NULL
;
40 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
43 value
= strtoul(argv
[2]->arg
, NULL
, 10);
45 rfi
->config_var
= value
;
49 DEFUN (rfp_holddown_factor
,
50 rfp_holddown_factor_cmd
,
51 "rfp holddown-factor (0-4294967295)",
53 "Set Hold-Down Factor as a percentage of registration lifetime.\n"
54 "Percentage of registration lifetime\n")
56 struct rfp_instance_t
*rfi
;
59 value
= strtoul((argv
[--argc
]->arg
), NULL
, 10);
60 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
62 vty_out(vty
, "VNC not configured\n");
65 rfi
->rfapi_config
.holddown_factor
= value
;
66 rfapi_rfp_set_configuration(rfi
, &rfi
->rfapi_config
);
71 DEFUN (rfp_full_table_download
,
72 rfp_full_table_download_cmd
,
73 "rfp full-table-download <on|off>",
75 "RFP full table download support (default=on)\n"
76 "Enable RFP full table download\n"
77 "Disable RFP full table download\n")
79 struct rfp_instance_t
*rfi
;
80 rfapi_rfp_download_type old
;
82 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
84 vty_out(vty
, "VNC not configured\n");
87 old
= rfi
->rfapi_config
.download_type
;
88 if (argv
[--argc
]->arg
[1] == 'n' || argv
[argc
]->arg
[1] == 'N')
89 rfi
->rfapi_config
.download_type
= RFAPI_RFP_DOWNLOAD_FULL
;
91 rfi
->rfapi_config
.download_type
= RFAPI_RFP_DOWNLOAD_PARTIAL
;
92 if (old
!= rfi
->rfapi_config
.download_type
)
93 rfapi_rfp_set_configuration(rfi
, &rfi
->rfapi_config
);
97 static void rfp_vty_install(void)
99 static int installed
= 0;
100 if (installed
) /* do this only once */
103 /* example of new cli command */
104 install_element(BGP_NODE
, &rfp_example_config_value_cmd
);
105 install_element(BGP_NODE
, &rfp_holddown_factor_cmd
);
106 install_element(BGP_NODE
, &rfp_full_table_download_cmd
);
109 /***********************************************************************
111 **********************************************************************/
113 /*------------------------------------------
116 * Callbacks of this type are used to provide asynchronous
117 * route updates from RFAPI to the RFP client.
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.
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
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.
137 * userdata value (cookie) originally specified in call to
140 *------------------------------------------*/
141 static void rfp_response_cb(struct rfapi_next_hop_entry
*next_hops
,
145 * Identify NVE based on userdata, which is a value passed
146 * to RFAPI in the rfapi_open call
149 /* process list of next_hops */
152 rfapi_free_next_hop_list(next_hops
);
156 /*------------------------------------------
159 * Callbacks of this type are used to provide asynchronous
160 * route updates from RFAPI to the RFP client.
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.
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.
174 * userdata value (cookie) originally specified in call to
177 *------------------------------------------*/
178 static void rfp_local_cb(struct rfapi_next_hop_entry
*next_hops
, void *userdata
)
181 * Identify NVE based on userdata, which is a value passed
182 * to RFAPI in the rfapi_open call
185 /* process list of local next_hops */
188 rfapi_free_next_hop_list(next_hops
);
192 /*------------------------------------------
195 * Callbacks used to provide asynchronous
196 * notification that an rfapi_handle was invalidated
199 * pHandle Firmerly valid rfapi_handle returned to
200 * client via rfapi_open().
202 * reason EIDRM handle administratively closed (clear nve ...)
203 * ESTALE handle invalidated by configuration change
205 *------------------------------------------*/
206 static void rfp_close_cb(rfapi_handle pHandle
, int reason
)
208 /* close / invalidate NVE with the pHandle returned by the rfapi_open
213 /*------------------------------------------
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.
221 * vty -- quagga vty context
222 * rfp_start_val -- value returned by rfp_start
225 * to vty, rfp related configuration
229 --------------------------------------------*/
230 static int rfp_cfg_write_cb(struct vty
*vty
, void *rfp_start_val
)
232 struct rfp_instance_t
*rfi
= rfp_start_val
;
234 assert(rfp_start_val
!= NULL
);
235 if (rfi
->config_var
!= 0) {
236 vty_out(vty
, " rfp example-config-value %u", rfi
->config_var
);
240 if (rfi
->rfapi_config
.holddown_factor
!= 0) {
241 vty_out(vty
, " rfp holddown-factor %u\n",
242 rfi
->rfapi_config
.holddown_factor
);
245 if (rfi
->rfapi_config
.download_type
== RFAPI_RFP_DOWNLOAD_FULL
) {
246 vty_out(vty
, " rfp full-table-download on\n");
252 /***********************************************************************
253 * RFAPI required functions
254 **********************************************************************/
256 /*------------------------------------------
259 * This function will start the RFP code
262 * master quagga thread_master to tie into bgpd threads
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
271 * rfp_start_val rfp returned value passed on rfp_stop and rfp_cfg_write
273 --------------------------------------------*/
274 void *rfp_start(struct thread_master
*master
, struct rfapi_rfp_cfg
**cfgp
,
275 struct rfapi_rfp_cb_methods
**cbmp
)
277 memset(&global_rfi
, 0, sizeof(global_rfi
));
278 global_rfi
.master
= master
; /* for BGPD threads */
280 /* initilize struct rfapi_rfp_cfg, see rfapi.h */
281 global_rfi
.rfapi_config
.download_type
=
282 RFAPI_RFP_DOWNLOAD_PARTIAL
; /* default=partial */
283 global_rfi
.rfapi_config
.ftd_advertisement_interval
=
284 RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL
;
285 global_rfi
.rfapi_config
.holddown_factor
=
286 0; /* default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR */
287 global_rfi
.rfapi_config
.use_updated_response
= 1; /* 0=no */
288 global_rfi
.rfapi_config
.use_removes
= 1; /* 0=no */
291 /* initilize structrfapi_rfp_cb_methods , see rfapi.h */
292 global_rfi
.rfapi_callbacks
.cfg_cb
= rfp_cfg_write_cb
;
293 /* no group config */
294 global_rfi
.rfapi_callbacks
.response_cb
= rfp_response_cb
;
295 global_rfi
.rfapi_callbacks
.local_cb
= rfp_local_cb
;
296 global_rfi
.rfapi_callbacks
.close_cb
= rfp_close_cb
;
299 *cfgp
= &global_rfi
.rfapi_config
;
301 *cbmp
= &global_rfi
.rfapi_callbacks
;
308 /*------------------------------------------
311 * This function is called on shutdown to trigger RFP cleanup
321 --------------------------------------------*/
322 void rfp_stop(void *rfp_start_val
)
324 assert(rfp_start_val
!= NULL
);
328 void rfp_clear_vnc_nve_all(void)