Browse Source

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@
OPENBSD_5_1
phessler 12 years ago
parent
commit
a32e45b068
7 changed files with 183 additions and 66 deletions
  1. +18
    -3
      src/usr.sbin/ntpd/client.c
  2. +8
    -5
      src/usr.sbin/ntpd/ntp.c
  3. +27
    -5
      src/usr.sbin/ntpd/ntpd.conf.5
  4. +5
    -1
      src/usr.sbin/ntpd/ntpd.h
  5. +38
    -12
      src/usr.sbin/ntpd/parse.y
  6. +73
    -39
      src/usr.sbin/ntpd/server.c
  7. +14
    -1
      src/usr.sbin/ntpd/util.c

+ 18
- 3
src/usr.sbin/ntpd/client.c View File

@ -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)


+ 8
- 5
src/usr.sbin/ntpd/ntp.c View File

@ -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));
}
}
}


+ 27
- 5
src/usr.sbin/ntpd/ntpd.conf.5 View File

@ -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.

+ 5
- 1
src/usr.sbin/ntpd/ntpd.h View File

@ -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);


+ 38
- 12
src/usr.sbin/ntpd/parse.y View File

@ -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},


+ 73
- 39
src/usr.sbin/ntpd/server.c View File

@ -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);


+ 14
- 1
src/usr.sbin/ntpd/util.c View File

@ -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);
}

Loading…
Cancel
Save