Commit 0793380b authored by Simon Kelley's avatar Simon Kelley

Implement dhcp-ignore-names and DNSMASQ_RELAY_ADDRESS for IPv6

Build DHCPv6 by default.
parent 1adadf58
...@@ -820,7 +820,7 @@ agent ID and one provided by a relay agent, the tag is set. ...@@ -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
......
...@@ -116,7 +116,7 @@ RESOLVFILE ...@@ -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 */
......
...@@ -292,8 +292,12 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl ...@@ -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;
......
...@@ -928,6 +928,7 @@ struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type); ...@@ -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);
......
...@@ -490,6 +490,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) ...@@ -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++)
{ {
......
...@@ -493,7 +493,31 @@ struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 add ...@@ -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 */
......
...@@ -32,7 +32,7 @@ static void put_opt6_string(char *s); ...@@ -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 ** ...@@ -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 ** ...@@ -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 ...@@ -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 ...@@ -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)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment