Commit c630924d authored by Simon Kelley's avatar Simon Kelley

Experimental support for DHCPv6 prefix-class option.

parent ff59fc82
......@@ -59,6 +59,11 @@
#define OPTION6_SUBSCRIBER_ID 38
#define OPTION6_FQDN 39
/* replace this with the real number when allocated.
defining this also enables the relevant code. */
/* #define OPTION6_PREFIX_CLASS 99 */
#define DHCP6SUCCESS 0
#define DHCP6UNSPEC 1
#define DHCP6NOADDRS 2
......
......@@ -266,7 +266,7 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
}
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
int iaid, struct dhcp_netid *netids, struct in6_addr *ans)
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
{
/* Find a free address: exclude anything in use and anything allocated to
a particular hwaddr/clientid/hostname in our configuration.
......@@ -286,7 +286,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
for (j = iaid, i = 0; i < clid_len; i++)
j += clid[i] + (j << 6) + (j << 16) - j;
for (pass = 0; pass <= 1; pass++)
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
for (c = context; c; c = c->current)
if (c->flags & (CONTEXT_DEPRECATE | CONTEXT_STATIC | CONTEXT_RA_STATELESS | CONTEXT_USED))
continue;
......@@ -296,7 +296,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
{
if (option_bool(OPT_CONSEC_ADDR))
/* seed is largest extant lease addr in this context */
start = lease_find_max_addr6(c);
start = lease_find_max_addr6(c) + serial;
else
start = addr6part(&c->start6) + ((j + c->addr_epoch) % (1 + addr6part(&c->end6) - addr6part(&c->start6)));
......@@ -332,7 +332,8 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
/* can dynamically allocate addr */
struct dhcp_context *address6_available(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids)
struct dhcp_netid *netids,
int plain_range)
{
u64 start, end, addr = addr6part(taddr);
struct dhcp_context *tmp;
......@@ -347,7 +348,7 @@ struct dhcp_context *address6_available(struct dhcp_context *context,
is_same_net6(&tmp->end6, taddr, tmp->prefix) &&
addr >= start &&
addr <= end &&
match_netid(tmp->filter, netids, 1))
match_netid(tmp->filter, netids, plain_range))
return tmp;
}
......@@ -356,14 +357,15 @@ struct dhcp_context *address6_available(struct dhcp_context *context,
/* address OK if configured */
struct dhcp_context *address6_valid(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids)
struct in6_addr *taddr,
struct dhcp_netid *netids,
int plain_range)
{
struct dhcp_context *tmp;
for (tmp = context; tmp; tmp = tmp->current)
if (is_same_net6(&tmp->start6, taddr, tmp->prefix) &&
match_netid(tmp->filter, netids, 1))
match_netid(tmp->filter, netids, plain_range))
return tmp;
return NULL;
......
......@@ -684,7 +684,7 @@ struct cond_domain {
#ifdef OPTION6_PREFIX_CLASS
struct prefix_class {
int class;
struct dhcp_netid netid;
struct dhcp_netid tag;
struct prefix_class *next;
};
#endif
......@@ -829,6 +829,9 @@ extern struct daemon {
unsigned char *duid_config;
char *dbus_name;
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
#ifdef OPTION6_PREFIX_CLASS
struct prefix_class *prefix_classes;
#endif
/* globally used stuff for DNS */
char *packet; /* packet buffer */
......@@ -1171,14 +1174,16 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
void dhcp6_init(void);
void dhcp6_packet(time_t now);
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
int iaid, struct dhcp_netid *netids, struct in6_addr *ans);
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
int is_addr_in_context6(struct dhcp_context *context, struct in6_addr *addr);
struct dhcp_context *address6_available(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids);
struct dhcp_netid *netids,
int plain_range);
struct dhcp_context *address6_valid(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids);
struct dhcp_netid *netids,
int plain_range);
struct dhcp_config *find_config6(struct dhcp_config *configs,
struct dhcp_context *context,
unsigned char *duid, int duid_len,
......
......@@ -128,6 +128,9 @@ struct myoption {
#define LOPT_AUTHSFS 317
#define LOPT_AUTHPEER 318
#define LOPT_IPSET 319
#ifdef OPTION6_PREFIX_CLASS
#define LOPT_PREF_CLSS 320
#endif
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
......@@ -261,6 +264,9 @@ static const struct myoption opts[] =
{ "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
{ "auth-peer", 1, 0, LOPT_AUTHPEER },
{ "ipset", 1, 0, LOPT_IPSET },
#ifdef OPTION6_PREFIX_CLASS
{ "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
#endif
{ NULL, 0, 0, 0 }
};
......@@ -400,6 +406,9 @@ static struct {
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
{ LOPT_IPSET, ARG_DUP, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
#ifdef OPTION6_PREFIX_CLASS
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
#endif
{ 0, 0, NULL, NULL, NULL }
};
......@@ -2943,7 +2952,25 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
break;
#ifdef OPTION6_PREFIX_CLASS
case LOPT_PREF_CLSS: /* --dhcp-prefix-class */
{
struct prefix_class *new = opt_malloc(sizeof(struct prefix_class));
if (!(comma = split(arg)) ||
!atoi_check16(comma, &new->class))
ret_err(gen_err);
new->tag.net = opt_string_alloc(set_prefix(arg));
new->next = daemon->prefix_classes;
daemon->prefix_classes = new;
break;
}
#endif
case 'U': /* --dhcp-vendorclass */
case 'j': /* --dhcp-userclass */
case LOPT_CIRCUIT: /* --dhcp-circuitid */
......
This diff is collapsed.
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