You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/04/10 14:18:22 UTC

[incubator-nuttx] 05/08: netlink: Implement netlink_connect and netlink_getpeername

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 16dbe373c0f5120023310334b4e7ed1a9ec682d8
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Wed Apr 8 02:31:57 2020 +0800

    netlink: Implement netlink_connect and netlink_getpeername
    
    and refine netlink_bind and netlink_send implmentation
    
    Change-Id: I2b3e7980eac01dc42927cfaa0a64874df52d6bf5
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 net/netlink/netlink.h        |   2 +
 net/netlink/netlink_sockif.c | 107 +++++++++++++++++++++++--------------------
 2 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/net/netlink/netlink.h b/net/netlink/netlink.h
index ff745b5..f1f204c 100644
--- a/net/netlink/netlink.h
+++ b/net/netlink/netlink.h
@@ -71,6 +71,8 @@ struct netlink_conn_s
 
   uint32_t pid;                      /* Port ID (if bound) */
   uint32_t groups;                   /* Multicast groups mask (if bound) */
+  uint32_t dst_pid;                  /* Destination port ID */
+  uint32_t dst_groups;               /* Destination multicast groups mask */
   uint8_t crefs;                     /* Reference counts on this instance */
   uint8_t protocol;                  /* See NETLINK_* definitions */
 
diff --git a/net/netlink/netlink_sockif.c b/net/netlink/netlink_sockif.c
index 45fc04e..63c9bd5 100644
--- a/net/netlink/netlink_sockif.c
+++ b/net/netlink/netlink_sockif.c
@@ -281,11 +281,11 @@ static int netlink_bind(FAR struct socket *psock,
 
   /* Save the address information in the connection structure */
 
-  nladdr          = (FAR struct sockaddr_nl *)addr;
-  conn            = (FAR struct netlink_conn_s *)psock->s_conn;
+  nladdr = (FAR struct sockaddr_nl *)addr;
+  conn   = (FAR struct netlink_conn_s *)psock->s_conn;
 
-  conn->pid       = nladdr->nl_pid;
-  conn->groups    = nladdr->nl_groups;
+  conn->pid    = nladdr->nl_pid ? nladdr->nl_pid : getpid();
+  conn->groups = nladdr->nl_groups;
 
   return OK;
 }
@@ -317,25 +317,21 @@ static int netlink_getsockname(FAR struct socket *psock,
                                FAR socklen_t *addrlen)
 {
   FAR struct sockaddr_nl *nladdr;
+  FAR struct netlink_conn_s *conn;
 
   DEBUGASSERT(psock != NULL && psock->s_conn != NULL && addr != NULL &&
               addrlen != NULL && *addrlen >= sizeof(struct sockaddr_nl));
 
+  conn = (FAR struct netlink_conn_s *)psock->s_conn;
+
   /* Return the address information in the address structure */
 
   nladdr = (FAR struct sockaddr_nl *)addr;
   memset(nladdr, 0, sizeof(struct sockaddr_nl));
 
-  nladdr->nl_family     = AF_NETLINK;
-
-  if (_SS_ISBOUND(psock->s_flags))
-    {
-      FAR struct netlink_conn_s *conn;
-
-      conn              = (FAR struct netlink_conn_s *)psock->s_conn;
-      nladdr->nl_pid    = conn->pid;
-      nladdr->nl_groups = conn->groups;
-    }
+  nladdr->nl_family = AF_NETLINK;
+  nladdr->nl_pid    = conn->pid;
+  nladdr->nl_groups = conn->groups;
 
   *addrlen = sizeof(struct sockaddr_nl);
   return OK;
@@ -373,8 +369,25 @@ static int netlink_getpeername(FAR struct socket *psock,
                                FAR struct sockaddr *addr,
                                FAR socklen_t *addrlen)
 {
-#warning Missing logic for NETLINK getsockname
-  return -EOPNOTSUPP;  /* Or maybe return -EAFNOSUPPORT; */
+  FAR struct sockaddr_nl *nladdr;
+  FAR struct netlink_conn_s *conn;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && addr != NULL &&
+              addrlen != NULL && *addrlen >= sizeof(struct sockaddr_nl));
+
+  conn = (FAR struct netlink_conn_s *)psock->s_conn;
+
+  /* Return the address information in the address structure */
+
+  nladdr = (FAR struct sockaddr_nl *)addr;
+  memset(nladdr, 0, sizeof(struct sockaddr_nl));
+
+  nladdr->nl_family = AF_NETLINK;
+  nladdr->nl_pid    = conn->dst_pid;
+  nladdr->nl_groups = conn->dst_groups;
+
+  *addrlen = sizeof(struct sockaddr_nl);
+  return OK;
 }
 
 /****************************************************************************
@@ -405,7 +418,6 @@ static int netlink_getpeername(FAR struct socket *psock,
 
 static int netlink_listen(FAR struct socket *psock, int backlog)
 {
-#warning Missing logic for NETLINK listen
   return -EOPNOTSUPP;
 }
 
@@ -431,8 +443,21 @@ static int netlink_connect(FAR struct socket *psock,
                            FAR const struct sockaddr *addr,
                            socklen_t addrlen)
 {
-#warning Missing logic for NETLINK connect
-  return -EOPNOTSUPP;
+  FAR struct sockaddr_nl *nladdr;
+  FAR struct netlink_conn_s *conn;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && addr != NULL &&
+              addrlen >= sizeof(struct sockaddr_nl));
+
+  /* Save the address information in the connection structure */
+
+  nladdr = (FAR struct sockaddr_nl *)addr;
+  conn   = (FAR struct netlink_conn_s *)psock->s_conn;
+
+  conn->dst_pid    = nladdr->nl_pid;
+  conn->dst_groups = nladdr->nl_groups;
+
+  return OK;
 }
 
 /****************************************************************************
@@ -482,7 +507,6 @@ static int netlink_connect(FAR struct socket *psock,
 static int netlink_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
                           FAR socklen_t *addrlen, FAR struct socket *newsock)
 {
-#warning Missing logic for NETLINK accept
   return -EOPNOTSUPP;
 }
 
@@ -665,38 +689,27 @@ static int netlink_poll(FAR struct socket *psock, FAR struct pollfd *fds,
 static ssize_t netlink_send(FAR struct socket *psock, FAR const void *buf,
                             size_t len, int flags)
 {
-  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
-
-  /* The socket must be connected in order to use send */
-
-  if (_SS_ISBOUND(psock->s_flags))
-    {
-      FAR struct netlink_conn_s *conn;
-      struct sockaddr_nl nladdr;
-
-      /* Get the underlying connection structure */
+  FAR struct netlink_conn_s *conn;
+  struct sockaddr_nl nladdr;
 
-      conn             = (FAR struct netlink_conn_s *)psock->s_conn;
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
 
-      /* Format the address */
+  /* Get the underlying connection structure */
 
-      nladdr.nl_family = AF_NETLINK;
-      nladdr.nl_pad    = 0;
-      nladdr.nl_pid    = conn->pid;
-      nladdr.nl_groups = conn->groups;
+  conn = (FAR struct netlink_conn_s *)psock->s_conn;
 
-      /* Then let sendto() perform the actual send operation */
+  /* Format the address */
 
-      return netlink_sendto(psock, buf, len, flags,
-                            (FAR const struct sockaddr *)&nladdr,
-                            sizeof(struct sockaddr_nl));
-    }
+  nladdr.nl_family = AF_NETLINK;
+  nladdr.nl_pad    = 0;
+  nladdr.nl_pid    = conn->dst_pid;
+  nladdr.nl_groups = conn->dst_groups;
 
-  /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and no
-   * peer address is set.
-   */
+  /* Then let sendto() perform the actual send operation */
 
-  return -EDESTADDRREQ;
+  return netlink_sendto(psock, buf, len, flags,
+                        (FAR const struct sockaddr *)&nladdr,
+                        sizeof(struct sockaddr_nl));
 }
 
 /****************************************************************************
@@ -851,10 +864,6 @@ static int netlink_close(FAR struct socket *psock)
 
   if (conn->crefs <= 1)
     {
-      /* Yes... inform user-space daemon of socket close. */
-
-#warning Missing logic in NETLINK close()
-
       /* Free the connection structure */
 
       conn->crefs = 0;