diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/session/session.c | 9 | ||||
-rw-r--r-- | src/vnet/session/session_node.c | 6 | ||||
-rw-r--r-- | src/vnet/udp/udp.c | 84 |
3 files changed, 60 insertions, 39 deletions
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index 9549cbaf577..5bb57761c90 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -1524,14 +1524,7 @@ session_stop_listen (session_t * s) return SESSION_E_NONE; if (!(tc->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP)) - { - if (transport_connection_is_cless (tc)) - { - clib_memset (&tc->rmt_ip, 0, sizeof (tc->rmt_ip)); - tc->rmt_port = 0; - } - session_lookup_del_connection (tc); - } + session_lookup_del_connection (tc); transport_stop_listen (tp, s->connection_index); return 0; diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index b0f4a93ee76..f652f2e9a1c 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -1105,10 +1105,8 @@ session_tx_fill_buffer (session_worker_t *wrk, session_tx_context_t *ctx, if (transport_connection_is_cless (ctx->tc)) { - ip_copy (&ctx->tc->rmt_ip, &hdr->rmt_ip, ctx->tc->is_ip4); - ip_copy (&ctx->tc->lcl_ip, &hdr->lcl_ip, ctx->tc->is_ip4); - /* Local port assumed to be bound, not overwriting it */ - ctx->tc->rmt_port = hdr->rmt_port; + clib_memcpy_fast (data0 - sizeof (session_dgram_hdr_t), hdr, + sizeof (*hdr)); } hdr->data_offset += n_bytes_read; if (hdr->data_offset == hdr->data_length) diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c index 493275006f7..b3c410a2330 100644 --- a/src/vnet/udp/udp.c +++ b/src/vnet/udp/udp.c @@ -226,50 +226,68 @@ udp_session_get_listener (u32 listener_index) } always_inline u32 -udp_push_one_header (vlib_main_t *vm, udp_connection_t *uc, vlib_buffer_t *b) +udp_push_one_header (vlib_main_t *vm, udp_connection_t *uc, vlib_buffer_t *b, + u8 is_cless) { - vlib_buffer_push_udp (b, uc->c_lcl_port, uc->c_rmt_port, - udp_csum_offload (uc)); b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; - - /* Handle ip header now as session layer overwrite connection details for - * non-connected udp. */ - if (uc->c_is_ip4) - vlib_buffer_push_ip4_custom (vm, b, &uc->c_lcl_ip4, &uc->c_rmt_ip4, - IP_PROTOCOL_UDP, udp_csum_offload (uc), - 0 /* is_df */, uc->c_dscp); - else - vlib_buffer_push_ip6 (vm, b, &uc->c_lcl_ip6, &uc->c_rmt_ip6, - IP_PROTOCOL_UDP); - /* reuse tcp medatada for now */ vnet_buffer (b)->tcp.connection_index = uc->c_c_index; - /* Not connected udp session. Mark buffer for custom handling in - * udp_output */ - if (PREDICT_FALSE (!(uc->flags & UDP_CONN_F_CONNECTED))) - vnet_buffer (b)->tcp.flags |= UDP_CONN_F_LISTEN; + if (!is_cless) + { + vlib_buffer_push_udp (b, uc->c_lcl_port, uc->c_rmt_port, + udp_csum_offload (uc)); + + if (uc->c_is_ip4) + vlib_buffer_push_ip4_custom (vm, b, &uc->c_lcl_ip4, &uc->c_rmt_ip4, + IP_PROTOCOL_UDP, udp_csum_offload (uc), + 0 /* is_df */, uc->c_dscp); + else + vlib_buffer_push_ip6 (vm, b, &uc->c_lcl_ip6, &uc->c_rmt_ip6, + IP_PROTOCOL_UDP); + + vnet_buffer (b)->tcp.flags = 0; + } else - vnet_buffer (b)->tcp.flags = 0; + { + u8 *data = vlib_buffer_get_current (b); + session_dgram_hdr_t hdr; + + hdr = *(session_dgram_hdr_t *) (data - sizeof (hdr)); + + /* Local port assumed to be bound, not overwriting it */ + vlib_buffer_push_udp (b, uc->c_lcl_port, hdr.rmt_port, + udp_csum_offload (uc)); + + if (uc->c_is_ip4) + vlib_buffer_push_ip4_custom (vm, b, &hdr.lcl_ip.ip4, &hdr.rmt_ip.ip4, + IP_PROTOCOL_UDP, udp_csum_offload (uc), + 0 /* is_df */, uc->c_dscp); + else + vlib_buffer_push_ip6 (vm, b, &hdr.lcl_ip.ip6, &hdr.rmt_ip.ip6, + IP_PROTOCOL_UDP); + + /* Not connected udp session. Mark buffer for custom handling in + * udp_output */ + vnet_buffer (b)->tcp.flags |= UDP_CONN_F_LISTEN; + } return 0; } -static u32 -udp_push_header (transport_connection_t *tc, vlib_buffer_t **bs, u32 n_bufs) +always_inline void +udp_push_header_batch (udp_connection_t *uc, vlib_buffer_t **bs, u32 n_bufs, + u8 is_cless) { vlib_main_t *vm = vlib_get_main (); - udp_connection_t *uc; - - uc = udp_connection_from_transport (tc); while (n_bufs >= 4) { vlib_prefetch_buffer_header (bs[2], STORE); vlib_prefetch_buffer_header (bs[3], STORE); - udp_push_one_header (vm, uc, bs[0]); - udp_push_one_header (vm, uc, bs[1]); + udp_push_one_header (vm, uc, bs[0], is_cless); + udp_push_one_header (vm, uc, bs[1], is_cless); n_bufs -= 2; bs += 2; @@ -279,11 +297,23 @@ udp_push_header (transport_connection_t *tc, vlib_buffer_t **bs, u32 n_bufs) if (n_bufs > 1) vlib_prefetch_buffer_header (bs[1], STORE); - udp_push_one_header (vm, uc, bs[0]); + udp_push_one_header (vm, uc, bs[0], is_cless); n_bufs -= 1; bs += 1; } +} + +static u32 +udp_push_header (transport_connection_t *tc, vlib_buffer_t **bs, u32 n_bufs) +{ + udp_connection_t *uc; + + uc = udp_connection_from_transport (tc); + if (uc->flags & UDP_CONN_F_CONNECTED) + udp_push_header_batch (uc, bs, n_bufs, 0 /* is_cless */); + else + udp_push_header_batch (uc, bs, n_bufs, 1 /* is_cless */); if (PREDICT_FALSE (uc->flags & UDP_CONN_F_CLOSING)) { |