vcl: support connected udp listens
[vpp.git] / src / vcl / vppcom.c
index a8cebd8..35e7804 100644 (file)
@@ -209,6 +209,8 @@ vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s)
   clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
   mp->port = s->transport.lcl_port;
   mp->proto = s->session_type;
+  if (s->flags & VCL_SESSION_F_CONNECTED)
+    mp->flags = TRANSPORT_CFG_F_CONNECTED;
   app_send_ctrl_evt_to_vpp (mq, app_evt);
 }
 
@@ -749,6 +751,17 @@ vcl_session_cleanup_handler (vcl_worker_t * wrk, void *data)
       return;
     }
 
+  if (msg->type == SESSION_CLEANUP_TRANSPORT)
+    {
+      /* Transport was cleaned up before we confirmed close. Probably the
+       * app is still waiting for some data that cannot be delivered.
+       * Confirm close to make sure everything is cleaned up */
+      if (session->session_state == STATE_VPP_CLOSING)
+       vcl_session_cleanup (wrk, session, vcl_session_handle (session),
+                            1 /* do_disconnect */ );
+      return;
+    }
+
   vcl_session_table_del_vpp_handle (wrk, msg->handle);
   /* Should not happen. App did not close the connection so don't free it. */
   if (session->session_state != STATE_CLOSED)
@@ -1211,8 +1224,8 @@ vppcom_app_create (char *app_name)
 void
 vppcom_app_destroy (void)
 {
+  vcl_worker_t *wrk, *current_wrk;
   struct dlmallinfo mi;
-  vcl_worker_t *wrk;
   mspace heap;
 
   if (!pool_elts (vcm->workers))
@@ -1220,16 +1233,19 @@ vppcom_app_destroy (void)
 
   vcl_evt (VCL_EVT_DETACH, vcm);
 
-  vcl_send_app_detach (vcl_worker_get_current ());
+  current_wrk = vcl_worker_get_current ();
 
   /* *INDENT-OFF* */
   pool_foreach (wrk, vcm->workers, ({
-    if (pool_elts (vcm->workers) == 1)
-      vl_client_disconnect_from_vlib ();
-    vcl_worker_cleanup (wrk, 0 /* notify vpp */ );
+    if (current_wrk != wrk)
+      vcl_worker_cleanup (wrk, 0 /* notify vpp */ );
   }));
   /* *INDENT-ON* */
 
+  vcl_send_app_detach (current_wrk);
+  vppcom_disconnect_from_vpp ();
+  vcl_worker_cleanup (current_wrk, 0 /* notify vpp */ );
+
   vcl_elog_stop (vcm);
 
   /*
@@ -1240,6 +1256,7 @@ vppcom_app_destroy (void)
   munmap (mspace_least_addr (heap), mi.arena);
 
   vcm = &_vppcom_main;
+  vcm->is_init = 0;
 }
 
 int
@@ -1541,10 +1558,6 @@ vppcom_unformat_proto (uint8_t * proto, char *proto_str)
     *proto = VPPCOM_PROTO_UDP;
   else if (!strcmp (proto_str, "udp"))
     *proto = VPPCOM_PROTO_UDP;
-  else if (!strcmp (proto_str, "UDPC"))
-    *proto = VPPCOM_PROTO_UDPC;
-  else if (!strcmp (proto_str, "udpc"))
-    *proto = VPPCOM_PROTO_UDPC;
   else if (!strcmp (proto_str, "TLS"))
     *proto = VPPCOM_PROTO_TLS;
   else if (!strcmp (proto_str, "tls"))
@@ -2908,7 +2921,7 @@ vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq,
        }
     }
   ASSERT (maxevents > *num_ev);
-  vcl_mq_dequeue_batch (wrk, mq, maxevents - *num_ev);
+  vcl_mq_dequeue_batch (wrk, mq, ~0);
   svm_msg_q_unlock (mq);
 
 handle_dequeued:
@@ -2916,7 +2929,10 @@ handle_dequeued:
     {
       msg = vec_elt_at_index (wrk->mq_msg_vector, i);
       e = svm_msg_q_msg_data (mq, msg);
-      vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
+      if (*num_ev < maxevents)
+       vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev);
+      else
+       vcl_handle_mq_event (wrk, e);
       svm_msg_q_free_msg (mq, msg);
     }
   vec_reset_length (wrk->mq_msg_vector);
@@ -3578,6 +3594,11 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
        *(int *) buffer = SHUT_RDWR;
       *buflen = sizeof (int);
       break;
+
+    case VPPCOM_ATTR_SET_CONNECTED:
+      session->flags |= VCL_SESSION_F_CONNECTED;
+      break;
+
     default:
       rv = VPPCOM_EINVAL;
       break;
@@ -3816,6 +3837,12 @@ vppcom_worker_unregister (void)
   vcl_set_worker_index (~0);
 }
 
+void
+vppcom_worker_index_set (int index)
+{
+  vcl_set_worker_index (index);
+}
+
 int
 vppcom_worker_index (void)
 {