summaryrefslogtreecommitdiffstats
path: root/ipv6.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2013-05-21 09:24:49 +0000
committerRoy Marples <roy@marples.name>2013-05-21 09:24:49 +0000
commit99d2575328ed914f44dda510a35ff22044356263 (patch)
tree9db115c649b5c053f7111405143877579fb4609c /ipv6.c
parente5b9d6028161a580674241e82db0d5a99a69276d (diff)
downloaddhcpcd-99d2575328ed914f44dda510a35ff22044356263.tar.xz
Don't actually remove unreachable routers and prefixes from the routing table.
Instead we just change the interface if they are reachable via another one.
Diffstat (limited to 'ipv6.c')
-rw-r--r--ipv6.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/ipv6.c b/ipv6.c
index 9fb159ea..cae5c96f 100644
--- a/ipv6.c
+++ b/ipv6.c
@@ -641,12 +641,36 @@ ipv6_removesubnet(const struct interface *ifp, struct ipv6_addr *addr)
(IN6_ARE_ADDR_EQUAL(&((rtp)->dest), &in6addr_any) && \
IN6_ARE_ADDR_EQUAL(&((rtp)->net), &in6addr_any))
+static void
+ipv6_buildroutes1(struct rt6head *dnr, int expired)
+{
+ struct rt6 *rt;
+ struct ra *rap;
+ struct ipv6_addr *addr;
+
+ TAILQ_FOREACH(rap, &ipv6_routers, next) {
+ if (rap->expired != expired)
+ continue;
+ if (options & DHCPCD_IPV6RA_OWN) {
+ TAILQ_FOREACH(addr, &rap->addrs, next) {
+ if (!addr->onlink)
+ continue;
+ rt = make_prefix(rap->iface, rap, addr);
+ if (rt)
+ TAILQ_INSERT_TAIL(dnr, rt, next);
+ }
+ }
+ rt = make_router(rap);
+ if (rt)
+ TAILQ_INSERT_TAIL(dnr, rt, next);
+ }
+}
+
void
ipv6_buildroutes(void)
{
struct rt6head dnr, *nrs;
struct rt6 *rt, *rtn, *or;
- struct ra *rap;
struct ipv6_addr *addr;
const struct interface *ifp;
const struct dhcp6_state *d6_state;
@@ -656,6 +680,12 @@ ipv6_buildroutes(void)
return;
TAILQ_INIT(&dnr);
+
+ /* First add reachable routers and their prefixes */
+ ipv6_buildroutes1(&dnr, 0);
+
+ /* We have no way of knowing if prefixes added by DHCP are reachable
+ * or not, so we have to assume they are */
TAILQ_FOREACH(ifp, ifaces, next) {
d6_state = D6_CSTATE(ifp);
if (d6_state &&
@@ -671,22 +701,11 @@ ipv6_buildroutes(void)
}
}
}
- TAILQ_FOREACH(rap, &ipv6_routers, next) {
- if (options & DHCPCD_IPV6RA_OWN) {
- TAILQ_FOREACH(addr, &rap->addrs, next) {
- if (!addr->onlink)
- continue;
- rt = make_prefix(rap->iface, rap, addr);
- if (rt)
- TAILQ_INSERT_TAIL(&dnr, rt, next);
- }
- }
- if (!rap->expired) {
- rt = make_router(rap);
- if (rt)
- TAILQ_INSERT_TAIL(&dnr, rt, next);
- }
- }
+
+ /* Add our non-reachable routers and prefixes
+ * Unsure if this is needed, but it's a close match to kernel
+ * behaviour */
+ ipv6_buildroutes1(&dnr, 1);
nrs = malloc(sizeof(*nrs));
if (nrs == NULL) {