IPv6: More framework for automatic neighbor solicition. I think this also corrects and error in a broadcast/multicast address chedk

This commit is contained in:
Gregory Nutt 2015-02-02 11:34:51 -06:00
parent 3385082b99
commit b1b8c0e47d
8 changed files with 88 additions and 18 deletions

View file

@ -60,8 +60,6 @@ config ARP_SEND_DELAYMSEC
on the network since it is basically the time from when an ARP
request is sent until the response is received.
#endif
endif # NET_ARP_SEND
config NET_ARP_DUMP

View file

@ -87,7 +87,7 @@ int arp_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
/* Perform the ARP callbacks */
(void)devif_callback_execute(dev, &g_arp_conn, PKT_POLL, g_arp_conn.list);
(void)devif_callback_execute(dev, &g_arp_conn, ARP_POLL, g_arp_conn.list);
/* Call back into the driver */

View file

@ -238,7 +238,7 @@ int arp_send(in_addr_t ipaddr)
/* ARP support is only built if the Ethernet data link is supported.
* However, if we are supporting multiple network devices and using
* different link level protocols then we can get here for other
* link protocals as well. Continue and send the ARP request only
* link protocols as well. Continue and send the ARP request only
* if this device uses the Ethernet data link protocol.
*/
@ -332,7 +332,7 @@ int arp_send(in_addr_t ipaddr)
/* Arm/re-arm the callback */
state.snd_sent = false;
state.snd_cb->flags = PKT_POLL;
state.snd_cb->flags = ARP_POLL;
state.snd_cb->priv = (FAR void *)&state;
state.snd_cb->event = arp_send_interrupt;

View file

@ -79,11 +79,12 @@
* was last sent. (TCP only)
* OUT: Not used
*
* TCP_POLL IN: Used for polling the socket layer. This is provided
* UDP_POLL periodically from the drivers to support (1) timed
* PKT_POLL operations, and (2) to check if the socket layer has
* ICMP_POLL data that it wants to send
* ICMPv6_POLL OUT: Not used
* ARP_POLL IN: Used for polling the socket layer. This is provided
* TCP_POLL periodically from the drivers to support (1) timed
* UDP_POLL operations, and (2) to check if the socket layer has
* PKT_POLL data that it wants to send
* ICMP_POLL OUT: Not used
* ICMPv6_POLL
*
* TCP_BACKLOG IN: There is a new connection in the backlog list set
* up by the listen() command. (TCP only)
@ -128,11 +129,12 @@
#define ICMPv6_NEWDATA TCP_NEWDATA
#define TCP_SNDACK (1 << 2)
#define TCP_REXMIT (1 << 3)
#define TCP_POLL (1 << 4)
#define UDP_POLL TCP_POLL
#define PKT_POLL TCP_POLL
#define ICMP_POLL TCP_POLL
#define ICMPv6_POLL TCP_POLL
#define ARP_POLL (1 << 4)
#define TCP_POLL ARP_POLL
#define UDP_POLL ARP_POLL
#define PKT_POLL ARP_POLL
#define ICMP_POLL ARP_POLL
#define ICMPv6_POLL ARP_POLL
#define TCP_BACKLOG (1 << 5)
#define TCP_CLOSE (1 << 6)
#define TCP_ABORT (1 << 7)

View file

@ -32,6 +32,28 @@ config NET_ICMPv6_NEIGHBOR
the target IPv6 address mapping does not appear in the Neighbor
table.
if NET_ICMPv6_NEIGHBOR
config ICMPv6_NEIGHBOR_MAXTRIES
int "ICMPv6 solicitation retries"
default 5
---help---
Send the Neighbor solicitation this number of times before giving
up and deciding that the target IP6 address is non reachable.
config ICMPv6_NEIGHBOR_DELAYMSEC
int "ICMPv6 re-solicit delay"
default 20
---help---
Wait this number of milliseconds after sending the Neighbor
Solicitation before checking if the IPv6 address mapping is present
in the Neighbor Table. This time should be related to the maximum
round trip time on the network since it is basically the time from
when an Neighbor Solicitation is sent until the Neighbor
Advertisement is received.
endif # NET_ICMPv6_NEIGHBOR
endif # NET_ICMPv6
endmenu # ICMPv6 Networking Support
endif # NET_IPv6

View file

@ -56,6 +56,29 @@
* Public Type Definitions
****************************************************************************/
#ifdef CONFIG_NET_IPv6_NEIGHBOR
/* For symmetry with other protocols, a "connection" structure is
* provided. But it is a singleton for the case of ARP packet transfers.
*/
struct icmpv6_conn_s
{
FAR struct devif_callback_s *list; /* ARP callbacks */
};
#endif
#ifdef CONFIG_NET_IPv6_NEIGHBOR
/* Used to notify a thread waiting for a particular ARP response */
struct icmpv6_notify_s
{
FAR struct icmpv6_notify_s *nt_flink; /* Supports singly linked list */
in_addr_t nt_ipaddr; /* Waited for IP address in the mapping */
sem_t nt_sem; /* Will wake up the waiter */
int nt_result; /* The result of the wait */
};
#endif
/****************************************************************************
* Public Data
****************************************************************************/
@ -104,7 +127,7 @@ void icmpv6_input(FAR struct net_driver_s *dev);
* If the requested IPv6 address in not in the Neighbor Table, then this
* function will send the Neighbor Solicitation, delay, then check if the
* IP address is now in the Neighbor able. It will repeat this sequence
* until either (1) the IPv6 address mapping is now in the Neibhbor table,
* until either (1) the IPv6 address mapping is now in the Neighbor table,
* or (2) a configurable number of timeouts occur without receiving the
* ICMPv6 Neighbor Advertisement.
*

View file

@ -88,6 +88,8 @@
void icmpv6_poll(FAR struct net_driver_s *dev)
{
uint16_t flags;
/* Setup for the application callback */
dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev) + IPICMPv6_HDRLEN];
@ -96,7 +98,30 @@ void icmpv6_poll(FAR struct net_driver_s *dev)
/* Perform the application callback */
(void)devif_callback_execute(dev, NULL, ICMPv6_POLL, g_icmpv6_echocallback);
#ifdef CONFIG_NET_ICMPv6_PING
#ifdef CONFIG_NET_NET_ICMPv6_NEIGHBOR
flags = ICMPv6_POLL;
#endif
if (g_icmpv6_echocallback)
{
flags = devif_callback_execute(dev, NULL, ICMPv6_POLL,
g_icmpv6_echocallback);
}
#endif /* CONFIG_NET_ICMPv6_PING */
#ifdef CONFIG_NET_NET_ICMPv6_NEIGHBOR
if (
#ifdef CONFIG_NET_ICMPv6_PING
flags != 0 &&
#endif
g_icmpv6_neighborcallback)
{
flags = devif_callback_execute(dev, NULL, ICMPv6_POLL,
g_icmpv6_neighborcallback);
}
#endif /* CONFIG_NET_NET_ICMPv6_NEIGHBOR */
UNUSED(flags);
}
#endif /* CONFIG_NET_ICMPv6_PING || CONFIG_NET_NET_ICMPv6_NEIGHBOR */

View file

@ -165,7 +165,7 @@ void neighbor_out(FAR struct net_driver_s *dev)
* broadcast Ethernet address?
*/
if ((ip->destipaddr[0] & 0xff00) == 0xff00)
if ((ip->destipaddr[0] & HTONS(0xff00)) == HTONS(0xff00))
{
memcpy(eth->dest, g_broadcast_ethaddr.ether_addr_octet,
ETHER_ADDR_LEN);