Networking: Drivers can have both IPv4 and IPv6 addesses, but a socket can only only one or the other; The socket connnection structures need to include a union of IPv4 and IPv6 addresses for the local address binding and for the remote address connections

This commit is contained in:
Gregory Nutt 2015-01-16 10:01:54 -06:00
parent fe8b3c5220
commit bee89be4f4
17 changed files with 113 additions and 75 deletions

View File

@ -90,7 +90,7 @@
* Public Type Definitions * Public Type Definitions
****************************************************************************/ ****************************************************************************/
/* Representation of an IP address */ /* Representation of an IP address in the IPv6 domains */
typedef uint16_t net_ipv6addr_t[8]; typedef uint16_t net_ipv6addr_t[8];
@ -100,6 +100,52 @@ typedef net_ipv6addr_t net_ipaddr_t;
typedef in_addr_t net_ipaddr_t; typedef in_addr_t net_ipaddr_t;
#endif #endif
/* Describes and address in either the IPv4 or IPv6 domain */
union ip_addr_u
{
#ifdef CONFIG_NET_IPv4
/* IPv4 address */
in_addr_t ipv4;
#endif
#ifdef CONFIG_NET_IPv6
/* IPv6 addresse */
net_ipv6addr_t ipv6;
#endif
};
/* Describes address binding for a PF_INET or PF_INET6 socket */
union ip_binding_u
{
#ifdef CONFIG_NET_IPv4
/* IPv4 addresses (for PF_INET socket) */
struct
{
#ifdef CONFIG_NETDEV_MULTINIC
in_addr_t laddr; /* The bound local IPv4 address */
#endif
in_addr_t raddr; /* The IPv4 address of the remote host */
} ipv4;
#endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6
/* IPv6 addresses (for PF_INET6 socket) */
struct
{
#ifdef CONFIG_NETDEV_MULTINIC
net_ipv6addr_t laddr; /* The bound local IPv6 address */
#endif
net_ipv6addr_t raddr; /* The IPv6 address of the remote host */
} ipv6;
#endif /* CONFIG_NET_IPv6 */
};
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
/* The IPv4 header */ /* The IPv4 header */

View File

@ -209,7 +209,7 @@ int ipv6_input(FAR struct net_driver_s *dev)
else else
#endif #endif
#ifdef CONFIG_NET_ICMPv6 #ifdef CONFIG_NET_ICMPv6
if (net_ipv6addr_cmp(dev->d_ipaddr, g_allzeroaddr)) if (net_ipv6addr_cmp(dev->d_ipv6addr, g_allzeroaddr))
{ {
/* If we are configured to use ping IP address configuration and /* If we are configured to use ping IP address configuration and
* hasn't been assigned an IP address yet, we accept all ICMP * hasn't been assigned an IP address yet, we accept all ICMP
@ -233,7 +233,7 @@ int ipv6_input(FAR struct net_driver_s *dev)
* multicast packets that are sent to the ff02::/16 addresses. * multicast packets that are sent to the ff02::/16 addresses.
*/ */
if (!net_ipv6addr_cmp(pbuf->destipaddr, dev->d_ipaddr) && if (!net_ipv6addr_cmp(pbuf->destipaddr, dev->d_ipv6addr) &&
pbuf->destipaddr[0] != 0xff02) pbuf->destipaddr[0] != 0xff02)
{ {
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS

View File

@ -160,7 +160,7 @@ netdev_finddevice_ipv6addr(const net_ipv6addr_t ripaddr)
{ {
/* Yes.. check for an address match (under the netmask) */ /* Yes.. check for an address match (under the netmask) */
if (net_ipaddr_maskcmp(dev->d_ipv6ipaddr, ripaddr, dev->d_ipv6netmask)) if (net_ipaddr_maskcmp(dev->d_ipv6addr, ripaddr, dev->d_ipv6netmask))
{ {
/* Its a match */ /* Its a match */

View File

@ -112,7 +112,7 @@ static inline void accept_tcpsender(FAR struct tcp_conn_s *conn,
{ {
addr->sin_family = AF_INET6; addr->sin_family = AF_INET6;
addr->sin_port = conn->rport; addr->sin_port = conn->rport;
net_ipaddr_copy(addr->sin6_addr.s6_addr, conn->ripaddr); net_ipaddr_copy(addr->sin6_addr.s6_addr, conn->u.ipv4.raddr);
} }
} }
#else #else
@ -123,7 +123,7 @@ static inline void accept_tcpsender(FAR struct tcp_conn_s *conn,
{ {
addr->sin_family = AF_INET; addr->sin_family = AF_INET;
addr->sin_port = conn->rport; addr->sin_port = conn->rport;
net_ipaddr_copy(addr->sin_addr.s_addr, conn->ripaddr); net_ipaddr_copy(addr->sin_addr.s_addr, conn->u.ipv4.raddr);
} }
} }
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */

View File

@ -121,8 +121,8 @@ int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn; FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn;
outaddr->sin_port = tcp_conn->lport; /* Already in network byte order */ outaddr->sin_port = tcp_conn->lport; /* Already in network byte order */
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
lipaddr = tcp_conn->lipaddr; lipaddr = tcp_conn->u.ipv4.laddr;
ripaddr = tcp_conn->ripaddr; ripaddr = tcp_conn->u.ipv4.raddr;
#endif #endif
} }
break; break;
@ -134,8 +134,8 @@ int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn; FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn;
outaddr->sin_port = udp_conn->lport; /* Already in network byte order */ outaddr->sin_port = udp_conn->lport; /* Already in network byte order */
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
lipaddr = udp_conn->lipaddr; lipaddr = udp_conn->u.ipv4.laddr;
ripaddr = udp_conn->ripaddr; ripaddr = udp_conn->u.ipv4.raddr;
#endif #endif
} }
break; break;
@ -244,8 +244,8 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn; FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn;
outaddr->sin_port = tcp_conn->lport; /* Already in network byte order */ outaddr->sin_port = tcp_conn->lport; /* Already in network byte order */
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
lipaddr = tcp_conn->lipaddr; lipaddr = &tcp_conn->u.ipv6.laddr;
ripaddr = tcp_conn->ripaddr; ripaddr = &tcp_conn->u.ipv6.raddr;
#endif #endif
} }
break; break;
@ -257,16 +257,15 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn; FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn;
outaddr->sin_port = udp_conn->lport; /* Already in network byte order */ outaddr->sin_port = udp_conn->lport; /* Already in network byte order */
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
lipaddr = &udp_conn->lipaddr; lipaddr = &udp_conn->u.ipv6.laddr;
ripaddr = &udp_conn->ripaddr; ripaddr = &udp_conn->u.ipv6.raddr;
#endif #endif
} }
break; break;
#endif #endif
default: default:
err = EOPNOTSUPP; return -EOPNOTSUPP;
goto errout;
} }
/* The socket/connection does not know its IP address unless /* The socket/connection does not know its IP address unless
@ -296,7 +295,7 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP) #if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
outaddr->sin_family = AF_INET6; outaddr->sin_family = AF_INET6;
memcpy(outaddr->sin6_addr.in6_u.u6_addr8, dev->d_ipaddr, 16); memcpy(outaddr->sin6_addr.in6_u.u6_addr8, dev->d_ipv6addr, 16);
*addrlen = sizeof(struct sockaddr_in6); *addrlen = sizeof(struct sockaddr_in6);
#endif #endif
netdev_semgive(); netdev_semgive();

View File

@ -358,9 +358,9 @@ static inline int netclose_disconnect(FAR struct socket *psock)
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
#ifdef CONFIG_NET_MULTILINK #ifdef CONFIG_NET_MULTILINK
netdev_txnotify(conn->lipaddr, conn->ripaddr); netdev_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr);
#else #else
netdev_txnotify(conn->ripaddr); netdev_txnotify(conn->u.ipv4.raddr);
#endif #endif
#ifdef CONFIG_NET_SOLINGER #ifdef CONFIG_NET_SOLINGER

View File

@ -330,7 +330,7 @@ static uint16_t sendfile_interrupt(FAR struct net_driver_s *dev, FAR void *pvcon
#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \ #if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \
!defined(CONFIG_NET_ARP_SEND) !defined(CONFIG_NET_ARP_SEND)
if (pstate->snd_sent != 0 || arp_find(conn->ripaddr) != NULL) if (pstate->snd_sent != 0 || arp_find(conn->u.ipv4.raddr) != NULL)
#endif #endif
{ {
/* Update the amount of data sent (but not necessarily ACKed) */ /* Update the amount of data sent (but not necessarily ACKed) */
@ -484,7 +484,7 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
/* Make sure that the IP address mapping is in the ARP table */ /* Make sure that the IP address mapping is in the ARP table */
#ifdef CONFIG_NET_ARP_SEND #ifdef CONFIG_NET_ARP_SEND
ret = arp_send(conn->ripaddr); ret = arp_send(conn->u.ipv4.raddr);
if (ret < 0) if (ret < 0)
{ {
ndbg("ERROR: Not reachable\n"); ndbg("ERROR: Not reachable\n");
@ -565,9 +565,9 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset,
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
#ifdef CONFIG_NET_MULTILINK #ifdef CONFIG_NET_MULTILINK
netdev_txnotify(conn->lipaddr, conn->ripaddr); netdev_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr);
#else #else
netdev_txnotify(conn->ripaddr); netdev_txnotify(conn->u.ipv4.raddr);
#endif #endif
net_lockedwait(&state.snd_sem); net_lockedwait(&state.snd_sem);
} }

View File

@ -1097,9 +1097,9 @@ static ssize_t pkt_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
#if 0 /* No */ #if 0 /* No */
#ifdef CONFIG_NET_MULTILINK #ifdef CONFIG_NET_MULTILINK
netdev_rxnotify(conn->lipaddr, conn->ripaddr); netdev_rxnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr);
#else #else
netdev_rxnotify(conn->ripaddr); netdev_rxnotify(conn->u.ipv4.raddr);
#endif #endif
#endif #endif
@ -1196,9 +1196,9 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
/* Notify the device driver of the receive call */ /* Notify the device driver of the receive call */
#ifdef CONFIG_NET_MULTILINK #ifdef CONFIG_NET_MULTILINK
netdev_rxnotify(conn->lipaddr, conn->ripaddr); netdev_rxnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr);
#else #else
netdev_rxnotify(conn->ripaddr); netdev_rxnotify(conn->u.ipv4.raddr);
#endif #endif
/* Wait for either the receive to complete or for an error/timeout to occur. /* Wait for either the receive to complete or for an error/timeout to occur.

View File

@ -420,9 +420,9 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
#ifdef CONFIG_NET_MULTILINK #ifdef CONFIG_NET_MULTILINK
netdev_txnotify(conn->lipaddr, conn->ripaddr); netdev_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr);
#else #else
netdev_txnotify(conn->ripaddr); netdev_txnotify(conn->u.ipv4.raddr);
#endif #endif
/* Wait for either the receive to complete or for an error/timeout to occur. /* Wait for either the receive to complete or for an error/timeout to occur.

View File

@ -90,7 +90,6 @@
/**************************************************************************** /****************************************************************************
* Public Type Definitions * Public Type Definitions
****************************************************************************/ ****************************************************************************/
/* Representation of a TCP connection. /* Representation of a TCP connection.
* *
* The tcp_conn_s structure is used for identifying a connection. All * The tcp_conn_s structure is used for identifying a connection. All
@ -108,10 +107,7 @@ struct tcp_hdr_s; /* Forward reference */
struct tcp_conn_s struct tcp_conn_s
{ {
dq_entry_t node; /* Implements a doubly linked list */ dq_entry_t node; /* Implements a doubly linked list */
#ifdef CONFIG_NETDEV_MULTINIC union ip_binding_u u; /* IP address binding */
net_ipaddr_t lipaddr; /* The bound local IP address */
#endif
net_ipaddr_t ripaddr; /* The IP address of the remote host */
uint8_t rcvseq[4]; /* The sequence number that we expect to uint8_t rcvseq[4]; /* The sequence number that we expect to
* receive next */ * receive next */
uint8_t sndseq[4]; /* The sequence number that was last sent by us */ uint8_t sndseq[4]; /* The sequence number that was last sent by us */

View File

@ -132,11 +132,11 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno)
* with INADDR_ANY. * with INADDR_ANY.
*/ */
if (net_ipaddr_cmp(conn->lipaddr, ipaddr) || if (net_ipaddr_cmp(conn->u.ipv4.laddr, ipaddr) ||
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr)) net_ipaddr_cmp(conn->u.ipv4.laddr, g_allzeroaddr))
#else #else
net_ipaddr_cmp(conn->lipaddr, INADDR_ANY)) net_ipaddr_cmp(conn->u.ipv4.laddr, INADDR_ANY))
#endif #endif
#endif #endif
{ {
@ -525,10 +525,10 @@ FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
tcp->destport == conn->lport && tcp->destport == conn->lport &&
tcp->srcport == conn->rport && tcp->srcport == conn->rport &&
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
(net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr) || (net_ipaddr_cmp(conn->u.ipv4.laddr, g_allzeroaddr) ||
net_ipaddr_cmp(destipaddr, conn->lipaddr)) && net_ipaddr_cmp(destipaddr, conn->u.ipv4.laddr)) &&
#endif #endif
net_ipaddr_cmp(srcipaddr, conn->ripaddr)) net_ipaddr_cmp(srcipaddr, conn->u.ipv4.raddr))
{ {
/* Matching connection found.. break out of the loop and return a /* Matching connection found.. break out of the loop and return a
* reference to it. * reference to it.
@ -601,9 +601,9 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
conn->lport = tcp->destport; conn->lport = tcp->destport;
conn->rport = tcp->srcport; conn->rport = tcp->srcport;
conn->mss = TCP_INITIAL_MSS(dev); conn->mss = TCP_INITIAL_MSS(dev);
net_ipaddr_copy(conn->ripaddr, net_ip4addr_conv32(ip->srcipaddr)); net_ipaddr_copy(conn->u.ipv4.raddr, net_ip4addr_conv32(ip->srcipaddr));
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
net_ipaddr_copy(conn->lipaddr, net_ip4addr_conv32(ip->destipaddr)); net_ipaddr_copy(conn->u.ipv4.laddr, net_ip4addr_conv32(ip->destipaddr));
#endif #endif
conn->tcpstateflags = TCP_SYN_RCVD; conn->tcpstateflags = TCP_SYN_RCVD;
@ -707,7 +707,7 @@ int tcp_bind(FAR struct tcp_conn_s *conn,
conn->lport = addr->sin_port; conn->lport = addr->sin_port;
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
net_ipaddr_copy(conn->lipaddr, ipaddr); net_ipaddr_copy(conn->u.ipv4.laddr, ipaddr);
#endif #endif
return OK; return OK;
@ -761,7 +761,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn,
flags = net_lock(); flags = net_lock();
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
port = tcp_selectport(conn->lipaddr, ntohs(conn->lport)); port = tcp_selectport(conn->u.ipv4.laddr, ntohs(conn->lport));
#else #else
port = tcp_selectport(ntohs(conn->lport)); port = tcp_selectport(ntohs(conn->lport));
#endif #endif
@ -801,7 +801,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn,
/* The sockaddr address is 32-bits in network order. */ /* The sockaddr address is 32-bits in network order. */
net_ipaddr_copy(conn->ripaddr, addr->sin_addr.s_addr); net_ipaddr_copy(conn->u.ipv4.raddr, addr->sin_addr.s_addr);
#ifdef CONFIG_NET_TCP_READAHEAD #ifdef CONFIG_NET_TCP_READAHEAD
/* Initialize the list of TCP read-ahead buffers */ /* Initialize the list of TCP read-ahead buffers */

View File

@ -188,7 +188,7 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
pbuf->destport = conn->rport; pbuf->destport = conn->rport;
net_ipaddr_hdrcopy(pbuf->srcipaddr, &dev->d_ipaddr); net_ipaddr_hdrcopy(pbuf->srcipaddr, &dev->d_ipaddr);
net_ipaddr_hdrcopy(pbuf->destipaddr, &conn->ripaddr); net_ipaddr_hdrcopy(pbuf->destipaddr, &conn->u.ipv4.raddr);
if (conn->tcpstateflags & TCP_STOPPED) if (conn->tcpstateflags & TCP_STOPPED)
{ {

View File

@ -552,7 +552,7 @@ static uint16_t psock_send_interrupt(FAR struct net_driver_s *dev,
#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \ #if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \
!defined(CONFIG_NET_ARP_SEND) !defined(CONFIG_NET_ARP_SEND)
if (arp_find(conn->ripaddr) != NULL) if (arp_find(conn->u.ipv4.raddr) != NULL)
#endif #endif
{ {
FAR struct tcp_wrbuffer_s *wrb; FAR struct tcp_wrbuffer_s *wrb;
@ -754,7 +754,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
conn = (FAR struct tcp_conn_s *)psock->s_conn; conn = (FAR struct tcp_conn_s *)psock->s_conn;
#ifdef CONFIG_NET_ARP_SEND #ifdef CONFIG_NET_ARP_SEND
ret = arp_send(conn->ripaddr); ret = arp_send(conn->u.ipv4.raddr);
if (ret < 0) if (ret < 0)
{ {
ndbg("ERROR: Not reachable\n"); ndbg("ERROR: Not reachable\n");
@ -829,9 +829,9 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
#ifdef CONFIG_NET_MULTILINK #ifdef CONFIG_NET_MULTILINK
netdev_txnotify(conn->lipaddr, conn->ripaddr); netdev_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr);
#else #else
netdev_txnotify(conn->ripaddr); netdev_txnotify(conn->u.ipv4.raddr);
#endif #endif
result = len; result = len;
} }

View File

@ -397,7 +397,7 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev,
#if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \ #if defined(CONFIG_NET_ETHERNET) && !defined(CONFIG_NET_ARP_IPIN) && \
!defined(CONFIG_NET_ARP_SEND) !defined(CONFIG_NET_ARP_SEND)
if (pstate->snd_sent != 0 || arp_find(conn->ripaddr) != NULL) if (pstate->snd_sent != 0 || arp_find(conn->u.ipv4.raddr) != NULL)
#endif #endif
{ {
/* Update the amount of data sent (but not necessarily ACKed) */ /* Update the amount of data sent (but not necessarily ACKed) */
@ -538,7 +538,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
conn = (FAR struct tcp_conn_s *)psock->s_conn; conn = (FAR struct tcp_conn_s *)psock->s_conn;
#ifdef CONFIG_NET_ARP_SEND #ifdef CONFIG_NET_ARP_SEND
ret = arp_send(conn->ripaddr); ret = arp_send(conn->u.ipv4.raddr);
if (ret < 0) if (ret < 0)
{ {
ndbg("ERROR: Not reachable\n"); ndbg("ERROR: Not reachable\n");
@ -591,15 +591,15 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL |
TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT); TCP_CLOSE | TCP_ABORT | TCP_TIMEDOUT);
state.snd_cb->priv = (void*)&state; state.snd_cb->priv = (FAR void *)&state;
state.snd_cb->event = tcpsend_interrupt; state.snd_cb->event = tcpsend_interrupt;
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
#ifdef CONFIG_NET_MULTILINK #ifdef CONFIG_NET_MULTILINK
netdev_txnotify(conn->lipaddr, conn->ripaddr); netdev_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr);
#else #else
netdev_txnotify(conn->ripaddr); netdev_txnotify(conn->u.ipv4.raddr);
#endif #endif
/* Wait for the send to complete or an error to occur: NOTES: (1) /* Wait for the send to complete or an error to occur: NOTES: (1)

View File

@ -67,10 +67,7 @@ struct udp_hdr_s; /* Forward reference */
struct udp_conn_s struct udp_conn_s
{ {
dq_entry_t node; /* Supports a doubly linked list */ dq_entry_t node; /* Supports a doubly linked list */
#ifdef CONFIG_NETDEV_MULTINIC union ip_binding_u u; /* IP address binding */
net_ipaddr_t lipaddr; /* Bound local IP address (network byte order) */
#endif
net_ipaddr_t ripaddr; /* IP address of remote peer (network byte order) */
uint16_t lport; /* Bound local port number (network byte order) */ uint16_t lport; /* Bound local port number (network byte order) */
uint16_t rport; /* Remote port number (network byte order) */ uint16_t rport; /* Remote port number (network byte order) */
uint8_t ttl; /* Default time-to-live */ uint8_t ttl; /* Default time-to-live */

View File

@ -150,11 +150,11 @@ static FAR struct udp_conn_s *udp_find_conn(uint16_t portno)
*/ */
if (conn->lport == portno && if (conn->lport == portno &&
(net_ipaddr_cmp(conn->lipaddr, ipaddr) || (net_ipaddr_cmp(conn->u.ipv4.laddr, ipaddr) ||
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr))) net_ipaddr_cmp(conn->u.ipv4.laddr, g_allzeroaddr)))
#else #else
net_ipaddr_cmp(conn->lipaddr, INADDR_ANY))) net_ipaddr_cmp(conn->u.ipv4.laddr, INADDR_ANY)))
#endif #endif
{ {
return conn; return conn;
@ -368,7 +368,7 @@ FAR struct udp_conn_s *udp_active(FAR struct net_driver_s *dev,
* IP address is available and we will insist that the * IP address is available and we will insist that the
* destination IP matches the bound address (or the destination * destination IP matches the bound address (or the destination
* IP address is a broadcast address). If a socket is bound to * IP address is a broadcast address). If a socket is bound to
* INADDRY_ANY (lipaddr), then it should receive all packets * INADDRY_ANY (laddr), then it should receive all packets
* directed to the port. * directed to the port.
* - Finally, if the connection is bound to a remote IP address, * - Finally, if the connection is bound to a remote IP address,
* the source IP address of the packet is checked. Broadcast * the source IP address of the packet is checked. Broadcast
@ -381,13 +381,13 @@ FAR struct udp_conn_s *udp_active(FAR struct net_driver_s *dev,
if (conn->lport != 0 && udp->destport == conn->lport && if (conn->lport != 0 && udp->destport == conn->lport &&
(conn->rport == 0 || udp->srcport == conn->rport) && (conn->rport == 0 || udp->srcport == conn->rport) &&
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
(net_ipaddr_cmp(conn->lipaddr, g_allzeroaddr) || (net_ipaddr_cmp(conn->u.ipv4.laddr, g_allzeroaddr) ||
net_ipaddr_cmp(conn->lipaddr, g_alloneaddr) || net_ipaddr_cmp(conn->u.ipv4.laddr, g_alloneaddr) ||
net_ipaddr_hdrcmp(ip->destipaddr, &conn->lipaddr)) && net_ipaddr_hdrcmp(ip->destipaddr, &conn->u.ipv4.laddr)) &&
#endif #endif
(net_ipaddr_cmp(conn->ripaddr, g_allzeroaddr) || (net_ipaddr_cmp(conn->u.ipv4.raddr, g_allzeroaddr) ||
net_ipaddr_cmp(conn->ripaddr, g_alloneaddr) || net_ipaddr_cmp(conn->u.ipv4.raddr, g_alloneaddr) ||
net_ipaddr_hdrcmp(ip->srcipaddr, &conn->ripaddr))) net_ipaddr_hdrcmp(ip->srcipaddr, &conn->u.ipv4.raddr)))
{ {
/* Matching connection found.. return a reference to it */ /* Matching connection found.. return a reference to it */
@ -467,7 +467,7 @@ int udp_bind(FAR struct udp_conn_s *conn, FAR const struct sockaddr_in *addr)
* for receiving (Sending will use the default port). * for receiving (Sending will use the default port).
*/ */
net_ipaddr_copy(conn->lipaddr, ipaddr); net_ipaddr_copy(conn->u.ipv4.laddr, ipaddr);
#endif #endif
/* Is the user requesting to bind to any port? */ /* Is the user requesting to bind to any port? */
@ -553,7 +553,7 @@ int udp_connect(FAR struct udp_conn_s *conn,
*/ */
#ifdef CONFIG_NETDEV_MULTINIC #ifdef CONFIG_NETDEV_MULTINIC
conn->lport = htons(udp_select_port(conn->lipaddr)); conn->lport = htons(udp_select_port(conn->u.ipv4.laddr));
#else #else
conn->lport = htons(udp_select_port()); conn->lport = htons(udp_select_port());
#endif #endif
@ -564,12 +564,12 @@ int udp_connect(FAR struct udp_conn_s *conn,
if (addr) if (addr)
{ {
conn->rport = addr->sin_port; conn->rport = addr->sin_port;
net_ipaddr_copy(conn->ripaddr, addr->sin_addr.s_addr); net_ipaddr_copy(conn->u.ipv4.raddr, addr->sin_addr.s_addr);
} }
else else
{ {
conn->rport = 0; conn->rport = 0;
net_ipaddr_copy(conn->ripaddr, g_allzeroaddr); net_ipaddr_copy(conn->u.ipv4.raddr, g_allzeroaddr);
} }
conn->ttl = IP_TTL; conn->ttl = IP_TTL;

View File

@ -126,7 +126,7 @@ void udp_send(struct net_driver_s *dev, struct udp_conn_s *conn)
pudpbuf->ttl = conn->ttl; pudpbuf->ttl = conn->ttl;
net_ipaddr_copy(pudpbuf->srcipaddr, &dev->d_ipaddr); net_ipaddr_copy(pudpbuf->srcipaddr, &dev->d_ipaddr);
net_ipaddr_copy(pudpbuf->destipaddr, &conn->ripaddr); net_ipaddr_copy(pudpbuf->destipaddr, &conn->u.ipv4.raddr);
#else /* CONFIG_NET_IPv6 */ #else /* CONFIG_NET_IPv6 */
@ -143,7 +143,7 @@ void udp_send(struct net_driver_s *dev, struct udp_conn_s *conn)
pudpbuf->proto = IP_PROTO_UDP; pudpbuf->proto = IP_PROTO_UDP;
net_ipaddr_hdrcopy(pudpbuf->srcipaddr, &dev->d_ipaddr); net_ipaddr_hdrcopy(pudpbuf->srcipaddr, &dev->d_ipaddr);
net_ipaddr_hdrcopy(pudpbuf->destipaddr, &conn->ripaddr); net_ipaddr_hdrcopy(pudpbuf->destipaddr, &conn->u.ipv4.raddr);
/* Calculate IP checksum. */ /* Calculate IP checksum. */