X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Fpg%2Fstream.c;h=b66fb742ab418a90347860576d35b4bcd26d0463;hb=0bfe5d8c792abcdbcf27bfcc7b7b353fba04aee2;hp=1dd5624338fa9116657e90edb55e1422a55e85d9;hpb=cb9cadad578297ffd78fa8a33670bdf1ab669e7e;p=vpp.git diff --git a/vnet/vnet/pg/stream.c b/vnet/vnet/pg/stream.c index 1dd5624338f..b66fb742ab4 100644 --- a/vnet/vnet/pg/stream.c +++ b/vnet/vnet/pg/stream.c @@ -39,40 +39,43 @@ #include #include +#include +#include +#include /* Mark stream active or inactive. */ -void pg_stream_enable_disable (pg_main_t * pg, pg_stream_t * s, int want_enabled) +void +pg_stream_enable_disable (pg_main_t * pg, pg_stream_t * s, int want_enabled) { - vnet_main_t * vnm = vnet_get_main(); - pg_interface_t * pi = vec_elt_at_index (pg->interfaces, s->pg_if_index); + vnet_main_t *vnm = vnet_get_main (); + pg_interface_t *pi = pool_elt_at_index (pg->interfaces, s->pg_if_index); want_enabled = want_enabled != 0; if (pg_stream_is_enabled (s) == want_enabled) /* No change necessary. */ return; - + if (want_enabled) s->n_packets_generated = 0; /* Toggle enabled flag. */ s->flags ^= PG_STREAM_FLAGS_IS_ENABLED; - ASSERT (! pool_is_free (pg->streams, s)); + ASSERT (!pool_is_free (pg->streams, s)); pg->enabled_streams = clib_bitmap_set (pg->enabled_streams, s - pg->streams, want_enabled); - vnet_hw_interface_set_flags (vnm, pi->hw_if_index, - (want_enabled - ? VNET_HW_INTERFACE_FLAG_LINK_UP - : 0)); + if (want_enabled) + { + vnet_hw_interface_set_flags (vnm, pi->hw_if_index, + VNET_HW_INTERFACE_FLAG_LINK_UP); + + vnet_sw_interface_set_flags (vnm, pi->sw_if_index, + VNET_SW_INTERFACE_FLAG_ADMIN_UP); + } - vnet_sw_interface_set_flags (vnm, pi->sw_if_index, - (want_enabled - ? VNET_SW_INTERFACE_FLAG_ADMIN_UP - : 0)); - vlib_node_set_state (pg->vlib_main, pg_input_node.index, (clib_bitmap_is_zero (pg->enabled_streams) @@ -83,32 +86,48 @@ void pg_stream_enable_disable (pg_main_t * pg, pg_stream_t * s, int want_enabled s->time_last_generate = 0; } -static u8 * format_pg_interface_name (u8 * s, va_list * args) +static u8 * +format_pg_interface_name (u8 * s, va_list * args) { - pg_main_t * pg = &pg_main; + pg_main_t *pg = &pg_main; u32 if_index = va_arg (*args, u32); - pg_interface_t * pi; + pg_interface_t *pi; - pi = vec_elt_at_index (pg->interfaces, if_index); - s = format (s, "pg/stream-%d", pi->stream_index); + pi = pool_elt_at_index (pg->interfaces, if_index); + s = format (s, "pg%d", pi->id); return s; } -VNET_DEVICE_CLASS (pg_dev_class,static) = { +static clib_error_t * +pg_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) +{ + u32 hw_flags = 0; + + if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) + hw_flags = VNET_HW_INTERFACE_FLAG_LINK_UP; + + vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags); + + return 0; +} + +/* *INDENT-OFF* */ +VNET_DEVICE_CLASS (pg_dev_class) = { .name = "pg", .tx_function = pg_output, .format_device_name = format_pg_interface_name, + .admin_up_down_function = pg_interface_admin_up_down, }; +/* *INDENT-ON* */ -static uword pg_set_rewrite (vnet_main_t * vnm, - u32 sw_if_index, - u32 l3_type, - void * dst_address, - void * rewrite, - uword max_rewrite_bytes) +static uword +pg_set_rewrite (vnet_main_t * vnm, + u32 sw_if_index, + u32 l3_type, + void *dst_address, void *rewrite, uword max_rewrite_bytes) { - u16 * h = rewrite; + u16 *h = rewrite; if (max_rewrite_bytes < sizeof (h[0])) return 0; @@ -117,48 +136,73 @@ static uword pg_set_rewrite (vnet_main_t * vnm, return sizeof (h[0]); } +/* *INDENT-OFF* */ VNET_HW_INTERFACE_CLASS (pg_interface_class,static) = { .name = "Packet generator", .set_rewrite = pg_set_rewrite, }; +/* *INDENT-ON* */ -u32 pg_interface_find_free (pg_main_t * pg, uword stream_index) +static u32 +pg_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags) { - vnet_main_t * vnm = vnet_get_main(); - pg_interface_t * pi; - vnet_hw_interface_t * hi; - u32 i, l; + /* nothing for now */ + return 0; +} + +u32 +pg_interface_add_or_get (pg_main_t * pg, uword if_id) +{ + vnet_main_t *vnm = vnet_get_main (); + vlib_main_t *vm = vlib_get_main (); + pg_interface_t *pi; + vnet_hw_interface_t *hi; + uword *p; + u32 i; - if ((l = vec_len (pg->free_interfaces)) > 0) + p = hash_get (pg->if_index_by_if_id, if_id); + + if (p) { - i = pg->free_interfaces[l - 1]; - _vec_len (pg->free_interfaces) = l - 1; - pi = vec_elt_at_index (pg->interfaces, i); - pi->stream_index = stream_index; - } + return p[0]; + } else { - i = vec_len (pg->interfaces); - vec_add2 (pg->interfaces, pi, 1); - - pi->stream_index = stream_index; - pi->hw_if_index = vnet_register_interface (vnm, - pg_dev_class.index, i, - pg_interface_class.index, stream_index); + u8 hw_addr[6]; + f64 now = vlib_time_now (vm); + u32 rnd; + + pool_get (pg->interfaces, pi); + i = pi - pg->interfaces; + + rnd = (u32) (now * 1e6); + rnd = random_u32 (&rnd); + clib_memcpy (hw_addr + 2, &rnd, sizeof (rnd)); + hw_addr[0] = 2; + hw_addr[1] = 0xfe; + + pi->id = if_id; + ethernet_register_interface (vnm, pg_dev_class.index, i, hw_addr, + &pi->hw_if_index, pg_eth_flag_change); hi = vnet_get_hw_interface (vnm, pi->hw_if_index); pi->sw_if_index = hi->sw_if_index; + + hash_set (pg->if_index_by_if_id, if_id, i); + + ip4_sw_interface_enable_disable (pi->hw_if_index, 1); + ip6_sw_interface_enable_disable (pi->hw_if_index, 1); + mpls_sw_interface_enable_disable (&mpls_main, pi->hw_if_index, 1); } return i; } -static void do_edit (pg_stream_t * stream, - pg_edit_group_t * g, - pg_edit_t * e, - uword want_commit) +static void +do_edit (pg_stream_t * stream, + pg_edit_group_t * g, pg_edit_t * e, uword want_commit) { u32 i, i0, i1, mask, n_bits_left; - u8 * v, * s, * m; + u8 *v, *s, *m; i0 = e->lsb_bit_offset / BITS (u8); @@ -179,11 +223,11 @@ static void do_edit (pg_stream_t * stream, break; } - if (want_commit) - { - ASSERT(e->type != PG_EDIT_INVALID_TYPE); - vec_add1 (g->non_fixed_edits, e[0]); - } + if (want_commit) + { + ASSERT (e->type != PG_EDIT_INVALID_TYPE); + vec_add1 (g->non_fixed_edits, e[0]); + } return; } @@ -206,7 +250,7 @@ static void do_edit (pg_stream_t * stream, ASSERT (i0 < vec_len (s)); ASSERT (i < vec_len (v)); - ASSERT ((v[i] &~ mask) == 0); + ASSERT ((v[i] & ~mask) == 0); s[i0] |= v[i] & mask; m[i0] |= mask; @@ -237,7 +281,7 @@ static void do_edit (pg_stream_t * stream, ASSERT (i0 < vec_len (s)); ASSERT (i < vec_len (v)); - ASSERT ((v[i] &~ mask) == 0); + ASSERT ((v[i] & ~mask) == 0); s[i0] |= v[i] & mask; m[i0] |= mask; @@ -247,73 +291,73 @@ static void do_edit (pg_stream_t * stream, pg_edit_free (e); } -void pg_edit_group_get_fixed_packet_data (pg_stream_t * s, - u32 group_index, - void * packet_data, - void * packet_data_mask) +void +pg_edit_group_get_fixed_packet_data (pg_stream_t * s, + u32 group_index, + void *packet_data, + void *packet_data_mask) { - pg_edit_group_t * g = pg_stream_get_group (s, group_index); - pg_edit_t * e; + pg_edit_group_t *g = pg_stream_get_group (s, group_index); + pg_edit_t *e; - vec_foreach (e, g->edits) - do_edit (s, g, e, /* want_commit */ 0); + vec_foreach (e, g->edits) do_edit (s, g, e, /* want_commit */ 0); - memcpy (packet_data, g->fixed_packet_data, vec_len (g->fixed_packet_data)); - memcpy (packet_data_mask, g->fixed_packet_data_mask, vec_len (g->fixed_packet_data_mask)); + clib_memcpy (packet_data, g->fixed_packet_data, + vec_len (g->fixed_packet_data)); + clib_memcpy (packet_data_mask, g->fixed_packet_data_mask, + vec_len (g->fixed_packet_data_mask)); } -static void perform_fixed_edits (pg_stream_t * s) +static void +perform_fixed_edits (pg_stream_t * s) { - pg_edit_group_t * g; - pg_edit_t * e; + pg_edit_group_t *g; + pg_edit_t *e; word i; for (i = vec_len (s->edit_groups) - 1; i >= 0; i--) { g = vec_elt_at_index (s->edit_groups, i); - vec_foreach (e, g->edits) - do_edit (s, g, e, /* want_commit */ 1); + vec_foreach (e, g->edits) do_edit (s, g, e, /* want_commit */ 1); /* All edits have either been performed or added to - g->non_fixed_edits. So, we can delete the vector. */ + g->non_fixed_edits. So, we can delete the vector. */ vec_free (g->edits); } vec_free (s->fixed_packet_data_mask); vec_free (s->fixed_packet_data); vec_foreach (g, s->edit_groups) - { - int i; - g->start_byte_offset = vec_len (s->fixed_packet_data); - - /* Relocate and copy non-fixed edits from group to stream. */ - vec_foreach (e, g->non_fixed_edits) - e->lsb_bit_offset += g->start_byte_offset * BITS (u8); - - for (i = 0; i < vec_len (g->non_fixed_edits); i++) - ASSERT(g->non_fixed_edits[i].type != PG_EDIT_INVALID_TYPE); - - vec_add (s->non_fixed_edits, - g->non_fixed_edits, - vec_len (g->non_fixed_edits)); - vec_free (g->non_fixed_edits); - - vec_add (s->fixed_packet_data, - g->fixed_packet_data, - vec_len (g->fixed_packet_data)); - vec_add (s->fixed_packet_data_mask, - g->fixed_packet_data_mask, - vec_len (g->fixed_packet_data_mask)); - } + { + int i; + g->start_byte_offset = vec_len (s->fixed_packet_data); + + /* Relocate and copy non-fixed edits from group to stream. */ + vec_foreach (e, g->non_fixed_edits) + e->lsb_bit_offset += g->start_byte_offset * BITS (u8); + + for (i = 0; i < vec_len (g->non_fixed_edits); i++) + ASSERT (g->non_fixed_edits[i].type != PG_EDIT_INVALID_TYPE); + + vec_add (s->non_fixed_edits, + g->non_fixed_edits, vec_len (g->non_fixed_edits)); + vec_free (g->non_fixed_edits); + + vec_add (s->fixed_packet_data, + g->fixed_packet_data, vec_len (g->fixed_packet_data)); + vec_add (s->fixed_packet_data_mask, + g->fixed_packet_data_mask, vec_len (g->fixed_packet_data_mask)); + } } -void pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) +void +pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) { - vlib_main_t * vm = pg->vlib_main; - pg_stream_t * s; - uword * p; + vlib_main_t *vm = pg->vlib_main; + pg_stream_t *s; + uword *p; - if (! pg->stream_index_by_name) + if (!pg->stream_index_by_name) pg->stream_index_by_name = hash_create_vec (0, sizeof (s->name[0]), sizeof (uword)); @@ -328,7 +372,7 @@ void pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) s[0] = s_init[0]; /* Give it a name. */ - if (! s->name) + if (!s->name) s->name = format (0, "stream%d", s - pg->streams); else s->name = vec_dup (s->name); @@ -336,7 +380,8 @@ void pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) hash_set_mem (pg->stream_index_by_name, s->name, s - pg->streams); /* Get fixed part of buffer data. */ - perform_fixed_edits (s); + if (s->edit_groups) + perform_fixed_edits (s); /* Determine packet size. */ switch (s->packet_size_edit_type) @@ -350,18 +395,19 @@ void pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) default: /* Get packet size from fixed edits. */ s->packet_size_edit_type = PG_EDIT_FIXED; - if (! s->replay_packet_templates) - s->min_packet_bytes = s->max_packet_bytes = vec_len (s->fixed_packet_data); + if (!s->replay_packet_templates) + s->min_packet_bytes = s->max_packet_bytes = + vec_len (s->fixed_packet_data); break; } s->last_increment_packet_size = s->min_packet_bytes; { - pg_buffer_index_t * bi; + pg_buffer_index_t *bi; int n; - if (! s->buffer_bytes) + if (!s->buffer_bytes) s->buffer_bytes = s->max_packet_bytes; s->buffer_bytes = vlib_buffer_round_size (s->buffer_bytes); @@ -375,46 +421,56 @@ void pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) bi->free_list_index = vlib_buffer_create_free_list (vm, s->buffer_bytes, "pg stream %d buffer #%d", s - pg->streams, - 1 + (bi - s->buffer_indices)); + 1 + (bi - + s-> + buffer_indices)); } /* Find an interface to use. */ - s->pg_if_index = pg_interface_find_free (pg, s - pg->streams); + s->pg_if_index = pg_interface_add_or_get (pg, s->if_id); { - pg_interface_t * pi = vec_elt_at_index (pg->interfaces, s->pg_if_index); + pg_interface_t *pi = pool_elt_at_index (pg->interfaces, s->pg_if_index); vlib_rx_or_tx_t rx_or_tx; vlib_foreach_rx_tx (rx_or_tx) - { - if (s->sw_if_index[rx_or_tx] == ~0) - s->sw_if_index[rx_or_tx] = pi->sw_if_index; - } + { + if (s->sw_if_index[rx_or_tx] == ~0) + s->sw_if_index[rx_or_tx] = pi->sw_if_index; + } } /* Connect the graph. */ s->next_index = vlib_node_add_next (vm, pg_input_node.index, s->node_index); } -void pg_stream_del (pg_main_t * pg, uword index) +void +pg_stream_del (pg_main_t * pg, uword index) { - vlib_main_t * vm = pg->vlib_main; - pg_stream_t * s; - pg_buffer_index_t * bi; + vlib_main_t *vm = pg->vlib_main; + pg_stream_t *s; + pg_buffer_index_t *bi; s = pool_elt_at_index (pg->streams, index); pg_stream_enable_disable (pg, s, /* want_enabled */ 0); - vec_add1 (pg->free_interfaces, s->pg_if_index); hash_unset_mem (pg->stream_index_by_name, s->name); vec_foreach (bi, s->buffer_indices) - { - vlib_buffer_delete_free_list (vm, bi->free_list_index); - clib_fifo_free (bi->buffer_fifo); - } + { + vlib_buffer_delete_free_list (vm, bi->free_list_index); + clib_fifo_free (bi->buffer_fifo); + } pg_stream_free (s); pool_put (pg->streams, s); } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */