Commit 850b5e80 authored by Mark Andrews's avatar Mark Andrews

Add Linux support to:

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]
parent f2016fce
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]
......
......@@ -39,6 +39,20 @@
#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;
......
......@@ -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
......
......@@ -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
......
......@@ -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>
......
......@@ -28,6 +28,11 @@
#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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment