summaryrefslogtreecommitdiffstats
path: root/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2016-04-07 20:35:57 +0000
committerRoy Marples <roy@marples.name>2016-04-07 20:35:57 +0000
commitd306a8f2df27b629cac51cd6df648262046dcd20 (patch)
tree4260a01b6cd62f96c647a781b9cb1941c528f649 /if-bsd.c
parent0480237e31fb49330bc5d547e1bb863bb94b94d9 (diff)
downloaddhcpcd-d306a8f2df27b629cac51cd6df648262046dcd20.tar.xz
Linux netlink nlmsg_pid is not process id - only the first socket opened
has that. So after opening the link socket, open a persistent route socket and record the nlmsg_pid the kernel creates which is guaranteed unique and won't clash with a process id which can then be ignored by testing it directly and not that it's some large number.
Diffstat (limited to 'if-bsd.c')
-rw-r--r--if-bsd.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/if-bsd.c b/if-bsd.c
index aa7e89ae..eb988623 100644
--- a/if-bsd.c
+++ b/if-bsd.c
@@ -105,6 +105,10 @@
# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
#endif
+struct priv {
+ int pf_inet6_fd;
+};
+
int
if_init(__unused struct interface *iface)
{
@@ -120,10 +124,35 @@ if_conf(__unused struct interface *iface)
}
int
-if_openlinksocket(void)
+if_opensockets_os(struct dhcpcd_ctx *ctx)
+{
+ struct priv *priv;
+
+ if ((priv = malloc(sizeof(*priv))) == NULL)
+ return -1;
+ ctx->priv = priv;
+
+#ifdef INET6
+ priv->pf_inet6_fd = xsocket(PF_INET6, SOCK_DGRAM, 0, SOCK_CLOEXEC);
+ /* Don't return an error so we at least work on kernels witout INET6
+ * even though we expect INET6 support.
+ * We will fail noisily elsewhere anyway. */
+#else
+ priv->pf_inet6_fd = -1;
+#endif
+
+ ctx->pf_link_fd = xsocket(PF_LINK, SOCK_DGRAM, 0, SOCK_CLOEXEC);
+ return ctx->pf_link_fd == -1 ? -1 : 0;
+}
+
+void
+if_closesockets_os(struct dhcpcd_ctx *ctx)
{
+ struct priv *priv;
- return xsocket(PF_ROUTE, SOCK_RAW, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
+ priv = (struct priv *)ctx->priv;
+ if (priv->pf_inet6_fd != -1)
+ close(priv->pf_inet6_fd);
}
#if defined(INET) || defined(INET6)