LCOV - code coverage report
Current view: top level - vcl - vcl_private.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 120 143 83.9 %
Date: 2023-07-05 22:20:52 Functions: 36 39 92.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018-2019 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this
       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             : 
      16             : #ifndef SRC_VCL_VCL_PRIVATE_H_
      17             : #define SRC_VCL_VCL_PRIVATE_H_
      18             : 
      19             : #include <vnet/session/application_interface.h>
      20             : #include <vcl/vppcom.h>
      21             : #include <vcl/vcl_debug.h>
      22             : 
      23             : #if (CLIB_DEBUG > 0)
      24             : /* Set VPPCOM_DEBUG_INIT 2 for connection debug,
      25             :  *                       3 for read/write debug output
      26             :  * or
      27             :  *    export VCL_DEBUG=<#> to set dynamically.
      28             :  */
      29             : #define VPPCOM_DEBUG_INIT 1
      30             : #else
      31             : #define VPPCOM_DEBUG_INIT 0
      32             : #endif
      33             : 
      34             : #define VPPCOM_DEBUG vcm->debug
      35             : 
      36             : extern __thread uword __vcl_worker_index;
      37             : 
      38             : static inline void
      39         103 : vcl_set_worker_index (uword wrk_index)
      40             : {
      41         103 :   __vcl_worker_index = wrk_index;
      42         103 : }
      43             : 
      44             : static inline uword
      45   184582493 : vcl_get_worker_index (void)
      46             : {
      47   184582493 :   return __vcl_worker_index;
      48             : }
      49             : 
      50             : /*
      51             :  * VPPCOM Private definitions and functions.
      52             :  */
      53             : typedef enum
      54             : {
      55             :   STATE_APP_START,
      56             :   STATE_APP_CONN_VPP,
      57             :   STATE_APP_ENABLED,
      58             :   STATE_APP_ATTACHED,
      59             :   STATE_APP_ADDING_WORKER,
      60             :   STATE_APP_ADDING_TLS_DATA,
      61             :   STATE_APP_FAILED,
      62             :   STATE_APP_READY
      63             : } vcl_bapi_app_state_t;
      64             : 
      65             : typedef enum vcl_session_state_
      66             : {
      67             :   VCL_STATE_CLOSED,
      68             :   VCL_STATE_LISTEN,
      69             :   VCL_STATE_READY,
      70             :   VCL_STATE_VPP_CLOSING,
      71             :   VCL_STATE_DISCONNECT,
      72             :   VCL_STATE_DETACHED,
      73             :   VCL_STATE_UPDATED,
      74             :   VCL_STATE_LISTEN_NO_MQ,
      75             : } vcl_session_state_t;
      76             : 
      77             : typedef struct epoll_event vppcom_epoll_event_t;
      78             : 
      79             : typedef struct
      80             : {
      81             :   u32 next_sh;
      82             :   u32 prev_sh;
      83             :   u32 vep_sh;
      84             :   vppcom_epoll_event_t ev;
      85             : #define VEP_DEFAULT_ET_MASK  (EPOLLIN|EPOLLOUT)
      86             : #define VEP_UNSUPPORTED_EVENTS (EPOLLONESHOT|EPOLLEXCLUSIVE)
      87             :   u32 et_mask;
      88             :   u32 lt_next;
      89             :   u32 lt_prev;
      90             : } vppcom_epoll_t;
      91             : 
      92             : /* Select uses the vcl_si_set as if a clib_bitmap. Make sure they are the
      93             :  * same size */
      94             : STATIC_ASSERT (sizeof (clib_bitmap_t) == sizeof (vcl_si_set),
      95             :                "vppcom bitmap size mismatch");
      96             : 
      97             : typedef struct
      98             : {
      99             :   u8 is_ip4;
     100             :   ip46_address_t ip46;
     101             : } vppcom_ip46_t;
     102             : 
     103             : #define VCL_ACCEPTED_F_CLOSED   (1 << 0)
     104             : #define VCL_ACCEPTED_F_RESET    (1 << 1)
     105             : 
     106             : typedef struct vcl_session_msg
     107             : {
     108             :   union
     109             :   {
     110             :     session_accepted_msg_t accepted_msg;
     111             :   };
     112             :   u32 flags;
     113             : } vcl_session_msg_t;
     114             : 
     115             : typedef enum
     116             : {
     117             :   VCL_SESS_ATTR_SERVER,
     118             :   VCL_SESS_ATTR_CUT_THRU,
     119             :   VCL_SESS_ATTR_VEP,
     120             :   VCL_SESS_ATTR_VEP_SESSION,
     121             :   VCL_SESS_ATTR_LISTEN,        // SOL_SOCKET,SO_ACCEPTCONN
     122             :   VCL_SESS_ATTR_NONBLOCK,      // fcntl,O_NONBLOCK
     123             :   VCL_SESS_ATTR_REUSEADDR,     // SOL_SOCKET,SO_REUSEADDR
     124             :   VCL_SESS_ATTR_REUSEPORT,     // SOL_SOCKET,SO_REUSEPORT
     125             :   VCL_SESS_ATTR_BROADCAST,     // SOL_SOCKET,SO_BROADCAST
     126             :   VCL_SESS_ATTR_V6ONLY,        // SOL_TCP,IPV6_V6ONLY
     127             :   VCL_SESS_ATTR_KEEPALIVE,     // SOL_SOCKET,SO_KEEPALIVE
     128             :   VCL_SESS_ATTR_TCP_NODELAY,   // SOL_TCP,TCP_NODELAY
     129             :   VCL_SESS_ATTR_TCP_KEEPIDLE,  // SOL_TCP,TCP_KEEPIDLE
     130             :   VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
     131             :   VCL_SESS_ATTR_IP_PKTINFO,    /* IPPROTO_IP, IP_PKTINFO */
     132             :   VCL_SESS_ATTR_MAX
     133             : } vppcom_session_attr_t;
     134             : 
     135             : typedef enum vcl_session_flags_
     136             : {
     137             :   VCL_SESSION_F_CONNECTED = 1 << 0,
     138             :   VCL_SESSION_F_IS_VEP = 1 << 1,
     139             :   VCL_SESSION_F_IS_VEP_SESSION = 1 << 2,
     140             :   VCL_SESSION_F_HAS_RX_EVT = 1 << 3,
     141             :   VCL_SESSION_F_RD_SHUTDOWN = 1 << 4,
     142             :   VCL_SESSION_F_WR_SHUTDOWN = 1 << 5,
     143             :   VCL_SESSION_F_PENDING_DISCONNECT = 1 << 6,
     144             :   VCL_SESSION_F_PENDING_FREE = 1 << 7,
     145             :   VCL_SESSION_F_PENDING_LISTEN = 1 << 8,
     146             : } __clib_packed vcl_session_flags_t;
     147             : 
     148             : typedef struct vcl_session_
     149             : {
     150             :   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
     151             : 
     152             : #define _(type, name) type name;
     153             :   foreach_app_session_field
     154             : #undef _
     155             :   vcl_session_flags_t flags;    /**< see @ref vcl_session_flags_t */
     156             :   u32 rx_bytes_pending;         /**< bytes rx-ed as segs but not yet freed */
     157             : 
     158             :   svm_fifo_t *ct_rx_fifo;
     159             :   svm_fifo_t *ct_tx_fifo;
     160             :   vcl_session_msg_t *accept_evts_fifo;
     161             : 
     162             :   u64 vpp_handle;
     163             :   u64 parent_handle;
     164             :   u32 listener_index;           /**< index of parent listener (if any) */
     165             :   int n_accepted_sessions;      /**< sessions accepted by this listener */
     166             :   vppcom_epoll_t vep;
     167             :   u32 attributes;               /**< see @ref vppcom_session_attr_t */
     168             :   int libc_epfd;
     169             :   u32 vrf;
     170             :   u16 gso_size;
     171             : 
     172             :   u32 sndbuf_size;              // VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
     173             :   u32 rcvbuf_size;              // VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
     174             : 
     175             :   transport_endpt_ext_cfg_t *ext_config;
     176             :   u8 dscp;
     177             : 
     178             :   i32 vpp_error;
     179             : 
     180             : #if VCL_ELOG
     181             :   elog_track_t elog_track;
     182             : #endif
     183             : } vcl_session_t;
     184             : 
     185             : typedef struct vppcom_cfg_t_
     186             : {
     187             :   uword heapsize;
     188             :   u32 max_workers;
     189             :   uword segment_baseva;
     190             :   uword segment_size;
     191             :   uword add_segment_size;
     192             :   u32 preallocated_fifo_pairs;
     193             :   u32 rx_fifo_size;
     194             :   u32 tx_fifo_size;
     195             :   u32 event_queue_size;
     196             :   u8 app_proxy_transport_tcp;
     197             :   u8 app_proxy_transport_udp;
     198             :   u8 app_scope_local;
     199             :   u8 app_scope_global;
     200             :   u8 *namespace_id;
     201             :   u64 namespace_secret;
     202             :   u8 use_mq_eventfd;
     203             :   f64 app_timeout;
     204             :   f64 session_timeout;
     205             :   char *event_log_path;
     206             :   u8 *vpp_app_socket_api;       /**< app socket api socket file name */
     207             :   u8 *vpp_bapi_socket_name;     /**< bapi socket transport socket name */
     208             :   u32 tls_engine;
     209             :   u8 mt_wrk_supported;
     210             :   u8 huge_page;
     211             : } vppcom_cfg_t;
     212             : 
     213             : void vppcom_cfg (vppcom_cfg_t * vcl_cfg);
     214             : 
     215             : typedef struct vcl_cut_through_registration_
     216             : {
     217             :   svm_msg_q_t *mq;
     218             :   svm_msg_q_t *peer_mq;
     219             :   u32 sid;
     220             :   u32 epoll_evt_conn_index;     /*< mq evt connection index part of
     221             :                                    the mqs evtfd epoll (if used) */
     222             : } vcl_cut_through_registration_t;
     223             : 
     224             : typedef struct vcl_mq_evt_conn_
     225             : {
     226             :   svm_msg_q_t *mq;
     227             :   int mq_fd;
     228             : } vcl_mq_evt_conn_t;
     229             : 
     230             : typedef struct vcl_worker_
     231             : {
     232             :   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
     233             : 
     234             :   /* Session pool */
     235             :   vcl_session_t *sessions;
     236             : 
     237             :   /** Worker/thread index in current process */
     238             :   u32 wrk_index;
     239             : 
     240             :   /** Worker index in vpp*/
     241             :   u32 vpp_wrk_index;
     242             : 
     243             :   /**
     244             :    * Generic api client handle. When binary api is in used, it stores
     245             :    * the "client_index" and when socket api is use, it stores the sapi
     246             :    * client handle */
     247             :   u32 api_client_handle;
     248             : 
     249             :   /** VPP binary api input queue */
     250             :   svm_queue_t *vl_input_queue;
     251             : 
     252             :   /** VPP mq to be used for exchanging control messages */
     253             :   svm_msg_q_t *ctrl_mq;
     254             : 
     255             :   /** Message queues epoll fd. Initialized only if using mqs with eventfds */
     256             :   int mqs_epfd;
     257             : 
     258             :   /** Pool of event message queue event connections */
     259             :   vcl_mq_evt_conn_t *mq_evt_conns;
     260             : 
     261             :   /** Per worker buffer for receiving mq epoll events */
     262             :   struct epoll_event *mq_events;
     263             : 
     264             :   /** Next session to be lt polled */
     265             :   u32 ep_lt_current;
     266             : 
     267             :   /** Hash table for disconnect processing */
     268             :   uword *session_index_by_vpp_handles;
     269             : 
     270             :   /** Select bitmaps */
     271             :   clib_bitmap_t *rd_bitmap;
     272             :   clib_bitmap_t *wr_bitmap;
     273             :   clib_bitmap_t *ex_bitmap;
     274             : 
     275             :   /** Our event message queue */
     276             :   svm_msg_q_t *app_event_queue;
     277             : 
     278             :   /** For deadman timers */
     279             :   clib_time_t clib_time;
     280             : 
     281             :   /** Vector acting as buffer for mq messages */
     282             :   svm_msg_q_msg_t *mq_msg_vector;
     283             : 
     284             :   /** Vector of unhandled events */
     285             :   session_event_t *unhandled_evts_vector;
     286             : 
     287             :   u32 *pending_session_wrk_updates;
     288             : 
     289             :   /** Used also as a thread stop key buffer */
     290             :   pthread_t thread_id;
     291             : 
     292             :   /** Current pid, may be different from main_pid if forked child */
     293             :   pid_t current_pid;
     294             : 
     295             :   u32 forked_child;
     296             : 
     297             :   clib_socket_t app_api_sock;
     298             :   socket_client_main_t bapi_sock_ctx;
     299             :   api_main_t bapi_api_ctx;
     300             :   memory_client_main_t bapi_mem_ctx;
     301             : 
     302             :   /* State of the connection, shared between msg RX thread and main thread */
     303             :   volatile vcl_bapi_app_state_t bapi_app_state;
     304             :   volatile uword bapi_return;
     305             : 
     306             :   u8 session_attr_op;
     307             :   int session_attr_op_rv;
     308             :   transport_endpt_attr_t session_attr_rv;
     309             : 
     310             :   /** vcl needs next epoll_create to go to libc_epoll */
     311             :   u8 vcl_needs_real_epoll;
     312             :   volatile int rpc_done;
     313             : } vcl_worker_t;
     314             : 
     315             : STATIC_ASSERT (sizeof (session_disconnected_msg_t) <= 16,
     316             :                "disconnected must fit in session_event_t");
     317             : STATIC_ASSERT (sizeof (session_reset_msg_t) <= 16,
     318             :                "disconnected must fit in session_event_t");
     319             : 
     320             : typedef void (vcl_rpc_fn_t) (void *args);
     321             : 
     322             : typedef struct vppcom_main_t_
     323             : {
     324             :   u8 is_init;
     325             :   u32 debug;
     326             :   pthread_t main_cpu;
     327             : 
     328             :   /** Main process pid */
     329             :   pid_t main_pid;
     330             : 
     331             :   /** App's index in vpp. It's used by vpp to identify the app */
     332             :   u32 app_index;
     333             : 
     334             :   u8 *app_name;
     335             : 
     336             :   /** VCL configuration */
     337             :   vppcom_cfg_t cfg;
     338             : 
     339             :   volatile u32 forking;
     340             : 
     341             :   /** Workers */
     342             :   vcl_worker_t *workers;
     343             : 
     344             :   /** Lock to protect worker registrations */
     345             :   clib_spinlock_t workers_lock;
     346             : 
     347             :   /** Counter to determine order of execution of `vcl_api_retry_attach`
     348             :    * function by multiple workers */
     349             :   int reattach_count;
     350             : 
     351             :   /** Lock to protect segment hash table */
     352             :   clib_rwlock_t segment_table_lock;
     353             : 
     354             :   /** Mapped segments table */
     355             :   uword *segment_table;
     356             : 
     357             :   /** Control mq obtained from attach */
     358             :   svm_msg_q_t *ctrl_mq;
     359             : 
     360             :   fifo_segment_main_t segment_main;
     361             : 
     362             :   vcl_rpc_fn_t *wrk_rpc_fn;
     363             : 
     364             :   /*
     365             :    * Binary api context
     366             :    */
     367             : 
     368             :   /* VNET_API_ERROR_FOO -> "Foo" hash table */
     369             :   uword *error_string_by_error_number;
     370             : 
     371             : #ifdef VCL_ELOG
     372             :   /* VPP Event-logger */
     373             :   elog_main_t elog_main;
     374             :   elog_track_t elog_track;
     375             : #endif
     376             : 
     377             : } vppcom_main_t;
     378             : 
     379             : extern vppcom_main_t *vcm;
     380             : extern vppcom_main_t _vppcom_main;
     381             : 
     382             : #define VCL_INVALID_SESSION_INDEX ((u32)~0)
     383             : #define VCL_INVALID_SESSION_HANDLE ((u64)~0)
     384             : #define VCL_INVALID_SEGMENT_INDEX ((u32)~0)
     385             : #define VCL_INVALID_SEGMENT_HANDLE ((u64)~0)
     386             : 
     387             : void vcl_session_detach_fifos (vcl_session_t *s);
     388             : 
     389             : static inline vcl_session_t *
     390         135 : vcl_session_alloc (vcl_worker_t * wrk)
     391             : {
     392             :   vcl_session_t *s;
     393         135 :   pool_get (wrk->sessions, s);
     394         135 :   memset (s, 0, sizeof (*s));
     395         135 :   s->session_index = s - wrk->sessions;
     396         135 :   s->listener_index = VCL_INVALID_SESSION_INDEX;
     397         135 :   return s;
     398             : }
     399             : 
     400             : static inline void
     401          24 : vcl_session_free (vcl_worker_t * wrk, vcl_session_t * s)
     402             : {
     403             :   /* Debug level set to 1 to avoid debug messages while ldp is cleaning up */
     404          24 :   VDBG (1, "session %u [0x%llx] removed", s->session_index, s->vpp_handle);
     405          24 :   vcl_session_detach_fifos (s);
     406          24 :   if (s->ext_config)
     407           0 :     clib_mem_free (s->ext_config);
     408          24 :   pool_put (wrk->sessions, s);
     409          24 : }
     410             : 
     411             : static inline vcl_session_t *
     412   181831000 : vcl_session_get (vcl_worker_t * wrk, u32 session_index)
     413             : {
     414   181831000 :   if (pool_is_free_index (wrk->sessions, session_index))
     415           1 :     return 0;
     416   181831000 :   return pool_elt_at_index (wrk->sessions, session_index);
     417             : }
     418             : 
     419             : static inline vcl_session_handle_t
     420      442744 : vcl_session_handle_from_wrk_session_index (u32 session_index, u32 wrk_index)
     421             : {
     422      442744 :   ASSERT (session_index < 2 << 24);
     423      442744 :   return (wrk_index << 24 | session_index);
     424             : }
     425             : 
     426             : static inline vcl_session_handle_t
     427     3971875 : vcl_session_handle_from_index (u32 session_index)
     428             : {
     429     3971875 :   ASSERT (session_index < 2 << 24);
     430     3971875 :   return (vcl_get_worker_index () << 24 | session_index);
     431             : }
     432             : 
     433             : static inline vcl_session_handle_t
     434         135 : vcl_session_handle (vcl_session_t * s)
     435             : {
     436         135 :   return vcl_session_handle_from_index (s->session_index);
     437             : }
     438             : 
     439             : static inline void
     440   123736000 : vcl_session_handle_parse (u32 handle, u32 * wrk_index, u32 * session_index)
     441             : {
     442   123736000 :   *wrk_index = handle >> 24;
     443   123736000 :   *session_index = handle & 0xFFFFFF;
     444   123736000 : }
     445             : 
     446             : static inline vcl_session_t *
     447   123736000 : vcl_session_get_w_handle (vcl_worker_t * wrk, u32 session_handle)
     448             : {
     449             :   u32 session_index, wrk_index;
     450   123736000 :   vcl_session_handle_parse (session_handle, &wrk_index, &session_index);
     451   123736000 :   ASSERT (wrk_index == wrk->wrk_index);
     452   123736000 :   return vcl_session_get (wrk, session_index);
     453             : }
     454             : 
     455             : static inline vcl_session_t *
     456          80 : vcl_session_get_w_vpp_handle (vcl_worker_t * wrk, u64 vpp_handle)
     457             : {
     458             :   uword *p;
     459          80 :   if ((p = hash_get (wrk->session_index_by_vpp_handles, vpp_handle)))
     460          43 :     return vcl_session_get (wrk, (u32) p[0]);
     461          37 :   return 0;
     462             : }
     463             : 
     464             : static inline u32
     465           5 : vcl_session_index_from_vpp_handle (vcl_worker_t * wrk, u64 vpp_handle)
     466             : {
     467             :   uword *p;
     468           5 :   if ((p = hash_get (wrk->session_index_by_vpp_handles, vpp_handle)))
     469           5 :     return p[0];
     470           0 :   return VCL_INVALID_SESSION_INDEX;
     471             : }
     472             : 
     473             : static inline void
     474         121 : vcl_session_table_add_vpp_handle (vcl_worker_t * wrk, u64 handle, u32 value)
     475             : {
     476         121 :   hash_set (wrk->session_index_by_vpp_handles, handle, value);
     477         121 : }
     478             : 
     479             : static inline void
     480          24 : vcl_session_table_del_vpp_handle (vcl_worker_t * wrk, u64 vpp_handle)
     481             : {
     482          24 :   hash_unset (wrk->session_index_by_vpp_handles, vpp_handle);
     483          24 : }
     484             : 
     485             : static inline uword *
     486             : vcl_session_table_lookup_vpp_handle (vcl_worker_t * wrk, u64 handle)
     487             : {
     488             :   return hash_get (wrk->session_index_by_vpp_handles, handle);
     489             : }
     490             : 
     491             : static inline void
     492          40 : vcl_session_table_add_listener (vcl_worker_t * wrk, u64 listener_handle,
     493             :                                 u32 value)
     494             : {
     495          40 :   hash_set (wrk->session_index_by_vpp_handles, listener_handle, value);
     496          40 : }
     497             : 
     498             : static inline void
     499             : vcl_session_table_del_listener (vcl_worker_t * wrk, u64 listener_handle)
     500             : {
     501             :   hash_unset (wrk->session_index_by_vpp_handles, listener_handle);
     502             : }
     503             : 
     504             : static inline int
     505        4729 : vcl_session_is_connectable_listener (vcl_worker_t * wrk,
     506             :                                      vcl_session_t * session)
     507             : {
     508             :   /* Tell if we session_handle is a QUIC session.
     509             :    * We can be in the following cases :
     510             :    * Listen session <- QUIC session <- Stream session
     511             :    * QUIC session <- Stream session
     512             :    */
     513             :   vcl_session_t *ls;
     514        4729 :   if (session->session_type != VPPCOM_PROTO_QUIC)
     515        4729 :     return 0;
     516           0 :   if (session->listener_index == VCL_INVALID_SESSION_INDEX)
     517           0 :     return !(session->session_state == VCL_STATE_LISTEN);
     518           0 :   ls = vcl_session_get_w_handle (wrk, session->listener_index);
     519           0 :   if (!ls)
     520           0 :     return VPPCOM_EBADFD;
     521           0 :   return ls->session_state == VCL_STATE_LISTEN;
     522             : }
     523             : 
     524             : static inline vcl_session_t *
     525          37 : vcl_session_table_lookup_listener (vcl_worker_t * wrk, u64 handle)
     526             : {
     527             :   uword *p;
     528             :   vcl_session_t *s;
     529             : 
     530          37 :   p = hash_get (wrk->session_index_by_vpp_handles, handle);
     531          37 :   if (!p)
     532             :     {
     533           0 :       VDBG (0, "could not find listen session: unknown vpp listener handle"
     534             :             " %llx", handle);
     535           0 :       return 0;
     536             :     }
     537          37 :   s = vcl_session_get (wrk, p[0]);
     538          37 :   if (!s)
     539             :     {
     540           0 :       VDBG (1, "invalid listen session index (%u)", p[0]);
     541           0 :       return 0;
     542             :     }
     543             : 
     544          37 :   if (s->session_state == VCL_STATE_DISCONNECT)
     545             :     {
     546           0 :       VDBG (0, "listen session [0x%llx] is closing", s->vpp_handle);
     547           0 :       return 0;
     548             :     }
     549             : 
     550          37 :   ASSERT (s->session_state == VCL_STATE_LISTEN
     551             :           || s->session_state == VCL_STATE_LISTEN_NO_MQ
     552             :           || vcl_session_is_connectable_listener (wrk, s));
     553          37 :   return s;
     554             : }
     555             : 
     556             : static inline u8
     557    52900640 : vcl_session_is_ct (vcl_session_t * s)
     558             : {
     559    52900640 :   return (s->ct_tx_fifo != 0);
     560             : }
     561             : 
     562             : static inline u8
     563    14213357 : vcl_session_is_cl (vcl_session_t * s)
     564             : {
     565    14213357 :   if (s->session_type == VPPCOM_PROTO_UDP)
     566         892 :     return !(s->flags & VCL_SESSION_F_CONNECTED);
     567    14212450 :   return 0;
     568             : }
     569             : 
     570             : static inline u8
     571           6 : vcl_session_has_crypto (vcl_session_t *s)
     572             : {
     573           8 :   return (s->session_type == VPPCOM_PROTO_TLS ||
     574           8 :           s->session_type == VPPCOM_PROTO_QUIC ||
     575           2 :           s->session_type == VPPCOM_PROTO_DTLS);
     576             : }
     577             : 
     578             : static inline u8
     579    59660240 : vcl_session_is_ready (vcl_session_t * s)
     580             : {
     581    59660240 :   return (s->session_state == VCL_STATE_READY
     582    59660240 :           || s->session_state == VCL_STATE_VPP_CLOSING);
     583             : }
     584             : 
     585             : static inline u8
     586    59660130 : vcl_session_is_open (vcl_session_t * s)
     587             : {
     588    59660130 :   return ((vcl_session_is_ready (s))
     589    59660130 :           || (s->session_state == VCL_STATE_LISTEN && vcl_session_is_cl (s)));
     590             : }
     591             : 
     592             : static inline u8
     593      261327 : vcl_session_is_closing (vcl_session_t * s)
     594             : {
     595      261327 :   return (s->session_state == VCL_STATE_VPP_CLOSING
     596      261327 :           || s->session_state == VCL_STATE_DISCONNECT);
     597             : }
     598             : 
     599             : static inline u8
     600        5783 : vcl_session_is_closed (vcl_session_t * s)
     601             : {
     602        5783 :   return (!s || (s->session_state == VCL_STATE_CLOSED));
     603             : }
     604             : 
     605             : static inline int
     606           0 : vcl_session_closing_error (vcl_session_t * s)
     607             : {
     608             :   /* Return 0 on closing sockets */
     609           0 :   return s->session_state == VCL_STATE_DISCONNECT ? VPPCOM_ECONNRESET : 0;
     610             : }
     611             : 
     612             : static inline int
     613           0 : vcl_session_closed_error (vcl_session_t * s)
     614             : {
     615           0 :   return s->session_state == VCL_STATE_DISCONNECT
     616           0 :     ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN;
     617             : }
     618             : 
     619             : static inline void
     620          47 : vcl_ip_copy_from_ep (ip46_address_t * ip, vppcom_endpt_t * ep)
     621             : {
     622          47 :   if (ep->is_ip4)
     623          43 :     clib_memcpy_fast (&ip->ip4, ep->ip, sizeof (ip4_address_t));
     624             :   else
     625           4 :     clib_memcpy_fast (&ip->ip6, ep->ip, sizeof (ip6_address_t));
     626          47 : }
     627             : 
     628             : static inline void
     629             : vcl_ip_copy_to_ep (ip46_address_t * ip, vppcom_endpt_t * ep, u8 is_ip4)
     630             : {
     631             :   ep->is_ip4 = is_ip4;
     632             :   if (is_ip4)
     633             :     clib_memcpy_fast (ep->ip, &ip->ip4, sizeof (ip4_address_t));
     634             :   else
     635             :     clib_memcpy_fast (ep->ip, &ip->ip6, sizeof (ip6_address_t));
     636             : }
     637             : 
     638             : static inline int
     639         122 : vcl_proto_is_dgram (uint8_t proto)
     640             : {
     641         122 :   return proto == VPPCOM_PROTO_UDP || proto == VPPCOM_PROTO_DTLS ||
     642             :          proto == VPPCOM_PROTO_SRTP;
     643             : }
     644             : 
     645             : static inline u8
     646     1566220 : vcl_session_has_attr (vcl_session_t * s, u8 attr)
     647             : {
     648     1566220 :   return (s->attributes & (1 << attr)) ? 1 : 0;
     649             : }
     650             : 
     651             : static inline void
     652          62 : vcl_session_set_attr (vcl_session_t * s, u8 attr)
     653             : {
     654          62 :   s->attributes |= 1 << attr;
     655          62 : }
     656             : 
     657             : static inline void
     658           4 : vcl_session_clear_attr (vcl_session_t * s, u8 attr)
     659             : {
     660           4 :   s->attributes &= ~(1 << attr);
     661           4 : }
     662             : 
     663             : static inline session_evt_type_t
     664        1380 : vcl_session_dgram_tx_evt (vcl_session_t *s, session_evt_type_t et)
     665             : {
     666        1380 :   return (s->flags & VCL_SESSION_F_CONNECTED) ? et : SESSION_IO_EVT_TX_MAIN;
     667             : }
     668             : 
     669             : static inline void
     670     7513460 : vcl_session_add_want_deq_ntf (vcl_session_t *s, svm_fifo_deq_ntf_t evt)
     671             : {
     672     7513460 :   svm_fifo_t *txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
     673     7513460 :   if (txf)
     674     7513460 :     svm_fifo_add_want_deq_ntf (txf, evt);
     675     7513460 : }
     676             : 
     677             : static inline void
     678          27 : vcl_session_del_want_deq_ntf (vcl_session_t *s, svm_fifo_deq_ntf_t evt)
     679             : {
     680          27 :   svm_fifo_t *txf = vcl_session_is_ct (s) ? s->ct_tx_fifo : s->tx_fifo;
     681          27 :   if (txf)
     682          27 :     svm_fifo_del_want_deq_ntf (txf, evt);
     683          27 : }
     684             : 
     685             : /*
     686             :  * Helpers
     687             :  */
     688             : vcl_mq_evt_conn_t *vcl_mq_evt_conn_alloc (vcl_worker_t * wrk);
     689             : u32 vcl_mq_evt_conn_index (vcl_worker_t * wrk, vcl_mq_evt_conn_t * mqc);
     690             : vcl_mq_evt_conn_t *vcl_mq_evt_conn_get (vcl_worker_t * wrk, u32 mq_conn_idx);
     691             : int vcl_mq_epoll_add_evfd (vcl_worker_t * wrk, svm_msg_q_t * mq);
     692             : int vcl_mq_epoll_del_evfd (vcl_worker_t * wrk, u32 mqc_index);
     693             : 
     694             : vcl_worker_t *vcl_worker_alloc_and_init (void);
     695             : void vcl_worker_cleanup (vcl_worker_t * wrk, u8 notify_vpp);
     696             : int vcl_worker_register_with_vpp (void);
     697             : svm_msg_q_t *vcl_worker_ctrl_mq (vcl_worker_t * wrk);
     698             : 
     699             : void vcl_flush_mq_events (void);
     700             : int vcl_session_cleanup (vcl_worker_t * wrk, vcl_session_t * session,
     701             :                          vcl_session_handle_t sh, u8 do_disconnect);
     702             : 
     703             : void vcl_segment_table_add (u64 segment_handle, u32 svm_segment_index);
     704             : u32 vcl_segment_table_lookup (u64 segment_handle);
     705             : void vcl_segment_table_del (u64 segment_handle);
     706             : 
     707             : int vcl_session_read_ready (vcl_session_t * session);
     708             : int vcl_session_write_ready (vcl_session_t * session);
     709             : int vcl_session_alloc_ext_cfg (vcl_session_t *s,
     710             :                                transport_endpt_ext_cfg_type_t type, u32 len);
     711             : 
     712             : static inline vcl_worker_t *
     713   150587343 : vcl_worker_get (u32 wrk_index)
     714             : {
     715   150587343 :   return pool_elt_at_index (vcm->workers, wrk_index);
     716             : }
     717             : 
     718             : static inline vcl_worker_t *
     719           0 : vcl_worker_get_if_valid (u32 wrk_index)
     720             : {
     721           0 :   if (pool_is_free_index (vcm->workers, wrk_index))
     722           0 :     return 0;
     723           0 :   return pool_elt_at_index (vcm->workers, wrk_index);
     724             : }
     725             : 
     726             : static inline vcl_worker_t *
     727   150587285 : vcl_worker_get_current (void)
     728             : {
     729   150587285 :   return vcl_worker_get (vcl_get_worker_index ());
     730             : }
     731             : 
     732             : static inline u8
     733          26 : vcl_n_workers (void)
     734             : {
     735          26 :   return pool_elts (vcm->workers);
     736             : }
     737             : 
     738             : static inline u64
     739         204 : vcl_vpp_worker_segment_handle (u32 wrk_index)
     740             : {
     741         204 :   return (VCL_INVALID_SEGMENT_HANDLE - wrk_index - 1);
     742             : }
     743             : 
     744             : void vcl_send_session_worker_update (vcl_worker_t * wrk, vcl_session_t * s,
     745             :                                      u32 wrk_index);
     746             : int vcl_send_worker_rpc (u32 dst_wrk_index, void *data, u32 data_len);
     747             : 
     748             : int vcl_segment_attach (u64 segment_handle, char *name,
     749             :                         ssvm_segment_type_t type, int fd);
     750             : void vcl_segment_detach (u64 segment_handle);
     751             : void vcl_segment_detach_segments (u32 *seg_indices);
     752             : void vcl_send_session_listen (vcl_worker_t *wrk, vcl_session_t *s);
     753             : void vcl_send_session_unlisten (vcl_worker_t * wrk, vcl_session_t * s);
     754             : 
     755             : int vcl_segment_attach_session (uword segment_handle, uword rxf_offset,
     756             :                                 uword txf_offset, uword mq_offset,
     757             :                                 u32 mq_index, u8 is_ct, vcl_session_t *s);
     758             : int vcl_segment_attach_mq (uword segment_handle, uword mq_offset, u32 mq_index,
     759             :                            svm_msg_q_t **mq);
     760             : int vcl_segment_discover_mqs (uword segment_handle, int *fds, u32 n_fds);
     761             : svm_fifo_chunk_t *vcl_segment_alloc_chunk (uword segment_handle,
     762             :                                            u32 slice_index, u32 size,
     763             :                                            uword *offset);
     764             : int vcl_session_share_fifos (vcl_session_t *s, svm_fifo_t *rxf,
     765             :                              svm_fifo_t *txf);
     766             : void vcl_worker_detach_sessions (vcl_worker_t *wrk);
     767             : 
     768             : /*
     769             :  * VCL Binary API
     770             :  */
     771             : int vcl_bapi_attach (void);
     772             : int vcl_bapi_app_worker_add (void);
     773             : void vcl_bapi_app_worker_del (vcl_worker_t * wrk);
     774             : void vcl_bapi_disconnect_from_vpp (void);
     775             : int vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds);
     776             : int vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair);
     777             : int vcl_bapi_del_cert_key_pair (u32 ckpair_index);
     778             : u32 vcl_bapi_max_nsid_len (void);
     779             : int vcl_bapi_worker_set (void);
     780             : 
     781             : /*
     782             :  * VCL Socket API
     783             :  */
     784             : int vcl_sapi_attach (void);
     785             : int vcl_sapi_app_worker_add (void);
     786             : void vcl_sapi_app_worker_del (vcl_worker_t * wrk);
     787             : void vcl_sapi_detach (vcl_worker_t * wrk);
     788             : int vcl_sapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds);
     789             : int vcl_sapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair);
     790             : int vcl_sapi_del_cert_key_pair (u32 ckpair_index);
     791             : 
     792             : /*
     793             :  * Utility functions
     794             :  */
     795             : const char *vcl_session_state_str (vcl_session_state_t state);
     796             : u8 *vcl_format_ip4_address (u8 *s, va_list *args);
     797             : u8 *vcl_format_ip6_address (u8 *s, va_list *args);
     798             : u8 *vcl_format_ip46_address (u8 *s, va_list *args);
     799             : 
     800             : #endif /* SRC_VCL_VCL_PRIVATE_H_ */
     801             : 
     802             : /*
     803             :  * fd.io coding-style-patch-verification: ON
     804             :  *
     805             :  * Local Variables:
     806             :  * eval: (c-set-style "gnu")
     807             :  * End:
     808             :  */

Generated by: LCOV version 1.14