Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to the project are documented in this file.

### Changes

- Add NTP server support, issue #904
- Add support for configurable OSPF debug logging, issue #1281. Debug options
can now be enabled per category (bfd, packet, ism, nsm, default-information,
nssa). All debug options are disabled by default to prevent log flooding in
Expand Down
160 changes: 160 additions & 0 deletions doc/ntp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# NTP Server

The NTP (Network Time Protocol) server provides accurate time synchronization
for network clients. It supports both standalone operation with a local
reference clock and hybrid mode where it synchronizes with upstream servers
while serving time to downstream clients.

> [!NOTE]
> The NTP server is mutually exclusive with the NTP client in system
> configuration context.

## Standalone Mode

Configure a standalone NTP server using only a local reference clock:

```
admin@example:/> configure
admin@example:/config/> edit ntp
admin@example:/config/ntp/> leave
```

When setting up NTP via the CLI the system automatically configures a local
reference clock with [stratum](#ntp-stratum-levels) 10.

View the configuration:

```
admin@example:/> show running-config
"ietf-ntp:ntp": {
"refclock-master": {
"master-stratum": 10
}
}
```

## Server Mode

Synchronize from upstream NTP servers while serving time to clients:

```
admin@example:/config/> edit ntp
admin@example:/config/ntp/> edit unicast-configuration 0.pool.ntp.org type uc-server
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> set iburst true
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> end
admin@example:/config/ntp/> edit unicast-configuration 1.pool.ntp.org type uc-server
admin@example:/config/ntp/…/1.pool.ntp.org/type/uc-server/> set iburst true
admin@example:/config/ntp/…/1.pool.ntp.org/type/uc-server/> end
admin@example:/config/ntp/> leave
```

The `unicast-configuration` uses a composite key with both address and type.
Both hostnames and IP addresses are supported. The `iburst` option enables
fast initial synchronization. The local reference clock (stratum 10) is
automatically configured as a fallback.

## Peer Mode

In peer mode, two NTP servers synchronize with each other bidirectionally.
Each server acts as both client and server to the other:

**First peer:**

```
admin@peer1:/config/> edit ntp
admin@peer1:/config/ntp/> edit unicast-configuration 192.168.1.2 type uc-peer
admin@peer1:/config/ntp/…/192.168.1.2/type/uc-peer/> end
admin@peer1:/config/ntp/> set refclock-master master-stratum 8
admin@peer1:/config/ntp/> leave
```

**Second peer:**

```
admin@peer2:/config/> edit ntp
admin@peer2:/config/ntp/> edit unicast-configuration 192.168.1.1 type uc-peer
admin@peer2:/config/ntp/…/192.168.1.1/type/uc-peer/> end
admin@peer2:/config/ntp/> set refclock-master master-stratum 8
admin@peer2:/config/ntp/> leave
```

This configuration provides mutual synchronization between peers. If one peer
fails, the other continues to serve time to clients.

> [!NOTE]
> The `iburst` and `burst` options are not supported in peer mode.

## Timing Configuration

### Poll Intervals

Control how often the NTP server polls upstream sources:

```
admin@example:/config/ntp/> edit unicast-configuration 0.pool.ntp.org type uc-server
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> set minpoll 4
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> set maxpoll 10
admin@example:/config/ntp/…/0.pool.ntp.org/type/uc-server/> end
```

Poll intervals are specified as powers of 2:
- `minpoll 4` = poll every 2^4 = 16 seconds (minimum polling rate)
- `maxpoll 10` = poll every 2^10 = 1024 seconds (maximum polling rate)
- Defaults: minpoll 6 (64 seconds), maxpoll 10 (1024 seconds)

Use shorter intervals (minpoll 2-4) for faster convergence in test environments
or peer configurations. Use defaults for production servers.

### Initial Synchronization

Enable clock stepping for systems that boot with incorrect time:

```
admin@example:/config/ntp/> edit makestep
admin@example:/config/ntp/makestep/> set threshold 1.0
admin@example:/config/ntp/makestep/> set limit 3
admin@example:/config/ntp/makestep/> end
```

The `makestep` directive is automatically configured with safe defaults (1.0
seconds threshold, 3 updates limit) when creating an NTP server. This is
critical for embedded systems without RTC that boot with epoch time.

- **threshold** - If clock offset exceeds this (in seconds), step immediately
instead of slewing slowly
- **limit** - Number of updates during which stepping is allowed. After this,
only gradual slewing is used for security

With these defaults, a device booting at epoch time (1970-01-01) will sync to
correct time within seconds instead of hours.

## Monitoring

Check NTP server statistics:

```
admin@example:/> show ntp server
NTP SERVER CONFIGURATION
Local Stratum : 10

SERVER STATISTICS
Packets Received : 142
Packets Sent : 142
Packets Dropped : 0
Send Failures : 0
```

## NTP Stratum Levels

NTP uses a hierarchical system called **stratum** to indicate distance from
authoritative time sources:

- **Stratum 0**: Reference clocks (atomic clocks, GPS receivers)
- **Stratum 1**: Servers directly connected to stratum 0
- **Stratum 2-15**: Servers that sync from lower stratum (each hop adds one)
- **Stratum 16**: Unsynchronized (invalid)

**Default Stratum 10**: Infix uses stratum 10 as the default for local
reference clocks. This is a safe, low-priority value that ensures clients
will prefer upstream-synchronized servers (stratum 1-9) while still having
a fallback time source in isolated networks.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ nav:
- Services:
- Device Discovery: discovery.md
- DHCP Server: dhcp.md
- NTP Server: ntp.md
- System:
- Boot Procedure: boot.md
- Configuration: system.md
Expand Down
1 change: 1 addition & 0 deletions src/confd/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ confd_plugin_la_SOURCES = \
if-wifi.c \
keystore.c \
system.c \
ntp.c \
syslog.c \
factory-default.c \
routing.c \
Expand Down
27 changes: 27 additions & 0 deletions src/confd/src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
if ((rc = keystore_change(session, config, diff, event, confd)))
goto free_diff;

/* ietf-ntp */
if ((rc = ntp_change(session, config, diff, event, confd)))
goto free_diff;

/* infix-services */
if ((rc = services_change(session, config, diff, event, confd)))
goto free_diff;
Expand Down Expand Up @@ -244,6 +248,20 @@ static int change_cb(sr_session_ctx_t *session, uint32_t sub_id, const char *mod
if ((rc = meta_change_cb(session, config, diff, event, confd)))
goto free_diff;

/*
* Manage chronyd service enable/disable state. Must be done
* after both ietf-system:ntp and ietf-ntp have are done.
*/
if (event == SR_EV_DONE && config) {
bool client = false;
bool server = false;

client = srx_enabled(session, "/ietf-system:system/ntp/enabled");
server = lydx_get_xpathf(config, "/ietf-ntp:ntp") != NULL;

systemf("initctl -nbq %s chronyd", client || server ? "enable" : "disable");
}

if (cfg)
sr_release_data(cfg);

Expand Down Expand Up @@ -332,6 +350,11 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
ERROR("Failed to subscribe to ietf-netconf-acm");
goto err;
}
rc = subscribe_model("ietf-ntp", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to ietf-ntp");
goto err;
}
rc = subscribe_model("infix-dhcp-client", &confd, 0);
if (rc) {
ERROR("Failed to subscribe to infix-dhcp-client");
Expand Down Expand Up @@ -432,6 +455,10 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **priv)
goto err;

rc = dhcp_server_candidate_init(&confd);
if (rc)
goto err;

rc = ntp_candidate_init(&confd);
if (rc)
goto err;
/* YOUR_INIT GOES HERE */
Expand Down
6 changes: 6 additions & 0 deletions src/confd/src/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,10 @@ int firewall_rpc_init(struct confd *confd);
int firewall_candidate_init(struct confd *confd);
int firewall_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);

/* ntp.c */
int ntp_change(sr_session_ctx_t *session, struct lyd_node *config, struct lyd_node *diff, sr_event_t event, struct confd *confd);
int ntp_cand(sr_session_ctx_t *session, uint32_t sub_id, const char *module,
const char *path, sr_event_t event, unsigned request_id, void *priv);
int ntp_candidate_init(struct confd *confd);

#endif /* CONFD_CORE_H_ */
Loading