netlink: Remove netlink_route_recvfrom
The same functionality could be implemented in the common place(netlink_recvfrom) Change-Id: I8aedb29c4f0572f020ca5c0775f06c5e1e17ae4a Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
parent
16dbe373c0
commit
70012bc4a2
@ -279,21 +279,6 @@ ssize_t netlink_route_sendto(FAR struct socket *psock,
|
|||||||
socklen_t tolen);
|
socklen_t tolen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: netlink_route_recvfrom()
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Perform the recvfrom() operation for the NETLINK_ROUTE protocol.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_NETLINK_ROUTE
|
|
||||||
ssize_t netlink_route_recvfrom(FAR struct socket *psock,
|
|
||||||
FAR struct nlmsghdr *nlmsg,
|
|
||||||
size_t len, int flags,
|
|
||||||
FAR struct sockaddr_nl *from);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1015,179 +1015,4 @@ ssize_t netlink_route_sendto(FAR struct socket *psock,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: netlink_route_recvfrom()
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Perform the recvfrom() operation for the NETLINK_ROUTE protocol.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
ssize_t netlink_route_recvfrom(FAR struct socket *psock,
|
|
||||||
FAR struct nlmsghdr *nlmsg,
|
|
||||||
size_t len, int flags,
|
|
||||||
FAR struct sockaddr_nl *from)
|
|
||||||
{
|
|
||||||
FAR struct netlink_response_s *entry;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
DEBUGASSERT(psock != NULL && nlmsg != NULL &&
|
|
||||||
len >= sizeof(struct nlmsghdr));
|
|
||||||
|
|
||||||
/* Find the response to this message. The return value */
|
|
||||||
|
|
||||||
entry = (FAR struct netlink_response_s *)netlink_tryget_response(psock);
|
|
||||||
if (entry == NULL)
|
|
||||||
{
|
|
||||||
/* No response is variable, but presumably, one is expected. Check
|
|
||||||
* if the socket has been configured for non-blocking operation.
|
|
||||||
* REVISIT: I think there needs to be some higher level logic to
|
|
||||||
* select Netlink non-blocking sockets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
|
|
||||||
{
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for the response. This should always succeed. */
|
|
||||||
|
|
||||||
entry = (FAR struct netlink_response_s *)netlink_get_response(psock);
|
|
||||||
DEBUGASSERT(entry != NULL);
|
|
||||||
if (entry == NULL)
|
|
||||||
{
|
|
||||||
return -EPIPE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len < entry->msg.nlmsg_len)
|
|
||||||
{
|
|
||||||
kmm_free(entry);
|
|
||||||
return -EMSGSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle the response according to the message type */
|
|
||||||
|
|
||||||
switch (entry->msg.nlmsg_type)
|
|
||||||
{
|
|
||||||
#ifndef CONFIG_NETLINK_DISABLE_GETLINK
|
|
||||||
case RTM_NEWLINK:
|
|
||||||
{
|
|
||||||
FAR struct getlink_recvfrom_rsplist_s *resp =
|
|
||||||
(FAR struct getlink_recvfrom_rsplist_s *)entry;
|
|
||||||
|
|
||||||
/* Copy the payload to the user buffer */
|
|
||||||
|
|
||||||
memcpy(nlmsg, &resp->payload, resp->payload.hdr.nlmsg_len);
|
|
||||||
|
|
||||||
/* Return address. REVISIT... this is just a guess. */
|
|
||||||
|
|
||||||
if (from != NULL)
|
|
||||||
{
|
|
||||||
from->nl_family = resp->payload.iface.ifi_family;
|
|
||||||
from->nl_pad = 0;
|
|
||||||
from->nl_pid = resp->payload.hdr.nlmsg_pid;
|
|
||||||
from->nl_groups = resp->payload.hdr.nlmsg_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The return value is the payload size */
|
|
||||||
|
|
||||||
ret = resp->payload.hdr.nlmsg_len;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_NETLINK_DISABLE_GETNEIGH
|
|
||||||
case RTM_GETNEIGH:
|
|
||||||
{
|
|
||||||
FAR struct getneigh_recvfrom_rsplist_s *resp =
|
|
||||||
(FAR struct getneigh_recvfrom_rsplist_s *)entry;
|
|
||||||
|
|
||||||
/* Copy the payload to the user buffer */
|
|
||||||
|
|
||||||
memcpy(nlmsg, &resp->payload, resp->payload.hdr.nlmsg_len);
|
|
||||||
|
|
||||||
/* Return address. REVISIT... this is just a guess. */
|
|
||||||
|
|
||||||
if (from != NULL)
|
|
||||||
{
|
|
||||||
from->nl_family = resp->payload.msg.ndm_family;
|
|
||||||
from->nl_pad = 0;
|
|
||||||
from->nl_pid = resp->payload.hdr.nlmsg_pid;
|
|
||||||
from->nl_groups = resp->payload.hdr.nlmsg_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The return value is the payload size */
|
|
||||||
|
|
||||||
ret = resp->payload.hdr.nlmsg_len;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_NETLINK_DISABLE_GETROUTE
|
|
||||||
case RTM_NEWROUTE:
|
|
||||||
{
|
|
||||||
FAR struct getroute_recvfrom_resplist_s *resp =
|
|
||||||
(FAR struct getroute_recvfrom_resplist_s *)entry;
|
|
||||||
|
|
||||||
/* Copy the payload to the user buffer */
|
|
||||||
|
|
||||||
memcpy(nlmsg, &resp->payload, resp->payload.hdr.nlmsg_len);
|
|
||||||
|
|
||||||
/* Return address. REVISIT... this is just a guess. */
|
|
||||||
|
|
||||||
if (from != NULL)
|
|
||||||
{
|
|
||||||
from->nl_family = resp->payload.rte.rtm_family;
|
|
||||||
from->nl_pad = 0;
|
|
||||||
from->nl_pid = resp->payload.hdr.nlmsg_pid;
|
|
||||||
from->nl_groups = resp->payload.hdr.nlmsg_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The return value is the payload size */
|
|
||||||
|
|
||||||
ret = resp->payload.hdr.nlmsg_len;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NETLINK_DISABLE_NLMSGDONE
|
|
||||||
case NLMSG_DONE:
|
|
||||||
{
|
|
||||||
FAR struct nlroute_msgdone_rsplist_s *resp =
|
|
||||||
(FAR struct nlroute_msgdone_rsplist_s *)entry;
|
|
||||||
|
|
||||||
/* Copy the payload to the user buffer */
|
|
||||||
|
|
||||||
resp->payload.hdr.nlmsg_len = sizeof(struct nlmsghdr);
|
|
||||||
memcpy(nlmsg, &resp->payload, sizeof(struct nlmsghdr));
|
|
||||||
|
|
||||||
/* Return address. REVISIT... this is just a guess. */
|
|
||||||
|
|
||||||
if (from != NULL)
|
|
||||||
{
|
|
||||||
from->nl_family = resp->payload.gen.rtgen_family;
|
|
||||||
from->nl_pad = 0;
|
|
||||||
from->nl_pid = resp->payload.hdr.nlmsg_pid;
|
|
||||||
from->nl_groups = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The return value is the payload size */
|
|
||||||
|
|
||||||
ret = sizeof(struct nlmsghdr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
nerr("ERROR: Unrecognized message type: %u\n",
|
|
||||||
entry->msg.nlmsg_type);
|
|
||||||
ret = -EIO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
kmm_free(entry);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_NETLINK_ROUTE */
|
#endif /* CONFIG_NETLINK_ROUTE */
|
||||||
|
@ -799,40 +799,52 @@ static ssize_t netlink_recvfrom(FAR struct socket *psock, FAR void *buf,
|
|||||||
FAR struct sockaddr *from,
|
FAR struct sockaddr *from,
|
||||||
FAR socklen_t *fromlen)
|
FAR socklen_t *fromlen)
|
||||||
{
|
{
|
||||||
FAR struct netlink_conn_s *conn;
|
FAR struct netlink_response_s *entry;
|
||||||
FAR struct nlmsghdr *nlmsg;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
|
DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
|
||||||
DEBUGASSERT(from == NULL ||
|
DEBUGASSERT(from == NULL ||
|
||||||
(fromlen != NULL && *fromlen >= sizeof(struct sockaddr_nl)));
|
(fromlen != NULL && *fromlen >= sizeof(struct sockaddr_nl)));
|
||||||
|
|
||||||
conn = (FAR struct netlink_conn_s *)psock->s_conn;
|
/* Find the response to this message. The return value */
|
||||||
|
|
||||||
/* Get a reference to the NetLink message */
|
entry = (FAR struct netlink_response_s *)netlink_tryget_response(psock);
|
||||||
|
if (entry == NULL)
|
||||||
nlmsg = (FAR struct nlmsghdr *)buf;
|
|
||||||
|
|
||||||
switch (conn->protocol)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NETLINK_ROUTE
|
/* No response is variable, but presumably, one is expected. Check
|
||||||
case NETLINK_ROUTE:
|
* if the socket has been configured for non-blocking operation.
|
||||||
ret = netlink_route_recvfrom(psock, nlmsg, len, flags,
|
*/
|
||||||
(FAR struct sockaddr_nl *)from);
|
|
||||||
if (ret >= 0 && fromlen != NULL)
|
|
||||||
{
|
|
||||||
*fromlen = sizeof(struct sockaddr_nl);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
|
||||||
#endif
|
{
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
/* Wait for the response. This should always succeed. */
|
||||||
ret = -EOPNOTSUPP;
|
|
||||||
break;
|
entry = (FAR struct netlink_response_s *)netlink_get_response(psock);
|
||||||
|
DEBUGASSERT(entry != NULL);
|
||||||
|
if (entry == NULL)
|
||||||
|
{
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
if (len > entry->msg.nlmsg_len)
|
||||||
|
{
|
||||||
|
len = entry->msg.nlmsg_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the payload to the user buffer */
|
||||||
|
|
||||||
|
memcpy(buf, &entry->msg, len);
|
||||||
|
kmm_free(entry);
|
||||||
|
|
||||||
|
if (from != NULL)
|
||||||
|
{
|
||||||
|
netlink_getpeername(psock, from, fromlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user