From f4d42db4377b3755564b55e7691c7865c1753545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Fri, 9 Jan 2026 23:07:49 +0100 Subject: [PATCH] =?UTF-8?q?services:=20static-networking:=20Add=20?= =?UTF-8?q?=E2=80=98scope=E2=80=99=20field=20to=20.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/services/base.scm (assert-network-route-scope): New procedure. ()[scope]: New field. (network-set-up/linux)[route-scope->constant]: New procedure. Use it to pass #:scope to ‘route-add’. * doc/guix.texi (Networking Setup): Document it. Fixes: guix/guix#4175 Reported-by: Christopher Baines Change-Id: I24399eca6e691d63fa3d01be564060a3d693d650 Signed-off-by: Ludovic Courtès Merges: #5507 --- doc/guix.texi | 16 ++++++++++++++++ gnu/services/base.scm | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index aab2d8640c..898550a64e 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -22102,6 +22102,22 @@ determined based on @code{destination} or @code{gateway}. @item @code{gateway} (default: @code{#f}) IP address (a string) through which traffic is routed. + +@item @code{scope} (default: @code{'universe}) +Scope of the route, as a symbol: + +@table @code @c see rtnetlink(7) +@item universe +global route; +@item site +route within the local autonomous system; +@item link +route on this link; +@item host +route on the local host; +@item nowhere +means the destination does not exist. +@end table @end table @end deftp diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 40f3c7c7e2..458515c4a1 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013-2025 Ludovic Courtès +;;; Copyright © 2013-2026 Ludovic Courtès ;;; Copyright © 2015, 2016 Alex Kost ;;; Copyright © 2015, 2016, 2020 Mark H Weaver ;;; Copyright © 2015 Sou Bunnbu @@ -3205,6 +3205,15 @@ Write, say, @samp{\"~a/24\"} for a 24-bit network mask.") (condition (&error-location (location (source-properties->location properties))))))))) +(define-with-syntax-properties (assert-network-route-scope (value properties)) + (if (memq value '(universe site link host nowhere)) + value + (raise + (make-compound-condition + (formatted-message (G_ "~s: invalid network scope") value) + (condition (&error-location + (location (source-properties->location properties)))))))) + (define-record-type* static-networking make-static-networking static-networking? @@ -3253,7 +3262,10 @@ Write, say, @samp{\"~a/24\"} for a 24-bit network mask.") (or (ipv6-address? (network-route-destination this-record)) (and=> (network-route-gateway this-record) ipv6-address?)))) - (gateway network-route-gateway (default #f))) + (gateway network-route-gateway (default #f)) + (scope network-route-scope + (default 'universe) + (sanitize assert-network-route-scope))) (eval-when (expand load eval) (define* (cidr->netmask str #:optional (family AF_INET)) @@ -3363,12 +3375,23 @@ to CONFIG." ;; Maximum waiting time in seconds for devices to be up. 60) + (define (route-scope->constant scope) + (match scope + ('universe #~RT_SCOPE_UNIVERSE) + ('site #~RT_SCOPE_SITE) + ('link #~RT_SCOPE_LINK) + ('host #~RT_SCOPE_HOST) + ('nowhere #~RT_SCOPE_NOWHERE))) + (match-record config (addresses links routes) (program-file "set-up-network" (with-extensions (list guile-netlink) #~(begin (use-modules (ip addr) (ip link) (ip route) + ((netlink constant) + #:select (RT_SCOPE_UNIVERSE + RT_SCOPE_LINK)) (srfi srfi-1) (ice-9 format) (ice-9 match)) @@ -3475,7 +3498,11 @@ to CONFIG." #:via #$(network-route-gateway route) #:src - #$(network-route-source route))) + #$(network-route-source route) + #:scope + #$(route-scope->constant + (network-route-scope + route)))) routes) #t)))))