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
22 #include "rfp_internal.h"
23 #include "bgpd/rfapi/rfapi.h"
24 #include "lib/command.h"
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
;
34 global_rfi
; /* dynamically allocate in full implementation */
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",
44 "Example value to be configured\n"
48 struct rfp_instance_t
*rfi
= NULL
;
49 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
52 value
= strtoul(argv
[2]->arg
, NULL
, 10);
54 rfi
->config_var
= value
;
58 DEFUN (rfp_holddown_factor
,
59 rfp_holddown_factor_cmd
,
60 "rfp holddown-factor (0-4294967295)",
62 "Set Hold-Down Factor as a percentage of registration lifetime.\n"
63 "Percentage of registration lifetime\n")
65 struct rfp_instance_t
*rfi
;
68 value
= strtoul((argv
[--argc
]->arg
), NULL
, 10);
69 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
71 vty_out(vty
, "VNC not configured\n");
74 rfi
->rfapi_config
.holddown_factor
= value
;
75 rfapi_rfp_set_configuration(rfi
, &rfi
->rfapi_config
);
80 DEFUN (rfp_full_table_download
,
81 rfp_full_table_download_cmd
,
82 "rfp full-table-download <on|off>",
84 "RFP full table download support (default=on)\n"
85 "Enable RFP full table download\n"
86 "Disable RFP full table download\n")
88 struct rfp_instance_t
*rfi
;
89 rfapi_rfp_download_type old
;
91 rfi
= rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp
)); /* BGP_NODE */
93 vty_out(vty
, "VNC not configured\n");
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
;
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
);
106 static void rfp_vty_install()
108 static int installed
= 0;
109 if (installed
) /* do this only once */
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
);
118 /***********************************************************************
120 **********************************************************************/
122 /*------------------------------------------
125 * Callbacks of this type are used to provide asynchronous
126 * route updates from RFAPI to the RFP client.
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.
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
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.
146 * userdata value (cookie) originally specified in call to
149 *------------------------------------------*/
150 static void rfp_response_cb(struct rfapi_next_hop_entry
*next_hops
,
154 * Identify NVE based on userdata, which is a value passed
155 * to RFAPI in the rfapi_open call
158 /* process list of next_hops */
161 rfapi_free_next_hop_list(next_hops
);
165 /*------------------------------------------
168 * Callbacks of this type are used to provide asynchronous
169 * route updates from RFAPI to the RFP client.
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.
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.
183 * userdata value (cookie) originally specified in call to
186 *------------------------------------------*/
187 static void rfp_local_cb(struct rfapi_next_hop_entry
*next_hops
, void *userdata
)
190 * Identify NVE based on userdata, which is a value passed
191 * to RFAPI in the rfapi_open call
194 /* process list of local next_hops */
197 rfapi_free_next_hop_list(next_hops
);
201 /*------------------------------------------
204 * Callbacks used to provide asynchronous
205 * notification that an rfapi_handle was invalidated
208 * pHandle Firmerly valid rfapi_handle returned to
209 * client via rfapi_open().
211 * reason EIDRM handle administratively closed (clear nve ...)
212 * ESTALE handle invalidated by configuration change
214 *------------------------------------------*/
215 static void rfp_close_cb(rfapi_handle pHandle
, int reason
)
217 /* close / invalidate NVE with the pHandle returned by the rfapi_open
222 /*------------------------------------------
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.
230 * vty -- quagga vty context
231 * rfp_start_val -- value returned by rfp_start
234 * to vty, rfp related configuration
238 --------------------------------------------*/
239 static int rfp_cfg_write_cb(struct vty
*vty
, void *rfp_start_val
)
241 struct rfp_instance_t
*rfi
= rfp_start_val
;
243 assert(rfp_start_val
!= NULL
);
244 if (rfi
->config_var
!= 0) {
245 vty_out(vty
, " rfp example-config-value %u", rfi
->config_var
);
249 if (rfi
->rfapi_config
.holddown_factor
!= 0) {
250 vty_out(vty
, " rfp holddown-factor %u\n",
251 rfi
->rfapi_config
.holddown_factor
);
254 if (rfi
->rfapi_config
.download_type
!= RFAPI_RFP_DOWNLOAD_FULL
) {
255 vty_out(vty
, " rfp full-table-download off\n");
261 /***********************************************************************
262 * RFAPI required functions
263 **********************************************************************/
265 /*------------------------------------------
268 * This function will start the RFP code
271 * master quagga thread_master to tie into bgpd threads
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
280 * rfp_start_val rfp returned value passed on rfp_stop and rfp_cfg_write
282 --------------------------------------------*/
283 void *rfp_start(struct thread_master
*master
, struct rfapi_rfp_cfg
**cfgp
,
284 struct rfapi_rfp_cb_methods
**cbmp
)
286 memset(&global_rfi
, 0, sizeof(struct rfp_instance_t
));
287 global_rfi
.master
= master
; /* for BGPD threads */
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 */
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
;
308 *cfgp
= &global_rfi
.rfapi_config
;
310 *cbmp
= &global_rfi
.rfapi_callbacks
;
317 /*------------------------------------------
320 * This function is called on shutdown to trigger RFP cleanup
330 --------------------------------------------*/
331 void rfp_stop(void *rfp_start_val
)
333 assert(rfp_start_val
!= NULL
);
337 void rfp_clear_vnc_nve_all(void)