af_packet_main_t af_packet_main;
+VNET_HW_INTERFACE_CLASS (af_packet_ip_device_hw_interface_class, static) = {
+ .name = "af-packet-ip-device",
+ .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
+};
+
#define AF_PACKET_DEFAULT_TX_FRAMES_PER_BLOCK 1024
#define AF_PACKET_DEFAULT_TX_FRAME_SIZE (2048 * 5)
#define AF_PACKET_TX_BLOCK_NR 1
apif->per_interface_next_index = ~0;
apif->next_tx_frame = 0;
apif->next_rx_frame = 0;
+ apif->mode = arg->mode;
ret = af_packet_read_mtu (apif);
if (ret != 0)
if (tm->n_vlib_mains > 1)
clib_spinlock_init (&apif->lockp);
- /*use configured or generate random MAC address */
- if (arg->hw_addr)
- clib_memcpy (hw_addr, arg->hw_addr, 6);
- else
+ if (apif->mode == AF_PACKET_IF_MODE_ETHERNET)
{
- f64 now = vlib_time_now (vm);
- u32 rnd;
- rnd = (u32) (now * 1e6);
- rnd = random_u32 (&rnd);
-
- clib_memcpy (hw_addr + 2, &rnd, sizeof (rnd));
- hw_addr[0] = 2;
- hw_addr[1] = 0xfe;
- }
+ /*use configured or generate random MAC address */
+ if (arg->hw_addr)
+ clib_memcpy (hw_addr, arg->hw_addr, 6);
+ else
+ {
+ f64 now = vlib_time_now (vm);
+ u32 rnd;
+ rnd = (u32) (now * 1e6);
+ rnd = random_u32 (&rnd);
+
+ clib_memcpy (hw_addr + 2, &rnd, sizeof (rnd));
+ hw_addr[0] = 2;
+ hw_addr[1] = 0xfe;
+ }
- error = ethernet_register_interface (vnm, af_packet_device_class.index,
- if_index, hw_addr, &apif->hw_if_index,
- af_packet_eth_flag_change);
+ error = ethernet_register_interface (
+ vnm, af_packet_device_class.index, if_index, hw_addr,
+ &apif->hw_if_index, af_packet_eth_flag_change);
- if (error)
+ if (error)
+ {
+ clib_memset (apif, 0, sizeof (*apif));
+ pool_put (apm->interfaces, apif);
+ vlib_log_err (apm->log_class, "Unable to register interface: %U",
+ format_clib_error, error);
+ clib_error_free (error);
+ ret = VNET_API_ERROR_SYSCALL_ERROR_1;
+ goto error;
+ }
+ }
+ else
{
- clib_memset (apif, 0, sizeof (*apif));
- pool_put (apm->interfaces, apif);
- vlib_log_err (apm->log_class, "Unable to register interface: %U",
- format_clib_error, error);
- clib_error_free (error);
- ret = VNET_API_ERROR_SYSCALL_ERROR_1;
- goto error;
+ apif->hw_if_index = vnet_register_interface (
+ vnm, af_packet_device_class.index, if_index,
+ af_packet_ip_device_hw_interface_class.index, if_index);
}
-
sw = vnet_get_hw_sw_interface (vnm, apif->hw_if_index);
hw = vnet_get_hw_interface (vnm, apif->hw_if_index);
apif->sw_if_index = sw->sw_if_index;
mhash_unset (&apm->if_index_by_host_if_name, host_if_name, &if_index);
- ethernet_delete_interface (vnm, apif->hw_if_index);
+ if (apif->mode == AF_PACKET_IF_MODE_ETHERNET)
+ ethernet_delete_interface (vnm, apif->hw_if_index);
+ else
+ vnet_delete_hw_interface (vnm, apif->hw_if_index);
pool_put (apm->interfaces, apif);
clib_memset (arg, 0, sizeof (*arg));
+ // Default mode
+ arg->mode = AF_PACKET_IF_MODE_ETHERNET;
+
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
else if (unformat (line_input, "tx-per-block %u",
&arg->tx_frames_per_block))
;
+ else if (unformat (line_input, "mode ip"))
+ arg->mode = AF_PACKET_IF_MODE_IP;
else if (unformat (line_input, "hw-addr %U", unformat_ethernet_address,
hwaddr))
arg->hw_addr = hwaddr;
?*/
VLIB_CLI_COMMAND (af_packet_create_command, static) = {
.path = "create host-interface",
- .short_help = "create host-interface name <ifname> [hw-addr <mac-addr>]",
+ .short_help =
+ "create host-interface name <ifname> [hw-addr <mac-addr>] [mode ip]",
.function = af_packet_create_command_fn,
};
{
af_packet_main_t *apm = &af_packet_main;
struct tpacket2_hdr *tph;
- u32 next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
+ u32 next_index;
u32 block = 0;
u32 rx_frame;
u32 n_free_bufs;
u32 thread_index = vm->thread_index;
u32 n_buffer_bytes = vlib_buffer_get_default_data_size (vm);
u32 min_bufs = apif->rx_req->tp_frame_size / n_buffer_bytes;
+ vlib_buffer_t bt;
+
+ if (apif->mode == AF_PACKET_IF_MODE_IP)
+ {
+ next_index = VNET_DEVICE_INPUT_NEXT_IP4_INPUT;
+ }
+ else
+ {
+ next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
+ if (PREDICT_FALSE (apif->per_interface_next_index != ~0))
+ next_index = apif->per_interface_next_index;
+
+ /* redirect if feature path enabled */
+ vnet_feature_start_device_input_x1 (apif->sw_if_index, &next_index, &bt);
+ }
n_free_bufs = vec_len (apm->rx_buffers[thread_index]);
if (PREDICT_FALSE (n_free_bufs < VLIB_FRAME_SIZE))
}
else
{
- next0 = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
-
- if (PREDICT_FALSE (apif->per_interface_next_index != ~0))
- next0 = apif->per_interface_next_index;
-
- /* redirect if feature path enabled */
- vnet_feature_start_device_input_x1 (apif->sw_if_index, &next0,
- first_b0);
+ if (PREDICT_FALSE (apif->mode == AF_PACKET_IF_MODE_IP))
+ {
+ switch (first_b0->data[0] & 0xf0)
+ {
+ case 0x40:
+ next0 = VNET_DEVICE_INPUT_NEXT_IP4_INPUT;
+ break;
+ case 0x60:
+ next0 = VNET_DEVICE_INPUT_NEXT_IP6_INPUT;
+ break;
+ default:
+ next0 = VNET_DEVICE_INPUT_NEXT_DROP;
+ break;
+ }
+ if (PREDICT_FALSE (apif->per_interface_next_index != ~0))
+ next0 = apif->per_interface_next_index;
+ }
+ else
+ {
+ /* copy feature arc data from template */
+ first_b0->current_config_index = bt.current_config_index;
+ vnet_buffer (first_b0)->feature_arc_index =
+ vnet_buffer (&bt)->feature_arc_index;
+ }
}
/* trace */