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