Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
ef1a94ab
Commit
ef1a94ab
authored
Jul 26, 2013
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Advertise lost prefixes with pref_time == 0 for 2 hours.
parent
d9fb0be8
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
154 additions
and
49 deletions
+154
-49
CHANGELOG
CHANGELOG
+8
-0
src/dhcp-common.c
src/dhcp-common.c
+5
-4
src/dhcp6.c
src/dhcp6.c
+39
-17
src/dnsmasq.h
src/dnsmasq.h
+4
-2
src/radv.c
src/radv.c
+93
-23
src/rfc3315.c
src/rfc3315.c
+1
-1
src/slaac.c
src/slaac.c
+4
-2
No files found.
CHANGELOG
View file @
ef1a94ab
...
...
@@ -71,6 +71,14 @@ version 2.67
Make --clear-on-reload apply to setting upstream servers
via DBus too.
When the address which triggered the construction of an
advertised IPv6 prefix disappears, continue to advertise
the prefix for up to 2 hours, with the preferred lifetime
set to zero. This satisfies RFC 6204 4.3 L-13 and makes
things work better if a prefix disappears without being
deprecated first. Thanks to Uwe Schindler for persuasively
arguing for this.
version 2.66
Add the ability to act as an authoritative DNS
...
...
src/dhcp-common.c
View file @
ef1a94ab
...
...
@@ -720,7 +720,7 @@ void log_context(int family, struct dhcp_context *context)
p
+=
sprintf
(
p
,
", "
);
if
(
indextoname
(
daemon
->
doing_dhcp6
?
daemon
->
dhcp6fd
:
daemon
->
icmp6fd
,
context
->
if_index
,
ifrn_name
))
sprintf
(
p
,
"
constructed for %s
"
,
ifrn_name
);
sprintf
(
p
,
"
%s for %s"
,
(
context
->
flags
&
CONTEXT_OLD
)
?
"old prefix"
:
"constructed
"
,
ifrn_name
);
}
else
if
(
context
->
flags
&
CONTEXT_TEMPLATE
)
{
...
...
@@ -731,7 +731,8 @@ void log_context(int family, struct dhcp_context *context)
}
#endif
if
((
context
->
flags
&
CONTEXT_DHCP
)
||
family
==
AF_INET
)
if
(
!
(
context
->
flags
&
CONTEXT_OLD
)
&&
((
context
->
flags
&
CONTEXT_DHCP
)
||
family
==
AF_INET
))
{
inet_ntop
(
family
,
start
,
daemon
->
dhcp_buff
,
256
);
inet_ntop
(
family
,
end
,
daemon
->
dhcp_buff3
,
256
);
...
...
@@ -748,9 +749,9 @@ void log_context(int family, struct dhcp_context *context)
}
#ifdef HAVE_DHCP6
if
(
context
->
flags
&
CONTEXT_RA_NAME
)
if
(
(
context
->
flags
&
CONTEXT_RA_NAME
)
&&
!
(
context
->
flags
&
CONTEXT_OLD
)
)
my_syslog
(
MS_DHCP
|
LOG_INFO
,
_
(
"DHCPv4-derived IPv6 names on %s%s"
),
daemon
->
addrbuff
,
template
);
if
((
context
->
flags
&
CONTEXT_RA
)
||
(
option_bool
(
OPT_RA
)
&&
(
context
->
flags
&
CONTEXT_DHCP
)
&&
family
==
AF_INET6
))
my_syslog
(
MS_DHCP
|
LOG_INFO
,
_
(
"router advertisement on %s%s"
),
daemon
->
addrbuff
,
template
);
#endif
...
...
src/dhcp6.c
View file @
ef1a94ab
...
...
@@ -220,7 +220,7 @@ static int complete_context6(struct in6_addr *local, int prefix,
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
{
if
((
context
->
flags
&
CONTEXT_DHCP
)
&&
!
(
context
->
flags
&
CONTEXT_TEMPLATE
)
&&
!
(
context
->
flags
&
(
CONTEXT_TEMPLATE
|
CONTEXT_OLD
)
)
&&
prefix
==
context
->
prefix
&&
is_same_net6
(
local
,
&
context
->
start6
,
prefix
)
&&
is_same_net6
(
local
,
&
context
->
end6
,
prefix
))
...
...
@@ -552,7 +552,10 @@ static int construct_worker(struct in6_addr *local, int prefix,
IN6_ARE_ADDR_EQUAL
(
&
start6
,
&
context
->
start6
)
&&
IN6_ARE_ADDR_EQUAL
(
&
end6
,
&
context
->
end6
))
{
context
->
flags
&=
~
CONTEXT_GC
;
int
flags
=
context
->
flags
;
context
->
flags
&=
~
(
CONTEXT_GC
|
CONTEXT_OLD
);
if
(
flags
&
CONTEXT_OLD
)
log_context
(
AF_INET6
,
context
);
break
;
}
...
...
@@ -565,6 +568,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
context
->
flags
|=
CONTEXT_CONSTRUCTED
;
context
->
if_index
=
if_index
;
context
->
local6
=
*
local
;
context
->
saved_valid
=
0
;
context
->
next
=
daemon
->
dhcp6
;
daemon
->
dhcp6
=
context
;
...
...
@@ -587,35 +591,53 @@ static int construct_worker(struct in6_addr *local, int prefix,
void
dhcp_construct_contexts
(
time_t
now
)
{
struct
dhcp_context
*
tmp
,
*
context
,
**
up
;
struct
dhcp_context
*
context
,
*
tmp
,
**
up
;
struct
cparam
param
;
param
.
newone
=
0
;
param
.
newname
=
0
;
param
.
now
=
now
;
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
{
context
->
if_index
=
0
;
if
(
context
->
flags
&
CONTEXT_CONSTRUCTED
)
context
->
flags
|=
CONTEXT_GC
;
}
if
(
context
->
flags
&
CONTEXT_CONSTRUCTED
)
context
->
flags
|=
CONTEXT_GC
;
iface_enumerate
(
AF_INET6
,
&
param
,
construct_worker
);
for
(
up
=
&
daemon
->
dhcp6
,
context
=
daemon
->
dhcp6
;
context
;
context
=
tmp
)
{
tmp
=
context
->
next
;
if
(
context
->
flags
&
CONTEXT_GC
)
tmp
=
context
->
next
;
if
(
context
->
flags
&
CONTEXT_GC
&&
!
(
context
->
flags
&
CONTEXT_OLD
))
{
*
up
=
context
->
next
;
param
.
newone
=
1
;
/* include deletion */
if
(
context
->
flags
&
CONTEXT_RA_NAME
)
param
.
newname
=
1
;
free
(
context
);
if
((
context
->
flags
&
(
CONTEXT_RA_ONLY
|
CONTEXT_RA_NAME
|
CONTEXT_RA_STATELESS
))
||
option_bool
(
OPT_RA
))
{
/* previously constructed context has gone. advertise it's demise */
context
->
flags
|=
CONTEXT_OLD
;
context
->
address_lost_time
=
now
;
if
(
context
->
saved_valid
>
7200
)
/* 2 hours */
context
->
saved_valid
=
7200
;
ra_start_unsolicted
(
now
,
context
);
param
.
newone
=
1
;
/* include deletion */
if
(
context
->
flags
&
CONTEXT_RA_NAME
)
param
.
newname
=
1
;
log_context
(
AF_INET6
,
context
);
up
=
&
context
->
next
;
}
else
{
/* we were never doing RA for this, so free now */
*
up
=
context
->
next
;
free
(
context
);
}
}
else
up
=
&
context
->
next
;
up
=
&
context
->
next
;
}
if
(
param
.
newone
)
...
...
src/dnsmasq.h
View file @
ef1a94ab
...
...
@@ -706,8 +706,8 @@ struct dhcp_context {
struct
in6_addr
start6
,
end6
;
/* range of available addresses */
struct
in6_addr
local6
;
int
prefix
,
if_index
;
unsigned
int
valid
,
preferred
;
time_t
ra_time
,
ra_short_period_start
;
unsigned
int
valid
,
preferred
,
saved_valid
;
time_t
ra_time
,
ra_short_period_start
,
address_lost_time
;
char
*
template_interface
;
#endif
int
flags
;
...
...
@@ -732,6 +732,8 @@ struct dhcp_context {
#define CONTEXT_CONF_USED 16384
#define CONTEXT_USED 32768
#define CONTEXT_NOAUTH 65536
#define CONTEXT_OLD 131072
struct
ping_result
{
struct
in_addr
addr
;
...
...
src/radv.c
View file @
ef1a94ab
...
...
@@ -47,6 +47,7 @@ static int iface_search(struct in6_addr *local, int prefix,
int
scope
,
int
if_index
,
int
flags
,
int
prefered
,
int
valid
,
void
*
vparam
);
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
int
hop_limit
;
...
...
@@ -187,9 +188,8 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
{
struct
ra_packet
*
ra
;
struct
ra_param
parm
;
struct
ifreq
ifr
;
struct
sockaddr_in6
addr
;
struct
dhcp_context
*
context
;
struct
dhcp_context
*
context
,
*
tmp
,
**
up
;
struct
dhcp_netid
iface_id
;
struct
dhcp_opt
*
opt_cfg
;
int
done_dns
=
0
;
...
...
@@ -228,12 +228,66 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
context
->
netid
.
next
=
&
context
->
netid
;
}
if
(
!
iface_enumerate
(
AF_INET6
,
&
parm
,
add_prefixes
)
||
!
parm
.
found_context
)
if
(
!
iface_enumerate
(
AF_INET6
,
&
parm
,
add_prefixes
))
return
;
strncpy
(
ifr
.
ifr_name
,
iface_name
,
IF_NAMESIZE
);
/* Look for constructed contexts associated with addresses which have gone,
and advertise them with preferred_time == 0 RFC 6204 4.3 L-13 */
for
(
up
=
&
daemon
->
dhcp6
,
context
=
daemon
->
dhcp6
;
context
;
context
=
tmp
)
{
tmp
=
context
->
next
;
if
(
context
->
if_index
==
iface
&&
(
context
->
flags
&
CONTEXT_OLD
))
{
unsigned
int
old
=
difftime
(
now
,
context
->
address_lost_time
);
if
(
old
>
context
->
saved_valid
)
{
/* We've advertised this enough, time to go */
*
up
=
context
->
next
;
free
(
context
);
}
else
{
struct
prefix_opt
*
opt
;
struct
in6_addr
local
=
context
->
start6
;
int
do_slaac
=
0
;
parm
.
found_context
=
1
;
/* zero net part of address */
setaddr6part
(
&
local
,
addr6part
(
&
local
)
&
~
((
context
->
prefix
==
64
)
?
(
u64
)
-
1LL
:
(
1LLU
<<
(
128
-
context
->
prefix
))
-
1LLU
));
if
((
context
->
flags
&
(
CONTEXT_RA_ONLY
|
CONTEXT_RA_NAME
|
CONTEXT_RA_STATELESS
)))
do_slaac
=
1
;
if
((
opt
=
expand
(
sizeof
(
struct
prefix_opt
))))
{
opt
->
type
=
ICMP6_OPT_PREFIX
;
opt
->
len
=
4
;
opt
->
prefix_len
=
context
->
prefix
;
/* autonomous only if we're not doing dhcp, always set "on-link" */
opt
->
flags
=
do_slaac
?
0xC0
:
0x80
;
opt
->
valid_lifetime
=
htonl
(
context
->
saved_valid
-
old
);
opt
->
preferred_lifetime
=
htonl
(
0
);
opt
->
reserved
=
0
;
opt
->
prefix
=
local
;
inet_ntop
(
AF_INET6
,
&
local
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
my_syslog
(
MS_DHCP
|
LOG_INFO
,
"RTR-ADVERT(%s) %s old prefix"
,
iface_name
,
daemon
->
addrbuff
);
}
up
=
&
context
->
next
;
}
}
else
up
=
&
context
->
next
;
}
if
(
!
parm
.
found_context
)
return
;
#ifdef HAVE_LINUX_NETWORK
/* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
available from SIOCGIFMTU */
...
...
@@ -361,11 +415,13 @@ static int add_prefixes(struct in6_addr *local, int prefix,
struct
dhcp_context
*
context
;
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
if
(
!
(
context
->
flags
&
CONTEXT_TEMPLATE
)
&&
if
(
!
(
context
->
flags
&
(
CONTEXT_TEMPLATE
|
CONTEXT_OLD
)
)
&&
prefix
==
context
->
prefix
&&
is_same_net6
(
local
,
&
context
->
start6
,
prefix
)
&&
is_same_net6
(
local
,
&
context
->
end6
,
prefix
))
{
context
->
saved_valid
=
valid
;
if
((
context
->
flags
&
(
CONTEXT_RA_ONLY
|
CONTEXT_RA_NAME
|
CONTEXT_RA_STATELESS
)))
{
...
...
@@ -466,6 +522,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
inet_ntop
(
AF_INET6
,
local
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
my_syslog
(
MS_DHCP
|
LOG_INFO
,
"RTR-ADVERT(%s) %s"
,
param
->
if_name
,
daemon
->
addrbuff
);
}
}
}
}
...
...
@@ -520,16 +577,25 @@ time_t periodic_ra(time_t now)
if
(
!
context
)
break
;
/* There's a context overdue, but we can't find an interface
associated with it, because it's for a subnet we dont
have an interface on. Probably we're doing DHCP on
a remote subnet via a relay. Zero the timer, since we won't
ever be able to send ra's and satistfy it. */
if
(
iface_enumerate
(
AF_INET6
,
&
param
,
iface_search
))
if
((
context
->
flags
&
CONTEXT_OLD
)
&&
context
->
if_index
!=
0
)
{
/* 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
sent at least one RA whilst the address was current. */
param
.
iface
=
context
->
if_index
;
new_timeout
(
context
,
now
);
}
else
if
(
iface_enumerate
(
AF_INET6
,
&
param
,
iface_search
))
/* There's a context overdue, but we can't find an interface
associated with it, because it's for a subnet we dont
have an interface on. Probably we're doing DHCP on
a remote subnet via a relay. Zero the timer, since we won't
ever be able to send ra's and satistfy it. */
context
->
ra_time
=
0
;
else
if
(
param
.
iface
!=
0
&&
indextoname
(
daemon
->
icmp6fd
,
param
.
iface
,
interface
)
&&
iface_check
(
AF_LOCAL
,
NULL
,
interface
,
NULL
))
if
(
param
.
iface
!=
0
&&
indextoname
(
daemon
->
icmp6fd
,
param
.
iface
,
interface
)
&&
iface_check
(
AF_LOCAL
,
NULL
,
interface
,
NULL
))
{
struct
iname
*
tmp
;
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
...
...
@@ -554,7 +620,7 @@ static int iface_search(struct in6_addr *local, int prefix,
(
void
)
valid
;
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
if
(
!
(
context
->
flags
&
CONTEXT_TEMPLATE
)
&&
if
(
!
(
context
->
flags
&
(
CONTEXT_TEMPLATE
|
CONTEXT_OLD
)
)
&&
prefix
==
context
->
prefix
&&
is_same_net6
(
local
,
&
context
->
start6
,
prefix
)
&&
is_same_net6
(
local
,
&
context
->
end6
,
prefix
)
&&
...
...
@@ -568,12 +634,7 @@ static int iface_search(struct in6_addr *local, int prefix,
if
(
!
(
flags
&
IFACE_TENTATIVE
))
param
->
iface
=
if_index
;
if
(
difftime
(
param
->
now
,
context
->
ra_short_period_start
)
<
60
.
0
)
/* range 5 - 20 */
context
->
ra_time
=
param
->
now
+
5
+
(
rand16
()
/
4400
);
else
/* range 3/4 - 1 times RA_INTERVAL */
context
->
ra_time
=
param
->
now
+
(
3
*
RA_INTERVAL
)
/
4
+
((
RA_INTERVAL
*
(
unsigned
int
)
rand16
())
>>
18
);
new_timeout
(
context
,
param
->
now
);
/* zero timers for other contexts on the same subnet, so they don't timeout
independently */
...
...
@@ -588,6 +649,15 @@ static int iface_search(struct in6_addr *local, int prefix,
return
1
;
/* keep searching */
}
static
void
new_timeout
(
struct
dhcp_context
*
context
,
time_t
now
)
{
if
(
difftime
(
now
,
context
->
ra_short_period_start
)
<
60
.
0
)
/* range 5 - 20 */
context
->
ra_time
=
now
+
5
+
(
rand16
()
/
4400
);
else
/* range 3/4 - 1 times RA_INTERVAL */
context
->
ra_time
=
now
+
(
3
*
RA_INTERVAL
)
/
4
+
((
RA_INTERVAL
*
(
unsigned
int
)
rand16
())
>>
18
);
}
#endif
src/rfc3315.c
View file @
ef1a94ab
...
...
@@ -120,7 +120,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
!
IN6_IS_ADDR_MULTICAST
(
link_address
))
for
(
c
=
daemon
->
dhcp6
;
c
;
c
=
c
->
next
)
if
((
c
->
flags
&
CONTEXT_DHCP
)
&&
!
(
c
->
flags
&
CONTEXT_TEMPLATE
)
&&
!
(
c
->
flags
&
(
CONTEXT_TEMPLATE
|
CONTEXT_OLD
)
)
&&
is_same_net6
(
link_address
,
&
c
->
start6
,
c
->
prefix
)
&&
is_same_net6
(
link_address
,
&
c
->
end6
,
c
->
prefix
))
{
...
...
src/slaac.c
View file @
ef1a94ab
...
...
@@ -38,7 +38,9 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
lease
->
slaac_address
=
NULL
;
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
if
((
context
->
flags
&
CONTEXT_RA_NAME
)
&&
lease
->
last_interface
==
context
->
if_index
)
if
((
context
->
flags
&
CONTEXT_RA_NAME
)
&&
!
(
context
->
flags
&
CONTEXT_OLD
)
&&
lease
->
last_interface
==
context
->
if_index
)
{
struct
in6_addr
addr
=
context
->
start6
;
if
(
lease
->
hwaddr_len
==
6
&&
...
...
@@ -123,7 +125,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
time_t
next_event
=
0
;
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
if
((
context
->
flags
&
CONTEXT_RA_NAME
))
if
((
context
->
flags
&
CONTEXT_RA_NAME
)
&&
!
(
context
->
flags
&
CONTEXT_OLD
)
)
break
;
/* nothing configured */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment