diff options
Diffstat (limited to 'src/vcl')
-rw-r--r-- | src/vcl/vcom_socket.c | 98 | ||||
-rw-r--r-- | src/vcl/vppcom.c | 124 | ||||
-rw-r--r-- | src/vcl/vppcom.h | 6 |
3 files changed, 194 insertions, 34 deletions
diff --git a/src/vcl/vcom_socket.c b/src/vcl/vcom_socket.c index 1ccb05451ad..304cebb8f9b 100644 --- a/src/vcl/vcom_socket.c +++ b/src/vcl/vcom_socket.c @@ -1513,9 +1513,29 @@ vcom_session_sendto (int __sid, void *__buf, size_t __n, socklen_t __addr_len) { int rv = -1; - /* TBD add new vpp api */ - /* TBD add flags parameter */ - rv = vppcom_session_write (__sid, (void *) __buf, (int) __n); + vppcom_endpt_t ep; + + ep.vrf = VPPCOM_VRF_DEFAULT; + switch (__addr->sa_family) + { + case AF_INET: + ep.is_ip4 = VPPCOM_IS_IP4; + ep.ip = (uint8_t *) & ((const struct sockaddr_in *) __addr)->sin_addr; + ep.port = (uint16_t) ((const struct sockaddr_in *) __addr)->sin_port; + break; + + case AF_INET6: + ep.is_ip4 = VPPCOM_IS_IP6; + ep.ip = (uint8_t *) & ((const struct sockaddr_in6 *) __addr)->sin6_addr; + ep.port = (uint16_t) ((const struct sockaddr_in6 *) __addr)->sin6_port; + break; + + default: + return -1; + } + + rv = vppcom_session_sendto (__sid, __buf, __n, __flags, &ep); + return rv; } @@ -1580,10 +1600,44 @@ vcom_session_recvfrom (int __sid, void *__restrict __buf, size_t __n, int __flags, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len) { - int rv = -1; + int rv; + vppcom_endpt_t ep; + + if (__addr) + { + ep.ip = (u8 *) & ((const struct sockaddr_in *) __addr)->sin_addr; + rv = vppcom_session_recvfrom (__sid, __buf, __n, __flags, &ep); + + if (rv > 0) + { + if (ep.vrf == VPPCOM_VRF_DEFAULT) + { + __addr->sa_family = + ep.is_ip4 == VPPCOM_IS_IP4 ? AF_INET : AF_INET6; + switch (__addr->sa_family) + { + case AF_INET: + ((struct sockaddr_in *) __addr)->sin_port = ep.port; + *__addr_len = sizeof (struct sockaddr_in); + break; + + case AF_INET6: + ((struct sockaddr_in6 *) __addr)->sin6_port = ep.port; + *__addr_len = sizeof (struct sockaddr_in6); + break; + + default: + rv = -1; + break; + } + } + else + rv = -1; + } + } + else + rv = vppcom_session_recvfrom (__sid, __buf, __n, __flags, NULL); - /* TBD add flags parameter */ - rv = vppcom_session_read (__sid, __buf, __n); return rv; } @@ -1597,10 +1651,8 @@ vcom_socket_recvfrom (int __fd, void *__restrict __buf, size_t __n, uword *p; vcom_socket_t *vsock; - if (!__buf || !__addr || !__addr_len) - { - return -EINVAL; - } + if (__addr && !__addr_len) + return -EINVAL; p = hash_get (vsm->sockidx_by_fd, __fd); if (!p) @@ -1737,9 +1789,26 @@ vcom_session_get_sockopt (int __sid, int __level, int __optname, void *__restrict __optval, socklen_t * __restrict __optlen) { + int rv = 0; + /* 1. for socket level options that are NOT socket attributes * and that has corresponding vpp options get from vppcom */ - return 0; + switch (__level) + { + case SOL_SOCKET: + switch (__optname) + { + case SO_ERROR: + *(int *) __optval = 0; + break; + default: + break; + } + default: + break; + } + /* 2. unhandled options */ + return rv; } int @@ -1768,7 +1837,6 @@ vcom_socket_getsockopt (int __fd, int __level, int __optname, switch (__level) { - /* handle options at socket level */ case SOL_SOCKET: switch (__optname) { @@ -1791,7 +1859,6 @@ vcom_socket_getsockopt (int __fd, int __level, int __optname, case SO_TYPE: case SO_PROTOCOL: case SO_DOMAIN: - case SO_ERROR: case SO_OOBINLINE: case SO_NO_CHECK: case SO_PRIORITY: @@ -1835,6 +1902,11 @@ vcom_socket_getsockopt (int __fd, int __level, int __optname, } break; + case SO_ERROR: + rv = vcom_session_get_sockopt (vsock->sid, __level, __optname, + __optval, __optlen); + break; + default: /* We implement the SO_SNDLOWAT etc to not be settable * (1003.1g 7). diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 0f30c60c803..1b1a08e4c06 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -109,7 +109,8 @@ typedef struct u32 vrf; vppcom_ip46_t lcl_addr; vppcom_ip46_t peer_addr; - u16 port; + u16 lcl_port; // network order + u16 peer_port; // network order u8 proto; u64 client_queue_address; u64 options[16]; @@ -806,7 +807,7 @@ vppcom_send_connect_sock (session_t * session, u32 session_index) cmp->vrf = session->vrf; cmp->is_ip4 = session->peer_addr.is_ip4; clib_memcpy (cmp->ip, &session->peer_addr.ip46, sizeof (cmp->ip)); - cmp->port = session->port; + cmp->port = session->peer_port; cmp->proto = session->proto; clib_memcpy (cmp->options, session->options, sizeof (cmp->options)); vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & cmp); @@ -1014,7 +1015,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 = mp->port; + session->peer_port = mp->port; session->peer_addr.is_ip4 = mp->is_ip4; clib_memcpy (&session->peer_addr.ip46, mp->ip, sizeof (session->peer_addr.ip46)); @@ -1132,7 +1133,7 @@ vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp) session->client_queue_address = mp->client_queue_address; session->is_cut_thru = 1; session->is_server = 1; - session->port = mp->port; + session->peer_port = mp->port; session->peer_addr.is_ip4 = mp->is_ip4; clib_memcpy (&session->peer_addr.ip46, mp->ip, sizeof (session->peer_addr.ip46)); @@ -1198,7 +1199,7 @@ vppcom_send_bind_sock (session_t * session) bmp->vrf = session->vrf; bmp->is_ip4 = session->lcl_addr.is_ip4; clib_memcpy (bmp->ip, &session->lcl_addr.ip46, sizeof (bmp->ip)); - bmp->port = session->port; + bmp->port = session->lcl_port; bmp->proto = session->proto; clib_memcpy (bmp->options, session->options, sizeof (bmp->options)); vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & bmp); @@ -1986,13 +1987,16 @@ vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep) return VPPCOM_EBADFD; } - if (VPPCOM_DEBUG > 0) - clib_warning ("[%d] sid %d", vcm->my_pid, session_index); - session->vrf = ep->vrf; session->lcl_addr.is_ip4 = ep->is_ip4; session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip); - session->port = ep->port; + session->lcl_port = ep->port; + + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] sid %d, bound to lcl address %U lcl port %u", + vcm->my_pid, session_index, format_ip46_address, + &session->lcl_addr.ip46, session->lcl_addr.is_ip4, + clib_net_to_host_u16 (session->lcl_port)); clib_spinlock_unlock (&vcm->sessions_lockp); return VPPCOM_OK; @@ -2138,16 +2142,26 @@ vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep, clib_warning ("[%d] Got a request: client sid %d", vcm->my_pid, client_session_index); + // Copy the lcl information from the listening session to the client session + // client_session->lcl_port = listen_session->lcl_port; + // client_session->lcl_addr = listen_session->lcl_addr; + ep->vrf = client_session->vrf; ep->is_cut_thru = client_session->is_cut_thru; ep->is_ip4 = client_session->peer_addr.is_ip4; - ep->port = client_session->port; + ep->port = client_session->peer_port; if (client_session->peer_addr.is_ip4) clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4, sizeof (ip4_address_t)); else clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6, sizeof (ip6_address_t)); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] sid %d, accepted peer address %U peer port %u", + vcm->my_pid, client_session_index, format_ip46_address, + &client_session->peer_addr.ip46, + client_session->peer_addr.is_ip4, + clib_net_to_host_u16 (client_session->peer_port)); clib_spinlock_unlock (&vcm->sessions_lockp); return (int) client_session_index; } @@ -2191,7 +2205,7 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) session->vrf = server_ep->vrf; session->peer_addr.is_ip4 = server_ep->is_ip4; session->peer_addr.ip46 = to_ip46 (!server_ep->is_ip4, server_ep->ip); - session->port = server_ep->port; + session->peer_port = server_ep->port; if (VPPCOM_DEBUG > 0) { @@ -2200,7 +2214,7 @@ vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep) session->peer_addr.is_ip4); 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->peer_port), session->proto ? "UDP" : "TCP"); vec_free (ip_str); } @@ -3181,7 +3195,7 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, { ep->vrf = session->vrf; ep->is_ip4 = session->peer_addr.is_ip4; - ep->port = session->port; + ep->port = session->peer_port; if (session->peer_addr.is_ip4) clib_memcpy (ep->ip, &session->peer_addr.ip46.ip4, sizeof (ip4_address_t)); @@ -3190,9 +3204,11 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, sizeof (ip6_address_t)); *buflen = sizeof (*ep); if (VPPCOM_DEBUG > 0) - clib_warning ("VPPCOM_ATTR_GET_PEER_ADDR: is_ip4 = %u, " - "addr = %U", ep->is_ip4, format_ip46_address, - &session->peer_addr.ip46, ep->is_ip4); + clib_warning ("VPPCOM_ATTR_GET_PEER_ADDR: sid %u is_ip4 = %u, " + "addr = %U, port %u", session_index, + ep->is_ip4, format_ip46_address, + &session->peer_addr.ip46, ep->is_ip4, + clib_net_to_host_u16 (ep->port)); } else rv = VPPCOM_EINVAL; @@ -3203,7 +3219,7 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, { ep->vrf = session->vrf; ep->is_ip4 = session->lcl_addr.is_ip4; - ep->port = session->port; + ep->port = session->lcl_port; if (session->lcl_addr.is_ip4) clib_memcpy (ep->ip, &session->lcl_addr.ip46.ip4, sizeof (ip4_address_t)); @@ -3212,10 +3228,11 @@ vppcom_session_attr (uint32_t session_index, uint32_t op, sizeof (ip6_address_t)); *buflen = sizeof (*ep); if (VPPCOM_DEBUG > 0) - 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); + clib_warning ("VPPCOM_ATTR_GET_LCL_ADDR: sid %u is_ip4 = %u, " + "addr = %U port %d", session_index, + ep->is_ip4, format_ip46_address, + &session->lcl_addr.ip46, ep->is_ip4, + clib_net_to_host_u16 (ep->port)); } else rv = VPPCOM_EINVAL; @@ -3249,6 +3266,71 @@ done: return rv; } +int +vppcom_session_recvfrom (uint32_t session_index, void *buffer, + uint32_t buflen, int flags, vppcom_endpt_t * ep) +{ + vppcom_main_t *vcm = &vppcom_main; + int rv = VPPCOM_OK; + session_t *session = 0; + + if (ep) + { + clib_spinlock_lock (&vcm->sessions_lockp); + rv = vppcom_session_at_index (session_index, &session); + if (PREDICT_FALSE (rv)) + { + clib_spinlock_unlock (&vcm->sessions_lockp); + if (VPPCOM_DEBUG > 0) + clib_warning ("[%d] invalid session, sid (%u) has been closed!", + vcm->my_pid, session_index); + rv = VPPCOM_EINVAL; + } + ep->vrf = session->vrf; + ep->is_ip4 = session->peer_addr.is_ip4; + ep->port = session->peer_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)); + clib_spinlock_unlock (&vcm->sessions_lockp); + rv = vppcom_session_read (session_index, buffer, buflen); + } + else if (flags == 0) + rv = vppcom_session_read (session_index, buffer, buflen); + else if (flags & MSG_PEEK) + { + rv = vppcom_session_attr (session_index, VPPCOM_ATTR_GET_NREAD, 0, 0); + if (rv > buflen) + rv = buflen; + } + else + { + clib_warning ("Unsupport flags for recvfro %d", flags); + rv = VPPCOM_EAFNOSUPPORT; + } + + return rv; +} + +int +vppcom_session_sendto (uint32_t session_index, void *buffer, + uint32_t buflen, int flags, vppcom_endpt_t * ep) +{ + if (ep) + // TBD + return -1; + else if (flags == 0) + return (vppcom_session_write (session_index, buffer, buflen)); + else if (flags) + // TBD check the flags and do the right thing + return (vppcom_session_write (session_index, buffer, buflen)); + + return -1; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h index dd72986ec53..d9ed22fe755 100644 --- a/src/vcl/vppcom.h +++ b/src/vcl/vppcom.h @@ -159,6 +159,12 @@ extern int vppcom_epoll_wait (uint32_t vep_idx, struct epoll_event *events, int maxevents, double wait_for_time); extern int vppcom_session_attr (uint32_t session_index, uint32_t op, void *buffer, uint32_t * buflen); +extern int vppcom_session_recvfrom (uint32_t session_index, void *buffer, + uint32_t buflen, int flags, + vppcom_endpt_t * ep); +extern int vppcom_session_sendto (uint32_t session_index, void *buffer, + uint32_t buflen, int flags, + vppcom_endpt_t * ep); #endif /* included_vppcom_h */ |