diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-02-04 16:13:27 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-02-04 16:13:27 -0600 |
commit | 03f2ef027f45ab95d4d953539834a5d9ae2aa4cf (patch) | |
tree | 524d0156b517ff6582fa07f12292a31ca3d6876f /nuttx/net | |
parent | 74e258a6b586a08d8dd1ed2fa6e0ac91f68fff8d (diff) | |
download | nuttx-03f2ef027f45ab95d4d953539834a5d9ae2aa4cf.tar.gz nuttx-03f2ef027f45ab95d4d953539834a5d9ae2aa4cf.tar.bz2 nuttx-03f2ef027f45ab95d4d953539834a5d9ae2aa4cf.zip |
ICMPv6 Auto-configuration: If no router reponds to the Router Solicitation, claim the link local address by sending the Neighbor Advertisement and return success
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/icmpv6/icmpv6.h | 6 | ||||
-rw-r--r-- | nuttx/net/icmpv6/icmpv6_advertise.c | 7 | ||||
-rw-r--r-- | nuttx/net/icmpv6/icmpv6_autoconfig.c | 52 | ||||
-rw-r--r-- | nuttx/net/icmpv6/icmpv6_input.c | 9 |
4 files changed, 48 insertions, 26 deletions
diff --git a/nuttx/net/icmpv6/icmpv6.h b/nuttx/net/icmpv6/icmpv6.h index 554aa5aa0..53d345fe9 100644 --- a/nuttx/net/icmpv6/icmpv6.h +++ b/nuttx/net/icmpv6/icmpv6.h @@ -263,15 +263,15 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev); * buffer * * Return: - * Zero (OK) on success; A negated errno value on return. + * None. * * Assumptions: * The network is locked * ****************************************************************************/ -int icmpv6_advertise(FAR struct net_driver_s *dev, - const net_ipv6addr_t destipaddr); +void icmpv6_advertise(FAR struct net_driver_s *dev, + const net_ipv6addr_t destipaddr); /**************************************************************************** * Function: icmpv6_wait_setup diff --git a/nuttx/net/icmpv6/icmpv6_advertise.c b/nuttx/net/icmpv6/icmpv6_advertise.c index 62edf78f3..fea000ae3 100644 --- a/nuttx/net/icmpv6/icmpv6_advertise.c +++ b/nuttx/net/icmpv6/icmpv6_advertise.c @@ -83,15 +83,15 @@ * buffer * * Return: - * Zero (OK) on success; A negated errno value on return. + * None * * Assumptions: * The network is locked * ****************************************************************************/ -int icmpv6_advertise(FAR struct net_driver_s *dev, - const net_ipv6addr_t destipaddr) +void icmpv6_advertise(FAR struct net_driver_s *dev, + const net_ipv6addr_t destipaddr) { FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF; FAR struct icmpv6_neighbor_advertise_s *adv; @@ -186,7 +186,6 @@ int icmpv6_advertise(FAR struct net_driver_s *dev, g_netstats.icmpv6.sent++; g_netstats.ipv6.sent++; #endif - return OK; } #endif /* CONFIG_NET_ICMPv6 */ diff --git a/nuttx/net/icmpv6/icmpv6_autoconfig.c b/nuttx/net/icmpv6/icmpv6_autoconfig.c index 2c0a9a9c9..e688cbecb 100644 --- a/nuttx/net/icmpv6/icmpv6_autoconfig.c +++ b/nuttx/net/icmpv6/icmpv6_autoconfig.c @@ -78,6 +78,7 @@ struct icmpv6_router_s FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */ sem_t snd_sem; /* Used to wake up the waiting thread */ volatile bool snd_sent; /* True: if request sent */ + bool snd_advertise; /* True: Send Neighbor Advertisement */ #ifdef CONFIG_NETDEV_MULTINIC uint8_t snd_ifname[IFNAMSIZ]; /* Interface name */ #endif @@ -135,7 +136,18 @@ static uint16_t icmpv6_router_interrupt(FAR struct net_driver_s *dev, /* It looks like we are good to send the data */ /* Copy the packet data into the device packet buffer and send it */ - icmpv6_rsolicit(dev); + if (state->snd_advertise) + { + /* Send the ICMPv6 Neighbor Advertisement message */ + + icmpv6_advertise(dev, g_ipv6_allnodes); + } + else + { + /* Send the ICMPv6 Router Solicitation message */ + + icmpv6_rsolicit(dev); + } /* Make sure no additional Router Solicitation overwrites this one. * This flag will be cleared in icmpv6_out(). @@ -159,13 +171,14 @@ static uint16_t icmpv6_router_interrupt(FAR struct net_driver_s *dev, } /**************************************************************************** - * Name: icmpv6_send_rsolicit + * Name: icmpv6_send_message * * Description: * Send an ICMPv6 Router Solicitation to resolve an IPv6 address. * * Parameters: - * dev - The device to use to send the solicitation + * dev - The device to use to send the solicitation + * advertise - True: Send the Neighbor Advertisement message * * Returned Value: * Zero (OK) is returned on success; On error a negated errno value is @@ -176,7 +189,7 @@ static uint16_t icmpv6_router_interrupt(FAR struct net_driver_s *dev, * ****************************************************************************/ -int icmpv6_send_rsolicit(FAR struct net_driver_s *dev) +static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise) { struct icmpv6_router_s state; int ret; @@ -210,6 +223,7 @@ int icmpv6_send_rsolicit(FAR struct net_driver_s *dev) /* Arm the callback */ state.snd_sent = false; + state.snd_advertise = advertise; state.snd_cb->flags = ICMPv6_POLL; state.snd_cb->priv = (FAR void *)&state; state.snd_cb->event = icmpv6_router_interrupt; @@ -242,7 +256,7 @@ errout_with_semaphore: * Name: icmpv6_wait_radvertise * * Description: - * Wait for the receipt of the Router Advertisment matching the Router + * Wait for the receipt of the Router Advertisement matching the Router * Solicitation that we just sent. * * Parameters: @@ -259,9 +273,9 @@ errout_with_semaphore: * ****************************************************************************/ -int icmpv6_wait_radvertise(FAR struct net_driver_s *dev, - FAR struct icmpv6_rnotify_s *notify, - net_lock_t *save) +static int icmpv6_wait_radvertise(FAR struct net_driver_s *dev, + FAR struct icmpv6_rnotify_s *notify, + net_lock_t *save) { struct timespec delay; #ifdef CONFIG_NET_NOINTS @@ -459,7 +473,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) /* Send the ICMPv6 Router solicitation message */ - ret = icmpv6_send_rsolicit(dev); + ret = icmpv6_send_message(dev, false); if (ret < 0) { ndbg("ERROR: Failed send router solicitation: %d\n", ret); @@ -490,11 +504,25 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) ndbg("ERROR: Failed to get the router advertisement: %d (retries=%d)\n", ret, retries); - /* Take the network down and return the failure */ + /* Claim the link local address as ours by sending the ICMPv6 Neighbor + * Advertisement message. + */ + + ret = icmpv6_send_message(dev, true); + if (ret < 0) + { + ndbg("ERROR: Failed send neighbor advertisement: %d\n", ret); + netdev_ifdown(dev); + net_unlock(save); + return ret; + } + + /* Leave the network up and return success (even though things did not + * work out quite the way we wanted. + */ - netdev_ifdown(dev); net_unlock(save); - return ret; + return OK; } /* 5. Router Direction: The router provides direction to the node on how to diff --git a/nuttx/net/icmpv6/icmpv6_input.c b/nuttx/net/icmpv6/icmpv6_input.c index 5842e128e..3ed539ce7 100644 --- a/nuttx/net/icmpv6/icmpv6_input.c +++ b/nuttx/net/icmpv6/icmpv6_input.c @@ -109,7 +109,6 @@ struct icmpv6_conn_s g_icmpv6_conn; void icmpv6_input(FAR struct net_driver_s *dev) { FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF; - int ret; #ifdef CONFIG_NET_STATISTICS g_netstats.icmpv6.recv++; @@ -136,13 +135,9 @@ void icmpv6_input(FAR struct net_driver_s *dev) * solicitation came from. */ - ret = icmpv6_advertise(dev, icmp->srcipaddr); - if (ret < 0) - { - goto icmpv6_drop_packet; - } + icmpv6_advertise(dev, icmp->srcipaddr); - /* All statistics have been updated */ + /* All statistics have been updated. Nothing to do but exit. */ return; } |