mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-20 02:38:32 +00:00
More flexible RA configuration.
This commit is contained in:
@@ -229,7 +229,7 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
|
|||||||
|
|
||||||
for (pass = 0; pass <= 1; pass++)
|
for (pass = 0; pass <= 1; pass++)
|
||||||
for (c = context; c; c = c->current)
|
for (c = context; c; c = c->current)
|
||||||
if (c->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
|
if (c->flags & (CONTEXT_STATIC | CONTEXT_RA_STATELESS))
|
||||||
continue;
|
continue;
|
||||||
else if (!match_netid(c->filter, netids, pass))
|
else if (!match_netid(c->filter, netids, pass))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -549,23 +549,30 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
start = &dhcp_tmp->start6;
|
start = &dhcp_tmp->start6;
|
||||||
end = &dhcp_tmp->end6;
|
end = &dhcp_tmp->end6;
|
||||||
|
struct in6_addr subnet = dhcp_tmp->start6;
|
||||||
|
setaddr6part(&subnet, 0);
|
||||||
|
inet_ntop(AF_INET6, &subnet, daemon->dhcp_buff2, 256);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
|
prettyprint_time(daemon->namebuff, dhcp_tmp->lease_time);
|
||||||
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
||||||
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
||||||
my_syslog(MS_DHCP | LOG_INFO,
|
if ((dhcp_tmp->flags & CONTEXT_DHCP) || family == AF_INET)
|
||||||
(dhcp_tmp->flags & CONTEXT_STATIC) ?
|
my_syslog(MS_DHCP | LOG_INFO,
|
||||||
_("DHCP, static leases only on %.0s%s, lease time %s") :
|
(dhcp_tmp->flags & CONTEXT_STATIC) ?
|
||||||
(dhcp_tmp->flags & CONTEXT_RA_NAME) ?
|
_("DHCP, static leases only on %.0s%s, lease time %s") :
|
||||||
_("router advertisement with DHCPv4-derived names on %.0s%s, lifetime %s") :
|
(dhcp_tmp->flags & CONTEXT_RA_STATELESS) ?
|
||||||
(dhcp_tmp->flags & CONTEXT_RA_ONLY) ?
|
_("SLAAC and stateless DHCPv6 on %.0s%s%.0s") :
|
||||||
_("router advertisement only on %.0s%s, lifetime %s") :
|
(dhcp_tmp->flags & CONTEXT_PROXY) ?
|
||||||
(dhcp_tmp->flags & CONTEXT_PROXY) ?
|
_("DHCP, proxy on subnet %.0s%s%.0s") :
|
||||||
_("DHCP, proxy on subnet %.0s%s%.0s") :
|
_("DHCP, IP range %s -- %s, lease time %s"),
|
||||||
_("DHCP, IP range %s -- %s, lease time %s"),
|
daemon->dhcp_buff, daemon->dhcp_buff3, daemon->namebuff);
|
||||||
daemon->dhcp_buff, daemon->dhcp_buff3, daemon->dhcp_buff2);
|
if (dhcp_tmp->flags & CONTEXT_RA_NAME)
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, _("SLAAC and DHCPv4-derived names on %s"), daemon->dhcp_buff2);
|
||||||
|
if (dhcp_tmp->flags & CONTEXT_RA_ONLY)
|
||||||
|
my_syslog(MS_DHCP | LOG_INFO, _("SLAAC on %s"), daemon->dhcp_buff2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
|
|||||||
@@ -646,13 +646,15 @@ struct dhcp_context {
|
|||||||
struct dhcp_context *next, *current;
|
struct dhcp_context *next, *current;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CONTEXT_STATIC 1
|
#define CONTEXT_STATIC 1
|
||||||
#define CONTEXT_NETMASK 2
|
#define CONTEXT_NETMASK 2
|
||||||
#define CONTEXT_BRDCAST 4
|
#define CONTEXT_BRDCAST 4
|
||||||
#define CONTEXT_PROXY 8
|
#define CONTEXT_PROXY 8
|
||||||
#define CONTEXT_RA_ONLY 16
|
#define CONTEXT_RA_ONLY 16
|
||||||
#define CONTEXT_RA_DONE 32
|
#define CONTEXT_RA_DONE 32
|
||||||
#define CONTEXT_RA_NAME 64
|
#define CONTEXT_RA_NAME 64
|
||||||
|
#define CONTEXT_RA_STATELESS 128
|
||||||
|
#define CONTEXT_DHCP 256
|
||||||
|
|
||||||
struct ping_result {
|
struct ping_result {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|||||||
80
src/option.c
80
src/option.c
@@ -1959,7 +1959,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
case 'F': /* --dhcp-range */
|
case 'F': /* --dhcp-range */
|
||||||
{
|
{
|
||||||
int k, leasepos = 2;
|
int k, leasepos = 2;
|
||||||
char *cp, *a[5] = { NULL, NULL, NULL, NULL, NULL };
|
char *cp, *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||||
struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
|
struct dhcp_context *new = opt_malloc(sizeof(struct dhcp_context));
|
||||||
|
|
||||||
memset (new, 0, sizeof(*new));
|
memset (new, 0, sizeof(*new));
|
||||||
@@ -2010,7 +2010,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k = 1; k < 5; k++)
|
for (k = 1; k < 7; k++)
|
||||||
if (!(a[k] = split(a[k-1])))
|
if (!(a[k] = split(a[k-1])))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2020,17 +2020,12 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
{
|
{
|
||||||
new->next = daemon->dhcp;
|
new->next = daemon->dhcp;
|
||||||
daemon->dhcp = new;
|
daemon->dhcp = new;
|
||||||
|
new->end = new->start;
|
||||||
if (strcmp(a[1], "static") == 0)
|
if (strcmp(a[1], "static") == 0)
|
||||||
{
|
new->flags |= CONTEXT_STATIC;
|
||||||
new->end = new->start;
|
|
||||||
new->flags |= CONTEXT_STATIC;
|
|
||||||
}
|
|
||||||
else if (strcmp(a[1], "proxy") == 0)
|
else if (strcmp(a[1], "proxy") == 0)
|
||||||
{
|
new->flags |= CONTEXT_PROXY;
|
||||||
new->end = new->start;
|
else if (!inet_pton(AF_INET, a[1], &new->end))
|
||||||
new->flags |= CONTEXT_PROXY;
|
|
||||||
}
|
|
||||||
else if ((new->end.s_addr = inet_addr(a[1])) == (in_addr_t)-1)
|
|
||||||
option = '?';
|
option = '?';
|
||||||
|
|
||||||
if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr))
|
if (ntohl(new->start.s_addr) > ntohl(new->end.s_addr))
|
||||||
@@ -2060,53 +2055,54 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
else if (inet_pton(AF_INET6, a[0], &new->start6))
|
else if (inet_pton(AF_INET6, a[0], &new->start6))
|
||||||
{
|
{
|
||||||
new->prefix = 64; /* default */
|
new->prefix = 64; /* default */
|
||||||
|
new->end6 = new->start6;
|
||||||
|
|
||||||
|
for (leasepos = 1; leasepos < k; leasepos++)
|
||||||
|
{
|
||||||
|
if (strcmp(a[leasepos], "static") == 0)
|
||||||
|
new->flags |= CONTEXT_STATIC | CONTEXT_DHCP;
|
||||||
|
else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 )
|
||||||
|
new->flags |= CONTEXT_RA_ONLY;
|
||||||
|
else if (strcmp(a[leasepos], "ra-names") == 0)
|
||||||
|
new->flags |= CONTEXT_RA_NAME;
|
||||||
|
else if (strcmp(a[leasepos], "ra-stateless") == 0)
|
||||||
|
new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP;
|
||||||
|
else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6))
|
||||||
|
new->flags |= CONTEXT_DHCP;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(a[1], "static") == 0)
|
if (new->flags & CONTEXT_DHCP)
|
||||||
{
|
|
||||||
memcpy(&new->end6, &new->start6, IN6ADDRSZ);
|
|
||||||
new->flags |= CONTEXT_STATIC;
|
|
||||||
}
|
|
||||||
else if (strcmp(a[1], "ra-only") == 0)
|
|
||||||
{
|
|
||||||
memcpy(&new->end6, &new->start6, IN6ADDRSZ);
|
|
||||||
new->flags |= CONTEXT_RA_ONLY;
|
|
||||||
}
|
|
||||||
else if (strcmp(a[1], "ra-names") == 0)
|
|
||||||
{
|
|
||||||
memcpy(&new->end6, &new->start6, IN6ADDRSZ);
|
|
||||||
new->flags |= CONTEXT_RA_NAME | CONTEXT_RA_ONLY;
|
|
||||||
}
|
|
||||||
else if (!inet_pton(AF_INET6, a[1], &new->end6))
|
|
||||||
option = '?';
|
|
||||||
|
|
||||||
if (new->flags & CONTEXT_RA_ONLY)
|
|
||||||
{
|
|
||||||
new->next = daemon->ra_contexts;
|
|
||||||
daemon->ra_contexts = new;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
new->next = daemon->dhcp6;
|
new->next = daemon->dhcp6;
|
||||||
daemon->dhcp6 = new;
|
daemon->dhcp6 = new;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new->next = daemon->ra_contexts;
|
||||||
|
daemon->ra_contexts = new;
|
||||||
|
}
|
||||||
|
|
||||||
/* bare integer < 128 is prefix value */
|
/* bare integer < 128 is prefix value */
|
||||||
if (option != '?' && k >= 3)
|
if (option != '?' && leasepos < k)
|
||||||
{
|
{
|
||||||
int pref;
|
int pref;
|
||||||
for (cp = a[2]; *cp; cp++)
|
for (cp = a[leasepos]; *cp; cp++)
|
||||||
if (!(*cp >= '0' && *cp <= '9'))
|
if (!(*cp >= '0' && *cp <= '9'))
|
||||||
break;
|
break;
|
||||||
if (!*cp && (pref = atoi(a[2])) <= 128)
|
if (!*cp && (pref = atoi(a[leasepos])) <= 128)
|
||||||
{
|
{
|
||||||
new->prefix = pref;
|
new->prefix = pref;
|
||||||
leasepos = 3;
|
leasepos++;
|
||||||
if ((new->flags & CONTEXT_RA_ONLY) && new->prefix != 64)
|
if ((new->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) &&
|
||||||
|
new->prefix != 64)
|
||||||
problem = _("prefix must be exactly 64 for RA subnets");
|
problem = _("prefix must be exactly 64 for RA subnets");
|
||||||
else if (new->prefix < 64)
|
else if (new->prefix < 64)
|
||||||
problem = _("prefix must be at least 64");
|
problem = _("prefix must be at least 64");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!problem && !is_same_net6(&new->start6, &new->end6, new->prefix))
|
if (!problem && !is_same_net6(&new->start6, &new->end6, new->prefix))
|
||||||
problem = _("inconsistent DHCPv6 range");
|
problem = _("inconsistent DHCPv6 range");
|
||||||
else if (addr6part(&new->start6) > addr6part(&new->end6))
|
else if (addr6part(&new->start6) > addr6part(&new->end6))
|
||||||
@@ -2118,7 +2114,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (k >= leasepos+1)
|
if (leasepos < k)
|
||||||
{
|
{
|
||||||
if (strcmp(a[leasepos], "infinite") == 0)
|
if (strcmp(a[leasepos], "infinite") == 0)
|
||||||
new->lease_time = 0xffffffff;
|
new->lease_time = 0xffffffff;
|
||||||
|
|||||||
42
src/radv.c
42
src/radv.c
@@ -27,7 +27,7 @@
|
|||||||
#include <netinet/icmp6.h>
|
#include <netinet/icmp6.h>
|
||||||
|
|
||||||
struct ra_param {
|
struct ra_param {
|
||||||
int ind, managed, found_context, first;
|
int ind, managed, other, found_context, first;
|
||||||
char *if_name;
|
char *if_name;
|
||||||
struct in6_addr link_local;
|
struct in6_addr link_local;
|
||||||
};
|
};
|
||||||
@@ -213,6 +213,7 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
|||||||
|
|
||||||
parm.ind = iface;
|
parm.ind = iface;
|
||||||
parm.managed = 0;
|
parm.managed = 0;
|
||||||
|
parm.other = 0;
|
||||||
parm.found_context = 0;
|
parm.found_context = 0;
|
||||||
parm.if_name = iface_name;
|
parm.if_name = iface_name;
|
||||||
parm.first = 1;
|
parm.first = 1;
|
||||||
@@ -246,8 +247,10 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
|||||||
|
|
||||||
/* set managed bits unless we're providing only RA on this link */
|
/* set managed bits unless we're providing only RA on this link */
|
||||||
if (parm.managed)
|
if (parm.managed)
|
||||||
ra->flags = 0xc0; /* M flag, managed, O flag, other */
|
ra->flags |= 0x80; /* M flag, managed, */
|
||||||
|
if (parm.other)
|
||||||
|
ra->flags |= 0x40; /* O flag, other */
|
||||||
|
|
||||||
/* decide where we're sending */
|
/* decide where we're sending */
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||||
@@ -295,14 +298,20 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
{
|
{
|
||||||
int do_slaac = 0;
|
int do_slaac = 0;
|
||||||
|
|
||||||
if (context->flags & CONTEXT_RA_ONLY)
|
if ((context->flags &
|
||||||
do_slaac = 1;
|
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
|
||||||
|
{
|
||||||
|
do_slaac = 1;
|
||||||
|
if (context->flags & CONTEXT_RA_STATELESS)
|
||||||
|
param->other = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* don't do RA for non-ra-only unless --enable-ra is set */
|
/* don't do RA for non-ra-only unless --enable-ra is set */
|
||||||
if (!option_bool(OPT_RA))
|
if (!option_bool(OPT_RA))
|
||||||
continue;
|
continue;
|
||||||
param->managed = 1;
|
param->managed = 1;
|
||||||
|
param->other = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->flags & CONTEXT_RA_DONE)
|
if (context->flags & CONTEXT_RA_DONE)
|
||||||
@@ -321,14 +330,27 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
is_same_net6(local, &tmp->start6, prefix) &&
|
is_same_net6(local, &tmp->start6, prefix) &&
|
||||||
is_same_net6(local, &tmp->end6, prefix))
|
is_same_net6(local, &tmp->end6, prefix))
|
||||||
{
|
{
|
||||||
/* if any dhcp-range with ra-only on this subnet
|
|
||||||
set the "do_slaac" bit */
|
|
||||||
if (tmp->flags & CONTEXT_RA_ONLY)
|
|
||||||
do_slaac = 1;
|
|
||||||
tmp->flags |= CONTEXT_RA_DONE;
|
tmp->flags |= CONTEXT_RA_DONE;
|
||||||
context->ra_time = 0;
|
context->ra_time = 0;
|
||||||
|
/* if any dhcp-range with ra-only on this subnet
|
||||||
|
set the "do_slaac" bit */
|
||||||
|
if (tmp->flags &
|
||||||
|
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS))
|
||||||
|
{
|
||||||
|
do_slaac = 1;
|
||||||
|
if (context->flags & CONTEXT_RA_STATELESS)
|
||||||
|
param->other = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* don't do RA for non-ra-only unless --enable-ra is set */
|
||||||
|
if (!option_bool(OPT_RA))
|
||||||
|
continue;
|
||||||
|
param->managed = 1;
|
||||||
|
param->other = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((opt = expand(sizeof(struct prefix_opt))))
|
if ((opt = expand(sizeof(struct prefix_opt))))
|
||||||
{
|
{
|
||||||
u64 addrpart = addr6part(&context->start6);
|
u64 addrpart = addr6part(&context->start6);
|
||||||
|
|||||||
Reference in New Issue
Block a user