mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 03:45:50 +08:00
net/icmpv6: Fix icmpv6_neighbor for link-local address
The netdev of link-local address cannot be auto decided, and the link-local address should always be reguarded as address on local network. The problem we met: When using `icmpv6_autoconfig` with multiple netdev, the `icmpv6_neighbor` may take out wrong netdev with ip address already set, then it may send solicitation with wrong address (`dev->d_ipv6draddr`) on wrong device, and regard the link-local address as conflict (because `dev->d_ipv6draddr` exists on this network). Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
+5
-2
@@ -205,6 +205,8 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen);
|
|||||||
* ICMPv6 Neighbor Advertisement.
|
* ICMPv6 Neighbor Advertisement.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
|
* dev The suggested device driver structure to do the solicitation,
|
||||||
|
* can be NULL for auto decision, must set for link-local ipaddr.
|
||||||
* ipaddr The IPv6 address to be queried.
|
* ipaddr The IPv6 address to be queried.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -221,9 +223,10 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
||||||
int icmpv6_neighbor(const net_ipv6addr_t ipaddr);
|
int icmpv6_neighbor(FAR struct net_driver_s *dev,
|
||||||
|
const net_ipv6addr_t ipaddr);
|
||||||
#else
|
#else
|
||||||
# define icmpv6_neighbor(i) (0)
|
# define icmpv6_neighbor(d,i) (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
|||||||
* method must be employed.
|
* method must be employed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = icmpv6_neighbor(lladdr);
|
ret = icmpv6_neighbor(dev, lladdr);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
/* Hmmm... someone else responded to our Neighbor Solicitation. We
|
/* Hmmm... someone else responded to our Neighbor Solicitation. We
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ static uint16_t icmpv6_neighbor_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
* ICMPv6 Neighbor Advertisement.
|
* ICMPv6 Neighbor Advertisement.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
|
* dev The suggested device driver structure to do the solicitation,
|
||||||
|
* can be NULL for auto decision, must set for link-local ipaddr.
|
||||||
* ipaddr The IPv6 address to be queried.
|
* ipaddr The IPv6 address to be queried.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -176,9 +178,9 @@ static uint16_t icmpv6_neighbor_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
|
int icmpv6_neighbor(FAR struct net_driver_s *dev,
|
||||||
|
const net_ipv6addr_t ipaddr)
|
||||||
{
|
{
|
||||||
FAR struct net_driver_s *dev;
|
|
||||||
struct icmpv6_notify_s notify;
|
struct icmpv6_notify_s notify;
|
||||||
struct icmpv6_neighbor_s state;
|
struct icmpv6_neighbor_s state;
|
||||||
net_ipv6addr_t lookup;
|
net_ipv6addr_t lookup;
|
||||||
@@ -202,7 +204,11 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
|
|||||||
|
|
||||||
/* Get the device that can route this request */
|
/* Get the device that can route this request */
|
||||||
|
|
||||||
dev = netdev_findby_ripv6addr(g_ipv6_unspecaddr, ipaddr);
|
if (!dev)
|
||||||
|
{
|
||||||
|
dev = netdev_findby_ripv6addr(g_ipv6_unspecaddr, ipaddr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Unreachable: %08lx\n", (unsigned long)ipaddr);
|
nerr("ERROR: Unreachable: %08lx\n", (unsigned long)ipaddr);
|
||||||
@@ -212,7 +218,8 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
|
|||||||
|
|
||||||
/* Check if the destination address is on the local network. */
|
/* Check if the destination address is on the local network. */
|
||||||
|
|
||||||
if (net_ipv6addr_maskcmp(ipaddr, dev->d_ipv6addr, dev->d_ipv6netmask))
|
if (net_ipv6addr_maskcmp(ipaddr, dev->d_ipv6addr, dev->d_ipv6netmask) ||
|
||||||
|
net_is_addr_linklocal(ipaddr))
|
||||||
{
|
{
|
||||||
/* Yes.. use the input address for the lookup */
|
/* Yes.. use the input address for the lookup */
|
||||||
|
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
|
|||||||
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(inaddr->sin6_addr.s6_addr16);
|
ret = icmpv6_neighbor(dev, inaddr->sin6_addr.s6_addr16);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Not reachable\n");
|
nerr("ERROR: Not reachable\n");
|
||||||
|
|||||||
@@ -774,7 +774,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
|
ret = icmpv6_neighbor(dev, conn->u.ipv6.raddr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Not reachable\n");
|
nerr("ERROR: Not reachable\n");
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
|
|||||||
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(to6->sin6_addr.in6_u.u6_addr16);
|
ret = icmpv6_neighbor(dev, to6->sin6_addr.in6_u.u6_addr16);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Not reachable\n");
|
nerr("ERROR: Not reachable\n");
|
||||||
|
|||||||
+1
-1
@@ -1494,7 +1494,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
|
|||||||
{
|
{
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
|
ret = icmpv6_neighbor(NULL, conn->u.ipv6.raddr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
||||||
|
|
||||||
|
|||||||
@@ -1299,7 +1299,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
{
|
{
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
|
ret = icmpv6_neighbor(NULL, conn->u.ipv6.raddr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
||||||
|
|
||||||
|
|||||||
@@ -525,7 +525,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
|
|||||||
{
|
{
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
|
ret = icmpv6_neighbor(NULL, conn->u.ipv6.raddr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
||||||
|
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
|
|||||||
{
|
{
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
|
ret = icmpv6_neighbor(NULL, conn->u.ipv6.raddr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
||||||
|
|
||||||
|
|||||||
@@ -651,7 +651,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
|
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(destipaddr);
|
ret = icmpv6_neighbor(NULL, destipaddr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
||||||
|
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
|
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = icmpv6_neighbor(destipaddr);
|
ret = icmpv6_neighbor(NULL, destipaddr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
#endif /* CONFIG_NET_ICMPv6_NEIGHBOR */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user