summaryrefslogtreecommitdiffstats
path: root/src/vlib
diff options
context:
space:
mode:
authorMohammed Hawari <mohammed@hawari.fr>2021-02-05 15:40:00 +0100
committerNeale Ranns <neale@graphiant.com>2021-03-14 14:37:01 +0000
commit45723b8d305c7c6d034e16fcbf1904fd72dd6bb2 (patch)
treebb010ccd464efcfb90ccfabddded7b63b8223e6a /src/vlib
parent4e3f7b2869925b0812a58d04c4bf6371e6773630 (diff)
ip: extend punt CLI for exception packets
Change-Id: I20e48a5ac8068eccb8d998346d35227c4802bb68 Signed-off-by: Mohammed Hawari <mohammed@hawari.fr> Type: feature
Diffstat (limited to 'src/vlib')
-rw-r--r--src/vlib/punt.c65
-rw-r--r--src/vlib/punt.h25
2 files changed, 75 insertions, 15 deletions
diff --git a/src/vlib/punt.c b/src/vlib/punt.c
index 04e3b5a3956..4a5e42db203 100644
--- a/src/vlib/punt.c
+++ b/src/vlib/punt.c
@@ -63,6 +63,16 @@ typedef struct punt_reason_data_t_
* Data to pass to the callback
*/
void *pd_data;
+
+ /**
+ * Flags associated to the reason
+ */
+ u32 flags;
+
+ /**
+ * Formatting function for flags;
+ */
+ format_function_t *flags_format;
} punt_reason_data_t;
/**
@@ -148,8 +158,13 @@ u8 *
format_vlib_punt_reason (u8 * s, va_list * args)
{
vlib_punt_reason_t pr = va_arg (*args, int);
-
- return (format (s, "[%d] %v", pr, punt_reason_data[pr].pd_name));
+ format_function_t *flags_format = punt_reason_data[pr].flags_format;
+ u32 flags = punt_reason_data[pr].flags;
+ if (flags_format)
+ return (format (s, "[%d] %v flags: %U", pr, punt_reason_data[pr].pd_name,
+ flags_format, flags));
+ else
+ return (format (s, "[%d] %v", pr, punt_reason_data[pr].pd_name));
}
vlib_punt_hdl_t
@@ -400,11 +415,17 @@ vlib_punt_reason_validate (vlib_punt_reason_t reason)
return (-1);
}
+u32
+vlib_punt_reason_get_flags (vlib_punt_reason_t pr)
+{
+ return pr < punt_reason_last ? punt_reason_data[pr].flags : 0;
+}
+
int
-vlib_punt_reason_alloc (vlib_punt_hdl_t client,
- const char *reason_name,
- punt_interested_listener_t fn,
- void *data, vlib_punt_reason_t * reason)
+vlib_punt_reason_alloc (vlib_punt_hdl_t client, const char *reason_name,
+ punt_interested_listener_t fn, void *data,
+ vlib_punt_reason_t *reason, u32 flags,
+ format_function_t *flags_format)
{
vlib_punt_reason_t new;
@@ -417,6 +438,8 @@ vlib_punt_reason_alloc (vlib_punt_hdl_t client,
punt_reason_data[new].pd_reason = new;
punt_reason_data[new].pd_fn = fn;
punt_reason_data[new].pd_data = data;
+ punt_reason_data[new].flags = flags;
+ punt_reason_data[new].flags_format = flags_format;
vec_add1 (punt_reason_data[new].pd_owners, client);
vlib_validate_combined_counter (&punt_counters, new);
@@ -451,6 +474,29 @@ unformat_punt_client (unformat_input_t * input, va_list * args)
punt_client_db, result);
}
+/* Parse punt reason */
+uword
+unformat_punt_reason (unformat_input_t *input, va_list *args)
+{
+ u32 *result = va_arg (*args, u32 *);
+ u8 *s = 0;
+ u8 found = 0;
+ for (int i = 0; i < punt_reason_last - 1; i++)
+ {
+ punt_reason_data_t *pd = vec_elt_at_index (punt_reason_data, 1 + i);
+ vec_reset_length (s);
+ s = format (0, "%v%c", pd->pd_name, 0);
+ if (unformat (input, (const char *) s))
+ {
+ *result = pd->pd_reason;
+ found = 1;
+ break;
+ }
+ }
+ vec_free (s);
+ return found;
+}
+
u8 *
format_punt_reg (u8 * s, va_list * args)
{
@@ -472,8 +518,11 @@ format_punt_reason_data (u8 * s, va_list * args)
punt_reason_data_t *pd = va_arg (*args, punt_reason_data_t *);
punt_client_t *pc;
u32 *pci;
-
- s = format (s, "[%d] %v from:[", pd->pd_reason, pd->pd_name);
+ if (pd->flags_format)
+ s = format (s, "[%d] %v flags: %U from:[", pd->pd_reason, pd->pd_name,
+ pd->flags_format, pd->flags);
+ else
+ s = format (s, "[%d] %v from:[", pd->pd_reason, pd->pd_name);
vec_foreach (pci, pd->pd_owners)
{
pc = pool_elt_at_index (punt_client_pool, *pci);
diff --git a/src/vlib/punt.h b/src/vlib/punt.h
index d93b5eac599..ce949421dad 100644
--- a/src/vlib/punt.h
+++ b/src/vlib/punt.h
@@ -31,8 +31,8 @@ typedef enum vlib_punt_reason_t_
/**
* Walk each punt reason
*/
-typedef int (*punt_reason_walk_cb_t) (vlib_punt_reason_t id,
- const u8 * name, void *ctx);
+typedef int (*punt_reason_walk_cb_t) (vlib_punt_reason_t id, const u8 *name,
+ void *ctx);
extern void punt_reason_walk (punt_reason_walk_cb_t cb, void *cxt);
@@ -42,6 +42,11 @@ extern void punt_reason_walk (punt_reason_walk_cb_t cb, void *cxt);
extern u8 *format_vlib_punt_reason (u8 * s, va_list * args);
/**
+ * @brief Unformat a punt reason
+ */
+extern uword unformat_punt_reason (unformat_input_t *input, va_list *args);
+
+/**
* Typedef for a client handle
*/
typedef int vlib_punt_hdl_t;
@@ -61,14 +66,18 @@ typedef void (*punt_interested_listener_t) (vlib_enable_or_disable_t i,
/**
* Allocate a new punt reason
- * @param fn - A callback to invoke when an entity becomes [un]interested
- * in the punt code.
- * @param data - To be passed in the callback function.
+ * @param fn - A callback to invoke when an entity becomes
+ * [un]interested in the punt code.
+ * @param data - To be passed in the callback function.
+ * @param flags - flags associated with the punt reason
+ * @param flags_format - formatting function to display those flags (may be
+ * NULL)
*/
extern int vlib_punt_reason_alloc (vlib_punt_hdl_t client,
const char *reason_name,
- punt_interested_listener_t fn,
- void *data, vlib_punt_reason_t * reason);
+ punt_interested_listener_t fn, void *data,
+ vlib_punt_reason_t *reason, u32 flags,
+ format_function_t *flags_format);
/**
* Validate that a punt reason is assigned
@@ -87,6 +96,8 @@ extern int vlib_punt_register (vlib_punt_hdl_t client,
extern int vlib_punt_unregister (vlib_punt_hdl_t client,
vlib_punt_reason_t pr, const char *node);
+extern u32 vlib_punt_reason_get_flags (vlib_punt_reason_t pr);
+
/**
* FOR USE IN THE DP ONLY
*