X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fpg%2Fstream.c;h=0ce640bf13fad911836af504b2149e3c1d689947;hb=36f7a6aeb021a549f2d684868303c9891bc0dd00;hp=c91cacafe5702e16796a85f40ef3e2b1d8d48fb7;hpb=4222347a87994cc109499ebe67498792c0e705f8;p=vpp.git diff --git a/src/vnet/pg/stream.c b/src/vnet/pg/stream.c index c91cacafe57..0ce640bf13f 100644 --- a/src/vnet/pg/stream.c +++ b/src/vnet/pg/stream.c @@ -139,6 +139,39 @@ pg_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) return 0; } +static int +pg_mac_address_cmp (const mac_address_t * m1, const mac_address_t * m2) +{ + return (!mac_address_cmp (m1, m2)); +} + +static clib_error_t * +pg_add_del_mac_address (vnet_hw_interface_t * hi, + const u8 * address, u8 is_add) +{ + pg_main_t *pg = &pg_main; + + if (ethernet_address_cast (address)) + { + mac_address_t mac; + pg_interface_t *pi; + + pi = pool_elt_at_index (pg->interfaces, hi->dev_instance); + + mac_address_from_bytes (&mac, address); + if (is_add) + vec_add1 (pi->allowed_mcast_macs, mac); + else + { + u32 pos = vec_search_with_function (pi->allowed_mcast_macs, &mac, + pg_mac_address_cmp); + if (~0 != pos) + vec_del1 (pi->allowed_mcast_macs, pos); + } + } + return (NULL); +} + /* *INDENT-OFF* */ VNET_DEVICE_CLASS (pg_dev_class) = { .name = "pg", @@ -146,6 +179,7 @@ VNET_DEVICE_CLASS (pg_dev_class) = { .format_device_name = format_pg_interface_name, .format_tx_trace = format_pg_output_trace, .admin_up_down_function = pg_interface_admin_up_down, + .mac_addr_add_del_function = pg_add_del_mac_address, }; /* *INDENT-ON* */ @@ -178,8 +212,26 @@ pg_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags) return 0; } +void +pg_interface_enable_disable_coalesce (pg_interface_t * pi, u8 enable, + u32 tx_node_index) +{ + if (enable) + { + gro_flow_table_init (&pi->flow_table, 1 /* is_l2 */ , + tx_node_index); + pi->coalesce_enabled = 1; + } + else + { + pi->coalesce_enabled = 0; + gro_flow_table_free (pi->flow_table); + } +} + u32 -pg_interface_add_or_get (pg_main_t * pg, uword if_id) +pg_interface_add_or_get (pg_main_t * pg, uword if_id, u8 gso_enabled, + u32 gso_size, u8 coalesce_enabled) { vnet_main_t *vnm = vnet_get_main (); vlib_main_t *vm = vlib_get_main (); @@ -213,10 +265,23 @@ pg_interface_add_or_get (pg_main_t * pg, uword 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); + if (gso_enabled) + { + hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO; + pi->gso_enabled = 1; + pi->gso_size = gso_size; + if (coalesce_enabled) + { + pg_interface_enable_disable_coalesce (pi, 1, hi->tx_node_index); + } + } pi->sw_if_index = hi->sw_if_index; hash_set (pg->if_index_by_if_id, if_id, i); + vec_validate (pg->if_id_by_sw_if_index, hi->sw_if_index); + pg->if_id_by_sw_if_index[hi->sw_if_index] = i; + if (vlib_num_workers ()) { pi->lockp = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, @@ -437,7 +502,7 @@ pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) { int n; - s->buffer_bytes = VLIB_BUFFER_DATA_SIZE; + s->buffer_bytes = vlib_buffer_get_default_data_size (vm); n = s->max_packet_bytes / s->buffer_bytes; n += (s->max_packet_bytes % s->buffer_bytes) != 0; @@ -445,18 +510,20 @@ pg_stream_add (pg_main_t * pg, pg_stream_t * s_init) } /* Find an interface to use. */ - s->pg_if_index = pg_interface_add_or_get (pg, s->if_id); + s->pg_if_index = + pg_interface_add_or_get (pg, s->if_id, 0 /* gso_enabled */ , + 0 /* gso_size */ , 0 /* coalesce_enabled */ ); - { - 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[VLIB_RX] == ~0) { - if (s->sw_if_index[rx_or_tx] == ~0) - s->sw_if_index[rx_or_tx] = pi->sw_if_index; + pg_interface_t *pi = pool_elt_at_index (pg->interfaces, s->pg_if_index); + /* + * Default the RX interface if unset. It's a bad mistake to + * set [VLIB_TX] prior to ip lookup, since the ip lookup code + * interprets [VLIB_TX] as a fib index... + */ + s->sw_if_index[VLIB_RX] = pi->sw_if_index; } - } /* Connect the graph. */ s->next_index = vlib_node_add_next (vm, device_input_node.index,