ICMPv6: This completes coding of the ICMPv6 auto-configuration feature. It is not yet functional
This commit is contained in:
parent
2c14d4ef93
commit
9791e829f5
@ -93,10 +93,6 @@ struct icmpv6_rnotify_s
|
||||
{
|
||||
#ifdef CONFIG_NET_MULTILINK
|
||||
FAR struct icmpv6_notify_s *rn_flink; /* Supports singly linked list */
|
||||
#endif
|
||||
net_ipv6addr_t rn_prefix; /* Waited for router prefix */
|
||||
uint8_t rn_preflen; /* Prefix length (# valid leading bits) */
|
||||
#ifdef CONFIG_NET_MULTILINK
|
||||
char rn_ifname[IFNAMSIZ]; /* Device name */
|
||||
#endif
|
||||
sem_t rn_sem; /* Will wake up the waiter */
|
||||
@ -431,6 +427,9 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify,
|
||||
* wake-up any threads that may be waiting for this particular Router
|
||||
* Advertisement.
|
||||
*
|
||||
* NOTE: On success the network has the new address applied and is in
|
||||
* the down state.
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called from the MAC device driver indirectly through
|
||||
* icmpv6_icmpv6in() will execute with the network locked.
|
||||
@ -438,8 +437,8 @@ int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_AUTOCONF
|
||||
void icmpv6_rnotify(FAR struct net_driver_s *dev, const net_ipv6addr_t prefix,
|
||||
unsigned int preflen);
|
||||
void icmpv6_rnotify(FAR struct net_driver_s *dev, const net_ipv6addr_t draddr,
|
||||
const net_ipv6addr_t prefix, unsigned int preflen);
|
||||
#else
|
||||
# define icmpv6_rnotify(d,p,l)
|
||||
#endif
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#include "devif/devif.h"
|
||||
#include "netdev/netdev.h"
|
||||
#include "icmpv6/icmpv6.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -327,7 +328,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
ndbg("ERROR: Only Ethernet is supported\n");
|
||||
return -ENOSYS;
|
||||
|
||||
#else
|
||||
#else /* CONFIG_NET_ETHERNET */
|
||||
struct icmpv6_rnotify_s notify;
|
||||
net_ipv6addr_t lladdr;
|
||||
net_lock_t save;
|
||||
@ -348,6 +349,11 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
/* The interface should be in the down state */
|
||||
|
||||
save = net_lock();
|
||||
netdev_ifdown(dev);
|
||||
net_unlock(save);
|
||||
|
||||
/* IPv6 Stateless Autoconfiguration
|
||||
* Reference: http://www.tcpipguide.com/free/t_IPv6AutoconfiguratinoandRenumbering.htm
|
||||
@ -378,6 +384,10 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
memset(&lladdr[1], 0, 4* sizeof(uint16_t)); /* 64 more zeroes */
|
||||
memcpy(&lladdr[5], dev->d_mac.ether_addr_octet, sizeof(struct ether_addr)); /* 48-bit Ethernet address */
|
||||
|
||||
nvdbg("lladdr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||
lladdr[0], lladdr[1], lladdr[2], lladdr[3],
|
||||
lladdr[4], lladdr[6], lladdr[6], lladdr[7]);
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
||||
/* 2. Link-Local Address Uniqueness Test: The node tests to ensure that
|
||||
* the address it generated isn't for some reason already in use on the
|
||||
@ -410,6 +420,11 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
|
||||
net_ipv6addr_copy(dev->d_ipv6addr, lladdr);
|
||||
|
||||
/* Bring the interface up with the new, temporary IP address */
|
||||
|
||||
save = net_lock();
|
||||
netdev_ifup(dev);
|
||||
|
||||
/* 4. Router Contact: The node next attempts to contact a local router for
|
||||
* more information on continuing the configuration. This is done either
|
||||
* by listening for Router Advertisement messages sent periodically by
|
||||
@ -417,7 +432,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
* for information on what to do next.
|
||||
*/
|
||||
|
||||
save = net_lock();
|
||||
for (retries = 0; retries < CONFIG_ICMPv6_AUTOCONF_MAXTRIES; retries++)
|
||||
{
|
||||
/* Set up the Router Advertisement BEFORE we send the Router
|
||||
@ -447,17 +461,22 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
break;
|
||||
}
|
||||
|
||||
nvdbg("Timed out... retrying\n");
|
||||
nvdbg("Timed out... retrying %d\n", retries + 1);
|
||||
}
|
||||
|
||||
net_unlock(save);
|
||||
|
||||
/* Check for failures */
|
||||
/* Check for failures. Note: On successful return, the network will be
|
||||
* in the down state, but not in the event of failures.
|
||||
*/
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
ndbg("ERROR: Failed to get the router advertisement: %d (retries=%d)\n",
|
||||
ret, retries);
|
||||
|
||||
/* Take the network down and return the failure */
|
||||
|
||||
netdev_ifdown(dev);
|
||||
net_unlock(save);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -466,20 +485,23 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
* network "stateful" auto-configuration is in use, and tell it the
|
||||
* address of a DHCP server to use. Alternately, it will tell the host
|
||||
* how to determine its global Internet address.
|
||||
*/
|
||||
#warning Missing logic
|
||||
|
||||
/* 6. Global Address Configuration: Assuming that stateless auto-
|
||||
*
|
||||
* 6. Global Address Configuration: Assuming that stateless auto-
|
||||
* configuration is in use on the network, the host will configure
|
||||
* itself with its globally-unique Internet address. This address is
|
||||
* generally formed from a network prefix provided to the host by the
|
||||
* router, combined with the device's identifier as generated in the
|
||||
* first step.
|
||||
*/
|
||||
#warning Missing logic
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
/* On success, the new address was already set (in icmpv_rnotify()). We
|
||||
* need only to bring the network back to the up state and return success.
|
||||
*/
|
||||
|
||||
netdev_ifup(dev);
|
||||
net_unlock(save);
|
||||
return OK;
|
||||
#endif /* CONFIG_NET_ETHERNET */
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_ICMPv6_AUTOCONF */
|
||||
|
@ -321,7 +321,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
|
||||
{
|
||||
/* Yes.. Notify any waiting threads */
|
||||
|
||||
icmpv6_rnotify(dev, opt->prefix, opt->preflen);
|
||||
icmpv6_rnotify(dev, icmp->srcipaddr, opt->prefix, opt->preflen);
|
||||
goto icmpv_send_nothing;
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,11 @@ void netdev_semtake(void);
|
||||
void netdev_semgive(void);
|
||||
#endif
|
||||
|
||||
/* netdev_ioctl.c ************************************************************/
|
||||
|
||||
void netdev_ifup(FAR struct net_driver_s *dev);
|
||||
void netdev_ifdown(FAR struct net_driver_s *dev);
|
||||
|
||||
/* netdev_findbyname.c *******************************************************/
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* net/netdev/netdev_ioctl.c
|
||||
*
|
||||
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2012, 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -315,58 +315,6 @@ static void ioctl_setipv6addr(FAR net_ipv6addr_t outaddr,
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ioctl_ifup / ioctl_ifdown
|
||||
*
|
||||
* Description:
|
||||
* Bring the interface up/down
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ioctl_ifup(FAR struct net_driver_s *dev)
|
||||
{
|
||||
/* Make sure that the device supports the d_ifup() method */
|
||||
|
||||
if (dev->d_ifup)
|
||||
{
|
||||
/* Is the interface already up? */
|
||||
|
||||
if ((dev->d_flags & IFF_UP) == 0)
|
||||
{
|
||||
/* No, bring the interface up now */
|
||||
|
||||
if (dev->d_ifup(dev) == OK)
|
||||
{
|
||||
/* Mark the interface as up */
|
||||
|
||||
dev->d_flags |= IFF_UP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ioctl_ifdown(FAR struct net_driver_s *dev)
|
||||
{
|
||||
/* Make sure that the device supports the d_ifdown() method */
|
||||
|
||||
if (dev->d_ifdown)
|
||||
{
|
||||
/* Is the interface already down? */
|
||||
|
||||
if ((dev->d_flags & IFF_UP) != 0)
|
||||
{
|
||||
/* No, take the interface down now */
|
||||
|
||||
if (dev->d_ifdown(dev) == OK)
|
||||
{
|
||||
/* Mark the interface as down */
|
||||
|
||||
dev->d_flags &= ~IFF_UP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_ifrdev
|
||||
*
|
||||
@ -445,9 +393,9 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
|
||||
dev = netdev_ifrdev(req);
|
||||
if (dev)
|
||||
{
|
||||
ioctl_ifdown(dev);
|
||||
netdev_ifdown(dev);
|
||||
ioctl_setipv4addr(&dev->d_ipaddr, &req->ifr_addr);
|
||||
ioctl_ifup(dev);
|
||||
netdev_ifup(dev);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
@ -538,9 +486,9 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
|
||||
{
|
||||
FAR struct lifreq *lreq = (FAR struct lifreq *)req;
|
||||
|
||||
ioctl_ifdown(dev);
|
||||
netdev_ifdown(dev);
|
||||
ioctl_setipv6addr(dev->d_ipv6addr, &lreq->lifr_addr);
|
||||
ioctl_ifup(dev);
|
||||
netdev_ifup(dev);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
@ -650,7 +598,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
|
||||
{
|
||||
/* Yes.. bring the interface up */
|
||||
|
||||
ioctl_ifup(dev);
|
||||
netdev_ifup(dev);
|
||||
}
|
||||
|
||||
/* Is this a request to take the interface down? */
|
||||
@ -659,7 +607,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
|
||||
{
|
||||
/* Yes.. take the interface down */
|
||||
|
||||
ioctl_ifdown(dev);
|
||||
netdev_ifdown(dev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -713,7 +661,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd,
|
||||
dev = netdev_ifrdev(req);
|
||||
if (dev)
|
||||
{
|
||||
ioctl_ifdown(dev);
|
||||
netdev_ifdown(dev);
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
dev->d_ipaddr = 0;
|
||||
#endif
|
||||
@ -1051,4 +999,56 @@ errout:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_ifup / netdev_ifdown
|
||||
*
|
||||
* Description:
|
||||
* Bring the interface up/down
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netdev_ifup(FAR struct net_driver_s *dev)
|
||||
{
|
||||
/* Make sure that the device supports the d_ifup() method */
|
||||
|
||||
if (dev->d_ifup)
|
||||
{
|
||||
/* Is the interface already up? */
|
||||
|
||||
if ((dev->d_flags & IFF_UP) == 0)
|
||||
{
|
||||
/* No, bring the interface up now */
|
||||
|
||||
if (dev->d_ifup(dev) == OK)
|
||||
{
|
||||
/* Mark the interface as up */
|
||||
|
||||
dev->d_flags |= IFF_UP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void netdev_ifdown(FAR struct net_driver_s *dev)
|
||||
{
|
||||
/* Make sure that the device supports the d_ifdown() method */
|
||||
|
||||
if (dev->d_ifdown)
|
||||
{
|
||||
/* Is the interface already down? */
|
||||
|
||||
if ((dev->d_flags & IFF_UP) != 0)
|
||||
{
|
||||
/* No, take the interface down now */
|
||||
|
||||
if (dev->d_ifdown(dev) == OK)
|
||||
{
|
||||
/* Mark the interface as down */
|
||||
|
||||
dev->d_flags &= ~IFF_UP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */
|
||||
|
Loading…
Reference in New Issue
Block a user