diff options
-rw-r--r-- | src/vnet/dev/dev.c | 1 | ||||
-rw-r--r-- | src/vnet/dev/dev.h | 14 | ||||
-rw-r--r-- | src/vnet/dev/error.c | 25 | ||||
-rw-r--r-- | src/vnet/dev/errors.h | 4 | ||||
-rw-r--r-- | src/vnet/dev/format.c | 15 | ||||
-rw-r--r-- | src/vnet/dev/handlers.c | 42 |
6 files changed, 97 insertions, 4 deletions
diff --git a/src/vnet/dev/dev.c b/src/vnet/dev/dev.c index 0e04e9ab64b..e04fa161ce2 100644 --- a/src/vnet/dev/dev.c +++ b/src/vnet/dev/dev.c @@ -399,6 +399,7 @@ vnet_dev_main_init (vlib_main_t *vm) .mac_addr_change_function = vnet_dev_port_mac_change, .mac_addr_add_del_function = vnet_dev_add_del_mac_address, .flow_ops_function = vnet_dev_flow_ops_fn, + .format_flow = format_vnet_dev_flow, .set_rss_queues_function = vnet_dev_interface_set_rss_queues, }; driver->dev_class_index = vnet_register_device_class (vm, dev_class); diff --git a/src/vnet/dev/dev.h b/src/vnet/dev/dev.h index e7c6ca45fb5..bbf2f9dff21 100644 --- a/src/vnet/dev/dev.h +++ b/src/vnet/dev/dev.h @@ -144,7 +144,11 @@ typedef struct _ (ADD_SECONDARY_HW_ADDR) \ _ (REMOVE_SECONDARY_HW_ADDR) \ _ (RXQ_INTR_MODE_ENABLE) \ - _ (RXQ_INTR_MODE_DISABLE) + _ (RXQ_INTR_MODE_DISABLE) \ + _ (ADD_RX_FLOW) \ + _ (DEL_RX_FLOW) \ + _ (GET_RX_FLOW_COUNTER) \ + _ (RESET_RX_FLOW_COUNTER) typedef enum { @@ -166,6 +170,11 @@ typedef struct vnet_dev_port_cfg_change_req vnet_dev_hw_addr_t addr; u16 max_rx_frame_size; vnet_dev_queue_id_t queue_id; + struct + { + u32 flow_index; + uword *private_data; + }; }; } vnet_dev_port_cfg_change_req_t; @@ -237,6 +246,7 @@ typedef struct vnet_dev_port_op_no_rv_t *deinit; vnet_dev_port_op_no_rv_t *free; format_function_t *format_status; + format_function_t *format_flow; } vnet_dev_port_ops_t; typedef union @@ -535,6 +545,7 @@ void *vnet_dev_get_device_info (vlib_main_t *, vnet_dev_device_id_t); /* error.c */ clib_error_t *vnet_dev_port_err (vlib_main_t *, vnet_dev_port_t *, vnet_dev_rv_t, char *, ...); +int vnet_dev_flow_err (vlib_main_t *, vnet_dev_rv_t); /* handlers.c */ clib_error_t *vnet_dev_port_set_max_frame_size (vnet_main_t *, @@ -654,6 +665,7 @@ format_function_t format_vnet_dev_port_tx_offloads; format_function_t format_vnet_dev_rv; format_function_t format_vnet_dev_rx_queue_info; format_function_t format_vnet_dev_tx_queue_info; +format_function_t format_vnet_dev_flow; unformat_function_t unformat_vnet_dev_flags; unformat_function_t unformat_vnet_dev_port_flags; diff --git a/src/vnet/dev/error.c b/src/vnet/dev/error.c index df9c6d364e7..4e057010af0 100644 --- a/src/vnet/dev/error.c +++ b/src/vnet/dev/error.c @@ -6,6 +6,7 @@ #include <vnet/ethernet/ethernet.h> #include <vnet/dev/dev.h> #include <vnet/dev/counters.h> +#include <vnet/flow/flow.h> clib_error_t * vnet_dev_port_err (vlib_main_t *vm, vnet_dev_port_t *port, vnet_dev_rv_t rv, @@ -27,3 +28,27 @@ vnet_dev_port_err (vlib_main_t *vm, vnet_dev_port_t *port, vnet_dev_rv_t rv, vec_free (s); return err; } + +int +vnet_dev_flow_err (vlib_main_t *vm, vnet_dev_rv_t rv) +{ + if (rv == VNET_DEV_OK) + return 0; + + switch (rv) + { + /* clang-format off */ +#define _(n, e, s) \ + case VNET_DEV_ERR_##e: \ + return VNET_FLOW_ERROR_##e; + foreach_flow_error; +#undef _ + /* clang-format on */ + default: + ASSERT (0); + } + + ASSERT (0); + + return 0; +} diff --git a/src/vnet/dev/errors.h b/src/vnet/dev/errors.h index 47e72957da3..430a6aef282 100644 --- a/src/vnet/dev/errors.h +++ b/src/vnet/dev/errors.h @@ -39,6 +39,8 @@ _ (UNKNOWN_INTERFACE, "unknown interface") \ _ (UNSUPPORTED_CONFIG, "unsupported config") \ _ (UNSUPPORTED_DEVICE, "unsupported device") \ - _ (UNSUPPORTED_DEVICE_VER, "unsupported device version") + _ (UNSUPPORTED_DEVICE_VER, "unsupported device version") \ + _ (ALREADY_DONE, "already done") \ + _ (NO_SUCH_INTERFACE, "no such interface") #endif /* _VNET_DEV_ERRORS_H_ */ diff --git a/src/vnet/dev/format.c b/src/vnet/dev/format.c index 848cd13a6c3..ed83a0eba95 100644 --- a/src/vnet/dev/format.c +++ b/src/vnet/dev/format.c @@ -490,3 +490,18 @@ format_vnet_dev_port_tx_offloads (u8 *s, va_list *args) return s; } + +u8 * +format_vnet_dev_flow (u8 *s, va_list *args) +{ + u32 dev_instance = va_arg (*args, u32); + u32 flow_index = va_arg (*args, u32); + uword private_data = va_arg (*args, uword); + vnet_dev_port_t *port = vnet_dev_get_port_from_dev_instance (dev_instance); + + if (port->port_ops.format_flow) + s = format (s, "%U", port->port_ops.format_flow, port, flow_index, + private_data); + + return s; +} diff --git a/src/vnet/dev/handlers.c b/src/vnet/dev/handlers.c index fcaef14221f..2a55affe3e3 100644 --- a/src/vnet/dev/handlers.c +++ b/src/vnet/dev/handlers.c @@ -146,9 +146,47 @@ int vnet_dev_flow_ops_fn (vnet_main_t *vnm, vnet_flow_dev_op_t op, u32 dev_instance, u32 flow_index, uword *private_data) { + vlib_main_t *vm = vlib_get_main (); vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (dev_instance); - log_warn (p->dev, "unsupported request for flow_ops received"); - return VNET_FLOW_ERROR_NOT_SUPPORTED; + vnet_dev_port_cfg_change_req_t req; + vnet_dev_rv_t rv; + + switch (op) + { + case VNET_FLOW_DEV_OP_ADD_FLOW: + req.type = VNET_DEV_PORT_CFG_ADD_RX_FLOW; + break; + case VNET_FLOW_DEV_OP_DEL_FLOW: + req.type = VNET_DEV_PORT_CFG_DEL_RX_FLOW; + break; + case VNET_FLOW_DEV_OP_GET_COUNTER: + req.type = VNET_DEV_PORT_CFG_GET_RX_FLOW_COUNTER; + break; + case VNET_FLOW_DEV_OP_RESET_COUNTER: + req.type = VNET_DEV_PORT_CFG_RESET_RX_FLOW_COUNTER; + break; + default: + log_warn (p->dev, "unsupported request for flow_ops received"); + return VNET_FLOW_ERROR_NOT_SUPPORTED; + } + + req.flow_index = flow_index; + req.private_data = private_data; + + rv = vnet_dev_port_cfg_change_req_validate (vm, p, &req); + if (rv != VNET_DEV_OK) + { + log_err (p->dev, "validation failed for flow_ops"); + return VNET_FLOW_ERROR_NOT_SUPPORTED; + } + + if ((rv = vnet_dev_process_port_cfg_change_req (vm, p, &req)) != VNET_DEV_OK) + { + log_err (p->dev, "request for flow_ops failed"); + return vnet_dev_flow_err (vm, rv); + } + + return 0; } clib_error_t * |