Line data Source code
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 0 : 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 0 : uint32_t value = 0;
52 0 : struct rfp_instance_t *rfi = NULL;
53 0 : rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
54 0 : assert(rfi != NULL);
55 :
56 0 : value = strtoul(argv[2]->arg, NULL, 10);
57 0 : if (rfi)
58 0 : rfi->config_var = value;
59 0 : return CMD_SUCCESS;
60 : }
61 :
62 0 : 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 0 : struct rfp_instance_t *rfi;
70 0 : uint32_t value = 0;
71 :
72 0 : value = strtoul((argv[--argc]->arg), NULL, 10);
73 0 : rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
74 0 : if (!rfi) {
75 0 : vty_out(vty, "VNC not configured\n");
76 0 : return CMD_WARNING;
77 : }
78 0 : rfi->rfapi_config.holddown_factor = value;
79 0 : rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config);
80 0 : return CMD_SUCCESS;
81 : }
82 :
83 :
84 0 : 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 0 : struct rfp_instance_t *rfi;
93 0 : rfapi_rfp_download_type old;
94 :
95 0 : rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */
96 0 : if (!rfi) {
97 0 : vty_out(vty, "VNC not configured\n");
98 0 : return CMD_WARNING;
99 : }
100 0 : old = rfi->rfapi_config.download_type;
101 0 : if (argv[--argc]->arg[1] == 'n' || argv[argc]->arg[1] == 'N')
102 0 : rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_FULL;
103 : else
104 0 : rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL;
105 0 : if (old != rfi->rfapi_config.download_type)
106 0 : rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config);
107 : return CMD_SUCCESS;
108 : }
109 :
110 32 : static void rfp_vty_install(void)
111 : {
112 32 : static int installed = 0;
113 32 : if (installed) /* do this only once */
114 : return;
115 32 : installed = 1;
116 : /* example of new cli command */
117 32 : install_element(BGP_NODE, &rfp_example_config_value_cmd);
118 32 : install_element(BGP_NODE, &rfp_holddown_factor_cmd);
119 32 : 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 0 : 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 0 : rfapi_free_next_hop_list(next_hops);
166 0 : 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 0 : 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 0 : rfapi_free_next_hop_list(next_hops);
202 0 : 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 0 : 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 0 : 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 0 : static int rfp_cfg_write_cb(struct vty *vty, void *rfp_start_val)
244 : {
245 0 : struct rfp_instance_t *rfi = rfp_start_val;
246 0 : int write = 0;
247 0 : assert(rfp_start_val != NULL);
248 0 : if (rfi->config_var != 0) {
249 0 : vty_out(vty, " rfp example-config-value %u", rfi->config_var);
250 0 : vty_out(vty, "\n");
251 0 : write++;
252 : }
253 0 : if (rfi->rfapi_config.holddown_factor != 0) {
254 0 : vty_out(vty, " rfp holddown-factor %u\n",
255 : rfi->rfapi_config.holddown_factor);
256 0 : write++;
257 : }
258 0 : if (rfi->rfapi_config.download_type == RFAPI_RFP_DOWNLOAD_FULL) {
259 0 : vty_out(vty, " rfp full-table-download on\n");
260 0 : write++;
261 : }
262 0 : 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 32 : void *rfp_start(struct thread_master *master, struct rfapi_rfp_cfg **cfgp,
288 : struct rfapi_rfp_cb_methods **cbmp)
289 : {
290 32 : memset(&global_rfi, 0, sizeof(global_rfi));
291 32 : global_rfi.master = master; /* for BGPD threads */
292 :
293 : /* initilize struct rfapi_rfp_cfg, see rfapi.h */
294 32 : global_rfi.rfapi_config.download_type =
295 : RFAPI_RFP_DOWNLOAD_PARTIAL; /* default=partial */
296 32 : global_rfi.rfapi_config.ftd_advertisement_interval =
297 : RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL;
298 32 : global_rfi.rfapi_config.holddown_factor =
299 : 0; /* default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR */
300 32 : global_rfi.rfapi_config.use_updated_response = 1; /* 0=no */
301 32 : global_rfi.rfapi_config.use_removes = 1; /* 0=no */
302 :
303 :
304 : /* initilize structrfapi_rfp_cb_methods , see rfapi.h */
305 32 : global_rfi.rfapi_callbacks.cfg_cb = rfp_cfg_write_cb;
306 : /* no group config */
307 32 : global_rfi.rfapi_callbacks.response_cb = rfp_response_cb;
308 32 : global_rfi.rfapi_callbacks.local_cb = rfp_local_cb;
309 32 : global_rfi.rfapi_callbacks.close_cb = rfp_close_cb;
310 :
311 32 : if (cfgp != NULL)
312 32 : *cfgp = &global_rfi.rfapi_config;
313 32 : if (cbmp != NULL)
314 32 : *cbmp = &global_rfi.rfapi_callbacks;
315 :
316 32 : rfp_vty_install();
317 :
318 32 : 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 32 : void rfp_stop(void *rfp_start_val)
336 : {
337 32 : assert(rfp_start_val != NULL);
338 32 : }
339 :
340 : /* TO BE REMOVED */
341 32 : void rfp_clear_vnc_nve_all(void)
342 : {
343 32 : return;
344 : }
|