diff options
author | Dave Barach <dave@barachs.net> | 2017-04-20 17:50:39 -0400 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2017-04-24 13:24:58 +0000 |
commit | 636815199a1f359fdd0da706985a74eca95254da (patch) | |
tree | 8d613f317624127fdd8ba42097fb60f1347bbb60 /src/vnet/tcp/tcp_test.c | |
parent | b68ad1e99fb65f7ddb4a3211b47173f8c89b29c4 (diff) |
Debug CLI to magically create / delete a TCP session
The session ends up in established state, and is hand-crafted to look
like it was created by the builtin_server.
This will come in handy for injecting packets into tcp46-established,
along with ancillary debug CLI to adjust connection parameters.
Immediate applications include screwball window cases, out of order
segments, paws checking, and so on and so forth.
Debug CLI script:
loop create
set int ip address loop0 6.0.1.1/8
set int state loop0 up
set ip arp loop0 6.0.1.2 feed.face.babe
test tcp server
test tcp session
packet-generator new {
name tcp
limit 1
node ip4-input
size 100-100
interface loop0
no-recycle
data {
TCP: 6.0.1.2 -> 6.0.1.1
TCP: 11234 -> 1234
ACK window 2000
seqnum 0
acknum 0
incrementing 100
}
}
Change-Id: I866c2159376064b7d14f70531022c1fe949258c2
Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vnet/tcp/tcp_test.c')
-rw-r--r-- | src/vnet/tcp/tcp_test.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/src/vnet/tcp/tcp_test.c b/src/vnet/tcp/tcp_test.c index 0146154b742..d65ce1beeba 100644 --- a/src/vnet/tcp/tcp_test.c +++ b/src/vnet/tcp/tcp_test.c @@ -895,6 +895,68 @@ tcp_test_fifo (vlib_main_t * vm, unformat_input_t * input) return res; } +static int +tcp_test_session (vlib_main_t * vm, unformat_input_t * input) +{ + int rv = 0; + tcp_connection_t *tc0; + u8 sst = SESSION_TYPE_IP4_TCP; + ip4_address_t local, remote; + u16 local_port, remote_port; + tcp_main_t *tm = vnet_get_tcp_main (); + int is_add = 1; + + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "del")) + is_add = 0; + else if (unformat (input, "add")) + is_add = 1; + else + break; + } + + if (is_add) + { + local.as_u32 = clib_host_to_net_u32 (0x06000101); + remote.as_u32 = clib_host_to_net_u32 (0x06000102); + local_port = clib_host_to_net_u16 (1234); + remote_port = clib_host_to_net_u16 (11234); + + pool_get (tm->connections[0], tc0); + memset (tc0, 0, sizeof (*tc0)); + + tc0->state = TCP_STATE_ESTABLISHED; + tc0->rcv_las = 1; + tc0->c_c_index = tc0 - tm->connections[0]; + tc0->c_lcl_port = local_port; + tc0->c_rmt_port = remote_port; + tc0->c_is_ip4 = 1; + tc0->c_thread_index = 0; + tc0->c_lcl_ip4.as_u32 = local.as_u32; + tc0->c_rmt_ip4.as_u32 = remote.as_u32; + tc0->opt.mss = 1450; + tcp_connection_init_vars (tc0); + + TCP_EVT_DBG (TCP_EVT_OPEN, tc0); + + if (stream_session_accept (&tc0->connection, 0 /* listener index */ , + sst, 0 /* notify */ )) + clib_warning ("stream_session_accept failed"); + + stream_session_accept_notify (&tc0->connection); + } + else + { + tc0 = tcp_connection_get (0 /* connection index */ , 0 /* thread */ ); + tc0->state = TCP_STATE_CLOSED; + stream_session_disconnect_notify (&tc0->connection); + } + + return rv; +} + static clib_error_t * tcp_test (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd_arg) @@ -911,11 +973,12 @@ tcp_test (vlib_main_t * vm, { res = tcp_test_fifo (vm, input); } - else + else if (unformat (input, "session")) { - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); + res = tcp_test_session (vm, input); } + else + break; } if (res) |