dev: secondary interfaces support
Type: feature Change-Id: I6cc4340431b8273022955fca1600061a722e3ace Signed-off-by: Damjan Marion <damarion@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
de020ab478
commit
61e287b9f8
@ -156,6 +156,7 @@ vnet_dev_api_create_port_if (vlib_main_t *vm,
|
||||
{
|
||||
vnet_dev_t *dev = vnet_dev_by_index (args->dev_index);
|
||||
vnet_dev_port_t *port = 0;
|
||||
vnet_dev_port_if_create_args_t a = {};
|
||||
u16 n_threads = vlib_get_n_threads ();
|
||||
int default_is_intr_mode;
|
||||
vnet_dev_rv_t rv;
|
||||
@ -181,7 +182,7 @@ vnet_dev_api_create_port_if (vlib_main_t *vm,
|
||||
if (!port)
|
||||
return VNET_DEV_ERR_INVALID_DEVICE_ID;
|
||||
|
||||
if (port->interface_created)
|
||||
if (port->interfaces)
|
||||
return VNET_DEV_ERR_ALREADY_EXISTS;
|
||||
|
||||
if (args->args)
|
||||
@ -202,47 +203,82 @@ vnet_dev_api_create_port_if (vlib_main_t *vm,
|
||||
{
|
||||
if (args->num_rx_queues > port->attr.max_rx_queues)
|
||||
return VNET_DEV_ERR_INVALID_NUM_RX_QUEUES;
|
||||
port->intf.num_rx_queues = args->num_rx_queues;
|
||||
a.num_rx_queues = args->num_rx_queues;
|
||||
}
|
||||
else
|
||||
port->intf.num_rx_queues = clib_min (port->attr.max_tx_queues, 1);
|
||||
a.num_rx_queues = clib_min (port->attr.max_tx_queues, 1);
|
||||
|
||||
if (args->num_tx_queues)
|
||||
{
|
||||
if (args->num_tx_queues > port->attr.max_tx_queues)
|
||||
return VNET_DEV_ERR_INVALID_NUM_TX_QUEUES;
|
||||
port->intf.num_tx_queues = args->num_tx_queues;
|
||||
a.num_tx_queues = args->num_tx_queues;
|
||||
}
|
||||
else
|
||||
port->intf.num_tx_queues = clib_min (port->attr.max_tx_queues, n_threads);
|
||||
a.num_tx_queues = clib_min (port->attr.max_tx_queues, n_threads);
|
||||
|
||||
if (args->rx_queue_size)
|
||||
{
|
||||
if (!_vnet_dev_queue_size_validate (args->rx_queue_size,
|
||||
port->rx_queue_config))
|
||||
return VNET_DEV_ERR_INVALID_RX_QUEUE_SIZE;
|
||||
port->intf.rxq_sz = args->rx_queue_size;
|
||||
a.rxq_sz = args->rx_queue_size;
|
||||
}
|
||||
else
|
||||
port->intf.rxq_sz = port->rx_queue_config.default_size;
|
||||
a.rxq_sz = port->rx_queue_config.default_size;
|
||||
|
||||
if (args->tx_queue_size)
|
||||
{
|
||||
if (!_vnet_dev_queue_size_validate (args->tx_queue_size,
|
||||
port->tx_queue_config))
|
||||
return VNET_DEV_ERR_INVALID_TX_QUEUE_SIZE;
|
||||
port->intf.txq_sz = args->tx_queue_size;
|
||||
a.txq_sz = args->tx_queue_size;
|
||||
}
|
||||
else
|
||||
port->intf.txq_sz = port->tx_queue_config.default_size;
|
||||
a.txq_sz = port->tx_queue_config.default_size;
|
||||
|
||||
clib_memcpy (port->intf.name, args->intf_name, sizeof (port->intf.name));
|
||||
port->intf.default_is_intr_mode = default_is_intr_mode;
|
||||
port->intf.consistent_qp =
|
||||
(args->flags.n & VNET_DEV_PORT_F_CONSISTENT_QP) != 0;
|
||||
clib_memcpy (a.name, args->intf_name, sizeof (a.name));
|
||||
a.default_is_intr_mode = default_is_intr_mode;
|
||||
a.consistent_qp = (args->flags.n & VNET_DEV_PORT_F_CONSISTENT_QP) != 0;
|
||||
|
||||
rv = vnet_dev_process_call_port_op (vm, port, vnet_dev_port_if_create);
|
||||
args->sw_if_index = (rv == VNET_DEV_OK) ? port->intf.sw_if_index : ~0;
|
||||
rv = vnet_dev_process_call_port_op_with_ptr (vm, port,
|
||||
vnet_dev_port_if_create, &a);
|
||||
args->sw_if_index = (rv == VNET_DEV_OK) ? a.sw_if_index : ~0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
vnet_dev_rv_t
|
||||
vnet_dev_api_port_add_sec_if (vlib_main_t *vm,
|
||||
vnet_dev_api_port_add_sec_if_args_t *args)
|
||||
{
|
||||
vnet_dev_port_t *port = 0;
|
||||
vnet_dev_t *dev = 0;
|
||||
vnet_dev_port_sec_if_create_args_t a = {};
|
||||
vnet_dev_rv_t rv = VNET_DEV_OK;
|
||||
|
||||
port = vnet_dev_get_port_from_sw_if_index (args->primary_sw_if_index);
|
||||
if (port == 0)
|
||||
return VNET_DEV_ERR_NOT_FOUND;
|
||||
|
||||
log_debug (dev,
|
||||
"create_port_if: primary_sw_if_index %u intf_name '%s' "
|
||||
"args '%v'",
|
||||
args->primary_sw_if_index, args->intf_name, args->args);
|
||||
|
||||
if (port->interfaces == 0)
|
||||
return VNET_DEV_ERR_PRIMARY_INTERFACE_MISSING;
|
||||
|
||||
clib_memcpy (a.name, args->intf_name, sizeof (a.name));
|
||||
a.args = args->args;
|
||||
|
||||
rv = vnet_dev_process_call_port_op_with_ptr (vm, port,
|
||||
vnet_dev_port_add_sec_if, &a);
|
||||
|
||||
if (rv != VNET_DEV_OK)
|
||||
args->sw_if_index = ~0;
|
||||
else
|
||||
args->sw_if_index = a.sw_if_index;
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -250,10 +286,24 @@ vnet_dev_api_create_port_if (vlib_main_t *vm,
|
||||
vnet_dev_rv_t
|
||||
vnet_dev_api_remove_port_if (vlib_main_t *vm,
|
||||
vnet_dev_api_remove_port_if_args_t *args)
|
||||
{
|
||||
vnet_dev_port_t *port;
|
||||
|
||||
port = vnet_dev_get_port_from_sw_if_index (args->sw_if_index);
|
||||
|
||||
if (port == 0)
|
||||
return VNET_DEV_ERR_UNKNOWN_INTERFACE;
|
||||
|
||||
return vnet_dev_process_call_port_op (vm, port, vnet_dev_port_if_remove);
|
||||
}
|
||||
|
||||
vnet_dev_rv_t
|
||||
vnet_dev_api_port_del_sec_if (vlib_main_t *vm,
|
||||
vnet_dev_api_port_del_sec_if_args_t *args)
|
||||
{
|
||||
vnet_dev_main_t *dm = &vnet_dev_main;
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
vnet_sw_interface_t *si;
|
||||
vnet_sw_interface_t *si, *sup_si;
|
||||
vnet_hw_interface_t *hi;
|
||||
vnet_dev_port_t *port;
|
||||
|
||||
@ -261,7 +311,14 @@ vnet_dev_api_remove_port_if (vlib_main_t *vm,
|
||||
if (!si)
|
||||
return VNET_DEV_ERR_UNKNOWN_INTERFACE;
|
||||
|
||||
hi = vnet_get_hw_interface_or_null (vnm, si->hw_if_index);
|
||||
if (si->sup_sw_if_index == si->sw_if_index)
|
||||
return VNET_DEV_ERR_UNKNOWN_INTERFACE;
|
||||
|
||||
sup_si = vnet_get_sw_interface_or_null (vnm, si->sup_sw_if_index);
|
||||
if (!sup_si)
|
||||
return VNET_DEV_ERR_UNKNOWN_INTERFACE;
|
||||
|
||||
hi = vnet_get_hw_interface_or_null (vnm, sup_si->hw_if_index);
|
||||
if (!hi)
|
||||
return VNET_DEV_ERR_UNKNOWN_INTERFACE;
|
||||
|
||||
@ -270,8 +327,10 @@ vnet_dev_api_remove_port_if (vlib_main_t *vm,
|
||||
|
||||
port = vnet_dev_get_port_from_dev_instance (hi->dev_instance);
|
||||
|
||||
if (port->intf.hw_if_index != si->hw_if_index)
|
||||
if (port->interfaces->primary_interface.hw_if_index != si->hw_if_index)
|
||||
return VNET_DEV_ERR_UNKNOWN_INTERFACE;
|
||||
|
||||
return vnet_dev_process_call_port_op (vm, port, vnet_dev_port_if_remove);
|
||||
return vnet_dev_process_call_port_op_with_ptr (
|
||||
vm, port, vnet_dev_port_del_sec_if,
|
||||
&(vnet_dev_port_del_sec_if_args_t){ .sw_if_index = args->sw_if_index });
|
||||
}
|
||||
|
@ -65,4 +65,27 @@ vnet_dev_rv_t
|
||||
vnet_dev_api_remove_port_if (vlib_main_t *,
|
||||
vnet_dev_api_remove_port_if_args_t *);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 primary_sw_if_index;
|
||||
vnet_dev_if_name_t intf_name;
|
||||
u8 *args;
|
||||
|
||||
/* return */
|
||||
u32 sw_if_index;
|
||||
} vnet_dev_api_port_add_sec_if_args_t;
|
||||
|
||||
vnet_dev_rv_t
|
||||
vnet_dev_api_port_add_sec_if (vlib_main_t *,
|
||||
vnet_dev_api_port_add_sec_if_args_t *);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
} vnet_dev_api_port_del_sec_if_args_t;
|
||||
|
||||
vnet_dev_rv_t
|
||||
vnet_dev_api_port_del_sec_if (vlib_main_t *,
|
||||
vnet_dev_api_port_del_sec_if_args_t *);
|
||||
|
||||
#endif /* _VNET_DEV_API_H_ */
|
||||
|
@ -222,6 +222,94 @@ VLIB_CLI_COMMAND (device_remove_if_cmd, static) = {
|
||||
.is_mp_safe = 1,
|
||||
};
|
||||
|
||||
static clib_error_t *
|
||||
device_create_sec_if_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
|
||||
vlib_cli_command_t *cmd)
|
||||
{
|
||||
vnet_dev_api_port_add_sec_if_args_t a = {};
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
vnet_dev_rv_t rv;
|
||||
|
||||
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (!a.intf_name[0] &&
|
||||
unformat (input, "if-name %U", unformat_c_string_array, a.intf_name,
|
||||
sizeof (a.intf_name)))
|
||||
;
|
||||
else if (unformat (input, "primary-if-name %U",
|
||||
unformat_vnet_sw_interface, vnm,
|
||||
&a.primary_sw_if_index))
|
||||
;
|
||||
else if (unformat (input, "primary-sw-if-index %u",
|
||||
&a.primary_sw_if_index))
|
||||
;
|
||||
else if (!a.args && unformat (input, "args %v", &a.args))
|
||||
;
|
||||
else
|
||||
return clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, input);
|
||||
}
|
||||
|
||||
rv = vnet_dev_api_port_add_sec_if (vm, &a);
|
||||
|
||||
vec_free (a.args);
|
||||
|
||||
if (rv != VNET_DEV_OK)
|
||||
return clib_error_return (0, "unable to create secondary interface: %U",
|
||||
format_vnet_dev_rv, rv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VLIB_CLI_COMMAND (device_create_sec_if_cmd, static) = {
|
||||
.path = "device create-secondary-interface",
|
||||
.short_help = "device create-secondary-interface [<interface-name> | "
|
||||
"sw-if-index <n>] id <n> [args <sec-if-args>]",
|
||||
.function = device_create_sec_if_cmd_fn,
|
||||
.is_mp_safe = 1,
|
||||
};
|
||||
|
||||
static clib_error_t *
|
||||
device_remove_sec_if_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
|
||||
vlib_cli_command_t *cmd)
|
||||
{
|
||||
vnet_dev_api_port_del_sec_if_args_t a = { .sw_if_index = ~0 };
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
vnet_dev_rv_t rv;
|
||||
|
||||
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
|
||||
&a.sw_if_index))
|
||||
;
|
||||
else if (unformat (input, "sw-if-index %u", &a.sw_if_index))
|
||||
;
|
||||
else
|
||||
return clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, input);
|
||||
}
|
||||
|
||||
if (a.sw_if_index == ~0)
|
||||
return clib_error_return (
|
||||
0, "please specify existing secondary interface name");
|
||||
|
||||
rv = vnet_dev_api_port_del_sec_if (vm, &a);
|
||||
|
||||
if (rv != VNET_DEV_OK)
|
||||
return clib_error_return (0, "unable to remove secondary interface: %U",
|
||||
format_vnet_dev_rv, rv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VLIB_CLI_COMMAND (device_remove_sec_if_cmd, static) = {
|
||||
.path = "device remove-secondary-interface",
|
||||
.short_help =
|
||||
"device remove-secondary-interface [<interface-name> | sw-if-index <n>]",
|
||||
.function = device_remove_sec_if_cmd_fn,
|
||||
.is_mp_safe = 1,
|
||||
};
|
||||
|
||||
static clib_error_t *
|
||||
show_devices_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
|
||||
vlib_cli_command_t *cmd)
|
||||
|
@ -130,7 +130,7 @@ vnet_dev_deinit (vlib_main_t *vm, vnet_dev_t *dev)
|
||||
vnet_dev_validate (vm, dev);
|
||||
|
||||
foreach_vnet_dev_port (p, dev)
|
||||
ASSERT (p->interface_created == 0);
|
||||
ASSERT (p->interfaces == 0);
|
||||
|
||||
if (dev->ops.deinit)
|
||||
dev->ops.deinit (vm, dev);
|
||||
@ -188,7 +188,7 @@ void
|
||||
vnet_dev_detach (vlib_main_t *vm, vnet_dev_t *dev)
|
||||
{
|
||||
foreach_vnet_dev_port (p, dev)
|
||||
if (p->interface_created)
|
||||
if (p->interfaces)
|
||||
vnet_dev_port_if_remove (vm, p);
|
||||
vnet_dev_deinit (vm, dev);
|
||||
vnet_dev_free (vm, dev);
|
||||
@ -260,6 +260,8 @@ vnet_dev_feature_update_cb (u32 sw_if_index, u8 arc_index, u8 is_enable,
|
||||
vnet_feature_config_main_t *cm;
|
||||
vnet_dev_main_t *vdm = &vnet_dev_main;
|
||||
vnet_dev_port_t *port;
|
||||
vnet_dev_port_interface_t *intf;
|
||||
vnet_dev_instance_t *di;
|
||||
vnet_hw_interface_t *hw;
|
||||
u32 current_config_index = ~0;
|
||||
u32 next_index = ~0;
|
||||
@ -269,9 +271,18 @@ vnet_dev_feature_update_cb (u32 sw_if_index, u8 arc_index, u8 is_enable,
|
||||
return;
|
||||
|
||||
hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
port = vnet_dev_get_port_from_dev_instance (hw->dev_instance);
|
||||
di = vnet_dev_get_dev_instance (hw->dev_instance);
|
||||
|
||||
if (port == 0 || port->intf.sw_if_index != sw_if_index)
|
||||
if (!di)
|
||||
return;
|
||||
|
||||
intf = di->is_primary_if ?
|
||||
vnet_dev_port_get_primary_if (di->port) :
|
||||
vnet_dev_port_get_sec_if_by_index (di->port, di->sec_if_index);
|
||||
|
||||
port = di->port;
|
||||
|
||||
if (port == 0 || intf->sw_if_index != sw_if_index)
|
||||
return;
|
||||
|
||||
if (vnet_have_features (arc_index, sw_if_index))
|
||||
@ -281,28 +292,27 @@ vnet_dev_feature_update_cb (u32 sw_if_index, u8 arc_index, u8 is_enable,
|
||||
vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
|
||||
vnet_get_config_data (&cm->config_main, ¤t_config_index,
|
||||
&next_index, 0);
|
||||
if (port->intf.feature_arc == 0 ||
|
||||
port->intf.rx_next_index != next_index ||
|
||||
port->intf.current_config_index != current_config_index)
|
||||
if (intf->feature_arc == 0 || intf->rx_next_index != next_index ||
|
||||
intf->current_config_index != current_config_index)
|
||||
{
|
||||
port->intf.current_config_index = current_config_index;
|
||||
port->intf.rx_next_index = next_index;
|
||||
port->intf.feature_arc_index = arc_index;
|
||||
port->intf.feature_arc = 1;
|
||||
intf->current_config_index = current_config_index;
|
||||
intf->rx_next_index = next_index;
|
||||
intf->feature_arc_index = arc_index;
|
||||
intf->feature_arc = 1;
|
||||
update_runtime = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (port->intf.feature_arc)
|
||||
if (intf->feature_arc)
|
||||
{
|
||||
port->intf.current_config_index = 0;
|
||||
port->intf.rx_next_index =
|
||||
port->intf.redirect_to_node ?
|
||||
port->intf.redirect_to_node_next_index :
|
||||
vnet_dev_default_next_index_by_port_type[port->attr.type];
|
||||
port->intf.feature_arc_index = 0;
|
||||
port->intf.feature_arc = 0;
|
||||
intf->current_config_index = 0;
|
||||
intf->rx_next_index =
|
||||
intf->redirect_to_node ?
|
||||
intf->redirect_to_node_next_index :
|
||||
vnet_dev_default_next_index_by_port_type[port->attr.type];
|
||||
intf->feature_arc_index = 0;
|
||||
intf->feature_arc = 0;
|
||||
update_runtime = 1;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ typedef enum
|
||||
_ (interrupt_mode) \
|
||||
_ (rss) \
|
||||
_ (change_max_rx_frame_size) \
|
||||
_ (mac_filter)
|
||||
_ (mac_filter) \
|
||||
_ (secondary_interfaces)
|
||||
|
||||
#define foreach_vnet_dev_port_rx_offloads _ (ip4_cksum)
|
||||
|
||||
@ -253,6 +254,8 @@ typedef struct
|
||||
vnet_dev_port_op_no_rv_t *deinit;
|
||||
vnet_dev_port_op_no_rv_t *free;
|
||||
vnet_dev_port_op_no_rv_t *clear_counters;
|
||||
vnet_dev_port_op_with_ptr_t *add_sec_if;
|
||||
vnet_dev_port_op_with_ptr_t *del_sec_if;
|
||||
format_function_t *format_status;
|
||||
format_function_t *format_flow;
|
||||
} vnet_dev_port_ops_t;
|
||||
@ -269,30 +272,41 @@ typedef union
|
||||
u8 as_number;
|
||||
} vnet_dev_rx_queue_rt_req_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vlib_buffer_template_t buffer_template;
|
||||
u32 sw_if_index;
|
||||
u16 next_index;
|
||||
u16 sec_if_index;
|
||||
} vnet_dev_rx_queue_if_rt_data_t;
|
||||
|
||||
typedef struct vnet_dev_rx_queue
|
||||
{
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||
vnet_dev_port_t *port;
|
||||
u16 rx_thread_index;
|
||||
u16 index;
|
||||
vnet_dev_counter_main_t *counter_main;
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (runtime0);
|
||||
vnet_dev_rx_queue_t *next_on_thread;
|
||||
u16 size;
|
||||
u8 interrupt_mode : 1;
|
||||
u8 enabled : 1;
|
||||
u8 started : 1;
|
||||
u8 suspended : 1;
|
||||
vnet_dev_queue_id_t queue_id;
|
||||
u16 size;
|
||||
u16 next_index;
|
||||
vnet_dev_rx_queue_rt_req_t runtime_request;
|
||||
vnet_dev_counter_main_t *counter_main;
|
||||
vnet_dev_rx_queue_t *next_on_thread;
|
||||
vnet_dev_queue_id_t queue_id;
|
||||
vnet_dev_rx_queue_if_rt_data_t **sec_if_rt_data;
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (runtime1);
|
||||
vlib_buffer_template_t buffer_template;
|
||||
vnet_dev_rx_queue_if_rt_data_t if_rt_data;
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (driver_data);
|
||||
u8 data[];
|
||||
} vnet_dev_rx_queue_t;
|
||||
|
||||
#if CLIB_CACHE_LINE_BYTES > 64
|
||||
STATIC_ASSERT_SIZEOF (vnet_dev_rx_queue_t, 2 * CLIB_CACHE_LINE_BYTES);
|
||||
#else
|
||||
STATIC_ASSERT_SIZEOF (vnet_dev_rx_queue_t, 3 * CLIB_CACHE_LINE_BYTES);
|
||||
#endif
|
||||
|
||||
typedef struct vnet_dev_tx_queue
|
||||
{
|
||||
@ -314,6 +328,38 @@ typedef struct vnet_dev_tx_queue
|
||||
|
||||
STATIC_ASSERT_SIZEOF (vnet_dev_tx_queue_t, 2 * CLIB_CACHE_LINE_BYTES);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vnet_dev_if_name_t name;
|
||||
u8 interface_created : 1;
|
||||
u8 feature_arc : 1;
|
||||
u8 redirect_to_node : 1;
|
||||
u8 feature_arc_index;
|
||||
u16 rx_next_index;
|
||||
u32 index;
|
||||
u32 sw_if_index;
|
||||
u32 hw_if_index;
|
||||
u32 dev_instance;
|
||||
u32 tx_node_index;
|
||||
u32 next_index;
|
||||
u32 current_config_index;
|
||||
u16 redirect_to_node_next_index;
|
||||
u32 user_data;
|
||||
vnet_dev_arg_t *args;
|
||||
} vnet_dev_port_interface_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 rx_node_index;
|
||||
u8 default_is_intr_mode : 1;
|
||||
u16 num_rx_queues;
|
||||
u16 num_tx_queues;
|
||||
u16 txq_sz;
|
||||
u16 rxq_sz;
|
||||
vnet_dev_port_interface_t primary_interface;
|
||||
vnet_dev_port_interface_t **secondary_interfaces;
|
||||
} vnet_dev_port_interfaces_t;
|
||||
|
||||
typedef struct vnet_dev_port
|
||||
{
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||
@ -324,7 +370,6 @@ typedef struct vnet_dev_port
|
||||
u8 started : 1;
|
||||
u8 link_up : 1;
|
||||
u8 promisc : 1;
|
||||
u8 interface_created : 1;
|
||||
u8 rx_node_assigned : 1;
|
||||
vnet_dev_counter_main_t *counter_main;
|
||||
vnet_dev_queue_config_t rx_queue_config;
|
||||
@ -339,32 +384,12 @@ typedef struct vnet_dev_port
|
||||
vnet_dev_tx_queue_t **tx_queues;
|
||||
vnet_dev_port_ops_t port_ops;
|
||||
vnet_dev_arg_t *args;
|
||||
vnet_dev_arg_t *sec_if_args;
|
||||
vnet_dev_rx_queue_ops_t rx_queue_ops;
|
||||
vnet_dev_tx_queue_ops_t tx_queue_ops;
|
||||
vnet_dev_node_t rx_node;
|
||||
vnet_dev_node_t tx_node;
|
||||
|
||||
struct
|
||||
{
|
||||
vnet_dev_if_name_t name;
|
||||
u32 dev_instance;
|
||||
u32 rx_node_index;
|
||||
u32 current_config_index;
|
||||
u16 rx_next_index;
|
||||
u16 redirect_to_node_next_index;
|
||||
u8 feature_arc_index;
|
||||
u8 feature_arc : 1;
|
||||
u8 redirect_to_node : 1;
|
||||
u8 default_is_intr_mode : 1;
|
||||
u8 consistent_qp : 1;
|
||||
u32 tx_node_index;
|
||||
u32 hw_if_index;
|
||||
u32 sw_if_index;
|
||||
u16 num_rx_queues;
|
||||
u16 num_tx_queues;
|
||||
u16 txq_sz;
|
||||
u16 rxq_sz;
|
||||
} intf;
|
||||
vnet_dev_port_interfaces_t *interfaces;
|
||||
|
||||
CLIB_CACHE_LINE_ALIGN_MARK (data0);
|
||||
u8 data[];
|
||||
@ -463,6 +488,8 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
vnet_dev_port_t *port;
|
||||
u32 sec_if_index;
|
||||
u8 is_primary_if : 1;
|
||||
} vnet_dev_instance_t;
|
||||
|
||||
typedef struct
|
||||
@ -493,6 +520,7 @@ typedef struct
|
||||
vnet_dev_port_attr_t attr;
|
||||
vnet_dev_port_ops_t ops;
|
||||
vnet_dev_arg_t *args;
|
||||
vnet_dev_arg_t *sec_if_args;
|
||||
u16 data_size;
|
||||
void *initial_data;
|
||||
} port;
|
||||
@ -578,12 +606,44 @@ void vnet_dev_clear_hw_interface_counters (u32);
|
||||
void vnet_dev_set_interface_next_node (vnet_main_t *, u32, u32);
|
||||
|
||||
/* port.c */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vnet_dev_if_name_t name;
|
||||
u16 num_rx_queues;
|
||||
u16 num_tx_queues;
|
||||
u16 rxq_sz;
|
||||
u16 txq_sz;
|
||||
u8 default_is_intr_mode : 1;
|
||||
u8 consistent_qp : 1;
|
||||
|
||||
/* return */
|
||||
u32 sw_if_index;
|
||||
} vnet_dev_port_if_create_args_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vnet_dev_if_name_t name;
|
||||
u8 *args;
|
||||
|
||||
/* return */
|
||||
u32 sw_if_index;
|
||||
} vnet_dev_port_sec_if_create_args_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
} vnet_dev_port_del_sec_if_args_t;
|
||||
|
||||
vnet_dev_port_op_t vnet_dev_port_start;
|
||||
vnet_dev_port_op_t vnet_dev_port_start_all_rx_queues;
|
||||
vnet_dev_port_op_t vnet_dev_port_start_all_tx_queues;
|
||||
vnet_dev_port_op_no_rv_t vnet_dev_port_stop;
|
||||
vnet_dev_port_op_no_rv_t vnet_dev_port_deinit;
|
||||
vnet_dev_port_op_no_rv_t vnet_dev_port_free;
|
||||
vnet_dev_port_op_with_ptr_t vnet_dev_port_add_sec_if;
|
||||
vnet_dev_port_op_with_ptr_t vnet_dev_port_del_sec_if;
|
||||
|
||||
void vnet_dev_port_add_counters (vlib_main_t *, vnet_dev_port_t *,
|
||||
vnet_dev_counter_t *, u16);
|
||||
vnet_dev_port_op_no_rv_t vnet_dev_port_free_counters;
|
||||
@ -596,7 +656,7 @@ vnet_dev_port_cfg_change_req_validate (vlib_main_t *, vnet_dev_port_t *,
|
||||
vnet_dev_port_cfg_change_req_t *);
|
||||
vnet_dev_rv_t vnet_dev_port_cfg_change (vlib_main_t *, vnet_dev_port_t *,
|
||||
vnet_dev_port_cfg_change_req_t *);
|
||||
vnet_dev_port_op_t vnet_dev_port_if_create;
|
||||
vnet_dev_port_op_with_ptr_t vnet_dev_port_if_create;
|
||||
vnet_dev_port_op_t vnet_dev_port_if_remove;
|
||||
|
||||
/* queue.c */
|
||||
|
@ -60,6 +60,18 @@ vnet_dev_get_dev_instance (u32 dev_instance)
|
||||
return pool_elt_at_index (dm->dev_instances, dev_instance);
|
||||
}
|
||||
|
||||
static_always_inline vnet_dev_port_interface_t *
|
||||
vnet_dev_port_get_primary_if (vnet_dev_port_t *p)
|
||||
{
|
||||
return &p->interfaces->primary_interface;
|
||||
}
|
||||
|
||||
static_always_inline vnet_dev_port_interface_t *
|
||||
vnet_dev_port_get_sec_if_by_index (vnet_dev_port_t *p, u32 index)
|
||||
{
|
||||
return *pool_elt_at_index (p->interfaces->secondary_interfaces, index);
|
||||
}
|
||||
|
||||
static_always_inline vnet_dev_port_t *
|
||||
vnet_dev_get_port_from_dev_instance (u32 dev_instance)
|
||||
{
|
||||
@ -76,7 +88,8 @@ vnet_dev_get_port_from_hw_if_index (u32 hw_if_index)
|
||||
hw = vnet_get_hw_interface (vnet_get_main (), hw_if_index);
|
||||
port = vnet_dev_get_port_from_dev_instance (hw->dev_instance);
|
||||
|
||||
if (!port || port->intf.hw_if_index != hw_if_index)
|
||||
if (!port || !port->interfaces ||
|
||||
port->interfaces->primary_interface.hw_if_index != hw_if_index)
|
||||
return 0;
|
||||
|
||||
return port;
|
||||
@ -85,19 +98,32 @@ vnet_dev_get_port_from_hw_if_index (u32 hw_if_index)
|
||||
static_always_inline u32
|
||||
vnet_dev_get_rx_queue_if_sw_if_index (vnet_dev_rx_queue_t *rxq)
|
||||
{
|
||||
return rxq->port->intf.sw_if_index;
|
||||
return rxq->port->interfaces->primary_interface.sw_if_index;
|
||||
}
|
||||
|
||||
static_always_inline u32
|
||||
vnet_dev_get_rx_queue_if_hw_if_index (vnet_dev_rx_queue_t *rxq)
|
||||
{
|
||||
return rxq->port->intf.hw_if_index;
|
||||
return rxq->port->interfaces->primary_interface.hw_if_index;
|
||||
}
|
||||
|
||||
static_always_inline u32
|
||||
vnet_dev_get_port_rx_node_index (vnet_dev_port_t *port)
|
||||
{
|
||||
return port->intf.rx_node_index;
|
||||
return port->interfaces->rx_node_index;
|
||||
}
|
||||
|
||||
static_always_inline vnet_dev_port_t *
|
||||
vnet_dev_get_port_from_sw_if_index (u32 sw_if_index)
|
||||
{
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
vnet_sw_interface_t *si;
|
||||
|
||||
si = vnet_get_sw_interface_or_null (vnm, sw_if_index);
|
||||
if (!si)
|
||||
return 0;
|
||||
|
||||
return vnet_dev_get_port_from_hw_if_index (si->hw_if_index);
|
||||
}
|
||||
|
||||
static_always_inline vnet_dev_t *
|
||||
@ -219,22 +245,49 @@ vnet_dev_tx_queue_unlock_if_needed (vnet_dev_tx_queue_t *txq)
|
||||
__atomic_store_n (&txq->lock, 0, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
static_always_inline vnet_dev_rx_queue_if_rt_data_t *
|
||||
vnet_dev_get_rx_queue_if_rt_data (vnet_dev_rx_queue_t *rxq)
|
||||
{
|
||||
return &rxq->if_rt_data;
|
||||
}
|
||||
|
||||
static_always_inline vnet_dev_rx_queue_if_rt_data_t *
|
||||
vnet_dev_get_rx_queue_sec_if_rt_data (vnet_dev_rx_queue_t *rxq,
|
||||
u32 sec_if_index)
|
||||
{
|
||||
return rxq->sec_if_rt_data[sec_if_index];
|
||||
}
|
||||
|
||||
static_always_inline vlib_buffer_template_t
|
||||
vnet_dev_get_rx_queue_if_buffer_template (vnet_dev_rx_queue_t *rxq)
|
||||
{
|
||||
return rxq->buffer_template;
|
||||
return rxq->if_rt_data.buffer_template;
|
||||
}
|
||||
|
||||
static_always_inline vlib_buffer_template_t
|
||||
vnet_dev_get_rx_queue_sec_if_buffer_template (vnet_dev_rx_queue_t *rxq,
|
||||
u32 sec_if_index)
|
||||
{
|
||||
return rxq->sec_if_rt_data[sec_if_index]->buffer_template;
|
||||
}
|
||||
|
||||
static_always_inline u16
|
||||
vnet_dev_get_rx_queue_if_next_index (vnet_dev_rx_queue_t *rxq)
|
||||
{
|
||||
return rxq->next_index;
|
||||
return rxq->if_rt_data.next_index;
|
||||
}
|
||||
|
||||
static_always_inline u16
|
||||
vnet_dev_get_rx_queue_sec_if_next_index (vnet_dev_rx_queue_t *rxq,
|
||||
u32 sec_if_index)
|
||||
{
|
||||
return rxq->sec_if_rt_data[sec_if_index]->next_index;
|
||||
}
|
||||
|
||||
static_always_inline u8
|
||||
vnet_dev_get_rx_queue_buffer_pool_index (vnet_dev_rx_queue_t *rxq)
|
||||
{
|
||||
return rxq->buffer_template.buffer_pool_index;
|
||||
return rxq->if_rt_data.buffer_template.buffer_pool_index;
|
||||
}
|
||||
|
||||
static_always_inline u32
|
||||
@ -269,8 +322,8 @@ static_always_inline vnet_dev_rx_queue_t *
|
||||
foreach_vnet_dev_rx_queue_runtime_helper (vlib_node_runtime_t *node,
|
||||
vnet_dev_rx_queue_t *rxq)
|
||||
{
|
||||
vnet_dev_port_t *port;
|
||||
vnet_dev_rx_queue_rt_req_t req;
|
||||
vnet_dev_port_interfaces_t *ifs;
|
||||
|
||||
if (rxq == 0)
|
||||
rxq = vnet_dev_get_rx_node_runtime (node)->first_rx_queue;
|
||||
@ -287,15 +340,34 @@ foreach_vnet_dev_rx_queue_runtime_helper (vlib_node_runtime_t *node,
|
||||
req.as_number =
|
||||
__atomic_exchange_n (&rxq->runtime_request.as_number, 0, __ATOMIC_ACQUIRE);
|
||||
|
||||
port = rxq->port;
|
||||
ifs = rxq->port->interfaces;
|
||||
if (req.update_next_index)
|
||||
rxq->next_index = port->intf.rx_next_index;
|
||||
{
|
||||
vnet_dev_port_interface_t **si =
|
||||
rxq->port->interfaces->secondary_interfaces;
|
||||
rxq->if_rt_data.next_index = ifs->primary_interface.rx_next_index;
|
||||
vec_foreach_pointer (rtd, rxq->sec_if_rt_data)
|
||||
if (rtd)
|
||||
rtd->next_index = si[rtd->sec_if_index]->next_index;
|
||||
}
|
||||
|
||||
if (req.update_feature_arc)
|
||||
{
|
||||
vlib_buffer_template_t *bt = &rxq->buffer_template;
|
||||
bt->current_config_index = port->intf.current_config_index;
|
||||
vnet_buffer (bt)->feature_arc_index = port->intf.feature_arc_index;
|
||||
vnet_dev_port_interface_t **si =
|
||||
rxq->port->interfaces->secondary_interfaces;
|
||||
vlib_buffer_template_t *bt = &rxq->if_rt_data.buffer_template;
|
||||
bt->current_config_index = ifs->primary_interface.current_config_index;
|
||||
vnet_buffer (bt)->feature_arc_index =
|
||||
ifs->primary_interface.feature_arc_index;
|
||||
vec_foreach_pointer (rtd, rxq->sec_if_rt_data)
|
||||
if (rtd)
|
||||
{
|
||||
vlib_buffer_template_t *bt = &rtd->buffer_template;
|
||||
bt->current_config_index =
|
||||
si[rtd->sec_if_index]->current_config_index;
|
||||
vnet_buffer (bt)->feature_arc_index =
|
||||
si[rtd->sec_if_index]->feature_arc_index;
|
||||
}
|
||||
}
|
||||
|
||||
if (req.suspend_on)
|
||||
|
@ -37,9 +37,12 @@
|
||||
_ (TIMEOUT, "timeout") \
|
||||
_ (UNKNOWN_DEVICE, "unknown device") \
|
||||
_ (UNKNOWN_INTERFACE, "unknown interface") \
|
||||
_ (NOT_PRIMARY_INTERFACE, "not primary interface") \
|
||||
_ (PRIMARY_INTERFACE_MISSING, "primary interface missing") \
|
||||
_ (UNSUPPORTED_CONFIG, "unsupported config") \
|
||||
_ (UNSUPPORTED_DEVICE, "unsupported device") \
|
||||
_ (UNSUPPORTED_DEVICE_VER, "unsupported device version") \
|
||||
_ (UNSUPPORTED_INTERFACE, "unsupported interface") \
|
||||
_ (ALREADY_DONE, "already done") \
|
||||
_ (NO_SUCH_INTERFACE, "no such interface") \
|
||||
_ (INIT_FAILED, "init failed")
|
||||
|
@ -44,9 +44,15 @@ u8 *
|
||||
format_vnet_dev_interface_name (u8 *s, va_list *args)
|
||||
{
|
||||
u32 i = va_arg (*args, u32);
|
||||
vnet_dev_port_t *port = vnet_dev_get_port_from_dev_instance (i);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (i);
|
||||
vnet_dev_port_interface_t *si;
|
||||
vnet_dev_port_t *p = di->port;
|
||||
|
||||
return format (s, "%s", port->intf.name);
|
||||
if (di->is_primary_if)
|
||||
return format (s, "%s", p->interfaces->primary_interface.name);
|
||||
|
||||
si = vnet_dev_port_get_sec_if_by_index (p, di->sec_if_index);
|
||||
return format (s, "%s", si->name);
|
||||
}
|
||||
|
||||
u8 *
|
||||
@ -138,12 +144,22 @@ format_vnet_dev_port_info (u8 *s, va_list *args)
|
||||
format_vnet_dev_args, port->args);
|
||||
|
||||
s = format (s, "\n%UInterface ", format_white_space, indent);
|
||||
if (port->interface_created)
|
||||
if (port->interfaces)
|
||||
{
|
||||
s = format (s, "assigned, interface name is '%U', RX node is '%U'",
|
||||
format_vnet_sw_if_index_name, vnm, port->intf.sw_if_index,
|
||||
format_vlib_node_name, vm,
|
||||
vnet_dev_get_port_rx_node_index (port));
|
||||
s = format (
|
||||
s, "assigned, primary interface name is '%U', RX node is '%U'",
|
||||
format_vnet_sw_if_index_name, vnm,
|
||||
port->interfaces->primary_interface.sw_if_index, format_vlib_node_name,
|
||||
vm, vnet_dev_get_port_rx_node_index (port));
|
||||
pool_foreach_pointer (sif, port->interfaces->secondary_interfaces)
|
||||
{
|
||||
s = format (s, "\n%USecondary interface '%U'", format_white_space,
|
||||
indent, format_vnet_sw_if_index_name, vnm,
|
||||
sif->sw_if_index);
|
||||
if (sif->args)
|
||||
s = format (s, "\n%U args '%U", format_white_space, indent,
|
||||
format_vnet_dev_args, sif->args);
|
||||
}
|
||||
}
|
||||
else
|
||||
s = format (s, "not assigned");
|
||||
|
@ -19,7 +19,8 @@ vnet_dev_port_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hw,
|
||||
u32 frame_size)
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hw->dev_instance);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (hw->dev_instance);
|
||||
vnet_dev_port_t *p;
|
||||
vnet_dev_rv_t rv;
|
||||
|
||||
vnet_dev_port_cfg_change_req_t req = {
|
||||
@ -27,6 +28,11 @@ vnet_dev_port_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hw,
|
||||
.max_rx_frame_size = frame_size,
|
||||
};
|
||||
|
||||
p = di->port;
|
||||
|
||||
if (!di->is_primary_if)
|
||||
return vnet_dev_port_err (vm, p, VNET_DEV_ERR_NOT_PRIMARY_INTERFACE, "");
|
||||
|
||||
log_debug (p->dev, "size %u", frame_size);
|
||||
|
||||
rv = vnet_dev_port_cfg_change_req_validate (vm, p, &req);
|
||||
@ -49,13 +55,17 @@ vnet_dev_port_eth_flag_change (vnet_main_t *vnm, vnet_hw_interface_t *hw,
|
||||
u32 flags)
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hw->dev_instance);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (hw->dev_instance);
|
||||
vnet_dev_port_t *p = di->port;
|
||||
vnet_dev_rv_t rv;
|
||||
|
||||
vnet_dev_port_cfg_change_req_t req = {
|
||||
.type = VNET_DEV_PORT_CFG_PROMISC_MODE,
|
||||
};
|
||||
|
||||
if (!di->is_primary_if)
|
||||
return ~0;
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
case ETHERNET_INTERFACE_FLAG_DEFAULT_L3:
|
||||
@ -87,13 +97,17 @@ vnet_dev_port_mac_change (vnet_hw_interface_t *hi, const u8 *old,
|
||||
const u8 *new)
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hi->dev_instance);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (hi->dev_instance);
|
||||
vnet_dev_port_t *p = di->port;
|
||||
vnet_dev_rv_t rv;
|
||||
|
||||
vnet_dev_port_cfg_change_req_t req = {
|
||||
.type = VNET_DEV_PORT_CFG_CHANGE_PRIMARY_HW_ADDR,
|
||||
};
|
||||
|
||||
if (!di->is_primary_if)
|
||||
return vnet_dev_port_err (vm, p, VNET_DEV_ERR_NOT_PRIMARY_INTERFACE, "");
|
||||
|
||||
vnet_dev_set_hw_addr_eth_mac (&req.addr, new);
|
||||
|
||||
log_debug (p->dev, "new mac %U", format_vnet_dev_hw_addr, &req.addr);
|
||||
@ -116,7 +130,8 @@ vnet_dev_add_del_mac_address (vnet_hw_interface_t *hi, const u8 *address,
|
||||
u8 is_add)
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hi->dev_instance);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (hi->dev_instance);
|
||||
vnet_dev_port_t *p = di->port;
|
||||
vnet_dev_rv_t rv;
|
||||
|
||||
vnet_dev_port_cfg_change_req_t req = {
|
||||
@ -124,6 +139,9 @@ vnet_dev_add_del_mac_address (vnet_hw_interface_t *hi, const u8 *address,
|
||||
VNET_DEV_PORT_CFG_REMOVE_SECONDARY_HW_ADDR,
|
||||
};
|
||||
|
||||
if (!di->is_primary_if)
|
||||
return vnet_dev_port_err (vm, p, VNET_DEV_ERR_NOT_PRIMARY_INTERFACE, "");
|
||||
|
||||
vnet_dev_set_hw_addr_eth_mac (&req.addr, address);
|
||||
|
||||
log_debug (p->dev, "received (addr %U is_add %u", format_vnet_dev_hw_addr,
|
||||
@ -147,10 +165,19 @@ 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);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (dev_instance);
|
||||
vnet_dev_port_t *p;
|
||||
vnet_dev_port_cfg_change_req_t req;
|
||||
vnet_dev_rv_t rv;
|
||||
|
||||
if (!di)
|
||||
return VNET_FLOW_ERROR_NO_SUCH_INTERFACE;
|
||||
|
||||
if (di->is_primary_if)
|
||||
return VNET_FLOW_ERROR_NOT_SUPPORTED;
|
||||
|
||||
p = di->port;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case VNET_FLOW_DEV_OP_ADD_FLOW:
|
||||
@ -201,10 +228,12 @@ vnet_dev_interface_set_rss_queues (vnet_main_t *vnm, vnet_hw_interface_t *hi,
|
||||
void
|
||||
vnet_dev_clear_hw_interface_counters (u32 instance)
|
||||
{
|
||||
vnet_dev_port_t *port = vnet_dev_get_port_from_dev_instance (instance);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (instance);
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
|
||||
vnet_dev_process_call_port_op_no_rv (vm, port, vnet_dev_port_clear_counters);
|
||||
if (di->is_primary_if)
|
||||
vnet_dev_process_call_port_op_no_rv (vm, di->port,
|
||||
vnet_dev_port_clear_counters);
|
||||
}
|
||||
|
||||
void
|
||||
@ -213,44 +242,49 @@ vnet_dev_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
|
||||
{
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
vnet_dev_port_t *port =
|
||||
vnet_dev_get_port_from_dev_instance (hw->dev_instance);
|
||||
vnet_dev_instance_t *di = vnet_dev_get_dev_instance (hw->dev_instance);
|
||||
vnet_dev_port_interface_t *intf;
|
||||
int runtime_update = 0;
|
||||
|
||||
if (di->is_primary_if)
|
||||
intf = vnet_dev_port_get_primary_if (di->port);
|
||||
else
|
||||
intf = vnet_dev_port_get_sec_if_by_index (di->port, di->sec_if_index);
|
||||
|
||||
if (node_index == ~0)
|
||||
{
|
||||
port->intf.redirect_to_node_next_index = 0;
|
||||
if (port->intf.feature_arc == 0)
|
||||
intf->redirect_to_node_next_index = 0;
|
||||
if (intf->feature_arc == 0)
|
||||
{
|
||||
port->intf.rx_next_index =
|
||||
vnet_dev_default_next_index_by_port_type[port->attr.type];
|
||||
intf->rx_next_index =
|
||||
vnet_dev_default_next_index_by_port_type[di->port->attr.type];
|
||||
runtime_update = 1;
|
||||
}
|
||||
port->intf.redirect_to_node = 0;
|
||||
intf->redirect_to_node = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 next_index = vlib_node_add_next (vlib_get_main (),
|
||||
port_rx_eth_node.index, node_index);
|
||||
port->intf.redirect_to_node_next_index = next_index;
|
||||
if (port->intf.feature_arc == 0)
|
||||
intf->redirect_to_node_next_index = next_index;
|
||||
if (intf->feature_arc == 0)
|
||||
{
|
||||
port->intf.rx_next_index = next_index;
|
||||
intf->rx_next_index = next_index;
|
||||
runtime_update = 1;
|
||||
}
|
||||
port->intf.redirect_to_node = 1;
|
||||
intf->redirect_to_node = 1;
|
||||
}
|
||||
port->intf.rx_next_index =
|
||||
intf->rx_next_index =
|
||||
node_index == ~0 ?
|
||||
vnet_dev_default_next_index_by_port_type[port->attr.type] :
|
||||
node_index;
|
||||
vnet_dev_default_next_index_by_port_type[di->port->attr.type] :
|
||||
node_index;
|
||||
|
||||
if (runtime_update)
|
||||
{
|
||||
foreach_vnet_dev_port_rx_queue (rxq, port)
|
||||
foreach_vnet_dev_port_rx_queue (rxq, di->port)
|
||||
vnet_dev_rx_queue_rt_request (
|
||||
vm, rxq, (vnet_dev_rx_queue_rt_req_t){ .update_next_index = 1 });
|
||||
log_debug (port->dev, "runtime update requested due to chgange in "
|
||||
"reditect-to-next configuration");
|
||||
log_debug (di->port->dev, "runtime update requested due to chgange in "
|
||||
"reditect-to-next configuration");
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,6 @@ vnet_dev_rx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port,
|
||||
vnet_dev_t *dev = port->dev;
|
||||
vnet_dev_rv_t rv = VNET_DEV_OK;
|
||||
u16 n_threads = vlib_get_n_threads ();
|
||||
u8 buffer_pool_index;
|
||||
|
||||
vnet_dev_port_validate (vm, port);
|
||||
|
||||
@ -65,15 +64,6 @@ vnet_dev_rx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port,
|
||||
dm->next_rx_queue_thread = 1;
|
||||
}
|
||||
|
||||
buffer_pool_index =
|
||||
vlib_buffer_pool_get_default_for_numa (vm, dev->numa_node);
|
||||
vlib_buffer_pool_t *bp = vlib_get_buffer_pool (vm, buffer_pool_index);
|
||||
|
||||
rxq->buffer_template = bp->buffer_template;
|
||||
vnet_buffer (&rxq->buffer_template)->sw_if_index[VLIB_TX] = ~0;
|
||||
|
||||
rxq->next_index = vnet_dev_default_next_index_by_port_type[port->attr.type];
|
||||
|
||||
if (port->rx_queue_ops.alloc)
|
||||
rv = port->rx_queue_ops.alloc (vm, rxq);
|
||||
|
||||
|
Reference in New Issue
Block a user