api: improve REPLY_MACRO safety
[vpp.git] / src / vnet / session / session_api.c
index 371fcfc..767a24a 100644 (file)
@@ -601,6 +601,17 @@ vl_api_session_enable_disable_t_handler (vl_api_session_enable_disable_t * mp)
   REPLY_MACRO (VL_API_SESSION_ENABLE_DISABLE_REPLY);
 }
 
+static void
+vl_api_session_sapi_enable_disable_t_handler (
+  vl_api_session_sapi_enable_disable_t *mp)
+{
+  vl_api_session_sapi_enable_disable_reply_t *rmp;
+  int rv = 0;
+
+  rv = appns_sapi_enable_disable (mp->is_enable);
+  REPLY_MACRO (VL_API_SESSION_SAPI_ENABLE_DISABLE_REPLY);
+}
+
 static void
 vl_api_app_attach_t_handler (vl_api_app_attach_t * mp)
 {
@@ -685,25 +696,28 @@ vl_api_app_attach_t_handler (vl_api_app_attach_t * mp)
 
 done:
   /* *INDENT-OFF* */
-  REPLY_MACRO2 (VL_API_APP_ATTACH_REPLY, ({
-    if (!rv)
-      {
-       ctrl_thread = n_workers ? 1 : 0;
-       segp = (fifo_segment_t *) a->segment;
-       rmp->app_index = clib_host_to_net_u32 (a->app_index);
-       rmp->app_mq = fifo_segment_msg_q_offset (segp, 0);
-       rmp->vpp_ctrl_mq = fifo_segment_msg_q_offset (rx_mqs_seg, ctrl_thread);
-       rmp->vpp_ctrl_mq_thread = ctrl_thread;
-       rmp->n_fds = n_fds;
-       rmp->fd_flags = fd_flags;
-       if (vec_len (segp->ssvm.name))
-         {
-           vl_api_vec_to_api_string (segp->ssvm.name, &rmp->segment_name);
-         }
-       rmp->segment_size = segp->ssvm.ssvm_size;
-       rmp->segment_handle = clib_host_to_net_u64 (a->segment_handle);
-      }
-  }));
+  REPLY_MACRO3 (
+    VL_API_APP_ATTACH_REPLY,
+    ((!rv) ? vec_len (((fifo_segment_t *) a->segment)->ssvm.name) : 0), ({
+      if (!rv)
+       {
+         ctrl_thread = n_workers ? 1 : 0;
+         segp = (fifo_segment_t *) a->segment;
+         rmp->app_index = clib_host_to_net_u32 (a->app_index);
+         rmp->app_mq = fifo_segment_msg_q_offset (segp, 0);
+         rmp->vpp_ctrl_mq =
+           fifo_segment_msg_q_offset (rx_mqs_seg, ctrl_thread);
+         rmp->vpp_ctrl_mq_thread = ctrl_thread;
+         rmp->n_fds = n_fds;
+         rmp->fd_flags = fd_flags;
+         if (vec_len (segp->ssvm.name))
+           {
+             vl_api_vec_to_api_string (segp->ssvm.name, &rmp->segment_name);
+           }
+         rmp->segment_size = segp->ssvm.ssvm_size;
+         rmp->segment_handle = clib_host_to_net_u64 (a->segment_handle);
+       }
+    }));
   /* *INDENT-ON* */
 
   if (n_fds)
@@ -769,22 +783,25 @@ vl_api_app_worker_add_del_t_handler (vl_api_app_worker_add_del_t * mp)
 
   /* *INDENT-OFF* */
 done:
-  REPLY_MACRO2 (VL_API_APP_WORKER_ADD_DEL_REPLY, ({
-    rmp->is_add = mp->is_add;
-    rmp->wrk_index = clib_host_to_net_u32 (args.wrk_map_index);
-    rmp->segment_handle = clib_host_to_net_u64 (args.segment_handle);
-    if (!rv && mp->is_add)
-      {
-       rmp->app_event_queue_address =
-         fifo_segment_msg_q_offset ((fifo_segment_t *) args.segment, 0);
-       rmp->n_fds = n_fds;
-       rmp->fd_flags = fd_flags;
-       if (vec_len (args.segment->name))
-         {
-           vl_api_vec_to_api_string (args.segment->name, &rmp->segment_name);
-         }
-      }
-  }));
+  REPLY_MACRO3 (
+    VL_API_APP_WORKER_ADD_DEL_REPLY,
+    ((!rv && mp->is_add) ? vec_len (args.segment->name) : 0), ({
+      rmp->is_add = mp->is_add;
+      rmp->wrk_index = clib_host_to_net_u32 (args.wrk_map_index);
+      rmp->segment_handle = clib_host_to_net_u64 (args.segment_handle);
+      if (!rv && mp->is_add)
+       {
+         rmp->app_event_queue_address =
+           fifo_segment_msg_q_offset ((fifo_segment_t *) args.segment, 0);
+         rmp->n_fds = n_fds;
+         rmp->fd_flags = fd_flags;
+         if (vec_len (args.segment->name))
+           {
+             vl_api_vec_to_api_string (args.segment->name,
+                                       &rmp->segment_name);
+           }
+       }
+    }));
   /* *INDENT-ON* */
 
   if (n_fds)
@@ -834,6 +851,8 @@ vl_api_app_namespace_add_del_t_handler (vl_api_app_namespace_add_del_t * mp)
 
   vnet_app_namespace_add_del_args_t args = {
     .ns_id = ns_id,
+    .netns = 0,
+    .sock_name = 0,
     .secret = clib_net_to_host_u64 (mp->secret),
     .sw_if_index = clib_net_to_host_u32 (mp->sw_if_index),
     .ip4_fib_id = clib_net_to_host_u32 (mp->ip4_fib_id),
@@ -884,6 +903,7 @@ vl_api_app_namespace_add_del_v2_t_handler (
   vnet_app_namespace_add_del_args_t args = {
     .ns_id = ns_id,
     .netns = netns,
+    .sock_name = 0,
     .secret = clib_net_to_host_u64 (mp->secret),
     .sw_if_index = clib_net_to_host_u32 (mp->sw_if_index),
     .ip4_fib_id = clib_net_to_host_u32 (mp->ip4_fib_id),
@@ -896,7 +916,7 @@ vl_api_app_namespace_add_del_v2_t_handler (
       appns_index = app_namespace_index_from_id (ns_id);
       if (appns_index == APP_NAMESPACE_INVALID_INDEX)
        {
-         clib_warning ("app ns lookup failed");
+         clib_warning ("app ns lookup failed id:%s", ns_id);
          rv = VNET_API_ERROR_UNSPECIFIED;
        }
     }
@@ -910,6 +930,54 @@ done:
                }));
 }
 
+static void
+vl_api_app_namespace_add_del_v3_t_handler (
+  vl_api_app_namespace_add_del_v3_t *mp)
+{
+  vl_api_app_namespace_add_del_v3_reply_t *rmp;
+  u8 *ns_id = 0, *netns = 0, *sock_name = 0;
+  u32 appns_index = 0;
+  int rv = 0;
+  if (session_main_is_enabled () == 0)
+    {
+      rv = VNET_API_ERROR_FEATURE_DISABLED;
+      goto done;
+    }
+  mp->namespace_id[sizeof (mp->namespace_id) - 1] = 0;
+  mp->netns[sizeof (mp->netns) - 1] = 0;
+  ns_id = format (0, "%s", &mp->namespace_id);
+  netns = format (0, "%s", &mp->netns);
+  sock_name = vl_api_from_api_to_new_vec (mp, &mp->sock_name);
+  vnet_app_namespace_add_del_args_t args = {
+    .ns_id = ns_id,
+    .netns = netns,
+    .sock_name = sock_name,
+    .secret = clib_net_to_host_u64 (mp->secret),
+    .sw_if_index = clib_net_to_host_u32 (mp->sw_if_index),
+    .ip4_fib_id = clib_net_to_host_u32 (mp->ip4_fib_id),
+    .ip6_fib_id = clib_net_to_host_u32 (mp->ip6_fib_id),
+    .is_add = mp->is_add,
+  };
+  rv = vnet_app_namespace_add_del (&args);
+  if (!rv && mp->is_add)
+    {
+      appns_index = app_namespace_index_from_id (ns_id);
+      if (appns_index == APP_NAMESPACE_INVALID_INDEX)
+       {
+         clib_warning ("app ns lookup failed id:%s", ns_id);
+         rv = VNET_API_ERROR_UNSPECIFIED;
+       }
+    }
+  vec_free (ns_id);
+  vec_free (netns);
+  vec_free (sock_name);
+done:
+  REPLY_MACRO2 (VL_API_APP_NAMESPACE_ADD_DEL_V3_REPLY, ({
+                 if (!rv)
+                   rmp->appns_index = clib_host_to_net_u32 (appns_index);
+               }));
+}
+
 static void
 vl_api_session_rule_add_del_t_handler (vl_api_session_rule_add_del_t * mp)
 {
@@ -1711,6 +1779,23 @@ error:
   return err;
 }
 
+void
+appns_sapi_del_ns_socket (app_namespace_t *app_ns)
+{
+  app_ns_api_handle_t *handle;
+  clib_socket_t *cs;
+
+  pool_foreach (cs, app_ns->app_sockets)
+    {
+      handle = (app_ns_api_handle_t *) &cs->private_data;
+      clib_file_del_by_index (&file_main, handle->aah_file_index);
+
+      clib_socket_close (cs);
+      clib_socket_free (cs);
+    }
+  pool_free (app_ns->app_sockets);
+}
+
 int
 appns_sapi_add_ns_socket (app_namespace_t * app_ns)
 {
@@ -1722,25 +1807,33 @@ appns_sapi_add_ns_socket (app_namespace_t * app_ns)
   clib_socket_t *cs;
   char dir[4096];
 
-  snprintf (dir, sizeof (dir), "%s%s", vlib_unix_get_runtime_dir (), subdir);
-  err = vlib_unix_recursive_mkdir ((char *) dir);
-  if (err)
+  if (app_ns->netns)
     {
-      clib_error_report (err);
-      return -1;
+      if (!app_ns->sock_name)
+       app_ns->sock_name = format (0, "@vpp/session/%v%c", app_ns->ns_id, 0);
+      if (app_ns->sock_name[0] != '@')
+       return VNET_API_ERROR_INVALID_VALUE;
     }
-
-  /* Use abstract sockets if a netns was provided */
-  if (app_ns->netns)
-    app_ns->sock_name = format (0, "@vpp/session/%v%c", app_ns->ns_id, 0);
   else
-    app_ns->sock_name = format (0, "%s%v%c", dir, app_ns->ns_id, 0);
+    {
+      snprintf (dir, sizeof (dir), "%s%s", vlib_unix_get_runtime_dir (),
+               subdir);
+      err = vlib_unix_recursive_mkdir ((char *) dir);
+      if (err)
+       {
+         clib_error_report (err);
+         return VNET_API_ERROR_SYSCALL_ERROR_1;
+       }
+
+      if (!app_ns->sock_name)
+       app_ns->sock_name = format (0, "%s%v%c", dir, app_ns->ns_id, 0);
+    }
 
   /*
    * Create and initialize socket to listen on
    */
   cs = appns_sapi_alloc_socket (app_ns);
-  cs->config = (char *) app_ns->sock_name;
+  cs->config = (char *) vec_dup (app_ns->sock_name);
   cs->flags = CLIB_SOCKET_F_IS_SERVER |
     CLIB_SOCKET_F_ALLOW_GROUP_WRITE |
     CLIB_SOCKET_F_SEQPACKET | CLIB_SOCKET_F_PASSCRED;