summaryrefslogtreecommitdiffstats
path: root/src/vnet/pg/stream.c
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2024-07-05 14:09:35 +0200
committerDave Wallace <dwallacelf@gmail.com>2024-12-12 14:45:14 +0000
commit8fadde6f0154a735dce2624d56b36bf2276b6a7f (patch)
tree0ea12e83c4d2d546df9142ec0e65f03f5bf3e044 /src/vnet/pg/stream.c
parent504a7d1c93a2f73023d2552a49df0d6d43970830 (diff)
pg: misc improvements and fixes
1) pg can typically injects packets in ethernet-input, ip4-input or ip6-input. Make sure offload offsets are correctly set for ip4-input and ip6-input. 2) add hw-addr support for ethernet mode (only available through cli) 3) refactor pg creation code to improve the readability by using data structure pg_interface_args_t 4) fix the pg input and output traces to use headers according to pg interface mode 5) introduce pg interface flags i.e. checksum, gso, gro Type: improvement Change-Id: Iffed502e9c6357d7ef8e8a72217867e8297236aa Signed-off-by: Benoît Ganne <bganne@cisco.com> Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Diffstat (limited to 'src/vnet/pg/stream.c')
-rw-r--r--src/vnet/pg/stream.c74
1 files changed, 39 insertions, 35 deletions
diff --git a/src/vnet/pg/stream.c b/src/vnet/pg/stream.c
index 440e285031a..31a41e8cc88 100644
--- a/src/vnet/pg/stream.c
+++ b/src/vnet/pg/stream.c
@@ -105,9 +105,16 @@ format_pg_output_trace (u8 * s, va_list * va)
s = format (s, "%Ubuffer 0x%x: %U", format_white_space, indent,
t->buffer_index, format_vnet_buffer_no_chain, &t->buffer);
- s = format (s, "\n%U%U", format_white_space, indent,
- format_ethernet_header_with_length, t->buffer.pre_data,
- sizeof (t->buffer.pre_data));
+ if (t->mode == PG_MODE_IP4)
+ s = format (s, "\n%U%U", format_white_space, indent, format_ip4_header,
+ t->buffer.pre_data, sizeof (t->buffer.pre_data));
+ else if (t->mode == PG_MODE_IP6)
+ s = format (s, "\n%U%U", format_white_space, indent, format_ip6_header,
+ t->buffer.pre_data, sizeof (t->buffer.pre_data));
+ else
+ s = format (s, "\n%U%U", format_white_space, indent,
+ format_ethernet_header_with_length, t->buffer.pre_data,
+ sizeof (t->buffer.pre_data));
return s;
}
@@ -245,18 +252,15 @@ VNET_HW_INTERFACE_CLASS (pg_tun_hw_interface_class) = {
};
u32
-pg_interface_add_or_get (pg_main_t *pg, u32 if_id, u8 gso_enabled,
- u32 gso_size, u8 coalesce_enabled,
- pg_interface_mode_t mode)
+pg_interface_add_or_get (pg_main_t *pg, pg_interface_args_t *args)
{
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;
- p = hash_get (pg->if_index_by_if_id, if_id);
+ p = hash_get (pg->if_index_by_if_id, args->if_id);
if (p)
{
@@ -264,32 +268,26 @@ pg_interface_add_or_get (pg_main_t *pg, u32 if_id, u8 gso_enabled,
}
else
{
- vnet_eth_interface_registration_t eir = {};
- 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_fast (hw_addr + 2, &rnd, sizeof (rnd));
- hw_addr[0] = 2;
- hw_addr[1] = 0xfe;
-
- pi->id = if_id;
- pi->mode = mode;
+ pi->id = args->if_id;
+ pi->mode = args->mode;
switch (pi->mode)
{
case PG_MODE_ETHERNET:
- eir.dev_class_index = pg_dev_class.index;
- eir.dev_instance = i;
- eir.address = hw_addr;
- eir.cb.flag_change = pg_eth_flag_change;
- pi->hw_if_index = vnet_eth_register_interface (vnm, &eir);
- break;
+ {
+ vnet_eth_interface_registration_t eir = { 0 };
+ if (!args->hw_addr_set)
+ ethernet_mac_address_generate (args->hw_addr.bytes);
+ clib_memcpy (pi->hw_addr.bytes, args->hw_addr.bytes, 6);
+ eir.dev_class_index = pg_dev_class.index;
+ eir.dev_instance = i;
+ eir.address = pi->hw_addr.bytes;
+ eir.cb.flag_change = pg_eth_flag_change;
+ pi->hw_if_index = vnet_eth_register_interface (vnm, &eir);
+ break;
+ }
case PG_MODE_IP4:
case PG_MODE_IP6:
pi->hw_if_index = vnet_register_interface (
@@ -297,19 +295,19 @@ pg_interface_add_or_get (pg_main_t *pg, u32 if_id, u8 gso_enabled,
break;
}
hi = vnet_get_hw_interface (vnm, pi->hw_if_index);
- if (gso_enabled)
+ if (args->flags & PG_INTERFACE_FLAG_GSO)
{
vnet_hw_if_set_caps (vnm, pi->hw_if_index, VNET_HW_IF_CAP_TCP_GSO);
pi->gso_enabled = 1;
- pi->gso_size = gso_size;
- if (coalesce_enabled)
+ pi->gso_size = args->gso_size;
+ if (args->flags & PG_INTERFACE_FLAG_GRO_COALESCE)
{
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);
+ hash_set (pg->if_index_by_if_id, pi->id, i);
vec_validate (pg->if_index_by_sw_if_index, hi->sw_if_index);
pg->if_index_by_sw_if_index[hi->sw_if_index] = i;
@@ -585,10 +583,16 @@ pg_stream_add (pg_main_t * pg, pg_stream_t * s_init)
vec_resize (s->buffer_indices, n);
}
+ pg_interface_args_t args = {
+ .if_id = s->if_id,
+ .mode = PG_MODE_ETHERNET,
+ .flags = 0, /* gso_enabled and coalesce_enabled */
+ .gso_size = 0, /* gso_size */
+ .hw_addr_set = 0, /* mac address set */
+ };
+
/* Find an interface to use. */
- s->pg_if_index = pg_interface_add_or_get (
- pg, s->if_id, 0 /* gso_enabled */, 0 /* gso_size */,
- 0 /* coalesce_enabled */, PG_MODE_ETHERNET);
+ s->pg_if_index = pg_interface_add_or_get (pg, &args);
if (s->sw_if_index[VLIB_RX] == ~0)
{