tcp: find bound device when laddr is ANY

icmp: find bound device when s_boundto is not zero

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu 2022-11-10 14:44:17 +08:00 committed by Xiang Xiao
parent 6f33dd6ea0
commit ab15887a0b
6 changed files with 147 additions and 64 deletions

View File

@ -316,7 +316,17 @@ ssize_t icmp_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
/* Get the device that will be used to route this ICMP ECHO request */
dev = netdev_findby_ripv4addr(INADDR_ANY, inaddr->sin_addr.s_addr);
#ifdef CONFIG_NET_BINDTODEVICE
if (conn->sconn.s_boundto != 0)
{
dev = net_bound_device(&conn->sconn);
}
else
#endif
{
dev = netdev_findby_ripv4addr(INADDR_ANY, inaddr->sin_addr.s_addr);
}
if (dev == NULL)
{
nerr("ERROR: Not reachable\n");

View File

@ -34,6 +34,7 @@
#include "netdev/netdev.h"
#include "inet/inet.h"
#include "tcp/tcp.h"
#include "utils/utils.h"
/****************************************************************************
* Private Functions
@ -74,7 +75,13 @@ static int tcp_find_ipv4_device(FAR struct tcp_conn_s *conn,
if (net_ipv4addr_cmp(addr, INADDR_ANY))
{
return local ? OK : -EINVAL;
if (local)
{
conn->dev = net_bound_device(&conn->sconn);
return OK;
}
return -EINVAL;
}
/* We need to select the device that is going to route the TCP packet
@ -124,7 +131,13 @@ static int tcp_find_ipv6_device(FAR struct tcp_conn_s *conn,
if (net_ipv6addr_cmp(addr, g_ipv6_unspecaddr))
{
return local ? OK : -EINVAL;
if (local)
{
conn->dev = net_bound_device(&conn->sconn);
return OK;
}
return -EINVAL;
}
/* We need to select the device that is going to route the TCP packet

View File

@ -33,63 +33,7 @@
#include "netdev/netdev.h"
#include "inet/inet.h"
#include "udp/udp.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: upd_bound_device
*
* Description:
* If the UDP socket is bound to a device, return the reference to the
* bound device.
*
* Input Parameters:
* conn - UDP connection structure (not currently used).
*
* Returned Value:
* A reference to the bound device. If the retained interface index no
* longer refers to a valid device, this function will unbind the device
* and return an arbitrary network device at the head of the list of
* registered devices. This supports legacy IPv4 DHCPD behavior when
* there is only a single registered network device.
*
****************************************************************************/
#ifdef CONFIG_NET_BINDTODEVICE
static FAR struct net_driver_s *upd_bound_device(FAR struct udp_conn_s *conn)
{
FAR struct net_driver_s *dev = NULL;
/* Is the UDP socket bound to a device? */
if (conn->sconn.s_boundto != 0)
{
/* Yes..This socket has been bound to an interface. Convert the
* interface index into a device structure reference.
*/
dev = netdev_findbyindex(conn->sconn.s_boundto);
if (dev == NULL)
{
/* No device? It must have been unregistered. Un-bind the UDP
* socket.
*/
conn->sconn.s_boundto = 0;
}
}
/* If no device was bound or the bound device is no longer valid,
* then let's try the default network device.
*/
return dev == NULL ? netdev_default() : dev;
}
#else
# define upd_bound_device(c) netdev_default();
#endif
#include "utils/utils.h"
/****************************************************************************
* Public Functions
@ -226,7 +170,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn,
{
/* Return the device bound to this UDP socket, if any */
return upd_bound_device(conn);
return net_bound_device(&conn->sconn);
}
else
{
@ -252,7 +196,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn,
* Return the device bound to this UDP socket, if any.
*/
return upd_bound_device(conn);
return net_bound_device(&conn->sconn);
}
}
#endif
@ -292,7 +236,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn,
{
/* Return the device bound to this UDP socket, if any */
return upd_bound_device(conn);
return net_bound_device(&conn->sconn);
}
else
{
@ -318,7 +262,7 @@ udp_find_raddr_device(FAR struct udp_conn_s *conn,
* Return the device bound to this UDP socket, if any.
*/
return upd_bound_device(conn);
return net_bound_device(&conn->sconn);
}
}
#endif

View File

@ -49,6 +49,12 @@ else ifeq ($(CONFIG_NET_ICMPv6),y)
NET_CSRCS += net_icmpchksum.c
endif
# Bound device find
ifeq ($(CONFIG_NET_BINDTODEVICE),y)
NET_CSRCS += net_bounddev.c
endif
# Include utility build support
DEPPATH += --dep-path utils

85
net/utils/net_bounddev.c Normal file
View File

@ -0,0 +1,85 @@
/****************************************************************************
* net/utils/net_bounddev.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/net/netdev.h>
#include <nuttx/net/net.h>
#include "netdev/netdev.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: net_bound_device
*
* Description:
* If the socket is bound to a device, return the reference to the
* bound device.
*
* Input Parameters:
* sconn - Socket connection structure (not currently used).
*
* Returned Value:
* A reference to the bound device. If the retained interface index no
* longer refers to a valid device, this function will unbind the device
* and return an arbitrary network device at the head of the list of
* registered devices. This supports legacy IPv4 DHCPD behavior when
* there is only a single registered network device.
*
****************************************************************************/
#ifdef CONFIG_NET_BINDTODEVICE
FAR struct net_driver_s *net_bound_device(FAR struct socket_conn_s *sconn)
{
FAR struct net_driver_s *dev = NULL;
/* Is the socket bound to a device? */
if (sconn->s_boundto != 0)
{
/* Yes..This socket has been bound to an interface. Convert the
* interface index into a device structure reference.
*/
dev = netdev_findbyindex(sconn->s_boundto);
if (dev == NULL)
{
/* No device? It must have been unregistered. Un-bind the
* socket.
*/
sconn->s_boundto = 0;
}
}
/* If no device was bound or the bound device is no longer valid,
* then let's try the default network device.
*/
return dev == NULL ? netdev_default() : dev;
}
#endif

View File

@ -389,6 +389,31 @@ uint16_t icmp_chksum(FAR struct net_driver_s *dev, int len);
uint16_t icmpv6_chksum(FAR struct net_driver_s *dev, unsigned int iplen);
#endif
/****************************************************************************
* Name: net_bound_device
*
* Description:
* If the socket is bound to a device, return the reference to the
* bound device.
*
* Input Parameters:
* sconn - Socket connection structure (not currently used).
*
* Returned Value:
* A reference to the bound device. If the retained interface index no
* longer refers to a valid device, this function will unbind the device
* and return an arbitrary network device at the head of the list of
* registered devices. This supports legacy IPv4 DHCPD behavior when
* there is only a single registered network device.
*
****************************************************************************/
#ifdef CONFIG_NET_BINDTODEVICE
FAR struct net_driver_s *net_bound_device(FAR struct socket_conn_s *sconn);
#else
# define net_bound_device(c) netdev_default();
#endif
#undef EXTERN
#ifdef __cplusplus
}