diff options
Diffstat (limited to 'src/vnet/devices/virtio')
-rw-r--r-- | src/vnet/devices/virtio/device.c | 4 | ||||
-rw-r--r-- | src/vnet/devices/virtio/format.c | 4 | ||||
-rw-r--r-- | src/vnet/devices/virtio/node.c | 59 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio.c | 18 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio.h | 12 |
5 files changed, 72 insertions, 25 deletions
diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c index 1ee94806842..9d04474ada0 100644 --- a/src/vnet/devices/virtio/device.c +++ b/src/vnet/devices/virtio/device.c @@ -21,6 +21,7 @@ #include <vlib/vlib.h> #include <vlib/unix/unix.h> +#include <vnet/vnet.h> #include <vnet/ethernet/ethernet.h> #include <vnet/gso/gso.h> #include <vnet/ip/ip4_packet.h> @@ -343,7 +344,7 @@ add_buffer_to_slot (vlib_main_t * vm, virtio_if_t * vif, id->len = b->current_length; } } - else /* VIRTIO_IF_TYPE_TAP */ + else /* VIRTIO_IF_TYPE_[TAP | TUN] */ { d->addr = pointer_to_uword (id); /* first buffer in chain */ @@ -612,6 +613,7 @@ VNET_DEVICE_CLASS (virtio_device_class) = { .subif_add_del_function = virtio_subif_add_del_function, .rx_mode_change_function = virtio_interface_rx_mode_change, }; + /* *INDENT-ON* */ /* diff --git a/src/vnet/devices/virtio/format.c b/src/vnet/devices/virtio/format.c index 729635de35b..fe46d92cba9 100644 --- a/src/vnet/devices/virtio/format.c +++ b/src/vnet/devices/virtio/format.c @@ -36,6 +36,8 @@ format_virtio_device_name (u8 * s, va_list * args) s = format (s, "virtio-%x/%x/%x/%x", vif->pci_addr.domain, vif->pci_addr.bus, vif->pci_addr.slot, vif->pci_addr.function); + else if (vif->type == VIRTIO_IF_TYPE_TUN) + s = format (s, "tun%u", vif->id); else s = format (s, "virtio-%lu", vif->dev_instance); @@ -49,6 +51,8 @@ format_virtio_log_name (u8 * s, va_list * args) if (vif->type == VIRTIO_IF_TYPE_TAP) s = format (s, "tap%u", vif->id); + else if (vif->type == VIRTIO_IF_TYPE_TUN) + s = format (s, "tun%u", vif->id); else if (vif->type == VIRTIO_IF_TYPE_PCI) s = format (s, "%U", format_vlib_pci_addr, &vif->pci_addr); else diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index 3bb23662c50..8d7c9360b00 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -143,27 +143,44 @@ more: static_always_inline void virtio_needs_csum (vlib_buffer_t * b0, struct virtio_net_hdr_v1 *hdr, - u8 * l4_proto, u8 * l4_hdr_sz) + u8 * l4_proto, u8 * l4_hdr_sz, virtio_if_type_t type) { if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { - ethernet_header_t *eh = - (ethernet_header_t *) vlib_buffer_get_current (b0); - u16 ethertype = clib_net_to_host_u16 (eh->type); - u16 l2hdr_sz = sizeof (ethernet_header_t); - - if (ethernet_frame_is_tagged (ethertype)) + u16 ethertype = 0, l2hdr_sz = 0; + if (type != VIRTIO_IF_TYPE_TUN) { - ethernet_vlan_header_t *vlan = (ethernet_vlan_header_t *) (eh + 1); + ethernet_header_t *eh = + (ethernet_header_t *) vlib_buffer_get_current (b0); + ethertype = clib_net_to_host_u16 (eh->type); + l2hdr_sz = sizeof (ethernet_header_t); - ethertype = clib_net_to_host_u16 (vlan->type); - l2hdr_sz += sizeof (*vlan); - if (ethertype == ETHERNET_TYPE_VLAN) + if (ethernet_frame_is_tagged (ethertype)) { - vlan++; + ethernet_vlan_header_t *vlan = + (ethernet_vlan_header_t *) (eh + 1); + ethertype = clib_net_to_host_u16 (vlan->type); l2hdr_sz += sizeof (*vlan); + if (ethertype == ETHERNET_TYPE_VLAN) + { + vlan++; + ethertype = clib_net_to_host_u16 (vlan->type); + l2hdr_sz += sizeof (*vlan); + } + } + } + else + { + switch (b0->data[0] & 0xf0) + { + case 0x40: + ethertype = ETHERNET_TYPE_IP4; + break; + case 0x60: + ethertype = ETHERNET_TYPE_IP6; + break; } } @@ -285,7 +302,7 @@ virtio_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, b0->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID; if (checksum_offload_enabled) - virtio_needs_csum (b0, hdr, &l4_proto, &l4_hdr_sz); + virtio_needs_csum (b0, hdr, &l4_proto, &l4_hdr_sz, vif->type); if (gso_enabled) fill_gso_buffer_flags (b0, hdr, l4_proto, l4_hdr_sz); @@ -321,6 +338,22 @@ virtio_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, n_left--; } } + if (PREDICT_FALSE (vif->type == VIRTIO_IF_TYPE_TUN)) + { + switch (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 (vif->per_interface_next_index != ~0)) next0 = vif->per_interface_next_index; diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c index d78c9114e5c..00a588af346 100644 --- a/src/vnet/devices/virtio/virtio.c +++ b/src/vnet/devices/virtio/virtio.c @@ -294,7 +294,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) vlib_cli_output (vm, " PCI Address: %U", format_vlib_pci_addr, &vif->pci_addr); } - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { u8 *str = 0; if (vif->host_if_name) @@ -304,8 +304,9 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) if (vif->host_mtu_size) vlib_cli_output (vm, " host-mtu-size \"%d\"", vif->host_mtu_size); - vlib_cli_output (vm, " host-mac-addr: %U", - format_ethernet_address, vif->host_mac_addr); + if (type == VIRTIO_IF_TYPE_TAP) + vlib_cli_output (vm, " host-mac-addr: %U", + format_ethernet_address, vif->host_mac_addr); vec_foreach_index (i, vif->vhost_fds) str = format (str, " %d", vif->vhost_fds[i]); @@ -315,8 +316,9 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) } vlib_cli_output (vm, " gso-enabled %d", vif->gso_enabled); vlib_cli_output (vm, " csum-enabled %d", vif->csum_offload_enabled); - vlib_cli_output (vm, " Mac Address: %U", format_ethernet_address, - vif->mac_addr); + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_PCI)) + vlib_cli_output (vm, " Mac Address: %U", format_ethernet_address, + vif->mac_addr); vlib_cli_output (vm, " Device instance: %u", vif->dev_instance); vlib_cli_output (vm, " flags 0x%x", vif->flags); flag_entry = (struct feat_struct *) &flags_array; @@ -366,7 +368,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d", vring->avail->flags, vring->avail->idx, vring->used->flags, vring->used->idx); - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd, vring->call_fd); @@ -401,7 +403,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d", vring->avail->flags, vring->avail->idx, vring->used->flags, vring->used->idx); - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd, vring->call_fd); @@ -437,7 +439,7 @@ virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr, u32 type) " avail.flags 0x%x avail.idx %d used.flags 0x%x used.idx %d", vring->avail->flags, vring->avail->idx, vring->used->flags, vring->used->idx); - if (type == VIRTIO_IF_TYPE_TAP) + if (type & (VIRTIO_IF_TYPE_TAP | VIRTIO_IF_TYPE_TUN)) { vlib_cli_output (vm, " kickfd %d, callfd %d", vring->kick_fd, vring->call_fd); diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h index e28922bf654..3e8f9416483 100644 --- a/src/vnet/devices/virtio/virtio.h +++ b/src/vnet/devices/virtio/virtio.h @@ -80,11 +80,17 @@ typedef enum #define TX_QUEUE_ACCESS(X) (X/2) #define RX_QUEUE_ACCESS(X) (X/2) +#define foreach_virtio_if_types \ + _ (TAP, 1) \ + _ (TUN, 2) \ + _ (PCI, 3) + typedef enum { - VIRTIO_IF_TYPE_TAP = 1, - VIRTIO_IF_TYPE_PCI, - VIRTIO_IF_N_TYPES, +#define _(a, b) VIRTIO_IF_TYPE_##a = (1 << b), + foreach_virtio_if_types +#undef _ + VIRTIO_IF_N_TYPES = (1 << 4), } virtio_if_type_t; |