mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
net/: IPv6 packet input, Improve checks that the packet is destined for us. There might be some odd things that can happen in certain forwarding scenarios.
This commit is contained in:
parent
4eaa136850
commit
4db21f4d7e
1 changed files with 110 additions and 10 deletions
|
@ -99,6 +99,7 @@
|
|||
#include "pkt/pkt.h"
|
||||
#include "icmpv6/icmpv6.h"
|
||||
|
||||
#include "netdev/netdev.h"
|
||||
#include "devif/devif.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -109,6 +110,106 @@
|
|||
|
||||
#define IPv6BUF ((FAR struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: check_dev_destipaddr
|
||||
*
|
||||
* Description:
|
||||
* Check if the destination address in the IPv6 is destined for the
|
||||
* provided network device.
|
||||
*
|
||||
* Returned Value:
|
||||
* 1 - This packet is destined for this network device
|
||||
* 0 - This packet is NOT destined for this network device
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
static int check_dev_destipaddr(FAR struct net_driver_s *dev, FAR void *arg);
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)arg;
|
||||
|
||||
/* Check if the IPv6 destination address matches the IPv6 address assigned
|
||||
* to this device.
|
||||
*/
|
||||
|
||||
if (net_ipv6addr_cmp(ipv6->destipaddr, dev->d_ipv6addr))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* No match, return 0 to keep searching */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: check_destipaddr
|
||||
*
|
||||
* Description:
|
||||
* Check if the destination address in the IPv6 is destined for us. This
|
||||
* is typically just a comparison the of the IPv6 destination address in
|
||||
* the IPv6 packet with the IPv6 address assigned to the receiving device.
|
||||
*
|
||||
* Returned Value:
|
||||
* true - This packet is destined for us
|
||||
* false - This packet is NOT destined for us and may need to be forwarded.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool check_destipaddr(FAR struct net_driver_s *dev,
|
||||
FAR struct ipv6_hdr_s *ipv6)
|
||||
{
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
/* For IPv6, packet reception is a little trickier as we need to make sure
|
||||
* that we listen to certain multicast addresses (all hosts multicast
|
||||
* address, and the solicited-node multicast address) as well. However,
|
||||
* we will cheat here and accept all multicast packets that are sent to
|
||||
* the ff02::/16 addresses.
|
||||
*/
|
||||
|
||||
if (ipv6->destipaddr[0] == HTONS(0xff02))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
/* We will also allow for a perverse case where we receive a packet
|
||||
* addressed to us, but on a different device. Can that really happen?
|
||||
*/
|
||||
|
||||
ret = netdev_foreach(check_dev_destipaddr, ipv6);
|
||||
if (ret == 1)
|
||||
{
|
||||
/* The traversal of the network devices will return 0 if there is
|
||||
* no network device with that address or 1 if there is a network
|
||||
* device with such an address.
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
/* There is only one network device. If this packet is addressed to us,
|
||||
* then the IPv6 destination address must be the address of assigned to
|
||||
* this device.
|
||||
*/
|
||||
|
||||
if (net_ipv6addr_cmp(ipv6->destipaddr, dev->d_ipv6addr))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -117,6 +218,8 @@
|
|||
* Name: ipv6_input
|
||||
*
|
||||
* Description:
|
||||
* Receive an IPv6 packet from the network device. Verify and forward to
|
||||
* L3 packet handling logic if the packet is destined for us.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK The packet was processed (or dropped) and can be discarded.
|
||||
|
@ -124,6 +227,10 @@
|
|||
* yet. Currently useful for UDP when a packet arrives before a recv
|
||||
* call is in place.
|
||||
*
|
||||
* If this function returns to the network driver with dev->d_len > 0,
|
||||
* that is an indication to the driver that there is an outgoing response
|
||||
* to this input.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
@ -222,20 +329,13 @@ int ipv6_input(FAR struct net_driver_s *dev)
|
|||
}
|
||||
|
||||
/* Check if the packet is destined for out IP address */
|
||||
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Check if the packet is destined for our IP address.
|
||||
*
|
||||
* For IPv6, packet reception is a little trickier as we need to
|
||||
* make sure that we listen to certain multicast addresses (all
|
||||
* hosts multicast address, and the solicited-node multicast
|
||||
* address) as well. However, we will cheat here and accept all
|
||||
* multicast packets that are sent to the ff02::/16 addresses.
|
||||
*/
|
||||
/* Check if the packet is destined for us. */
|
||||
|
||||
if (!net_ipv6addr_cmp(ipv6->destipaddr, dev->d_ipv6addr) &&
|
||||
ipv6->destipaddr[0] != HTONS(0xff02))
|
||||
if (check_destipaddr(dev, ipv6))
|
||||
{
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.ipv6.drop++;
|
||||
|
|
Loading…
Reference in a new issue