Don't use an AutoIP-configured address on a new network until the address has been configured.

When connecting to a new network with an AutoIP address, take the
interface down until the old address has passed the
AUTOIP_STATE_PROBING state.
This commit is contained in:
stoklund 2009-08-24 13:11:35 +00:00
parent e7d5739ce7
commit d83fc6893b
3 changed files with 76 additions and 18 deletions

View File

@ -110,12 +110,18 @@ static void autoip_handle_arp_conflict(struct netif *netif);
/* creates a pseudo random LL IP-Address for a network interface */ /* creates a pseudo random LL IP-Address for a network interface */
static void autoip_create_addr(struct netif *netif, struct ip_addr *IPAddr); static void autoip_create_addr(struct netif *netif, struct ip_addr *IPAddr);
/* sends an ARP probe */
static err_t autoip_arp_probe(struct netif *netif);
/* sends an ARP announce */ /* sends an ARP announce */
static err_t autoip_arp_announce(struct netif *netif); static err_t autoip_arp_announce(struct netif *netif);
/* configure interface for use with current LL IP-Address */ /* configure interface for use with current LL IP-Address */
static err_t autoip_bind(struct netif *netif); static err_t autoip_bind(struct netif *netif);
/* start sending probes for llipaddr */
static void autoip_start_probing(struct netif *netif);
/** /**
* Initialize this module * Initialize this module
*/ */
@ -191,6 +197,19 @@ autoip_create_addr(struct netif *netif, struct ip_addr *IPAddr)
(u16_t)(netif->autoip->tried_llipaddr), (u32_t)(IPAddr->addr))); (u16_t)(netif->autoip->tried_llipaddr), (u32_t)(IPAddr->addr)));
} }
/**
* Sends an ARP probe from a network interface
*
* @param netif network interface used to send the probe
*/
static err_t
autoip_arp_probe(struct netif *netif)
{
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
(struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, &ethzero,
&netif->autoip->llipaddr, ARP_REQUEST);
}
/** /**
* Sends an ARP announce from a network interface * Sends an ARP announce from a network interface
* *
@ -281,6 +300,16 @@ autoip_start(struct netif *netif)
autoip_create_addr(netif, &(autoip->llipaddr)); autoip_create_addr(netif, &(autoip->llipaddr));
autoip->tried_llipaddr++; autoip->tried_llipaddr++;
autoip_start_probing(netif);
return result;
}
static void
autoip_start_probing(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
autoip->state = AUTOIP_STATE_PROBING; autoip->state = AUTOIP_STATE_PROBING;
autoip->sent_num = 0; autoip->sent_num = 0;
@ -295,12 +324,24 @@ autoip_start(struct netif *netif)
* accquiring and probing address * accquiring and probing address
* compliant to RFC 3927 Section 2.2.1 * compliant to RFC 3927 Section 2.2.1
*/ */
if(autoip->tried_llipaddr > MAX_CONFLICTS) { if(autoip->tried_llipaddr > MAX_CONFLICTS) {
autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
} }
}
return result; /**
* Handle a possible change in the network configuration.
*
* If there is an AutoIP address configured, take the interface down
* and begin probing with the same address.
*/
void
autoip_network_changed(struct netif *netif)
{
if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
netif_set_down(netif);
autoip_start_probing(netif);
}
} }
/** /**
@ -340,12 +381,12 @@ autoip_tmr()
if(netif->autoip->ttw > 0) { if(netif->autoip->ttw > 0) {
netif->autoip->ttw--; netif->autoip->ttw--;
} else { } else {
if(netif->autoip->sent_num == PROBE_NUM) { if(netif->autoip->sent_num >= PROBE_NUM) {
netif->autoip->state = AUTOIP_STATE_ANNOUNCING; netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
netif->autoip->sent_num = 0; netif->autoip->sent_num = 0;
netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
} else { } else {
etharp_request(netif, &(netif->autoip->llipaddr)); autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
("autoip_tmr() PROBING Sent Probe\n")); ("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++; netif->autoip->sent_num++;
@ -363,21 +404,24 @@ autoip_tmr()
} else { } else {
if(netif->autoip->sent_num == 0) { if(netif->autoip->sent_num == 0) {
/* We are here the first time, so we waited ANNOUNCE_WAIT seconds /* We are here the first time, so we waited ANNOUNCE_WAIT seconds
* Now we can bind to an IP address and use it * Now we can bind to an IP address and use it.
*
* autoip_bind calls netif_set_up. This triggers a gratuitous ARP
* which counts as an announcement.
*/ */
autoip_bind(netif); autoip_bind(netif);
}
if(netif->autoip->sent_num == ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
} else { } else {
autoip_arp_announce(netif); autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
("autoip_tmr() ANNOUNCING Sent Announce\n")); ("autoip_tmr() ANNOUNCING Sent Announce\n"));
netif->autoip->sent_num++; }
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
netif->autoip->sent_num++;
if(netif->autoip->sent_num >= ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
} }
} }
break; break;

View File

@ -52,6 +52,10 @@
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
#endif /* ENABLE_LOOPBACK */ #endif /* ENABLE_LOOPBACK */
#if LWIP_AUTOIP
#include "lwip/autoip.h"
#endif /* LWIP_AUTOIP */
#if LWIP_NETIF_STATUS_CALLBACK #if LWIP_NETIF_STATUS_CALLBACK
#define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); } #define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); }
#else #else
@ -459,6 +463,13 @@ void netif_set_link_up(struct netif *netif )
{ {
netif->flags |= NETIF_FLAG_LINK_UP; netif->flags |= NETIF_FLAG_LINK_UP;
#if LWIP_AUTOIP
if (netif->autoip) {
autoip_network_changed(netif);
}
#endif /* LWIP_AUTOIP */
if (netif->flags & NETIF_FLAG_UP) {
#if LWIP_ARP #if LWIP_ARP
/* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
if (netif->flags & NETIF_FLAG_ETHARP) { if (netif->flags & NETIF_FLAG_ETHARP) {
@ -467,12 +478,12 @@ void netif_set_link_up(struct netif *netif )
#endif /* LWIP_ARP */ #endif /* LWIP_ARP */
#if LWIP_IGMP #if LWIP_IGMP
/* resend IGMP memberships */ /* resend IGMP memberships */
if (netif->flags & NETIF_FLAG_IGMP) { if (netif->flags & NETIF_FLAG_IGMP) {
igmp_report_groups( netif); igmp_report_groups( netif);
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
}
NETIF_LINK_CALLBACK(netif); NETIF_LINK_CALLBACK(netif);
} }

View File

@ -100,6 +100,9 @@ void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ /** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */
void autoip_tmr(void); void autoip_tmr(void);
/** Handle a possible change in the network configuration */
void autoip_network_changed(struct netif *netif);
#endif /* LWIP_AUTOIP */ #endif /* LWIP_AUTOIP */
#endif /* __LWIP_AUTOIP_H__ */ #endif /* __LWIP_AUTOIP_H__ */