X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fvppcom.c;h=ba1f11665568c5f6ee7b376446af6ebe1de58543;hb=57a5a2df5970f61259c9a14b5eb79358a2115b01;hp=39d665bdb27dc7d5847bd297a627a7b95067b65d;hpb=adcfb15fa0b08403c5b5b170149f7d3662e65761;p=vpp.git diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 39d665bdb27..ba1f1166556 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -231,7 +231,10 @@ vcl_send_session_connect (vcl_worker_t * wrk, vcl_session_t * s) clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip)); clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip)); mp->port = s->transport.rmt_port; + mp->lcl_port = s->transport.lcl_port; mp->proto = s->session_type; + if (s->flags & VCL_SESSION_F_CONNECTED) + mp->flags |= TRANSPORT_CFG_F_CONNECTED; app_send_ctrl_evt_to_vpp (mq, app_evt); } @@ -612,11 +615,21 @@ vcl_session_unlisten_reply_handler (vcl_worker_t * wrk, void *data) vcl_session_t *s; s = vcl_session_get_w_vpp_handle (wrk, mp->handle); - if (!s || s->session_state != STATE_DISCONNECT) + if (!s) { VDBG (0, "Unlisten reply with wrong handle %llx", mp->handle); return; } + if (s->session_state != STATE_DISCONNECT) + { + /* Connected udp listener */ + if (s->session_type == VPPCOM_PROTO_UDP + && s->session_state == STATE_CLOSED) + return; + + VDBG (0, "Unlisten session in wrong state %llx", mp->handle); + return; + } if (mp->retval) VDBG (0, "ERROR: session %u [0xllx]: unlisten failed: %U", @@ -679,6 +692,7 @@ vcl_session_accepted (vcl_worker_t * wrk, session_accepted_msg_t * msg) } clib_fifo_add2 (session->accept_evts_fifo, vcl_msg); + vcl_msg->flags = 0; vcl_msg->accepted_msg = *msg; /* Session handle points to listener until fully accepted by app */ vcl_session_table_add_vpp_handle (wrk, msg->handle, session->session_index); @@ -1529,10 +1543,6 @@ vppcom_unformat_proto (uint8_t * proto, char *proto_str) *proto = VPPCOM_PROTO_UDPC; else if (!strcmp (proto_str, "udpc")) *proto = VPPCOM_PROTO_UDPC; - else if (!strcmp (proto_str, "SCTP")) - *proto = VPPCOM_PROTO_SCTP; - else if (!strcmp (proto_str, "sctp")) - *proto = VPPCOM_PROTO_SCTP; else if (!strcmp (proto_str, "TLS")) *proto = VPPCOM_PROTO_TLS; else if (!strcmp (proto_str, "tls")) @@ -1655,25 +1665,6 @@ handle: return vcl_session_handle (client_session); } -static void -vcl_ip_copy_from_ep (ip46_address_t * ip, vppcom_endpt_t * ep) -{ - if (ep->is_ip4) - clib_memcpy_fast (&ip->ip4, ep->ip, sizeof (ip4_address_t)); - else - clib_memcpy_fast (&ip->ip6, ep->ip, sizeof (ip6_address_t)); -} - -void -vcl_ip_copy_to_ep (ip46_address_t * ip, vppcom_endpt_t * ep, u8 is_ip4) -{ - ep->is_ip4 = is_ip4; - if (is_ip4) - clib_memcpy_fast (ep->ip, &ip->ip4, sizeof (ip4_address_t)); - else - clib_memcpy_fast (ep->ip, &ip->ip6, sizeof (ip6_address_t)); -} - int vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep) { @@ -1708,13 +1699,24 @@ vppcom_session_connect (uint32_t session_handle, vppcom_endpt_t * server_ep) return VPPCOM_OK; } + /* Attempt to connect a connectionless listener */ + if (PREDICT_FALSE (session->session_state & STATE_LISTEN)) + { + if (session->session_type != VPPCOM_PROTO_UDP) + return VPPCOM_EINVAL; + vcl_send_session_unlisten (wrk, session); + session->session_state = STATE_CLOSED; + } + session->transport.is_ip4 = server_ep->is_ip4; vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep); session->transport.rmt_port = server_ep->port; session->parent_handle = VCL_INVALID_SESSION_HANDLE; + session->flags |= VCL_SESSION_F_CONNECTED; - VDBG (0, "session handle %u: connecting to server %s %U " + VDBG (0, "session handle %u (%s): connecting to peer %s %U " "port %d proto %s", session_handle, + vppcom_session_state_str (session->session_state), session->transport.is_ip4 ? "IPv4" : "IPv6", format_ip46_address, &session->transport.rmt_ip, session->transport.is_ip4 ? @@ -3196,7 +3198,8 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, /* VPP-TBD */ *(size_t *) buffer = (session->sndbuf_size ? session->sndbuf_size : - session->tx_fifo ? session->tx_fifo->nitems : + session->tx_fifo ? + svm_fifo_size (session->tx_fifo) : vcm->cfg.tx_fifo_size); *buflen = sizeof (u32); @@ -3227,7 +3230,8 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, /* VPP-TBD */ *(size_t *) buffer = (session->rcvbuf_size ? session->rcvbuf_size : - session->rx_fifo ? session->rx_fifo->nitems : + session->rx_fifo ? + svm_fifo_size (session->rx_fifo) : vcm->cfg.rx_fifo_size); *buflen = sizeof (u32); @@ -3569,20 +3573,8 @@ vppcom_session_recvfrom (uint32_t session_handle, void *buffer, uint32_t buflen, int flags, vppcom_endpt_t * ep) { vcl_worker_t *wrk = vcl_worker_get_current (); + vcl_session_t *session; int rv = VPPCOM_OK; - vcl_session_t *session = 0; - - if (ep) - { - session = vcl_session_get_w_handle (wrk, session_handle); - if (PREDICT_FALSE (!session)) - { - VDBG (0, "sh 0x%llx is closed!", session_handle); - return VPPCOM_EBADFD; - } - ep->is_ip4 = session->transport.is_ip4; - ep->port = session->transport.rmt_port; - } if (flags == 0) rv = vppcom_session_read (session_handle, buffer, buflen); @@ -3594,14 +3586,17 @@ vppcom_session_recvfrom (uint32_t session_handle, void *buffer, return VPPCOM_EAFNOSUPPORT; } - if (ep) + if (ep && rv > 0) { + session = vcl_session_get_w_handle (wrk, session_handle); if (session->transport.is_ip4) clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip4, sizeof (ip4_address_t)); else clib_memcpy_fast (ep->ip, &session->transport.rmt_ip.ip6, sizeof (ip6_address_t)); + ep->is_ip4 = session->transport.is_ip4; + ep->port = session->transport.rmt_port; } return rv; @@ -3616,8 +3611,28 @@ vppcom_session_sendto (uint32_t session_handle, void *buffer, if (ep) { - // TBD - return VPPCOM_EINVAL; + vcl_worker_t *wrk = vcl_worker_get_current (); + vcl_session_t *s; + + s = vcl_session_get_w_handle (wrk, session_handle); + if (!s) + return VPPCOM_EBADFD; + + if (s->session_type != VPPCOM_PROTO_UDP + || (s->flags & VCL_SESSION_F_CONNECTED)) + return VPPCOM_EINVAL; + + /* Session not connected/bound in vpp. Create it by 'connecting' it */ + if (PREDICT_FALSE (s->session_state == STATE_CLOSED)) + { + vcl_send_session_connect (wrk, s); + } + else + { + s->transport.is_ip4 = ep->is_ip4; + s->transport.rmt_port = ep->port; + vcl_ip_copy_from_ep (&s->transport.rmt_ip, ep); + } } if (flags)