summaryrefslogtreecommitdiffstats
path: root/src/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2018-02-02 11:24:58 +0000
committerRoy Marples <roy@marples.name>2018-02-02 11:24:58 +0000
commit8f483d192082a953dd035f38ee4555735106f1fc (patch)
treec88603ef9b0e5c2b04dcf0c820af0f6b77c92dcb /src/if-bsd.c
parentad85ee61b6205daa07452e8504492385411a4e65 (diff)
downloaddhcpcd-8f483d192082a953dd035f38ee4555735106f1fc.tar.xz
inet6: simplify setup of kernel
Rename if_checkipv6 to if_setup_inet6 so it's more descriptive. simpify code as we don't really care about the result. Restore the prior behavior of not disabling kernel RA handling if dhcpcd is not doing it.
Diffstat (limited to 'src/if-bsd.c')
-rw-r--r--src/if-bsd.c193
1 files changed, 79 insertions, 114 deletions
diff --git a/src/if-bsd.c b/src/if-bsd.c
index 6ec9e12b..26d75df9 100644
--- a/src/if-bsd.c
+++ b/src/if-bsd.c
@@ -1248,7 +1248,7 @@ if_machinearch(char *str, size_t len)
}
#ifdef INET6
-#ifdef IPV6CTL_ACCEPT_RTADV
+#if defined(IPV6CTL_ACCEPT_RTADV) && !defined(ND6_IFF_ACCEPT_RTADV)
#define get_inet6_sysctl(code) inet6_sysctl(code, 0, 0)
#define set_inet6_sysctl(code, val) inet6_sysctl(code, val, 1)
static int
@@ -1273,6 +1273,7 @@ inet6_sysctl(int code, int val, int action)
#ifdef IPV6_MANAGETEMPADDR
#ifndef IPV6CTL_TEMPVLTIME
+
#define get_inet6_sysctlbyname(code) inet6_sysctlbyname(code, 0, 0)
#define set_inet6_sysctlbyname(code, val) inet6_sysctlbyname(code, val, 1)
static int
@@ -1358,21 +1359,24 @@ set_ifxflags(int s, const struct interface *ifp)
#ifdef IFXF_NOINET6
flags &= ~IFXF_NOINET6;
#endif
- if (!(ifp->ctx->options & DHCPCD_TEST))
+ /*
+ * If dhcpcd is doing RS, disable RA support
+ * in the kernel. Otherwise, leave it alone.
+ * Logically it should be disabled regardless as dhcpcd can
+ * do it better and the user saying no RS means no RS even the kernel,
+ * but some crazy people want the kernel to do it still.
+ */
+ if (ifp->options->options & DHCPCD_IPV6RS)
flags &= ~IFXF_AUTOCONF6;
if (ifr.ifr_flags == flags)
return 0;
- if (ifp->ctx->options & DHCPCD_TEST) {
- errno = EPERM;
- return -1;
- }
ifr.ifr_flags = flags;
return ioctl(s, SIOCSIFXFLAGS, (void *)&ifr);
}
#endif
/* OpenBSD removed ND6 flags entirely, so we need to check for their
- * existnance. */
+ * existance. */
#if defined(ND6_IFF_AUTO_LINKLOCAL) || \
defined(ND6_IFF_PERFORMNUD) || \
defined(ND6_IFF_ACCEPT_RTADV) || \
@@ -1381,147 +1385,108 @@ set_ifxflags(int s, const struct interface *ifp)
#define ND6_NDI_FLAGS
#endif
-int
-if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp)
+void
+if_setup_inet6(const struct interface *ifp)
{
struct priv *priv;
- int s, ra;
+ int s;
+#ifdef ND6_NDI_FLAGS
+ struct in6_ndireq nd;
+ int flags;
+#endif
- priv = (struct priv *)ctx->priv;
+ priv = (struct priv *)ifp->ctx->priv;
s = priv->pf_inet6_fd;
- if (ifp) {
#ifdef ND6_NDI_FLAGS
- struct in6_ndireq nd;
- int flags;
-
- memset(&nd, 0, sizeof(nd));
- strlcpy(nd.ifname, ifp->name, sizeof(nd.ifname));
- if (ioctl(s, SIOCGIFINFO_IN6, &nd) == -1)
- return -1;
- flags = (int)nd.ndi.flags;
+ memset(&nd, 0, sizeof(nd));
+ strlcpy(nd.ifname, ifp->name, sizeof(nd.ifname));
+ if (ioctl(s, SIOCGIFINFO_IN6, &nd) == -1)
+ logerr("%s: SIOCGIFINFO_FLAGS", ifp->name);
+ flags = (int)nd.ndi.flags;
#endif
#ifdef ND6_IFF_AUTO_LINKLOCAL
- if (!(ctx->options & DHCPCD_TEST) &&
- flags & ND6_IFF_AUTO_LINKLOCAL)
- {
- logdebugx("%s: disabling Kernel IPv6 auto "
- "link-local support",
- ifp->name);
- flags &= ~ND6_IFF_AUTO_LINKLOCAL;
- }
+ /* Unlike the kernel,
+ * dhcpcd make make a stable private address. */
+ flags &= ~ND6_IFF_AUTO_LINKLOCAL;
#endif
#ifdef ND6_IFF_PERFORMNUD
- if ((flags & ND6_IFF_PERFORMNUD) == 0) {
- /* NUD is kind of essential. */
- flags |= ND6_IFF_PERFORMNUD;
- }
+ /* NUD is kind of essential. */
+ flags |= ND6_IFF_PERFORMNUD;
#endif
+#ifdef ND6_IFF_IFDISABLED
+ /* Ensure the interface is not disabled. */
+ flags &= ~ND6_IFF_IFDISABLED;
+#endif
+
+ /*
+ * If dhcpcd is doing RS, disable RA support
+ * in the kernel. Otherwise, leave it alone.
+ * Logically it should be disabled regardless as dhcpcd can
+ * do it better and the user saying no RS means no RS even the kernel,
+ * but some crazy people want the kernel to do it still.
+ */
#ifdef ND6_IFF_ACCEPT_RTADV
- if (!(ctx->options & DHCPCD_TEST) &&
- flags & ND6_IFF_ACCEPT_RTADV)
- {
- logdebugx("%s: disabling Kernel IPv6 RA support",
- ifp->name);
- flags &= ~ND6_IFF_ACCEPT_RTADV;
- }
+ if (ifp->options->options & DHCPCD_IPV6RS)
+ flags &= ~ND6_IFF_ACCEPT_RTADV;
#ifdef ND6_IFF_OVERRIDE_RTADV
- if (!(ctx->options & DHCPCD_TEST) &&
- flags & ND6_IFF_OVERRIDE_RTADV)
- flags &= ~ND6_IFF_OVERRIDE_RTADV;
+ if (ifp->options->options & DHCPCD_IPV6RS)
+ flags |= ND6_IFF_OVERRIDE_RTADV;
#endif
#endif
-#ifdef ND6_IFF_IFDISABLED
- flags &= ~ND6_IFF_IFDISABLED;
-#endif
-
#ifdef ND6_NDI_FLAGS
- if (nd.ndi.flags != (uint32_t)flags) {
- if (ctx->options & DHCPCD_TEST) {
- logwarnx("%s: interface not IPv6 enabled",
- ifp->name);
- return -1;
- }
- nd.ndi.flags = (uint32_t)flags;
- if (ioctl(s, SIOCSIFINFO_FLAGS, &nd) == -1) {
- logerr("%s: SIOCSIFINFO_FLAGS", ifp->name);
- return -1;
- }
- }
+ if (nd.ndi.flags != (uint32_t)flags) {
+ nd.ndi.flags = (uint32_t)flags;
+ if (ioctl(s, SIOCSIFINFO_FLAGS, &nd) == -1)
+ logerr("%s: SIOCSIFINFO_FLAGS", ifp->name);
+ }
#endif
- /* Enabling IPv6 by whatever means must be the
- * last action undertaken to ensure kernel RS and
- * LLADDR auto configuration are disabled where applicable. */
+ /* Enabling IPv6 by whatever means must be the
+ * last action undertaken to ensure kernel RS and
+ * LLADDR auto configuration are disabled where applicable. */
#ifdef SIOCIFAFATTACH
- if (af_attach(s, ifp, AF_INET6) == -1) {
- logerr("%s: af_attach", ifp->name);
- return -1;
- }
+ if (af_attach(s, ifp, AF_INET6) == -1)
+ logerr("%s: af_attach", ifp->name);
#endif
#ifdef SIOCGIFXFLAGS
- if (set_ifxflags(s, ifp) == -1) {
- logerr("%s: set_ifxflags", ifp->name);
- return -1;
- }
+ if (set_ifxflags(s, ifp) == -1)
+ logerr("%s: set_ifxflags", ifp->name);
#endif
-#ifdef ND6_IFF_ACCEPT_RTADV
-#ifdef ND6_IFF_OVERRIDE_RTADV
- switch (flags & (ND6_IFF_ACCEPT_RTADV|ND6_IFF_OVERRIDE_RTADV)) {
- case (ND6_IFF_ACCEPT_RTADV|ND6_IFF_OVERRIDE_RTADV):
- return 1;
- case ND6_IFF_ACCEPT_RTADV:
- return ctx->ra_global;
- default:
- return 0;
- }
-#else
- return flags & ND6_IFF_ACCEPT_RTADV ? 1 : 0;
-#endif
-#else
- return ctx->ra_global;
-#endif
- }
+#if defined(IPV6CTL_ACCEPT_RTADV) && !defined(ND6_IFF_ACCEPT_RTADV)
+ /* If we cannot control ra per interface, disable it globally. */
+ if (ifp->options->options & DHCPCD_IPV6RS) {
+ int ra = get_inet6_sysctl(IPV6CTL_ACCEPT_RTADV);
-#ifdef IPV6CTL_ACCEPT_RTADV
- ra = get_inet6_sysctl(IPV6CTL_ACCEPT_RTADV);
- if (ra == -1)
- if (errno == ENOENT)
- ra = 0;
- else
- logerr("IPV6CTL_ACCEPT_RTADV");
- else if (ra != 0 && !(ctx->options & DHCPCD_TEST)) {
- logdebugx("disabling Kernel IPv6 RA support");
- if (set_inet6_sysctl(IPV6CTL_ACCEPT_RTADV, 0) == -1) {
- logerr("IPV6CTL_ACCEPT_RTADV");
- return ra;
+ if (ra == -1) {
+ if (errno != ENOENT)
+ logerr("IPV6CTL_ACCEPT_RTADV");
+ else if (ra != 0)
+ if (set_inet6_sysctl(IPV6CTL_ACCEPT_RTADV, 0) == -1)
+ logerr("IPV6CTL_ACCEPT_RTADV");
}
- ra = 0;
-#else
- ra = 0;
- if (!(ctx->options & DHCPCD_TEST)) {
+ }
#endif
-#if defined(IPV6CTL_ACCEPT_RTADV) || defined(ND6_IFF_ACCEPT_RTADV)
- /* Flush the kernel knowledge of advertised routers
- * and prefixes so the kernel does not expire prefixes
- * and default routes we are trying to own. */
- char dummy[IFNAMSIZ + 8];
- strlcpy(dummy, "lo0", sizeof(dummy));
- if (ioctl(s, SIOCSRTRFLUSH_IN6, (void *)&dummy) == -1)
+#if defined(IPV6CTL_ACCEPT_RTADV) || defined(ND6_IFF_ACCEPT_RTADV)
+ /* Flush the kernel knowledge of advertised routers
+ * and prefixes so the kernel does not expire prefixes
+ * and default routes we are trying to own. */
+ if (ifp->options->options & DHCPCD_IPV6RS) {
+ char ifname[IFNAMSIZ + 8];
+
+ strlcpy(ifname, ifp->name, sizeof(ifname));
+ if (ioctl(s, SIOCSRTRFLUSH_IN6, (void *)&ifname) == -1)
logwarn("SIOCSRTRFLUSH_IN6");
- if (ioctl(s, SIOCSPFXFLUSH_IN6, (void *)&dummy) == -1)
+ if (ioctl(s, SIOCSPFXFLUSH_IN6, (void *)&ifname) == -1)
logwarn("SIOCSPFXFLUSH_IN6");
-#endif
}
-
- ctx->ra_global = ra;
- return ra;
+#endif
}
#endif