diff options
Diffstat (limited to 'src/vnet/devices/virtio/node.c')
-rw-r--r-- | src/vnet/devices/virtio/node.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index a022ee5eacc..8c837575cf8 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -19,7 +19,11 @@ #include <sys/stat.h> #include <fcntl.h> #include <net/if.h> +#ifdef __linux__ #include <linux/if_tun.h> +#elif __FreeBSD__ +#include <net/if_tun.h> +#endif /* __linux */ #include <sys/ioctl.h> #include <sys/eventfd.h> @@ -202,6 +206,19 @@ virtio_get_len (vnet_virtio_vring_t *vring, const int packed, const int hdr_sz, return vring->used->ring[last & mask].len - hdr_sz; } +#define virtio_packed_check_n_left(vring, last) \ + do \ + { \ + vnet_virtio_vring_packed_desc_t *d = &vring->packed_desc[last]; \ + u16 flags = d->flags; \ + if ((flags & VRING_DESC_F_AVAIL) != (vring->used_wrap_counter << 7) || \ + (flags & VRING_DESC_F_USED) != (vring->used_wrap_counter << 15)) \ + { \ + n_left = 0; \ + } \ + } \ + while (0) + #define increment_last(last, packed, vring) \ do \ { \ @@ -214,6 +231,29 @@ virtio_get_len (vnet_virtio_vring_t *vring, const int packed, const int hdr_sz, } \ while (0) +static_always_inline void +virtio_device_input_ethernet (vlib_main_t *vm, vlib_node_runtime_t *node, + const u32 next_index, const u32 sw_if_index, + const u32 hw_if_index) +{ + vlib_next_frame_t *nf; + vlib_frame_t *f; + ethernet_input_frame_t *ef; + + if (PREDICT_FALSE (VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT != next_index)) + return; + + nf = vlib_node_runtime_get_next_frame ( + vm, node, VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT); + f = vlib_get_frame (vm, nf->frame); + f->flags = ETH_INPUT_FRAME_F_SINGLE_SW_IF_IDX; + + ef = vlib_frame_scalar_args (f); + ef->sw_if_index = sw_if_index; + ef->hw_if_index = hw_if_index; + vlib_frame_no_append (f); +} + static_always_inline uword virtio_device_input_gso_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, virtio_if_t *vif, @@ -234,6 +274,11 @@ virtio_device_input_gso_inline (vlib_main_t *vm, vlib_node_runtime_t *node, u16 n_left = virtio_n_left_to_process (vring, packed); vlib_buffer_t bt = {}; + if (packed) + { + virtio_packed_check_n_left (vring, last); + } + if (n_left == 0) return 0; @@ -248,7 +293,7 @@ virtio_device_input_gso_inline (vlib_main_t *vm, vlib_node_runtime_t *node, next_index = vif->per_interface_next_index; /* only for l2, redirect if feature path enabled */ - vnet_feature_start_device_input_x1 (vif->sw_if_index, &next_index, &bt); + vnet_feature_start_device_input (vif->sw_if_index, &next_index, &bt); } while (n_left) @@ -256,7 +301,7 @@ virtio_device_input_gso_inline (vlib_main_t *vm, vlib_node_runtime_t *node, u32 n_left_to_next; u32 next0 = next_index; - vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); + vlib_get_new_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left && n_left_to_next) { @@ -386,6 +431,8 @@ virtio_device_input_gso_inline (vlib_main_t *vm, vlib_node_runtime_t *node, n_rx_packets++; n_rx_bytes += len; } + virtio_device_input_ethernet (vm, node, next_index, vif->sw_if_index, + vif->hw_if_index); vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vring->last_used_idx = last; @@ -477,7 +524,6 @@ VLIB_NODE_FN (virtio_input_node) (vlib_main_t * vm, return n_rx; } -/* *INDENT-OFF* */ VLIB_REGISTER_NODE (virtio_input_node) = { .name = "virtio-input", .sibling_of = "device-input", @@ -488,7 +534,6 @@ VLIB_REGISTER_NODE (virtio_input_node) = { .n_errors = VIRTIO_INPUT_N_ERROR, .error_strings = virtio_input_error_strings, }; -/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON |