vcl: enable gso for 'sendmsg' in LDP mode.
[vpp.git] / src / vcl / ldp.c
index 316d97d..522e85d 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdarg.h>
 #include <sys/resource.h>
 #include <netinet/tcp.h>
+#include <linux/udp.h>
 
 #include <vcl/ldp_socket_wrapper.h>
 #include <vcl/ldp.h>
@@ -271,10 +272,11 @@ ldp_init (void)
       /* Make sure there are enough bits in the fd set for vcl sessions */
       if (ldp->vlsh_bit_val > FD_SETSIZE / 2)
        {
-         LDBG (0, "ERROR: LDP vlsh bit value %d > FD_SETSIZE/2 %d!",
+         /* Only valid for select/pselect, so just WARNING and not exit */
+         LDBG (0,
+               "WARNING: LDP vlsh bit value %d > FD_SETSIZE/2 %d, "
+               "select/pselect not supported now!",
                ldp->vlsh_bit_val, FD_SETSIZE / 2);
-         ldp->init = 0;
-         return -1;
        }
     }
   env_var_str = getenv (LDP_ENV_TLS_TRANS);
@@ -724,10 +726,11 @@ ldp_pselect (int nfds, fd_set * __restrict readfds,
       time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
        (f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
 
+      time_out += clib_time_now (&ldpw->clib_time);
+
       /* select as fine grained sleep */
       if (!nfds)
        {
-         time_out += clib_time_now (&ldpw->clib_time);
          while (clib_time_now (&ldpw->clib_time) < time_out)
            ;
          return 0;
@@ -966,9 +969,7 @@ assign_cert_key_pair (vls_handle_t vlsh)
     return -1;
 
   ckp_len = sizeof (ldp->ckpair_index);
-  return vppcom_session_attr (vlsh_to_session_index (vlsh),
-                             VPPCOM_ATTR_SET_CKPAIR, &ldp->ckpair_index,
-                             &ckp_len);
+  return vls_attr (vlsh, VPPCOM_ATTR_SET_CKPAIR, &ldp->ckpair_index, &ckp_len);
 }
 
 int
@@ -1530,13 +1531,28 @@ recv (int fd, void *buf, size_t n, int flags)
   return size;
 }
 
-static int
-ldp_vls_sendo (vls_handle_t vlsh, const void *buf, size_t n, int flags,
+ssize_t
+__recv_chk (int fd, void *buf, size_t n, size_t buflen, int flags)
+{
+  if (n > buflen)
+    return -1;
+
+  return recv (fd, buf, n, flags);
+}
+
+static inline int
+ldp_vls_sendo (vls_handle_t vlsh, const void *buf, size_t n,
+              vppcom_endpt_tlv_t *ep_tlv, int flags,
               __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
 {
   vppcom_endpt_t *ep = 0;
   vppcom_endpt_t _ep;
 
+  if (ep_tlv)
+    {
+      _ep.app_data = *ep_tlv;
+    }
+
   if (addr)
     {
       ep = &_ep;
@@ -1603,9 +1619,9 @@ sendto (int fd, const void *buf, size_t n, int flags,
   ldp_init_check ();
 
   vlsh = ldp_fd_to_vlsh (fd);
-  if (vlsh != INVALID_SESSION_ID)
+  if (vlsh != VLS_INVALID_HANDLE)
     {
-      size = ldp_vls_sendo (vlsh, buf, n, flags, addr, addr_len);
+      size = ldp_vls_sendo (vlsh, buf, n, NULL, flags, addr, addr_len);
       if (size < 0)
        {
          errno = -size;
@@ -1660,12 +1676,27 @@ sendmsg (int fd, const struct msghdr * msg, int flags)
     {
       struct iovec *iov = msg->msg_iov;
       ssize_t total = 0;
-      int i, rv;
+      int i, rv = 0;
+      struct cmsghdr *cmsg;
+      uint16_t *valp;
+      vppcom_endpt_tlv_t _app_data;
+      vppcom_endpt_tlv_t *p_app_data = NULL;
+
+      cmsg = CMSG_FIRSTHDR (msg);
+      if (cmsg && cmsg->cmsg_type == UDP_SEGMENT)
+       {
+         p_app_data = &_app_data;
+         valp = (void *) CMSG_DATA (cmsg);
+         p_app_data->data_type = VCL_UDP_SEGMENT;
+         p_app_data->data_len = sizeof (*valp);
+         p_app_data->value = *valp;
+       }
 
       for (i = 0; i < msg->msg_iovlen; ++i)
        {
-         rv = ldp_vls_sendo (vlsh, iov[i].iov_base, iov[i].iov_len, flags,
-                             msg->msg_name, msg->msg_namelen);
+         rv =
+           ldp_vls_sendo (vlsh, iov[i].iov_base, iov[i].iov_len, p_app_data,
+                          flags, msg->msg_name, msg->msg_namelen);
          if (rv < 0)
            break;
          else
@@ -1702,7 +1733,7 @@ sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 
   ldp_init_check ();
 
-  if (sh != INVALID_SESSION_ID)
+  if (sh != VLS_INVALID_HANDLE)
     {
       clib_warning ("LDP<%d>: LDP-TBD", getpid ());
       errno = ENOSYS;
@@ -1802,7 +1833,7 @@ recvmmsg (int fd, struct mmsghdr *vmessages,
 
   ldp_init_check ();
 
-  if (sh != INVALID_SESSION_ID)
+  if (sh != VLS_INVALID_HANDLE)
     {
       clib_warning ("LDP<%d>: LDP-TBD", getpid ());
       errno = ENOSYS;