aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/virtio/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/devices/virtio/node.c')
-rw-r--r--src/vnet/devices/virtio/node.c53
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