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