summaryrefslogtreecommitdiffstats
path: root/bgpd/rfp-example/librfp/rfp_example.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/rfp-example/librfp/rfp_example.c')
-rw-r--r--bgpd/rfp-example/librfp/rfp_example.c331
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;
+}