NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/52554: IPv6 connections not routing to default gateway
On 03/10/2017 09:05, Roy Marples wrote:
> I appear as if by magic wearing my wizards robe and pointy hat!
>
> dhcpcd looks like it should be doing this correctly.
> https://roy.marples.name/git/dhcpcd.git/tree/src/ipv6nd.c#n506
OK, so it turned out there were quite a few issues with multiple routers
in dhcpcd-7 which I've fixed.
Here's a patch to fix them - it applies to dhcpcd-7.0.0-rc2, which is in
-current and pkgsrc-current.
It *might* apply to the version in NetBSD-8, but I'm not sure.
You could also take a copy of my git dhcpcd repo with these patches
already or download a tarball from my site and apply the attached patch:
git://roy.marples.name/dhcpcd.git
ftp://roy.marples.name/pub/dhcpcd/dhcpcd-7.0.0-rc2.tar.xz
Let me know how it works out for you!
Roy
diff --git a/src/ipv6nd.c b/src/ipv6nd.c
index 24b1cf55..4b2127ff 100644
--- a/src/ipv6nd.c
+++ b/src/ipv6nd.c
@@ -158,6 +158,10 @@ static void ipv6nd_handledata(void *);
#define IPV6_RECVPKTINFO IPV6_PKTINFO
#endif
+/* Handy defines */
+#define ipv6nd_free_ra(ra) ipv6nd_freedrop_ra((ra), 0)
+#define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra), 1)
+
void
ipv6nd_printoptions(const struct dhcpcd_ctx *ctx,
const struct dhcp_opt *opts, size_t opts_len)
@@ -448,14 +452,14 @@ ipv6nd_removefreedrop_ra(struct ra *rap, int remove_ra, int drop_ra)
eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap->iface);
eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap);
- if (remove_ra && !drop_ra)
+ if (remove_ra)
TAILQ_REMOVE(rap->iface->ctx->ra_routers, rap, next);
ipv6_freedrop_addrs(&rap->addrs, drop_ra, NULL);
free(rap->data);
free(rap);
}
-void
+static void
ipv6nd_freedrop_ra(struct ra *rap, int drop)
{
@@ -1396,27 +1400,20 @@ ipv6nd_expirera(void *arg)
void
ipv6nd_drop(struct interface *ifp)
{
- struct ra *rap;
+ struct ra *rap, *ran;
uint8_t expired = 0;
- TAILQ_HEAD(rahead, ra) rtrs;
if (ifp->ctx->ra_routers == NULL)
return;
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- TAILQ_INIT(&rtrs);
- TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
+ TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) {
if (rap->iface == ifp) {
rap->expired = expired = 1;
- TAILQ_REMOVE(ifp->ctx->ra_routers, rap, next);
- TAILQ_INSERT_TAIL(&rtrs, rap, next);
+ ipv6nd_drop_ra(rap);
}
}
if (expired) {
- while ((rap = TAILQ_FIRST(&rtrs))) {
- TAILQ_REMOVE(&rtrs, rap, next);
- ipv6nd_drop_ra(rap);
- }
rt_build(ifp->ctx, AF_INET6);
if ((ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP)
script_runreason(ifp, "ROUTERADVERT");
diff --git a/src/ipv6nd.h b/src/ipv6nd.h
index 6254760b..d49fd34c 100644
--- a/src/ipv6nd.h
+++ b/src/ipv6nd.h
@@ -93,9 +93,6 @@ const struct ipv6_addr *ipv6nd_iffindaddr(const struct interface *ifp,
const struct in6_addr *addr, unsigned int flags);
struct ipv6_addr *ipv6nd_findaddr(struct dhcpcd_ctx *,
const struct in6_addr *, unsigned int);
-void ipv6nd_freedrop_ra(struct ra *, int);
-#define ipv6nd_free_ra(ra) ipv6nd_freedrop_ra((ra), 0)
-#define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra), 1)
ssize_t ipv6nd_free(struct interface *);
void ipv6nd_expirera(void *arg);
int ipv6nd_hasra(const struct interface *);
diff --git a/src/route.c b/src/route.c
index 08ac7c05..29ca47eb 100644
--- a/src/route.c
+++ b/src/route.c
@@ -418,7 +418,7 @@ rt_cmp(const struct rt *r1, const struct rt *r2)
#ifdef HAVE_ROUTE_METRIC
r1->rt_metric == r2->rt_metric &&
#endif
- sa_cmp(&r1->rt_gateway, &r1->rt_gateway) == 0);
+ sa_cmp(&r1->rt_gateway, &r2->rt_gateway) == 0);
}
static bool
@@ -464,9 +464,6 @@ rt_build(struct dhcpcd_ctx *ctx, int af)
struct rt_head routes, added;
struct rt *rt, *rtn;
unsigned long long o;
-#ifdef INET6
- bool have_default = false;
-#endif
/* We need to have the interfaces in the correct order to ensure
* our routes are managed correctly. */
@@ -500,17 +497,10 @@ rt_build(struct dhcpcd_ctx *ctx, int af)
if (rt_doroute(rt)) {
TAILQ_REMOVE(&routes, rt, rt_next);
TAILQ_INSERT_TAIL(&added, rt, rt_next);
-#ifdef INET6
- if (sa_is_unspecified(&rt->rt_dest) &&
- sa_is_unspecified(&rt->rt_netmask))
- have_default = true;
-#endif
}
}
- /* Remove old routes we used to manage
- * If we own the default route, but not RA management itself
- * then we need to preserve the last best default route we had */
+ /* Remove old routes we used to manage. */
TAILQ_FOREACH_SAFE(rt, &ctx->routes, rt_next, rtn) {
if (rt->rt_dest.sa_family != af &&
rt->rt_gateway.sa_family != af)
@@ -520,16 +510,6 @@ rt_build(struct dhcpcd_ctx *ctx, int af)
o = rt->rt_ifp->options ?
rt->rt_ifp->options->options :
ctx->options;
-#ifdef INET6
- if (!have_default &&
- rt->rt_dest.sa_family == AF_INET6 &&
- sa_is_unspecified(&rt->rt_dest))
- have_default = true;
- /* no need to add it back to our routing table
- * as we delete an exiting route when we add
- * a new one */
- else
-#endif
if ((o &
(DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
(DHCPCD_EXITING | DHCPCD_PERSISTENT))
Home |
Main Index |
Thread Index |
Old Index