summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphessler <phessler@openbsd.org>2011-09-21 15:41:30 +0000
committerphessler <phessler@openbsd.org>2011-09-21 15:41:30 +0000
commit02d74365df1a465cc4922dabab6d8451a19b6dc8 (patch)
tree5bd498d42e5b370adac98716bce54ba7d47436e6
parentGet rid of curlwp references; mk@ (diff)
downloadwireguard-openbsd-02d74365df1a465cc4922dabab6d8451a19b6dc8.tar.xz
wireguard-openbsd-02d74365df1a465cc4922dabab6d8451a19b6dc8.zip
Add rdomain support to NTPd.
This basically adds the "rtable %d" keyword to "listen on", "server", "servers" keywords, to specify which routing table to use. OK henning@ claudio@ sthen@ manpage reviewed by jmc@
-rw-r--r--usr.sbin/ntpd/client.c21
-rw-r--r--usr.sbin/ntpd/ntp.c13
-rw-r--r--usr.sbin/ntpd/ntpd.conf.532
-rw-r--r--usr.sbin/ntpd/ntpd.h6
-rw-r--r--usr.sbin/ntpd/parse.y50
-rw-r--r--usr.sbin/ntpd/server.c112
-rw-r--r--usr.sbin/ntpd/util.c15
7 files changed, 183 insertions, 66 deletions
diff --git a/usr.sbin/ntpd/client.c b/usr.sbin/ntpd/client.c
index 807ba8db849..c6f20a25207 100644
--- a/usr.sbin/ntpd/client.c
+++ b/usr.sbin/ntpd/client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: client.c,v 1.88 2009/06/24 17:34:32 henning Exp $ */
+/* $OpenBSD: client.c,v 1.89 2011/09/21 15:41:30 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -134,12 +134,20 @@ client_query(struct ntp_peer *p)
if (p->state < STATE_DNS_DONE || p->addr == NULL)
return (-1);
+ if (p->addr->ss.ss_family != AF_INET && p->rtable != -1)
+ return (-1);
+
if (p->query->fd == -1) {
struct sockaddr *sa = (struct sockaddr *)&p->addr->ss;
if ((p->query->fd = socket(p->addr->ss.ss_family, SOCK_DGRAM,
0)) == -1)
fatal("client_query socket");
+
+ if (p->addr->ss.ss_family == AF_INET && p->rtable != -1 &&
+ setsockopt(p->query->fd, IPPROTO_IP, SO_RTABLE,
+ &p->rtable, sizeof(p->rtable)) == -1)
+ fatal("client_query setsockopt SO_RTABLE");
if (connect(p->query->fd, sa, SA_LEN(sa)) == -1) {
if (errno == ECONNREFUSED || errno == ENETUNREACH ||
errno == EHOSTUNREACH || errno == EADDRNOTAVAIL) {
@@ -243,6 +251,11 @@ client_dispatch(struct ntp_peer *p, u_int8_t settime)
return (0);
}
+ if (p->rtable != -1 &&
+ setsockopt(p->query->fd, IPPROTO_IP, SO_RTABLE, &p->rtable,
+ sizeof(p->rtable)) == -1)
+ fatal("client_dispatch setsockopt SO_RTABLE");
+
for (cmsg = CMSG_FIRSTHDR(&somsg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&somsg, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET &&
@@ -374,8 +387,10 @@ client_dispatch(struct ntp_peer *p, u_int8_t settime)
}
log_debug("reply from %s: offset %f delay %f, "
- "next query %ds", log_sockaddr((struct sockaddr *)&p->addr->ss),
- p->reply[p->shift].offset, p->reply[p->shift].delay, interval);
+ "next query %ds %s",
+ log_sockaddr((struct sockaddr *)&p->addr->ss),
+ p->reply[p->shift].offset, p->reply[p->shift].delay, interval,
+ print_rtable(p->rtable));
client_update(p);
if (settime)
diff --git a/usr.sbin/ntpd/ntp.c b/usr.sbin/ntpd/ntp.c
index f4c6c88c6d6..23713fc5e7c 100644
--- a/usr.sbin/ntpd/ntp.c
+++ b/usr.sbin/ntpd/ntp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntp.c,v 1.116 2011/06/17 18:12:05 henning Exp $ */
+/* $OpenBSD: ntp.c,v 1.117 2011/09/21 15:41:30 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -245,8 +245,9 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf, struct passwd *pw)
if (p->deadline > 0 && p->deadline <= getmonotime()) {
timeout = 300;
log_debug("no reply from %s received in time, "
- "next query %ds", log_sockaddr(
- (struct sockaddr *)&p->addr->ss), timeout);
+ "next query %ds %s", log_sockaddr(
+ (struct sockaddr *)&p->addr->ss), timeout,
+ print_rtable(p->rtable));
if (p->trustlevel >= TRUSTLEVEL_BADPEER &&
(p->trustlevel /= 2) < TRUSTLEVEL_BADPEER)
log_info("peer %s now invalid",
@@ -482,6 +483,7 @@ ntp_dispatch_imsg_dns(void)
npeer->addr_head.name =
peer->addr_head.name;
npeer->addr_head.pool = 1;
+ npeer->rtable = peer->rtable;
client_peer_init(npeer);
npeer->state = STATE_DNS_DONE;
peer_add(npeer);
@@ -770,8 +772,9 @@ report_peers(int always)
(struct sockaddr *)&p->addr->ss);
if (p->addr_head.pool)
pool = "from pool ";
- log_warnx("bad peer %s%s (%s)", pool,
- p->addr_head.name, a);
+ log_warnx("bad peer %s%s (%s) %s",
+ pool, p->addr_head.name, a,
+ print_rtable(p->rtable));
}
}
}
diff --git a/usr.sbin/ntpd/ntpd.conf.5 b/usr.sbin/ntpd/ntpd.conf.5
index 1a80a206530..ca000971133 100644
--- a/usr.sbin/ntpd/ntpd.conf.5
+++ b/usr.sbin/ntpd/ntpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ntpd.conf.5,v 1.22 2009/05/18 20:08:24 stevesk Exp $
+.\" $OpenBSD: ntpd.conf.5,v 1.23 2011/09/21 15:41:30 phessler Exp $
.\"
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
.\" OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 18 2009 $
+.Dd $Mdocdate: September 21 2011 $
.Dt NTPD.CONF 5
.Os
.Sh NAME
@@ -35,7 +35,9 @@ character are ignored.
Keywords may be specified multiple times within the configuration file.
They are as follows:
.Bl -tag -width Ds
-.It Ic listen on Ar address
+.It Xo Ic listen on Ar address
+.Op Ic rtable Ar table-id
+.Xc
Specify a local IP address or a hostname the
.Xr ntpd 8
daemon should listen on.
@@ -46,9 +48,15 @@ If
.Sq *
is given as an address,
.Xr ntpd 8
-will listen on all local addresses.
+will listen on all local addresses using the specified routing table.
.Xr ntpd 8
does not listen on any address by default.
+The optional
+.Ic rtable
+keyword will specify which routing table to listen on.
+By default
+.Xr ntpd 8
+will listen using the current routing table.
For example:
.Bd -literal -offset indent
listen on *
@@ -58,6 +66,7 @@ or
.Bd -literal -offset indent
listen on 127.0.0.1
listen on ::1
+listen on 127.0.0.1 rtable 4
.Ed
.It Xo Ic sensor Ar device
.Op Ic correction Ar microseconds
@@ -117,12 +126,17 @@ sensor nmea0 refid GPS
.Ed
.It Xo Ic server Ar address
.Op Ic weight Ar weight-value
+.Op Ic rtable Ar table-id
.Xc
Specify the IP address or the hostname of an NTP
server to synchronize to.
If it appears multiple times,
.Xr ntpd 8
will try to synchronize to all of the servers specified.
+The
+.Cm rtable
+option specifies which routing table should be used for connection attempts.
+Hostname resolution will still happen using the default routing table.
If a hostname resolves to multiple IPv4 and/or IPv6 addresses,
.Xr ntpd 8
uses the first address.
@@ -133,7 +147,7 @@ is found.
For example:
.Bd -literal -offset indent
server 10.0.0.2 weight 5
-server ntp.example.org weight 1
+server ntp.example.org weight 1 rtable 4
.Ed
.Pp
To provide redundancy, it is good practice to configure multiple servers.
@@ -141,6 +155,7 @@ In general, best accuracy is obtained by using servers that have a low
network latency.
.It Xo Ic servers Ar address
.Op Ic weight Ar weight-value
+.Op Ic rtable Ar table-id
.Xc
As with
.Cm server ,
@@ -154,6 +169,7 @@ will try to synchronize to all of them.
For example:
.Bd -literal -offset indent
servers pool.ntp.org
+servers pool.ntp.org rtable 5
.Ed
.El
.Sh FILES
@@ -171,3 +187,9 @@ The
.Nm
file format first appeared in
.Ox 3.6 .
+.Sh CAVEATS
+When using different
+.Cm rtable
+options,
+.Xr ntpd 8
+must be started in rtable 0.
diff --git a/usr.sbin/ntpd/ntpd.h b/usr.sbin/ntpd/ntpd.h
index 9546bb33442..1140eaf24ff 100644
--- a/usr.sbin/ntpd/ntpd.h
+++ b/usr.sbin/ntpd/ntpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntpd.h,v 1.103 2009/06/06 18:45:01 ckuethe Exp $ */
+/* $OpenBSD: ntpd.h,v 1.104 2011/09/21 15:41:30 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -81,11 +81,13 @@ struct listen_addr {
TAILQ_ENTRY(listen_addr) entry;
struct sockaddr_storage sa;
int fd;
+ int rtable;
};
struct ntp_addr {
struct ntp_addr *next;
struct sockaddr_storage ss;
+ int rtable;
};
struct ntp_addr_wrap {
@@ -132,6 +134,7 @@ struct ntp_peer {
u_int8_t weight;
int lasterror;
int senderrors;
+ int rtable;
};
struct ntp_sensor {
@@ -247,6 +250,7 @@ double lfp_to_d(struct l_fixedpt);
struct l_fixedpt d_to_lfp(double);
double sfp_to_d(struct s_fixedpt);
struct s_fixedpt d_to_sfp(double);
+char *print_rtable(int);
/* sensors.c */
void sensor_init(void);
diff --git a/usr.sbin/ntpd/parse.y b/usr.sbin/ntpd/parse.y
index 5751682bafc..2934b68d243 100644
--- a/usr.sbin/ntpd/parse.y
+++ b/usr.sbin/ntpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.47 2010/08/03 18:42:40 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.48 2011/09/21 15:41:30 phessler Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -60,6 +60,7 @@ struct ntpd_conf *conf;
struct opts {
int weight;
int correction;
+ int rtable;
char *refstr;
} opts;
void opts_default(void);
@@ -77,14 +78,16 @@ typedef struct {
%}
%token LISTEN ON
-%token SERVER SERVERS SENSOR CORRECTION REFID WEIGHT
+%token SERVER SERVERS SENSOR CORRECTION RTABLE REFID WEIGHT
%token ERROR
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.addr> address
+%type <v.opts> listen_opts listen_opts_l listen_opt
%type <v.opts> server_opts server_opts_l server_opt
%type <v.opts> sensor_opts sensor_opts_l sensor_opt
%type <v.opts> correction
+%type <v.opts> rtable
%type <v.opts> refid
%type <v.opts> weight
%%
@@ -95,11 +98,11 @@ grammar : /* empty */
| grammar error '\n' { file->errors++; }
;
-main : LISTEN ON address {
+main : LISTEN ON address listen_opts {
struct listen_addr *la;
struct ntp_addr *h, *next;
- if ((h = $3->a) == NULL &&
+ if ((h = $3->a) == NULL && (h->rtable = $4.rtable) &&
(host_dns($3->name, &h) == -1 || !h)) {
yyerror("could not resolve \"%s\"", $3->name);
free($3->name);
@@ -109,15 +112,11 @@ main : LISTEN ON address {
for (; h != NULL; h = next) {
next = h->next;
- if (h->ss.ss_family == AF_UNSPEC) {
- conf->listen_all = 1;
- free(h);
- continue;
- }
la = calloc(1, sizeof(struct listen_addr));
if (la == NULL)
fatal("listen on calloc");
la->fd = -1;
+ la->rtable = $4.rtable;
memcpy(&la->sa, &h->ss,
sizeof(struct sockaddr_storage));
TAILQ_INSERT_TAIL(&conf->listen_addrs, la,
@@ -150,6 +149,7 @@ main : LISTEN ON address {
p = new_peer();
p->weight = $3.weight;
+ p->rtable = $3.rtable;
p->addr = h;
p->addr_head.a = h;
p->addr_head.pool = 1;
@@ -158,8 +158,10 @@ main : LISTEN ON address {
fatal(NULL);
if (p->addr != NULL)
p->state = STATE_DNS_DONE;
- TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry);
-
+ if (!(p->rtable > 0 && p->addr &&
+ p->addr->ss.ss_family != AF_INET))
+ TAILQ_INSERT_TAIL(&conf->ntp_peers,
+ p, entry);
h = next;
} while (h != NULL);
@@ -188,6 +190,7 @@ main : LISTEN ON address {
}
p->weight = $3.weight;
+ p->rtable = $3.rtable;
p->addr_head.a = p->addr;
p->addr_head.pool = 0;
p->addr_head.name = strdup($2->name);
@@ -195,7 +198,9 @@ main : LISTEN ON address {
fatal(NULL);
if (p->addr != NULL)
p->state = STATE_DNS_DONE;
- TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry);
+ if (!(p->rtable > 0 && p->addr &&
+ p->addr->ss.ss_family != AF_INET))
+ TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry);
free($2->name);
free($2);
}
@@ -226,6 +231,17 @@ address : STRING {
}
;
+listen_opts : { opts_default(); }
+ listen_opts_l
+ { $$ = opts; }
+ | { opts_default(); $$ = opts; }
+ ;
+listen_opts_l : listen_opts_l listen_opt
+ | listen_opt
+ ;
+listen_opt : rtable
+ ;
+
server_opts : { opts_default(); }
server_opts_l
{ $$ = opts; }
@@ -235,6 +251,7 @@ server_opts_l : server_opts_l server_opt
| server_opt
;
server_opt : weight
+ | rtable
;
sensor_opts : { opts_default(); }
@@ -279,6 +296,13 @@ weight : WEIGHT NUMBER {
}
opts.weight = $2;
}
+rtable : RTABLE NUMBER {
+ if ($2 < 0 || $2 > RT_TABLEID_MAX) {
+ yyerror("rtable must be between 1 and RT_TABLEID_MAX");
+ YYERROR;
+ }
+ opts.rtable = $2;
+ }
;
%%
@@ -288,6 +312,7 @@ opts_default(void)
{
bzero(&opts, sizeof opts);
opts.weight = 1;
+ opts.rtable = -1;
}
struct keywords {
@@ -326,6 +351,7 @@ lookup(char *s)
{ "listen", LISTEN},
{ "on", ON},
{ "refid", REFID},
+ { "rtable", RTABLE},
{ "sensor", SENSOR},
{ "server", SERVER},
{ "servers", SERVERS},
diff --git a/usr.sbin/ntpd/server.c b/usr.sbin/ntpd/server.c
index 87dca9e5bd6..218524686df 100644
--- a/usr.sbin/ntpd/server.c
+++ b/usr.sbin/ntpd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.35 2009/05/20 14:55:59 henning Exp $ */
+/* $OpenBSD: server.c,v 1.36 2011/09/21 15:41:30 phessler Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -17,8 +17,10 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <net/if.h>
#include <errno.h>
#include <ifaddrs.h>
#include <stdlib.h>
@@ -30,51 +32,73 @@
int
setup_listeners(struct servent *se, struct ntpd_conf *lconf, u_int *cnt)
{
- struct listen_addr *la;
+ struct listen_addr *la, *nla, *lap;
struct ifaddrs *ifa, *ifap;
struct sockaddr *sa;
+ struct ifreq ifr;
u_int8_t *a6;
size_t sa6len = sizeof(struct in6_addr);
u_int new_cnt = 0;
- int tos = IPTOS_LOWDELAY;
-
- if (lconf->listen_all) {
- if (getifaddrs(&ifa) == -1)
- fatal("getifaddrs");
-
- for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
- sa = ifap->ifa_addr;
-
- if (sa == NULL ||
- (sa->sa_family != AF_INET &&
- sa->sa_family != AF_INET6))
- continue;
- if (SA_LEN(sa) == 0)
- continue;
-
- if (sa->sa_family == AF_INET &&
- ((struct sockaddr_in *)sa)->sin_addr.s_addr ==
- INADDR_ANY)
- continue;
-
- if (sa->sa_family == AF_INET6) {
- a6 = ((struct sockaddr_in6 *)sa)->
- sin6_addr.s6_addr;
- if (memcmp(a6, &in6addr_any, sa6len) == 0)
+ int tos = IPTOS_LOWDELAY, rdomain, fd;
+
+ TAILQ_FOREACH(lap, &lconf->listen_addrs, entry) {
+ switch (lap->sa.ss_family) {
+ case AF_UNSPEC:
+ if (getifaddrs(&ifa) == -1)
+ fatal("getifaddrs");
+
+ for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
+ sa = ifap->ifa_addr;
+ if (sa == NULL ||
+ (sa->sa_family != AF_INET &&
+ sa->sa_family != AF_INET6))
+ continue;
+ if (SA_LEN(sa) == 0)
continue;
- }
- if ((la = calloc(1, sizeof(struct listen_addr))) ==
- NULL)
- fatal("setup_listeners calloc");
+ strlcpy(ifr.ifr_name, ifap->ifa_name,
+ sizeof(ifr.ifr_name));
- memcpy(&la->sa, sa, SA_LEN(sa));
- TAILQ_INSERT_TAIL(&lconf->listen_addrs, la, entry);
- }
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (ioctl(fd, SIOCGIFRDOMAIN,
+ (caddr_t)&ifr) == -1)
+ rdomain = 0;
+ else
+ rdomain = ifr.ifr_rdomainid;
+ close(fd);
+
+ if (lap->rtable != -1 && rdomain != lap->rtable)
+ continue;
+
+ if (sa->sa_family == AF_INET &&
+ ((struct sockaddr_in *)sa)->sin_addr.s_addr ==
+ INADDR_ANY)
+ continue;
+
+ if (sa->sa_family == AF_INET6) {
+ a6 = ((struct sockaddr_in6 *)sa)->
+ sin6_addr.s6_addr;
+ if (memcmp(a6, &in6addr_any, sa6len) == 0)
+ continue;
+ }
+
+ if ((la = calloc(1, sizeof(struct listen_addr))) ==
+ NULL)
+ fatal("setup_listeners calloc");
+
+ memcpy(&la->sa, sa, SA_LEN(sa));
+ la->rtable = rdomain;
+
+ TAILQ_INSERT_TAIL(&lconf->listen_addrs, la, entry);
+ }
- freeifaddrs(ifa);
+ freeifaddrs(ifa);
+ default:
+ continue;
+ }
}
+
for (la = TAILQ_FIRST(&lconf->listen_addrs); la; ) {
switch (la->sa.ss_family) {
case AF_INET:
@@ -87,12 +111,19 @@ setup_listeners(struct servent *se, struct ntpd_conf *lconf, u_int *cnt)
((struct sockaddr_in6 *)&la->sa)->sin6_port =
se->s_port;
break;
+ case AF_UNSPEC:
+ nla = TAILQ_NEXT(la, entry);
+ TAILQ_REMOVE(&lconf->listen_addrs, la, entry);
+ free(la);
+ la = nla;
+ continue;
default:
fatalx("king bula sez: af borked");
}
- log_info("listening on %s",
- log_sockaddr((struct sockaddr *)&la->sa));
+ log_info("listening on %s %s",
+ log_sockaddr((struct sockaddr *)&la->sa),
+ print_rtable(la->rtable));
if ((la->fd = socket(la->sa.ss_family, SOCK_DGRAM, 0)) == -1)
fatal("socket");
@@ -101,10 +132,13 @@ setup_listeners(struct servent *se, struct ntpd_conf *lconf, u_int *cnt)
IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1)
log_warn("setsockopt IPTOS_LOWDELAY");
+ if (la->sa.ss_family == AF_INET && la->rtable != -1 &&
+ setsockopt(la->fd, IPPROTO_IP, SO_RTABLE, &la->rtable,
+ sizeof(la->rtable)) == -1)
+ fatal("setup_listeners setsockopt SO_RTABLE");
+
if (bind(la->fd, (struct sockaddr *)&la->sa,
SA_LEN((struct sockaddr *)&la->sa)) == -1) {
- struct listen_addr *nla;
-
log_warn("bind on %s failed, skipping",
log_sockaddr((struct sockaddr *)&la->sa));
close(la->fd);
diff --git a/usr.sbin/ntpd/util.c b/usr.sbin/ntpd/util.c
index 10075076ad5..a9e02316597 100644
--- a/usr.sbin/ntpd/util.c
+++ b/usr.sbin/ntpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.13 2007/03/27 18:22:02 otto Exp $ */
+/* $OpenBSD: util.c,v 1.14 2011/09/21 15:41:30 phessler Exp $ */
/*
* Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org>
@@ -18,6 +18,7 @@
#include <sys/time.h>
#include <limits.h>
+#include <stdio.h>
#include "ntpd.h"
@@ -117,3 +118,15 @@ d_to_sfp(double d)
return (sfp);
}
+
+char *
+print_rtable(int r)
+{
+ static char b[11];
+
+ b[0] = 0;
+ if (r > 0)
+ snprintf(b, sizeof(b), "rtable %d", r);
+
+ return(b);
+}