VPP-311 Coding standards cleanup for vnet/vnet/*.[ch]
Change-Id: I08ed983f594072bc8c72202e77205a7789eea599 Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
@@ -74,6 +74,12 @@
|
||||
(defun fix-reply-macro2 () (interactive)
|
||||
(fix-initializer "REPLY_MACRO2 *("))
|
||||
|
||||
(defun fix-vnet-device-class () (interactive)
|
||||
(fix-initializer "VNET_DEVICE_CLASS *("))
|
||||
|
||||
(defun fix-vnet-hw-interface-class () (interactive)
|
||||
(fix-initializer "VNET_HW_INTERFACE_CLASS *("))
|
||||
|
||||
;; Driver routine which runs the set of functions
|
||||
;; defined above, as well as the bottom boilerplate function
|
||||
|
||||
@@ -90,6 +96,8 @@
|
||||
(fix-vlib-cli-command)
|
||||
(fix-vlib-register-node)
|
||||
(fix-reply-macro2)
|
||||
(fix-vnet-device-class)
|
||||
(fix-vnet-hw-interface-class)
|
||||
(insert-style-boilerplate))
|
||||
|
||||
|
||||
|
||||
+11
-2
@@ -88,11 +88,20 @@ _(INCORRECT_ADJACENCY_TYPE, -94, "Invalid adjacency type for this operation") \
|
||||
_(EXCEEDED_NUMBER_OF_RANGES_CAPACITY, -95, "Operation would exceed configured capacity of ranges") \
|
||||
_(EXCEEDED_NUMBER_OF_PORTS_CAPACITY, -96, "Operation would exceed capacity of number of ports")
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(a,b,c) VNET_API_ERROR_##a = (b),
|
||||
foreach_vnet_api_error
|
||||
foreach_vnet_api_error
|
||||
#undef _
|
||||
VNET_API_N_ERROR,
|
||||
} vnet_api_error_t;
|
||||
|
||||
#endif /* included_vnet_api_errno_h */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+127
-88
File diff suppressed because it is too large
Load Diff
+106
-86
File diff suppressed because it is too large
Load Diff
+36
-27
@@ -43,7 +43,8 @@
|
||||
#include <vlib/vlib.h>
|
||||
#include <vppinfra/heap.h>
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/* Features are prioritized by index. Smaller indices get
|
||||
performed first. */
|
||||
u32 feature_index;
|
||||
@@ -55,19 +56,22 @@ typedef struct {
|
||||
u32 next_index;
|
||||
|
||||
/* Opaque per feature configuration data. */
|
||||
u32 * feature_config;
|
||||
u32 *feature_config;
|
||||
} vnet_config_feature_t;
|
||||
|
||||
always_inline void
|
||||
vnet_config_feature_free (vnet_config_feature_t * f)
|
||||
{ vec_free (f->feature_config); }
|
||||
{
|
||||
vec_free (f->feature_config);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/* Sorted vector of features for this configuration. */
|
||||
vnet_config_feature_t * features;
|
||||
vnet_config_feature_t *features;
|
||||
|
||||
/* Config string as vector for hashing. */
|
||||
u32 * config_string_vector;
|
||||
u32 *config_string_vector;
|
||||
|
||||
/* Config string including all next indices and feature data as a vector. */
|
||||
u32 config_string_heap_index, config_string_heap_handle;
|
||||
@@ -79,36 +83,36 @@ typedef struct {
|
||||
u32 reference_count;
|
||||
} vnet_config_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/* Pool of configs. Index 0 is always null config and is never deleted. */
|
||||
vnet_config_t * config_pool;
|
||||
vnet_config_t *config_pool;
|
||||
|
||||
/* Hash table mapping vector config string to config pool index. */
|
||||
uword * config_string_hash;
|
||||
uword *config_string_hash;
|
||||
|
||||
/* Global heap of configuration data. */
|
||||
u32 * config_string_heap;
|
||||
/* Global heap of configuration data. */
|
||||
u32 *config_string_heap;
|
||||
|
||||
/* Node index which starts/ends feature processing. */
|
||||
u32 * start_node_indices, end_node_index;
|
||||
u32 *start_node_indices, end_node_index;
|
||||
|
||||
/* Interior feature processing nodes (not including start and end nodes). */
|
||||
u32 * node_index_by_feature_index;
|
||||
u32 *node_index_by_feature_index;
|
||||
|
||||
/* vnet_config pool index by user index */
|
||||
u32 * config_pool_index_by_user_index;
|
||||
u32 *config_pool_index_by_user_index;
|
||||
|
||||
/* Temporary vector for holding config strings. Used to avoid continually
|
||||
allocating vectors. */
|
||||
u32 * config_string_temp;
|
||||
u32 *config_string_temp;
|
||||
} vnet_config_main_t;
|
||||
|
||||
always_inline void
|
||||
vnet_config_free (vnet_config_main_t * cm, vnet_config_t * c)
|
||||
{
|
||||
vnet_config_feature_t * f;
|
||||
vec_foreach (f, c->features)
|
||||
vnet_config_feature_free (f);
|
||||
vnet_config_feature_t *f;
|
||||
vec_foreach (f, c->features) vnet_config_feature_free (f);
|
||||
vec_free (c->features);
|
||||
heap_dealloc (cm->config_string_heap, c->config_string_heap_handle);
|
||||
vec_free (c->config_string_vector);
|
||||
@@ -116,11 +120,9 @@ vnet_config_free (vnet_config_main_t * cm, vnet_config_t * c)
|
||||
|
||||
always_inline void *
|
||||
vnet_get_config_data (vnet_config_main_t * cm,
|
||||
u32 * config_index,
|
||||
u32 * next_index,
|
||||
u32 n_data_bytes)
|
||||
u32 * config_index, u32 * next_index, u32 n_data_bytes)
|
||||
{
|
||||
u32 i, n, * d;
|
||||
u32 i, n, *d;
|
||||
|
||||
i = *config_index;
|
||||
|
||||
@@ -140,24 +142,31 @@ vnet_get_config_data (vnet_config_main_t * cm,
|
||||
|
||||
void vnet_config_init (vlib_main_t * vm,
|
||||
vnet_config_main_t * cm,
|
||||
char * start_node_names[],
|
||||
char *start_node_names[],
|
||||
int n_start_node_names,
|
||||
char * feature_node_names[],
|
||||
int n_feature_node_names);
|
||||
char *feature_node_names[], int n_feature_node_names);
|
||||
|
||||
/* Calls to add/delete features from configurations. */
|
||||
u32 vnet_config_add_feature (vlib_main_t * vm,
|
||||
vnet_config_main_t * cm,
|
||||
u32 config_id,
|
||||
u32 feature_index,
|
||||
void * feature_config,
|
||||
void *feature_config,
|
||||
u32 n_feature_config_bytes);
|
||||
|
||||
u32 vnet_config_del_feature (vlib_main_t * vm,
|
||||
vnet_config_main_t * cm,
|
||||
u32 config_id,
|
||||
u32 feature_index,
|
||||
void * feature_config,
|
||||
void *feature_config,
|
||||
u32 n_feature_config_bytes);
|
||||
|
||||
#endif /* included_vnet_config_h */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
#include <vnet/devices/dpdk/dpdk.h>
|
||||
|
||||
/*
|
||||
* vlib_dpdk_clone_buffer - clone a buffer
|
||||
* vlib_dpdk_clone_buffer - clone a buffer
|
||||
* for port mirroring, lawful intercept, etc.
|
||||
* rte_pktmbuf_clone (...) requires that the forwarding path
|
||||
* not touch any of the cloned data. The hope is that we'll
|
||||
* figure out how to relax that restriction.
|
||||
*
|
||||
* figure out how to relax that restriction.
|
||||
*
|
||||
* For the moment, copy packet data.
|
||||
*/
|
||||
|
||||
@@ -16,92 +16,100 @@ static inline vlib_buffer_t *
|
||||
vlib_dpdk_clone_buffer (vlib_main_t * vm, vlib_buffer_t * b)
|
||||
{
|
||||
u32 new_buffers_needed = 1;
|
||||
unsigned socket_id = rte_socket_id();
|
||||
unsigned socket_id = rte_socket_id ();
|
||||
struct rte_mempool *rmp = vm->buffer_main->pktmbuf_pools[socket_id];
|
||||
struct rte_mbuf *rte_mbufs[5];
|
||||
vlib_buffer_free_list_t * fl;
|
||||
vlib_buffer_t * rv;
|
||||
u8 * copy_src, * copy_dst;
|
||||
vlib_buffer_free_list_t *fl;
|
||||
vlib_buffer_t *rv;
|
||||
u8 *copy_src, *copy_dst;
|
||||
vlib_buffer_t *src_buf, *dst_buf;
|
||||
|
||||
fl = vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
|
||||
|
||||
if (PREDICT_FALSE(b->flags & VLIB_BUFFER_NEXT_PRESENT))
|
||||
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
|
||||
{
|
||||
vlib_buffer_t *tmp = b;
|
||||
int i;
|
||||
|
||||
while (tmp->flags & VLIB_BUFFER_NEXT_PRESENT)
|
||||
{
|
||||
new_buffers_needed ++;
|
||||
tmp = vlib_get_buffer (vm, tmp->next_buffer);
|
||||
}
|
||||
{
|
||||
new_buffers_needed++;
|
||||
tmp = vlib_get_buffer (vm, tmp->next_buffer);
|
||||
}
|
||||
|
||||
/* Should never happen... */
|
||||
if (PREDICT_FALSE(new_buffers_needed > ARRAY_LEN(rte_mbufs)))
|
||||
{
|
||||
clib_warning ("need %d buffers", new_buffers_needed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rte_mempool_get_bulk (rmp, (void **)rte_mbufs,
|
||||
new_buffers_needed) < 0)
|
||||
return 0;
|
||||
if (PREDICT_FALSE (new_buffers_needed > ARRAY_LEN (rte_mbufs)))
|
||||
{
|
||||
clib_warning ("need %d buffers", new_buffers_needed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rte_mempool_get_bulk (rmp, (void **) rte_mbufs,
|
||||
new_buffers_needed) < 0)
|
||||
return 0;
|
||||
|
||||
src_buf = b;
|
||||
rv = dst_buf = vlib_buffer_from_rte_mbuf(rte_mbufs[0]);
|
||||
rv = dst_buf = vlib_buffer_from_rte_mbuf (rte_mbufs[0]);
|
||||
vlib_buffer_init_for_free_list (dst_buf, fl);
|
||||
copy_src = b->data + src_buf->current_data;
|
||||
copy_dst = dst_buf->data + src_buf->current_data;
|
||||
|
||||
for (i = 0; i < new_buffers_needed; i++)
|
||||
{
|
||||
clib_memcpy (copy_src, copy_dst, src_buf->current_length);
|
||||
dst_buf->current_data = src_buf->current_data;
|
||||
dst_buf->current_length = src_buf->current_length;
|
||||
dst_buf->flags = src_buf->flags;
|
||||
{
|
||||
clib_memcpy (copy_src, copy_dst, src_buf->current_length);
|
||||
dst_buf->current_data = src_buf->current_data;
|
||||
dst_buf->current_length = src_buf->current_length;
|
||||
dst_buf->flags = src_buf->flags;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
dst_buf->total_length_not_including_first_buffer =
|
||||
src_buf->total_length_not_including_first_buffer;
|
||||
vnet_buffer(dst_buf)->sw_if_index[VLIB_RX] =
|
||||
vnet_buffer(src_buf)->sw_if_index[VLIB_RX];
|
||||
vnet_buffer(dst_buf)->sw_if_index[VLIB_TX] =
|
||||
vnet_buffer(src_buf)->sw_if_index[VLIB_TX];
|
||||
vnet_buffer(dst_buf)->l2 = vnet_buffer(b)->l2;
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
dst_buf->total_length_not_including_first_buffer =
|
||||
src_buf->total_length_not_including_first_buffer;
|
||||
vnet_buffer (dst_buf)->sw_if_index[VLIB_RX] =
|
||||
vnet_buffer (src_buf)->sw_if_index[VLIB_RX];
|
||||
vnet_buffer (dst_buf)->sw_if_index[VLIB_TX] =
|
||||
vnet_buffer (src_buf)->sw_if_index[VLIB_TX];
|
||||
vnet_buffer (dst_buf)->l2 = vnet_buffer (b)->l2;
|
||||
}
|
||||
|
||||
if (i < new_buffers_needed - 1)
|
||||
{
|
||||
src_buf = vlib_get_buffer (vm, src_buf->next_buffer);
|
||||
dst_buf = vlib_buffer_from_rte_mbuf(rte_mbufs[i+1]);
|
||||
vlib_buffer_init_for_free_list (dst_buf, fl);
|
||||
copy_src = src_buf->data;
|
||||
copy_dst = dst_buf->data;
|
||||
}
|
||||
}
|
||||
if (i < new_buffers_needed - 1)
|
||||
{
|
||||
src_buf = vlib_get_buffer (vm, src_buf->next_buffer);
|
||||
dst_buf = vlib_buffer_from_rte_mbuf (rte_mbufs[i + 1]);
|
||||
vlib_buffer_init_for_free_list (dst_buf, fl);
|
||||
copy_src = src_buf->data;
|
||||
copy_dst = dst_buf->data;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (rte_mempool_get_bulk (rmp, (void **)rte_mbufs, 1) < 0)
|
||||
if (rte_mempool_get_bulk (rmp, (void **) rte_mbufs, 1) < 0)
|
||||
return 0;
|
||||
|
||||
rv = vlib_buffer_from_rte_mbuf(rte_mbufs[0]);
|
||||
rv = vlib_buffer_from_rte_mbuf (rte_mbufs[0]);
|
||||
vlib_buffer_init_for_free_list (rv, fl);
|
||||
|
||||
clib_memcpy(rv->data + b->current_data, b->data + b->current_data,
|
||||
b->current_length);
|
||||
clib_memcpy (rv->data + b->current_data, b->data + b->current_data,
|
||||
b->current_length);
|
||||
rv->current_data = b->current_data;
|
||||
rv->current_length = b->current_length;
|
||||
vnet_buffer(rv)->sw_if_index[VLIB_RX] =
|
||||
vnet_buffer(b)->sw_if_index[VLIB_RX];
|
||||
vnet_buffer(rv)->sw_if_index[VLIB_TX] =
|
||||
vnet_buffer(b)->sw_if_index[VLIB_TX];
|
||||
vnet_buffer(rv)->l2 = vnet_buffer(b)->l2;
|
||||
vnet_buffer (rv)->sw_if_index[VLIB_RX] =
|
||||
vnet_buffer (b)->sw_if_index[VLIB_RX];
|
||||
vnet_buffer (rv)->sw_if_index[VLIB_TX] =
|
||||
vnet_buffer (b)->sw_if_index[VLIB_TX];
|
||||
vnet_buffer (rv)->l2 = vnet_buffer (b)->l2;
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __included_dpdk_replication_h__ */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
#ifndef included_vnet_global_funcs_h_
|
||||
#define included_vnet_global_funcs_h_
|
||||
|
||||
vnet_main_t * vnet_get_main (void);
|
||||
vnet_main_t *vnet_get_main (void);
|
||||
|
||||
#endif /* included_vnet_global_funcs_h_ */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+204
-175
File diff suppressed because it is too large
Load Diff
+147
-103
File diff suppressed because it is too large
Load Diff
+456
-353
File diff suppressed because it is too large
Load Diff
+128
-101
File diff suppressed because it is too large
Load Diff
+441
-369
File diff suppressed because it is too large
Load Diff
+114
-94
File diff suppressed because it is too large
Load Diff
+73
-40
@@ -42,17 +42,21 @@
|
||||
|
||||
always_inline vnet_hw_interface_t *
|
||||
vnet_get_hw_interface (vnet_main_t * vnm, u32 hw_if_index)
|
||||
{ return pool_elt_at_index (vnm->interface_main.hw_interfaces, hw_if_index); }
|
||||
{
|
||||
return pool_elt_at_index (vnm->interface_main.hw_interfaces, hw_if_index);
|
||||
}
|
||||
|
||||
always_inline vnet_sw_interface_t *
|
||||
vnet_get_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
|
||||
{ return pool_elt_at_index (vnm->interface_main.sw_interfaces, sw_if_index); }
|
||||
{
|
||||
return pool_elt_at_index (vnm->interface_main.sw_interfaces, sw_if_index);
|
||||
}
|
||||
|
||||
always_inline vnet_sw_interface_t *
|
||||
vnet_get_hw_sw_interface (vnet_main_t * vnm, u32 hw_if_index)
|
||||
{
|
||||
vnet_hw_interface_t * hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
vnet_sw_interface_t * sw = vnet_get_sw_interface (vnm, hw->sw_if_index);
|
||||
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, hw->sw_if_index);
|
||||
ASSERT (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE);
|
||||
return sw;
|
||||
}
|
||||
@@ -60,7 +64,7 @@ vnet_get_hw_sw_interface (vnet_main_t * vnm, u32 hw_if_index)
|
||||
always_inline vnet_sw_interface_t *
|
||||
vnet_get_sup_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
|
||||
{
|
||||
vnet_sw_interface_t * sw = vnet_get_sw_interface (vnm, sw_if_index);
|
||||
vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
|
||||
if (sw->type == VNET_SW_INTERFACE_TYPE_SUB)
|
||||
sw = vnet_get_sw_interface (vnm, sw->sup_sw_if_index);
|
||||
return sw;
|
||||
@@ -69,29 +73,35 @@ vnet_get_sup_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
|
||||
always_inline vnet_hw_interface_t *
|
||||
vnet_get_sup_hw_interface (vnet_main_t * vnm, u32 sw_if_index)
|
||||
{
|
||||
vnet_sw_interface_t * sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
|
||||
vnet_sw_interface_t *sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
|
||||
ASSERT (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE);
|
||||
return vnet_get_hw_interface (vnm, sw->hw_if_index);
|
||||
}
|
||||
|
||||
always_inline vnet_hw_interface_class_t *
|
||||
vnet_get_hw_interface_class (vnet_main_t * vnm, u32 hw_class_index)
|
||||
{ return vec_elt_at_index (vnm->interface_main.hw_interface_classes, hw_class_index); }
|
||||
{
|
||||
return vec_elt_at_index (vnm->interface_main.hw_interface_classes,
|
||||
hw_class_index);
|
||||
}
|
||||
|
||||
always_inline vnet_device_class_t *
|
||||
vnet_get_device_class (vnet_main_t * vnm, u32 dev_class_index)
|
||||
{ return vec_elt_at_index (vnm->interface_main.device_classes, dev_class_index); }
|
||||
{
|
||||
return vec_elt_at_index (vnm->interface_main.device_classes,
|
||||
dev_class_index);
|
||||
}
|
||||
|
||||
/* Register a hardware interface instance. */
|
||||
u32 vnet_register_interface (vnet_main_t * vnm,
|
||||
u32 dev_class_index,
|
||||
u32 dev_instance,
|
||||
u32 hw_class_index,
|
||||
u32 hw_instance);
|
||||
u32 hw_class_index, u32 hw_instance);
|
||||
|
||||
/* Creates a software interface given template. */
|
||||
clib_error_t *
|
||||
vnet_create_sw_interface (vnet_main_t * vnm, vnet_sw_interface_t * template, u32 * sw_if_index);
|
||||
clib_error_t *vnet_create_sw_interface (vnet_main_t * vnm,
|
||||
vnet_sw_interface_t * template,
|
||||
u32 * sw_if_index);
|
||||
|
||||
void vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index);
|
||||
void vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index);
|
||||
@@ -99,60 +109,68 @@ void vnet_delete_sw_interface (vnet_main_t * vnm, u32 sw_if_index);
|
||||
always_inline uword
|
||||
vnet_sw_interface_get_flags (vnet_main_t * vnm, u32 sw_if_index)
|
||||
{
|
||||
vnet_sw_interface_t * sw = vnet_get_sw_interface (vnm, sw_if_index);
|
||||
vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
|
||||
return sw->flags;
|
||||
}
|
||||
|
||||
always_inline uword
|
||||
vnet_sw_interface_is_admin_up (vnet_main_t * vnm, u32 sw_if_index)
|
||||
{ return (vnet_sw_interface_get_flags (vnm, sw_if_index) & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0; }
|
||||
{
|
||||
return (vnet_sw_interface_get_flags (vnm, sw_if_index) &
|
||||
VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
|
||||
}
|
||||
|
||||
always_inline uword
|
||||
vnet_hw_interface_get_flags (vnet_main_t * vnm, u32 hw_if_index)
|
||||
{
|
||||
vnet_hw_interface_t * hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
return hw->flags;
|
||||
}
|
||||
|
||||
always_inline uword
|
||||
vnet_hw_interface_is_link_up (vnet_main_t * vnm, u32 hw_if_index)
|
||||
{ return (vnet_hw_interface_get_flags (vnm, hw_if_index) & VNET_HW_INTERFACE_FLAG_LINK_UP) != 0; }
|
||||
{
|
||||
return (vnet_hw_interface_get_flags (vnm, hw_if_index) &
|
||||
VNET_HW_INTERFACE_FLAG_LINK_UP) != 0;
|
||||
}
|
||||
|
||||
always_inline vlib_frame_t *
|
||||
vnet_get_frame_to_sw_interface (vnet_main_t * vnm, u32 sw_if_index)
|
||||
{
|
||||
vnet_hw_interface_t * hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
return vlib_get_frame_to_node (vnm->vlib_main, hw->output_node_index);
|
||||
}
|
||||
|
||||
always_inline void
|
||||
vnet_put_frame_to_sw_interface (vnet_main_t * vnm, u32 sw_if_index, vlib_frame_t * f)
|
||||
vnet_put_frame_to_sw_interface (vnet_main_t * vnm, u32 sw_if_index,
|
||||
vlib_frame_t * f)
|
||||
{
|
||||
vnet_hw_interface_t * hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
return vlib_put_frame_to_node (vnm->vlib_main, hw->output_node_index, f);
|
||||
}
|
||||
|
||||
/* Change interface flags (e.g. up, down, enable, disable). */
|
||||
clib_error_t *
|
||||
vnet_hw_interface_set_flags (vnet_main_t * vnm, u32 hw_if_index, u32 flags);
|
||||
clib_error_t *vnet_hw_interface_set_flags (vnet_main_t * vnm, u32 hw_if_index,
|
||||
u32 flags);
|
||||
|
||||
/* Change interface flags (e.g. up, down, enable, disable). */
|
||||
clib_error_t *
|
||||
vnet_sw_interface_set_flags (vnet_main_t * vnm, u32 sw_if_index, u32 flags);
|
||||
clib_error_t *vnet_sw_interface_set_flags (vnet_main_t * vnm, u32 sw_if_index,
|
||||
u32 flags);
|
||||
|
||||
/* Change interface class. */
|
||||
clib_error_t *
|
||||
vnet_hw_interface_set_class (vnet_main_t * vnm, u32 hw_if_index, u32 new_hw_class_index);
|
||||
clib_error_t *vnet_hw_interface_set_class (vnet_main_t * vnm, u32 hw_if_index,
|
||||
u32 new_hw_class_index);
|
||||
|
||||
/* Redirect rx pkts to node */
|
||||
int vnet_hw_interface_rx_redirect_to_node (vnet_main_t * vnm, u32 hw_if_index,
|
||||
u32 node_index);
|
||||
u32 node_index);
|
||||
|
||||
void vnet_hw_interface_init_for_class (vnet_main_t * vnm, u32 hw_if_index, u32 hw_class_index, u32 hw_instance);
|
||||
void vnet_hw_interface_init_for_class (vnet_main_t * vnm, u32 hw_if_index,
|
||||
u32 hw_class_index, u32 hw_instance);
|
||||
|
||||
/* Rename interface */
|
||||
clib_error_t *
|
||||
vnet_rename_interface (vnet_main_t * vnm, u32 hw_if_index, char * new_name);
|
||||
clib_error_t *vnet_rename_interface (vnet_main_t * vnm, u32 hw_if_index,
|
||||
char *new_name);
|
||||
|
||||
/* Formats sw/hw interface. */
|
||||
format_function_t format_vnet_hw_interface;
|
||||
@@ -171,7 +189,8 @@ unformat_function_t unformat_vnet_hw_interface_flags;
|
||||
unformat_function_t unformat_vnet_sw_interface_flags;
|
||||
|
||||
/* Node runtime for interface output function. */
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
u32 hw_if_index;
|
||||
u32 sw_if_index;
|
||||
u32 dev_instance;
|
||||
@@ -179,35 +198,49 @@ typedef struct {
|
||||
} vnet_interface_output_runtime_t;
|
||||
|
||||
/* Interface output functions. */
|
||||
void * vnet_interface_output_node_multiarch_select (void);
|
||||
void * vnet_interface_output_node_no_flatten_multiarch_select (void);
|
||||
void *vnet_interface_output_node_multiarch_select (void);
|
||||
void *vnet_interface_output_node_no_flatten_multiarch_select (void);
|
||||
|
||||
word vnet_sw_interface_compare (vnet_main_t * vnm, uword sw_if_index0, uword sw_if_index1);
|
||||
word vnet_hw_interface_compare (vnet_main_t * vnm, uword hw_if_index0, uword hw_if_index1);
|
||||
word vnet_sw_interface_compare (vnet_main_t * vnm, uword sw_if_index0,
|
||||
uword sw_if_index1);
|
||||
word vnet_hw_interface_compare (vnet_main_t * vnm, uword hw_if_index0,
|
||||
uword hw_if_index1);
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define _(sym,str) VNET_INTERFACE_OUTPUT_NEXT_##sym,
|
||||
foreach_intf_output_feat
|
||||
#undef _
|
||||
VNET_INTERFACE_OUTPUT_NEXT_DROP,
|
||||
VNET_INTERFACE_OUTPUT_NEXT_DROP,
|
||||
VNET_INTERFACE_OUTPUT_NEXT_TX,
|
||||
} vnet_interface_output_next_t;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
VNET_INTERFACE_TX_NEXT_DROP,
|
||||
VNET_INTERFACE_TX_N_NEXT,
|
||||
} vnet_interface_tx_next_t;
|
||||
|
||||
#define VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT VNET_INTERFACE_TX_N_NEXT
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DOWN,
|
||||
VNET_INTERFACE_OUTPUT_ERROR_INTERFACE_DELETED,
|
||||
} vnet_interface_output_error_t;
|
||||
|
||||
/* Format for interface output traces. */
|
||||
u8 * format_vnet_interface_output_trace (u8 * s, va_list * va);
|
||||
u8 *format_vnet_interface_output_trace (u8 * s, va_list * va);
|
||||
|
||||
serialize_function_t serialize_vnet_interface_state, unserialize_vnet_interface_state;
|
||||
serialize_function_t serialize_vnet_interface_state,
|
||||
unserialize_vnet_interface_state;
|
||||
|
||||
#endif /* included_vnet_interface_funcs_h */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+471
-447
File diff suppressed because it is too large
Load Diff
+10
-1
@@ -41,10 +41,19 @@
|
||||
#define included_vnet_l3_types_h
|
||||
|
||||
/* Inherit generic L3 packet types from ethernet. */
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
#define ethernet_type(n,f) VNET_L3_PACKET_TYPE_##f,
|
||||
#include <vnet/ethernet/types.def>
|
||||
#undef ethernet_type
|
||||
} vnet_l3_packet_type_t;
|
||||
|
||||
#endif /* included_vnet_l3_types_h */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+17
-7
@@ -49,29 +49,32 @@ vnet_get_main (void)
|
||||
|
||||
static uword
|
||||
vnet_local_interface_tx (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node,
|
||||
vlib_frame_t * f)
|
||||
vlib_node_runtime_t * node, vlib_frame_t * f)
|
||||
{
|
||||
ASSERT (0);
|
||||
return f->n_vectors;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VNET_DEVICE_CLASS (vnet_local_interface_device_class) = {
|
||||
.name = "local",
|
||||
.tx_function = vnet_local_interface_tx,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VNET_HW_INTERFACE_CLASS (vnet_local_interface_hw_class,static) = {
|
||||
.name = "local",
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
clib_error_t *
|
||||
vnet_main_init (vlib_main_t * vm)
|
||||
{
|
||||
vnet_main_t * vnm = vnet_get_main();
|
||||
clib_error_t * error;
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
clib_error_t *error;
|
||||
u32 hw_if_index;
|
||||
vnet_hw_interface_t * hw;
|
||||
vnet_hw_interface_t *hw;
|
||||
|
||||
if ((error = vlib_call_init_function (vm, vnet_interface_init)))
|
||||
return error;
|
||||
@@ -88,8 +91,7 @@ vnet_main_init (vlib_main_t * vm)
|
||||
vnm->vlib_main = vm;
|
||||
|
||||
hw_if_index = vnet_register_interface
|
||||
(vnm,
|
||||
vnet_local_interface_device_class.index, /* instance */ 0,
|
||||
(vnm, vnet_local_interface_device_class.index, /* instance */ 0,
|
||||
vnet_local_interface_hw_class.index, /* instance */ 0);
|
||||
hw = vnet_get_hw_interface (vnm, hw_if_index);
|
||||
|
||||
@@ -100,3 +102,11 @@ vnet_main_init (vlib_main_t * vm)
|
||||
}
|
||||
|
||||
VLIB_INIT_FUNCTION (vnet_main_init);
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+321
-318
File diff suppressed because it is too large
Load Diff
+165
-147
File diff suppressed because it is too large
Load Diff
+63
-49
@@ -24,42 +24,46 @@
|
||||
#include <vnet/replication.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/* The entire vnet buffer header restored for each replica */
|
||||
u8 vnet_buffer[32]; /* 16B aligned to allow vector unit copy */
|
||||
u8 reserved[32]; /* space for future expansion of vnet buffer header */
|
||||
|
||||
// The entire vnet buffer header restored for each replica
|
||||
u8 vnet_buffer[32]; // 16B aligned to allow vector unit copy
|
||||
u8 reserved[32]; // space for future expansion of vnet buffer header
|
||||
/* feature state used during this replication */
|
||||
u64 feature_replicas; /* feature's id for its set of replicas */
|
||||
u32 feature_counter; /* feature's current index into set of replicas */
|
||||
u32 recycle_node_index; /* feature's recycle node index */
|
||||
|
||||
// feature state used during this replication
|
||||
u64 feature_replicas; // feature's id for its set of replicas
|
||||
u32 feature_counter; // feature's current index into set of replicas
|
||||
u32 recycle_node_index; // feature's recycle node index
|
||||
/*
|
||||
* data saved from the start of replication and restored
|
||||
* at the end of replication
|
||||
*/
|
||||
u32 saved_free_list_index; /* from vlib buffer */
|
||||
|
||||
// data saved from the start of replication and restored at the end of replication
|
||||
u32 saved_free_list_index; // from vlib buffer
|
||||
/* data saved from the original packet and restored for each replica */
|
||||
u64 l2_header[3]; /* 24B (must be at least 22B for l2 packets) */
|
||||
u16 ip_tos; /* v4 and v6 */
|
||||
u16 ip4_checksum; /* needed for v4 only */
|
||||
|
||||
// data saved from the original packet and restored for each replica
|
||||
u64 l2_header[3]; // 24B (must be at least 22B for l2 packets)
|
||||
u16 ip_tos; // v4 and v6
|
||||
u16 ip4_checksum; // needed for v4 only
|
||||
/* data saved from the vlib buffer header and restored for each replica */
|
||||
i16 current_data; /* offset of first byte of packet in packet data */
|
||||
u8 pad[6]; /* to 64B */
|
||||
u8 l2_packet; /* flag for l2 vs l3 packet data */
|
||||
|
||||
// data saved from the vlib buffer header and restored for each replica
|
||||
i16 current_data; // offset of first byte of packet in packet data
|
||||
u8 pad[6]; // to 64B
|
||||
u8 l2_packet; // flag for l2 vs l3 packet data
|
||||
|
||||
} replication_context_t; // 128B
|
||||
} replication_context_t; /* 128B */
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
|
||||
u32 recycle_list_index;
|
||||
|
||||
// per-thread pools of replication contexts
|
||||
replication_context_t ** contexts;
|
||||
/* per-thread pools of replication contexts */
|
||||
replication_context_t **contexts;
|
||||
|
||||
vlib_main_t * vlib_main;
|
||||
vnet_main_t * vnet_main;
|
||||
vlib_main_t *vlib_main;
|
||||
vnet_main_t *vnet_main;
|
||||
|
||||
} replication_main_t;
|
||||
|
||||
@@ -67,56 +71,66 @@ typedef struct {
|
||||
extern replication_main_t replication_main;
|
||||
|
||||
|
||||
// Return 1 if this buffer just came from the replication recycle handler.
|
||||
/* Return 1 if this buffer just came from the replication recycle handler. */
|
||||
always_inline u32
|
||||
replication_is_recycled (vlib_buffer_t * b0)
|
||||
{
|
||||
return b0->flags & VLIB_BUFFER_IS_RECYCLED;
|
||||
}
|
||||
|
||||
// Clear the recycle flag. If buffer came from the replication recycle
|
||||
// handler, this flag must be cleared before the packet is transmitted again.
|
||||
/*
|
||||
* Clear the recycle flag. If buffer came from the replication recycle
|
||||
* handler, this flag must be cleared before the packet is transmitted again.
|
||||
*/
|
||||
always_inline void
|
||||
replication_clear_recycled (vlib_buffer_t * b0)
|
||||
{
|
||||
b0->flags &= ~VLIB_BUFFER_IS_RECYCLED;
|
||||
}
|
||||
|
||||
// Return the active replication context if this buffer has
|
||||
// been recycled, otherwise return 0. (Note that this essentially
|
||||
// restricts access to the replication context to the replication
|
||||
// feature's prep and recycle nodes.)
|
||||
/*
|
||||
* Return the active replication context if this buffer has
|
||||
* been recycled, otherwise return 0. (Note that this essentially
|
||||
* restricts access to the replication context to the replication
|
||||
* feature's prep and recycle nodes.)
|
||||
*/
|
||||
always_inline replication_context_t *
|
||||
replication_get_ctx (vlib_buffer_t * b0)
|
||||
{
|
||||
replication_main_t * rm = &replication_main;
|
||||
replication_main_t *rm = &replication_main;
|
||||
|
||||
return replication_is_recycled (b0) ?
|
||||
pool_elt_at_index (rm->contexts[os_get_cpu_number()], b0->recycle_count) :
|
||||
0;
|
||||
return replication_is_recycled (b0) ?
|
||||
pool_elt_at_index (rm->contexts[os_get_cpu_number ()],
|
||||
b0->recycle_count) : 0;
|
||||
}
|
||||
|
||||
// Prefetch the replication context for this buffer, if it exists
|
||||
/* Prefetch the replication context for this buffer, if it exists */
|
||||
always_inline void
|
||||
replication_prefetch_ctx (vlib_buffer_t * b0)
|
||||
{
|
||||
replication_context_t *ctx = replication_get_ctx (b0);
|
||||
|
||||
if (ctx) {
|
||||
CLIB_PREFETCH (ctx, (2*CLIB_CACHE_LINE_BYTES), STORE);
|
||||
}
|
||||
if (ctx)
|
||||
{
|
||||
CLIB_PREFETCH (ctx, (2 * CLIB_CACHE_LINE_BYTES), STORE);
|
||||
}
|
||||
}
|
||||
|
||||
replication_context_t *
|
||||
replication_prep (vlib_main_t * vm,
|
||||
vlib_buffer_t * b0,
|
||||
u32 recycle_node_index,
|
||||
u32 l2_packet);
|
||||
replication_context_t *replication_prep (vlib_main_t * vm,
|
||||
vlib_buffer_t * b0,
|
||||
u32 recycle_node_index,
|
||||
u32 l2_packet);
|
||||
|
||||
replication_context_t *
|
||||
replication_recycle (vlib_main_t * vm,
|
||||
vlib_buffer_t * b0,
|
||||
u32 is_last);
|
||||
replication_context_t *replication_recycle (vlib_main_t * vm,
|
||||
vlib_buffer_t * b0, u32 is_last);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+93
-72
@@ -40,18 +40,19 @@
|
||||
#include <vnet/vnet.h>
|
||||
#include <vnet/ip/lookup.h>
|
||||
|
||||
void vnet_rewrite_copy_slow_path (vnet_rewrite_data_t * p0,
|
||||
vnet_rewrite_data_t * rw0,
|
||||
word n_left,
|
||||
uword most_likely_size)
|
||||
void
|
||||
vnet_rewrite_copy_slow_path (vnet_rewrite_data_t * p0,
|
||||
vnet_rewrite_data_t * rw0,
|
||||
word n_left, uword most_likely_size)
|
||||
{
|
||||
uword n_done = round_pow2 (most_likely_size, sizeof (rw0[0])) / sizeof (rw0[0]);
|
||||
uword n_done =
|
||||
round_pow2 (most_likely_size, sizeof (rw0[0])) / sizeof (rw0[0]);
|
||||
|
||||
p0 -= n_done;
|
||||
rw0 -= n_done;
|
||||
|
||||
/* As we enter the cleanup loop, p0 and rw0 point to the last chunk written
|
||||
by the fast path. Hence, the constant 1, which the
|
||||
by the fast path. Hence, the constant 1, which the
|
||||
vnet_rewrite_copy_one macro renders as p0[-1] = rw0[-1]. */
|
||||
|
||||
while (n_left > 0)
|
||||
@@ -63,13 +64,14 @@ void vnet_rewrite_copy_slow_path (vnet_rewrite_data_t * p0,
|
||||
}
|
||||
}
|
||||
|
||||
u8 * format_vnet_rewrite (u8 * s, va_list * args)
|
||||
u8 *
|
||||
format_vnet_rewrite (u8 * s, va_list * args)
|
||||
{
|
||||
vlib_main_t * vm = va_arg (*args, vlib_main_t *);
|
||||
vnet_rewrite_header_t * rw = va_arg (*args, vnet_rewrite_header_t *);
|
||||
vlib_main_t *vm = va_arg (*args, vlib_main_t *);
|
||||
vnet_rewrite_header_t *rw = va_arg (*args, vnet_rewrite_header_t *);
|
||||
u32 max_data_bytes = va_arg (*args, u32);
|
||||
vnet_main_t * vnm = vnet_get_main();
|
||||
vlib_node_t * next;
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
vlib_node_t *next;
|
||||
uword indent;
|
||||
|
||||
next = vlib_get_next_node (vm, rw->node_index, rw->next_index);
|
||||
@@ -78,7 +80,7 @@ u8 * format_vnet_rewrite (u8 * s, va_list * args)
|
||||
|
||||
if (rw->sw_if_index != ~0)
|
||||
{
|
||||
vnet_sw_interface_t * si;
|
||||
vnet_sw_interface_t *si;
|
||||
si = vnet_get_sw_interface (vnm, rw->sw_if_index);
|
||||
s = format (s, "%U", format_vnet_sw_interface_name, vnm, si);
|
||||
}
|
||||
@@ -90,19 +92,19 @@ u8 * format_vnet_rewrite (u8 * s, va_list * args)
|
||||
s = format (s, "\n%U%U",
|
||||
format_white_space, indent,
|
||||
next->format_buffer ? next->format_buffer : format_hex_bytes,
|
||||
rw->data + max_data_bytes - rw->data_bytes,
|
||||
rw->data_bytes);
|
||||
rw->data + max_data_bytes - rw->data_bytes, rw->data_bytes);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
u8 * format_vnet_rewrite_header (u8 * s, va_list * args)
|
||||
u8 *
|
||||
format_vnet_rewrite_header (u8 * s, va_list * args)
|
||||
{
|
||||
vlib_main_t * vm = va_arg (*args, vlib_main_t *);
|
||||
vnet_rewrite_header_t * rw = va_arg (*args, vnet_rewrite_header_t *);
|
||||
u8 * packet_data = va_arg (*args, u8 *);
|
||||
vlib_main_t *vm = va_arg (*args, vlib_main_t *);
|
||||
vnet_rewrite_header_t *rw = va_arg (*args, vnet_rewrite_header_t *);
|
||||
u8 *packet_data = va_arg (*args, u8 *);
|
||||
u32 packet_data_bytes = va_arg (*args, u32);
|
||||
vlib_node_t * next;
|
||||
vlib_node_t *next;
|
||||
|
||||
next = vlib_get_next_node (vm, rw->node_index, rw->next_index);
|
||||
|
||||
@@ -114,15 +116,16 @@ u8 * format_vnet_rewrite_header (u8 * s, va_list * args)
|
||||
return s;
|
||||
}
|
||||
|
||||
uword unformat_vnet_rewrite (unformat_input_t * input, va_list * args)
|
||||
uword
|
||||
unformat_vnet_rewrite (unformat_input_t * input, va_list * args)
|
||||
{
|
||||
vlib_main_t * vm = va_arg (*args, vlib_main_t *);
|
||||
vnet_rewrite_header_t * rw = va_arg (*args, vnet_rewrite_header_t *);
|
||||
vlib_main_t *vm = va_arg (*args, vlib_main_t *);
|
||||
vnet_rewrite_header_t *rw = va_arg (*args, vnet_rewrite_header_t *);
|
||||
u32 max_data_bytes = va_arg (*args, u32);
|
||||
vnet_main_t * vnm = vnet_get_main();
|
||||
vlib_node_t * next;
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
vlib_node_t *next;
|
||||
u32 next_index, sw_if_index, max_packet_bytes, error;
|
||||
u8 * rw_data;
|
||||
u8 *rw_data;
|
||||
|
||||
rw_data = 0;
|
||||
sw_if_index = ~0;
|
||||
@@ -130,10 +133,9 @@ uword unformat_vnet_rewrite (unformat_input_t * input, va_list * args)
|
||||
error = 1;
|
||||
|
||||
/* Parse sw interface. */
|
||||
if (unformat (input, "%U",
|
||||
unformat_vnet_sw_interface, vnm, &sw_if_index))
|
||||
if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
|
||||
{
|
||||
vnet_hw_interface_t * hi;
|
||||
vnet_hw_interface_t *hi;
|
||||
|
||||
hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
|
||||
@@ -141,8 +143,7 @@ uword unformat_vnet_rewrite (unformat_input_t * input, va_list * args)
|
||||
max_packet_bytes = hi->max_l3_packet_bytes[VLIB_RX];
|
||||
}
|
||||
|
||||
else if (unformat (input, "%U",
|
||||
unformat_vlib_node, vm, &next_index))
|
||||
else if (unformat (input, "%U", unformat_vlib_node, vm, &next_index))
|
||||
;
|
||||
|
||||
else
|
||||
@@ -157,7 +158,7 @@ uword unformat_vnet_rewrite (unformat_input_t * input, va_list * args)
|
||||
else if (unformat_user (input, unformat_hex_string, &rw_data)
|
||||
|| unformat (input, "0x%U", unformat_hex_string, &rw_data))
|
||||
;
|
||||
|
||||
|
||||
else
|
||||
goto done;
|
||||
|
||||
@@ -177,29 +178,33 @@ uword unformat_vnet_rewrite (unformat_input_t * input, va_list * args)
|
||||
rw->sw_if_index = sw_if_index;
|
||||
rw->max_l3_packet_bytes = max_packet_bytes;
|
||||
rw->next_index = vlib_node_add_next (vm, rw->node_index, next_index);
|
||||
vnet_rewrite_set_data_internal (rw, max_data_bytes, rw_data, vec_len (rw_data));
|
||||
vnet_rewrite_set_data_internal (rw, max_data_bytes, rw_data,
|
||||
vec_len (rw_data));
|
||||
|
||||
done:
|
||||
done:
|
||||
vec_free (rw_data);
|
||||
return error == 0;
|
||||
}
|
||||
|
||||
void vnet_rewrite_for_sw_interface (vnet_main_t * vnm,
|
||||
vnet_l3_packet_type_t packet_type,
|
||||
u32 sw_if_index,
|
||||
u32 node_index,
|
||||
void * dst_address,
|
||||
vnet_rewrite_header_t * rw,
|
||||
u32 max_rewrite_bytes)
|
||||
void
|
||||
vnet_rewrite_for_sw_interface (vnet_main_t * vnm,
|
||||
vnet_l3_packet_type_t packet_type,
|
||||
u32 sw_if_index,
|
||||
u32 node_index,
|
||||
void *dst_address,
|
||||
vnet_rewrite_header_t * rw,
|
||||
u32 max_rewrite_bytes)
|
||||
{
|
||||
vnet_hw_interface_t * hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
vnet_hw_interface_class_t * hc = vnet_get_hw_interface_class (vnm, hw->hw_class_index);
|
||||
static u8 * rw_tmp = 0;
|
||||
vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
|
||||
vnet_hw_interface_class_t *hc =
|
||||
vnet_get_hw_interface_class (vnm, hw->hw_class_index);
|
||||
static u8 *rw_tmp = 0;
|
||||
uword n_rw_tmp;
|
||||
|
||||
rw->sw_if_index = sw_if_index;
|
||||
rw->node_index = node_index;
|
||||
rw->next_index = vlib_node_add_next (vnm->vlib_main, node_index, hw->output_node_index);
|
||||
rw->next_index =
|
||||
vlib_node_add_next (vnm->vlib_main, node_index, hw->output_node_index);
|
||||
rw->max_l3_packet_bytes = hw->max_l3_packet_bytes[VLIB_TX];
|
||||
|
||||
ASSERT (max_rewrite_bytes > 0);
|
||||
@@ -207,56 +212,62 @@ void vnet_rewrite_for_sw_interface (vnet_main_t * vnm,
|
||||
vec_validate (rw_tmp, max_rewrite_bytes - 1);
|
||||
|
||||
ASSERT (hc->set_rewrite);
|
||||
n_rw_tmp = hc->set_rewrite (vnm, sw_if_index, packet_type, dst_address, rw_tmp, max_rewrite_bytes);
|
||||
n_rw_tmp =
|
||||
hc->set_rewrite (vnm, sw_if_index, packet_type, dst_address, rw_tmp,
|
||||
max_rewrite_bytes);
|
||||
|
||||
ASSERT (n_rw_tmp < max_rewrite_bytes);
|
||||
vnet_rewrite_set_data_internal (rw, max_rewrite_bytes, rw_tmp, n_rw_tmp);
|
||||
}
|
||||
|
||||
void vnet_rewrite_for_tunnel (vnet_main_t * vnm,
|
||||
u32 tx_sw_if_index,
|
||||
u32 rewrite_node_index,
|
||||
u32 post_rewrite_node_index,
|
||||
vnet_rewrite_header_t * rw,
|
||||
u8 *rewrite_data,
|
||||
u32 rewrite_length)
|
||||
void
|
||||
vnet_rewrite_for_tunnel (vnet_main_t * vnm,
|
||||
u32 tx_sw_if_index,
|
||||
u32 rewrite_node_index,
|
||||
u32 post_rewrite_node_index,
|
||||
vnet_rewrite_header_t * rw,
|
||||
u8 * rewrite_data, u32 rewrite_length)
|
||||
{
|
||||
ip_adjacency_t * adj = 0;
|
||||
/*
|
||||
ip_adjacency_t *adj = 0;
|
||||
/*
|
||||
* Installed into vnet_buffer(b)->sw_if_index[VLIB_TX] e.g.
|
||||
* by ip4_rewrite_inline. If the post-rewrite node injects into
|
||||
* ipX-forward, this will be interpreted as a FIB number.
|
||||
* by ip4_rewrite_inline. If the post-rewrite node injects into
|
||||
* ipX-forward, this will be interpreted as a FIB number.
|
||||
*/
|
||||
rw->sw_if_index = tx_sw_if_index;
|
||||
rw->sw_if_index = tx_sw_if_index;
|
||||
rw->node_index = rewrite_node_index;
|
||||
rw->next_index = vlib_node_add_next (vnm->vlib_main, rewrite_node_index,
|
||||
post_rewrite_node_index);
|
||||
rw->max_l3_packet_bytes = (u16) ~0; /* we can't know at this point */
|
||||
rw->next_index = vlib_node_add_next (vnm->vlib_main, rewrite_node_index,
|
||||
post_rewrite_node_index);
|
||||
rw->max_l3_packet_bytes = (u16) ~ 0; /* we can't know at this point */
|
||||
|
||||
ASSERT (rewrite_length < sizeof (adj->rewrite_data));
|
||||
/* Leave room for ethernet + VLAN tag */
|
||||
vnet_rewrite_set_data_internal (rw, sizeof(adj->rewrite_data),
|
||||
rewrite_data, rewrite_length);
|
||||
vnet_rewrite_set_data_internal (rw, sizeof (adj->rewrite_data),
|
||||
rewrite_data, rewrite_length);
|
||||
}
|
||||
|
||||
void serialize_vnet_rewrite (serialize_main_t * m, va_list * va)
|
||||
void
|
||||
serialize_vnet_rewrite (serialize_main_t * m, va_list * va)
|
||||
{
|
||||
vnet_rewrite_header_t * rw = va_arg (*va, vnet_rewrite_header_t *);
|
||||
vnet_rewrite_header_t *rw = va_arg (*va, vnet_rewrite_header_t *);
|
||||
u32 max_data_bytes = va_arg (*va, u32);
|
||||
u8 * p;
|
||||
u8 *p;
|
||||
|
||||
serialize_integer (m, rw->sw_if_index, sizeof (rw->sw_if_index));
|
||||
serialize_integer (m, rw->data_bytes, sizeof (rw->data_bytes));
|
||||
serialize_integer (m, rw->max_l3_packet_bytes, sizeof (rw->max_l3_packet_bytes));
|
||||
serialize_integer (m, rw->max_l3_packet_bytes,
|
||||
sizeof (rw->max_l3_packet_bytes));
|
||||
p = serialize_get (m, rw->data_bytes);
|
||||
clib_memcpy (p, vnet_rewrite_get_data_internal (rw, max_data_bytes), rw->data_bytes);
|
||||
clib_memcpy (p, vnet_rewrite_get_data_internal (rw, max_data_bytes),
|
||||
rw->data_bytes);
|
||||
}
|
||||
|
||||
void unserialize_vnet_rewrite (serialize_main_t * m, va_list * va)
|
||||
void
|
||||
unserialize_vnet_rewrite (serialize_main_t * m, va_list * va)
|
||||
{
|
||||
vnet_rewrite_header_t * rw = va_arg (*va, vnet_rewrite_header_t *);
|
||||
vnet_rewrite_header_t *rw = va_arg (*va, vnet_rewrite_header_t *);
|
||||
u32 max_data_bytes = va_arg (*va, u32);
|
||||
u8 * p;
|
||||
u8 *p;
|
||||
|
||||
/* It is up to user to fill these in. */
|
||||
rw->node_index = ~0;
|
||||
@@ -264,7 +275,17 @@ void unserialize_vnet_rewrite (serialize_main_t * m, va_list * va)
|
||||
|
||||
unserialize_integer (m, &rw->sw_if_index, sizeof (rw->sw_if_index));
|
||||
unserialize_integer (m, &rw->data_bytes, sizeof (rw->data_bytes));
|
||||
unserialize_integer (m, &rw->max_l3_packet_bytes, sizeof (rw->max_l3_packet_bytes));
|
||||
unserialize_integer (m, &rw->max_l3_packet_bytes,
|
||||
sizeof (rw->max_l3_packet_bytes));
|
||||
p = unserialize_get (m, rw->data_bytes);
|
||||
clib_memcpy (vnet_rewrite_get_data_internal (rw, max_data_bytes), p, rw->data_bytes);
|
||||
clib_memcpy (vnet_rewrite_get_data_internal (rw, max_data_bytes), p,
|
||||
rw->data_bytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+60
-55
@@ -46,6 +46,7 @@
|
||||
/* Consider using vector types for speed? */
|
||||
typedef uword vnet_rewrite_data_t;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
typedef CLIB_PACKED (struct {
|
||||
/* Interface to mark re-written packets with. */
|
||||
u32 sw_if_index;
|
||||
@@ -66,13 +67,14 @@ typedef CLIB_PACKED (struct {
|
||||
/* Rewrite string starting at end and going backwards. */
|
||||
u8 data[0];
|
||||
}) vnet_rewrite_header_t;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
Helper macro for declaring rewrite string w/ given max-size.
|
||||
|
||||
Typical usage:
|
||||
typedef struct {
|
||||
// User data.
|
||||
//
|
||||
int a, b;
|
||||
|
||||
// Total adjacency is 64 bytes.
|
||||
@@ -88,11 +90,9 @@ struct { \
|
||||
|
||||
always_inline void
|
||||
vnet_rewrite_set_data_internal (vnet_rewrite_header_t * rw,
|
||||
int max_size,
|
||||
void * data,
|
||||
int data_bytes)
|
||||
int max_size, void *data, int data_bytes)
|
||||
{
|
||||
/* Sanity check values carefully for this memset operation*/
|
||||
/* Sanity check values carefully for this memset operation */
|
||||
ASSERT ((max_size > 0) && (max_size < VLIB_BUFFER_PRE_DATA_SIZE));
|
||||
ASSERT ((data_bytes >= 0) && (data_bytes < max_size));
|
||||
|
||||
@@ -118,30 +118,30 @@ vnet_rewrite_get_data_internal (vnet_rewrite_header_t * rw, int max_size)
|
||||
vnet_rewrite_get_data_internal (&((rw).rewrite_header), sizeof ((rw).rewrite_data))
|
||||
|
||||
always_inline void
|
||||
vnet_rewrite_copy_one (vnet_rewrite_data_t * p0, vnet_rewrite_data_t * rw0, int i)
|
||||
vnet_rewrite_copy_one (vnet_rewrite_data_t * p0, vnet_rewrite_data_t * rw0,
|
||||
int i)
|
||||
{
|
||||
p0[-i] = rw0[-i];
|
||||
}
|
||||
|
||||
void vnet_rewrite_copy_slow_path (vnet_rewrite_data_t * p0,
|
||||
vnet_rewrite_data_t * rw0,
|
||||
word n_left,
|
||||
uword most_likely_size);
|
||||
word n_left, uword most_likely_size);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
typedef CLIB_PACKED (struct {
|
||||
u64 a;
|
||||
u32 b;
|
||||
u16 c;
|
||||
}) eh_copy_t;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
always_inline void
|
||||
_vnet_rewrite_one_header (vnet_rewrite_header_t * h0,
|
||||
void * packet0,
|
||||
int max_size,
|
||||
int most_likely_size)
|
||||
void *packet0, int max_size, int most_likely_size)
|
||||
{
|
||||
vnet_rewrite_data_t * p0 = packet0;
|
||||
vnet_rewrite_data_t * rw0 = (vnet_rewrite_data_t *) (h0->data + max_size);
|
||||
vnet_rewrite_data_t *p0 = packet0;
|
||||
vnet_rewrite_data_t *rw0 = (vnet_rewrite_data_t *) (h0->data + max_size);
|
||||
word n_left0;
|
||||
|
||||
/* 0xfefe => poisoned adjacency => crash */
|
||||
@@ -149,13 +149,13 @@ _vnet_rewrite_one_header (vnet_rewrite_header_t * h0,
|
||||
|
||||
if (PREDICT_TRUE (h0->data_bytes == sizeof (eh_copy_t)))
|
||||
{
|
||||
eh_copy_t * s, * d;
|
||||
s = (eh_copy_t *)(h0->data + max_size - sizeof (eh_copy_t));
|
||||
d = (eh_copy_t *)(((u8 *)packet0) - sizeof (eh_copy_t));
|
||||
eh_copy_t *s, *d;
|
||||
s = (eh_copy_t *) (h0->data + max_size - sizeof (eh_copy_t));
|
||||
d = (eh_copy_t *) (((u8 *) packet0) - sizeof (eh_copy_t));
|
||||
clib_memcpy (d, s, sizeof (eh_copy_t));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define _(i) \
|
||||
do { \
|
||||
@@ -163,16 +163,16 @@ _vnet_rewrite_one_header (vnet_rewrite_header_t * h0,
|
||||
vnet_rewrite_copy_one (p0, rw0, (i)); \
|
||||
} while (0)
|
||||
|
||||
_ (4);
|
||||
_ (3);
|
||||
_ (2);
|
||||
_ (1);
|
||||
_(4);
|
||||
_(3);
|
||||
_(2);
|
||||
_(1);
|
||||
|
||||
#undef _
|
||||
|
||||
|
||||
n_left0 = (int)
|
||||
(((int) h0->data_bytes - most_likely_size) + (sizeof(rw0[0])-1))
|
||||
/ (int) sizeof (rw0[0]);
|
||||
(((int) h0->data_bytes - most_likely_size) + (sizeof (rw0[0]) - 1))
|
||||
/ (int) sizeof (rw0[0]);
|
||||
if (PREDICT_FALSE (n_left0 > 0))
|
||||
vnet_rewrite_copy_slow_path (p0, rw0, n_left0, most_likely_size);
|
||||
}
|
||||
@@ -180,15 +180,13 @@ _vnet_rewrite_one_header (vnet_rewrite_header_t * h0,
|
||||
always_inline void
|
||||
_vnet_rewrite_two_headers (vnet_rewrite_header_t * h0,
|
||||
vnet_rewrite_header_t * h1,
|
||||
void * packet0,
|
||||
void * packet1,
|
||||
int max_size,
|
||||
int most_likely_size)
|
||||
void *packet0,
|
||||
void *packet1, int max_size, int most_likely_size)
|
||||
{
|
||||
vnet_rewrite_data_t * p0 = packet0;
|
||||
vnet_rewrite_data_t * p1 = packet1;
|
||||
vnet_rewrite_data_t * rw0 = (vnet_rewrite_data_t *) (h0->data + max_size);
|
||||
vnet_rewrite_data_t * rw1 = (vnet_rewrite_data_t *) (h1->data + max_size);
|
||||
vnet_rewrite_data_t *p0 = packet0;
|
||||
vnet_rewrite_data_t *p1 = packet1;
|
||||
vnet_rewrite_data_t *rw0 = (vnet_rewrite_data_t *) (h0->data + max_size);
|
||||
vnet_rewrite_data_t *rw1 = (vnet_rewrite_data_t *) (h1->data + max_size);
|
||||
word n_left0, n_left1;
|
||||
int slow_path;
|
||||
|
||||
@@ -202,12 +200,12 @@ _vnet_rewrite_two_headers (vnet_rewrite_header_t * h0,
|
||||
|
||||
if (PREDICT_TRUE (slow_path == 0))
|
||||
{
|
||||
eh_copy_t * s0, * d0, * s1, * d1;
|
||||
s0 = (eh_copy_t *)(h0->data + max_size - sizeof (eh_copy_t));
|
||||
d0 = (eh_copy_t *)(((u8 *)packet0) - sizeof (eh_copy_t));
|
||||
eh_copy_t *s0, *d0, *s1, *d1;
|
||||
s0 = (eh_copy_t *) (h0->data + max_size - sizeof (eh_copy_t));
|
||||
d0 = (eh_copy_t *) (((u8 *) packet0) - sizeof (eh_copy_t));
|
||||
clib_memcpy (d0, s0, sizeof (eh_copy_t));
|
||||
s1 = (eh_copy_t *)(h1->data + max_size - sizeof (eh_copy_t));
|
||||
d1 = (eh_copy_t *)(((u8 *)packet1) - sizeof (eh_copy_t));
|
||||
s1 = (eh_copy_t *) (h1->data + max_size - sizeof (eh_copy_t));
|
||||
d1 = (eh_copy_t *) (((u8 *) packet1) - sizeof (eh_copy_t));
|
||||
clib_memcpy (d1, s1, sizeof (eh_copy_t));
|
||||
return;
|
||||
}
|
||||
@@ -221,19 +219,19 @@ _vnet_rewrite_two_headers (vnet_rewrite_header_t * h0,
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
_ (4);
|
||||
_ (3);
|
||||
_ (2);
|
||||
_ (1);
|
||||
_(4);
|
||||
_(3);
|
||||
_(2);
|
||||
_(1);
|
||||
|
||||
#undef _
|
||||
|
||||
|
||||
n_left0 = (int)
|
||||
(((int) h0->data_bytes - most_likely_size) + (sizeof(rw0[0])-1))
|
||||
/ (int) sizeof (rw0[0]);
|
||||
(((int) h0->data_bytes - most_likely_size) + (sizeof (rw0[0]) - 1))
|
||||
/ (int) sizeof (rw0[0]);
|
||||
n_left1 = (int)
|
||||
(((int) h1->data_bytes - most_likely_size) + (sizeof(rw1[0])-1))
|
||||
/ (int) sizeof (rw1[0]);
|
||||
(((int) h1->data_bytes - most_likely_size) + (sizeof (rw1[0]) - 1))
|
||||
/ (int) sizeof (rw1[0]);
|
||||
|
||||
if (PREDICT_FALSE (n_left0 > 0 || n_left1 > 0))
|
||||
{
|
||||
@@ -254,21 +252,20 @@ _vnet_rewrite_two_headers (vnet_rewrite_header_t * h0,
|
||||
(most_likely_size))
|
||||
|
||||
#define VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST ((void *) 0)
|
||||
void vnet_rewrite_for_sw_interface (struct vnet_main_t * vnm,
|
||||
void vnet_rewrite_for_sw_interface (struct vnet_main_t *vnm,
|
||||
vnet_l3_packet_type_t packet_type,
|
||||
u32 sw_if_index,
|
||||
u32 node_index,
|
||||
void * dst_address,
|
||||
void *dst_address,
|
||||
vnet_rewrite_header_t * rw,
|
||||
u32 max_rewrite_bytes);
|
||||
|
||||
void vnet_rewrite_for_tunnel (struct vnet_main_t * vnm,
|
||||
u32 tx_sw_if_index,
|
||||
u32 rewrite_node_index,
|
||||
u32 post_rewrite_node_index,
|
||||
vnet_rewrite_header_t * rw,
|
||||
u8 *rewrite_data,
|
||||
u32 rewrite_length);
|
||||
void vnet_rewrite_for_tunnel (struct vnet_main_t *vnm,
|
||||
u32 tx_sw_if_index,
|
||||
u32 rewrite_node_index,
|
||||
u32 post_rewrite_node_index,
|
||||
vnet_rewrite_header_t * rw,
|
||||
u8 * rewrite_data, u32 rewrite_length);
|
||||
|
||||
/* Parser for unformat header & rewrite string. */
|
||||
unformat_function_t unformat_vnet_rewrite;
|
||||
@@ -279,3 +276,11 @@ format_function_t format_vnet_rewrite_header;
|
||||
serialize_function_t serialize_vnet_rewrite, unserialize_vnet_rewrite;
|
||||
|
||||
#endif /* included_vnet_rewrite_h */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
+20
-10
@@ -42,7 +42,8 @@
|
||||
|
||||
#include <vppinfra/types.h>
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
VNET_UNICAST,
|
||||
VNET_MULTICAST,
|
||||
VNET_N_CAST,
|
||||
@@ -55,27 +56,28 @@ typedef enum {
|
||||
#include <vnet/rewrite.h>
|
||||
#include <vnet/api_errno.h>
|
||||
|
||||
typedef struct vnet_main_t {
|
||||
typedef struct vnet_main_t
|
||||
{
|
||||
u32 local_interface_hw_if_index;
|
||||
u32 local_interface_sw_if_index;
|
||||
|
||||
vnet_interface_main_t interface_main;
|
||||
|
||||
/* set up by constructors */
|
||||
vnet_device_class_t * device_class_registrations;
|
||||
vnet_hw_interface_class_t * hw_interface_class_registrations;
|
||||
_vnet_interface_function_list_elt_t * hw_interface_add_del_functions;
|
||||
_vnet_interface_function_list_elt_t * hw_interface_link_up_down_functions;
|
||||
_vnet_interface_function_list_elt_t * sw_interface_add_del_functions;
|
||||
_vnet_interface_function_list_elt_t * sw_interface_admin_up_down_functions;
|
||||
vnet_device_class_t *device_class_registrations;
|
||||
vnet_hw_interface_class_t *hw_interface_class_registrations;
|
||||
_vnet_interface_function_list_elt_t *hw_interface_add_del_functions;
|
||||
_vnet_interface_function_list_elt_t *hw_interface_link_up_down_functions;
|
||||
_vnet_interface_function_list_elt_t *sw_interface_add_del_functions;
|
||||
_vnet_interface_function_list_elt_t *sw_interface_admin_up_down_functions;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Last "api" error, preserved so we can issue reasonable diagnostics
|
||||
* at or near the top of the food chain
|
||||
*/
|
||||
vnet_api_error_t api_errno;
|
||||
|
||||
vlib_main_t * vlib_main;
|
||||
vlib_main_t *vlib_main;
|
||||
} vnet_main_t;
|
||||
|
||||
vnet_main_t vnet_main;
|
||||
@@ -85,3 +87,11 @@ vnet_main_t **vnet_mains;
|
||||
#include <vnet/global_funcs.h>
|
||||
|
||||
#endif /* included_vnet_vnet_h */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user