Implement dhcp-ignore-names and DNSMASQ_RELAY_ADDRESS for IPv6

Build DHCPv6 by default.
This commit is contained in:
Simon Kelley
2012-02-14 20:55:25 +00:00
parent 1adadf585d
commit 0793380b40
7 changed files with 58 additions and 8 deletions

View File

@@ -820,7 +820,7 @@ agent ID and one provided by a relay agent, the tag is set.
(IPv4 and IPv6) Map from RFC3993 subscriber-id relay agent options to tags. (IPv4 and IPv6) Map from RFC3993 subscriber-id relay agent options to tags.
.TP .TP
.B --dhcp-proxy[=<ip addr>]...... .B --dhcp-proxy[=<ip addr>]......
A normal DHCP relay agent is only used to forward the initial parts of (IPv4 only) A normal DHCP relay agent is only used to forward the initial parts of
a DHCP interaction to the DHCP server. Once a client is configured, it a DHCP interaction to the DHCP server. Once a client is configured, it
communicates directly with the server. This is undesirable if the communicates directly with the server. This is undesirable if the
relay agent is addding extra information to the DHCP packets, such as relay agent is addding extra information to the DHCP packets, such as

View File

@@ -116,7 +116,7 @@ RESOLVFILE
has no library dependencies other than libc */ has no library dependencies other than libc */
#define HAVE_DHCP #define HAVE_DHCP
/* #define HAVE_DHCP6 */ #define HAVE_DHCP6
#define HAVE_TFTP #define HAVE_TFTP
#define HAVE_SCRIPT #define HAVE_SCRIPT
/* #define HAVE_LUASCRIPT */ /* #define HAVE_LUASCRIPT */

View File

@@ -292,8 +292,12 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
else if (!match_netid(c->filter, netids, pass)) else if (!match_netid(c->filter, netids, pass))
continue; continue;
else else
{ {
start = addr6part(&c->start6) + ((j + c->addr_epoch + serial) % (1 + addr6part(&c->end6) - addr6part(&c->start6))); if (option_bool(OPT_CONSEC_ADDR))
/* seed is largest extant lease addr in this context */
start = lease_find_max_addr6(c) + serial;
else
start = addr6part(&c->start6) + ((j + c->addr_epoch + serial) % (1 + addr6part(&c->end6) - addr6part(&c->start6)));
/* iterate until we find a free address. */ /* iterate until we find a free address. */
addr = start; addr = start;

View File

@@ -928,6 +928,7 @@ struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len, struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
int lease_type, int iaid, struct in6_addr *addr); int lease_type, int iaid, struct in6_addr *addr);
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr); struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr);
u64 lease_find_max_addr6(struct dhcp_context *context);
#endif #endif
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr, void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
unsigned char *clid, int hw_len, int hw_type, int clid_len); unsigned char *clid, int hw_len, int hw_type, int clid_len);

View File

@@ -490,6 +490,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
} }
buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err); buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err);
if (is6)
buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);
for (i = 0; buf; i++) for (i = 0; buf; i++)
{ {

View File

@@ -493,7 +493,31 @@ struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 add
} }
return NULL; return NULL;
} }
/* Find largest assigned address in context */
u64 lease_find_max_addr6(struct dhcp_context *context)
{
struct dhcp_lease *lease;
u64 addr = addr6part(&context->start6);
if (!(context->flags & (CONTEXT_STATIC | CONTEXT_PROXY)))
for (lease = leases; lease; lease = lease->next)
{
#ifdef HAVE_DHCP6
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
continue;
#endif
if (is_same_net6((struct in6_addr *)lease->hwaddr, &context->start6, 64) &&
addr6part((struct in6_addr *)lease->hwaddr) > addr6part(&context->start6) &&
addr6part((struct in6_addr *)lease->hwaddr) <= addr6part(&context->end6) &&
addr6part((struct in6_addr *)lease->hwaddr) > addr)
addr = addr6part((struct in6_addr *)lease->hwaddr);
}
return addr;
}
#endif #endif
/* Find largest assigned address in context */ /* Find largest assigned address in context */

View File

@@ -32,7 +32,7 @@ static void put_opt6_string(char *s);
static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **relay_tagsp, struct dhcp_context *context, static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **relay_tagsp, struct dhcp_context *context,
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now); int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now);
static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_context *context, static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context,
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now); int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now);
static void log6_packet(char *type, unsigned char *clid, int clid_len, struct in6_addr *addr, int xid, char *iface, char *string); static void log6_packet(char *type, unsigned char *clid, int clid_len, struct in6_addr *addr, int xid, char *iface, char *string);
@@ -114,7 +114,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
return 0; return 0;
} }
return dhcp6_no_relay(msg_type, *relay_tagsp, context, interface, iface_name, inbuff, sz, is_unicast, now); return dhcp6_no_relay(msg_type, link_address, *relay_tagsp, context, interface, iface_name, inbuff, sz, is_unicast, now);
} }
/* must have at least msg_type+hopcount+link_address+peer_address+minimal size option /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
@@ -170,7 +170,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
return 1; return 1;
} }
static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_context *context, static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context,
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now) int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now)
{ {
void *packet_options = inbuff + 4; void *packet_options = inbuff + 4;
@@ -670,6 +670,11 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_con
lease_add_extradata(lease, (unsigned char *)n->net, strlen(n->net), n->next ? ' ' : 0); lease_add_extradata(lease, (unsigned char *)n->net, strlen(n->net), n->next ? ' ' : 0);
} }
} }
if (link_address)
inet_ntop(AF_INET6, link_address, daemon->addrbuff, ADDRSTRLEN);
lease_add_extradata(lease, (unsigned char *)daemon->addrbuff, link_address ? strlen(daemon->addrbuff) : 0, 0);
if ((class_opt = opt6_find(packet_options, end, OPTION6_USER_CLASS, 2))) if ((class_opt = opt6_find(packet_options, end, OPTION6_USER_CLASS, 2)))
{ {
@@ -1206,6 +1211,19 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_con
} }
} }
} }
/* if all the netids in the ignore_name list are present, ignore client-supplied name */
if (!hostname_auth)
{
struct dhcp_netid_list *id_list;
for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
if ((!id_list->list) || match_netid(id_list->list, tagif, 0))
break;
if (id_list)
hostname = NULL;
}
if (hostname) if (hostname)
{ {