Update L2 header offset after VLAN tag rewrite
[vpp.git] / src / uri / vppcom.c
index 76acc47..24475b4 100644 (file)
@@ -136,7 +136,6 @@ typedef struct vppcom_main_t_
   u8 init;
   u32 *client_session_index_fifo;
   volatile u32 bind_session_index;
-  u32 tx_event_id;
   int main_cpu;
 
   /* vpe input queue */
@@ -1015,7 +1014,7 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
   session->state = STATE_ACCEPT;
   session->is_cut_thru = 0;
   session->is_server = 1;
-  session->port = ntohs (mp->port);
+  session->port = mp->port;
   session->peer_addr.is_ip4 = mp->is_ip4;
   clib_memcpy (&session->peer_addr.ip46, mp->ip,
               sizeof (session->peer_addr.ip46));
@@ -1841,7 +1840,7 @@ vppcom_session_create (u32 vrf, u8 proto, u8 is_nonblocking)
   session->vrf = vrf;
   session->proto = proto;
   session->state = STATE_START;
-  session->is_nonblocking = is_nonblocking;
+  session->is_nonblocking = is_nonblocking ? 1 : 0;
   clib_spinlock_unlock (&vcm->sessions_lockp);
 
   if (VPPCOM_DEBUG > 0)
@@ -1925,19 +1924,17 @@ vppcom_session_close (uint32_t session_index)
          clib_spinlock_unlock (&vcm->sessions_lockp);
        }
 
-      if (session->is_cut_thru)
+      if (session->is_cut_thru && session->is_server &&
+         (session->state == STATE_ACCEPT))
        {
-         if (session->is_server)
-           {
-             rv = vppcom_session_unbind_cut_thru (session);
-             if ((VPPCOM_DEBUG > 0) && (rv < 0))
-               clib_warning ("[%d] unbind cut-thru (session %d) failed, "
-                             "rv = %s (%d)",
-                             vcm->my_pid, session_index,
-                             vppcom_retval_str (rv), rv);
-           }
+         rv = vppcom_session_unbind_cut_thru (session);
+         if ((VPPCOM_DEBUG > 0) && (rv < 0))
+           clib_warning ("[%d] unbind cut-thru (session %d) failed, "
+                         "rv = %s (%d)",
+                         vcm->my_pid, session_index,
+                         vppcom_retval_str (rv), rv);
        }
-      else if (session->is_server)
+      else if (session->is_server && session->is_listen)
        {
          rv = vppcom_session_unbind (session_index);
          if ((VPPCOM_DEBUG > 0) && (rv < 0))
@@ -1945,7 +1942,7 @@ vppcom_session_close (uint32_t session_index)
                          vcm->my_pid, session_index,
                          vppcom_retval_str (rv), rv);
        }
-      else
+      else if (session->state == STATE_CONNECT)
        {
          rv = vppcom_session_disconnect (session_index);
          if ((VPPCOM_DEBUG > 0) && (rv < 0))
@@ -1980,6 +1977,15 @@ vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
       return rv;
     }
 
+  if (session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (VPPCOM_DEBUG > 0)
     clib_warning ("[%d] sid %d", vcm->my_pid, session_index);
 
@@ -2010,6 +2016,15 @@ vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
       return rv;
     }
 
+  if (listen_session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, listen_session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (VPPCOM_DEBUG > 0)
     clib_warning ("[%d] sid %d", vcm->my_pid, listen_session_index);
 
@@ -2068,6 +2083,15 @@ vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
       return rv;
     }
 
+  if (listen_session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, listen_session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (listen_session->state != STATE_LISTEN)
     {
       clib_spinlock_unlock (&vcm->sessions_lockp);
@@ -2146,6 +2170,15 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
       return rv;
     }
 
+  if (session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (session->state == STATE_CONNECT)
     {
       clib_spinlock_unlock (&vcm->sessions_lockp);
@@ -2165,9 +2198,10 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
       u8 *ip_str = format (0, "%U", format_ip46_address,
                           &session->peer_addr.ip46,
                           session->peer_addr.is_ip4);
-      clib_warning ("[%d] connect sid %d to %s server port %d",
+      clib_warning ("[%d] connect sid %d to %s server port %d proto %s",
                    vcm->my_pid, session_index, ip_str,
-                   clib_net_to_host_u16 (session->port));
+                   clib_net_to_host_u16 (session->port),
+                   session->proto ? "UDP" : "TCP");
       vec_free (ip_str);
     }
 
@@ -2182,6 +2216,9 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
                      vcm->my_pid, vppcom_retval_str (rv), rv);
       return rv;
     }
+  if (VPPCOM_DEBUG > 0)
+    clib_warning ("[%d] sid %d connected!", vcm->my_pid, session_index);
+
   return VPPCOM_OK;
 }
 
@@ -2194,6 +2231,7 @@ vppcom_session_read (uint32_t session_index, void *buf, int n)
   int n_read = 0;
   int rv;
   char *fifo_str;
+  u32 poll_et;
 
   ASSERT (buf);
 
@@ -2208,6 +2246,15 @@ vppcom_session_read (uint32_t session_index, void *buf, int n)
       return rv;
     }
 
+  if (session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (session->state == STATE_DISCONNECT)
     {
       clib_spinlock_unlock (&vcm->sessions_lockp);
@@ -2221,6 +2268,8 @@ vppcom_session_read (uint32_t session_index, void *buf, int n)
             session->server_rx_fifo : session->server_tx_fifo);
   fifo_str = ((!session->is_cut_thru || session->is_server) ?
              "server_rx_fifo" : "server_tx_fifo");
+  poll_et = EPOLLET & session->vep.ev.events;
+  clib_spinlock_unlock (&vcm->sessions_lockp);
 
   do
     {
@@ -2228,10 +2277,12 @@ vppcom_session_read (uint32_t session_index, void *buf, int n)
     }
   while (!session->is_nonblocking && (n_read <= 0));
 
-  if (n_read <= 0)
-    session->vep.et_mask |= EPOLLIN;
-
-  clib_spinlock_unlock (&vcm->sessions_lockp);
+  if (poll_et && (n_read <= 0))
+    {
+      clib_spinlock_lock (&vcm->sessions_lockp);
+      session->vep.et_mask |= EPOLLIN;
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+    }
 
   if ((VPPCOM_DEBUG > 2) && (n_read > 0))
     clib_warning ("[%d] sid %d, read %d bytes from %s (%p)", vcm->my_pid,
@@ -2248,6 +2299,15 @@ vppcom_session_read_ready (session_t * session, u32 session_index)
   int ready = 0;
 
   /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
+  if (session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (session->state == STATE_DISCONNECT)
     {
       if (VPPCOM_DEBUG > 0)
@@ -2271,7 +2331,7 @@ vppcom_session_read_ready (session_t * session, u32 session_index)
                  session_index,
                  session->is_server ? "server_rx_fifo" : "server_tx_fifo",
                  rx_fifo, ready);
-  if (ready == 0)
+  if ((session->vep.ev.events & EPOLLET) && (ready == 0))
     session->vep.et_mask |= EPOLLIN;
 
   return ready;
@@ -2287,6 +2347,7 @@ vppcom_session_write (uint32_t session_index, void *buf, int n)
   session_fifo_event_t evt;
   int rv, n_write;
   char *fifo_str;
+  u32 poll_et;
 
   ASSERT (buf);
 
@@ -2301,6 +2362,15 @@ vppcom_session_write (uint32_t session_index, void *buf, int n)
       return rv;
     }
 
+  if (session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (session->state == STATE_DISCONNECT)
     {
       clib_spinlock_unlock (&vcm->sessions_lockp);
@@ -2314,6 +2384,10 @@ vppcom_session_write (uint32_t session_index, void *buf, int n)
             session->server_tx_fifo : session->server_rx_fifo);
   fifo_str = ((!session->is_cut_thru || session->is_server) ?
              "server_tx_fifo" : "server_rx_fifo");
+  q = session->vpp_event_queue;
+  poll_et = EPOLLET & session->vep.ev.events;
+  clib_spinlock_unlock (&vcm->sessions_lockp);
+
   do
     {
       n_write = svm_fifo_enqueue_nowait (tx_fifo, n, buf);
@@ -2328,32 +2402,37 @@ vppcom_session_write (uint32_t session_index, void *buf, int n)
       /* Fabricate TX event, send to vpp */
       evt.fifo = tx_fifo;
       evt.event_type = FIFO_EVENT_APP_TX;
-      evt.event_id = vcm->tx_event_id++;
 
       rval = vppcom_session_at_index (session_index, &session);
       if (PREDICT_FALSE (rval))
        {
-         clib_spinlock_unlock (&vcm->sessions_lockp);
          if (VPPCOM_DEBUG > 1)
            clib_warning ("[%d] invalid session, sid (%u) has been closed!",
                          vcm->my_pid, session_index);
          return rval;
        }
-      q = session->vpp_event_queue;
       ASSERT (q);
       unix_shared_memory_queue_add (q, (u8 *) & evt,
                                    0 /* do wait for mutex */ );
     }
 
-  if (n_write <= 0)
-    session->vep.et_mask |= EPOLLOUT;
-
-  clib_spinlock_unlock (&vcm->sessions_lockp);
+  if (poll_et && (n_write <= 0))
+    {
+      clib_spinlock_lock (&vcm->sessions_lockp);
+      session->vep.et_mask |= EPOLLOUT;
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+    }
 
   if (VPPCOM_DEBUG > 2)
-    clib_warning ("[%d] sid %d, wrote %d bytes to %s (%p)", vcm->my_pid,
-                 session_index, n_write, fifo_str, tx_fifo);
-  return n_write;
+    {
+      if (n_write == -2)
+       clib_warning ("[%d] sid %d, FIFO-FULL %s (%p)", vcm->my_pid,
+                     session_index, fifo_str, tx_fifo);
+      else
+       clib_warning ("[%d] sid %d, wrote %d bytes to %s (%p)", vcm->my_pid,
+                     session_index, n_write, fifo_str, tx_fifo);
+    }
+  return (n_write < 0) ? VPPCOM_EAGAIN : n_write;
 }
 
 static inline int
@@ -2365,6 +2444,15 @@ vppcom_session_write_ready (session_t * session, u32 session_index)
   int ready;
 
   /* Assumes caller has acquired spinlock: vcm->sessions_lockp */
+  if (session->is_vep)
+    {
+      clib_spinlock_unlock (&vcm->sessions_lockp);
+      if (VPPCOM_DEBUG > 0)
+       clib_warning ("[%d] invalid session, sid (%u) is an epoll session!",
+                     vcm->my_pid, session_index);
+      return VPPCOM_EBADFD;
+    }
+
   if (session->state == STATE_DISCONNECT)
     {
       if (VPPCOM_DEBUG > 0)
@@ -2383,7 +2471,7 @@ vppcom_session_write_ready (session_t * session, u32 session_index)
   if (VPPCOM_DEBUG > 3)
     clib_warning ("[%d] sid %d, peek %s (%p), ready = %d", vcm->my_pid,
                  session_index, fifo_str, tx_fifo, ready);
-  if (ready == 0)
+  if ((session->vep.ev.events & EPOLLET) && (ready == 0))
     session->vep.et_mask |= EPOLLOUT;
 
   return ready;
@@ -2403,19 +2491,19 @@ vppcom_select (unsigned long n_bits, unsigned long *read_map,
 
   ASSERT (sizeof (clib_bitmap_t) == sizeof (long int));
 
-  if (read_map)
+  if (n_bits && read_map)
     {
       clib_bitmap_validate (vcm->rd_bitmap, minbits);
       clib_memcpy (vcm->rd_bitmap, read_map, vec_len (vcm->rd_bitmap));
       memset (read_map, 0, vec_len (vcm->rd_bitmap));
     }
-  if (write_map)
+  if (n_bits && write_map)
     {
       clib_bitmap_validate (vcm->wr_bitmap, minbits);
       clib_memcpy (vcm->wr_bitmap, write_map, vec_len (vcm->wr_bitmap));
       memset (write_map, 0, vec_len (vcm->wr_bitmap));
     }
-  if (except_map)
+  if (n_bits && except_map)
     {
       clib_bitmap_validate (vcm->ex_bitmap, minbits);
       clib_memcpy (vcm->ex_bitmap, except_map, vec_len (vcm->ex_bitmap));
@@ -2425,91 +2513,100 @@ vppcom_select (unsigned long n_bits, unsigned long *read_map,
   do
     {
       /* *INDENT-OFF* */
-      clib_bitmap_foreach (session_index, vcm->rd_bitmap,
-        ({
-          clib_spinlock_lock (&vcm->sessions_lockp);
-          rv = vppcom_session_at_index (session_index, &session);
-          if (rv < 0)
+      if (n_bits)
+        {
+          if (read_map)
             {
-              clib_spinlock_unlock (&vcm->sessions_lockp);
-              if (VPPCOM_DEBUG > 1)
-                clib_warning ("[%d] session %d specified in "
-                              "read_map is closed.", vcm->my_pid,
-                              session_index);
-              bits_set = VPPCOM_EBADFD;
-              goto select_done;
+              clib_bitmap_foreach (session_index, vcm->rd_bitmap,
+                ({
+                  clib_spinlock_lock (&vcm->sessions_lockp);
+                  rv = vppcom_session_at_index (session_index, &session);
+                  if (rv < 0)
+                    {
+                      clib_spinlock_unlock (&vcm->sessions_lockp);
+                      if (VPPCOM_DEBUG > 1)
+                        clib_warning ("[%d] session %d specified in "
+                                      "read_map is closed.", vcm->my_pid,
+                                      session_index);
+                      bits_set = VPPCOM_EBADFD;
+                      goto select_done;
+                    }
+
+                  rv = vppcom_session_read_ready (session, session_index);
+                  clib_spinlock_unlock (&vcm->sessions_lockp);
+                  if (except_map && vcm->ex_bitmap &&
+                      clib_bitmap_get (vcm->ex_bitmap, session_index) &&
+                      (rv < 0))
+                    {
+                      // TBD: clib_warning
+                      clib_bitmap_set_no_check (except_map, session_index, 1);
+                      bits_set++;
+                    }
+                  else if (rv > 0)
+                    {
+                      // TBD: clib_warning
+                      clib_bitmap_set_no_check (read_map, session_index, 1);
+                      bits_set++;
+                    }
+                }));
             }
 
-          rv = vppcom_session_read_ready (session, session_index);
-          clib_spinlock_unlock (&vcm->sessions_lockp);
-          if (vcm->ex_bitmap &&
-              clib_bitmap_get (vcm->ex_bitmap, session_index) && (rv < 0))
+          if (write_map)
             {
-              // TBD: clib_warning
-              /* coverity[FORWARD_NULL] */
-              clib_bitmap_set_no_check (except_map, session_index, 1);
-              bits_set++;
-            }
-          else if (rv > 0)
-            {
-              // TBD: clib_warning
-              /* coverity[FORWARD_NULL] */
-              clib_bitmap_set_no_check (read_map, session_index, 1);
-              bits_set++;
-            }
-        }));
-
-      clib_bitmap_foreach (session_index, vcm->wr_bitmap,
-        ({
-          clib_spinlock_lock (&vcm->sessions_lockp);
-          rv = vppcom_session_at_index (session_index, &session);
-          if (rv < 0)
-            {
-              clib_spinlock_unlock (&vcm->sessions_lockp);
-              if (VPPCOM_DEBUG > 0)
-                clib_warning ("[%d] session %d specified in "
-                              "write_map is closed.", vcm->my_pid,
-                              session_index);
-              bits_set = VPPCOM_EBADFD;
-              goto select_done;
+              clib_bitmap_foreach (session_index, vcm->wr_bitmap,
+                ({
+                  clib_spinlock_lock (&vcm->sessions_lockp);
+                  rv = vppcom_session_at_index (session_index, &session);
+                  if (rv < 0)
+                    {
+                      clib_spinlock_unlock (&vcm->sessions_lockp);
+                      if (VPPCOM_DEBUG > 0)
+                        clib_warning ("[%d] session %d specified in "
+                                      "write_map is closed.", vcm->my_pid,
+                                      session_index);
+                      bits_set = VPPCOM_EBADFD;
+                      goto select_done;
+                    }
+
+                  rv = vppcom_session_write_ready (session, session_index);
+                  clib_spinlock_unlock (&vcm->sessions_lockp);
+                  if (write_map && (rv > 0))
+                    {
+                      // TBD: clib_warning
+                      clib_bitmap_set_no_check (write_map, session_index, 1);
+                      bits_set++;
+                    }
+                }));
             }
 
-          rv = vppcom_session_write_ready (session, session_index);
-          clib_spinlock_unlock (&vcm->sessions_lockp);
-          if (rv > 0 )
+          if (except_map)
             {
-              // TBD: clib_warning
-              /* coverity[FORWARD_NULL] */
-              clib_bitmap_set_no_check (write_map, session_index, 1);
-              bits_set++;
+              clib_bitmap_foreach (session_index, vcm->ex_bitmap,
+                ({
+                  clib_spinlock_lock (&vcm->sessions_lockp);
+                  rv = vppcom_session_at_index (session_index, &session);
+                  if (rv < 0)
+                    {
+                      clib_spinlock_unlock (&vcm->sessions_lockp);
+                      if (VPPCOM_DEBUG > 1)
+                        clib_warning ("[%d] session %d specified in "
+                                      "except_map is closed.", vcm->my_pid,
+                                      session_index);
+                      bits_set = VPPCOM_EBADFD;
+                      goto select_done;
+                    }
+
+                  rv = vppcom_session_read_ready (session, session_index);
+                  clib_spinlock_unlock (&vcm->sessions_lockp);
+                  if (rv < 0)
+                    {
+                      // TBD: clib_warning
+                      clib_bitmap_set_no_check (except_map, session_index, 1);
+                      bits_set++;
+                    }
+                }));
             }
-        }));
-
-      clib_bitmap_foreach (session_index, vcm->ex_bitmap,
-        ({
-          clib_spinlock_lock (&vcm->sessions_lockp);
-          rv = vppcom_session_at_index (session_index, &session);
-          if (rv < 0)
-            {
-              clib_spinlock_unlock (&vcm->sessions_lockp);
-              if (VPPCOM_DEBUG > 1)
-                clib_warning ("[%d] session %d specified in "
-                              "except_map is closed.", vcm->my_pid,
-                              session_index);
-              bits_set = VPPCOM_EBADFD;
-              goto select_done;
-            }
-
-          rv = vppcom_session_read_ready (session, session_index);
-          clib_spinlock_unlock (&vcm->sessions_lockp);
-          if (rv < 0)
-            {
-              // TBD: clib_warning
-              /* coverity[FORWARD_NULL] */
-              clib_bitmap_set_no_check (except_map, session_index, 1);
-              bits_set++;
-            }
-        }));
+        }
       /* *INDENT-ON* */
     }
   while (clib_time_now (&vcm->clib_time) < timeout);
@@ -2553,6 +2650,7 @@ vep_verify_epoll_chain (u32 vep_idx)
   do
     {
       vep = &session->vep;
+      sid = vep->next_sid;
       if (session->is_vep_session)
        {
          if (VPPCOM_DEBUG > 1)
@@ -2571,7 +2669,6 @@ vep_verify_epoll_chain (u32 vep_idx)
                          vep->vep_idx, vep->vep_idx,
                          vep->ev.events, vep->ev.data.u64, vep->et_mask);
        }
-      sid = vep->next_sid;
       if (sid != ~0)
        {
          rv = vppcom_session_at_index (sid, &session);
@@ -3036,7 +3133,7 @@ vppcom_session_attr (uint32_t session_index, uint32_t op,
   session_t *session;
   int rv = VPPCOM_OK;
   u32 *flags = buffer;
-  vppcom_ip46_t *vcl_addr = buffer;
+  vppcom_endpt_t *ep = buffer;
 
   VCL_LOCK_AND_GET_SESSION (session_index, &session);
   switch (op)
@@ -3080,28 +3177,45 @@ vppcom_session_attr (uint32_t session_index, uint32_t op,
       break;
 
     case VPPCOM_ATTR_GET_PEER_ADDR:
-      if (buffer && buflen && (*buflen >= sizeof (*vcl_addr)))
+      if (buffer && buflen && (*buflen >= sizeof (*ep)))
        {
-         *vcl_addr = session->peer_addr;
-         *buflen = sizeof (*vcl_addr);
+         ep->vrf = session->vrf;
+         ep->is_ip4 = session->peer_addr.is_ip4;
+         ep->port = session->port;
+         if (session->peer_addr.is_ip4)
+           clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4,
+                        sizeof (ip4_address_t));
+         else
+           clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6,
+                        sizeof (ip6_address_t));
+         *buflen = sizeof (*ep);
          if (VPPCOM_DEBUG > 0)
            clib_warning ("VPPCOM_ATTR_GET_PEER_ADDR: is_ip4 = %u, "
-                         "addr = %U", vcl_addr->is_ip4, format_ip46_address,
-                         &vcl_addr->ip46, vcl_addr->is_ip4);
+                         "addr = %U", ep->is_ip4, format_ip46_address,
+                         &session->peer_addr.ip46, ep->is_ip4);
        }
       else
        rv = VPPCOM_EINVAL;
       break;
 
     case VPPCOM_ATTR_GET_LCL_ADDR:
-      if (buffer && buflen && (*buflen >= sizeof (*vcl_addr)))
+      if (buffer && buflen && (*buflen >= sizeof (*ep)))
        {
-         *vcl_addr = session->lcl_addr;
-         *buflen = sizeof (*vcl_addr);
+         ep->vrf = session->vrf;
+         ep->is_ip4 = session->lcl_addr.is_ip4;
+         ep->port = session->port;
+         if (session->lcl_addr.is_ip4)
+           clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4,
+                        sizeof (ip4_address_t));
+         else
+           clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6,
+                        sizeof (ip6_address_t));
+         *buflen = sizeof (*ep);
          if (VPPCOM_DEBUG > 0)
-           clib_warning ("VPPCOM_ATTR_GET_LCL_ADDR: is_ip4 = %u, "
-                         "addr = %U", vcl_addr->is_ip4, format_ip46_address,
-                         &vcl_addr->ip46, vcl_addr->is_ip4);
+           if (VPPCOM_DEBUG > 0)
+             clib_warning ("VPPCOM_ATTR_GET_LCL_ADDR: is_ip4 = %u, "
+                           "addr = %U", ep->is_ip4, format_ip46_address,
+                           &session->lcl_addr.ip46, ep->is_ip4);
        }
       else
        rv = VPPCOM_EINVAL;
@@ -3115,6 +3229,19 @@ vppcom_session_attr (uint32_t session_index, uint32_t op,
 
     case VPPCOM_ATTR_SET_V6ONLY:
       break;
+
+    case VPPCOM_ATTR_SET_KEEPALIVE:
+      break;
+
+    case VPPCOM_ATTR_SET_TCP_KEEPIDLE:
+      break;
+
+    case VPPCOM_ATTR_SET_TCP_KEEPINTVL:
+      break;
+
+    default:
+      rv = VPPCOM_EINVAL;
+      break;
     }
 
 done:
@@ -3122,10 +3249,10 @@ done:
   return rv;
 }
 
-  /*
  * fd.io coding-style-patch-verification: ON
  *
  * Local Variables:
  * eval: (c-set-style "gnu")
  * End:
  */
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */