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

Generated by: LCOV version 1.14