Skip to content
This repository was archived by the owner on Dec 27, 2019. It is now read-only.

Commit 21c6bb5

Browse files
committed
global: switch to coarse ktime
Coarse ktime is broken until [1] in 5.2 and kernels without the backport, so we use fallback code there. The fallback code has also been improved significantly. It now only uses slower clocks on kernels < 3.17, at the expense of some accuracy we're not overly concerned about. [1] https://lore.kernel.org/lkml/[email protected]/ Suggested-by: Arnd Bergmann <[email protected]>
1 parent 7d47894 commit 21c6bb5

File tree

11 files changed

+43
-36
lines changed

11 files changed

+43
-36
lines changed

src/compat/compat.h

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -388,25 +388,38 @@ static inline int get_random_bytes_wait(void *buf, int nbytes)
388388
#define system_power_efficient_wq system_unbound_wq
389389
#endif
390390

391-
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) && !defined(ISRHEL7)
391+
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0)
392+
#include <linux/ktime.h>
393+
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
392394
#include <linux/hrtimer.h>
393-
static inline u64 ktime_get_boot_ns(void)
395+
#ifndef ktime_get_real_ts64
396+
#define timespec64 timespec
397+
#define ktime_get_real_ts64 ktime_get_real_ts
398+
#endif
399+
#else
400+
#include <linux/timekeeping.h>
401+
#endif
402+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
403+
static inline u64 __compat_jiffies64_to_nsecs(u64 j)
394404
{
395-
return ktime_to_ns(ktime_get_boottime());
405+
#if !(NSEC_PER_SEC % HZ)
406+
return (NSEC_PER_SEC / HZ) * j;
407+
# else
408+
return div_u64(j * HZ_TO_USEC_NUM, HZ_TO_USEC_DEN) * 1000;
409+
#endif
396410
}
411+
#define jiffies64_to_nsecs __compat_jiffies64_to_nsecs
397412
#endif
398-
399-
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
413+
static inline u64 ktime_get_coarse_boottime_ns(void)
414+
{
400415
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
401-
#include <linux/hrtimer.h>
416+
return ktime_to_ns(ktime_get_boottime());
417+
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 12) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) || LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 53)
418+
return ktime_to_ns(ktime_mono_to_any(ns_to_ktime(jiffies64_to_nsecs(get_jiffies_64())), TK_OFFS_BOOT));
402419
#else
403-
#include <linux/timekeeping.h>
420+
return ktime_to_ns(ktime_get_coarse_boottime());
404421
#endif
405-
static inline u64 __compat_ktime_get_boot_fast_ns(void)
406-
{
407-
return ktime_get_boot_ns();
408422
}
409-
#define ktime_get_boot_fast_ns __compat_ktime_get_boot_fast_ns
410423
#endif
411424

412425
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
@@ -646,11 +659,6 @@ struct __compat_dummy_container { char dev; };
646659
#define COMPAT_CANNOT_USE_AVX512
647660
#endif
648661

649-
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
650-
#define timespec64 timespec
651-
#define ktime_get_real_ts64 ktime_get_real_ts
652-
#endif
653-
654662
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
655663
#include <net/genetlink.h>
656664
#define genl_dump_check_consistent(a, b) genl_dump_check_consistent(a, b, &genl_family)

src/cookie.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void wg_cookie_checker_init(struct cookie_checker *checker,
2020
struct wg_device *wg)
2121
{
2222
init_rwsem(&checker->secret_lock);
23-
checker->secret_birthdate = ktime_get_boot_fast_ns();
23+
checker->secret_birthdate = ktime_get_coarse_boottime_ns();
2424
get_random_bytes(checker->secret, NOISE_HASH_LEN);
2525
checker->device = wg;
2626
}
@@ -96,7 +96,7 @@ static void make_cookie(u8 cookie[COOKIE_LEN], struct sk_buff *skb,
9696
if (wg_birthdate_has_expired(checker->secret_birthdate,
9797
COOKIE_SECRET_MAX_AGE)) {
9898
down_write(&checker->secret_lock);
99-
checker->secret_birthdate = ktime_get_boot_fast_ns();
99+
checker->secret_birthdate = ktime_get_coarse_boottime_ns();
100100
get_random_bytes(checker->secret, NOISE_HASH_LEN);
101101
up_write(&checker->secret_lock);
102102
}
@@ -222,7 +222,7 @@ void wg_cookie_message_consume(struct message_handshake_cookie *src,
222222
if (ret) {
223223
down_write(&peer->latest_cookie.lock);
224224
memcpy(peer->latest_cookie.cookie, cookie, COOKIE_LEN);
225-
peer->latest_cookie.birthdate = ktime_get_boot_fast_ns();
225+
peer->latest_cookie.birthdate = ktime_get_coarse_boottime_ns();
226226
peer->latest_cookie.is_valid = true;
227227
peer->latest_cookie.have_sent_mac1 = false;
228228
up_write(&peer->latest_cookie.lock);

src/device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static int wg_stop(struct net_device *dev)
113113
wg_noise_handshake_clear(&peer->handshake);
114114
wg_noise_keypairs_clear(&peer->keypairs);
115115
atomic64_set(&peer->last_sent_handshake,
116-
ktime_get_boot_fast_ns() -
116+
ktime_get_coarse_boottime_ns() -
117117
(u64)(REKEY_TIMEOUT + 1) * NSEC_PER_SEC);
118118
}
119119
mutex_unlock(&wg->device_update_lock);

src/noise.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ static void symmetric_key_init(struct noise_symmetric_key *key)
352352
atomic64_set(&key->counter.counter, 0);
353353
memset(key->counter.receive.backtrack, 0,
354354
sizeof(key->counter.receive.backtrack));
355-
key->birthdate = ktime_get_boot_fast_ns();
355+
key->birthdate = ktime_get_coarse_boottime_ns();
356356
key->is_valid = true;
357357
}
358358

@@ -585,9 +585,9 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
585585
down_read(&handshake->lock);
586586
replay_attack = memcmp(t, handshake->latest_timestamp,
587587
NOISE_TIMESTAMP_LEN) <= 0;
588-
flood_attack = handshake->last_initiation_consumption +
588+
flood_attack = (s64)handshake->last_initiation_consumption +
589589
NSEC_PER_SEC / INITIATIONS_PER_SECOND >
590-
ktime_get_boot_fast_ns();
590+
(s64)ktime_get_coarse_boottime_ns();
591591
up_read(&handshake->lock);
592592
if (replay_attack || flood_attack)
593593
goto out;
@@ -599,7 +599,7 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
599599
memcpy(handshake->hash, hash, NOISE_HASH_LEN);
600600
memcpy(handshake->chaining_key, chaining_key, NOISE_HASH_LEN);
601601
handshake->remote_index = src->sender_index;
602-
handshake->last_initiation_consumption = ktime_get_boot_fast_ns();
602+
handshake->last_initiation_consumption = ktime_get_coarse_boottime_ns();
603603
handshake->state = HANDSHAKE_CONSUMED_INITIATION;
604604
up_write(&handshake->lock);
605605
ret_peer = peer;

src/noise.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include <linux/atomic.h>
1414
#include <linux/rwsem.h>
1515
#include <linux/mutex.h>
16-
#include <linux/ktime.h>
1716
#include <linux/kref.h>
1817

1918
union noise_counter {

src/peer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct wg_peer *wg_peer_create(struct wg_device *wg,
5757
kref_init(&peer->refcount);
5858
skb_queue_head_init(&peer->staged_packet_queue);
5959
atomic64_set(&peer->last_sent_handshake,
60-
ktime_get_boot_fast_ns() -
60+
ktime_get_coarse_boottime_ns() -
6161
(u64)(REKEY_TIMEOUT + 1) * NSEC_PER_SEC);
6262
set_bit(NAPI_STATE_NO_BUSY_POLL, &peer->napi.state);
6363
netif_napi_add(wg->dev, &peer->napi, wg_packet_rx_poll,

src/ratelimiter.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static void entry_uninit(struct ratelimiter_entry *entry)
6666
/* Calling this function with a NULL work uninits all entries. */
6767
static void wg_ratelimiter_gc_entries(struct work_struct *work)
6868
{
69-
const u64 now = ktime_get_boot_fast_ns();
69+
const u64 now = ktime_get_coarse_boottime_ns();
7070
struct ratelimiter_entry *entry;
7171
struct hlist_node *temp;
7272
unsigned int i;
@@ -130,7 +130,7 @@ bool wg_ratelimiter_allow(struct sk_buff *skb, struct net *net)
130130
* as part of the rate.
131131
*/
132132
spin_lock(&entry->lock);
133-
now = ktime_get_boot_fast_ns();
133+
now = ktime_get_coarse_boottime_ns();
134134
tokens = min_t(u64, TOKEN_MAX,
135135
entry->tokens + now -
136136
entry->last_time_ns);
@@ -155,7 +155,7 @@ bool wg_ratelimiter_allow(struct sk_buff *skb, struct net *net)
155155
entry->ip = ip;
156156
INIT_HLIST_NODE(&entry->hash);
157157
spin_lock_init(&entry->lock);
158-
entry->last_time_ns = ktime_get_boot_fast_ns();
158+
entry->last_time_ns = ktime_get_coarse_boottime_ns();
159159
entry->tokens = TOKEN_MAX - PACKET_COST;
160160
spin_lock(&table_lock);
161161
hlist_add_head_rcu(&entry->hash, bucket);

src/receive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static void wg_receive_handshake_packet(struct wg_device *wg,
120120
under_load = skb_queue_len(&wg->incoming_handshakes) >=
121121
MAX_QUEUED_INCOMING_HANDSHAKES / 8;
122122
if (under_load)
123-
last_under_load = ktime_get_boot_fast_ns();
123+
last_under_load = ktime_get_coarse_boottime_ns();
124124
else if (last_under_load)
125125
under_load = !wg_birthdate_has_expired(last_under_load, 1);
126126
mac_state = wg_cookie_validate_packet(&wg->cookie_checker, skb,

src/send.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
2727
REKEY_TIMEOUT))
2828
return; /* This function is rate limited. */
2929

30-
atomic64_set(&peer->last_sent_handshake, ktime_get_boot_fast_ns());
30+
atomic64_set(&peer->last_sent_handshake, ktime_get_coarse_boottime_ns());
3131
net_dbg_ratelimited("%s: Sending handshake initiation to peer %llu (%pISpfsc)\n",
3232
peer->device->dev->name, peer->internal_id,
3333
&peer->endpoint.addr);
@@ -37,7 +37,7 @@ static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
3737
wg_timers_any_authenticated_packet_traversal(peer);
3838
wg_timers_any_authenticated_packet_sent(peer);
3939
atomic64_set(&peer->last_sent_handshake,
40-
ktime_get_boot_fast_ns());
40+
ktime_get_coarse_boottime_ns());
4141
wg_socket_send_buffer_to_peer(peer, &packet, sizeof(packet),
4242
HANDSHAKE_DSCP);
4343
wg_timers_handshake_initiated(peer);
@@ -87,7 +87,7 @@ void wg_packet_send_handshake_response(struct wg_peer *peer)
8787
{
8888
struct message_handshake_response packet;
8989

90-
atomic64_set(&peer->last_sent_handshake, ktime_get_boot_fast_ns());
90+
atomic64_set(&peer->last_sent_handshake, ktime_get_coarse_boottime_ns());
9191
net_dbg_ratelimited("%s: Sending handshake response to peer %llu (%pISpfsc)\n",
9292
peer->device->dev->name, peer->internal_id,
9393
&peer->endpoint.addr);
@@ -100,7 +100,7 @@ void wg_packet_send_handshake_response(struct wg_peer *peer)
100100
wg_timers_any_authenticated_packet_traversal(peer);
101101
wg_timers_any_authenticated_packet_sent(peer);
102102
atomic64_set(&peer->last_sent_handshake,
103-
ktime_get_boot_fast_ns());
103+
ktime_get_coarse_boottime_ns());
104104
wg_socket_send_buffer_to_peer(peer, &packet,
105105
sizeof(packet),
106106
HANDSHAKE_DSCP);

src/tests/qemu/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ endif
1414
ARCH := $(firstword $(subst -, ,$(CBUILD)))
1515

1616
# Set these from the environment to override
17-
KERNEL_VERSION ?= 5.1.3
17+
KERNEL_VERSION ?= 5.1.15
1818
KERNEL_VERSION := $(KERNEL_VERSION)$(if $(DEBUG_KERNEL),$(if $(findstring -debug,$(KERNEL_VERSION)),,-debug),)
1919
BUILD_PATH ?= $(PWD)/../../../qemu-build/$(ARCH)
2020
DISTFILES_PATH ?= $(PWD)/distfiles

0 commit comments

Comments
 (0)