aboutsummaryrefslogtreecommitdiffstats
path: root/src/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'src/vcl')
-rw-r--r--src/vcl/vcom_socket.c98
-rw-r--r--src/vcl/vppcom.c124
-rw-r--r--src/vcl/vppcom.h6
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 */