LCOV - code coverage report
Current view: top level - vnet/session - application_interface.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 81 111 73.0 %
Date: 2023-07-05 22:20:52 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016-2019 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : #ifndef __included_uri_h__
      16             : #define __included_uri_h__
      17             : 
      18             : #include <vlibmemory/api.h>
      19             : #include <svm/message_queue.h>
      20             : #include <vnet/session/session_types.h>
      21             : #include <vnet/tls/tls_test.h>
      22             : #include <svm/fifo_segment.h>
      23             : 
      24             : typedef struct certificate_
      25             : {
      26             :   u32 *app_interests;           /* vec of application index asking for deletion cb */
      27             :   u32 cert_key_index;           /* index in cert & key pool */
      28             :   u8 *key;
      29             :   u8 *cert;
      30             : } app_cert_key_pair_t;
      31             : 
      32             : typedef struct session_cb_vft_
      33             : {
      34             :   /** Notify server of new segment */
      35             :   int (*add_segment_callback) (u32 app_wrk_index, u64 segment_handle);
      36             : 
      37             :   /** Notify server of new segment */
      38             :   int (*del_segment_callback) (u32 app_wrk_index, u64 segment_handle);
      39             : 
      40             :   /** Notify server of newly accepted session */
      41             :   int (*session_accept_callback) (session_t * new_session);
      42             : 
      43             :   /** Connection request callback */
      44             :   int (*session_connected_callback) (u32 app_wrk_index, u32 opaque,
      45             :                                      session_t * s, session_error_t code);
      46             : 
      47             :   /** Notify app that session is closing */
      48             :   void (*session_disconnect_callback) (session_t * s);
      49             : 
      50             :   /** Notify app that transport is closed */
      51             :   void (*session_transport_closed_callback) (session_t * s);
      52             : 
      53             :   /** Notify app that session or transport are about to be removed */
      54             :   void (*session_cleanup_callback) (session_t * s, session_cleanup_ntf_t ntf);
      55             : 
      56             :   /** Notify app that half open state was cleaned up (optional) */
      57             :   void (*half_open_cleanup_callback) (session_t *s);
      58             : 
      59             :   /** Notify app that session was reset */
      60             :   void (*session_reset_callback) (session_t * s);
      61             : 
      62             :   /** Notify app that session pool migration happened */
      63             :   void (*session_migrate_callback) (session_t * s, session_handle_t new_sh);
      64             : 
      65             :   /** Direct RX callback for built-in application */
      66             :   int (*builtin_app_rx_callback) (session_t * session);
      67             : 
      68             :   /** Direct TX callback for built-in application */
      69             :   int (*builtin_app_tx_callback) (session_t * session);
      70             : 
      71             :   /** Cert and key pair delete notification */
      72             :   int (*app_cert_key_pair_delete_callback) (app_cert_key_pair_t * ckpair);
      73             : 
      74             :   /** Delegate fifo-tuning-logic to application */
      75             :   int (*fifo_tuning_callback) (session_t * s, svm_fifo_t * f,
      76             :                                session_ft_action_t act, u32 bytes);
      77             : 
      78             : } session_cb_vft_t;
      79             : 
      80             : #define foreach_app_init_args                   \
      81             :   _(u32, api_client_index)                      \
      82             :   _(u8 *, name)                                 \
      83             :   _(u64 *, options)                             \
      84             :   _(u8 *, namespace_id)                         \
      85             :   _(session_cb_vft_t *, session_cb_vft)         \
      86             :   _(u32, app_index)                             \
      87             :   _(u8, use_sock_api)                           \
      88             : 
      89             : typedef struct _vnet_app_attach_args_t
      90             : {
      91             : #define _(_type, _name) _type _name;
      92             :   foreach_app_init_args
      93             : #undef _
      94             :   ssvm_private_t * segment;
      95             :   svm_msg_q_t *app_evt_q;
      96             :   u64 segment_handle;
      97             : } vnet_app_attach_args_t;
      98             : 
      99             : typedef struct _vnet_app_detach_args_t
     100             : {
     101             :   u32 app_index;
     102             :   u32 api_client_index;
     103             : } vnet_app_detach_args_t;
     104             : 
     105             : typedef struct _vnet_bind_args_t
     106             : {
     107             :   union
     108             :   {
     109             :     session_endpoint_cfg_t sep_ext;
     110             :     session_endpoint_t sep;
     111             :     char *uri;
     112             :   };
     113             : 
     114             :   u32 app_index;
     115             :   u32 wrk_map_index;
     116             : 
     117             :   /*
     118             :    * Results
     119             :    */
     120             :   u64 handle;
     121             : } vnet_listen_args_t;
     122             : 
     123             : typedef struct _vnet_unlisten_args_t
     124             : {
     125             :   union
     126             :   {
     127             :     char *uri;
     128             :     u64 handle;                 /**< Session handle */
     129             :   };
     130             :   u32 app_index;                /**< Owning application index */
     131             :   u32 wrk_map_index;            /**< App's local pool worker index */
     132             : } vnet_unlisten_args_t;
     133             : 
     134             : typedef struct _vnet_connect_args
     135             : {
     136             :   union
     137             :   {
     138             :     session_endpoint_cfg_t sep_ext;
     139             :     session_endpoint_t sep;
     140             :     char *uri;
     141             :   };
     142             :   u32 app_index;
     143             :   u32 wrk_map_index;
     144             :   u32 api_context;
     145             : 
     146             :   /* Resulting session, or half-open session, if connect successful */
     147             :   session_handle_t sh;
     148             : } vnet_connect_args_t;
     149             : 
     150             : typedef struct _vnet_shutdown_args_t
     151             : {
     152             :   session_handle_t handle;
     153             :   u32 app_index;
     154             : } vnet_shutdown_args_t;
     155             : 
     156             : typedef struct _vnet_disconnect_args_t
     157             : {
     158             :   session_handle_t handle;
     159             :   u32 app_index;
     160             : } vnet_disconnect_args_t;
     161             : 
     162             : typedef struct _vnet_application_add_tls_cert_args_t
     163             : {
     164             :   u32 app_index;
     165             :   u8 *cert;
     166             : } vnet_app_add_tls_cert_args_t;
     167             : 
     168             : typedef struct _vnet_application_add_tls_key_args_t
     169             : {
     170             :   u32 app_index;
     171             :   u8 *key;
     172             : } vnet_app_add_tls_key_args_t;
     173             : 
     174             : typedef enum crypto_engine_type_
     175             : {
     176             :   CRYPTO_ENGINE_NONE,
     177             :   CRYPTO_ENGINE_OPENSSL,
     178             :   CRYPTO_ENGINE_MBEDTLS,
     179             :   CRYPTO_ENGINE_VPP,
     180             :   CRYPTO_ENGINE_PICOTLS,
     181             :   CRYPTO_ENGINE_LAST = CRYPTO_ENGINE_PICOTLS,
     182             : } crypto_engine_type_t;
     183             : 
     184             : typedef struct _vnet_app_add_cert_key_pair_args_
     185             : {
     186             :   u8 *cert;
     187             :   u8 *key;
     188             :   u32 cert_len;
     189             :   u32 key_len;
     190             :   u32 index;
     191             : } vnet_app_add_cert_key_pair_args_t;
     192             : 
     193             : typedef struct crypto_ctx_
     194             : {
     195             :   u32 ctx_index;                /**< index in crypto context pool */
     196             :   u32 n_subscribers;            /**< refcount of sessions using said context */
     197             :   u32 ckpair_index;             /**< certificate & key */
     198             :   u8 crypto_engine;
     199             :   void *data;                   /**< protocol specific data */
     200             : } crypto_context_t;
     201             : 
     202             : /* Application attach options */
     203             : typedef enum
     204             : {
     205             :   APP_OPTIONS_FLAGS,
     206             :   APP_OPTIONS_EVT_QUEUE_SIZE,
     207             :   APP_OPTIONS_SEGMENT_SIZE,
     208             :   APP_OPTIONS_ADD_SEGMENT_SIZE,
     209             :   APP_OPTIONS_PRIVATE_SEGMENT_COUNT,
     210             :   APP_OPTIONS_RX_FIFO_SIZE,
     211             :   APP_OPTIONS_TX_FIFO_SIZE,
     212             :   APP_OPTIONS_PREALLOC_FIFO_PAIRS,
     213             :   APP_OPTIONS_PREALLOC_FIFO_HDRS,
     214             :   APP_OPTIONS_NAMESPACE,
     215             :   APP_OPTIONS_NAMESPACE_SECRET,
     216             :   APP_OPTIONS_PROXY_TRANSPORT,
     217             :   APP_OPTIONS_ACCEPT_COOKIE,
     218             :   APP_OPTIONS_TLS_ENGINE,
     219             :   APP_OPTIONS_MAX_FIFO_SIZE,
     220             :   APP_OPTIONS_HIGH_WATERMARK,
     221             :   APP_OPTIONS_LOW_WATERMARK,
     222             :   APP_OPTIONS_PCT_FIRST_ALLOC,
     223             :   APP_OPTIONS_N_OPTIONS
     224             : } app_attach_options_index_t;
     225             : 
     226             : #define foreach_app_options_flags                                             \
     227             :   _ (ACCEPT_REDIRECT, "Use FIFO with redirects")                              \
     228             :   _ (ADD_SEGMENT, "Add segment and signal app if needed")                     \
     229             :   _ (IS_BUILTIN, "Application is builtin")                                    \
     230             :   _ (IS_TRANSPORT_APP, "Application is a transport proto")                    \
     231             :   _ (IS_PROXY, "Application is proxying")                                     \
     232             :   _ (USE_GLOBAL_SCOPE, "App can use global session scope")                    \
     233             :   _ (USE_LOCAL_SCOPE, "App can use local session scope")                      \
     234             :   _ (EVT_MQ_USE_EVENTFD, "Use eventfds for signaling")                        \
     235             :   _ (MEMFD_FOR_BUILTIN, "Use memfd for builtin app segs")                     \
     236             :   _ (USE_HUGE_PAGE, "Use huge page for FIFO")
     237             : 
     238             : typedef enum _app_options
     239             : {
     240             : #define _(sym, str) APP_OPTIONS_##sym,
     241             :   foreach_app_options_flags
     242             : #undef _
     243             : } app_options_t;
     244             : 
     245             : typedef enum _app_options_flags
     246             : {
     247             : #define _(sym, str) APP_OPTIONS_FLAGS_##sym = 1 << APP_OPTIONS_##sym,
     248             :   foreach_app_options_flags
     249             : #undef _
     250             : } app_options_flags_t;
     251             : 
     252             : #define foreach_fd_type                                         \
     253             :   _(VPP_MQ_SEGMENT, "Fd for vpp's event mq segment")          \
     254             :   _(MEMFD_SEGMENT, "Fd for memfd segment")                    \
     255             :   _(MQ_EVENTFD, "Event fd used by message queue")             \
     256             :   _(VPP_MQ_EVENTFD, "Event fd used by vpp's message queue")   \
     257             : 
     258             : typedef enum session_fd_type_
     259             : {
     260             : #define _(sym, str) SESSION_FD_##sym,
     261             :   foreach_fd_type
     262             : #undef _
     263             :   SESSION_N_FD_TYPE
     264             : } session_fd_type_t;
     265             : 
     266             : typedef enum session_fd_flag_
     267             : {
     268             : #define _(sym, str) SESSION_FD_F_##sym = 1 << SESSION_FD_##sym,
     269             :   foreach_fd_type
     270             : #undef _
     271             : } session_fd_flag_t;
     272             : 
     273             : int parse_uri (char *uri, session_endpoint_cfg_t * sep);
     274             : int vnet_bind_uri (vnet_listen_args_t *);
     275             : int vnet_unbind_uri (vnet_unlisten_args_t * a);
     276             : int vnet_connect_uri (vnet_connect_args_t * a);
     277             : 
     278             : int vnet_application_attach (vnet_app_attach_args_t * a);
     279             : int vnet_application_detach (vnet_app_detach_args_t * a);
     280             : int vnet_listen (vnet_listen_args_t * a);
     281             : int vnet_connect (vnet_connect_args_t * a);
     282             : int vnet_unlisten (vnet_unlisten_args_t * a);
     283             : int vnet_shutdown_session (vnet_shutdown_args_t *a);
     284             : int vnet_disconnect_session (vnet_disconnect_args_t * a);
     285             : 
     286             : int vnet_app_add_cert_key_pair (vnet_app_add_cert_key_pair_args_t * a);
     287             : int vnet_app_del_cert_key_pair (u32 index);
     288             : /** Ask for app cb on pair deletion */
     289             : int vnet_app_add_cert_key_interest (u32 index, u32 app_index);
     290             : 
     291             : uword unformat_vnet_uri (unformat_input_t *input, va_list *args);
     292             : 
     293             : typedef struct app_session_transport_
     294             : {
     295             :   ip46_address_t rmt_ip;        /**< remote ip */
     296             :   ip46_address_t lcl_ip;        /**< local ip */
     297             :   u16 rmt_port;                 /**< remote port (network order) */
     298             :   u16 lcl_port;                 /**< local port (network order) */
     299             :   u8 is_ip4;                    /**< set if uses ip4 networking */
     300             : } app_session_transport_t;
     301             : 
     302             : #define foreach_app_session_field                                       \
     303             :   _(svm_fifo_t, *rx_fifo)               /**< rx fifo */                      \
     304             :   _(svm_fifo_t, *tx_fifo)               /**< tx fifo */                      \
     305             :   _(session_type_t, session_type)       /**< session type */         \
     306             :   _(volatile u8, session_state)         /**< session state */                \
     307             :   _(u32, session_index)                 /**< index in owning pool */ \
     308             :   _(app_session_transport_t, transport) /**< transport info */               \
     309             :   _(svm_msg_q_t, *vpp_evt_q)            /**< vpp event queue  */     \
     310             :   _(u8, is_dgram)                       /**< flag for dgram mode */  \
     311             : 
     312             : typedef struct
     313             : {
     314             : #define _(type, name) type name;
     315             :   foreach_app_session_field
     316             : #undef _
     317             : } app_session_t;
     318             : 
     319             : typedef struct session_listen_msg_
     320             : {
     321             :   u32 client_index;
     322             :   u32 context;                  /* Not needed but keeping it for compatibility with bapi */
     323             :   u32 wrk_index;
     324             :   u32 vrf;
     325             :   u16 port;
     326             :   u8 proto;
     327             :   u8 is_ip4;
     328             :   ip46_address_t ip;
     329             :   u8 flags;
     330             :   uword ext_config;
     331             : } __clib_packed session_listen_msg_t;
     332             : 
     333             : STATIC_ASSERT (sizeof (session_listen_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
     334             :                "msg too large");
     335             : 
     336             : typedef struct session_listen_uri_msg_
     337             : {
     338             :   u32 client_index;
     339             :   u32 context;
     340             :   u8 uri[56];
     341             : } __clib_packed session_listen_uri_msg_t;
     342             : 
     343             : STATIC_ASSERT (sizeof (session_listen_uri_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
     344             :                "msg too large");
     345             : 
     346             : typedef struct session_bound_msg_
     347             : {
     348             :   u32 context;
     349             :   u64 handle;
     350             :   i32 retval;
     351             :   u8 lcl_is_ip4;
     352             :   u8 lcl_ip[16];
     353             :   u16 lcl_port;
     354             :   uword rx_fifo;
     355             :   uword tx_fifo;
     356             :   uword vpp_evt_q;
     357             :   u64 segment_handle;
     358             :   u32 mq_index;
     359             : } __clib_packed session_bound_msg_t;
     360             : 
     361             : typedef struct session_unlisten_msg_
     362             : {
     363             :   u32 client_index;
     364             :   u32 context;
     365             :   u32 wrk_index;
     366             :   session_handle_t handle;
     367             : } __clib_packed session_unlisten_msg_t;
     368             : 
     369             : typedef struct session_unlisten_reply_msg_
     370             : {
     371             :   u32 context;
     372             :   u64 handle;
     373             :   i32 retval;
     374             : } __clib_packed session_unlisten_reply_msg_t;
     375             : 
     376             : typedef struct session_accepted_msg_
     377             : {
     378             :   u32 context;
     379             :   u64 listener_handle;
     380             :   u64 handle;
     381             :   uword server_rx_fifo;
     382             :   uword server_tx_fifo;
     383             :   u64 segment_handle;
     384             :   uword vpp_event_queue_address;
     385             :   u32 mq_index;
     386             :   transport_endpoint_t lcl;
     387             :   transport_endpoint_t rmt;
     388             :   u8 flags;
     389             : } __clib_packed session_accepted_msg_t;
     390             : 
     391             : typedef struct session_accepted_reply_msg_
     392             : {
     393             :   u32 context;
     394             :   i32 retval;
     395             :   u64 handle;
     396             : } __clib_packed session_accepted_reply_msg_t;
     397             : 
     398             : typedef struct session_connect_msg_
     399             : {
     400             :   u32 client_index;
     401             :   u32 context;
     402             :   u32 wrk_index;
     403             :   u32 vrf;
     404             :   u16 port;
     405             :   u16 lcl_port;
     406             :   u8 proto;
     407             :   u8 is_ip4;
     408             :   ip46_address_t ip;
     409             :   ip46_address_t lcl_ip;
     410             :   u64 parent_handle;
     411             :   u32 ckpair_index;
     412             :   u8 crypto_engine;
     413             :   u8 flags;
     414             :   u8 dscp;
     415             :   uword ext_config;
     416             : } __clib_packed session_connect_msg_t;
     417             : 
     418             : STATIC_ASSERT (sizeof (session_connect_msg_t) <= SESSION_CTRL_MSG_MAX_SIZE,
     419             :                "msg too large");
     420             : 
     421             : typedef struct session_connect_uri_msg_
     422             : {
     423             :   u32 client_index;
     424             :   u32 context;
     425             :   u8 uri[56];
     426             : } __clib_packed session_connect_uri_msg_t;
     427             : 
     428             : STATIC_ASSERT (sizeof (session_connect_uri_msg_t) <=
     429             :                SESSION_CTRL_MSG_MAX_SIZE, "msg too large");
     430             : 
     431             : typedef struct session_connected_msg_
     432             : {
     433             :   u32 context;
     434             :   i32 retval;
     435             :   u64 handle;
     436             :   uword server_rx_fifo;
     437             :   uword server_tx_fifo;
     438             :   u64 segment_handle;
     439             :   uword ct_rx_fifo;
     440             :   uword ct_tx_fifo;
     441             :   u64 ct_segment_handle;
     442             :   uword vpp_event_queue_address;
     443             :   transport_endpoint_t lcl;
     444             :   u32 mq_index;
     445             : } __clib_packed session_connected_msg_t;
     446             : 
     447             : typedef struct session_shutdown_msg_
     448             : {
     449             :   u32 client_index;
     450             :   u32 context;
     451             :   session_handle_t handle;
     452             : } __clib_packed session_shutdown_msg_t;
     453             : 
     454             : typedef struct session_disconnect_msg_
     455             : {
     456             :   u32 client_index;
     457             :   u32 context;
     458             :   session_handle_t handle;
     459             : } __clib_packed session_disconnect_msg_t;
     460             : 
     461             : typedef struct session_disconnected_msg_
     462             : {
     463             :   u32 client_index;
     464             :   u32 context;
     465             :   u64 handle;
     466             : } __clib_packed session_disconnected_msg_t;
     467             : 
     468             : typedef struct session_disconnected_reply_msg_
     469             : {
     470             :   u32 context;
     471             :   i32 retval;
     472             :   u64 handle;
     473             : } __clib_packed session_disconnected_reply_msg_t;
     474             : 
     475             : typedef struct session_reset_msg_
     476             : {
     477             :   u32 client_index;
     478             :   u32 context;
     479             :   u64 handle;
     480             : } __clib_packed session_reset_msg_t;
     481             : 
     482             : typedef struct session_reset_reply_msg_
     483             : {
     484             :   u32 context;
     485             :   i32 retval;
     486             :   u64 handle;
     487             : } __clib_packed session_reset_reply_msg_t;
     488             : 
     489             : typedef struct session_req_worker_update_msg_
     490             : {
     491             :   u64 session_handle;
     492             : } __clib_packed session_req_worker_update_msg_t;
     493             : 
     494             : /* NOTE: using u16 for wrk indices because message needs to fit in 18B */
     495             : typedef struct session_worker_update_msg_
     496             : {
     497             :   u32 client_index;
     498             :   u16 wrk_index;
     499             :   u16 req_wrk_index;
     500             :   u64 handle;
     501             : } __clib_packed session_worker_update_msg_t;
     502             : 
     503             : typedef struct session_worker_update_reply_msg_
     504             : {
     505             :   u64 handle;
     506             :   uword rx_fifo;
     507             :   uword tx_fifo;
     508             :   u64 segment_handle;
     509             : } __clib_packed session_worker_update_reply_msg_t;
     510             : 
     511             : typedef struct session_app_detach_msg_
     512             : {
     513             :   u32 client_index;
     514             :   u32 context;
     515             : } session_app_detach_msg_t;
     516             : 
     517             : typedef struct app_map_another_segment_msg_
     518             : {
     519             :   u32 client_index;
     520             :   u32 context;
     521             :   u8 fd_flags;
     522             :   u32 segment_size;
     523             :   u8 segment_name[128];
     524             :   u64 segment_handle;
     525             : } session_app_add_segment_msg_t;
     526             : 
     527             : typedef struct app_unmap_segment_msg_
     528             : {
     529             :   u32 client_index;
     530             :   u32 context;
     531             :   u64 segment_handle;
     532             : } session_app_del_segment_msg_t;
     533             : 
     534             : typedef struct session_migrate_msg_
     535             : {
     536             :   uword vpp_evt_q;
     537             :   session_handle_t handle;
     538             :   session_handle_t new_handle;
     539             :   u64 segment_handle;
     540             :   u32 vpp_thread_index;
     541             : } __clib_packed session_migrated_msg_t;
     542             : 
     543             : typedef struct session_cleanup_msg_
     544             : {
     545             :   session_handle_t handle;
     546             :   u8 type;
     547             : } __clib_packed session_cleanup_msg_t;
     548             : 
     549             : typedef struct session_app_wrk_rpc_msg_
     550             : {
     551             :   u32 client_index;     /**< app client index */
     552             :   u32 wrk_index;        /**< dst worker index */
     553             :   u8 data[64];          /**< rpc data */
     554             : } __clib_packed session_app_wrk_rpc_msg_t;
     555             : 
     556             : typedef struct session_transport_attr_msg_
     557             : {
     558             :   u32 client_index;
     559             :   session_handle_t handle;
     560             :   transport_endpt_attr_t attr;
     561             :   u8 is_get;
     562             : } __clib_packed session_transport_attr_msg_t;
     563             : 
     564             : typedef struct session_transport_attr_reply_msg_
     565             : {
     566             :   i32 retval;
     567             :   session_handle_t handle;
     568             :   transport_endpt_attr_t attr;
     569             :   u8 is_get;
     570             : } __clib_packed session_transport_attr_reply_msg_t;
     571             : 
     572             : typedef struct app_session_event_
     573             : {
     574             :   svm_msg_q_msg_t msg;
     575             :   session_event_t *evt;
     576             : } __clib_packed app_session_evt_t;
     577             : 
     578             : static inline void
     579         260 : app_alloc_ctrl_evt_to_vpp (svm_msg_q_t * mq, app_session_evt_t * app_evt,
     580             :                            u8 evt_type)
     581             : {
     582         260 :   svm_msg_q_lock_and_alloc_msg_w_ring (mq,
     583             :                                        SESSION_MQ_CTRL_EVT_RING,
     584             :                                        SVM_Q_WAIT, &app_evt->msg);
     585         260 :   app_evt->evt = svm_msg_q_msg_data (mq, &app_evt->msg);
     586         260 :   clib_memset (app_evt->evt, 0, sizeof (*app_evt->evt));
     587         260 :   app_evt->evt->event_type = evt_type;
     588         260 : }
     589             : 
     590             : static inline void
     591         260 : app_send_ctrl_evt_to_vpp (svm_msg_q_t * mq, app_session_evt_t * app_evt)
     592             : {
     593         260 :   svm_msg_q_add_and_unlock (mq, &app_evt->msg);
     594         260 : }
     595             : 
     596             : /**
     597             :  * Send fifo io event to vpp worker thread
     598             :  *
     599             :  * Because there may be multiple writers to one of vpp's queues, this
     600             :  * protects message allocation and enqueueing.
     601             :  *
     602             :  * @param mq            vpp message queue
     603             :  * @param f             fifo for which the event is sent
     604             :  * @param evt_type      type of event
     605             :  * @param noblock       flag to indicate is request is blocking or not
     606             :  * @return              0 if success, negative integer otherwise
     607             :  */
     608             : static inline int
     609      135738 : app_send_io_evt_to_vpp (svm_msg_q_t * mq, u32 session_index, u8 evt_type,
     610             :                         u8 noblock)
     611             : {
     612             :   session_event_t *evt;
     613             :   svm_msg_q_msg_t msg;
     614             : 
     615      135738 :   if (noblock)
     616             :     {
     617           0 :       if (svm_msg_q_try_lock (mq))
     618           0 :         return -1;
     619           0 :       if (PREDICT_FALSE (
     620             :             svm_msg_q_or_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)))
     621             :         {
     622           0 :           svm_msg_q_unlock (mq);
     623           0 :           return -2;
     624             :         }
     625           0 :       msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
     626           0 :       evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
     627           0 :       evt->session_index = session_index;
     628           0 :       evt->event_type = evt_type;
     629           0 :       svm_msg_q_add_and_unlock (mq, &msg);
     630           0 :       return 0;
     631             :     }
     632             :   else
     633             :     {
     634      135738 :       svm_msg_q_lock (mq);
     635      135738 :       while (svm_msg_q_or_ring_is_full (mq, SESSION_MQ_IO_EVT_RING))
     636           0 :         svm_msg_q_or_ring_wait_prod (mq, SESSION_MQ_IO_EVT_RING);
     637      135738 :       msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
     638      135738 :       evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
     639      135738 :       evt->session_index = session_index;
     640      135738 :       evt->event_type = evt_type;
     641      135738 :       svm_msg_q_add_and_unlock (mq, &msg);
     642      135738 :       return 0;
     643             :     }
     644             : }
     645             : 
     646             : #define app_send_dgram_raw(f, at, vpp_evt_q, data, len, evt_type, do_evt,     \
     647             :                            noblock)                                           \
     648             :   app_send_dgram_raw_gso (f, at, vpp_evt_q, data, len, 0, evt_type, do_evt,   \
     649             :                           noblock)
     650             : 
     651             : always_inline int
     652        9569 : app_send_dgram_raw_gso (svm_fifo_t *f, app_session_transport_t *at,
     653             :                         svm_msg_q_t *vpp_evt_q, u8 *data, u32 len,
     654             :                         u16 gso_size, u8 evt_type, u8 do_evt, u8 noblock)
     655             : {
     656             :   session_dgram_hdr_t hdr;
     657             :   int rv;
     658        9569 :   if (svm_fifo_max_enqueue_prod (f) < (sizeof (session_dgram_hdr_t) + len))
     659           0 :     return 0;
     660             : 
     661        9569 :   hdr.data_length = len;
     662        9569 :   hdr.data_offset = 0;
     663        9569 :   clib_memcpy_fast (&hdr.rmt_ip, &at->rmt_ip, sizeof (ip46_address_t));
     664        9569 :   hdr.is_ip4 = at->is_ip4;
     665        9569 :   hdr.rmt_port = at->rmt_port;
     666        9569 :   clib_memcpy_fast (&hdr.lcl_ip, &at->lcl_ip, sizeof (ip46_address_t));
     667        9569 :   hdr.lcl_port = at->lcl_port;
     668        9569 :   hdr.gso_size = gso_size;
     669             :   /* *INDENT-OFF* */
     670        9569 :   svm_fifo_seg_t segs[2] = {{ (u8 *) &hdr, sizeof (hdr) }, { data, len }};
     671             :   /* *INDENT-ON* */
     672             : 
     673        9569 :   rv = svm_fifo_enqueue_segments (f, segs, 2, 0 /* allow partial */ );
     674        9569 :   if (PREDICT_FALSE (rv < 0))
     675           0 :     return 0;
     676             : 
     677        9569 :   if (do_evt)
     678             :     {
     679        8189 :       if (svm_fifo_set_event (f))
     680        7194 :         app_send_io_evt_to_vpp (vpp_evt_q, f->shr->master_session_index,
     681             :                                 evt_type, noblock);
     682             :     }
     683        9569 :   return len;
     684             : }
     685             : 
     686             : always_inline int
     687        7183 : app_send_dgram (app_session_t * s, u8 * data, u32 len, u8 noblock)
     688             : {
     689        7183 :   return app_send_dgram_raw (s->tx_fifo, &s->transport, s->vpp_evt_q, data,
     690             :                              len, SESSION_IO_EVT_TX, 1 /* do_evt */ ,
     691             :                              noblock);
     692             : }
     693             : 
     694             : always_inline int
     695     3073758 : app_send_stream_raw (svm_fifo_t * f, svm_msg_q_t * vpp_evt_q, u8 * data,
     696             :                      u32 len, u8 evt_type, u8 do_evt, u8 noblock)
     697             : {
     698             :   int rv;
     699             : 
     700     3073758 :   rv = svm_fifo_enqueue (f, len, data);
     701     3073758 :   if (do_evt)
     702             :     {
     703     2911489 :       if (rv > 0 && svm_fifo_set_event (f))
     704        2691 :         app_send_io_evt_to_vpp (vpp_evt_q, f->shr->master_session_index,
     705             :                                 evt_type, noblock);
     706             :     }
     707     3073758 :   return rv;
     708             : }
     709             : 
     710             : always_inline int
     711     2884632 : app_send_stream (app_session_t * s, u8 * data, u32 len, u8 noblock)
     712             : {
     713     2884632 :   return app_send_stream_raw (s->tx_fifo, s->vpp_evt_q, data, len,
     714             :                               SESSION_IO_EVT_TX, 1 /* do_evt */ , noblock);
     715             : }
     716             : 
     717             : always_inline int
     718     2873560 : app_send (app_session_t * s, u8 * data, u32 len, u8 noblock)
     719             : {
     720     2873560 :   if (s->is_dgram)
     721           0 :     return app_send_dgram (s, data, len, noblock);
     722     2873560 :   return app_send_stream (s, data, len, noblock);
     723             : }
     724             : 
     725             : always_inline int
     726        2390 : app_recv_dgram_raw (svm_fifo_t * f, u8 * buf, u32 len,
     727             :                     app_session_transport_t * at, u8 clear_evt, u8 peek)
     728             : {
     729             :   session_dgram_pre_hdr_t ph;
     730             :   u32 max_deq;
     731             :   int rv;
     732             : 
     733        2390 :   max_deq = svm_fifo_max_dequeue_cons (f);
     734        2390 :   if (max_deq <= sizeof (session_dgram_hdr_t))
     735             :     {
     736           5 :       if (clear_evt)
     737           0 :         svm_fifo_unset_event (f);
     738           5 :       return 0;
     739             :     }
     740             : 
     741        2385 :   if (clear_evt)
     742           0 :     svm_fifo_unset_event (f);
     743             : 
     744        2385 :   svm_fifo_peek (f, 0, sizeof (ph), (u8 *) & ph);
     745        2385 :   ASSERT (ph.data_length >= ph.data_offset);
     746             : 
     747             :   /* Check if we have the full dgram */
     748        2385 :   if (max_deq < (ph.data_length + SESSION_CONN_HDR_LEN)
     749           0 :       && len >= ph.data_length)
     750           0 :     return 0;
     751             : 
     752        2385 :   svm_fifo_peek (f, sizeof (ph), sizeof (*at), (u8 *) at);
     753        2385 :   len = clib_min (len, ph.data_length - ph.data_offset);
     754        2385 :   rv = svm_fifo_peek (f, ph.data_offset + SESSION_CONN_HDR_LEN, len, buf);
     755        2385 :   if (peek)
     756           0 :     return rv;
     757             : 
     758             :   /* Discards data that did not fit in buffer */
     759        2385 :   svm_fifo_dequeue_drop (f, ph.data_length + SESSION_CONN_HDR_LEN);
     760             : 
     761        2385 :   return rv;
     762             : }
     763             : 
     764             : always_inline int
     765           0 : app_recv_dgram (app_session_t * s, u8 * buf, u32 len)
     766             : {
     767           0 :   return app_recv_dgram_raw (s->rx_fifo, buf, len, &s->transport, 1, 0);
     768             : }
     769             : 
     770             : always_inline int
     771     8114479 : app_recv_stream_raw (svm_fifo_t * f, u8 * buf, u32 len, u8 clear_evt, u8 peek)
     772             : {
     773     8114479 :   if (clear_evt)
     774     7320830 :     svm_fifo_unset_event (f);
     775             : 
     776     8114479 :   if (peek)
     777           0 :     return svm_fifo_peek (f, 0, len, buf);
     778             : 
     779     8114479 :   return svm_fifo_dequeue (f, len, buf);
     780             : }
     781             : 
     782             : always_inline int
     783     7320830 : app_recv_stream (app_session_t * s, u8 * buf, u32 len)
     784             : {
     785     7320830 :   return app_recv_stream_raw (s->rx_fifo, buf, len, 1, 0);
     786             : }
     787             : 
     788             : always_inline int
     789     7294670 : app_recv (app_session_t * s, u8 * data, u32 len)
     790             : {
     791     7294670 :   if (s->is_dgram)
     792           0 :     return app_recv_dgram (s, data, len);
     793     7294670 :   return app_recv_stream (s, data, len);
     794             : }
     795             : 
     796             : /* *INDENT-OFF* */
     797             : static char *session_error_str[] = {
     798             : #define _(sym, str) str,
     799             :     foreach_session_error
     800             : #undef _
     801             : };
     802             : /* *INDENT-ON* */
     803             : 
     804             : static inline u8 *
     805           0 : format_session_error (u8 * s, va_list * args)
     806             : {
     807           0 :   session_error_t error = va_arg (*args, session_error_t);
     808           0 :   if (-error >= 0 && -error < SESSION_N_ERRORS)
     809           0 :     s = format (s, "%s", session_error_str[-error]);
     810             :   else
     811           0 :     s = format (s, "invalid session err %u", -error);
     812           0 :   return s;
     813             : }
     814             : 
     815             : /*
     816             :  * Socket API messages
     817             :  */
     818             : 
     819             : typedef enum app_sapi_msg_type
     820             : {
     821             :   APP_SAPI_MSG_TYPE_NONE,
     822             :   APP_SAPI_MSG_TYPE_ATTACH,
     823             :   APP_SAPI_MSG_TYPE_ATTACH_REPLY,
     824             :   APP_SAPI_MSG_TYPE_ADD_DEL_WORKER,
     825             :   APP_SAPI_MSG_TYPE_ADD_DEL_WORKER_REPLY,
     826             :   APP_SAPI_MSG_TYPE_SEND_FDS,
     827             :   APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY,
     828             :   APP_SAPI_MSG_TYPE_ADD_DEL_CERT_KEY_REPLY,
     829             : } __clib_packed app_sapi_msg_type_e;
     830             : 
     831             : typedef struct app_sapi_attach_msg_
     832             : {
     833             :   u8 name[64];
     834             :   u64 options[18];
     835             : } __clib_packed app_sapi_attach_msg_t;
     836             : 
     837             : STATIC_ASSERT (sizeof (u64) * APP_OPTIONS_N_OPTIONS <=
     838             :                sizeof (((app_sapi_attach_msg_t *) 0)->options),
     839             :                "Out of options, fix message definition");
     840             : 
     841             : typedef struct app_sapi_attach_reply_msg_
     842             : {
     843             :   i32 retval;
     844             :   u32 app_index;
     845             :   u64 app_mq;
     846             :   u64 vpp_ctrl_mq;
     847             :   u64 segment_handle;
     848             :   u32 api_client_handle;
     849             :   u8 vpp_ctrl_mq_thread;
     850             :   u8 n_fds;
     851             :   u8 fd_flags;
     852             : } __clib_packed app_sapi_attach_reply_msg_t;
     853             : 
     854             : typedef struct app_sapi_worker_add_del_msg_
     855             : {
     856             :   u32 app_index;
     857             :   u32 wrk_index;
     858             :   u8 is_add;
     859             : } __clib_packed app_sapi_worker_add_del_msg_t;
     860             : 
     861             : typedef struct app_sapi_worker_add_del_reply_msg_
     862             : {
     863             :   i32 retval;
     864             :   u32 wrk_index;
     865             :   u64 app_event_queue_address;
     866             :   u64 segment_handle;
     867             :   u32 api_client_handle;
     868             :   u8 n_fds;
     869             :   u8 fd_flags;
     870             :   u8 is_add;
     871             : } __clib_packed app_sapi_worker_add_del_reply_msg_t;
     872             : 
     873             : typedef struct app_sapi_cert_key_add_del_msg_
     874             : {
     875             :   u32 context;
     876             :   u32 index;
     877             :   u16 cert_len;
     878             :   u16 certkey_len;
     879             :   u8 is_add;
     880             : } __clib_packed app_sapi_cert_key_add_del_msg_t;
     881             : 
     882             : typedef struct app_sapi_cert_key_add_del_reply_msg_
     883             : {
     884             :   u32 context;
     885             :   i32 retval;
     886             :   u32 index;
     887             : } __clib_packed app_sapi_cert_key_add_del_reply_msg_t;
     888             : 
     889             : typedef struct app_sapi_msg_
     890             : {
     891             :   app_sapi_msg_type_e type;
     892             :   union
     893             :   {
     894             :     app_sapi_attach_msg_t attach;
     895             :     app_sapi_attach_reply_msg_t attach_reply;
     896             :     app_sapi_worker_add_del_msg_t worker_add_del;
     897             :     app_sapi_worker_add_del_reply_msg_t worker_add_del_reply;
     898             :     app_sapi_cert_key_add_del_msg_t cert_key_add_del;
     899             :     app_sapi_cert_key_add_del_reply_msg_t cert_key_add_del_reply;
     900             :   };
     901             : } __clib_packed app_sapi_msg_t;
     902             : 
     903             : static inline void
     904          19 : session_endpoint_alloc_ext_cfg (session_endpoint_cfg_t *sep_ext,
     905             :                                 transport_endpt_ext_cfg_type_t type)
     906             : {
     907             :   transport_endpt_ext_cfg_t *cfg;
     908             :   u32 cfg_size;
     909             : 
     910          19 :   cfg_size = sizeof (transport_endpt_ext_cfg_t);
     911          19 :   cfg = clib_mem_alloc (cfg_size);
     912          19 :   clib_memset (cfg, 0, cfg_size);
     913          19 :   cfg->type = type;
     914          19 :   sep_ext->ext_cfg = cfg;
     915          19 : }
     916             : 
     917             : #endif /* __included_uri_h__ */
     918             : 
     919             : /*
     920             :  * fd.io coding-style-patch-verification: ON
     921             :  *
     922             :  * Local Variables:
     923             :  * eval: (c-set-style "gnu")
     924             :  * End:
     925             :  */

Generated by: LCOV version 1.14