diff options
author | Maxime Peim <mpeim@cisco.com> | 2023-06-19 18:19:48 +0200 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2023-06-22 12:39:35 +0000 |
commit | fdf6fbe2e771d88beddb6ca8d8bbd39599beeb9c (patch) | |
tree | 0e2c781b36f8e169e5393a7aa68802dc964b32c9 /src/vnet/tcp/tcp_format.c | |
parent | 9ba6dcf558eeb876f863e13e6250c13341a2a3f0 (diff) |
tcp: options support into pg
Packet-generator does not support TCP options.
Along with its support, a formatting function has been added.
Further work will be needed to update header formatting functions
to take into account TCP connection options. For now, TCP options
are taken on a per-packet basis.
Type: improvement
Change-Id: Id800887853c4941d893be353ce6d8624ed8bbc5d
Signed-off-by: Maxime Peim <mpeim@cisco.com>
Diffstat (limited to 'src/vnet/tcp/tcp_format.c')
-rw-r--r-- | src/vnet/tcp/tcp_format.c | 87 |
1 files changed, 61 insertions, 26 deletions
diff --git a/src/vnet/tcp/tcp_format.c b/src/vnet/tcp/tcp_format.c index a3245f2046a..751042ce1cd 100644 --- a/src/vnet/tcp/tcp_format.c +++ b/src/vnet/tcp/tcp_format.c @@ -52,12 +52,68 @@ format_tcp_flags (u8 * s, va_list * args) return s; } +u8 * +format_tcp_options (u8 *s, va_list *args) +{ + tcp_options_t *opts = va_arg (*args, tcp_options_t *); + u32 indent, n_opts = 0; + int i; + + if (!opts->flags) + return s; + + indent = format_get_indent (s); + indent += 2; + + s = format (s, "options:\n%U", format_white_space, indent); + + if (tcp_opts_mss (opts)) + { + s = format (s, "mss %d", opts->mss); + n_opts++; + } + if (tcp_opts_wscale (opts)) + { + s = format (s, "%swindow scale %d", n_opts > 0 ? ", " : "", + format_white_space, indent, opts->wscale); + n_opts++; + } + if (tcp_opts_tstamp (opts)) + { + s = format (s, "%stimestamp %d, echo/reflected timestamp", + n_opts > 0 ? ", " : "", format_white_space, indent, + opts->tsval, opts->tsecr); + n_opts++; + } + if (tcp_opts_sack_permitted (opts)) + { + s = format (s, "%ssack permitted", n_opts > 0 ? ", " : "", + format_white_space, indent); + n_opts++; + } + if (tcp_opts_sack (opts)) + { + s = format (s, "%ssacks:", n_opts > 0 ? ", " : "", format_white_space, + indent); + for (i = 0; i < opts->n_sack_blocks; ++i) + { + s = format (s, "\n%Ublock %d: start %d, end %d", format_white_space, + indent + 2, i + 1, opts->sacks[i].start, + opts->sacks[i].end); + } + n_opts++; + } + + return s; +} + /* Format TCP header. */ u8 * format_tcp_header (u8 * s, va_list * args) { tcp_header_t *tcp = va_arg (*args, tcp_header_t *); u32 max_header_bytes = va_arg (*args, u32); + tcp_options_t opts = { .flags = 0 }; u32 header_bytes; u32 indent; @@ -83,32 +139,11 @@ format_tcp_header (u8 * s, va_list * args) clib_net_to_host_u16 (tcp->window), clib_net_to_host_u16 (tcp->checksum)); - -#if 0 - /* Format TCP options. */ - { - u8 *o; - u8 *option_start = (void *) (tcp + 1); - u8 *option_end = (void *) tcp + header_bytes; - - for (o = option_start; o < option_end;) - { - u32 length = o[1]; - switch (o[0]) - { - case TCP_OPTION_END: - length = 1; - o = option_end; - break; - - case TCP_OPTION_NOOP: - length = 1; - break; - - } - } - } -#endif + if (tcp_options_parse (tcp, &opts, tcp_is_syn (tcp)) < 0) + s = format (s, "\n%Uoptions: parsing failed", format_white_space, indent); + else + s = format (s, "\n%U%U", format_white_space, indent, format_tcp_options, + &opts); /* Recurse into next protocol layer. */ if (max_header_bytes != 0 && header_bytes < max_header_bytes) |