mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Add --ra-param and remove --force-fast-ra
This commit is contained in:
@@ -90,8 +90,6 @@ version 2.67
|
|||||||
smallest valid dhcp-range is sent. Thanks to Uwe Schindler
|
smallest valid dhcp-range is sent. Thanks to Uwe Schindler
|
||||||
for suggesting this.
|
for suggesting this.
|
||||||
|
|
||||||
Add --force-fast-ra option. Another thanks to Uwe Schindler.
|
|
||||||
|
|
||||||
Make --listen-address higher priority than --except-interface
|
Make --listen-address higher priority than --except-interface
|
||||||
in all circumstances. Thanks to Thomas Hood for the bugreport.
|
in all circumstances. Thanks to Thomas Hood for the bugreport.
|
||||||
|
|
||||||
@@ -132,6 +130,9 @@ version 2.67
|
|||||||
|
|
||||||
Update Spanish transalation. Thanks to Vicente Soriano.
|
Update Spanish transalation. Thanks to Vicente Soriano.
|
||||||
|
|
||||||
|
Add --ra-param option. Thanks to Vladislav Grishenko for
|
||||||
|
inspiration on this.
|
||||||
|
|
||||||
|
|
||||||
version 2.66
|
version 2.66
|
||||||
Add the ability to act as an authoritative DNS
|
Add the ability to act as an authoritative DNS
|
||||||
|
|||||||
@@ -1525,11 +1525,19 @@ the relevant link-local address of the machine running dnsmasq is sent
|
|||||||
as recursive DNS server. If provided, the DHCPv6 options dns-server and
|
as recursive DNS server. If provided, the DHCPv6 options dns-server and
|
||||||
domain-search are used for RDNSS and DNSSL.
|
domain-search are used for RDNSS and DNSSL.
|
||||||
.TP
|
.TP
|
||||||
.B --force-fast-ra
|
.B --ra-param=<interface>,[high|low],[[<ra-interval>],<router lifetime>]
|
||||||
Normally, dnsmasq advertises a new IPv6 prefix frequently (every 10 seconds or so) for the first minute, and then
|
Set non-default values for router advertisements sent via an
|
||||||
drops back to sending "maintenance" advertisements every 10 minutes or so. This option forces dnsmasq to be always in
|
interface. The priority field for the router may be altered from the
|
||||||
frequent RA mode. It's a bug workaround for mobile devices which go deaf to RAs during sleep and therefore
|
default of medium with eg
|
||||||
lose conectivity; with frequent RAs they recover in a reasonable time after wakeup.
|
.B --ra-param=eth0,high.
|
||||||
|
The interval between router advertisements may be set (in seconds) with
|
||||||
|
.B --ra-param=eth0,60.
|
||||||
|
The lifetime of the route may be changed or set to zero, which allows
|
||||||
|
a router to advertise prefixes but not a route via itself.
|
||||||
|
.B --ra-parm=eth0,0,0
|
||||||
|
(A value of zero for the interval means the default value.) All three parameters may be set at once.
|
||||||
|
.B --ra-param=low,60,1200
|
||||||
|
The interface field may include a wildcard.
|
||||||
.TP
|
.TP
|
||||||
.B --enable-tftp[=<interface>[,<interface>]]
|
.B --enable-tftp[=<interface>[,<interface>]]
|
||||||
Enable the TFTP server function. This is deliberately limited to that
|
Enable the TFTP server function. This is deliberately limited to that
|
||||||
|
|||||||
@@ -221,8 +221,7 @@ struct event_desc {
|
|||||||
#define OPT_TFTP_LC 38
|
#define OPT_TFTP_LC 38
|
||||||
#define OPT_CLEVERBIND 39
|
#define OPT_CLEVERBIND 39
|
||||||
#define OPT_TFTP 40
|
#define OPT_TFTP 40
|
||||||
#define OPT_FAST_RA 41
|
#define OPT_LAST 41
|
||||||
#define OPT_LAST 42
|
|
||||||
|
|
||||||
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
||||||
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
||||||
@@ -701,6 +700,12 @@ struct prefix_class {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ra_interface {
|
||||||
|
char *name;
|
||||||
|
int interval, lifetime, prio;
|
||||||
|
struct ra_interface *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct dhcp_context {
|
struct dhcp_context {
|
||||||
unsigned int lease_time, addr_epoch;
|
unsigned int lease_time, addr_epoch;
|
||||||
struct in_addr netmask, broadcast;
|
struct in_addr netmask, broadcast;
|
||||||
@@ -825,6 +830,7 @@ extern struct daemon {
|
|||||||
unsigned long local_ttl, neg_ttl, max_ttl, max_cache_ttl, auth_ttl;
|
unsigned long local_ttl, neg_ttl, max_ttl, max_cache_ttl, auth_ttl;
|
||||||
struct hostsfile *addn_hosts;
|
struct hostsfile *addn_hosts;
|
||||||
struct dhcp_context *dhcp, *dhcp6;
|
struct dhcp_context *dhcp, *dhcp6;
|
||||||
|
struct ra_interface *ra_interfaces;
|
||||||
struct dhcp_config *dhcp_conf;
|
struct dhcp_config *dhcp_conf;
|
||||||
struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
|
struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
|
||||||
struct dhcp_vendor *dhcp_vendors;
|
struct dhcp_vendor *dhcp_vendors;
|
||||||
|
|||||||
31
src/option.c
31
src/option.c
@@ -132,8 +132,8 @@ struct myoption {
|
|||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
#define LOPT_PREF_CLSS 321
|
#define LOPT_PREF_CLSS 321
|
||||||
#endif
|
#endif
|
||||||
#define LOPT_FAST_RA 322
|
|
||||||
#define LOPT_RELAY 323
|
#define LOPT_RELAY 323
|
||||||
|
#define LOPT_RA_PARAM 324
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT_LONG
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static const struct option opts[] =
|
static const struct option opts[] =
|
||||||
@@ -271,8 +271,8 @@ static const struct myoption opts[] =
|
|||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
{ "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
|
{ "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
|
||||||
#endif
|
#endif
|
||||||
{ "force-fast-ra", 0, 0, LOPT_FAST_RA },
|
|
||||||
{ "dhcp-relay", 1, 0, LOPT_RELAY },
|
{ "dhcp-relay", 1, 0, LOPT_RELAY },
|
||||||
|
{ "ra-param", 1, 0, LOPT_RA_PARAM },
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -402,7 +402,6 @@ static struct {
|
|||||||
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
||||||
{ LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
|
{ LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
|
||||||
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
|
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
|
||||||
{ LOPT_FAST_RA, OPT_FAST_RA, NULL, gettext_noop("Always send frequent router-advertisements"), NULL },
|
|
||||||
{ LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
|
{ LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
|
||||||
{ LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
|
{ LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
|
||||||
{ LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
|
{ LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
|
||||||
@@ -418,6 +417,7 @@ static struct {
|
|||||||
#ifdef OPTION6_PREFIX_CLASS
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
|
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
|
||||||
#endif
|
#endif
|
||||||
|
{ LOPT_RA_PARAM, ARG_DUP, "<interface>,[high,|low,]<interval>[,<lifetime>]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL },
|
||||||
{ 0, 0, NULL, NULL, NULL }
|
{ 0, 0, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3215,6 +3215,31 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
|
case LOPT_RA_PARAM: /* --ra-param */
|
||||||
|
if ((comma = split(arg)))
|
||||||
|
{
|
||||||
|
struct ra_interface *new = opt_malloc(sizeof(struct ra_interface));
|
||||||
|
new->lifetime = -1;
|
||||||
|
new->prio = 0;
|
||||||
|
new->name = opt_string_alloc(arg);
|
||||||
|
if (strcasestr(comma, "high") == comma || strcasestr(comma, "low") == comma)
|
||||||
|
{
|
||||||
|
if (*comma == 'l' || *comma == 'L')
|
||||||
|
new->prio = 0x18;
|
||||||
|
else
|
||||||
|
new->prio = 0x08;
|
||||||
|
comma = split(comma);
|
||||||
|
}
|
||||||
|
arg = split(comma);
|
||||||
|
if (!atoi_check(comma, &new->interval) ||
|
||||||
|
(arg && !atoi_check(arg, &new->lifetime)))
|
||||||
|
ret_err(_("bad RA-params"));
|
||||||
|
|
||||||
|
new->next = daemon->ra_interfaces;
|
||||||
|
daemon->ra_interfaces = new;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LOPT_DUID: /* --dhcp-duid */
|
case LOPT_DUID: /* --dhcp-duid */
|
||||||
if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
|
if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
|
||||||
ret_err(_("bad DUID"));
|
ret_err(_("bad DUID"));
|
||||||
|
|||||||
116
src/radv.c
116
src/radv.c
@@ -32,11 +32,12 @@ struct ra_param {
|
|||||||
char *if_name;
|
char *if_name;
|
||||||
struct dhcp_netid *tags;
|
struct dhcp_netid *tags;
|
||||||
struct in6_addr link_local, link_global;
|
struct in6_addr link_local, link_global;
|
||||||
unsigned int pref_time;
|
unsigned int pref_time, adv_interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct search_param {
|
struct search_param {
|
||||||
time_t now; int iface;
|
time_t now; int iface;
|
||||||
|
char name[IF_NAMESIZE+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest);
|
static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest);
|
||||||
@@ -47,7 +48,11 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
int scope, int if_index, int flags,
|
int scope, int if_index, int flags,
|
||||||
int prefered, int valid, void *vparam);
|
int prefered, int valid, void *vparam);
|
||||||
static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
static int add_lla(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
||||||
static void new_timeout(struct dhcp_context *context, time_t now);
|
static void new_timeout(struct dhcp_context *context, char *iface_name, time_t now);
|
||||||
|
static unsigned int calc_lifetime(struct ra_interface *ra);
|
||||||
|
static unsigned int calc_interval(struct ra_interface *ra);
|
||||||
|
static unsigned int calc_prio(struct ra_interface *ra);
|
||||||
|
static struct ra_interface *find_iface_param(char *iface);
|
||||||
|
|
||||||
static int hop_limit;
|
static int hop_limit;
|
||||||
|
|
||||||
@@ -198,6 +203,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
struct dhcp_context *context, *tmp, **up;
|
struct dhcp_context *context, *tmp, **up;
|
||||||
struct dhcp_netid iface_id;
|
struct dhcp_netid iface_id;
|
||||||
struct dhcp_opt *opt_cfg;
|
struct dhcp_opt *opt_cfg;
|
||||||
|
struct ra_interface *ra_param = find_iface_param(iface_name);
|
||||||
int done_dns = 0;
|
int done_dns = 0;
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -209,8 +215,8 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
ra->type = ND_ROUTER_ADVERT;
|
ra->type = ND_ROUTER_ADVERT;
|
||||||
ra->code = 0;
|
ra->code = 0;
|
||||||
ra->hop_limit = hop_limit;
|
ra->hop_limit = hop_limit;
|
||||||
ra->flags = 0x00;
|
ra->flags = calc_prio(ra_param);
|
||||||
ra->lifetime = htons(RA_INTERVAL * 3); /* AdvDefaultLifetime * 3 */
|
ra->lifetime = htons(calc_lifetime(ra_param));
|
||||||
ra->reachable_time = 0;
|
ra->reachable_time = 0;
|
||||||
ra->retrans_time = 0;
|
ra->retrans_time = 0;
|
||||||
|
|
||||||
@@ -222,6 +228,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
parm.first = 1;
|
parm.first = 1;
|
||||||
parm.now = now;
|
parm.now = now;
|
||||||
parm.pref_time = 0;
|
parm.pref_time = 0;
|
||||||
|
parm.adv_interval = calc_interval(ra_param);
|
||||||
|
|
||||||
/* set tag with name == interface */
|
/* set tag with name == interface */
|
||||||
iface_id.net = iface_name;
|
iface_id.net = iface_name;
|
||||||
@@ -335,7 +342,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
put_opt6_char(ICMP6_OPT_RDNSS);
|
put_opt6_char(ICMP6_OPT_RDNSS);
|
||||||
put_opt6_char((opt_cfg->len/8) + 1);
|
put_opt6_char((opt_cfg->len/8) + 1);
|
||||||
put_opt6_short(0);
|
put_opt6_short(0);
|
||||||
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
|
put_opt6_long(parm.adv_interval * 2); /* lifetime - twice RA retransmit */
|
||||||
/* zero means "self" */
|
/* zero means "self" */
|
||||||
for (i = 0; i < opt_cfg->len; i += IN6ADDRSZ, a++)
|
for (i = 0; i < opt_cfg->len; i += IN6ADDRSZ, a++)
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED(a))
|
if (IN6_IS_ADDR_UNSPECIFIED(a))
|
||||||
@@ -351,7 +358,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
put_opt6_char(ICMP6_OPT_DNSSL);
|
put_opt6_char(ICMP6_OPT_DNSSL);
|
||||||
put_opt6_char(len + 1);
|
put_opt6_char(len + 1);
|
||||||
put_opt6_short(0);
|
put_opt6_short(0);
|
||||||
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
|
put_opt6_long(parm.adv_interval * 2); /* lifetime - twice RA retransmit */
|
||||||
put_opt6(opt_cfg->val, opt_cfg->len);
|
put_opt6(opt_cfg->val, opt_cfg->len);
|
||||||
|
|
||||||
/* pad */
|
/* pad */
|
||||||
@@ -366,7 +373,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
put_opt6_char(ICMP6_OPT_RDNSS);
|
put_opt6_char(ICMP6_OPT_RDNSS);
|
||||||
put_opt6_char(3);
|
put_opt6_char(3);
|
||||||
put_opt6_short(0);
|
put_opt6_short(0);
|
||||||
put_opt6_long(RA_INTERVAL * 2); /* lifetime - twice RA retransmit */
|
put_opt6_long(parm.adv_interval * 2); /* lifetime - twice RA retransmit */
|
||||||
put_opt6(&parm.link_global, IN6ADDRSZ);
|
put_opt6(&parm.link_global, IN6ADDRSZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,8 +462,8 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
if (time > context->lease_time)
|
if (time > context->lease_time)
|
||||||
{
|
{
|
||||||
time = context->lease_time;
|
time = context->lease_time;
|
||||||
if (time < ((unsigned int)(3 * RA_INTERVAL)))
|
if (time < ((unsigned int)(3 * param->adv_interval)))
|
||||||
time = 3 * RA_INTERVAL;
|
time = 3 * param->adv_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->flags & CONTEXT_DEPRECATE)
|
if (context->flags & CONTEXT_DEPRECATE)
|
||||||
@@ -564,7 +571,6 @@ time_t periodic_ra(time_t now)
|
|||||||
struct search_param param;
|
struct search_param param;
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
time_t next_event;
|
time_t next_event;
|
||||||
char interface[IF_NAMESIZE+1];
|
|
||||||
|
|
||||||
param.now = now;
|
param.now = now;
|
||||||
param.iface = 0;
|
param.iface = 0;
|
||||||
@@ -586,13 +592,15 @@ time_t periodic_ra(time_t now)
|
|||||||
if (!context)
|
if (!context)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((context->flags & CONTEXT_OLD) && context->if_index != 0)
|
if ((context->flags & CONTEXT_OLD) &&
|
||||||
|
context->if_index != 0 &&
|
||||||
|
indextoname(daemon->icmp6fd, param.iface, param.name))
|
||||||
{
|
{
|
||||||
/* A context for an old address. We'll not find the interface by
|
/* A context for an old address. We'll not find the interface by
|
||||||
looking for addresses, but we know it anyway, as long as we
|
looking for addresses, but we know it anyway, since the context is
|
||||||
sent at least one RA whilst the address was current. */
|
constructed */
|
||||||
param.iface = context->if_index;
|
param.iface = context->if_index;
|
||||||
new_timeout(context, now);
|
new_timeout(context, param.name, now);
|
||||||
}
|
}
|
||||||
else if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
else if (iface_enumerate(AF_INET6, ¶m, iface_search))
|
||||||
/* There's a context overdue, but we can't find an interface
|
/* There's a context overdue, but we can't find an interface
|
||||||
@@ -603,15 +611,14 @@ time_t periodic_ra(time_t now)
|
|||||||
context->ra_time = 0;
|
context->ra_time = 0;
|
||||||
|
|
||||||
if (param.iface != 0 &&
|
if (param.iface != 0 &&
|
||||||
indextoname(daemon->icmp6fd, param.iface, interface) &&
|
iface_check(AF_LOCAL, NULL, param.name, NULL))
|
||||||
iface_check(AF_LOCAL, NULL, interface, NULL))
|
|
||||||
{
|
{
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && wildcard_match(tmp->name, interface))
|
if (tmp->name && wildcard_match(tmp->name, param.name))
|
||||||
break;
|
break;
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
send_ra(now, param.iface, interface, NULL);
|
send_ra(now, param.iface, param.name, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return next_event;
|
return next_event;
|
||||||
@@ -643,7 +650,14 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
if (!(flags & IFACE_TENTATIVE))
|
if (!(flags & IFACE_TENTATIVE))
|
||||||
param->iface = if_index;
|
param->iface = if_index;
|
||||||
|
|
||||||
new_timeout(context, param->now);
|
/* should never fail */
|
||||||
|
if (!indextoname(daemon->icmp6fd, if_index, param->name))
|
||||||
|
{
|
||||||
|
param->iface = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_timeout(context, param->name, param->now);
|
||||||
|
|
||||||
/* zero timers for other contexts on the same subnet, so they don't timeout
|
/* zero timers for other contexts on the same subnet, so they don't timeout
|
||||||
independently */
|
independently */
|
||||||
@@ -659,14 +673,70 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
return 1; /* keep searching */
|
return 1; /* keep searching */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_timeout(struct dhcp_context *context, time_t now)
|
static void new_timeout(struct dhcp_context *context, char *iface_name, time_t now)
|
||||||
{
|
{
|
||||||
if (difftime(now, context->ra_short_period_start) < 60.0 || option_bool(OPT_FAST_RA))
|
if (difftime(now, context->ra_short_period_start) < 60.0)
|
||||||
/* range 5 - 20 */
|
/* range 5 - 20 */
|
||||||
context->ra_time = now + 5 + (rand16()/4400);
|
context->ra_time = now + 5 + (rand16()/4400);
|
||||||
else
|
else
|
||||||
/* range 3/4 - 1 times RA_INTERVAL */
|
{
|
||||||
context->ra_time = now + (3 * RA_INTERVAL)/4 + ((RA_INTERVAL * (unsigned int)rand16()) >> 18);
|
/* range 3/4 - 1 times MaxRtrAdvInterval */
|
||||||
|
unsigned int adv_interval = calc_interval(find_iface_param(iface_name));
|
||||||
|
context->ra_time = now + (3 * adv_interval)/4 + ((adv_interval * (unsigned int)rand16()) >> 18);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ra_interface *find_iface_param(char *iface)
|
||||||
|
{
|
||||||
|
struct ra_interface *ra;
|
||||||
|
|
||||||
|
for (ra = daemon->ra_interfaces; ra; ra = ra->next)
|
||||||
|
if (wildcard_match(ra->name, iface))
|
||||||
|
return ra;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int calc_interval(struct ra_interface *ra)
|
||||||
|
{
|
||||||
|
int interval = 600;
|
||||||
|
|
||||||
|
if (ra && ra->interval != 0)
|
||||||
|
{
|
||||||
|
interval = ra->interval;
|
||||||
|
if (interval > 1800)
|
||||||
|
interval = 1800;
|
||||||
|
else if (interval < 4)
|
||||||
|
interval = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int)interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int calc_lifetime(struct ra_interface *ra)
|
||||||
|
{
|
||||||
|
int lifetime, interval = (int)calc_interval(ra);
|
||||||
|
|
||||||
|
if (!ra || ra->lifetime == -1) /* not specified */
|
||||||
|
lifetime = 3 * interval;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lifetime = ra->lifetime;
|
||||||
|
if (lifetime < interval && lifetime != 0)
|
||||||
|
lifetime = interval;
|
||||||
|
else if (lifetime > 9000)
|
||||||
|
lifetime = 9000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int)lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int calc_prio(struct ra_interface *ra)
|
||||||
|
{
|
||||||
|
if (ra)
|
||||||
|
return ra->prio;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user