mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +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:
+110
-10
@@ -99,6 +99,7 @@
|
|||||||
#include "pkt/pkt.h"
|
#include "pkt/pkt.h"
|
||||||
#include "icmpv6/icmpv6.h"
|
#include "icmpv6/icmpv6.h"
|
||||||
|
|
||||||
|
#include "netdev/netdev.h"
|
||||||
#include "devif/devif.h"
|
#include "devif/devif.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -109,6 +110,106 @@
|
|||||||
|
|
||||||
#define IPv6BUF ((FAR struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -117,6 +218,8 @@
|
|||||||
* Name: ipv6_input
|
* Name: ipv6_input
|
||||||
*
|
*
|
||||||
* Description:
|
* 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:
|
* Returned Value:
|
||||||
* OK The packet was processed (or dropped) and can be discarded.
|
* 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
|
* yet. Currently useful for UDP when a packet arrives before a recv
|
||||||
* call is in place.
|
* 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:
|
* Assumptions:
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -222,20 +329,13 @@ int ipv6_input(FAR struct net_driver_s *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the packet is destined for out IP address */
|
/* Check if the packet is destined for out IP address */
|
||||||
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* Check if the packet is destined for our IP address.
|
/* Check if the packet is destined for us. */
|
||||||
*
|
|
||||||
* 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 (!net_ipv6addr_cmp(ipv6->destipaddr, dev->d_ipv6addr) &&
|
if (check_destipaddr(dev, ipv6))
|
||||||
ipv6->destipaddr[0] != HTONS(0xff02))
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_STATISTICS
|
#ifdef CONFIG_NET_STATISTICS
|
||||||
g_netstats.ipv6.drop++;
|
g_netstats.ipv6.drop++;
|
||||||
|
|||||||
Reference in New Issue
Block a user