X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Furi%2Fvppcom.c;h=24475b46606f33782b02dd37f1406b03d9d46336;hb=4c151b5fa13312639b0a5ef0d0efb1866bf4ed5e;hp=76a277246af4c875316e4979f741e54ffba3e4bf;hpb=35830af800aefdcc6a3767bc101b4c300a74651b;p=vpp.git diff --git a/src/uri/vppcom.c b/src/uri/vppcom.c index 76a277246af..24475b46606 100644 --- a/src/uri/vppcom.c +++ b/src/uri/vppcom.c @@ -136,7 +136,6 @@ typedef struct vppcom_main_t_ u8 init; u32 *client_session_index_fifo; volatile u32 bind_session_index; - u32 tx_event_id; int main_cpu; /* vpe input queue */ @@ -1015,7 +1014,7 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) session->state = STATE_ACCEPT; session->is_cut_thru = 0; session->is_server = 1; - session->port = ntohs (mp->port); + session->port = mp->port; session->peer_addr.is_ip4 = mp->is_ip4; clib_memcpy (&session->peer_addr.ip46, mp->ip, sizeof (session->peer_addr.ip46)); @@ -1766,7 +1765,7 @@ vppcom_app_create (char *app_name) rv = vppcom_connect_to_vpp (app_name); if (rv) { - clib_warning ("[%s] couldn't connect to VPP.", vcm->my_pid); + clib_warning ("[%d] couldn't connect to VPP.", vcm->my_pid); return rv; } @@ -1841,7 +1840,7 @@ vppcom_session_create (u32 vrf, u8 proto, u8 is_nonblocking) session->vrf = vrf; session->proto = proto; session->state = STATE_START; - session->is_nonblocking = is_nonblocking; + session->is_nonblocking = is_nonblocking ? 1 : 0; clib_spinlock_unlock (&vcm->sessions_lockp); if (VPPCOM_DEBUG > 0) @@ -1925,19 +1924,17 @@ vppcom_session_close (uint32_t session_index) clib_spinlock_unlock (&vcm->sessions_lockp); } - if (session->is_cut_thru) + if (session->is_cut_thru && session->is_server && + (session->state == STATE_ACCEPT)) { - if (session->is_server) - { - rv = vppcom_session_unbind_cut_thru (session); - if ((VPPCOM_DEBUG > 0) && (rv < 0)) - clib_warning ("[%d] unbind cut-thru (session %d) failed, " - "rv = %s (%d)", - vcm->my_pid, session_index, - vppcom_retval_str (rv), rv); - } + rv = vppcom_session_unbind_cut_thru (session); + if ((VPPCOM_DEBUG > 0) && (rv < 0)) + clib_warning ("[%d] unbind cut-thru (session %d) failed, " + "rv = %s (%d)", + vcm->my_pid, session_index, + vppcom_retval_str (rv), rv); } - else if (session->is_server) + else if (session->is_server && session->is_listen) { rv = vppcom_session_unbind (session_index); if ((VPPCOM_DEBUG > 0) && (rv < 0)) @@ -1945,7 +1942,7 @@ vppcom_session_close (uint32_t session_index) vcm->my_pid, session_index, vppcom_retval_str (rv), rv); } - else + else if (session->state == STATE_CONNECT) { rv = vppcom_session_disconnect (session_index); if ((VPPCOM_DEBUG > 0) && (rv < 0)) @@ -1980,6 +1977,15 @@ vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep) return rv; } + if (session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, session_index); + return VPPCOM_EBADFD; + } + if (VPPCOM_DEBUG > 0) clib_warning ("[%d] sid %d", vcm->my_pid, session_index); @@ -2010,6 +2016,15 @@ vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len) return rv; } + if (listen_session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, listen_session_index); + return VPPCOM_EBADFD; + } + if (VPPCOM_DEBUG > 0) clib_warning ("[%d] sid %d", vcm->my_pid, listen_session_index); @@ -2068,6 +2083,15 @@ vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep, return rv; } + if (listen_session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, listen_session_index); + return VPPCOM_EBADFD; + } + if (listen_session->state != STATE_LISTEN) { clib_spinlock_unlock (&vcm->sessions_lockp); @@ -2146,6 +2170,15 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) return rv; } + if (session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, session_index); + return VPPCOM_EBADFD; + } + if (session->state == STATE_CONNECT) { clib_spinlock_unlock (&vcm->sessions_lockp); @@ -2165,9 +2198,10 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) u8 *ip_str = format (0, "%U", format_ip46_address, &session->peer_addr.ip46, session->peer_addr.is_ip4); - clib_warning ("[%d] connect sid %d to %s server port %d", + clib_warning ("[%d] connect sid %d to %s server port %d proto %s", vcm->my_pid, session_index, ip_str, - clib_net_to_host_u16 (session->port)); + clib_net_to_host_u16 (session->port), + session->proto ? "UDP" : "TCP"); vec_free (ip_str); } @@ -2182,6 +2216,9 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) vcm->my_pid, vppcom_retval_str (rv), rv); return rv; } + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] sid %d connected!", vcm->my_pid, session_index); + return VPPCOM_OK; } @@ -2194,6 +2231,7 @@ vppcom_session_read (uint32_t session_index, void *buf, int n) int n_read = 0; int rv; char *fifo_str; + u32 poll_et; ASSERT (buf); @@ -2208,6 +2246,15 @@ vppcom_session_read (uint32_t session_index, void *buf, int n) return rv; } + if (session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, session_index); + return VPPCOM_EBADFD; + } + if (session->state == STATE_DISCONNECT) { clib_spinlock_unlock (&vcm->sessions_lockp); @@ -2221,6 +2268,8 @@ vppcom_session_read (uint32_t session_index, void *buf, int n) session->server_rx_fifo : session->server_tx_fifo); fifo_str = ((!session->is_cut_thru || session->is_server) ? "server_rx_fifo" : "server_tx_fifo"); + poll_et = EPOLLET & session->vep.ev.events; + clib_spinlock_unlock (&vcm->sessions_lockp); do { @@ -2228,10 +2277,12 @@ vppcom_session_read (uint32_t session_index, void *buf, int n) } while (!session->is_nonblocking && (n_read <= 0)); - if (n_read <= 0) - session->vep.et_mask |= EPOLLIN; - - clib_spinlock_unlock (&vcm->sessions_lockp); + if (poll_et && (n_read <= 0)) + { + clib_spinlock_lock (&vcm->sessions_lockp); + session->vep.et_mask |= EPOLLIN; + clib_spinlock_unlock (&vcm->sessions_lockp); + } if ((VPPCOM_DEBUG > 2) && (n_read > 0)) clib_warning ("[%d] sid %d, read %d bytes from %s (%p)", vcm->my_pid, @@ -2248,6 +2299,15 @@ vppcom_session_read_ready (session_t * session, u32 session_index) int ready = 0; /* Assumes caller has acquired spinlock: vcm->sessions_lockp */ + if (session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, session_index); + return VPPCOM_EBADFD; + } + if (session->state == STATE_DISCONNECT) { if (VPPCOM_DEBUG > 0) @@ -2271,7 +2331,7 @@ vppcom_session_read_ready (session_t * session, u32 session_index) session_index, session->is_server ? "server_rx_fifo" : "server_tx_fifo", rx_fifo, ready); - if (ready == 0) + if ((session->vep.ev.events & EPOLLET) && (ready == 0)) session->vep.et_mask |= EPOLLIN; return ready; @@ -2287,6 +2347,7 @@ vppcom_session_write (uint32_t session_index, void *buf, int n) session_fifo_event_t evt; int rv, n_write; char *fifo_str; + u32 poll_et; ASSERT (buf); @@ -2301,6 +2362,15 @@ vppcom_session_write (uint32_t session_index, void *buf, int n) return rv; } + if (session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, session_index); + return VPPCOM_EBADFD; + } + if (session->state == STATE_DISCONNECT) { clib_spinlock_unlock (&vcm->sessions_lockp); @@ -2314,6 +2384,10 @@ vppcom_session_write (uint32_t session_index, void *buf, int n) session->server_tx_fifo : session->server_rx_fifo); fifo_str = ((!session->is_cut_thru || session->is_server) ? "server_tx_fifo" : "server_rx_fifo"); + q = session->vpp_event_queue; + poll_et = EPOLLET & session->vep.ev.events; + clib_spinlock_unlock (&vcm->sessions_lockp); + do { n_write = svm_fifo_enqueue_nowait (tx_fifo, n, buf); @@ -2328,32 +2402,37 @@ vppcom_session_write (uint32_t session_index, void *buf, int n) /* Fabricate TX event, send to vpp */ evt.fifo = tx_fifo; evt.event_type = FIFO_EVENT_APP_TX; - evt.event_id = vcm->tx_event_id++; rval = vppcom_session_at_index (session_index, &session); if (PREDICT_FALSE (rval)) { - clib_spinlock_unlock (&vcm->sessions_lockp); if (VPPCOM_DEBUG > 1) clib_warning ("[%d] invalid session, sid (%u) has been closed!", vcm->my_pid, session_index); return rval; } - q = session->vpp_event_queue; ASSERT (q); unix_shared_memory_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ ); } - if (n_write <= 0) - session->vep.et_mask |= EPOLLOUT; - - clib_spinlock_unlock (&vcm->sessions_lockp); + if (poll_et && (n_write <= 0)) + { + clib_spinlock_lock (&vcm->sessions_lockp); + session->vep.et_mask |= EPOLLOUT; + clib_spinlock_unlock (&vcm->sessions_lockp); + } if (VPPCOM_DEBUG > 2) - clib_warning ("[%d] sid %d, wrote %d bytes to %s (%p)", vcm->my_pid, - session_index, n_write, fifo_str, tx_fifo); - return n_write; + { + if (n_write == -2) + clib_warning ("[%d] sid %d, FIFO-FULL %s (%p)", vcm->my_pid, + session_index, fifo_str, tx_fifo); + else + clib_warning ("[%d] sid %d, wrote %d bytes to %s (%p)", vcm->my_pid, + session_index, n_write, fifo_str, tx_fifo); + } + return (n_write < 0) ? VPPCOM_EAGAIN : n_write; } static inline int @@ -2365,6 +2444,15 @@ vppcom_session_write_ready (session_t * session, u32 session_index) int ready; /* Assumes caller has acquired spinlock: vcm->sessions_lockp */ + if (session->is_vep) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) is an epoll session!", + vcm->my_pid, session_index); + return VPPCOM_EBADFD; + } + if (session->state == STATE_DISCONNECT) { if (VPPCOM_DEBUG > 0) @@ -2383,7 +2471,7 @@ vppcom_session_write_ready (session_t * session, u32 session_index) if (VPPCOM_DEBUG > 3) clib_warning ("[%d] sid %d, peek %s (%p), ready = %d", vcm->my_pid, session_index, fifo_str, tx_fifo, ready); - if (ready == 0) + if ((session->vep.ev.events & EPOLLET) && (ready == 0)) session->vep.et_mask |= EPOLLOUT; return ready; @@ -2403,19 +2491,19 @@ vppcom_select (unsigned long n_bits, unsigned long *read_map, ASSERT (sizeof (clib_bitmap_t) == sizeof (long int)); - if (read_map) + if (n_bits && read_map) { clib_bitmap_validate (vcm->rd_bitmap, minbits); clib_memcpy (vcm->rd_bitmap, read_map, vec_len (vcm->rd_bitmap)); memset (read_map, 0, vec_len (vcm->rd_bitmap)); } - if (write_map) + if (n_bits && write_map) { clib_bitmap_validate (vcm->wr_bitmap, minbits); clib_memcpy (vcm->wr_bitmap, write_map, vec_len (vcm->wr_bitmap)); memset (write_map, 0, vec_len (vcm->wr_bitmap)); } - if (except_map) + if (n_bits && except_map) { clib_bitmap_validate (vcm->ex_bitmap, minbits); clib_memcpy (vcm->ex_bitmap, except_map, vec_len (vcm->ex_bitmap)); @@ -2425,91 +2513,100 @@ vppcom_select (unsigned long n_bits, unsigned long *read_map, do { /* *INDENT-OFF* */ - clib_bitmap_foreach (session_index, vcm->rd_bitmap, - ({ - clib_spinlock_lock (&vcm->sessions_lockp); - rv = vppcom_session_at_index (session_index, &session); - if (rv < 0) - { - clib_spinlock_unlock (&vcm->sessions_lockp); - if (VPPCOM_DEBUG > 1) - clib_warning ("[%d] session %d specified in " - "read_map is closed.", vcm->my_pid, - session_index); - bits_set = VPPCOM_EBADFD; - goto select_done; - } - - rv = vppcom_session_read_ready (session, session_index); - clib_spinlock_unlock (&vcm->sessions_lockp); - if (vcm->ex_bitmap && - clib_bitmap_get (vcm->ex_bitmap, session_index) && (rv < 0)) - { - // TBD: clib_warning - /* coverity[FORWARD_NULL] */ - clib_bitmap_set_no_check (except_map, session_index, 1); - bits_set++; - } - else if (rv > 0) + if (n_bits) + { + if (read_map) { - // TBD: clib_warning - /* coverity[FORWARD_NULL] */ - clib_bitmap_set_no_check (read_map, session_index, 1); - bits_set++; + clib_bitmap_foreach (session_index, vcm->rd_bitmap, + ({ + clib_spinlock_lock (&vcm->sessions_lockp); + rv = vppcom_session_at_index (session_index, &session); + if (rv < 0) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 1) + clib_warning ("[%d] session %d specified in " + "read_map is closed.", vcm->my_pid, + session_index); + bits_set = VPPCOM_EBADFD; + goto select_done; + } + + rv = vppcom_session_read_ready (session, session_index); + clib_spinlock_unlock (&vcm->sessions_lockp); + if (except_map && vcm->ex_bitmap && + clib_bitmap_get (vcm->ex_bitmap, session_index) && + (rv < 0)) + { + // TBD: clib_warning + clib_bitmap_set_no_check (except_map, session_index, 1); + bits_set++; + } + else if (rv > 0) + { + // TBD: clib_warning + clib_bitmap_set_no_check (read_map, session_index, 1); + bits_set++; + } + })); } - })); - clib_bitmap_foreach (session_index, vcm->wr_bitmap, - ({ - clib_spinlock_lock (&vcm->sessions_lockp); - rv = vppcom_session_at_index (session_index, &session); - if (rv < 0) + if (write_map) { - clib_spinlock_unlock (&vcm->sessions_lockp); - if (VPPCOM_DEBUG > 0) - clib_warning ("[%d] session %d specified in " - "write_map is closed.", vcm->my_pid, - session_index); - bits_set = VPPCOM_EBADFD; - goto select_done; + clib_bitmap_foreach (session_index, vcm->wr_bitmap, + ({ + clib_spinlock_lock (&vcm->sessions_lockp); + rv = vppcom_session_at_index (session_index, &session); + if (rv < 0) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] session %d specified in " + "write_map is closed.", vcm->my_pid, + session_index); + bits_set = VPPCOM_EBADFD; + goto select_done; + } + + rv = vppcom_session_write_ready (session, session_index); + clib_spinlock_unlock (&vcm->sessions_lockp); + if (write_map && (rv > 0)) + { + // TBD: clib_warning + clib_bitmap_set_no_check (write_map, session_index, 1); + bits_set++; + } + })); } - rv = vppcom_session_write_ready (session, session_index); - clib_spinlock_unlock (&vcm->sessions_lockp); - if (rv > 0 ) + if (except_map) { - // TBD: clib_warning - /* coverity[FORWARD_NULL] */ - clib_bitmap_set_no_check (write_map, session_index, 1); - bits_set++; + clib_bitmap_foreach (session_index, vcm->ex_bitmap, + ({ + clib_spinlock_lock (&vcm->sessions_lockp); + rv = vppcom_session_at_index (session_index, &session); + if (rv < 0) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 1) + clib_warning ("[%d] session %d specified in " + "except_map is closed.", vcm->my_pid, + session_index); + bits_set = VPPCOM_EBADFD; + goto select_done; + } + + rv = vppcom_session_read_ready (session, session_index); + clib_spinlock_unlock (&vcm->sessions_lockp); + if (rv < 0) + { + // TBD: clib_warning + clib_bitmap_set_no_check (except_map, session_index, 1); + bits_set++; + } + })); } - })); - - clib_bitmap_foreach (session_index, vcm->ex_bitmap, - ({ - clib_spinlock_lock (&vcm->sessions_lockp); - rv = vppcom_session_at_index (session_index, &session); - if (rv < 0) - { - clib_spinlock_unlock (&vcm->sessions_lockp); - if (VPPCOM_DEBUG > 1) - clib_warning ("[%d] session %d specified in " - "except_map is closed.", vcm->my_pid, - session_index); - bits_set = VPPCOM_EBADFD; - goto select_done; - } - - rv = vppcom_session_read_ready (session, session_index); - clib_spinlock_unlock (&vcm->sessions_lockp); - if (rv < 0) - { - // TBD: clib_warning - /* coverity[FORWARD_NULL] */ - clib_bitmap_set_no_check (except_map, session_index, 1); - bits_set++; - } - })); + } /* *INDENT-ON* */ } while (clib_time_now (&vcm->clib_time) < timeout); @@ -2553,6 +2650,7 @@ vep_verify_epoll_chain (u32 vep_idx) do { vep = &session->vep; + sid = vep->next_sid; if (session->is_vep_session) { if (VPPCOM_DEBUG > 1) @@ -2571,7 +2669,6 @@ vep_verify_epoll_chain (u32 vep_idx) vep->vep_idx, vep->vep_idx, vep->ev.events, vep->ev.data.u64, vep->et_mask); } - sid = vep->next_sid; if (sid != ~0) { rv = vppcom_session_at_index (sid, &session); @@ -3036,7 +3133,7 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, session_t *session; int rv = VPPCOM_OK; u32 *flags = buffer; - vppcom_ip46_t *vcl_addr = buffer; + vppcom_endpt_t *ep = buffer; VCL_LOCK_AND_GET_SESSION (session_index, &session); switch (op) @@ -3080,32 +3177,71 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, break; case VPPCOM_ATTR_GET_PEER_ADDR: - if (buffer && buflen && (*buflen >= sizeof (*vcl_addr))) + if (buffer && buflen && (*buflen >= sizeof (*ep))) { - *vcl_addr = session->peer_addr; - *buflen = sizeof (*vcl_addr); + ep->vrf = session->vrf; + ep->is_ip4 = session->peer_addr.is_ip4; + ep->port = session->port; + if (session->peer_addr.is_ip4) + clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4, + sizeof (ip4_address_t)); + else + clib_memcpy (ep->ip, &session->peer_addr.ip46.ip6, + sizeof (ip6_address_t)); + *buflen = sizeof (*ep); if (VPPCOM_DEBUG > 0) clib_warning ("VPPCOM_ATTR_GET_PEER_ADDR: is_ip4 = %u, " - "addr = %U", vcl_addr->is_ip4, format_ip46_address, - &vcl_addr->ip46, vcl_addr->is_ip4); + "addr = %U", ep->is_ip4, format_ip46_address, + &session->peer_addr.ip46, ep->is_ip4); } else rv = VPPCOM_EINVAL; break; case VPPCOM_ATTR_GET_LCL_ADDR: - if (buffer && buflen && (*buflen >= sizeof (*vcl_addr))) + if (buffer && buflen && (*buflen >= sizeof (*ep))) { - *vcl_addr = session->lcl_addr; - *buflen = sizeof (*vcl_addr); + ep->vrf = session->vrf; + ep->is_ip4 = session->lcl_addr.is_ip4; + ep->port = session->port; + if (session->lcl_addr.is_ip4) + clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4, + sizeof (ip4_address_t)); + else + clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip6, + sizeof (ip6_address_t)); + *buflen = sizeof (*ep); if (VPPCOM_DEBUG > 0) - clib_warning ("VPPCOM_ATTR_GET_LCL_ADDR: is_ip4 = %u, " - "addr = %U", vcl_addr->is_ip4, format_ip46_address, - &vcl_addr->ip46, vcl_addr->is_ip4); + if (VPPCOM_DEBUG > 0) + clib_warning ("VPPCOM_ATTR_GET_LCL_ADDR: is_ip4 = %u, " + "addr = %U", ep->is_ip4, format_ip46_address, + &session->lcl_addr.ip46, ep->is_ip4); } else rv = VPPCOM_EINVAL; break; + + case VPPCOM_ATTR_SET_REUSEADDR: + break; + + case VPPCOM_ATTR_SET_BROADCAST: + break; + + case VPPCOM_ATTR_SET_V6ONLY: + break; + + case VPPCOM_ATTR_SET_KEEPALIVE: + break; + + case VPPCOM_ATTR_SET_TCP_KEEPIDLE: + break; + + case VPPCOM_ATTR_SET_TCP_KEEPINTVL: + break; + + default: + rv = VPPCOM_EINVAL; + break; } done: @@ -3113,10 +3249,10 @@ done: return rv; } - /* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */