]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add Linux support to:
authorMark Andrews <marka@isc.org>
Sun, 9 Feb 2014 22:46:54 +0000 (09:46 +1100)
committerMark Andrews <marka@isc.org>
Sun, 9 Feb 2014 22:46:54 +0000 (09:46 +1100)
3733.   [func]          Improve interface scanning support.  Interface
                        information will be automatically updated if the
                        OS supports routing sockets (MacOS, *BSD, Linux).
                        Use "automatic-interface-scan no;" to disable.

                        Add "rndc scan" to trigger a scan. [RT #23027]

CHANGES
bin/named/interfacemgr.c
config.h.in
configure
configure.in
lib/isc/unix/socket.c

diff --git a/CHANGES b/CHANGES
index 9a243740ff87333bfe3b1749d634ea0939ace9c7..e06ed87a43852b3aa11ba55e212ffac093a77f35 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,7 @@
 3733.  [func]          Improve interface scanning support.  Interface
                        information will be automatically updated if the
-                       OS supports routing sockets.  Use
-                       "automatic-interface-scan no;" to disable.
+                       OS supports routing sockets (MacOS, *BSD, Linux).
+                       Use "automatic-interface-scan no;" to disable.
 
                        Add "rndc scan" to trigger a scan. [RT #23027]
 
index 435200662f730a3775fe4889fe565ff67391caef..2dece8e6332862193f2c5c5869c70fa27110ef8b 100644 (file)
 #include <net/route.h>
 #if defined(RTM_VERSION) && defined(RTM_NEWADDR) && defined(RTM_DELADDR)
 #define USE_ROUTE_SOCKET 1
+#define ROUTE_SOCKET_PROTOCOL PF_ROUTE
+#define MSGHDR rt_msghdr
+#define MSGTYPE rtm_type
+#endif
+#endif
+
+#if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#if defined(RTM_NEWADDR) && defined(RTM_DELADDR)
+#define USE_ROUTE_SOCKET 1
+#define ROUTE_SOCKET_PROTOCOL PF_NETLINK
+#define MSGHDR nlmsghdr
+#define MSGTYPE nlmsg_type
 #endif
 #endif
 
@@ -83,7 +97,7 @@ route_event(isc_task_t *task, isc_event_t *event) {
        ns_interfacemgr_t *mgr = NULL;
        isc_region_t r;
        isc_result_t result;
-       struct rt_msghdr *rtm;
+       struct MSGHDR *rtm;
 
        UNUSED(task);
 
@@ -102,7 +116,8 @@ route_event(isc_task_t *task, isc_event_t *event) {
                return;
        }
 
-       rtm = (struct rt_msghdr *)mgr->buf;
+       rtm = (struct MSGHDR *)mgr->buf;
+#ifdef RTM_VERSION
        if (rtm->rtm_version != RTM_VERSION) {
                isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
                              "automatic interface rescanning disabled: "
@@ -115,8 +130,9 @@ route_event(isc_task_t *task, isc_event_t *event) {
                isc_event_free(&event);
                return;
        }
+#endif
 
-       switch (rtm->rtm_type) {
+       switch (rtm->MSGTYPE) {
        case RTM_NEWADDR:
        case RTM_DELADDR:
                if (ns_g_server->interface_auto)
@@ -190,12 +206,13 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
 
 #ifdef USE_ROUTE_SOCKET
        mgr->route = NULL;
-       result = isc_socket_create(mgr->socketmgr, PF_ROUTE,
+       result = isc_socket_create(mgr->socketmgr, ROUTE_SOCKET_PROTOCOL,
                                   isc_sockettype_raw, &mgr->route);
        switch (result) {
        case ISC_R_NOPERM:
        case ISC_R_SUCCESS:
        case ISC_R_NOTIMPLEMENTED:
+       case ISC_R_FAMILYNOSUPPORT:
            break;
        default:
                goto cleanup_aclenv;
index 06db5d4af1cd84985688804dc25c914b3a9428e1..285d9299ae012bb9e95ec912efbdb4a8465eab08 100644 (file)
@@ -287,6 +287,12 @@ int sigwait(const unsigned int *set, int *sig);
 /* Define to 1 if you have the <linux/capability.h> header file. */
 #undef HAVE_LINUX_CAPABILITY_H
 
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#undef HAVE_LINUX_NETLINK_H
+
+/* Define to 1 if you have the <linux/rtnetlink.h> header file. */
+#undef HAVE_LINUX_RTNETLINK_H
+
 /* Define to 1 if you have the <linux/types.h> header file. */
 #undef HAVE_LINUX_TYPES_H
 
index 5dd7fa6aeb596f547ec16ceb8ef5cce8b6ff8d5f..4bcde81f8d9a321411e21177fa0c506c81098946 100755 (executable)
--- a/configure
+++ b/configure
@@ -12544,7 +12544,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
 fi
 
 
-for ac_header in fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h
+for ac_header in fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h linux/netlink.h linux/rtnetlink.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
index 18653e4e8e89dadc8df3a87f7a9de70425f80340..bc7826be4631edeef25793e8f2813f3ba0ff1d48 100644 (file)
@@ -366,7 +366,7 @@ fi
 
 AC_HEADER_STDC
 
-AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h,,,
+AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h sys/socket.h net/route.h linux/netlink.h linux/rtnetlink.h,,,
 [$ac_includes_default
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
index 0b39e04156b125c7f192f03128ba2dbb19f81447..b0ef546465c967f1fe460e11f0a6574709613801 100644 (file)
 #include <sys/time.h>
 #include <sys/uio.h>
 
+#if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#endif
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stddef.h>
@@ -2477,10 +2482,41 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
                        sock->fd = socket(sock->pf, SOCK_STREAM, 0);
                        break;
                case isc_sockettype_raw:
-                       sock->fd = socket(sock->pf, SOCK_RAW, 0);
-#ifdef PF_ROUTE
-                       if (sock->pf == PF_ROUTE)
-                               sock->bound = 1;
+                       errno = EPFNOSUPPORT;
+                       /*
+                        * PF_ROUTE is a alias for PF_NETLINK on linux.
+                        */
+#if defined(PF_ROUTE)
+                       if (sock->fd == -1 && sock->pf == PF_ROUTE) {
+#ifdef NETLINK_ROUTE
+                               sock->fd = socket(sock->pf, SOCK_RAW,
+                                                 NETLINK_ROUTE);
+#else
+                               sock->fd = socket(sock->pf, SOCK_RAW, 0);
+#endif
+                               if (sock->fd != -1) {
+#ifdef NETLINK_ROUTE
+                                       struct sockaddr_nl sa;
+                                       int n;
+
+                                       /*
+                                        * Do an implicit bind.
+                                        */
+                                       memset(&sa, 0, sizeof(sa));
+                                       sa.nl_family = AF_NETLINK;
+                                       sa.nl_groups = RTMGRP_IPV4_IFADDR |
+                                                      RTMGRP_IPV6_IFADDR;
+                                       n = bind(sock->fd,
+                                                (struct sockaddr *) &sa,
+                                                sizeof(sa));
+                                       if (n < 0) {
+                                               close(sock->fd);
+                                               sock->fd = -1;
+                                       }
+#endif
+                                       sock->bound = 1;
+                               }
+                       }
 #endif
                        break;
                case isc_sockettype_fdwatch: