Skip to content
Snippets Groups Projects
Commit 4db21f4d authored by Gregory Nutt's avatar Gregory Nutt
Browse files

net/: IPv6 packet input, Improve checks that the packet is destined for us. ...

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.
parent 4eaa1368
No related branches found
No related tags found
No related merge requests found
......@@ -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++;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment