Allow IPv4LL address range to be configured by DHCP.

We now check the message for a DHCP cookie instead of the address
assigned to test for local link.
This commit is contained in:
Roy Marples 2010-02-17 22:23:17 +00:00
parent 793c4286eb
commit 1cc00d8a7c
7 changed files with 27 additions and 26 deletions

4
arp.c
View File

@ -78,7 +78,7 @@ send_arp(const struct interface *iface, int op, in_addr_t sip, in_addr_t tip)
static void
handle_arp_failure(struct interface *iface)
{
if (IN_LINKLOCAL(htonl(iface->state->fail.s_addr))) {
if (iface->state->offer->cookie != htonl(MAGIC_COOKIE)) {
handle_ipv4ll_failure(iface);
return;
}
@ -216,7 +216,7 @@ send_arp_announce(void *arg)
add_timeout_sec(ANNOUNCE_WAIT, send_arp_announce, iface);
return;
}
if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
if (state->new->cookie != htonl(MAGIC_COOKIE)) {
/* We should pretend to be at the end
* of the DHCP negotation cycle unless we rebooted */
if (state->interval != 0)

2
bind.c
View File

@ -143,7 +143,7 @@ bind_interface(void *arg)
lease->leasetime = ~0U;
lease->net.s_addr = ifo->req_mask.s_addr;
state->reason = "STATIC";
} else if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
} else if (state->new->cookie != htonl(MAGIC_COOKIE)) {
syslog(LOG_INFO, "%s: using IPv4LL address %s",
iface->name, inet_ntoa(lease->addr));
lease->leasetime = ~0U;

16
dhcp.c
View File

@ -843,19 +843,16 @@ make_message(struct dhcp_message **message,
m = (uint8_t *)dhcp;
p = dhcp->options;
if ((type == DHCP_INFORM ||
type == DHCP_RELEASE ||
type == DHCP_REQUEST) &&
!IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
(type == DHCP_REQUEST &&
iface->net.s_addr == lease->net.s_addr &&
(iface->state->new == NULL ||
iface->state->new->cookie == htonl(MAGIC_COOKIE)))))
{
dhcp->ciaddr = iface->addr.s_addr;
/* In-case we haven't actually configured the address yet */
if (type == DHCP_INFORM && iface->addr.s_addr == 0)
dhcp->ciaddr = lease->addr.s_addr;
/* Zero the address if we're currently on a different subnet */
if (type == DHCP_REQUEST &&
iface->net.s_addr != lease->net.s_addr)
dhcp->ciaddr = 0;
}
dhcp->op = DHCP_BOOTREQUEST;
@ -893,7 +890,7 @@ make_message(struct dhcp_message **message,
p += iface->clientid[0] + 1;
}
if (lease->addr.s_addr && !IN_LINKLOCAL(htonl(lease->addr.s_addr))) {
if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
if (type == DHCP_DECLINE ||
type == DHCP_DISCOVER ||
(type == DHCP_REQUEST &&
@ -1374,6 +1371,7 @@ get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
{
struct timeval now;
lease->cookie = dhcp->cookie;
/* BOOTP does not set yiaddr for replies when ciaddr is set. */
if (dhcp->yiaddr)
lease->addr.s_addr = dhcp->yiaddr;

1
dhcp.h
View File

@ -165,6 +165,7 @@ struct dhcp_lease {
time_t leasedfrom;
struct timeval boundtime;
uint8_t frominfo;
uint32_t cookie;
};
#include "dhcpcd.h"

View File

@ -540,6 +540,7 @@ handle_dhcp(struct interface *iface, struct dhcp_message **dhcpp)
{
lease->frominfo = 0;
lease->addr.s_addr = dhcp->yiaddr;
lease->cookie = dhcp->cookie;
if (type == 0 ||
get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
lease->server.s_addr = INADDR_ANY;
@ -728,8 +729,8 @@ send_release(struct interface *iface)
{
struct timespec ts;
if (iface->state->lease.addr.s_addr &&
!IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)))
if (iface->state->new != NULL &&
iface->state->new->cookie == htonl(MAGIC_COOKIE))
{
syslog(LOG_INFO, "%s: releasing lease of %s",
iface->name, inet_ntoa(iface->state->lease.addr));
@ -1064,21 +1065,20 @@ start_reboot(struct interface *iface)
start_static(iface);
return;
}
if (ifo->reboot == 0) {
if (ifo->reboot == 0 || iface->state->offer == NULL) {
start_discover(iface);
return;
}
if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr))) {
if (ifo->options & DHCPCD_INFORM) {
syslog(LOG_INFO, "%s: informing address of %s",
iface->name, inet_ntoa(iface->state->lease.addr));
} else if (iface->state->offer->cookie == 0) {
if (ifo->options & DHCPCD_IPV4LL) {
iface->state->claims = 0;
send_arp_announce(iface);
} else
start_discover(iface);
return;
}
if (ifo->options & DHCPCD_INFORM) {
syslog(LOG_INFO, "%s: informing address of %s",
iface->name, inet_ntoa(iface->state->lease.addr));
} else {
syslog(LOG_INFO, "%s: rebinding lease of %s",
iface->name, inet_ntoa(iface->state->lease.addr));
@ -1161,7 +1161,7 @@ start_interface(void *arg)
if (iface->state->offer) {
get_lease(&iface->state->lease, iface->state->offer);
iface->state->lease.frominfo = 1;
if (IN_LINKLOCAL(htonl(iface->state->offer->yiaddr))) {
if (iface->state->offer->cookie == 0) {
if (iface->state->offer->yiaddr ==
iface->addr.s_addr)
{
@ -1189,9 +1189,9 @@ start_interface(void *arg)
}
}
}
if (!iface->state->offer)
if (iface->state->offer == NULL)
start_discover(iface);
else if (IN_LINKLOCAL(htonl(iface->state->lease.addr.s_addr)) &&
else if (iface->state->offer->cookie == 0 &&
iface->state->options->options & DHCPCD_IPV4LL)
start_ipv4ll(iface);
else

View File

@ -51,9 +51,9 @@ ifcmp(struct interface *si, struct interface *ti)
return 1;
/* If we are either, they neither have a lease, or they both have.
* We need to check for IPv4LL and make it non-preferred. */
if (si->state->new) {
sill = IN_LINKLOCAL(htonl(si->state->new->yiaddr));
till = IN_LINKLOCAL(htonl(ti->state->new->yiaddr));
if (si->state->new && ti->state->new) {
sill = (si->state->new->cookie == htonl(MAGIC_COOKIE));
till = (ti->state->new->cookie == htonl(MAGIC_COOKIE));
if (!sill && till)
return -1;
if (sill && !till)

View File

@ -99,6 +99,8 @@ start_ipv4ll(void *arg)
iface->state->offer = make_ipv4ll_lease(0);
iface->state->lease.frominfo = 0;
}
/* Ensure we don't have a cookie */
iface->state->offer->cookie = 0;
send_arp_probe(iface);
}