diff options
Diffstat (limited to 'bgpd/rfp-example/librfp/rfp_example.c')
-rw-r--r-- | bgpd/rfp-example/librfp/rfp_example.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/bgpd/rfp-example/librfp/rfp_example.c b/bgpd/rfp-example/librfp/rfp_example.c new file mode 100644 index 0000000..1ada36b --- /dev/null +++ b/bgpd/rfp-example/librfp/rfp_example.c @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * + * Copyright 2015-2016, LabN Consulting, L.L.C. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* stub rfp */ +#include "rfp_internal.h" +#include "bgpd/rfapi/rfapi.h" +#include "lib/command.h" + +struct rfp_instance_t { + struct rfapi_rfp_cfg rfapi_config; + struct rfapi_rfp_cb_methods rfapi_callbacks; + struct event_loop *master; + uint32_t config_var; +}; + +struct rfp_instance_t + global_rfi; /* dynamically allocate in full implementation */ + +/*********************************************************************** + * Sample VTY / internal function + **********************************************************************/ +#define RFP_SHOW_STR "RFP information\n" +DEFUN (rfp_example_config_value, + rfp_example_config_value_cmd, + "rfp example-config-value VALUE", + RFP_SHOW_STR + "Example value to be configured\n" + "Value to display\n") +{ + uint32_t value = 0; + struct rfp_instance_t *rfi = NULL; + rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */ + assert(rfi != NULL); + + value = strtoul(argv[2]->arg, NULL, 10); + if (rfi) + rfi->config_var = value; + return CMD_SUCCESS; +} + +DEFUN (rfp_holddown_factor, + rfp_holddown_factor_cmd, + "rfp holddown-factor (0-4294967295)", + RFP_SHOW_STR + "Set Hold-Down Factor as a percentage of registration lifetime.\n" + "Percentage of registration lifetime\n") +{ + struct rfp_instance_t *rfi; + uint32_t value = 0; + + value = strtoul((argv[--argc]->arg), NULL, 10); + rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */ + if (!rfi) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING; + } + rfi->rfapi_config.holddown_factor = value; + rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config); + return CMD_SUCCESS; +} + + +DEFUN (rfp_full_table_download, + rfp_full_table_download_cmd, + "rfp full-table-download <on|off>", + RFP_SHOW_STR + "RFP full table download support (default=on)\n" + "Enable RFP full table download\n" + "Disable RFP full table download\n") +{ + struct rfp_instance_t *rfi; + rfapi_rfp_download_type old; + + rfi = rfapi_get_rfp_start_val(VTY_GET_CONTEXT(bgp)); /* BGP_NODE */ + if (!rfi) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING; + } + old = rfi->rfapi_config.download_type; + if (argv[--argc]->arg[1] == 'n' || argv[argc]->arg[1] == 'N') + rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_FULL; + else + rfi->rfapi_config.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL; + if (old != rfi->rfapi_config.download_type) + rfapi_rfp_set_configuration(rfi, &rfi->rfapi_config); + return CMD_SUCCESS; +} + +static void rfp_vty_install(void) +{ + static int installed = 0; + if (installed) /* do this only once */ + return; + installed = 1; + /* example of new cli command */ + install_element(BGP_NODE, &rfp_example_config_value_cmd); + install_element(BGP_NODE, &rfp_holddown_factor_cmd); + install_element(BGP_NODE, &rfp_full_table_download_cmd); +} + +/*********************************************************************** + * RFAPI Callbacks + **********************************************************************/ + +/*------------------------------------------ + * rfp_response_cb + * + * Callbacks of this type are used to provide asynchronous + * route updates from RFAPI to the RFP client. + * + * response_cb + * called to notify the rfp client that a next hop list + * that has previously been provided in response to an + * rfapi_query call has been updated. Deleted routes are indicated + * with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME. + * + * By default, the routes an NVE receives via this callback include + * its own routes (that it has registered). However, these may be + * filtered out if the global BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP + * flag is set. + * + * input: + * next_hops a list of possible next hops. + * This is a linked list allocated within the + * rfapi. The response_cb callback function is responsible + * for freeing this memory via rfapi_free_next_hop_list() + * in order to avoid memory leaks. + * + * userdata value (cookie) originally specified in call to + * rfapi_open() + * + *------------------------------------------*/ +static void rfp_response_cb(struct rfapi_next_hop_entry *next_hops, + void *userdata) +{ + /* + * Identify NVE based on userdata, which is a value passed + * to RFAPI in the rfapi_open call + */ + + /* process list of next_hops */ + + /* free next hops */ + rfapi_free_next_hop_list(next_hops); + return; +} + +/*------------------------------------------ + * rfp_local_cb + * + * Callbacks of this type are used to provide asynchronous + * route updates from RFAPI to the RFP client. + * + * local_cb + * called to notify the rfp client that a local route + * has been added or deleted. Deleted routes are indicated + * with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME. + * + * input: + * next_hops a list of possible next hops. + * This is a linked list allocated within the + * rfapi. The local_cb callback function is responsible + * for freeing this memory via rfapi_free_next_hop_list() + * in order to avoid memory leaks. + * + * userdata value (cookie) originally specified in call to + * rfapi_open() + * + *------------------------------------------*/ +static void rfp_local_cb(struct rfapi_next_hop_entry *next_hops, void *userdata) +{ + /* + * Identify NVE based on userdata, which is a value passed + * to RFAPI in the rfapi_open call + */ + + /* process list of local next_hops */ + + /* free next hops */ + rfapi_free_next_hop_list(next_hops); + return; +} + +/*------------------------------------------ + * rfp_close_cb + * + * Callbacks used to provide asynchronous + * notification that an rfapi_handle was invalidated + * + * input: + * pHandle Firmerly valid rfapi_handle returned to + * client via rfapi_open(). + * + * reason EIDRM handle administratively closed (clear nve ...) + * ESTALE handle invalidated by configuration change + * + *------------------------------------------*/ +static void rfp_close_cb(rfapi_handle pHandle, int reason) +{ + /* close / invalidate NVE with the pHandle returned by the rfapi_open + * call */ + return; +} + +/*------------------------------------------ + * rfp_cfg_write_cb + * + * This callback is used to generate output for any config parameters + * that may supported by RFP via RFP defined vty commands at the bgp + * level. See loglevel as an example. + * + * input: + * vty -- quagga vty context + * rfp_start_val -- value returned by rfp_start + * + * output: + * to vty, rfp related configuration + * + * return value: + * lines written +--------------------------------------------*/ +static int rfp_cfg_write_cb(struct vty *vty, void *rfp_start_val) +{ + struct rfp_instance_t *rfi = rfp_start_val; + int write = 0; + assert(rfp_start_val != NULL); + if (rfi->config_var != 0) { + vty_out(vty, " rfp example-config-value %u", rfi->config_var); + vty_out(vty, "\n"); + write++; + } + if (rfi->rfapi_config.holddown_factor != 0) { + vty_out(vty, " rfp holddown-factor %u\n", + rfi->rfapi_config.holddown_factor); + write++; + } + if (rfi->rfapi_config.download_type == RFAPI_RFP_DOWNLOAD_FULL) { + vty_out(vty, " rfp full-table-download on\n"); + write++; + } + return write; +} + +/*********************************************************************** + * RFAPI required functions + **********************************************************************/ + +/*------------------------------------------ + * rfp_start + * + * This function will start the RFP code + * + * input: + * master quagga thread_master to tie into bgpd threads + * + * output: + * cfgp Pointer to rfapi_rfp_cfg (null = use defaults), + * copied by caller, updated via rfp_set_configuration + * cbmp Pointer to rfapi_rfp_cb_methods, may be null + * copied by caller, updated via rfapi_rfp_set_cb_methods + * + * return value: + * rfp_start_val rfp returned value passed on rfp_stop and rfp_cfg_write + * +--------------------------------------------*/ +void *rfp_start(struct event_loop *master, struct rfapi_rfp_cfg **cfgp, + struct rfapi_rfp_cb_methods **cbmp) +{ + memset(&global_rfi, 0, sizeof(global_rfi)); + global_rfi.master = master; /* for BGPD threads */ + + /* initilize struct rfapi_rfp_cfg, see rfapi.h */ + global_rfi.rfapi_config.download_type = + RFAPI_RFP_DOWNLOAD_PARTIAL; /* default=partial */ + global_rfi.rfapi_config.ftd_advertisement_interval = + RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL; + global_rfi.rfapi_config.holddown_factor = + 0; /* default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR */ + global_rfi.rfapi_config.use_updated_response = 1; /* 0=no */ + global_rfi.rfapi_config.use_removes = 1; /* 0=no */ + + + /* initilize structrfapi_rfp_cb_methods , see rfapi.h */ + global_rfi.rfapi_callbacks.cfg_cb = rfp_cfg_write_cb; + /* no group config */ + global_rfi.rfapi_callbacks.response_cb = rfp_response_cb; + global_rfi.rfapi_callbacks.local_cb = rfp_local_cb; + global_rfi.rfapi_callbacks.close_cb = rfp_close_cb; + + if (cfgp != NULL) + *cfgp = &global_rfi.rfapi_config; + if (cbmp != NULL) + *cbmp = &global_rfi.rfapi_callbacks; + + rfp_vty_install(); + + return &global_rfi; +} + +/*------------------------------------------ + * rfp_stop + * + * This function is called on shutdown to trigger RFP cleanup + * + * input: + * none + * + * output: + * none + * + * return value: + * rfp_start_val +--------------------------------------------*/ +void rfp_stop(void *rfp_start_val) +{ + assert(rfp_start_val != NULL); +} + +/* TO BE REMOVED */ +void rfp_clear_vnc_nve_all(void) +{ + return; +} |