udp session: jumbo frames and configurable mtu 93/26393/6
authorFlorin Coras <fcoras@cisco.com>
Mon, 6 Apr 2020 21:28:59 +0000 (21:28 +0000)
committerDave Barach <openvpp@barachs.net>
Tue, 7 Apr 2020 14:46:47 +0000 (14:46 +0000)
Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I6b750bef5df0f8544e05177ccd480f87a020832d

src/vcl/vppcom.c
src/vnet/session/application_interface.h
src/vnet/udp/udp.c
src/vnet/udp/udp.h
src/vnet/udp/udp_input.c

index dd37460..1591b08 100644 (file)
@@ -2012,7 +2012,6 @@ vcl_fifo_is_writeable (svm_fifo_t * f, u32 len, u8 is_dgram)
     return max_enq >= (sizeof (session_dgram_hdr_t) + len);
   else
     return max_enq > 0;
-
 }
 
 always_inline int
index b410c63..d09432d 100644 (file)
@@ -694,8 +694,13 @@ app_recv_dgram_raw (svm_fifo_t * f, u8 * buf, u32 len,
 
   svm_fifo_peek (f, 0, sizeof (ph), (u8 *) & ph);
   ASSERT (ph.data_length >= ph.data_offset);
-  svm_fifo_peek (f, sizeof (ph), sizeof (*at), (u8 *) at);
 
+  /* Check if we have the full dgram */
+  if (max_deq < (ph.data_length + SESSION_CONN_HDR_LEN)
+      && len >= ph.data_length)
+    return 0;
+
+  svm_fifo_peek (f, sizeof (ph), sizeof (*at), (u8 *) at);
   len = clib_min (len, ph.data_length - ph.data_offset);
   rv = svm_fifo_peek (f, ph.data_offset + SESSION_CONN_HDR_LEN, len, buf);
   if (peek)
index 48d518a..daab453 100644 (file)
@@ -196,6 +196,7 @@ udp_session_bind (u32 session_index, transport_endpoint_t * lcl)
   listener->c_proto = TRANSPORT_PROTO_UDP;
   listener->c_s_index = session_index;
   listener->c_fib_index = lcl->fib_index;
+  listener->mss = um->default_mtu - sizeof (udp_header_t);
   listener->flags |= UDP_CONN_F_OWNS_PORT | UDP_CONN_F_LISTEN;
   lcl_ext = (transport_endpoint_cfg_t *) lcl;
   if (lcl_ext->transport_flags & TRANSPORT_CFG_F_CONNECTED)
@@ -409,10 +410,14 @@ static int
 udp_session_send_params (transport_connection_t * tconn,
                         transport_send_params_t * sp)
 {
+  udp_connection_t *uc;
+
+  uc = udp_get_connection_from_transport (tconn);
+
   /* No constraint on TX window */
   sp->snd_space = ~0;
   /* TODO figure out MTU of output interface */
-  sp->snd_mss = 1460;
+  sp->snd_mss = uc->mss;
   sp->tx_offset = 0;
   sp->flags = 0;
   return 0;
@@ -423,6 +428,7 @@ udp_open_connection (transport_endpoint_cfg_t * rmt)
 {
   vlib_main_t *vm = vlib_get_main ();
   u32 thread_index = vm->thread_index;
+  udp_main_t *um = &udp_main;
   ip46_address_t lcl_addr;
   udp_connection_t *uc;
   u16 lcl_port;
@@ -483,6 +489,7 @@ conn_alloc:
   uc->c_is_ip4 = rmt->is_ip4;
   uc->c_proto = TRANSPORT_PROTO_UDP;
   uc->c_fib_index = rmt->fib_index;
+  uc->mss = rmt->mss ? rmt->mss : (um->default_mtu - sizeof (udp_header_t));
   uc->flags |= UDP_CONN_F_OWNS_PORT;
   if (rmt->transport_flags & TRANSPORT_CFG_F_CONNECTED)
     uc->flags |= UDP_CONN_F_CONNECTED;
@@ -639,6 +646,8 @@ udp_init (vlib_main_t * vm)
     vlib_node_add_next (vm, udp4_local_node.index, udp4_input_node.index);
   um->local_to_input_edge[UDP_IP6] =
     vlib_node_add_next (vm, udp6_local_node.index, udp6_input_node.index);
+
+  um->default_mtu = 1500;
   return 0;
 }
 
@@ -650,6 +659,24 @@ VLIB_INIT_FUNCTION (udp_init) =
 };
 /* *INDENT-ON* */
 
+static clib_error_t *
+udp_config_fn (vlib_main_t * vm, unformat_input_t * input)
+{
+  udp_main_t *um = &udp_main;
+  u32 tmp;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "mtu %u", &tmp))
+       um->default_mtu = tmp;
+      else
+       return clib_error_return (0, "unknown input `%U'",
+                                 format_unformat_error, input);
+    }
+  return 0;
+}
+
+VLIB_CONFIG_FUNCTION (udp_config_fn, "udp");
 
 static clib_error_t *
 show_udp_punt_fn (vlib_main_t * vm, unformat_input_t * input,
index 9e1aad6..f7985c9 100644 (file)
@@ -63,6 +63,7 @@ typedef struct
   transport_connection_t connection;   /**< must be first */
   clib_spinlock_t rx_lock;             /**< rx fifo lock */
   u8 flags;                            /**< connection flags */
+  u16 mss;                             /**< connection mss */
 } udp_connection_t;
 
 #define foreach_udp4_dst_port                  \
@@ -171,6 +172,7 @@ typedef struct
   clib_spinlock_t *peekers_write_locks;
   udp_connection_t *listener_pool;
 
+  u16 default_mtu;
 } udp_main_t;
 
 extern udp_main_t udp_main;
index 4b22cbe..1e1c60b 100644 (file)
@@ -208,6 +208,7 @@ udp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
              child0->c_rmt_port = udp0->src_port;
              child0->c_is_ip4 = is_ip4;
              child0->c_fib_index = tc0->fib_index;
+             child0->mss = uc0->mss;
              child0->flags |= UDP_CONN_F_CONNECTED;
 
              if (session_stream_accept (&child0->connection,
@@ -238,7 +239,14 @@ udp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
          error0 = UDP_ERROR_FIFO_FULL;
          goto trace0;
        }
-      hdr0.data_length = b0->current_length = data_len;
+
+      hdr0.data_length = data_len;
+      if (PREDICT_TRUE (!(b0->flags & VLIB_BUFFER_NEXT_PRESENT)))
+       b0->current_length = data_len;
+      else
+       b0->total_length_not_including_first_buffer = data_len
+         - b0->current_length;
+
       hdr0.data_offset = 0;
       ip_set (&hdr0.lcl_ip, lcl_addr, is_ip4);
       ip_set (&hdr0.rmt_ip, rmt_addr, is_ip4);