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 */
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 */
static err_t autoip_arp_announce(struct netif *netif);
/* configure interface for use with current LL IP-Address */
static err_t autoip_bind(struct netif *netif);
/* start sending probes for llipaddr */
static void autoip_start_probing(struct netif *netif);
/**
* 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)));
}
/**
* 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
*
@ -281,6 +300,16 @@ autoip_start(struct netif *netif)
autoip_create_addr(netif, &(autoip->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->sent_num = 0;
@ -295,12 +324,24 @@ autoip_start(struct netif *netif)
* accquiring and probing address
* compliant to RFC 3927 Section 2.2.1
*/
if(autoip->tried_llipaddr > MAX_CONFLICTS) {
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) {
netif->autoip->ttw--;
} else {
if(netif->autoip->sent_num == PROBE_NUM) {
if(netif->autoip->sent_num >= PROBE_NUM) {
netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
netif->autoip->sent_num = 0;
netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
} else {
etharp_request(netif, &(netif->autoip->llipaddr));
autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++;
@ -363,21 +404,24 @@ autoip_tmr()
} else {
if(netif->autoip->sent_num == 0) {
/* 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);
}
if(netif->autoip->sent_num == ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
} else {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
("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;

View File

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