3 * Copyright 2015-2016, LabN Consulting, L.L.C.
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.
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.
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
26 #include "rfp_internal.h"
27 #include "bgpd/rfapi/rfapi.h"
28 #include "lib/command.h"
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
;
38 global_rfi
; /* dynamically allocate in full implementation */
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",
48 "Example value to be configured\n"
52 struct rfp_instance_t
*rfi
= NULL
;
53 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
56 value
= strtoul(argv
[2]->arg
, NULL
, 10);
58 rfi
->config_var
= value
;
62 DEFUN (rfp_holddown_factor
,
63 rfp_holddown_factor_cmd
,
64 "rfp holddown-factor (0-4294967295)",
66 "Set Hold-Down Factor as a percentage of registration lifetime.\n"
67 "Percentage of registration lifetime\n")
69 struct rfp_instance_t
*rfi
;
72 value
= strtoul((argv
[--argc
]->arg
), NULL
, 10);
73 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
75 vty_out(vty
, "VNC not configured\n");
78 rfi
->rfapi_config
.holddown_factor
= value
;
79 rfapi_rfp_set_configuration(rfi
, &rfi
->rfapi_config
);
84 DEFUN (rfp_full_table_download
,
85 rfp_full_table_download_cmd
,
86 "rfp full-table-download <on|off>",
88 "RFP full table download support (default=on)\n"
89 "Enable RFP full table download\n"
90 "Disable RFP full table download\n")
92 struct rfp_instance_t
*rfi
;
93 rfapi_rfp_download_type old
;
95 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
97 vty_out(vty
, "VNC not configured\n");
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
;
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
);
110 static void rfp_vty_install(void)
112 static int installed
= 0;
113 if (installed
) /* do this only once */
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
);
122 /***********************************************************************
124 **********************************************************************/
126 /*------------------------------------------
129 * Callbacks of this type are used to provide asynchronous
130 * route updates from RFAPI to the RFP client.
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.
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
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.
150 * userdata value (cookie) originally specified in call to
153 *------------------------------------------*/
154 static void rfp_response_cb(struct rfapi_next_hop_entry
*next_hops
,
158 * Identify NVE based on userdata, which is a value passed
159 * to RFAPI in the rfapi_open call
162 /* process list of next_hops */
165 rfapi_free_next_hop_list(next_hops
);
169 /*------------------------------------------
172 * Callbacks of this type are used to provide asynchronous
173 * route updates from RFAPI to the RFP client.
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.
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.
187 * userdata value (cookie) originally specified in call to
190 *------------------------------------------*/
191 static void rfp_local_cb(struct rfapi_next_hop_entry
*next_hops
, void *userdata
)
194 * Identify NVE based on userdata, which is a value passed
195 * to RFAPI in the rfapi_open call
198 /* process list of local next_hops */
201 rfapi_free_next_hop_list(next_hops
);
205 /*------------------------------------------
208 * Callbacks used to provide asynchronous
209 * notification that an rfapi_handle was invalidated
212 * pHandle Firmerly valid rfapi_handle returned to
213 * client via rfapi_open().
215 * reason EIDRM handle administratively closed (clear nve ...)
216 * ESTALE handle invalidated by configuration change
218 *------------------------------------------*/
219 static void rfp_close_cb(rfapi_handle pHandle
, int reason
)
221 /* close / invalidate NVE with the pHandle returned by the rfapi_open
226 /*------------------------------------------
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.
234 * vty -- quagga vty context
235 * rfp_start_val -- value returned by rfp_start
238 * to vty, rfp related configuration
242 --------------------------------------------*/
243 static int rfp_cfg_write_cb(struct vty
*vty
, void *rfp_start_val
)
245 struct rfp_instance_t
*rfi
= rfp_start_val
;
247 assert(rfp_start_val
!= NULL
);
248 if (rfi
->config_var
!= 0) {
249 vty_out(vty
, " rfp example-config-value %u", rfi
->config_var
);
253 if (rfi
->rfapi_config
.holddown_factor
!= 0) {
254 vty_out(vty
, " rfp holddown-factor %u\n",
255 rfi
->rfapi_config
.holddown_factor
);
258 if (rfi
->rfapi_config
.download_type
== RFAPI_RFP_DOWNLOAD_FULL
) {
259 vty_out(vty
, " rfp full-table-download on\n");
265 /***********************************************************************
266 * RFAPI required functions
267 **********************************************************************/
269 /*------------------------------------------
272 * This function will start the RFP code
275 * master quagga thread_master to tie into bgpd threads
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
284 * rfp_start_val rfp returned value passed on rfp_stop and rfp_cfg_write
286 --------------------------------------------*/
287 void *rfp_start(struct thread_master
*master
, struct rfapi_rfp_cfg
**cfgp
,
288 struct rfapi_rfp_cb_methods
**cbmp
)
290 memset(&global_rfi
, 0, sizeof(global_rfi
));
291 global_rfi
.master
= master
; /* for BGPD threads */
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 */
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
;
312 *cfgp
= &global_rfi
.rfapi_config
;
314 *cbmp
= &global_rfi
.rfapi_callbacks
;
321 /*------------------------------------------
324 * This function is called on shutdown to trigger RFP cleanup
334 --------------------------------------------*/
335 void rfp_stop(void *rfp_start_val
)
337 assert(rfp_start_val
!= NULL
);
341 void rfp_clear_vnc_nve_all(void)