GNU bug report logs - #51440
[PATCH 00/10] Declarative static networking interface

Previous Next

Package: guix-patches;

Reported by: Ludovic Courtès <ludo <at> gnu.org>

Date: Wed, 27 Oct 2021 14:00:02 UTC

Severity: normal

Tags: patch

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 51440 in the body.
You can then email your comments to 51440 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to julien <at> lepiller.eu, guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:00:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Ludovic Courtès <ludo <at> gnu.org>:
New bug report received and forwarded. Copy sent to julien <at> lepiller.eu, guix-patches <at> gnu.org. (Wed, 27 Oct 2021 14:00:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: guix-patches <at> gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 00/10] Declarative static networking interface
Date: Wed, 27 Oct 2021 15:59:18 +0200
Hi!

This patch set builds on Julien’s neat Guile-Netlink to finally
provide a proper static networking configuration interface.  One
can now write things like:

  (service static-networking-service-type
           ;; Network configuration for one NIC, IPv4 + IPv6.
           (static-networking
            (addresses (list (network-address
                              (device "eno1")
                              (value "10.0.2.15/24"))
                             (network-address
                              (device "eno1")
                              (value "2001:123:4567:101::1"))))
            (routes (list (network-route
                           (destination "default")
                           (gateway "10.0.2.2"))
                          (network-route
                           (destination "default")
                           (gateway "2020:321:4567:42::1"))))
            (name-servers '("10.0.2.3"))))

For the record, the ‘static-networking-service’ procedure currently
in ‘master’ is IPv4-only and would not allow you to assign more
than one address to an interface anyway, among other limitations.
These long-overdue patches close an embarrassing gap.

The interface provided here is a direct mapping of that of Guile-Netlink,
which is the same as that of the ‘ip’ command, itself closely
modeled after Linux’s internal interfaces AIUI.  Thus, it should be
roughly as expressive as ‘ip’, but declarative.

I’m not a network person though, so I’d appreciate if more
knowledgeable people would take a look at the interface.  In particular,
I’d like to have examples of ‘links’ to include in the manual—I’m not
quite sure how to use that.  Ideas?

This patches preserve backward-compatibility: the
‘static-networking-service’ procedure still works the same.  There’s
one observable difference though: there’s only one ‘networking’
Shepherd service now; you no longer get ‘networking-eno1’ and similar.
The ‘static-networking’ constructor was public since commit
c9436025a90b86047ba2203d58bbf238f8f9b2f9 but undocumented; thus I
changed the fields of <static-networking> without worrying about
compatibility.

I tested this with:

  make check-system \
    TESTS="static-networking openvswitch ganeti-kvm dhcpd childhurd"

I would appreciate more testing, including tests on the bare metal
for IPv6 support.

Ensuring portability to GNU/Hurd took me more time than I’d have
thought, but it works.  “Links” are not supported there, and only
“default” routes are supported.

I took a detour in commit “Use Guile-Netlink on GNU/Linux”: that
patch shows that I was blissfully hoping to use good’ol ioctls
on GNU/Hurd, but that turned out to be a dead end because they
don’t support IPv6 (which really isn’t a surprise but I don’t know,
I must have been lacking focus at that point of my journey!).

With all this I think we should be able to do “cool things with
containers”, but again, that’s not my area of expertise so please
do chime in if you container networking is your thing.

Feedback welcome!

Ludo’.

Ludovic Courtès (10):
  tests: Add 'static-networking' test.
  tests: openvswitch: Check whether ovs0 is up.
  doc: Add new "Networking Setup" node for the main setup options.
  gnu: guile-netlink: Allow cross-compilation.
  services: static-networking: Use Guile-Netlink on GNU/Linux.
  services: secret-service: Turn into a Shepherd service.
  services: static-networking: Change interface to mimic netlink.
  services: Define '%qemu-static-networking'.
  services: Define '%loopback-static-networking'.
  tests: Replace uses of deprecated 'static-networking-service'.

 doc/guix.texi                   | 505 ++++++++++++++++++++++----------
 gnu/build/hurd-boot.scm         |  10 +-
 gnu/build/secret-service.scm    |  17 +-
 gnu/packages/guile-xyz.scm      |  11 +-
 gnu/services/base.scm           | 391 +++++++++++++++++++------
 gnu/services/virtualization.scm |  45 ++-
 gnu/system/hurd.scm             |  12 +-
 gnu/system/install.scm          |   5 +-
 gnu/tests/ganeti.scm            |   7 +-
 gnu/tests/networking.scm        | 141 ++++++++-
 10 files changed, 851 insertions(+), 293 deletions(-)


base-commit: 0a42998a50e8bbe9e49142b21a570db00efe7491
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:01 GMT) Full text and rfc822 format available.

Message #8 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 01/10] tests: Add 'static-networking' test.
Date: Wed, 27 Oct 2021 16:02:36 +0200
* gnu/tests/networking.scm (run-static-networking-test): New procedure.
(%test-static-networking): New variable.
---
 gnu/tests/networking.scm | 99 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 2 deletions(-)

diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index 453e63f52d..5da1c91da6 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2018 Chris Marusich <cmmarusich <at> gmail.com>
 ;;; Copyright © 2018 Arun Isaac <arunisaac <at> systemreboot.net>
 ;;; Copyright © 2021 Maxime Devos <maximedevos <at> telenet.be>
+;;; Copyright © 2021 Ludovic Courtès <ludo <at> gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -37,8 +38,102 @@ (define-module (gnu tests networking)
   #:use-module (gnu packages guile)
   #:use-module (gnu services shepherd)
   #:use-module (ice-9 match)
-  #:export (%test-inetd %test-openvswitch %test-dhcpd %test-tor %test-iptables
-                        %test-ipfs))
+  #:export (%test-static-networking
+            %test-inetd
+            %test-openvswitch
+            %test-dhcpd
+            %test-tor
+            %test-iptables
+            %test-ipfs))
+
+
+;;;
+;;; Static networking.
+;;;
+
+(define (run-static-networking-test vm)
+  (define test
+    (with-imported-modules '((gnu build marionette)
+                             (guix build syscalls))
+      #~(begin
+          (use-modules (gnu build marionette)
+                       (guix build syscalls)
+                       (srfi srfi-64))
+
+          (define marionette
+            (make-marionette
+             '(#$vm "-nic" "user,model=virtio-net-pci")))
+
+          (mkdir #$output)
+          (chdir #$output)
+
+          (test-begin "static-networking")
+
+          (test-assert "service is up"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (start-service 'networking))
+             marionette))
+
+          (test-assert "network interfaces"
+            (marionette-eval
+             '(begin
+                (use-modules (guix build syscalls))
+                (network-interface-names))
+             marionette))
+
+          (test-equal "address of eth0"
+            "10.0.2.15"
+            (marionette-eval
+             '(let* ((sock (socket AF_INET SOCK_STREAM 0))
+                     (addr (network-interface-address sock "eth0")))
+                (close-port sock)
+                (inet-ntop (sockaddr:fam addr) (sockaddr:addr addr)))
+             marionette))
+
+          (test-equal "netmask of eth0"
+            "255.255.255.0"
+            (marionette-eval
+             '(let* ((sock (socket AF_INET SOCK_STREAM 0))
+                     (mask (network-interface-netmask sock "eth0")))
+                (close-port sock)
+                (inet-ntop (sockaddr:fam mask) (sockaddr:addr mask)))
+             marionette))
+
+          (test-equal "eth0 is up"
+            IFF_UP
+            (marionette-eval
+             '(let* ((sock  (socket AF_INET SOCK_STREAM 0))
+                     (flags (network-interface-flags sock "eth0")))
+                (logand flags IFF_UP))
+             marionette))
+
+          (test-end)
+
+          (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+  (gexp->derivation "static-networking" test))
+
+(define %test-static-networking
+  (system-test
+   (name "static-networking")
+   (description "Test the 'static-networking' service.")
+   (value
+    (let ((os (marionette-operating-system
+               (simple-operating-system
+                (static-networking-service "eth0" "10.0.2.15"
+                                           #:netmask "255.255.255.0"
+                                           #:gateway "10.0.2.2"
+                                           #:name-servers '("10.0.2.2")))
+               #:imported-modules '((gnu services herd)
+                                    (guix combinators)))))
+      (run-static-networking-test (virtual-machine os))))))
+
+
+;;;
+;;; Inetd.
+;;;
 
 (define %inetd-os
   ;; Operating system with 2 inetd services.
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:02 GMT) Full text and rfc822 format available.

Message #11 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 02/10] tests: openvswitch: Check whether ovs0 is up.
Date: Wed, 27 Oct 2021 16:02:37 +0200
* gnu/tests/networking.scm (run-openvswitch-test)["ovs0 is up"]: New test.
---
 gnu/tests/networking.scm | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index 5da1c91da6..131428c128 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -286,12 +286,15 @@ (define %openvswitch-os
 (define (run-openvswitch-test)
   (define os
     (marionette-operating-system %openvswitch-os
-                                 #:imported-modules '((gnu services herd))))
+                                 #:imported-modules '((gnu services herd)
+                                                      (guix build syscalls))))
 
   (define test
-    (with-imported-modules '((gnu build marionette))
+    (with-imported-modules '((gnu build marionette)
+                             (guix build syscalls))
       #~(begin
           (use-modules (gnu build marionette)
+                       (guix build syscalls)
                        (ice-9 popen)
                        (ice-9 rdelim)
                        (srfi srfi-64))
@@ -339,6 +342,18 @@ (define marionette
                        (current-services))))
              marionette))
 
+          (test-equal "ovs0 is up"
+            IFF_UP
+            (marionette-eval
+             '(begin
+                (use-modules (guix build syscalls))
+
+                (let* ((sock  (socket AF_INET SOCK_STREAM 0))
+                       (flags (network-interface-flags sock "ovs0")))
+                  (close-port sock)
+                  (logand flags IFF_UP)))
+             marionette))
+
           (test-end)
           (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
 
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:02 GMT) Full text and rfc822 format available.

Message #14 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 04/10] gnu: guile-netlink: Allow cross-compilation.
Date: Wed, 27 Oct 2021 16:02:39 +0200
* gnu/packages/guile-xyz.scm (guile-netlink)[arguments]: Add #:phases.
Remove unnecessary #:tests? #f.
[native-inputs]: Add GUILE-3.0.
---
 gnu/packages/guile-xyz.scm | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/guile-xyz.scm b/gnu/packages/guile-xyz.scm
index 355b23f57e..daef8bbb26 100644
--- a/gnu/packages/guile-xyz.scm
+++ b/gnu/packages/guile-xyz.scm
@@ -4854,13 +4854,22 @@ (define-public guile-netlink
          "03zmsha2d7whlwb52gna83jdas9bqi18rq3sss7kkicv814qb35g"))))
     (build-system gnu-build-system)
     (arguments
-     `(#:tests? #f)); no tests
+     `(#:phases (modify-phases %standard-phases
+                  (add-before 'bootstrap 'set-guile-target
+                    (lambda* (#:key target #:allow-other-keys)
+                      (when target
+                        ;; Pass '--target=TRIPLET' to 'guild compile'.
+                        (substitute* "guile.am"
+                          (("\\$\\(GUILD\\) compile")
+                           (string-append "$(GUILD) compile --target="
+                                          target " ")))))))))
     (inputs
      `(("guile" ,guile-3.0)))
     (native-inputs
      `(("automake" ,automake)
        ("autoconf" ,autoconf)
        ("pkg-config" ,pkg-config)
+       ("guile" ,guile-3.0)                    ;for 'guild compile' + guile.m4
        ("texinfo" ,texinfo)))
     (home-page "https://git.lepiller.eu/guile-netlink")
     (synopsis "Netlink protocol implementation for Guile")
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:03 GMT) Full text and rfc822 format available.

Message #17 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 03/10] doc: Add new "Networking Setup" node for the main setup
 options.
Date: Wed, 27 Oct 2021 16:02:38 +0200
This should make it easier to find how to get started setting up
networking.

* doc/guix.texi (Networking Setup): New section.
(Networking Services): Remove 'static-networking-service',
'dhcp-client-service-type', 'network-manager-service-type',
'connman-service-type', 'wicd-service', 'modem-manager-service-type',
'usb-modeswitch-service-type', and 'wpa-supplicant-service-type'.
---
 doc/guix.texi | 289 ++++++++++++++++++++++++++++----------------------
 1 file changed, 160 insertions(+), 129 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 22215214e0..f7de378bdd 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -342,7 +342,8 @@ Services
 * Base Services::               Essential system services.
 * Scheduled Job Execution::     The mcron service.
 * Log Rotation::                The rottlog service.
-* Networking Services::         Network setup, SSH daemon, etc.
+* Networking Setup::            Setting up network interfaces.
+* Networking Services::         Firewall, SSH daemon, etc.
 * Unattended Upgrades::         Automated system upgrades.
 * X Window::                    Graphical display.
 * Printing Services::           Local and remote printer support.
@@ -15516,7 +15517,8 @@ declaration.
 * Base Services::               Essential system services.
 * Scheduled Job Execution::     The mcron service.
 * Log Rotation::                The rottlog service.
-* Networking Services::         Network setup, SSH daemon, etc.
+* Networking Setup::            Setting up network interfaces.
+* Networking Services::         Firewall, SSH daemon, etc.
 * Unattended Upgrades::         Automated system upgrades.
 * X Window::                    Graphical display.
 * Printing Services::           Local and remote printer support.
@@ -16738,63 +16740,26 @@ The list of syslog-controlled files to be rotated.  By default it is:
 "/var/log/maillog")}.
 @end defvr
 
-@node Networking Services
-@subsection Networking Services
+@node Networking Setup
+@subsection Networking Setup
 
-The @code{(gnu services networking)} module provides services to configure
-the network interface.
+The @code{(gnu services networking)} module provides services to
+configure network interfaces and set up networking on your machine.
+Those services provide different ways for you to set up your machine: by
+declaring a static network configuration, by running a Dynamic Host
+Configuration Protocol (DHCP) client, or by running daemons such as
+NetworkManager and Connman that automate the whole process,
+automatically adapt to connectivity changes, and provide a high-level
+user interface.
 
-@cindex DHCP, networking service
-@defvr {Scheme Variable} dhcp-client-service-type
-This is the type of services that run @var{dhcp}, a Dynamic Host Configuration
-Protocol (DHCP) client, on all the non-loopback network interfaces.  Its value
-is the DHCP client package to use, @code{isc-dhcp} by default.
-@end defvr
+On a laptop, NetworkManager and Connman are by far the most convenient
+options, which is why the default desktop services include
+NetworkManager (@pxref{Desktop Services, @code{%desktop-services}}).
+For a server, or for a virtual machine or a container, static network
+configuration or a simple DHCP client are often more appropriate.
 
-@deffn {Scheme Procedure} dhcpd-service-type
-This type defines a service that runs a DHCP daemon.  To create a
-service of this type, you must supply a @code{<dhcpd-configuration>}.
-For example:
-
-@lisp
-(service dhcpd-service-type
-         (dhcpd-configuration
-          (config-file (local-file "my-dhcpd.conf"))
-          (interfaces '("enp0s25"))))
-@end lisp
-@end deffn
-
-@deftp {Data Type} dhcpd-configuration
-@table @asis
-@item @code{package} (default: @code{isc-dhcp})
-The package that provides the DHCP daemon.  This package is expected to
-provide the daemon at @file{sbin/dhcpd} relative to its output
-directory.  The default package is the
-@uref{https://www.isc.org/products/DHCP, ISC's DHCP server}.
-@item @code{config-file} (default: @code{#f})
-The configuration file to use.  This is required.  It will be passed to
-@code{dhcpd} via its @code{-cf} option.  This may be any ``file-like''
-object (@pxref{G-Expressions, file-like objects}).  See @code{man
-dhcpd.conf} for details on the configuration file syntax.
-@item @code{version} (default: @code{"4"})
-The DHCP version to use.  The ISC DHCP server supports the values ``4'',
-``6'', and ``4o6''.  These correspond to the @code{dhcpd} program
-options @code{-4}, @code{-6}, and @code{-4o6}.  See @code{man dhcpd} for
-details.
-@item @code{run-directory} (default: @code{"/run/dhcpd"})
-The run directory to use.  At service activation time, this directory
-will be created if it does not exist.
-@item @code{pid-file} (default: @code{"/run/dhcpd/dhcpd.pid"})
-The PID file to use.  This corresponds to the @code{-pf} option of
-@code{dhcpd}.  See @code{man dhcpd} for details.
-@item @code{interfaces} (default: @code{'()})
-The names of the network interfaces on which dhcpd should listen for
-broadcasts.  If this list is not empty, then its elements (which must be
-strings) will be appended to the @code{dhcpd} invocation when starting
-the daemon.  It may not be necessary to explicitly specify any
-interfaces here; see @code{man dhcpd} for details.
-@end table
-@end deftp
+This section describes the various network setup services available,
+starting with static network configuration.
 
 @defvr {Scheme Variable} static-networking-service-type
 This is the type for statically-configured network interfaces.
@@ -16824,81 +16789,13 @@ For example:
 @end lisp
 @end deffn
 
-@cindex wicd
-@cindex wireless
-@cindex WiFi
-@cindex network management
-@deffn {Scheme Procedure} wicd-service [#:wicd @var{wicd}]
-Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
-management daemon that aims to simplify wired and wireless networking.
-
-This service adds the @var{wicd} package to the global profile, providing
-several commands to interact with the daemon and configure networking:
-@command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
-and @command{wicd-curses} user interfaces.
-@end deffn
-
-@cindex ModemManager
-
-@defvr {Scheme Variable} modem-manager-service-type
-This is the service type for the
-@uref{https://wiki.gnome.org/Projects/ModemManager, ModemManager}
-service.  The value for this service type is a
-@code{modem-manager-configuration} record.
-
-This service is part of @code{%desktop-services} (@pxref{Desktop
-Services}).
+@cindex DHCP, networking service
+@defvr {Scheme Variable} dhcp-client-service-type
+This is the type of services that run @var{dhcp}, a Dynamic Host Configuration
+Protocol (DHCP) client, on all the non-loopback network interfaces.  Its value
+is the DHCP client package to use, @code{isc-dhcp} by default.
 @end defvr
 
-@deftp {Data Type} modem-manager-configuration
-Data type representing the configuration of ModemManager.
-
-@table @asis
-@item @code{modem-manager} (default: @code{modem-manager})
-The ModemManager package to use.
-
-@end table
-@end deftp
-
-@cindex USB_ModeSwitch
-@cindex Modeswitching
-
-@defvr {Scheme Variable} usb-modeswitch-service-type
-This is the service type for the
-@uref{https://www.draisberghof.de/usb_modeswitch/, USB_ModeSwitch}
-service.  The value for this service type is
-a @code{usb-modeswitch-configuration} record.
-
-When plugged in, some USB modems (and other USB devices) initially present
-themselves as a read-only storage medium and not as a modem.  They need to be
-@dfn{modeswitched} before they are usable.  The USB_ModeSwitch service type
-installs udev rules to automatically modeswitch these devices when they are
-plugged in.
-
-This service is part of @code{%desktop-services} (@pxref{Desktop
-Services}).
-@end defvr
-
-@deftp {Data Type} usb-modeswitch-configuration
-Data type representing the configuration of USB_ModeSwitch.
-
-@table @asis
-@item @code{usb-modeswitch} (default: @code{usb-modeswitch})
-The USB_ModeSwitch package providing the binaries for modeswitching.
-
-@item @code{usb-modeswitch-data} (default: @code{usb-modeswitch-data})
-The package providing the device data and udev rules file used by
-USB_ModeSwitch.
-
-@item @code{config-file} (default: @code{#~(string-append #$usb-modeswitch:dispatcher "/etc/usb_modeswitch.conf")})
-Which config file to use for the USB_ModeSwitch dispatcher.  By default the
-config file shipped with USB_ModeSwitch is used which disables logging to
-@file{/var/log} among other default settings.  If set to @code{#f}, no config
-file is used.
-
-@end table
-@end deftp
-
 @cindex NetworkManager
 
 @defvr {Scheme Variable} network-manager-service-type
@@ -17035,6 +16932,139 @@ List of additional command-line arguments to pass to the daemon.
 @end table
 @end deftp
 
+@cindex wicd
+@cindex wireless
+@cindex WiFi
+@cindex network management
+@deffn {Scheme Procedure} wicd-service [#:wicd @var{wicd}]
+Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
+management daemon that aims to simplify wired and wireless networking.
+
+This service adds the @var{wicd} package to the global profile, providing
+several commands to interact with the daemon and configure networking:
+@command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
+and @command{wicd-curses} user interfaces.
+@end deffn
+
+@cindex ModemManager
+Some networking devices such as modems require special care, and this is
+what the services below focus on.
+
+@defvr {Scheme Variable} modem-manager-service-type
+This is the service type for the
+@uref{https://wiki.gnome.org/Projects/ModemManager, ModemManager}
+service.  The value for this service type is a
+@code{modem-manager-configuration} record.
+
+This service is part of @code{%desktop-services} (@pxref{Desktop
+Services}).
+@end defvr
+
+@deftp {Data Type} modem-manager-configuration
+Data type representing the configuration of ModemManager.
+
+@table @asis
+@item @code{modem-manager} (default: @code{modem-manager})
+The ModemManager package to use.
+
+@end table
+@end deftp
+
+@cindex USB_ModeSwitch
+@cindex Modeswitching
+
+@defvr {Scheme Variable} usb-modeswitch-service-type
+This is the service type for the
+@uref{https://www.draisberghof.de/usb_modeswitch/, USB_ModeSwitch}
+service.  The value for this service type is
+a @code{usb-modeswitch-configuration} record.
+
+When plugged in, some USB modems (and other USB devices) initially present
+themselves as a read-only storage medium and not as a modem.  They need to be
+@dfn{modeswitched} before they are usable.  The USB_ModeSwitch service type
+installs udev rules to automatically modeswitch these devices when they are
+plugged in.
+
+This service is part of @code{%desktop-services} (@pxref{Desktop
+Services}).
+@end defvr
+
+@deftp {Data Type} usb-modeswitch-configuration
+Data type representing the configuration of USB_ModeSwitch.
+
+@table @asis
+@item @code{usb-modeswitch} (default: @code{usb-modeswitch})
+The USB_ModeSwitch package providing the binaries for modeswitching.
+
+@item @code{usb-modeswitch-data} (default: @code{usb-modeswitch-data})
+The package providing the device data and udev rules file used by
+USB_ModeSwitch.
+
+@item @code{config-file} (default: @code{#~(string-append #$usb-modeswitch:dispatcher "/etc/usb_modeswitch.conf")})
+Which config file to use for the USB_ModeSwitch dispatcher.  By default the
+config file shipped with USB_ModeSwitch is used which disables logging to
+@file{/var/log} among other default settings.  If set to @code{#f}, no config
+file is used.
+
+@end table
+@end deftp
+
+
+@node Networking Services
+@subsection Networking Services
+
+The @code{(gnu services networking)} module discussed in the previous
+section provides services for more advanced setups: providing a DHCP
+service for others to use, filtering packets with iptables or nftables,
+running a WiFi access point with @command{hostapd}, running the
+@command{inetd} ``superdaemon'', and more.  This section describes
+those.
+
+@deffn {Scheme Procedure} dhcpd-service-type
+This type defines a service that runs a DHCP daemon.  To create a
+service of this type, you must supply a @code{<dhcpd-configuration>}.
+For example:
+
+@lisp
+(service dhcpd-service-type
+         (dhcpd-configuration
+          (config-file (local-file "my-dhcpd.conf"))
+          (interfaces '("enp0s25"))))
+@end lisp
+@end deffn
+
+@deftp {Data Type} dhcpd-configuration
+@table @asis
+@item @code{package} (default: @code{isc-dhcp})
+The package that provides the DHCP daemon.  This package is expected to
+provide the daemon at @file{sbin/dhcpd} relative to its output
+directory.  The default package is the
+@uref{https://www.isc.org/products/DHCP, ISC's DHCP server}.
+@item @code{config-file} (default: @code{#f})
+The configuration file to use.  This is required.  It will be passed to
+@code{dhcpd} via its @code{-cf} option.  This may be any ``file-like''
+object (@pxref{G-Expressions, file-like objects}).  See @code{man
+dhcpd.conf} for details on the configuration file syntax.
+@item @code{version} (default: @code{"4"})
+The DHCP version to use.  The ISC DHCP server supports the values ``4'',
+``6'', and ``4o6''.  These correspond to the @code{dhcpd} program
+options @code{-4}, @code{-6}, and @code{-4o6}.  See @code{man dhcpd} for
+details.
+@item @code{run-directory} (default: @code{"/run/dhcpd"})
+The run directory to use.  At service activation time, this directory
+will be created if it does not exist.
+@item @code{pid-file} (default: @code{"/run/dhcpd/dhcpd.pid"})
+The PID file to use.  This corresponds to the @code{-pf} option of
+@code{dhcpd}.  See @code{man dhcpd} for details.
+@item @code{interfaces} (default: @code{'()})
+The names of the network interfaces on which dhcpd should listen for
+broadcasts.  If this list is not empty, then its elements (which must be
+strings) will be appended to the @code{dhcpd} invocation when starting
+the daemon.  It may not be necessary to explicitly specify any
+interfaces here; see @code{man dhcpd} for details.
+@end table
+@end deftp
+
 @cindex hostapd service, for Wi-Fi access points
 @cindex Wi-Fi access points, hostapd service
 @defvr {Scheme Variable} hostapd-service-type
@@ -17097,6 +17127,7 @@ network that can be seen on @code{wlan0}, by default.
 The service's value is a @code{hostapd-configuration} record.
 @end defvr
 
+
 @cindex iptables
 @defvr {Scheme Variable} iptables-service-type
 This is the service type to set up an iptables configuration.  iptables is a
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:03 GMT) Full text and rfc822 format available.

Message #20 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 05/10] services: static-networking: Use Guile-Netlink on
 GNU/Linux.
Date: Wed, 27 Oct 2021 16:02:40 +0200
* gnu/services/base.scm (static-networking-shepherd-service): Define
'set-up-via-ioctl', 'tear-down-via-ioctl', 'set-up-via-netlink',
'tear-down-via-netlink', and 'helpers' and use them in 'start' and
'stop'.  Add (ip *) modules to 'modules'.
---
 gnu/services/base.scm | 102 +++++++++++++++++++++++++++++-------------
 1 file changed, 72 insertions(+), 30 deletions(-)

diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 50865055fe..d5ee03bbbd 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -53,6 +53,7 @@ (define-module (gnu services base)
   #:use-module (gnu packages bash)
   #:use-module ((gnu packages base)
                 #:select (coreutils glibc glibc-utf8-locales))
+  #:autoload   (gnu packages guile-xyz) (guile-netlink)
   #:use-module (gnu packages package-management)
   #:use-module ((gnu packages gnupg) #:select (guile-gcrypt))
   #:use-module (gnu packages linux)
@@ -2336,6 +2337,66 @@ (define static-networking-shepherd-service
     (($ <static-networking> interface ip netmask gateway provision
                             requirement name-servers)
      (let ((loopback? (and provision (memq 'loopback provision))))
+       (define set-up-via-ioctl
+         #~(let* ((addr     (inet-pton AF_INET #$ip))
+                  (sockaddr (make-socket-address AF_INET addr 0))
+                  (mask     (and #$netmask (inet-pton AF_INET #$netmask)))
+                  (maskaddr (and mask
+                                 (make-socket-address AF_INET mask 0)))
+                  (gateway  (and #$gateway
+                                 (inet-pton AF_INET #$gateway)))
+                  (gatewayaddr (and gateway
+                                    (make-socket-address AF_INET
+                                                         gateway 0))))
+             (configure-network-interface #$interface sockaddr
+                                          (logior IFF_UP
+                                                  #$(if loopback?
+                                                        #~IFF_LOOPBACK
+                                                        0))
+                                          #:netmask maskaddr)
+             (when gateway
+               (let ((sock (socket AF_INET SOCK_DGRAM 0)))
+                 (add-network-route/gateway sock gatewayaddr)
+                 (close-port sock)))))
+
+       (define tear-down-via-ioctl
+         #~(let ((sock (socket AF_INET SOCK_STREAM 0)))
+             (when #$gateway
+               (delete-network-route sock
+                                     (make-socket-address AF_INET
+                                                          INADDR_ANY 0)))
+             (set-network-interface-flags sock #$interface 0)
+             (close-port sock)
+             #f))
+
+       (define set-up-via-netlink
+         (with-extensions (list guile-netlink)
+           #~(let ((ip #$(if netmask
+                             #~(ip+netmask->cidr #$ip #$netmask)
+                             ip)))
+               (addr-add #$interface ip)
+               (when #$gateway
+                 (route-add "default" #:device #$interface
+                            #:via #$gateway))
+               (link-set #$interface #:up #t))))
+
+       (define tear-down-via-netlink
+         (with-extensions (list guile-netlink)
+           #~(begin
+               (link-set #$interface #:down #t)
+               (when #$gateway
+                 (route-del "default" #:device #$interface))
+               (addr-del #$interface #$ip)
+               #f)))
+
+       (define helpers
+         #~(define (ip+netmask->cidr ip netmask)
+             ;; Return the CIDR notation (a string) for IP and NETMASK, two
+             ;; IPv4 address strings.
+             (let* ((netmask (inet-pton AF_INET netmask))
+                    (bits    (logcount netmask)))
+               (string-append ip "/" (number->string bits)))))
+
        (shepherd-service
 
         (documentation
@@ -2347,38 +2408,19 @@ (define static-networking-shepherd-service
 
         (start #~(lambda _
                    ;; Return #t if successfully started.
-                   (let* ((addr     (inet-pton AF_INET #$ip))
-                          (sockaddr (make-socket-address AF_INET addr 0))
-                          (mask     (and #$netmask
-                                         (inet-pton AF_INET #$netmask)))
-                          (maskaddr (and mask
-                                         (make-socket-address AF_INET
-                                                              mask 0)))
-                          (gateway  (and #$gateway
-                                         (inet-pton AF_INET #$gateway)))
-                          (gatewayaddr (and gateway
-                                            (make-socket-address AF_INET
-                                                                 gateway 0))))
-                     (configure-network-interface #$interface sockaddr
-                                                  (logior IFF_UP
-                                                          #$(if loopback?
-                                                                #~IFF_LOOPBACK
-                                                                0))
-                                                  #:netmask maskaddr)
-                     (when gateway
-                       (let ((sock (socket AF_INET SOCK_DGRAM 0)))
-                         (add-network-route/gateway sock gatewayaddr)
-                         (close-port sock))))))
+                   #$helpers
+                   (if (string-contains %host-type "-linux")
+                       #$set-up-via-netlink
+                       #$set-up-via-ioctl)))
         (stop #~(lambda _
                   ;; Return #f is successfully stopped.
-                  (let ((sock (socket AF_INET SOCK_STREAM 0)))
-                    (when #$gateway
-                      (delete-network-route sock
-                                            (make-socket-address
-                                             AF_INET INADDR_ANY 0)))
-                    (set-network-interface-flags sock #$interface 0)
-                    (close-port sock)
-                    #f)))
+                  (if (string-contains %host-type "-linux")
+                      #$tear-down-via-netlink
+                      #$tear-down-via-ioctl)))
+        (modules `((ip addr)
+                   (ip link)
+                   (ip route)
+                   ,@%default-modules))
         (respawn? #f))))))
 
 (define (static-networking-etc-files interfaces)
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:03 GMT) Full text and rfc822 format available.

Message #23 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 06/10] services: secret-service: Turn into a Shepherd service.
Date: Wed, 27 Oct 2021 16:02:41 +0200
* gnu/services/virtualization.scm (secret-service-activation): Remove.
(secret-service-shepherd-services): New procedure.
(secret-service-type)[extensions]: Remove ACTIVATION-SERVICE-TYPE
extension.  Add SHEPHERD-ROOT-SERVICE-TYPE and
USER-PROCESSES-SERVICE-TYPE extensions.
* gnu/build/secret-service.scm (delete-file*): New procedure.
(secret-service-receive-secrets): Use it.
---
 gnu/build/secret-service.scm    | 17 ++++++++++++-
 gnu/services/virtualization.scm | 45 ++++++++++++++++++++++++---------
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/gnu/build/secret-service.scm b/gnu/build/secret-service.scm
index 46dcf1b9c3..4e183e11e8 100644
--- a/gnu/build/secret-service.scm
+++ b/gnu/build/secret-service.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2020 Ludovic Courtès <ludo <at> gnu.org>
+;;; Copyright © 2020, 2021 Ludovic Courtès <ludo <at> gnu.org>
 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke <at> gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -111,6 +111,15 @@ (define (send-files sock)
        (close-port sock)
        #f))))
 
+(define (delete-file* file)
+  "Ensure FILE does not exist."
+  (catch 'system-error
+    (lambda ()
+      (delete-file file))
+    (lambda args
+      (unless (= ENOENT (system-error-errno args))
+        (apply throw args)))))
+
 (define (secret-service-receive-secrets port)
   "Listen to local PORT and wait for a secret service client to send secrets.
 Write them to the file system.  Return the list of files installed on success,
@@ -170,6 +179,12 @@ (define (read-secrets port)
                    (log "installing file '~a' (~a bytes)...~%"
                         file size)
                    (mkdir-p (dirname file))
+
+                   ;; It could be that FILE already exists, for instance
+                   ;; because it has been created by a service's activation
+                   ;; snippet (e.g., SSH host keys).  Delete it.
+                   (delete-file* file)
+
                    (call-with-output-file file
                      (lambda (output)
                        (dump port output size)
diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm
index bca5f56b87..e7d2a7b833 100644
--- a/gnu/services/virtualization.scm
+++ b/gnu/services/virtualization.scm
@@ -852,23 +852,44 @@ (define qemu-binfmt-service-type
 ;;; Secrets for guest VMs.
 ;;;
 
-(define (secret-service-activation port)
-  "Return an activation snippet that fetches sensitive material at local PORT,
+(define (secret-service-shepherd-services port)
+  "Return a Shepherd service that fetches sensitive material at local PORT,
 over TCP.  Reboot upon failure."
-  (with-imported-modules '((gnu build secret-service)
-                           (guix build utils))
-    #~(begin
-        (use-modules (gnu build secret-service))
-        (let ((sent (secret-service-receive-secrets #$port)))
-          (unless sent
-            (sleep 3)
-            (reboot))))))
+  ;; This is a Shepherd service, rather than an activation snippet, to make
+  ;; sure it is started once 'networking' is up so it can accept incoming
+  ;; connections.
+  (list
+   (shepherd-service
+    (documentation "Fetch secrets from the host at startup time.")
+    (provision '(secret-service-client))
+    (requirement '(loopback networking))
+    (modules '((gnu build secret-service)
+               (guix build utils)))
+    (start (with-imported-modules '((gnu build secret-service)
+                                    (guix build utils))
+             #~(lambda ()
+                 ;; Since shepherd's output port goes to /dev/log, write this
+                 ;; message to stderr so it's visible on the Mach console.
+                 (format (current-error-port)
+                         "receiving secrets from the host...~%")
+                 (force-output (current-error-port))
+
+                 (let ((sent (secret-service-receive-secrets #$port)))
+                   (unless sent
+                     (sleep 3)
+                     (reboot))))))
+    (stop #~(const #f)))))
 
 (define secret-service-type
   (service-type
    (name 'secret-service)
-   (extensions (list (service-extension activation-service-type
-                                        secret-service-activation)))
+   (extensions (list (service-extension shepherd-root-service-type
+                                        secret-service-shepherd-services)
+
+                     ;; Make every Shepherd service depend on
+                     ;; 'secret-service-client'.
+                     (service-extension user-processes-service-type
+                                        (const '(secret-service-client)))))
    (description
     "This service fetches secret key and other sensitive material over TCP at
 boot time.  This service is meant to be used by virtual machines (VMs) that
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:04 GMT) Full text and rfc822 format available.

Message #26 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 07/10] services: static-networking: Change interface to mimic
 netlink.
Date: Wed, 27 Oct 2021 16:02:42 +0200
* gnu/services/base.scm (<static-networking>)[interface, ip, netmask]
[gateway]: Remove.
[addresses, links, routes]: New fields.
[requirement]: Default to '(udev).
(<network-address>, <network-link>, <network-route>): New record types.
(ensure-no-separate-netmask, %ensure-no-separate-netmask): Remove.
(ipv6-address?, cidr->netmask, ip+netmask->cidr)
(network-set-up/hurd, network-tear-down/hurd)
(network-set-up/linux, network-tear-down/linux)
(static-networking->hurd-pfinet-options): New procedures.
(static-networking-shepherd-service): New procedure.
(static-networking-shepherd-services): Rewrite in terms of the above.
(static-networking-service): Deprecate.  Adjust to new
'static-networking' API.
(%base-services): Likewise.
* gnu/system/install.scm (%installation-services): Likewise.
* gnu/system/hurd.scm (%base-services/hurd): Likewise, and separate
'loopback' from 'networking'.
* gnu/build/hurd-boot.scm (set-hurd-device-translators): Remove
"servers/socket/2".
* gnu/tests/networking.scm (run-openvswitch-test)["networking has
started on ovs0"]: Check for 'networking instead of 'networking-ovs0,
which is no longer provided.
* doc/guix.texi (Networking Setup): Document the new interface.  Remove
documentation of 'static-networking-service'.
(Virtualization Services): Change Ganeti example to use the new
interface.
---
 doc/guix.texi            | 191 +++++++++++++++---
 gnu/build/hurd-boot.scm  |  10 +-
 gnu/services/base.scm    | 410 +++++++++++++++++++++++++++------------
 gnu/system/hurd.scm      |  27 ++-
 gnu/system/install.scm   |  11 +-
 gnu/tests/networking.scm |   2 +-
 6 files changed, 481 insertions(+), 170 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index f7de378bdd..b529a8db6c 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -16762,32 +16762,166 @@ This section describes the various network setup services available,
 starting with static network configuration.
 
 @defvr {Scheme Variable} static-networking-service-type
-This is the type for statically-configured network interfaces.
-@c TODO Document <static-networking> data structures.
+This is the type for statically-configured network interfaces.  Its
+value must be a list of @code{static-networking} records.  Each of them
+declares a set of @dfn{addresses}, @dfn{routes}, and @dfn{links}, as
+show below.
+
+@cindex network interface controller (NIC)
+@cindex NIC, networking interface controller
+Here is the simplest configuration, with only one network interface
+controller (NIC) and only IPv4 connectivity:
+
+@example
+;; Static networking for one NIC, IPv4-only.
+(service static-networking-service-type
+         (list (static-networking
+                (addresses
+                 (list (network-address
+                        (device "eno1")
+                        (value "10.0.2.15/24"))))
+                (routes
+                 (list (network-route
+                        (destination "default")
+                        (gateway "10.0.2.2"))))
+                (name-servers '("10.0.2.3")))))
+@end example
+
+The snippet above can be added to the @code{services} field of your
+operating system configuration (@pxref{Using the Configuration System}).
+It will configure your machine to have 10.0.2.15 as its IP address, with
+a 24-bit netmask for the local network---meaning that any 10.0.2.@var{x}
+address is on the local area network (LAN).  Traffic to addresses
+outside the local network is routed @i{via} 10.0.2.2.  Host names are
+resolved by sending domain name system (DNS) queries to 10.0.2.3.
 @end defvr
 
-@deffn {Scheme Procedure} static-networking-service @var{interface} @var{ip} @
-       [#:netmask #f] [#:gateway #f] [#:name-servers @code{'()}] @
-       [#:requirement @code{'(udev)}]
-Return a service that starts @var{interface} with address @var{ip}.  If
-@var{netmask} is true, use it as the network mask.  If @var{gateway} is true,
-it must be a string specifying the default network gateway.  @var{requirement}
-can be used to declare a dependency on another service before configuring the
-interface.
+@deftp {Data Type} static-networking
+This is the data type representing a static network configuration.
 
-This procedure can be called several times, one for each network
-interface of interest.  Behind the scenes what it does is extend
-@code{static-networking-service-type} with additional network interfaces
-to handle.
-
-For example:
+As an example, here is how you would declare the configuration of a
+machine with a single network interface controller (NIC) available as
+@code{eno1}, and with one IPv4 and one IPv6 address:
 
 @lisp
-(static-networking-service "eno1" "192.168.1.82"
-                           #:gateway "192.168.1.2"
-                           #:name-servers '("192.168.1.2"))
+;; Network configuration for one NIC, IPv4 + IPv6.
+(static-networking
+ (addresses (list (network-address
+                   (device "eno1")
+                   (value "10.0.2.15/24"))
+                  (network-address
+                   (device "eno1")
+                   (value "2001:123:4567:101::1"))))
+ (routes (list (network-route
+                (destination "default")
+                (gateway "10.0.2.2"))
+               (network-route
+                (destination "default")
+                (gateway "2020:321:4567:42::1"))))
+ (name-servers '("10.0.2.3")))
 @end lisp
-@end deffn
+
+If you are familiar with the @command{ip} command of the
+@uref{https://wiki.linuxfoundation.org/networking/iproute2,
+@code{iproute2} package} found on Linux-based systems, the declaration
+above is equivalent to typing:
+
+@example
+ip address add 10.0.2.15/24 dev eno1
+ip address add 2001:123:4567:101::1 dev eno1
+ip route add default via inet 10.0.2.2
+ip route add default via inet6 2020:321:4567:42::1
+@end example
+
+Run @command{man 8 ip} for more info.  Venerable GNU/Linux users will
+certainly know how to do it with @command{ifconfig} and @command{route},
+but we'll spare you that.
+
+The available fields of this data type are as follows:
+
+@table @asis
+@item @code{addresses}
+@itemx @code{links} (default: @code{'()})
+@itemx @code{links} (default: @code{'()})
+The list of @code{network-address}, @code{network-link}, and
+@code{network-route} records for this network (see below).
+
+@item @code{name-servers} (default: @code{'()})
+The list of IP addresses (strings) of domain name servers.  These IP
+addresses go to @file{/etc/resolv.conf}.
+
+@item @code{provision} (default: @code{#f})
+If true, this should be a list of symbols for the Shepherd service
+corresponding to this network configuration.  When @code{#f},
+@code{'(networking)} or @code{'(loopback)} is used.
+
+@item @code{requirement} (default @code{'()})
+The list of Shepherd services depended on.
+@end table
+@end deftp
+
+@deftp {Data Type} network-address
+This is the data type representing the IP address of a network
+interface.
+
+@table @code
+@item device
+The name of the network interface for this address---e.g.,
+@code{"eno1"}.
+
+@item value
+The actual IP address and network mask, in
+@uref{https://en.wikipedia.org/wiki/CIDR#CIDR_notation, @acronym{CIDR,
+Classless Inter-Domain Routing} notation}, as a string.
+
+For example, @code{"10.0.2.15/24"} denotes IPv4 address 10.0.2.15 on a
+24-bit sub-network---all 10.0.2.@var{x} addresses are on the same local
+network.
+
+@item ipv6?
+Whether @code{value} denotes an IPv6 address.  By default this is
+automatically determined.
+@end table
+@end deftp
+
+@deftp {Data Type} network-route
+This is the data type representing a network route.
+
+@table @asis
+@item @code{destination}
+The route destination (a string), either an IP address or
+@code{"default"} to denote the default route.
+
+@item @code{source} (default: @code{#f})
+The route source.
+
+@item @code{device} (default: @code{#f})
+The device used for this route---e.g., @code{"eno2"}.
+
+@item @code{ipv6?} (default: auto)
+Whether this is an IPv6 route.  By default this is automatically
+determined based on @code{destination} or @code{gateway}.
+
+@item @code{gateway} (default: @code{#f})
+IP address (a string) through which traffic is routed.
+@end table
+@end deftp
+
+@deftp {Data Type} network-link
+Data type for a network link (@pxref{Link,,, guile-netlink,
+Guile-Netlink Manual}).
+
+@table @code
+@item name
+The name of the link---e.g., @code{"v0p0"}.
+
+@item type
+A symbol denoting the type of the link---e.g., @code{'veth}.
+
+@item arguments
+List of arguments for this type of link.
+@end table
+@end deftp
 
 @cindex DHCP, networking service
 @defvr {Scheme Variable} dhcp-client-service-type
@@ -30300,11 +30434,18 @@ cluster node that supports multiple storage backends, and installs the
                            "ganeti-instance-guix" "ganeti-instance-debootstrap"))
                     %base-packages))
   (services
-   (append (list (static-networking-service "eth0" "192.168.1.201"
-                                            #:netmask "255.255.255.0"
-                                            #:gateway "192.168.1.254"
-                                            #:name-servers '("192.168.1.252"
-                                                             "192.168.1.253"))
+   (append (list (service static-networking-service-type
+                          (list (static-networking
+                                 (addresses
+                                  (list (network-address
+                                         (device "eth0")
+                                         (value "192.168.1.201/24"))))
+                                 (routes
+                                  (list (network-route
+                                         (destination "default")
+                                         (gateway "192.168.1.254"))))
+                                 (name-servers '("192.168.1.252"
+                                                 "192.168.1.253")))))
 
                  ;; Ganeti uses SSH to communicate between nodes.
                  (service openssh-service-type
diff --git a/gnu/build/hurd-boot.scm b/gnu/build/hurd-boot.scm
index 8b27995438..ac36bd17d4 100644
--- a/gnu/build/hurd-boot.scm
+++ b/gnu/build/hurd-boot.scm
@@ -185,13 +185,9 @@ (define servers
       ("servers/crash-suspend"   ("/hurd/crash" "--suspend"))
       ("servers/password"        ("/hurd/password"))
       ("servers/socket/1"        ("/hurd/pflocal"))
-      ("servers/socket/2"        ("/hurd/pfinet"
-                                  "--interface" "eth0"
-                                  "--address"
-                                  "10.0.2.15" ;the default QEMU guest IP
-                                  "--netmask" "255.255.255.0"
-                                  "--gateway" "10.0.2.2"
-                                  "--ipv6" "/servers/socket/26"))
+      ;; /servers/socket/2 and /26 are created by 'static-networking-service'.
+      ;; XXX: Spawn pfinet without arguments on these nodes so that a DHCP
+      ;; client has someone to talk to?
       ("proc"                    ("/hurd/procfs" "--stat-mode=444"))))
 
   (define devices
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index d5ee03bbbd..03f6b388a8 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -35,6 +35,8 @@
 (define-module (gnu services base)
   #:use-module (guix store)
   #:use-module (guix deprecation)
+  #:autoload   (guix diagnostics) (warning)
+  #:autoload   (guix i18n) (G_)
   #:use-module (gnu services)
   #:use-module (gnu services admin)
   #:use-module (gnu services shepherd)
@@ -54,6 +56,7 @@ (define-module (gnu services base)
   #:use-module ((gnu packages base)
                 #:select (coreutils glibc glibc-utf8-locales))
   #:autoload   (gnu packages guile-xyz) (guile-netlink)
+  #:autoload   (gnu packages hurd) (hurd)
   #:use-module (gnu packages package-management)
   #:use-module ((gnu packages gnupg) #:select (guile-gcrypt))
   #:use-module (gnu packages linux)
@@ -81,14 +84,32 @@ (define-module (gnu services base)
             virtual-terminal-service-type
 
             static-networking
-
             static-networking?
-            static-networking-interface
-            static-networking-ip
-            static-networking-netmask
-            static-networking-gateway
+            static-networking-addresses
+            static-networking-links
+            static-networking-routes
             static-networking-requirement
 
+            network-address
+            network-address?
+            network-address-device
+            network-address-value
+            network-address-ipv6?
+
+            network-link
+            network-link?
+            network-link-name
+            network-link-type
+            network-link-arguments
+
+            network-route
+            network-route?
+            network-route-destination
+            network-route-source
+            network-route-device
+            network-route-ipv6?
+            network-route-gateway
+
             static-networking-service
             static-networking-service-type
 
@@ -2316,113 +2337,254 @@ (define kmscon-command
    (description "Start the @command{kmscon} virtual terminal emulator for the
 Linux @dfn{kernel mode setting} (KMS).")))
 
+
+;;;
+;;; Static networking.
+;;;
+
+(define (ipv6-address? str)
+  "Return true if STR denotes an IPv6 address."
+  (false-if-exception (->bool (inet-pton AF_INET6 str))))
+
 (define-record-type* <static-networking>
   static-networking make-static-networking
   static-networking?
-  (interface static-networking-interface)
-  (ip static-networking-ip)
-  (netmask static-networking-netmask
-           (default #f))
-  (gateway static-networking-gateway              ;FIXME: doesn't belong here
-           (default #f))
+  (addresses static-networking-addresses)         ;list of <network-address>
+  (links     static-networking-links (default '())) ;list of <network-link>
+  (routes    static-networking-routes (default '())) ;list of <network-routes>
   (provision static-networking-provision
              (default #f))
   (requirement static-networking-requirement
-               (default '()))
+               (default '(udev)))
   (name-servers static-networking-name-servers    ;FIXME: doesn't belong here
                 (default '())))
 
-(define static-networking-shepherd-service
+(define-record-type* <network-address>
+  network-address make-network-address
+  network-address?
+  (device    network-address-device)              ;string--e.g., "en01"
+  (value     network-address-value)               ;string--CIDR notation
+  (ipv6?     network-address-ipv6?                ;Boolean
+             (thunked)
+             (default
+               (ipv6-address? (cidr->ip (network-address-value this-record))))))
+
+(define-record-type* <network-link>
+  network-link make-network-link
+  network-link?
+  (name      network-link-name)                   ;string--e.g, "v0p0"
+  (type      network-link-type)                   ;symbol--e.g.,'veth
+  (arguments network-link-arguments))             ;list
+
+(define-record-type* <network-route>
+  network-route make-network-route
+  network-route?
+  (destination network-route-destination)
+  (source      network-route-source (default #f))
+  (device      network-route-device (default #f))
+  (ipv6?       network-route-ipv6? (thunked)
+               (default
+                 (or (ipv6-address? (network-route-destination this-record))
+                     (and=> (network-route-gateway this-record)
+                            ipv6-address?))))
+  (gateway     network-route-gateway (default #f)))
+
+(define* (cidr->netmask str #:optional (family AF_INET))
+  "Given @var{str}, a string in CIDR notation (e.g., \"1.2.3.4/24\"), return
+the netmask as a string like \"255.255.255.0\"."
+  (match (string-split str #\/)
+    ((ip (= string->number bits))
+     (let ((mask (ash (- (expt 2 bits) 1)
+                      (- (if (= family AF_INET6) 128 32)
+                         bits))))
+       (inet-ntop family mask)))
+    (_ #f)))
+
+(define (cidr->ip str)
+  "Strip the netmask bit of @var{str}, a CIDR-notation IP/netmask address."
+  (match (string-split str #\/)
+    ((or (ip _) (ip))
+     ip)))
+
+(define* (ip+netmask->cidr ip netmask #:optional (family AF_INET))
+  "Return the CIDR notation (a string) for @var{ip} and @var{netmask}, two
+@var{family} address strings, where @var{family} is @code{AF_INET} or
+@code{AF_INET6}."
+  (let* ((netmask (inet-pton family netmask))
+         (bits    (logcount netmask)))
+    (string-append ip "/" (number->string bits))))
+
+(define (static-networking->hurd-pfinet-options config)
+  "Return command-line options for the Hurd's pfinet translator corresponding
+to CONFIG."
+  (unless (null? (static-networking-links config))
+    ;; XXX: Presumably this is not supported, or perhaps could be approximated
+    ;; by running separate pfinet instances in some cases?
+    (warning (G_ "network links are currently ignored on GNU/Hurd~%")))
+
+  (match (static-networking-addresses config)
+    ((and addresses (first _ ...))
+     `("--ipv6" "/servers/socket/26"
+       "--interface" ,(network-address-device first)
+       ,@(append-map (lambda (address)
+                       `(,(if (network-address-ipv6? address)
+                              "--address6"
+                              "--address")
+                         ,(cidr->ip (network-address-value address))
+                         ,@(match (cidr->netmask (network-address-value address)
+                                                 (if (network-address-ipv6? address)
+                                                     AF_INET6
+                                                     AF_INET))
+                             (#f '())
+                             (mask (list "--netmask" mask)))))
+                     addresses)
+       ,@(append-map (lambda (route)
+                       (match route
+                         (($ <network-route> "default" #f device _ gateway)
+                          (if (network-route-ipv6? route)
+                              `("--gateway6" ,gateway)
+                              `("--gateway" ,gateway)))
+                         (($ <network-route> destination)
+                          (warning (G_ "ignoring network route for '~a'~%")
+                                   destination)
+                          '())))
+                     (static-networking-routes config))))))
+
+(define (network-set-up/hurd config)
+  "Set up networking for the Hurd."
+  ;; The Hurd implements SIOCGIFADDR and other old-style ioctls, but the only
+  ;; way to set up IPv6 is by starting pfinet with the right options.
+  (if (equal? (static-networking-provision config) '(loopback))
+      (scheme-file "set-up-pflocal" #~(begin 'nothing-to-do! #t))
+      (scheme-file "set-up-pfinet"
+                   (with-imported-modules '((guix build utils))
+                     #~(begin
+                         (use-modules (guix build utils)
+                                      (ice-9 format))
+
+                         ;; TODO: Do that without forking.
+                         (let ((options '#$(static-networking->hurd-pfinet-options
+                                            config)))
+                           (format #t "starting '~a~{ ~s~}'~%"
+                                   #$(file-append hurd "/hurd/pfinet")
+                                   options)
+                           (apply invoke #$(file-append hurd "/bin/settrans") "-fac"
+                                  "/servers/socket/2"
+                                  #$(file-append hurd "/hurd/pfinet")
+                                  options)))))))
+
+(define (network-tear-down/hurd config)
+  (scheme-file "tear-down-pfinet"
+               (with-imported-modules '((guix build utils))
+                 #~(begin
+                     (use-modules (guix build utils))
+
+                     ;; Forcefully terminate pfinet.  XXX: In theory this
+                     ;; should just undo the addresses and routes of CONFIG;
+                     ;; this could be done using ioctls like SIOCDELRT, but
+                     ;; these are IPv4-only; another option would be to use
+                     ;; fsysopts but that seems to crash pfinet.
+                     (invoke #$(file-append hurd "/bin/settrans") "-fg"
+                             "/servers/socket/2")
+                     #f))))
+
+(define network-set-up/linux
   (match-lambda
-    (($ <static-networking> interface ip netmask gateway provision
-                            requirement name-servers)
+    (($ <static-networking> addresses links routes)
+     (scheme-file "set-up-network"
+                  (with-extensions (list guile-netlink)
+                    #~(begin
+                        (use-modules (ip addr) (ip link) (ip route))
+
+                        #$@(map (lambda (address)
+                                  #~(begin
+                                      (addr-add #$(network-address-device address)
+                                                #$(network-address-value address)
+                                                #:ipv6?
+                                                #$(network-address-ipv6? address))
+                                      ;; FIXME: loopback?
+                                      (link-set #$(network-address-device address)
+                                                #:up #t)))
+                                addresses)
+                        #$@(map (match-lambda
+                                  (($ <network-link> name type arguments)
+                                   #~(link-add #:device #$name #$type
+                                               #:type-args '#$arguments)))
+                                links)
+                        #$@(map (lambda (route)
+                                  #~(route-add #$(network-route-destination route)
+                                               #:device
+                                               #$(network-route-device route)
+                                               #:ipv6?
+                                               #$(network-route-ipv6? route)
+                                               #:via
+                                               #$(network-route-gateway route)
+                                               #:src
+                                               #$(network-route-source route)))
+                                routes)
+                        #t))))))
+
+(define network-tear-down/linux
+  (match-lambda
+    (($ <static-networking> addresses links routes)
+     (scheme-file "set-up-network"
+                  (with-extensions (list guile-netlink)
+                    #~(begin
+                        (use-modules (ip addr) (ip link) (ip route))
+
+                        #$@(map (lambda (route)
+                                  #~(route-del #$(network-route-destination route)
+                                               #:device
+                                               #$(network-route-device route)
+                                               #:ipv6?
+                                               #$(network-route-ipv6? route)
+                                               #:via
+                                               #$(network-route-gateway route)
+                                               #:src
+                                               #$(network-route-source route)))
+                                routes)
+                        #$@(map (match-lambda
+                                  (($ <network-link> name type arguments)
+                                   #~(link-del #$name)))
+                                links)
+                        #$@(map (lambda (address)
+                                  #~(addr-del #$(network-address-device
+                                                 address)
+                                              #$(network-address-value address)
+                                              #:ipv6?
+                                              #$(network-address-ipv6? address)))
+                                addresses)
+                        #f))))))
+
+(define (static-networking-shepherd-service config)
+  (match config
+    (($ <static-networking> addresses links routes
+                            provision requirement name-servers)
      (let ((loopback? (and provision (memq 'loopback provision))))
-       (define set-up-via-ioctl
-         #~(let* ((addr     (inet-pton AF_INET #$ip))
-                  (sockaddr (make-socket-address AF_INET addr 0))
-                  (mask     (and #$netmask (inet-pton AF_INET #$netmask)))
-                  (maskaddr (and mask
-                                 (make-socket-address AF_INET mask 0)))
-                  (gateway  (and #$gateway
-                                 (inet-pton AF_INET #$gateway)))
-                  (gatewayaddr (and gateway
-                                    (make-socket-address AF_INET
-                                                         gateway 0))))
-             (configure-network-interface #$interface sockaddr
-                                          (logior IFF_UP
-                                                  #$(if loopback?
-                                                        #~IFF_LOOPBACK
-                                                        0))
-                                          #:netmask maskaddr)
-             (when gateway
-               (let ((sock (socket AF_INET SOCK_DGRAM 0)))
-                 (add-network-route/gateway sock gatewayaddr)
-                 (close-port sock)))))
-
-       (define tear-down-via-ioctl
-         #~(let ((sock (socket AF_INET SOCK_STREAM 0)))
-             (when #$gateway
-               (delete-network-route sock
-                                     (make-socket-address AF_INET
-                                                          INADDR_ANY 0)))
-             (set-network-interface-flags sock #$interface 0)
-             (close-port sock)
-             #f))
-
-       (define set-up-via-netlink
-         (with-extensions (list guile-netlink)
-           #~(let ((ip #$(if netmask
-                             #~(ip+netmask->cidr #$ip #$netmask)
-                             ip)))
-               (addr-add #$interface ip)
-               (when #$gateway
-                 (route-add "default" #:device #$interface
-                            #:via #$gateway))
-               (link-set #$interface #:up #t))))
-
-       (define tear-down-via-netlink
-         (with-extensions (list guile-netlink)
-           #~(begin
-               (link-set #$interface #:down #t)
-               (when #$gateway
-                 (route-del "default" #:device #$interface))
-               (addr-del #$interface #$ip)
-               #f)))
-
-       (define helpers
-         #~(define (ip+netmask->cidr ip netmask)
-             ;; Return the CIDR notation (a string) for IP and NETMASK, two
-             ;; IPv4 address strings.
-             (let* ((netmask (inet-pton AF_INET netmask))
-                    (bits    (logcount netmask)))
-               (string-append ip "/" (number->string bits)))))
-
        (shepherd-service
 
         (documentation
          "Bring up the networking interface using a static IP address.")
         (requirement requirement)
-        (provision (or provision
-                       (list (symbol-append 'networking-
-                                            (string->symbol interface)))))
+        (provision (or provision '(networking)))
 
         (start #~(lambda _
                    ;; Return #t if successfully started.
-                   #$helpers
-                   (if (string-contains %host-type "-linux")
-                       #$set-up-via-netlink
-                       #$set-up-via-ioctl)))
+                   (load #$(let-system (system target)
+                             (if (string-contains (or target system) "-linux")
+                                 (network-set-up/linux config)
+                                 (network-set-up/hurd config))))))
         (stop #~(lambda _
                   ;; Return #f is successfully stopped.
-                  (if (string-contains %host-type "-linux")
-                      #$tear-down-via-netlink
-                      #$tear-down-via-ioctl)))
-        (modules `((ip addr)
-                   (ip link)
-                   (ip route)
-                   ,@%default-modules))
+                  #$(let-system (system target)
+                      (if (string-contains (or target system) "-linux")
+                          (network-tear-down/linux config)
+                          (network-tear-down/hurd config)))))
         (respawn? #f))))))
 
+(define (static-networking-shepherd-services networks)
+  (map static-networking-shepherd-service networks))
+
 (define (static-networking-etc-files interfaces)
   "Return a /etc/resolv.conf entry for INTERFACES or the empty list."
   (match (delete-duplicates
@@ -2441,30 +2603,6 @@ (define (static-networking-etc-files interfaces)
 # Generated by 'static-networking-service'.\n"
                                       content))))))))
 
-(define (static-networking-shepherd-services interfaces)
-  "Return the list of Shepherd services to bring up INTERFACES, a list of
-<static-networking> objects."
-  (define (loopback? service)
-    (memq 'loopback (shepherd-service-provision service)))
-
-  (let ((services (map static-networking-shepherd-service interfaces)))
-    (match (remove loopback? services)
-      (()
-       ;; There's no interface other than 'loopback', so we assume that the
-       ;; 'networking' service will be provided by dhclient or similar.
-       services)
-      ((non-loopback ...)
-       ;; Assume we're providing all the interfaces, and thus, provide a
-       ;; 'networking' service.
-       (cons (shepherd-service
-              (provision '(networking))
-              (requirement (append-map shepherd-service-provision
-                                       services))
-              (start #~(const #t))
-              (stop #~(const #f))
-              (documentation "Bring up all the networking interfaces."))
-             services)))))
-
 (define static-networking-service-type
   ;; The service type for statically-defined network interfaces.
   (service-type (name 'static-networking)
@@ -2482,12 +2620,13 @@ (define static-networking-service-type
 services of this type is a list of @code{static-networking} objects, one per
 network interface.")))
 
-(define* (static-networking-service interface ip
-                                    #:key
-                                    netmask gateway provision
-                                    ;; Most interfaces require udev to be usable.
-                                    (requirement '(udev))
-                                    (name-servers '()))
+(define-deprecated (static-networking-service interface ip
+                                              #:key
+                                              netmask gateway provision
+                                              ;; Most interfaces require udev to be usable.
+                                              (requirement '(udev))
+                                              (name-servers '()))
+  static-networking-service-type
   "Return a service that starts @var{interface} with address @var{ip}.  If
 @var{netmask} is true, use it as the network mask.  If @var{gateway} is true,
 it must be a string specifying the default network gateway.
@@ -2498,11 +2637,24 @@ (define* (static-networking-service interface ip
 to handle."
   (simple-service 'static-network-interface
                   static-networking-service-type
-                  (list (static-networking (interface interface) (ip ip)
-                                           (netmask netmask) (gateway gateway)
-                                           (provision provision)
-                                           (requirement requirement)
-                                           (name-servers name-servers)))))
+                  (list (static-networking
+                         (addresses
+                          (list (network-address
+                                 (device interface)
+                                 (value (if netmask
+                                            (ip+netmask->cidr ip netmask)
+                                            ip))
+                                 (ipv6? #f))))
+                         (routes
+                          (if gateway
+                              (list (network-route
+                                     (destination "default")
+                                     (gateway gateway)
+                                     (ipv6? #f)))
+                              '()))
+                         (requirement requirement)
+                         (provision provision)
+                         (name-servers name-servers)))))
 
 
 (define %base-services
@@ -2534,10 +2686,12 @@ (define %base-services
                                          (tty "tty6")))
 
         (service static-networking-service-type
-                 (list (static-networking (interface "lo")
-                                          (ip "127.0.0.1")
-                                          (requirement '())
-                                          (provision '(loopback)))))
+                 (list (static-networking
+                        (addresses (list (network-address
+                                          (device "lo")
+                                          (value "127.0.0.1"))))
+                        (requirement '())
+                        (provision '(loopback)))))
         (syslog-service)
         (service urandom-seed-service-type)
         (service guix-service-type)
diff --git a/gnu/system/hurd.scm b/gnu/system/hurd.scm
index 0794671ce4..0e73ca0d99 100644
--- a/gnu/system/hurd.scm
+++ b/gnu/system/hurd.scm
@@ -79,11 +79,28 @@ (define %base-services/hurd
         (service hurd-getty-service-type (hurd-getty-configuration
                                           (tty "tty2")))
         (service static-networking-service-type
-                 (list (static-networking (interface "lo")
-                                          (ip "127.0.0.1")
-                                          (requirement '())
-                                          (provision '(loopback networking))
-                                          (name-servers '("10.0.2.3")))))
+                 (list (static-networking
+                        (addresses
+                         (list (network-address
+                                (device "lo")
+                                (value "127.0.0.1"))))
+                        (requirement '())
+                        (provision '(loopback)))
+                       (static-networking
+                        (addresses
+                         ;; The default QEMU guest address.  To get "eth0",
+                         ;; you need QEMU to emulate a device for which Mach
+                         ;; has an in-kernel driver, for instance with:
+                         ;; --device rtl8139,netdev=net0 --netdev user,id=net0
+                         (list (network-address
+                                (device "eth0")
+                                (value "10.0.2.15/24"))))
+                        (routes
+                         (list (network-route
+                                (destination "default")
+                                (gateway "10.0.2.2"))))
+                        (provision '(networking))
+                        (name-servers '("10.0.2.3")))))
         (syslog-service)
         (service guix-service-type
                  (guix-configuration
diff --git a/gnu/system/install.scm b/gnu/system/install.scm
index 7b394184ad..bdfe580145 100644
--- a/gnu/system/install.scm
+++ b/gnu/system/install.scm
@@ -408,10 +408,13 @@ (define bare-bones-os
 
           ;; Loopback device, needed by OpenSSH notably.
           (service static-networking-service-type
-                   (list (static-networking (interface "lo")
-                                            (ip "127.0.0.1")
-                                            (requirement '())
-                                            (provision '(loopback)))))
+                   (list (static-networking
+                          (addresses
+                           (list (network-address
+                                  (device "lo")
+                                  (value "127.0.0.1"))))
+                          (requirement '())
+                          (provision '(loopback)))))
 
           (service wpa-supplicant-service-type)
           (dbus-service)
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index 131428c128..c66af279f2 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -337,7 +337,7 @@ (define marionette
                              (srfi srfi-1))
                 (live-service-running
                  (find (lambda (live)
-                         (memq 'networking-ovs0
+                         (memq 'networking
                                (live-service-provision live)))
                        (current-services))))
              marionette))
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:04 GMT) Full text and rfc822 format available.

Message #29 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 08/10] services: Define '%qemu-static-networking'.
Date: Wed, 27 Oct 2021 16:02:43 +0200
* gnu/services/base.scm (%qemu-static-networking): New variable.
* gnu/system/hurd.scm (%base-services/hurd): Use it.
* doc/guix.texi (Networking Setup): Document it.
---
 doc/guix.texi         |  8 ++++++++
 gnu/services/base.scm | 16 ++++++++++++++++
 gnu/system/hurd.scm   | 21 ++++++---------------
 3 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index b529a8db6c..0b23075d8c 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -16923,6 +16923,14 @@ List of arguments for this type of link.
 @end table
 @end deftp
 
+@cindex networking, with QEMU
+@cindex QEMU, networking
+@defvr {Scheme Variable} %qemu-static-networking
+This is the @code{static-networking} record representing network setup
+when using QEMU's user-mode network stack on @code{eth0} (@pxref{Using
+the user mode network stack,,, QEMU, QEMU Documentation}).
+@end defvr
+
 @cindex DHCP, networking service
 @defvr {Scheme Variable} dhcp-client-service-type
 This is the type of services that run @var{dhcp}, a Dynamic Host Configuration
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 03f6b388a8..380be1c71e 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -113,6 +113,8 @@ (define-module (gnu services base)
             static-networking-service
             static-networking-service-type
 
+            %qemu-static-networking
+
             udev-configuration
             udev-configuration?
             udev-configuration-rules
@@ -2656,6 +2658,20 @@ (define-deprecated (static-networking-service interface ip
                          (provision provision)
                          (name-servers name-servers)))))
 
+(define %qemu-static-networking
+  ;; Networking configuration for QEMU's user-mode network stack (info "(QEMU)
+  ;; Using the user mode network stack").
+  (static-networking
+   (addresses (list (network-address
+                     (device "eth0")
+                     (value "10.0.2.15/24"))))
+   (routes (list (network-route
+                  (destination "default")
+                  (gateway "10.0.2.2"))))
+   (requirement '())
+   (provision '(networking))
+   (name-servers '("10.0.2.3"))))
+
 
 (define %base-services
   ;; Convenience variable holding the basic services.
diff --git a/gnu/system/hurd.scm b/gnu/system/hurd.scm
index 0e73ca0d99..ec8484d746 100644
--- a/gnu/system/hurd.scm
+++ b/gnu/system/hurd.scm
@@ -86,21 +86,12 @@ (define %base-services/hurd
                                 (value "127.0.0.1"))))
                         (requirement '())
                         (provision '(loopback)))
-                       (static-networking
-                        (addresses
-                         ;; The default QEMU guest address.  To get "eth0",
-                         ;; you need QEMU to emulate a device for which Mach
-                         ;; has an in-kernel driver, for instance with:
-                         ;; --device rtl8139,netdev=net0 --netdev user,id=net0
-                         (list (network-address
-                                (device "eth0")
-                                (value "10.0.2.15/24"))))
-                        (routes
-                         (list (network-route
-                                (destination "default")
-                                (gateway "10.0.2.2"))))
-                        (provision '(networking))
-                        (name-servers '("10.0.2.3")))))
+
+                       ;; QEMU user-mode networking.  To get "eth0", you need
+                       ;; QEMU to emulate a device for which Mach has an
+                       ;; in-kernel driver, for instance with:
+                       ;; --device rtl8139,netdev=net0 --netdev user,id=net0
+                       %qemu-static-networking))
         (syslog-service)
         (service guix-service-type
                  (guix-configuration
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:05 GMT) Full text and rfc822 format available.

Message #32 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 09/10] services: Define '%loopback-static-networking'.
Date: Wed, 27 Oct 2021 16:02:44 +0200
* gnu/services/base.scm (%loopback-static-networking): New variable.
(%base-services): Use it.
* gnu/system/hurd.scm (%base-services/hurd): Use it.
* gnu/system/install.scm (%installation-services): Use it.
* doc/guix.texi (Networking Setup): Document it.
---
 doc/guix.texi          |  7 +++++++
 gnu/services/base.scm  | 17 +++++++++++------
 gnu/system/hurd.scm    |  8 +-------
 gnu/system/install.scm |  8 +-------
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 0b23075d8c..b8b9cf2730 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -16923,6 +16923,13 @@ List of arguments for this type of link.
 @end table
 @end deftp
 
+@cindex loopback device
+@defvr {Scheme Variable} %loopback-static-networking
+This is the @code{static-networking} record representing the ``loopback
+device'', @code{lo}, for IP addresses 127.0.0.1 and ::1, and providing
+the @code{loopback} Shepherd service.
+@end defvr
+
 @cindex networking, with QEMU
 @cindex QEMU, networking
 @defvr {Scheme Variable} %qemu-static-networking
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 380be1c71e..66683f153f 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -113,6 +113,7 @@ (define-module (gnu services base)
             static-networking-service
             static-networking-service-type
 
+            %loopback-static-networking
             %qemu-static-networking
 
             udev-configuration
@@ -2658,6 +2659,15 @@ (define-deprecated (static-networking-service interface ip
                          (provision provision)
                          (name-servers name-servers)))))
 
+(define %loopback-static-networking
+  ;; The loopback device.
+  (static-networking
+   (addresses (list (network-address
+                     (device "lo")
+                     (value "127.0.0.1"))))
+   (requirement '())
+   (provision '(loopback))))
+
 (define %qemu-static-networking
   ;; Networking configuration for QEMU's user-mode network stack (info "(QEMU)
   ;; Using the user mode network stack").
@@ -2702,12 +2712,7 @@ (define %base-services
                                          (tty "tty6")))
 
         (service static-networking-service-type
-                 (list (static-networking
-                        (addresses (list (network-address
-                                          (device "lo")
-                                          (value "127.0.0.1"))))
-                        (requirement '())
-                        (provision '(loopback)))))
+                 (list %loopback-static-networking))
         (syslog-service)
         (service urandom-seed-service-type)
         (service guix-service-type)
diff --git a/gnu/system/hurd.scm b/gnu/system/hurd.scm
index ec8484d746..2acc7b7e11 100644
--- a/gnu/system/hurd.scm
+++ b/gnu/system/hurd.scm
@@ -79,13 +79,7 @@ (define %base-services/hurd
         (service hurd-getty-service-type (hurd-getty-configuration
                                           (tty "tty2")))
         (service static-networking-service-type
-                 (list (static-networking
-                        (addresses
-                         (list (network-address
-                                (device "lo")
-                                (value "127.0.0.1"))))
-                        (requirement '())
-                        (provision '(loopback)))
+                 (list %loopback-static-networking
 
                        ;; QEMU user-mode networking.  To get "eth0", you need
                        ;; QEMU to emulate a device for which Mach has an
diff --git a/gnu/system/install.scm b/gnu/system/install.scm
index bdfe580145..073d7df1db 100644
--- a/gnu/system/install.scm
+++ b/gnu/system/install.scm
@@ -408,13 +408,7 @@ (define bare-bones-os
 
           ;; Loopback device, needed by OpenSSH notably.
           (service static-networking-service-type
-                   (list (static-networking
-                          (addresses
-                           (list (network-address
-                                  (device "lo")
-                                  (value "127.0.0.1"))))
-                          (requirement '())
-                          (provision '(loopback)))))
+                   (list %loopback-static-networking))
 
           (service wpa-supplicant-service-type)
           (dbus-service)
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 14:04:05 GMT) Full text and rfc822 format available.

Message #35 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH 10/10] tests: Replace uses of deprecated
 'static-networking-service'.
Date: Wed, 27 Oct 2021 16:02:45 +0200
* gnu/tests/ganeti.scm (%ganeti-os): Replace call to
'static-networking-service' by instantiating
STATIC-NETWORKING-SERVICE-TYPE.
* gnu/tests/networking.scm (%test-static-networking)
(%openvswitch-os, %dhcpd-os): Likewise.
---
 gnu/tests/ganeti.scm     |  7 ++-----
 gnu/tests/networking.scm | 29 ++++++++++++++++++-----------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/gnu/tests/ganeti.scm b/gnu/tests/ganeti.scm
index 5ac2fd48dd..c29b885a5e 100644
--- a/gnu/tests/ganeti.scm
+++ b/gnu/tests/ganeti.scm
@@ -59,11 +59,8 @@ (define %ganeti-os
     (packages (append (list ganeti-instance-debootstrap ganeti-instance-guix)
                       %base-packages))
     (services
-     (append (list (static-networking-service "eth0" "10.0.2.15"
-                                              #:netmask "255.255.255.0"
-                                              #:gateway "10.0.2.2"
-                                              #:name-servers '("10.0.2.3"))
-
+     (append (list (service static-networking-service-type
+                            (list %qemu-static-networking))
                    (service openssh-service-type
                             (openssh-configuration
                              (permit-root-login 'prohibit-password)))
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index c66af279f2..246e0a15fa 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -122,10 +122,8 @@ (define %test-static-networking
    (value
     (let ((os (marionette-operating-system
                (simple-operating-system
-                (static-networking-service "eth0" "10.0.2.15"
-                                           #:netmask "255.255.255.0"
-                                           #:gateway "10.0.2.2"
-                                           #:name-servers '("10.0.2.2")))
+                (service static-networking-service-type
+                         (list %qemu-static-networking)))
                #:imported-modules '((gnu services herd)
                                     (guix combinators)))))
       (run-static-networking-test (virtual-machine os))))))
@@ -275,9 +273,13 @@ (define openvswitch-configuration-service
 (define %openvswitch-os
   (operating-system
     (inherit (simple-operating-system
-              (static-networking-service "ovs0" "10.1.1.1"
-                                         #:netmask "255.255.255.252"
-                                         #:requirement '(openvswitch-configuration))
+              (simple-service 'openswitch-networking
+                              static-networking-service-type
+                              (list (static-networking
+                                     (addresses (list (network-address
+                                                       (value "10.1.1.1/24")
+                                                       (device "ovs0"))))
+                                     (requirement '(openvswitch-configuration)))))
               (service openvswitch-service-type)
               openvswitch-configuration-service))
     ;; Ensure the interface name does not change depending on the driver.
@@ -392,10 +394,15 @@ (define dhcpd-v4-configuration
 
 (define %dhcpd-os
   (simple-operating-system
-   (static-networking-service "ens3" "192.168.1.4"
-                              #:netmask "255.255.255.0"
-                              #:gateway "192.168.1.1"
-                              #:name-servers '("192.168.1.2" "192.168.1.3"))
+   (service static-networking-service-type
+            (list (static-networking
+                   (addresses (list (network-address
+                                     (value "192.168.1.4/24")
+                                     (device "ens3"))))
+                   (routes (list (network-route
+                                  (destination "default")
+                                  (gateway "192.168.1.1"))))
+                   (name-servers '("192.168.1.2" "192.168.1.3")))))
    (service dhcpd-service-type dhcpd-v4-configuration)))
 
 (define (run-dhcpd-test)
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 27 Oct 2021 15:31:02 GMT) Full text and rfc822 format available.

Message #38 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Julien Lepiller <julien <at> lepiller.eu>
To: debbugs-submit <at> debbugs.gnu.org,
 Ludovic Courtès <ludo <at> gnu.org>, 51440 <at> debbugs.gnu.org
Subject: Re: [bug#51440] [PATCH 00/10] Declarative static networking interface
Date: Wed, 27 Oct 2021 11:29:47 -0400
Le 27 octobre 2021 09:59:18 GMT-04:00, "Ludovic Courtès" <ludo <at> gnu.org> a écrit :
>Hi!
>
>This patch set builds on Julien’s neat Guile-Netlink to finally
>provide a proper static networking configuration interface.  One
>can now write things like:
>
>  (service static-networking-service-type
>           ;; Network configuration for one NIC, IPv4 + IPv6.
>           (static-networking
>            (addresses (list (network-address
>                              (device "eno1")
>                              (value "10.0.2.15/24"))
>                             (network-address
>                              (device "eno1")
>                              (value "2001:123:4567:101::1"))))
>            (routes (list (network-route
>                           (destination "default")
>                           (gateway "10.0.2.2"))
>                          (network-route
>                           (destination "default")
>                           (gateway "2020:321:4567:42::1"))))
>            (name-servers '("10.0.2.3"))))
>
>For the record, the ‘static-networking-service’ procedure currently
>in ‘master’ is IPv4-only and would not allow you to assign more
>than one address to an interface anyway, among other limitations.
>These long-overdue patches close an embarrassing gap.
>
>The interface provided here is a direct mapping of that of Guile-Netlink,
>which is the same as that of the ‘ip’ command, itself closely
>modeled after Linux’s internal interfaces AIUI.  Thus, it should be
>roughly as expressive as ‘ip’, but declarative.
>
>I’m not a network person though, so I’d appreciate if more
>knowledgeable people would take a look at the interface.  In particular,
>I’d like to have examples of ‘links’ to include in the manual—I’m not
>quite sure how to use that.  Ideas?
>
>This patches preserve backward-compatibility: the
>‘static-networking-service’ procedure still works the same.  There’s
>one observable difference though: there’s only one ‘networking’
>Shepherd service now; you no longer get ‘networking-eno1’ and similar.
>The ‘static-networking’ constructor was public since commit
>c9436025a90b86047ba2203d58bbf238f8f9b2f9 but undocumented; thus I
>changed the fields of <static-networking> without worrying about
>compatibility.
>
>I tested this with:
>
>  make check-system \
>    TESTS="static-networking openvswitch ganeti-kvm dhcpd childhurd"
>
>I would appreciate more testing, including tests on the bare metal
>for IPv6 support.
>
>Ensuring portability to GNU/Hurd took me more time than I’d have
>thought, but it works.  “Links” are not supported there, and only
>“default” routes are supported.
>
>I took a detour in commit “Use Guile-Netlink on GNU/Linux”: that
>patch shows that I was blissfully hoping to use good’ol ioctls
>on GNU/Hurd, but that turned out to be a dead end because they
>don’t support IPv6 (which really isn’t a surprise but I don’t know,
>I must have been lacking focus at that point of my journey!).
>
>With all this I think we should be able to do “cool things with
>containers”, but again, that’s not my area of expertise so please
>do chime in if you container networking is your thing.
>
>Feedback welcome!
>
>Ludo’.
>
>Ludovic Courtès (10):
>  tests: Add 'static-networking' test.
>  tests: openvswitch: Check whether ovs0 is up.
>  doc: Add new "Networking Setup" node for the main setup options.
>  gnu: guile-netlink: Allow cross-compilation.
>  services: static-networking: Use Guile-Netlink on GNU/Linux.
>  services: secret-service: Turn into a Shepherd service.
>  services: static-networking: Change interface to mimic netlink.
>  services: Define '%qemu-static-networking'.
>  services: Define '%loopback-static-networking'.
>  tests: Replace uses of deprecated 'static-networking-service'.
>
> doc/guix.texi                   | 505 ++++++++++++++++++++++----------
> gnu/build/hurd-boot.scm         |  10 +-
> gnu/build/secret-service.scm    |  17 +-
> gnu/packages/guile-xyz.scm      |  11 +-
> gnu/services/base.scm           | 391 +++++++++++++++++++------
> gnu/services/virtualization.scm |  45 ++-
> gnu/system/hurd.scm             |  12 +-
> gnu/system/install.scm          |   5 +-
> gnu/tests/ganeti.scm            |   7 +-
> gnu/tests/networking.scm        | 141 ++++++++-
> 10 files changed, 851 insertions(+), 293 deletions(-)
>
>
>base-commit: 0a42998a50e8bbe9e49142b21a570db00efe7491

Looks good at first glance. I noticed a few typos in the manual, so I'll send you more details after I read it more carefully. I'll try that on my hardware, although again I'm not sure how I can run reconfigure from my checkout exactly? (Where do I use sudo, and what options do I need)




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Thu, 28 Oct 2021 00:59:02 GMT) Full text and rfc822 format available.

Message #41 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Julien Lepiller <julien <at> lepiller.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: [bug#51440] [PATCH 04/10] gnu: guile-netlink: Allow
 cross-compilation.
Date: Thu, 28 Oct 2021 02:58:40 +0200
Le Wed, 27 Oct 2021 16:02:39 +0200,
Ludovic Courtès <ludo <at> gnu.org> a écrit :

> * gnu/packages/guile-xyz.scm (guile-netlink)[arguments]: Add #:phases.
> Remove unnecessary #:tests? #f.
> [native-inputs]: Add GUILE-3.0.
> ---
>  gnu/packages/guile-xyz.scm | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/gnu/packages/guile-xyz.scm b/gnu/packages/guile-xyz.scm
> index 355b23f57e..daef8bbb26 100644
> --- a/gnu/packages/guile-xyz.scm
> +++ b/gnu/packages/guile-xyz.scm
> @@ -4854,13 +4854,22 @@ (define-public guile-netlink
>           "03zmsha2d7whlwb52gna83jdas9bqi18rq3sss7kkicv814qb35g"))))
>      (build-system gnu-build-system)
>      (arguments
> -     `(#:tests? #f)); no tests
> +     `(#:phases (modify-phases %standard-phases
> +                  (add-before 'bootstrap 'set-guile-target
> +                    (lambda* (#:key target #:allow-other-keys)
> +                      (when target
> +                        ;; Pass '--target=TRIPLET' to 'guild
> compile'.
> +                        (substitute* "guile.am"
> +                          (("\\$\\(GUILD\\) compile")
> +                           (string-append "$(GUILD) compile
> --target="
> +                                          target " ")))))))))
>      (inputs
>       `(("guile" ,guile-3.0)))
>      (native-inputs
>       `(("automake" ,automake)
>         ("autoconf" ,autoconf)
>         ("pkg-config" ,pkg-config)
> +       ("guile" ,guile-3.0)                    ;for 'guild compile'
> + guile.m4 ("texinfo" ,texinfo)))
>      (home-page "https://git.lepiller.eu/guile-netlink")
>      (synopsis "Netlink protocol implementation for Guile")

Is there anything I can do as the author of guile-netlink to allow
cross-compilation?




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Thu, 28 Oct 2021 01:18:01 GMT) Full text and rfc822 format available.

Message #44 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Julien Lepiller <julien <at> lepiller.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: [bug#51440] [PATCH 07/10] services: static-networking: Change
 interface to mimic netlink.
Date: Thu, 28 Oct 2021 03:17:38 +0200
A few comments on the documentation below.

Le Wed, 27 Oct 2021 16:02:42 +0200,
Ludovic Courtès <ludo <at> gnu.org> a écrit :

>  @lisp
> -(static-networking-service "eno1" "192.168.1.82"
> -                           #:gateway "192.168.1.2"
> -                           #:name-servers '("192.168.1.2"))
> +;; Network configuration for one NIC, IPv4 + IPv6.
> +(static-networking
> + (addresses (list (network-address
> +                   (device "eno1")
> +                   (value "10.0.2.15/24"))
> +                  (network-address
> +                   (device "eno1")
> +                   (value "2001:123:4567:101::1"))))
> + (routes (list (network-route
> +                (destination "default")
> +                (gateway "10.0.2.2"))
> +               (network-route
> +                (destination "default")
> +                (gateway "2020:321:4567:42::1"))))
> + (name-servers '("10.0.2.3")))
>  @end lisp

I don't know if you tested that, but I think this is not routable
because the IPv6 network doesn't have a netmask, so I think it defaults
to a /128 (one IP in the network), so the router is not on the local
network. Many ISPs provide a /64 (when the provide IPv6), so maybe use
that as the netmask?

> -@end deffn
> +
> +If you are familiar with the @command{ip} command of the
> +@uref{https://wiki.linuxfoundation.org/networking/iproute2,
> +@code{iproute2} package} found on Linux-based systems, the
> declaration +above is equivalent to typing:
> +
> +@example
> +ip address add 10.0.2.15/24 dev eno1
> +ip address add 2001:123:4567:101::1 dev eno1
> +ip route add default via inet 10.0.2.2
> +ip route add default via inet6 2020:321:4567:42::1
> +@end example

And so, change it here too.

> +Run @command{man 8 ip} for more info.  Venerable GNU/Linux users will
> +certainly know how to do it with @command{ifconfig} and
> @command{route}, +but we'll spare you that.
> +
> +The available fields of this data type are as follows:
> +
> +@table @asis
> +@item @code{addresses}
> +@itemx @code{links} (default: @code{'()})
> +@itemx @code{links} (default: @code{'()})

One of them should be routes, right?

> +@item @code{provision} (default: @code{#f})
> +If true, this should be a list of symbols for the Shepherd service
> +corresponding to this network configuration.  When @code{#f},
> +@code{'(networking)} or @code{'(loopback)} is used.

Under which conditions is it 'loopback instead of 'networking?

> +@item @code{requirement} (default @code{'()})
> +The list of Shepherd services depended on.
> +@end table
> +@end deftp

The rest of the manual changes look good :)




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Fri, 29 Oct 2021 21:39:02 GMT) Full text and rfc822 format available.

Message #47 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Julien Lepiller <julien <at> lepiller.eu>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Fri, 29 Oct 2021 23:38:35 +0200
Hi,

Julien Lepiller <julien <at> lepiller.eu> skribis:

> Le Wed, 27 Oct 2021 16:02:39 +0200,
> Ludovic Courtès <ludo <at> gnu.org> a écrit :

[...]

>> +                        ;; Pass '--target=TRIPLET' to 'guild
>> compile'.
>> +                        (substitute* "guile.am"
>> +                          (("\\$\\(GUILD\\) compile")
>> +                           (string-append "$(GUILD) compile
>> --target="

[...]

> Is there anything I can do as the author of guile-netlink to allow
> cross-compilation?

Yes, please!  Pass ‘--target=$(HOST)’ to ‘guild compile’.  See for
example how guile-zstd does it.

Thanks,
Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Fri, 29 Oct 2021 21:44:01 GMT) Full text and rfc822 format available.

Message #50 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Julien Lepiller <julien <at> lepiller.eu>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Fri, 29 Oct 2021 23:43:02 +0200
Hi!

Julien Lepiller <julien <at> lepiller.eu> skribis:

> A few comments on the documentation below.
>
> Le Wed, 27 Oct 2021 16:02:42 +0200,
> Ludovic Courtès <ludo <at> gnu.org> a écrit :
>
>>  @lisp
>> -(static-networking-service "eno1" "192.168.1.82"
>> -                           #:gateway "192.168.1.2"
>> -                           #:name-servers '("192.168.1.2"))
>> +;; Network configuration for one NIC, IPv4 + IPv6.
>> +(static-networking
>> + (addresses (list (network-address
>> +                   (device "eno1")
>> +                   (value "10.0.2.15/24"))
>> +                  (network-address
>> +                   (device "eno1")
>> +                   (value "2001:123:4567:101::1"))))
>> + (routes (list (network-route
>> +                (destination "default")
>> +                (gateway "10.0.2.2"))
>> +               (network-route
>> +                (destination "default")
>> +                (gateway "2020:321:4567:42::1"))))
>> + (name-servers '("10.0.2.3")))
>>  @end lisp
>
> I don't know if you tested that, but I think this is not routable
> because the IPv6 network doesn't have a netmask, so I think it defaults
> to a /128 (one IP in the network), so the router is not on the local
> network. Many ISPs provide a /64 (when the provide IPv6), so maybe use
> that as the netmask?

No I didn’t test it, so yes: let’s add /64 above.

>> +ip address add 10.0.2.15/24 dev eno1
>> +ip address add 2001:123:4567:101::1 dev eno1
>> +ip route add default via inet 10.0.2.2
>> +ip route add default via inet6 2020:321:4567:42::1
>> +@end example
>
> And so, change it here too.

Yes.

>> +Run @command{man 8 ip} for more info.  Venerable GNU/Linux users will
>> +certainly know how to do it with @command{ifconfig} and
>> @command{route}, +but we'll spare you that.
>> +
>> +The available fields of this data type are as follows:
>> +
>> +@table @asis
>> +@item @code{addresses}
>> +@itemx @code{links} (default: @code{'()})
>> +@itemx @code{links} (default: @code{'()})
>
> One of them should be routes, right?

Oops, yes.

>> +@item @code{provision} (default: @code{#f})
>> +If true, this should be a list of symbols for the Shepherd service
>> +corresponding to this network configuration.  When @code{#f},
>> +@code{'(networking)} or @code{'(loopback)} is used.
>
> Under which conditions is it 'loopback instead of 'networking?

Hmm that part is wrong: #f is equivalent to (networking) in practice.
I’ll fix that.

> The rest of the manual changes look good :)

You mentioned on IRC veth pairs as an example use of links.  Could you
formalize it for inclusion as an example?

Thanks for the careful review!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Fri, 29 Oct 2021 21:45:02 GMT) Full text and rfc822 format available.

Message #53 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Julien Lepiller <julien <at> lepiller.eu>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Fri, 29 Oct 2021 23:44:26 +0200
Julien Lepiller <julien <at> lepiller.eu> skribis:

> Looks good at first glance. I noticed a few typos in the manual, so I'll send you more details after I read it more carefully. I'll try that on my hardware, although again I'm not sure how I can run reconfigure from my checkout exactly? (Where do I use sudo, and what options do I need)

To reconfigure from a checkout, you can run:

  sudo -E ./pre-inst-env guix system reconfigure …

where ‘-E’ tells sudo to preserve notably GUILE_LOAD_PATH & co., such
that Guile-Gcrypt and the other dependencies are found.

HTH!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 03 Nov 2021 14:15:02 GMT) Full text and rfc822 format available.

Message #56 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: David Aaron Fendley <tricon <at> triconium.com>
To: 51440 <at> debbugs.gnu.org
Subject: [PATCH 00/10] Declarative static networking interface
Date: Wed, 3 Nov 2021 09:27:04 -0400
If I have:

  (service static-networking-service-type
  	   (list (static-networking
  		  (addresses (list (network-address
  				    (device "eno33559296")
  				    (value "10.7.99.99/24"))
  				   (network-address
  				    (device "eno16780032")
  				    (value "10.10.199.98/24"))))
  		  (routes (list (network-route
  				 (destination "default")
  				 (gateway "10.10.199.1"))
  				(network-route
  				 (destination "192.168.0.1/32")
  				 (gateway "10.10.199.1"))))
  		  (name-servers '("10.10.199.17" "10.10.101.2")))))

After reconfigure and restart of the networking service, no routes
listed are created. Only the standard routes for each network:

  > ip a
  
  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
      link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
      inet 127.0.0.1/8 scope host lo
         valid_lft forever preferred_lft forever
      inet 127.0.0.1/0 scope global lo
         valid_lft forever preferred_lft forever
      inet6 ::1/128 scope host 
         valid_lft forever preferred_lft forever
  2: eno16780032: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
      link/ether 00:50:56:98:d1:9f brd ff:ff:ff:ff:ff:ff
      inet 10.10.199.98/24 scope global eno16780032
         valid_lft forever preferred_lft forever
      inet6 fe80::250:56ff:fe98:d19f/64 scope link 
         valid_lft forever preferred_lft forever
  3: eno33559296: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
      link/ether 00:50:56:98:37:c2 brd ff:ff:ff:ff:ff:ff
      inet 10.7.99.99/24 scope global eno33559296
         valid_lft forever preferred_lft forever
      inet6 fe80::250:56ff:fe98:37c2/64 scope link 
         valid_lft forever preferred_lft forever


  > ip r
  
  10.7.99.0/24 dev eno33559296 proto kernel scope link src 10.7.99.99 
  10.10.199.0/24 dev eno16780032 proto kernel scope link src 10.10.199.98 


If I then change the config to:

  (service static-networking-service-type
  	   (list (static-networking
  		  (addresses (list (network-address
  				    (device "eno33559296")
  				    (value "10.0.7.15/24"))
  				   (network-address
  				    (device "eno16780032")
  				    (value "10.10.2.15/24"))))
  		  (routes (list (network-route
  				 (destination "default")
  				 (gateway "10.0.2.2"))))
  		  (name-servers '("10.0.2.3")))))



After reconfigure and restart of the networking service, routes
specified are still not created, and the addresses and routes are
appended:

  > ip a

  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
      link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
      inet 127.0.0.1/8 scope host lo
         valid_lft forever preferred_lft forever
      inet 127.0.0.1/0 scope global lo
         valid_lft forever preferred_lft forever
      inet6 ::1/128 scope host 
         valid_lft forever preferred_lft forever
  2: eno16780032: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
      link/ether 00:50:56:98:d1:9f brd ff:ff:ff:ff:ff:ff
      inet 10.10.199.98/24 scope global eno16780032
         valid_lft forever preferred_lft forever
      inet 10.10.2.15/24 scope global eno16780032
         valid_lft forever preferred_lft forever
      inet6 fe80::250:56ff:fe98:d19f/64 scope link 
         valid_lft forever preferred_lft forever
  3: eno33559296: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
      link/ether 00:50:56:98:37:c2 brd ff:ff:ff:ff:ff:ff
      inet 10.7.99.99/24 scope global eno33559296
         valid_lft forever preferred_lft forever
      inet 10.0.7.15/24 scope global eno33559296
         valid_lft forever preferred_lft forever
      inet6 fe80::250:56ff:fe98:37c2/64 scope link 
         valid_lft forever preferred_lft forever

  > ip r

  10.0.7.0/24 dev eno33559296 proto kernel scope link src 10.0.7.15 
  10.7.99.0/24 dev eno33559296 proto kernel scope link src 10.7.99.99 
  10.10.2.0/24 dev eno16780032 proto kernel scope link src 10.10.2.15 
  10.10.199.0/24 dev eno16780032 proto kernel scope link src 10.10.199.98 


Expectation:

Routes declared would be added and standard network routes would be
removed if no longer relevant.


Environment:

These ten patches were applied on top of:

  7af3b822178782d6598865e1d6a780a756dd0cb3


  > guix describe
  
  Generation 2	Nov 02 2021 13:37:58	(current)
    guix 8d02b0d
      repository URL: https://git.savannah.gnu.org/git/guix.git
      branch: master
      commit: 8d02b0d46cfc27b905f9276760aefacf518ae4f7




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Thu, 11 Nov 2021 22:09:02 GMT) Full text and rfc822 format available.

Message #59 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: David Aaron Fendley <tricon <at> triconium.com>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Thu, 11 Nov 2021 23:08:39 +0100
[Message part 1 (text/plain, inline)]
Hi David,

David Aaron Fendley <tricon <at> triconium.com> skribis:

> If I have:
>
>   (service static-networking-service-type
>   	   (list (static-networking
>   		  (addresses (list (network-address
>   				    (device "eno33559296")
>   				    (value "10.7.99.99/24"))
>   				   (network-address
>   				    (device "eno16780032")
>   				    (value "10.10.199.98/24"))))
>   		  (routes (list (network-route
>   				 (destination "default")
>   				 (gateway "10.10.199.1"))
>   				(network-route
>   				 (destination "192.168.0.1/32")
>   				 (gateway "10.10.199.1"))))
>   		  (name-servers '("10.10.199.17" "10.10.101.2")))))
>
> After reconfigure and restart of the networking service, no routes
> listed are created. Only the standard routes for each network:

Hmm right, I need to investigate this one some more.  Apparently the
‘route-add’ call leads to “Network is unreachable”.

[...]

> If I then change the config to:
>
>   (service static-networking-service-type
>   	   (list (static-networking
>   		  (addresses (list (network-address
>   				    (device "eno33559296")
>   				    (value "10.0.7.15/24"))
>   				   (network-address
>   				    (device "eno16780032")
>   				    (value "10.10.2.15/24"))))
>   		  (routes (list (network-route
>   				 (destination "default")
>   				 (gateway "10.0.2.2"))))
>   		  (name-servers '("10.0.2.3")))))
>
>
>
> After reconfigure and restart of the networking service, routes
> specified are still not created, and the addresses and routes are
> appended:

This one is fixed by the patch below: the ‘stop’ method of the service
would not actually load the “tear-down-network” file, oops!

Thanks a lot for testing and reporting!

To be continued…

Ludo’.

[Message part 2 (text/x-patch, inline)]
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 66683f153f..3123122200 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -2511,7 +2511,7 @@ (define network-set-up/linux
                                 addresses)
                         #$@(map (match-lambda
                                   (($ <network-link> name type arguments)
-                                   #~(link-add #:device #$name #$type
+                                   #~(link-add #$name #$type
                                                #:type-args '#$arguments)))
                                 links)
                         #$@(map (lambda (route)
@@ -2530,7 +2530,7 @@ (define network-set-up/linux
 (define network-tear-down/linux
   (match-lambda
     (($ <static-networking> addresses links routes)
-     (scheme-file "set-up-network"
+     (scheme-file "tear-down-network"
                   (with-extensions (list guile-netlink)
                     #~(begin
                         (use-modules (ip addr) (ip link) (ip route))
@@ -2579,10 +2579,10 @@ (define (static-networking-shepherd-service config)
                                  (network-set-up/hurd config))))))
         (stop #~(lambda _
                   ;; Return #f is successfully stopped.
-                  #$(let-system (system target)
-                      (if (string-contains (or target system) "-linux")
-                          (network-tear-down/linux config)
-                          (network-tear-down/hurd config)))))
+                  (load #$(let-system (system target)
+                            (if (string-contains (or target system) "-linux")
+                                (network-tear-down/linux config)
+                                (network-tear-down/hurd config))))))
         (respawn? #f))))))
 
 (define (static-networking-shepherd-services networks)

Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Sun, 14 Nov 2021 20:53:02 GMT) Full text and rfc822 format available.

Message #62 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: David Aaron Fendley <tricon <at> triconium.com>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Sun, 14 Nov 2021 21:52:26 +0100
Ludovic Courtès <ludo <at> gnu.org> skribis:

> David Aaron Fendley <tricon <at> triconium.com> skribis:
>
>> If I have:
>>
>>   (service static-networking-service-type
>>   	   (list (static-networking
>>   		  (addresses (list (network-address
>>   				    (device "eno33559296")
>>   				    (value "10.7.99.99/24"))
>>   				   (network-address
>>   				    (device "eno16780032")
>>   				    (value "10.10.199.98/24"))))
>>   		  (routes (list (network-route
>>   				 (destination "default")
>>   				 (gateway "10.10.199.1"))
>>   				(network-route
>>   				 (destination "192.168.0.1/32")
>>   				 (gateway "10.10.199.1"))))
>>   		  (name-servers '("10.10.199.17" "10.10.101.2")))))
>>
>> After reconfigure and restart of the networking service, no routes
>> listed are created. Only the standard routes for each network:
>
> Hmm right, I need to investigate this one some more.  Apparently the
> ‘route-add’ call leads to “Network is unreachable”.

Julien has just fixed that:

  https://git.lepiller.eu/guile-netlink/commit/f5867cc920ea3703b11e257a63043ac29153e34c

Hopefully we’ll have a new Guile-Netlink release soon with this fix.
:-)

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:02 GMT) Full text and rfc822 format available.

Message #65 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 00/10] Declarative static networking interface
Date: Mon, 15 Nov 2021 23:30:34 +0100
Hi!

Changes since v1:

  • ‘herd stop networking’ fixed, as reported by David Aaron
    Fendley.

  • Guile-Netlink cross-compilation simplified thanks to changes
    in Guile-Netlink 1.1.

  • ‘provision’ field of <static-networking> defaults to
    '(networking), as suggested by Julien.

  • “network-tear-down” script wraps calls in ‘false-if-netlink-error’
    to go as far as possible.

  • Documentation fixed as suggested by Julien.

Thoughts?  Test reports?  :-)

Note: It requires Guile-Netlink 1.1 as added in
46432cceebe392a1744980f370a48ef73afbac2c (it fixes another issue
David reported earlier.)

Ludo’.

Ludovic Courtès (10):
  tests: Add 'static-networking' test.
  tests: openvswitch: Check whether ovs0 is up.
  doc: Add new "Networking Setup" node for the main setup options.
  gnu: guile-netlink: Allow cross-compilation.
  services: static-networking: Use Guile-Netlink on GNU/Linux.
  services: secret-service: Turn into a Shepherd service.
  services: static-networking: Change interface to mimic netlink.
  services: Define '%qemu-static-networking'.
  services: Define '%loopback-static-networking'.
  tests: Replace uses of deprecated 'static-networking-service'.

 doc/guix.texi                   | 504 ++++++++++++++++++++++----------
 gnu/build/hurd-boot.scm         |  10 +-
 gnu/build/secret-service.scm    |  17 +-
 gnu/packages/guile-xyz.scm      |   3 +-
 gnu/services/base.scm           | 406 +++++++++++++++++++------
 gnu/services/virtualization.scm |  45 ++-
 gnu/system/hurd.scm             |  12 +-
 gnu/system/install.scm          |   5 +-
 gnu/tests/ganeti.scm            |   7 +-
 gnu/tests/networking.scm        | 141 ++++++++-
 10 files changed, 855 insertions(+), 295 deletions(-)


base-commit: 21332f3b8cb8f407a89cdfe7d0460a9947675872
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:02 GMT) Full text and rfc822 format available.

Message #68 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 02/10] tests: openvswitch: Check whether ovs0 is up.
Date: Mon, 15 Nov 2021 23:30:36 +0100
* gnu/tests/networking.scm (run-openvswitch-test)["ovs0 is up"]: New test.
---
 gnu/tests/networking.scm | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index 5da1c91da6..131428c128 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -286,12 +286,15 @@ (define %openvswitch-os
 (define (run-openvswitch-test)
   (define os
     (marionette-operating-system %openvswitch-os
-                                 #:imported-modules '((gnu services herd))))
+                                 #:imported-modules '((gnu services herd)
+                                                      (guix build syscalls))))
 
   (define test
-    (with-imported-modules '((gnu build marionette))
+    (with-imported-modules '((gnu build marionette)
+                             (guix build syscalls))
       #~(begin
           (use-modules (gnu build marionette)
+                       (guix build syscalls)
                        (ice-9 popen)
                        (ice-9 rdelim)
                        (srfi srfi-64))
@@ -339,6 +342,18 @@ (define marionette
                        (current-services))))
              marionette))
 
+          (test-equal "ovs0 is up"
+            IFF_UP
+            (marionette-eval
+             '(begin
+                (use-modules (guix build syscalls))
+
+                (let* ((sock  (socket AF_INET SOCK_STREAM 0))
+                       (flags (network-interface-flags sock "ovs0")))
+                  (close-port sock)
+                  (logand flags IFF_UP)))
+             marionette))
+
           (test-end)
           (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
 
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:02 GMT) Full text and rfc822 format available.

Message #71 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 03/10] doc: Add new "Networking Setup" node for the main
 setup options.
Date: Mon, 15 Nov 2021 23:30:37 +0100
This should make it easier to find how to get started setting up
networking.

* doc/guix.texi (Networking Setup): New section.
(Networking Services): Remove 'static-networking-service',
'dhcp-client-service-type', 'network-manager-service-type',
'connman-service-type', 'wicd-service', 'modem-manager-service-type',
'usb-modeswitch-service-type', and 'wpa-supplicant-service-type'.
---
 doc/guix.texi | 289 ++++++++++++++++++++++++++++----------------------
 1 file changed, 160 insertions(+), 129 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index ea0c51d11a..399664b910 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -342,7 +342,8 @@ Services
 * Base Services::               Essential system services.
 * Scheduled Job Execution::     The mcron service.
 * Log Rotation::                The rottlog service.
-* Networking Services::         Network setup, SSH daemon, etc.
+* Networking Setup::            Setting up network interfaces.
+* Networking Services::         Firewall, SSH daemon, etc.
 * Unattended Upgrades::         Automated system upgrades.
 * X Window::                    Graphical display.
 * Printing Services::           Local and remote printer support.
@@ -15534,7 +15535,8 @@ declaration.
 * Base Services::               Essential system services.
 * Scheduled Job Execution::     The mcron service.
 * Log Rotation::                The rottlog service.
-* Networking Services::         Network setup, SSH daemon, etc.
+* Networking Setup::            Setting up network interfaces.
+* Networking Services::         Firewall, SSH daemon, etc.
 * Unattended Upgrades::         Automated system upgrades.
 * X Window::                    Graphical display.
 * Printing Services::           Local and remote printer support.
@@ -16756,63 +16758,26 @@ The list of syslog-controlled files to be rotated.  By default it is:
 "/var/log/maillog")}.
 @end defvr
 
-@node Networking Services
-@subsection Networking Services
+@node Networking Setup
+@subsection Networking Setup
 
-The @code{(gnu services networking)} module provides services to configure
-the network interface.
+The @code{(gnu services networking)} module provides services to
+configure network interfaces and set up networking on your machine.
+Those services provide different ways for you to set up your machine: by
+declaring a static network configuration, by running a Dynamic Host
+Configuration Protocol (DHCP) client, or by running daemons such as
+NetworkManager and Connman that automate the whole process,
+automatically adapt to connectivity changes, and provide a high-level
+user interface.
 
-@cindex DHCP, networking service
-@defvr {Scheme Variable} dhcp-client-service-type
-This is the type of services that run @var{dhcp}, a Dynamic Host Configuration
-Protocol (DHCP) client, on all the non-loopback network interfaces.  Its value
-is the DHCP client package to use, @code{isc-dhcp} by default.
-@end defvr
+On a laptop, NetworkManager and Connman are by far the most convenient
+options, which is why the default desktop services include
+NetworkManager (@pxref{Desktop Services, @code{%desktop-services}}).
+For a server, or for a virtual machine or a container, static network
+configuration or a simple DHCP client are often more appropriate.
 
-@deffn {Scheme Procedure} dhcpd-service-type
-This type defines a service that runs a DHCP daemon.  To create a
-service of this type, you must supply a @code{<dhcpd-configuration>}.
-For example:
-
-@lisp
-(service dhcpd-service-type
-         (dhcpd-configuration
-          (config-file (local-file "my-dhcpd.conf"))
-          (interfaces '("enp0s25"))))
-@end lisp
-@end deffn
-
-@deftp {Data Type} dhcpd-configuration
-@table @asis
-@item @code{package} (default: @code{isc-dhcp})
-The package that provides the DHCP daemon.  This package is expected to
-provide the daemon at @file{sbin/dhcpd} relative to its output
-directory.  The default package is the
-@uref{https://www.isc.org/products/DHCP, ISC's DHCP server}.
-@item @code{config-file} (default: @code{#f})
-The configuration file to use.  This is required.  It will be passed to
-@code{dhcpd} via its @code{-cf} option.  This may be any ``file-like''
-object (@pxref{G-Expressions, file-like objects}).  See @code{man
-dhcpd.conf} for details on the configuration file syntax.
-@item @code{version} (default: @code{"4"})
-The DHCP version to use.  The ISC DHCP server supports the values ``4'',
-``6'', and ``4o6''.  These correspond to the @code{dhcpd} program
-options @code{-4}, @code{-6}, and @code{-4o6}.  See @code{man dhcpd} for
-details.
-@item @code{run-directory} (default: @code{"/run/dhcpd"})
-The run directory to use.  At service activation time, this directory
-will be created if it does not exist.
-@item @code{pid-file} (default: @code{"/run/dhcpd/dhcpd.pid"})
-The PID file to use.  This corresponds to the @code{-pf} option of
-@code{dhcpd}.  See @code{man dhcpd} for details.
-@item @code{interfaces} (default: @code{'()})
-The names of the network interfaces on which dhcpd should listen for
-broadcasts.  If this list is not empty, then its elements (which must be
-strings) will be appended to the @code{dhcpd} invocation when starting
-the daemon.  It may not be necessary to explicitly specify any
-interfaces here; see @code{man dhcpd} for details.
-@end table
-@end deftp
+This section describes the various network setup services available,
+starting with static network configuration.
 
 @defvr {Scheme Variable} static-networking-service-type
 This is the type for statically-configured network interfaces.
@@ -16842,81 +16807,13 @@ For example:
 @end lisp
 @end deffn
 
-@cindex wicd
-@cindex wireless
-@cindex WiFi
-@cindex network management
-@deffn {Scheme Procedure} wicd-service [#:wicd @var{wicd}]
-Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
-management daemon that aims to simplify wired and wireless networking.
-
-This service adds the @var{wicd} package to the global profile, providing
-several commands to interact with the daemon and configure networking:
-@command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
-and @command{wicd-curses} user interfaces.
-@end deffn
-
-@cindex ModemManager
-
-@defvr {Scheme Variable} modem-manager-service-type
-This is the service type for the
-@uref{https://wiki.gnome.org/Projects/ModemManager, ModemManager}
-service.  The value for this service type is a
-@code{modem-manager-configuration} record.
-
-This service is part of @code{%desktop-services} (@pxref{Desktop
-Services}).
+@cindex DHCP, networking service
+@defvr {Scheme Variable} dhcp-client-service-type
+This is the type of services that run @var{dhcp}, a Dynamic Host Configuration
+Protocol (DHCP) client, on all the non-loopback network interfaces.  Its value
+is the DHCP client package to use, @code{isc-dhcp} by default.
 @end defvr
 
-@deftp {Data Type} modem-manager-configuration
-Data type representing the configuration of ModemManager.
-
-@table @asis
-@item @code{modem-manager} (default: @code{modem-manager})
-The ModemManager package to use.
-
-@end table
-@end deftp
-
-@cindex USB_ModeSwitch
-@cindex Modeswitching
-
-@defvr {Scheme Variable} usb-modeswitch-service-type
-This is the service type for the
-@uref{https://www.draisberghof.de/usb_modeswitch/, USB_ModeSwitch}
-service.  The value for this service type is
-a @code{usb-modeswitch-configuration} record.
-
-When plugged in, some USB modems (and other USB devices) initially present
-themselves as a read-only storage medium and not as a modem.  They need to be
-@dfn{modeswitched} before they are usable.  The USB_ModeSwitch service type
-installs udev rules to automatically modeswitch these devices when they are
-plugged in.
-
-This service is part of @code{%desktop-services} (@pxref{Desktop
-Services}).
-@end defvr
-
-@deftp {Data Type} usb-modeswitch-configuration
-Data type representing the configuration of USB_ModeSwitch.
-
-@table @asis
-@item @code{usb-modeswitch} (default: @code{usb-modeswitch})
-The USB_ModeSwitch package providing the binaries for modeswitching.
-
-@item @code{usb-modeswitch-data} (default: @code{usb-modeswitch-data})
-The package providing the device data and udev rules file used by
-USB_ModeSwitch.
-
-@item @code{config-file} (default: @code{#~(string-append #$usb-modeswitch:dispatcher "/etc/usb_modeswitch.conf")})
-Which config file to use for the USB_ModeSwitch dispatcher.  By default the
-config file shipped with USB_ModeSwitch is used which disables logging to
-@file{/var/log} among other default settings.  If set to @code{#f}, no config
-file is used.
-
-@end table
-@end deftp
-
 @cindex NetworkManager
 
 @defvr {Scheme Variable} network-manager-service-type
@@ -17053,6 +16950,139 @@ List of additional command-line arguments to pass to the daemon.
 @end table
 @end deftp
 
+@cindex wicd
+@cindex wireless
+@cindex WiFi
+@cindex network management
+@deffn {Scheme Procedure} wicd-service [#:wicd @var{wicd}]
+Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
+management daemon that aims to simplify wired and wireless networking.
+
+This service adds the @var{wicd} package to the global profile, providing
+several commands to interact with the daemon and configure networking:
+@command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
+and @command{wicd-curses} user interfaces.
+@end deffn
+
+@cindex ModemManager
+Some networking devices such as modems require special care, and this is
+what the services below focus on.
+
+@defvr {Scheme Variable} modem-manager-service-type
+This is the service type for the
+@uref{https://wiki.gnome.org/Projects/ModemManager, ModemManager}
+service.  The value for this service type is a
+@code{modem-manager-configuration} record.
+
+This service is part of @code{%desktop-services} (@pxref{Desktop
+Services}).
+@end defvr
+
+@deftp {Data Type} modem-manager-configuration
+Data type representing the configuration of ModemManager.
+
+@table @asis
+@item @code{modem-manager} (default: @code{modem-manager})
+The ModemManager package to use.
+
+@end table
+@end deftp
+
+@cindex USB_ModeSwitch
+@cindex Modeswitching
+
+@defvr {Scheme Variable} usb-modeswitch-service-type
+This is the service type for the
+@uref{https://www.draisberghof.de/usb_modeswitch/, USB_ModeSwitch}
+service.  The value for this service type is
+a @code{usb-modeswitch-configuration} record.
+
+When plugged in, some USB modems (and other USB devices) initially present
+themselves as a read-only storage medium and not as a modem.  They need to be
+@dfn{modeswitched} before they are usable.  The USB_ModeSwitch service type
+installs udev rules to automatically modeswitch these devices when they are
+plugged in.
+
+This service is part of @code{%desktop-services} (@pxref{Desktop
+Services}).
+@end defvr
+
+@deftp {Data Type} usb-modeswitch-configuration
+Data type representing the configuration of USB_ModeSwitch.
+
+@table @asis
+@item @code{usb-modeswitch} (default: @code{usb-modeswitch})
+The USB_ModeSwitch package providing the binaries for modeswitching.
+
+@item @code{usb-modeswitch-data} (default: @code{usb-modeswitch-data})
+The package providing the device data and udev rules file used by
+USB_ModeSwitch.
+
+@item @code{config-file} (default: @code{#~(string-append #$usb-modeswitch:dispatcher "/etc/usb_modeswitch.conf")})
+Which config file to use for the USB_ModeSwitch dispatcher.  By default the
+config file shipped with USB_ModeSwitch is used which disables logging to
+@file{/var/log} among other default settings.  If set to @code{#f}, no config
+file is used.
+
+@end table
+@end deftp
+
+
+@node Networking Services
+@subsection Networking Services
+
+The @code{(gnu services networking)} module discussed in the previous
+section provides services for more advanced setups: providing a DHCP
+service for others to use, filtering packets with iptables or nftables,
+running a WiFi access point with @command{hostapd}, running the
+@command{inetd} ``superdaemon'', and more.  This section describes
+those.
+
+@deffn {Scheme Procedure} dhcpd-service-type
+This type defines a service that runs a DHCP daemon.  To create a
+service of this type, you must supply a @code{<dhcpd-configuration>}.
+For example:
+
+@lisp
+(service dhcpd-service-type
+         (dhcpd-configuration
+          (config-file (local-file "my-dhcpd.conf"))
+          (interfaces '("enp0s25"))))
+@end lisp
+@end deffn
+
+@deftp {Data Type} dhcpd-configuration
+@table @asis
+@item @code{package} (default: @code{isc-dhcp})
+The package that provides the DHCP daemon.  This package is expected to
+provide the daemon at @file{sbin/dhcpd} relative to its output
+directory.  The default package is the
+@uref{https://www.isc.org/products/DHCP, ISC's DHCP server}.
+@item @code{config-file} (default: @code{#f})
+The configuration file to use.  This is required.  It will be passed to
+@code{dhcpd} via its @code{-cf} option.  This may be any ``file-like''
+object (@pxref{G-Expressions, file-like objects}).  See @code{man
+dhcpd.conf} for details on the configuration file syntax.
+@item @code{version} (default: @code{"4"})
+The DHCP version to use.  The ISC DHCP server supports the values ``4'',
+``6'', and ``4o6''.  These correspond to the @code{dhcpd} program
+options @code{-4}, @code{-6}, and @code{-4o6}.  See @code{man dhcpd} for
+details.
+@item @code{run-directory} (default: @code{"/run/dhcpd"})
+The run directory to use.  At service activation time, this directory
+will be created if it does not exist.
+@item @code{pid-file} (default: @code{"/run/dhcpd/dhcpd.pid"})
+The PID file to use.  This corresponds to the @code{-pf} option of
+@code{dhcpd}.  See @code{man dhcpd} for details.
+@item @code{interfaces} (default: @code{'()})
+The names of the network interfaces on which dhcpd should listen for
+broadcasts.  If this list is not empty, then its elements (which must be
+strings) will be appended to the @code{dhcpd} invocation when starting
+the daemon.  It may not be necessary to explicitly specify any
+interfaces here; see @code{man dhcpd} for details.
+@end table
+@end deftp
+
 @cindex hostapd service, for Wi-Fi access points
 @cindex Wi-Fi access points, hostapd service
 @defvr {Scheme Variable} hostapd-service-type
@@ -17115,6 +17145,7 @@ network that can be seen on @code{wlan0}, by default.
 The service's value is a @code{hostapd-configuration} record.
 @end defvr
 
+
 @cindex iptables
 @defvr {Scheme Variable} iptables-service-type
 This is the service type to set up an iptables configuration.  iptables is a
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:03 GMT) Full text and rfc822 format available.

Message #74 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 01/10] tests: Add 'static-networking' test.
Date: Mon, 15 Nov 2021 23:30:35 +0100
* gnu/tests/networking.scm (run-static-networking-test): New procedure.
(%test-static-networking): New variable.
---
 gnu/tests/networking.scm | 99 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 2 deletions(-)

diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index 453e63f52d..5da1c91da6 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2018 Chris Marusich <cmmarusich <at> gmail.com>
 ;;; Copyright © 2018 Arun Isaac <arunisaac <at> systemreboot.net>
 ;;; Copyright © 2021 Maxime Devos <maximedevos <at> telenet.be>
+;;; Copyright © 2021 Ludovic Courtès <ludo <at> gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -37,8 +38,102 @@ (define-module (gnu tests networking)
   #:use-module (gnu packages guile)
   #:use-module (gnu services shepherd)
   #:use-module (ice-9 match)
-  #:export (%test-inetd %test-openvswitch %test-dhcpd %test-tor %test-iptables
-                        %test-ipfs))
+  #:export (%test-static-networking
+            %test-inetd
+            %test-openvswitch
+            %test-dhcpd
+            %test-tor
+            %test-iptables
+            %test-ipfs))
+
+
+;;;
+;;; Static networking.
+;;;
+
+(define (run-static-networking-test vm)
+  (define test
+    (with-imported-modules '((gnu build marionette)
+                             (guix build syscalls))
+      #~(begin
+          (use-modules (gnu build marionette)
+                       (guix build syscalls)
+                       (srfi srfi-64))
+
+          (define marionette
+            (make-marionette
+             '(#$vm "-nic" "user,model=virtio-net-pci")))
+
+          (mkdir #$output)
+          (chdir #$output)
+
+          (test-begin "static-networking")
+
+          (test-assert "service is up"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (start-service 'networking))
+             marionette))
+
+          (test-assert "network interfaces"
+            (marionette-eval
+             '(begin
+                (use-modules (guix build syscalls))
+                (network-interface-names))
+             marionette))
+
+          (test-equal "address of eth0"
+            "10.0.2.15"
+            (marionette-eval
+             '(let* ((sock (socket AF_INET SOCK_STREAM 0))
+                     (addr (network-interface-address sock "eth0")))
+                (close-port sock)
+                (inet-ntop (sockaddr:fam addr) (sockaddr:addr addr)))
+             marionette))
+
+          (test-equal "netmask of eth0"
+            "255.255.255.0"
+            (marionette-eval
+             '(let* ((sock (socket AF_INET SOCK_STREAM 0))
+                     (mask (network-interface-netmask sock "eth0")))
+                (close-port sock)
+                (inet-ntop (sockaddr:fam mask) (sockaddr:addr mask)))
+             marionette))
+
+          (test-equal "eth0 is up"
+            IFF_UP
+            (marionette-eval
+             '(let* ((sock  (socket AF_INET SOCK_STREAM 0))
+                     (flags (network-interface-flags sock "eth0")))
+                (logand flags IFF_UP))
+             marionette))
+
+          (test-end)
+
+          (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+  (gexp->derivation "static-networking" test))
+
+(define %test-static-networking
+  (system-test
+   (name "static-networking")
+   (description "Test the 'static-networking' service.")
+   (value
+    (let ((os (marionette-operating-system
+               (simple-operating-system
+                (static-networking-service "eth0" "10.0.2.15"
+                                           #:netmask "255.255.255.0"
+                                           #:gateway "10.0.2.2"
+                                           #:name-servers '("10.0.2.2")))
+               #:imported-modules '((gnu services herd)
+                                    (guix combinators)))))
+      (run-static-networking-test (virtual-machine os))))))
+
+
+;;;
+;;; Inetd.
+;;;
 
 (define %inetd-os
   ;; Operating system with 2 inetd services.
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:03 GMT) Full text and rfc822 format available.

Message #77 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 08/10] services: Define '%qemu-static-networking'.
Date: Mon, 15 Nov 2021 23:30:42 +0100
* gnu/services/base.scm (%qemu-static-networking): New variable.
* gnu/system/hurd.scm (%base-services/hurd): Use it.
* doc/guix.texi (Networking Setup): Document it.
---
 doc/guix.texi         |  8 ++++++++
 gnu/services/base.scm | 16 ++++++++++++++++
 gnu/system/hurd.scm   | 21 ++++++---------------
 3 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 439ef28e96..85e76991d9 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -16940,6 +16940,14 @@ List of arguments for this type of link.
 @end table
 @end deftp
 
+@cindex networking, with QEMU
+@cindex QEMU, networking
+@defvr {Scheme Variable} %qemu-static-networking
+This is the @code{static-networking} record representing network setup
+when using QEMU's user-mode network stack on @code{eth0} (@pxref{Using
+the user mode network stack,,, QEMU, QEMU Documentation}).
+@end defvr
+
 @cindex DHCP, networking service
 @defvr {Scheme Variable} dhcp-client-service-type
 This is the type of services that run @var{dhcp}, a Dynamic Host Configuration
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 112c6ab065..e78add4e20 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -113,6 +113,8 @@ (define-module (gnu services base)
             static-networking-service
             static-networking-service-type
 
+            %qemu-static-networking
+
             udev-configuration
             udev-configuration?
             udev-configuration-rules
@@ -2669,6 +2671,20 @@ (define-deprecated (static-networking-service interface ip
                          (provision (or provision '(networking)))
                          (name-servers name-servers)))))
 
+(define %qemu-static-networking
+  ;; Networking configuration for QEMU's user-mode network stack (info "(QEMU)
+  ;; Using the user mode network stack").
+  (static-networking
+   (addresses (list (network-address
+                     (device "eth0")
+                     (value "10.0.2.15/24"))))
+   (routes (list (network-route
+                  (destination "default")
+                  (gateway "10.0.2.2"))))
+   (requirement '())
+   (provision '(networking))
+   (name-servers '("10.0.2.3"))))
+
 
 (define %base-services
   ;; Convenience variable holding the basic services.
diff --git a/gnu/system/hurd.scm b/gnu/system/hurd.scm
index 0e73ca0d99..ec8484d746 100644
--- a/gnu/system/hurd.scm
+++ b/gnu/system/hurd.scm
@@ -86,21 +86,12 @@ (define %base-services/hurd
                                 (value "127.0.0.1"))))
                         (requirement '())
                         (provision '(loopback)))
-                       (static-networking
-                        (addresses
-                         ;; The default QEMU guest address.  To get "eth0",
-                         ;; you need QEMU to emulate a device for which Mach
-                         ;; has an in-kernel driver, for instance with:
-                         ;; --device rtl8139,netdev=net0 --netdev user,id=net0
-                         (list (network-address
-                                (device "eth0")
-                                (value "10.0.2.15/24"))))
-                        (routes
-                         (list (network-route
-                                (destination "default")
-                                (gateway "10.0.2.2"))))
-                        (provision '(networking))
-                        (name-servers '("10.0.2.3")))))
+
+                       ;; QEMU user-mode networking.  To get "eth0", you need
+                       ;; QEMU to emulate a device for which Mach has an
+                       ;; in-kernel driver, for instance with:
+                       ;; --device rtl8139,netdev=net0 --netdev user,id=net0
+                       %qemu-static-networking))
         (syslog-service)
         (service guix-service-type
                  (guix-configuration
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:04 GMT) Full text and rfc822 format available.

Message #80 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 10/10] tests: Replace uses of deprecated
 'static-networking-service'.
Date: Mon, 15 Nov 2021 23:30:44 +0100
* gnu/tests/ganeti.scm (%ganeti-os): Replace call to
'static-networking-service' by instantiating
STATIC-NETWORKING-SERVICE-TYPE.
* gnu/tests/networking.scm (%test-static-networking)
(%openvswitch-os, %dhcpd-os): Likewise.
---
 gnu/tests/ganeti.scm     |  7 ++-----
 gnu/tests/networking.scm | 29 ++++++++++++++++++-----------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/gnu/tests/ganeti.scm b/gnu/tests/ganeti.scm
index 5ac2fd48dd..c29b885a5e 100644
--- a/gnu/tests/ganeti.scm
+++ b/gnu/tests/ganeti.scm
@@ -59,11 +59,8 @@ (define %ganeti-os
     (packages (append (list ganeti-instance-debootstrap ganeti-instance-guix)
                       %base-packages))
     (services
-     (append (list (static-networking-service "eth0" "10.0.2.15"
-                                              #:netmask "255.255.255.0"
-                                              #:gateway "10.0.2.2"
-                                              #:name-servers '("10.0.2.3"))
-
+     (append (list (service static-networking-service-type
+                            (list %qemu-static-networking))
                    (service openssh-service-type
                             (openssh-configuration
                              (permit-root-login 'prohibit-password)))
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index c66af279f2..246e0a15fa 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -122,10 +122,8 @@ (define %test-static-networking
    (value
     (let ((os (marionette-operating-system
                (simple-operating-system
-                (static-networking-service "eth0" "10.0.2.15"
-                                           #:netmask "255.255.255.0"
-                                           #:gateway "10.0.2.2"
-                                           #:name-servers '("10.0.2.2")))
+                (service static-networking-service-type
+                         (list %qemu-static-networking)))
                #:imported-modules '((gnu services herd)
                                     (guix combinators)))))
       (run-static-networking-test (virtual-machine os))))))
@@ -275,9 +273,13 @@ (define openvswitch-configuration-service
 (define %openvswitch-os
   (operating-system
     (inherit (simple-operating-system
-              (static-networking-service "ovs0" "10.1.1.1"
-                                         #:netmask "255.255.255.252"
-                                         #:requirement '(openvswitch-configuration))
+              (simple-service 'openswitch-networking
+                              static-networking-service-type
+                              (list (static-networking
+                                     (addresses (list (network-address
+                                                       (value "10.1.1.1/24")
+                                                       (device "ovs0"))))
+                                     (requirement '(openvswitch-configuration)))))
               (service openvswitch-service-type)
               openvswitch-configuration-service))
     ;; Ensure the interface name does not change depending on the driver.
@@ -392,10 +394,15 @@ (define dhcpd-v4-configuration
 
 (define %dhcpd-os
   (simple-operating-system
-   (static-networking-service "ens3" "192.168.1.4"
-                              #:netmask "255.255.255.0"
-                              #:gateway "192.168.1.1"
-                              #:name-servers '("192.168.1.2" "192.168.1.3"))
+   (service static-networking-service-type
+            (list (static-networking
+                   (addresses (list (network-address
+                                     (value "192.168.1.4/24")
+                                     (device "ens3"))))
+                   (routes (list (network-route
+                                  (destination "default")
+                                  (gateway "192.168.1.1"))))
+                   (name-servers '("192.168.1.2" "192.168.1.3")))))
    (service dhcpd-service-type dhcpd-v4-configuration)))
 
 (define (run-dhcpd-test)
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:04 GMT) Full text and rfc822 format available.

Message #83 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 07/10] services: static-networking: Change interface to
 mimic netlink.
Date: Mon, 15 Nov 2021 23:30:41 +0100
* gnu/services/base.scm (<static-networking>)[interface, ip, netmask]
[gateway]: Remove.
[addresses, links, routes]: New fields.
[requirement]: Default to '(udev).
(<network-address>, <network-link>, <network-route>): New record types.
(ensure-no-separate-netmask, %ensure-no-separate-netmask): Remove.
(ipv6-address?, cidr->netmask, ip+netmask->cidr)
(network-set-up/hurd, network-tear-down/hurd)
(network-set-up/linux, network-tear-down/linux)
(static-networking->hurd-pfinet-options): New procedures.
(static-networking-shepherd-service): New procedure.
(static-networking-shepherd-services): Rewrite in terms of the above.
(static-networking-service): Deprecate.  Adjust to new
'static-networking' API.
(%base-services): Likewise.
* gnu/system/install.scm (%installation-services): Likewise.
* gnu/system/hurd.scm (%base-services/hurd): Likewise, and separate
'loopback' from 'networking'.
* gnu/build/hurd-boot.scm (set-hurd-device-translators): Remove
"servers/socket/2".
* gnu/tests/networking.scm (run-openvswitch-test)["networking has
started on ovs0"]: Check for 'networking instead of 'networking-ovs0,
which is no longer provided.
* doc/guix.texi (Networking Setup): Document the new interface.  Remove
documentation of 'static-networking-service'.
(Virtualization Services): Change Ganeti example to use the new
interface.
---
 doc/guix.texi            | 190 ++++++++++++++---
 gnu/build/hurd-boot.scm  |  10 +-
 gnu/services/base.scm    | 425 +++++++++++++++++++++++++++------------
 gnu/system/hurd.scm      |  27 ++-
 gnu/system/install.scm   |  11 +-
 gnu/tests/networking.scm |   2 +-
 6 files changed, 494 insertions(+), 171 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 399664b910..439ef28e96 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -16780,32 +16780,165 @@ This section describes the various network setup services available,
 starting with static network configuration.
 
 @defvr {Scheme Variable} static-networking-service-type
-This is the type for statically-configured network interfaces.
-@c TODO Document <static-networking> data structures.
+This is the type for statically-configured network interfaces.  Its
+value must be a list of @code{static-networking} records.  Each of them
+declares a set of @dfn{addresses}, @dfn{routes}, and @dfn{links}, as
+show below.
+
+@cindex network interface controller (NIC)
+@cindex NIC, networking interface controller
+Here is the simplest configuration, with only one network interface
+controller (NIC) and only IPv4 connectivity:
+
+@example
+;; Static networking for one NIC, IPv4-only.
+(service static-networking-service-type
+         (list (static-networking
+                (addresses
+                 (list (network-address
+                        (device "eno1")
+                        (value "10.0.2.15/24"))))
+                (routes
+                 (list (network-route
+                        (destination "default")
+                        (gateway "10.0.2.2"))))
+                (name-servers '("10.0.2.3")))))
+@end example
+
+The snippet above can be added to the @code{services} field of your
+operating system configuration (@pxref{Using the Configuration System}).
+It will configure your machine to have 10.0.2.15 as its IP address, with
+a 24-bit netmask for the local network---meaning that any 10.0.2.@var{x}
+address is on the local area network (LAN).  Traffic to addresses
+outside the local network is routed @i{via} 10.0.2.2.  Host names are
+resolved by sending domain name system (DNS) queries to 10.0.2.3.
 @end defvr
 
-@deffn {Scheme Procedure} static-networking-service @var{interface} @var{ip} @
-       [#:netmask #f] [#:gateway #f] [#:name-servers @code{'()}] @
-       [#:requirement @code{'(udev)}]
-Return a service that starts @var{interface} with address @var{ip}.  If
-@var{netmask} is true, use it as the network mask.  If @var{gateway} is true,
-it must be a string specifying the default network gateway.  @var{requirement}
-can be used to declare a dependency on another service before configuring the
-interface.
+@deftp {Data Type} static-networking
+This is the data type representing a static network configuration.
 
-This procedure can be called several times, one for each network
-interface of interest.  Behind the scenes what it does is extend
-@code{static-networking-service-type} with additional network interfaces
-to handle.
-
-For example:
+As an example, here is how you would declare the configuration of a
+machine with a single network interface controller (NIC) available as
+@code{eno1}, and with one IPv4 and one IPv6 address:
 
 @lisp
-(static-networking-service "eno1" "192.168.1.82"
-                           #:gateway "192.168.1.2"
-                           #:name-servers '("192.168.1.2"))
+;; Network configuration for one NIC, IPv4 + IPv6.
+(static-networking
+ (addresses (list (network-address
+                   (device "eno1")
+                   (value "10.0.2.15/24"))
+                  (network-address
+                   (device "eno1")
+                   (value "2001:123:4567:101::1/64"))))
+ (routes (list (network-route
+                (destination "default")
+                (gateway "10.0.2.2"))
+               (network-route
+                (destination "default")
+                (gateway "2020:321:4567:42::1"))))
+ (name-servers '("10.0.2.3")))
 @end lisp
-@end deffn
+
+If you are familiar with the @command{ip} command of the
+@uref{https://wiki.linuxfoundation.org/networking/iproute2,
+@code{iproute2} package} found on Linux-based systems, the declaration
+above is equivalent to typing:
+
+@example
+ip address add 10.0.2.15/24 dev eno1
+ip address add 2001:123:4567:101::1/64 dev eno1
+ip route add default via inet 10.0.2.2
+ip route add default via inet6 2020:321:4567:42::1
+@end example
+
+Run @command{man 8 ip} for more info.  Venerable GNU/Linux users will
+certainly know how to do it with @command{ifconfig} and @command{route},
+but we'll spare you that.
+
+The available fields of this data type are as follows:
+
+@table @asis
+@item @code{addresses}
+@itemx @code{links} (default: @code{'()})
+@itemx @code{routes} (default: @code{'()})
+The list of @code{network-address}, @code{network-link}, and
+@code{network-route} records for this network (see below).
+
+@item @code{name-servers} (default: @code{'()})
+The list of IP addresses (strings) of domain name servers.  These IP
+addresses go to @file{/etc/resolv.conf}.
+
+@item @code{provision} (default: @code{'(networking)})
+If true, this should be a list of symbols for the Shepherd service
+corresponding to this network configuration.
+
+@item @code{requirement} (default @code{'()})
+The list of Shepherd services depended on.
+@end table
+@end deftp
+
+@deftp {Data Type} network-address
+This is the data type representing the IP address of a network
+interface.
+
+@table @code
+@item device
+The name of the network interface for this address---e.g.,
+@code{"eno1"}.
+
+@item value
+The actual IP address and network mask, in
+@uref{https://en.wikipedia.org/wiki/CIDR#CIDR_notation, @acronym{CIDR,
+Classless Inter-Domain Routing} notation}, as a string.
+
+For example, @code{"10.0.2.15/24"} denotes IPv4 address 10.0.2.15 on a
+24-bit sub-network---all 10.0.2.@var{x} addresses are on the same local
+network.
+
+@item ipv6?
+Whether @code{value} denotes an IPv6 address.  By default this is
+automatically determined.
+@end table
+@end deftp
+
+@deftp {Data Type} network-route
+This is the data type representing a network route.
+
+@table @asis
+@item @code{destination}
+The route destination (a string), either an IP address or
+@code{"default"} to denote the default route.
+
+@item @code{source} (default: @code{#f})
+The route source.
+
+@item @code{device} (default: @code{#f})
+The device used for this route---e.g., @code{"eno2"}.
+
+@item @code{ipv6?} (default: auto)
+Whether this is an IPv6 route.  By default this is automatically
+determined based on @code{destination} or @code{gateway}.
+
+@item @code{gateway} (default: @code{#f})
+IP address (a string) through which traffic is routed.
+@end table
+@end deftp
+
+@deftp {Data Type} network-link
+Data type for a network link (@pxref{Link,,, guile-netlink,
+Guile-Netlink Manual}).
+
+@table @code
+@item name
+The name of the link---e.g., @code{"v0p0"}.
+
+@item type
+A symbol denoting the type of the link---e.g., @code{'veth}.
+
+@item arguments
+List of arguments for this type of link.
+@end table
+@end deftp
 
 @cindex DHCP, networking service
 @defvr {Scheme Variable} dhcp-client-service-type
@@ -30371,11 +30504,18 @@ cluster node that supports multiple storage backends, and installs the
                            "ganeti-instance-guix" "ganeti-instance-debootstrap"))
                     %base-packages))
   (services
-   (append (list (static-networking-service "eth0" "192.168.1.201"
-                                            #:netmask "255.255.255.0"
-                                            #:gateway "192.168.1.254"
-                                            #:name-servers '("192.168.1.252"
-                                                             "192.168.1.253"))
+   (append (list (service static-networking-service-type
+                          (list (static-networking
+                                 (addresses
+                                  (list (network-address
+                                         (device "eth0")
+                                         (value "192.168.1.201/24"))))
+                                 (routes
+                                  (list (network-route
+                                         (destination "default")
+                                         (gateway "192.168.1.254"))))
+                                 (name-servers '("192.168.1.252"
+                                                 "192.168.1.253")))))
 
                  ;; Ganeti uses SSH to communicate between nodes.
                  (service openssh-service-type
diff --git a/gnu/build/hurd-boot.scm b/gnu/build/hurd-boot.scm
index 8b27995438..ac36bd17d4 100644
--- a/gnu/build/hurd-boot.scm
+++ b/gnu/build/hurd-boot.scm
@@ -185,13 +185,9 @@ (define servers
       ("servers/crash-suspend"   ("/hurd/crash" "--suspend"))
       ("servers/password"        ("/hurd/password"))
       ("servers/socket/1"        ("/hurd/pflocal"))
-      ("servers/socket/2"        ("/hurd/pfinet"
-                                  "--interface" "eth0"
-                                  "--address"
-                                  "10.0.2.15" ;the default QEMU guest IP
-                                  "--netmask" "255.255.255.0"
-                                  "--gateway" "10.0.2.2"
-                                  "--ipv6" "/servers/socket/26"))
+      ;; /servers/socket/2 and /26 are created by 'static-networking-service'.
+      ;; XXX: Spawn pfinet without arguments on these nodes so that a DHCP
+      ;; client has someone to talk to?
       ("proc"                    ("/hurd/procfs" "--stat-mode=444"))))
 
   (define devices
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index d5ee03bbbd..112c6ab065 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -35,6 +35,8 @@
 (define-module (gnu services base)
   #:use-module (guix store)
   #:use-module (guix deprecation)
+  #:autoload   (guix diagnostics) (warning)
+  #:autoload   (guix i18n) (G_)
   #:use-module (gnu services)
   #:use-module (gnu services admin)
   #:use-module (gnu services shepherd)
@@ -54,6 +56,7 @@ (define-module (gnu services base)
   #:use-module ((gnu packages base)
                 #:select (coreutils glibc glibc-utf8-locales))
   #:autoload   (gnu packages guile-xyz) (guile-netlink)
+  #:autoload   (gnu packages hurd) (hurd)
   #:use-module (gnu packages package-management)
   #:use-module ((gnu packages gnupg) #:select (guile-gcrypt))
   #:use-module (gnu packages linux)
@@ -81,14 +84,32 @@ (define-module (gnu services base)
             virtual-terminal-service-type
 
             static-networking
-
             static-networking?
-            static-networking-interface
-            static-networking-ip
-            static-networking-netmask
-            static-networking-gateway
+            static-networking-addresses
+            static-networking-links
+            static-networking-routes
             static-networking-requirement
 
+            network-address
+            network-address?
+            network-address-device
+            network-address-value
+            network-address-ipv6?
+
+            network-link
+            network-link?
+            network-link-name
+            network-link-type
+            network-link-arguments
+
+            network-route
+            network-route?
+            network-route-destination
+            network-route-source
+            network-route-device
+            network-route-ipv6?
+            network-route-gateway
+
             static-networking-service
             static-networking-service-type
 
@@ -2316,113 +2337,267 @@ (define kmscon-command
    (description "Start the @command{kmscon} virtual terminal emulator for the
 Linux @dfn{kernel mode setting} (KMS).")))
 
+
+;;;
+;;; Static networking.
+;;;
+
+(define (ipv6-address? str)
+  "Return true if STR denotes an IPv6 address."
+  (false-if-exception (->bool (inet-pton AF_INET6 str))))
+
 (define-record-type* <static-networking>
   static-networking make-static-networking
   static-networking?
-  (interface static-networking-interface)
-  (ip static-networking-ip)
-  (netmask static-networking-netmask
-           (default #f))
-  (gateway static-networking-gateway              ;FIXME: doesn't belong here
-           (default #f))
+  (addresses static-networking-addresses)         ;list of <network-address>
+  (links     static-networking-links (default '())) ;list of <network-link>
+  (routes    static-networking-routes (default '())) ;list of <network-routes>
   (provision static-networking-provision
-             (default #f))
+             (default '(networking)))
   (requirement static-networking-requirement
-               (default '()))
+               (default '(udev)))
   (name-servers static-networking-name-servers    ;FIXME: doesn't belong here
                 (default '())))
 
-(define static-networking-shepherd-service
+(define-record-type* <network-address>
+  network-address make-network-address
+  network-address?
+  (device    network-address-device)              ;string--e.g., "en01"
+  (value     network-address-value)               ;string--CIDR notation
+  (ipv6?     network-address-ipv6?                ;Boolean
+             (thunked)
+             (default
+               (ipv6-address? (cidr->ip (network-address-value this-record))))))
+
+(define-record-type* <network-link>
+  network-link make-network-link
+  network-link?
+  (name      network-link-name)                   ;string--e.g, "v0p0"
+  (type      network-link-type)                   ;symbol--e.g.,'veth
+  (arguments network-link-arguments))             ;list
+
+(define-record-type* <network-route>
+  network-route make-network-route
+  network-route?
+  (destination network-route-destination)
+  (source      network-route-source (default #f))
+  (device      network-route-device (default #f))
+  (ipv6?       network-route-ipv6? (thunked)
+               (default
+                 (or (ipv6-address? (network-route-destination this-record))
+                     (and=> (network-route-gateway this-record)
+                            ipv6-address?))))
+  (gateway     network-route-gateway (default #f)))
+
+(define* (cidr->netmask str #:optional (family AF_INET))
+  "Given @var{str}, a string in CIDR notation (e.g., \"1.2.3.4/24\"), return
+the netmask as a string like \"255.255.255.0\"."
+  (match (string-split str #\/)
+    ((ip (= string->number bits))
+     (let ((mask (ash (- (expt 2 bits) 1)
+                      (- (if (= family AF_INET6) 128 32)
+                         bits))))
+       (inet-ntop family mask)))
+    (_ #f)))
+
+(define (cidr->ip str)
+  "Strip the netmask bit of @var{str}, a CIDR-notation IP/netmask address."
+  (match (string-split str #\/)
+    ((or (ip _) (ip))
+     ip)))
+
+(define* (ip+netmask->cidr ip netmask #:optional (family AF_INET))
+  "Return the CIDR notation (a string) for @var{ip} and @var{netmask}, two
+@var{family} address strings, where @var{family} is @code{AF_INET} or
+@code{AF_INET6}."
+  (let* ((netmask (inet-pton family netmask))
+         (bits    (logcount netmask)))
+    (string-append ip "/" (number->string bits))))
+
+(define (static-networking->hurd-pfinet-options config)
+  "Return command-line options for the Hurd's pfinet translator corresponding
+to CONFIG."
+  (unless (null? (static-networking-links config))
+    ;; XXX: Presumably this is not supported, or perhaps could be approximated
+    ;; by running separate pfinet instances in some cases?
+    (warning (G_ "network links are currently ignored on GNU/Hurd~%")))
+
+  (match (static-networking-addresses config)
+    ((and addresses (first _ ...))
+     `("--ipv6" "/servers/socket/26"
+       "--interface" ,(network-address-device first)
+       ,@(append-map (lambda (address)
+                       `(,(if (network-address-ipv6? address)
+                              "--address6"
+                              "--address")
+                         ,(cidr->ip (network-address-value address))
+                         ,@(match (cidr->netmask (network-address-value address)
+                                                 (if (network-address-ipv6? address)
+                                                     AF_INET6
+                                                     AF_INET))
+                             (#f '())
+                             (mask (list "--netmask" mask)))))
+                     addresses)
+       ,@(append-map (lambda (route)
+                       (match route
+                         (($ <network-route> "default" #f device _ gateway)
+                          (if (network-route-ipv6? route)
+                              `("--gateway6" ,gateway)
+                              `("--gateway" ,gateway)))
+                         (($ <network-route> destination)
+                          (warning (G_ "ignoring network route for '~a'~%")
+                                   destination)
+                          '())))
+                     (static-networking-routes config))))))
+
+(define (network-set-up/hurd config)
+  "Set up networking for the Hurd."
+  ;; The Hurd implements SIOCGIFADDR and other old-style ioctls, but the only
+  ;; way to set up IPv6 is by starting pfinet with the right options.
+  (if (equal? (static-networking-provision config) '(loopback))
+      (scheme-file "set-up-pflocal" #~(begin 'nothing-to-do! #t))
+      (scheme-file "set-up-pfinet"
+                   (with-imported-modules '((guix build utils))
+                     #~(begin
+                         (use-modules (guix build utils)
+                                      (ice-9 format))
+
+                         ;; TODO: Do that without forking.
+                         (let ((options '#$(static-networking->hurd-pfinet-options
+                                            config)))
+                           (format #t "starting '~a~{ ~s~}'~%"
+                                   #$(file-append hurd "/hurd/pfinet")
+                                   options)
+                           (apply invoke #$(file-append hurd "/bin/settrans") "-fac"
+                                  "/servers/socket/2"
+                                  #$(file-append hurd "/hurd/pfinet")
+                                  options)))))))
+
+(define (network-tear-down/hurd config)
+  (scheme-file "tear-down-pfinet"
+               (with-imported-modules '((guix build utils))
+                 #~(begin
+                     (use-modules (guix build utils))
+
+                     ;; Forcefully terminate pfinet.  XXX: In theory this
+                     ;; should just undo the addresses and routes of CONFIG;
+                     ;; this could be done using ioctls like SIOCDELRT, but
+                     ;; these are IPv4-only; another option would be to use
+                     ;; fsysopts but that seems to crash pfinet.
+                     (invoke #$(file-append hurd "/bin/settrans") "-fg"
+                             "/servers/socket/2")
+                     #f))))
+
+(define network-set-up/linux
   (match-lambda
-    (($ <static-networking> interface ip netmask gateway provision
-                            requirement name-servers)
+    (($ <static-networking> addresses links routes)
+     (scheme-file "set-up-network"
+                  (with-extensions (list guile-netlink)
+                    #~(begin
+                        (use-modules (ip addr) (ip link) (ip route))
+
+                        #$@(map (lambda (address)
+                                  #~(begin
+                                      (addr-add #$(network-address-device address)
+                                                #$(network-address-value address)
+                                                #:ipv6?
+                                                #$(network-address-ipv6? address))
+                                      ;; FIXME: loopback?
+                                      (link-set #$(network-address-device address)
+                                                #:up #t)))
+                                addresses)
+                        #$@(map (match-lambda
+                                  (($ <network-link> name type arguments)
+                                   #~(link-add #$name #$type
+                                               #:type-args '#$arguments)))
+                                links)
+                        #$@(map (lambda (route)
+                                  #~(route-add #$(network-route-destination route)
+                                               #:device
+                                               #$(network-route-device route)
+                                               #:ipv6?
+                                               #$(network-route-ipv6? route)
+                                               #:via
+                                               #$(network-route-gateway route)
+                                               #:src
+                                               #$(network-route-source route)))
+                                routes)
+                        #t))))))
+
+(define network-tear-down/linux
+  (match-lambda
+    (($ <static-networking> addresses links routes)
+     (scheme-file "tear-down-network"
+                  (with-extensions (list guile-netlink)
+                    #~(begin
+                        (use-modules (ip addr) (ip link) (ip route)
+                                     (netlink error)
+                                     (srfi srfi-34))
+
+                        (define-syntax-rule (false-if-netlink-error exp)
+                          (guard (c ((netlink-error? c) #f))
+                            exp))
+
+                        ;; Wrap calls in 'false-if-netlink-error' so this
+                        ;; script goes as far as possible undoing the effects
+                        ;; of "set-up-network".
+
+                        #$@(map (lambda (route)
+                                  #~(false-if-netlink-error
+                                     (route-del #$(network-route-destination route)
+                                                #:device
+                                                #$(network-route-device route)
+                                                #:ipv6?
+                                                #$(network-route-ipv6? route)
+                                                #:via
+                                                #$(network-route-gateway route)
+                                                #:src
+                                                #$(network-route-source route))))
+                                routes)
+                        #$@(map (match-lambda
+                                  (($ <network-link> name type arguments)
+                                   #~(false-if-netlink-error
+                                      (link-del #$name))))
+                                links)
+                        #$@(map (lambda (address)
+                                  #~(false-if-netlink-error
+                                     (addr-del #$(network-address-device
+                                                  address)
+                                               #$(network-address-value address)
+                                               #:ipv6?
+                                               #$(network-address-ipv6? address))))
+                                addresses)
+                        #f))))))
+
+(define (static-networking-shepherd-service config)
+  (match config
+    (($ <static-networking> addresses links routes
+                            provision requirement name-servers)
      (let ((loopback? (and provision (memq 'loopback provision))))
-       (define set-up-via-ioctl
-         #~(let* ((addr     (inet-pton AF_INET #$ip))
-                  (sockaddr (make-socket-address AF_INET addr 0))
-                  (mask     (and #$netmask (inet-pton AF_INET #$netmask)))
-                  (maskaddr (and mask
-                                 (make-socket-address AF_INET mask 0)))
-                  (gateway  (and #$gateway
-                                 (inet-pton AF_INET #$gateway)))
-                  (gatewayaddr (and gateway
-                                    (make-socket-address AF_INET
-                                                         gateway 0))))
-             (configure-network-interface #$interface sockaddr
-                                          (logior IFF_UP
-                                                  #$(if loopback?
-                                                        #~IFF_LOOPBACK
-                                                        0))
-                                          #:netmask maskaddr)
-             (when gateway
-               (let ((sock (socket AF_INET SOCK_DGRAM 0)))
-                 (add-network-route/gateway sock gatewayaddr)
-                 (close-port sock)))))
-
-       (define tear-down-via-ioctl
-         #~(let ((sock (socket AF_INET SOCK_STREAM 0)))
-             (when #$gateway
-               (delete-network-route sock
-                                     (make-socket-address AF_INET
-                                                          INADDR_ANY 0)))
-             (set-network-interface-flags sock #$interface 0)
-             (close-port sock)
-             #f))
-
-       (define set-up-via-netlink
-         (with-extensions (list guile-netlink)
-           #~(let ((ip #$(if netmask
-                             #~(ip+netmask->cidr #$ip #$netmask)
-                             ip)))
-               (addr-add #$interface ip)
-               (when #$gateway
-                 (route-add "default" #:device #$interface
-                            #:via #$gateway))
-               (link-set #$interface #:up #t))))
-
-       (define tear-down-via-netlink
-         (with-extensions (list guile-netlink)
-           #~(begin
-               (link-set #$interface #:down #t)
-               (when #$gateway
-                 (route-del "default" #:device #$interface))
-               (addr-del #$interface #$ip)
-               #f)))
-
-       (define helpers
-         #~(define (ip+netmask->cidr ip netmask)
-             ;; Return the CIDR notation (a string) for IP and NETMASK, two
-             ;; IPv4 address strings.
-             (let* ((netmask (inet-pton AF_INET netmask))
-                    (bits    (logcount netmask)))
-               (string-append ip "/" (number->string bits)))))
-
        (shepherd-service
 
         (documentation
          "Bring up the networking interface using a static IP address.")
         (requirement requirement)
-        (provision (or provision
-                       (list (symbol-append 'networking-
-                                            (string->symbol interface)))))
+        (provision provision)
 
         (start #~(lambda _
                    ;; Return #t if successfully started.
-                   #$helpers
-                   (if (string-contains %host-type "-linux")
-                       #$set-up-via-netlink
-                       #$set-up-via-ioctl)))
+                   (load #$(let-system (system target)
+                             (if (string-contains (or target system) "-linux")
+                                 (network-set-up/linux config)
+                                 (network-set-up/hurd config))))))
         (stop #~(lambda _
                   ;; Return #f is successfully stopped.
-                  (if (string-contains %host-type "-linux")
-                      #$tear-down-via-netlink
-                      #$tear-down-via-ioctl)))
-        (modules `((ip addr)
-                   (ip link)
-                   (ip route)
-                   ,@%default-modules))
+                  (load #$(let-system (system target)
+                            (if (string-contains (or target system) "-linux")
+                                (network-tear-down/linux config)
+                                (network-tear-down/hurd config))))))
         (respawn? #f))))))
 
+(define (static-networking-shepherd-services networks)
+  (map static-networking-shepherd-service networks))
+
 (define (static-networking-etc-files interfaces)
   "Return a /etc/resolv.conf entry for INTERFACES or the empty list."
   (match (delete-duplicates
@@ -2441,30 +2616,6 @@ (define (static-networking-etc-files interfaces)
 # Generated by 'static-networking-service'.\n"
                                       content))))))))
 
-(define (static-networking-shepherd-services interfaces)
-  "Return the list of Shepherd services to bring up INTERFACES, a list of
-<static-networking> objects."
-  (define (loopback? service)
-    (memq 'loopback (shepherd-service-provision service)))
-
-  (let ((services (map static-networking-shepherd-service interfaces)))
-    (match (remove loopback? services)
-      (()
-       ;; There's no interface other than 'loopback', so we assume that the
-       ;; 'networking' service will be provided by dhclient or similar.
-       services)
-      ((non-loopback ...)
-       ;; Assume we're providing all the interfaces, and thus, provide a
-       ;; 'networking' service.
-       (cons (shepherd-service
-              (provision '(networking))
-              (requirement (append-map shepherd-service-provision
-                                       services))
-              (start #~(const #t))
-              (stop #~(const #f))
-              (documentation "Bring up all the networking interfaces."))
-             services)))))
-
 (define static-networking-service-type
   ;; The service type for statically-defined network interfaces.
   (service-type (name 'static-networking)
@@ -2482,12 +2633,13 @@ (define static-networking-service-type
 services of this type is a list of @code{static-networking} objects, one per
 network interface.")))
 
-(define* (static-networking-service interface ip
-                                    #:key
-                                    netmask gateway provision
-                                    ;; Most interfaces require udev to be usable.
-                                    (requirement '(udev))
-                                    (name-servers '()))
+(define-deprecated (static-networking-service interface ip
+                                              #:key
+                                              netmask gateway provision
+                                              ;; Most interfaces require udev to be usable.
+                                              (requirement '(udev))
+                                              (name-servers '()))
+  static-networking-service-type
   "Return a service that starts @var{interface} with address @var{ip}.  If
 @var{netmask} is true, use it as the network mask.  If @var{gateway} is true,
 it must be a string specifying the default network gateway.
@@ -2498,11 +2650,24 @@ (define* (static-networking-service interface ip
 to handle."
   (simple-service 'static-network-interface
                   static-networking-service-type
-                  (list (static-networking (interface interface) (ip ip)
-                                           (netmask netmask) (gateway gateway)
-                                           (provision provision)
-                                           (requirement requirement)
-                                           (name-servers name-servers)))))
+                  (list (static-networking
+                         (addresses
+                          (list (network-address
+                                 (device interface)
+                                 (value (if netmask
+                                            (ip+netmask->cidr ip netmask)
+                                            ip))
+                                 (ipv6? #f))))
+                         (routes
+                          (if gateway
+                              (list (network-route
+                                     (destination "default")
+                                     (gateway gateway)
+                                     (ipv6? #f)))
+                              '()))
+                         (requirement requirement)
+                         (provision (or provision '(networking)))
+                         (name-servers name-servers)))))
 
 
 (define %base-services
@@ -2534,10 +2699,12 @@ (define %base-services
                                          (tty "tty6")))
 
         (service static-networking-service-type
-                 (list (static-networking (interface "lo")
-                                          (ip "127.0.0.1")
-                                          (requirement '())
-                                          (provision '(loopback)))))
+                 (list (static-networking
+                        (addresses (list (network-address
+                                          (device "lo")
+                                          (value "127.0.0.1"))))
+                        (requirement '())
+                        (provision '(loopback)))))
         (syslog-service)
         (service urandom-seed-service-type)
         (service guix-service-type)
diff --git a/gnu/system/hurd.scm b/gnu/system/hurd.scm
index 0794671ce4..0e73ca0d99 100644
--- a/gnu/system/hurd.scm
+++ b/gnu/system/hurd.scm
@@ -79,11 +79,28 @@ (define %base-services/hurd
         (service hurd-getty-service-type (hurd-getty-configuration
                                           (tty "tty2")))
         (service static-networking-service-type
-                 (list (static-networking (interface "lo")
-                                          (ip "127.0.0.1")
-                                          (requirement '())
-                                          (provision '(loopback networking))
-                                          (name-servers '("10.0.2.3")))))
+                 (list (static-networking
+                        (addresses
+                         (list (network-address
+                                (device "lo")
+                                (value "127.0.0.1"))))
+                        (requirement '())
+                        (provision '(loopback)))
+                       (static-networking
+                        (addresses
+                         ;; The default QEMU guest address.  To get "eth0",
+                         ;; you need QEMU to emulate a device for which Mach
+                         ;; has an in-kernel driver, for instance with:
+                         ;; --device rtl8139,netdev=net0 --netdev user,id=net0
+                         (list (network-address
+                                (device "eth0")
+                                (value "10.0.2.15/24"))))
+                        (routes
+                         (list (network-route
+                                (destination "default")
+                                (gateway "10.0.2.2"))))
+                        (provision '(networking))
+                        (name-servers '("10.0.2.3")))))
         (syslog-service)
         (service guix-service-type
                  (guix-configuration
diff --git a/gnu/system/install.scm b/gnu/system/install.scm
index 7b394184ad..bdfe580145 100644
--- a/gnu/system/install.scm
+++ b/gnu/system/install.scm
@@ -408,10 +408,13 @@ (define bare-bones-os
 
           ;; Loopback device, needed by OpenSSH notably.
           (service static-networking-service-type
-                   (list (static-networking (interface "lo")
-                                            (ip "127.0.0.1")
-                                            (requirement '())
-                                            (provision '(loopback)))))
+                   (list (static-networking
+                          (addresses
+                           (list (network-address
+                                  (device "lo")
+                                  (value "127.0.0.1"))))
+                          (requirement '())
+                          (provision '(loopback)))))
 
           (service wpa-supplicant-service-type)
           (dbus-service)
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index 131428c128..c66af279f2 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -337,7 +337,7 @@ (define marionette
                              (srfi srfi-1))
                 (live-service-running
                  (find (lambda (live)
-                         (memq 'networking-ovs0
+                         (memq 'networking
                                (live-service-provision live)))
                        (current-services))))
              marionette))
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:04 GMT) Full text and rfc822 format available.

Message #86 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 09/10] services: Define '%loopback-static-networking'.
Date: Mon, 15 Nov 2021 23:30:43 +0100
* gnu/services/base.scm (%loopback-static-networking): New variable.
(%base-services): Use it.
* gnu/system/hurd.scm (%base-services/hurd): Use it.
* gnu/system/install.scm (%installation-services): Use it.
* doc/guix.texi (Networking Setup): Document it.
---
 doc/guix.texi          |  7 +++++++
 gnu/services/base.scm  | 17 +++++++++++------
 gnu/system/hurd.scm    |  8 +-------
 gnu/system/install.scm |  8 +-------
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 85e76991d9..2e72eb64d2 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -16940,6 +16940,13 @@ List of arguments for this type of link.
 @end table
 @end deftp
 
+@cindex loopback device
+@defvr {Scheme Variable} %loopback-static-networking
+This is the @code{static-networking} record representing the ``loopback
+device'', @code{lo}, for IP addresses 127.0.0.1 and ::1, and providing
+the @code{loopback} Shepherd service.
+@end defvr
+
 @cindex networking, with QEMU
 @cindex QEMU, networking
 @defvr {Scheme Variable} %qemu-static-networking
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index e78add4e20..d996a7b07c 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -113,6 +113,7 @@ (define-module (gnu services base)
             static-networking-service
             static-networking-service-type
 
+            %loopback-static-networking
             %qemu-static-networking
 
             udev-configuration
@@ -2671,6 +2672,15 @@ (define-deprecated (static-networking-service interface ip
                          (provision (or provision '(networking)))
                          (name-servers name-servers)))))
 
+(define %loopback-static-networking
+  ;; The loopback device.
+  (static-networking
+   (addresses (list (network-address
+                     (device "lo")
+                     (value "127.0.0.1"))))
+   (requirement '())
+   (provision '(loopback))))
+
 (define %qemu-static-networking
   ;; Networking configuration for QEMU's user-mode network stack (info "(QEMU)
   ;; Using the user mode network stack").
@@ -2715,12 +2725,7 @@ (define %base-services
                                          (tty "tty6")))
 
         (service static-networking-service-type
-                 (list (static-networking
-                        (addresses (list (network-address
-                                          (device "lo")
-                                          (value "127.0.0.1"))))
-                        (requirement '())
-                        (provision '(loopback)))))
+                 (list %loopback-static-networking))
         (syslog-service)
         (service urandom-seed-service-type)
         (service guix-service-type)
diff --git a/gnu/system/hurd.scm b/gnu/system/hurd.scm
index ec8484d746..2acc7b7e11 100644
--- a/gnu/system/hurd.scm
+++ b/gnu/system/hurd.scm
@@ -79,13 +79,7 @@ (define %base-services/hurd
         (service hurd-getty-service-type (hurd-getty-configuration
                                           (tty "tty2")))
         (service static-networking-service-type
-                 (list (static-networking
-                        (addresses
-                         (list (network-address
-                                (device "lo")
-                                (value "127.0.0.1"))))
-                        (requirement '())
-                        (provision '(loopback)))
+                 (list %loopback-static-networking
 
                        ;; QEMU user-mode networking.  To get "eth0", you need
                        ;; QEMU to emulate a device for which Mach has an
diff --git a/gnu/system/install.scm b/gnu/system/install.scm
index bdfe580145..073d7df1db 100644
--- a/gnu/system/install.scm
+++ b/gnu/system/install.scm
@@ -408,13 +408,7 @@ (define bare-bones-os
 
           ;; Loopback device, needed by OpenSSH notably.
           (service static-networking-service-type
-                   (list (static-networking
-                          (addresses
-                           (list (network-address
-                                  (device "lo")
-                                  (value "127.0.0.1"))))
-                          (requirement '())
-                          (provision '(loopback)))))
+                   (list %loopback-static-networking))
 
           (service wpa-supplicant-service-type)
           (dbus-service)
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:05 GMT) Full text and rfc822 format available.

Message #89 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 04/10] gnu: guile-netlink: Allow cross-compilation.
Date: Mon, 15 Nov 2021 23:30:38 +0100
* gnu/packages/guile-xyz.scm (guile-netlink)[arguments]: Remove,
since #:tests? #f is unnecessary.
[native-inputs]: Add GUILE-3.0.
---
 gnu/packages/guile-xyz.scm | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gnu/packages/guile-xyz.scm b/gnu/packages/guile-xyz.scm
index 628d81710a..2751abc8e8 100644
--- a/gnu/packages/guile-xyz.scm
+++ b/gnu/packages/guile-xyz.scm
@@ -4777,14 +4777,13 @@ (define-public guile-netlink
         (base32
          "1x1rx6agjdah56r50cfs41vyvycydyjdq0plq3jxgvl1q2dar1gw"))))
     (build-system gnu-build-system)
-    (arguments
-     `(#:tests? #f)); no tests
     (inputs
      `(("guile" ,guile-3.0)))
     (native-inputs
      `(("automake" ,automake)
        ("autoconf" ,autoconf)
        ("pkg-config" ,pkg-config)
+       ("guile" ,guile-3.0)                    ;for 'guild compile' + guile.m4
        ("texinfo" ,texinfo)))
     (home-page "https://git.lepiller.eu/guile-netlink")
     (synopsis "Netlink protocol implementation for Guile")
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:05 GMT) Full text and rfc822 format available.

Message #92 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 06/10] services: secret-service: Turn into a Shepherd
 service.
Date: Mon, 15 Nov 2021 23:30:40 +0100
* gnu/services/virtualization.scm (secret-service-activation): Remove.
(secret-service-shepherd-services): New procedure.
(secret-service-type)[extensions]: Remove ACTIVATION-SERVICE-TYPE
extension.  Add SHEPHERD-ROOT-SERVICE-TYPE and
USER-PROCESSES-SERVICE-TYPE extensions.
* gnu/build/secret-service.scm (delete-file*): New procedure.
(secret-service-receive-secrets): Use it.
---
 gnu/build/secret-service.scm    | 17 ++++++++++++-
 gnu/services/virtualization.scm | 45 ++++++++++++++++++++++++---------
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/gnu/build/secret-service.scm b/gnu/build/secret-service.scm
index 46dcf1b9c3..4e183e11e8 100644
--- a/gnu/build/secret-service.scm
+++ b/gnu/build/secret-service.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2020 Ludovic Courtès <ludo <at> gnu.org>
+;;; Copyright © 2020, 2021 Ludovic Courtès <ludo <at> gnu.org>
 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke <at> gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -111,6 +111,15 @@ (define (send-files sock)
        (close-port sock)
        #f))))
 
+(define (delete-file* file)
+  "Ensure FILE does not exist."
+  (catch 'system-error
+    (lambda ()
+      (delete-file file))
+    (lambda args
+      (unless (= ENOENT (system-error-errno args))
+        (apply throw args)))))
+
 (define (secret-service-receive-secrets port)
   "Listen to local PORT and wait for a secret service client to send secrets.
 Write them to the file system.  Return the list of files installed on success,
@@ -170,6 +179,12 @@ (define (read-secrets port)
                    (log "installing file '~a' (~a bytes)...~%"
                         file size)
                    (mkdir-p (dirname file))
+
+                   ;; It could be that FILE already exists, for instance
+                   ;; because it has been created by a service's activation
+                   ;; snippet (e.g., SSH host keys).  Delete it.
+                   (delete-file* file)
+
                    (call-with-output-file file
                      (lambda (output)
                        (dump port output size)
diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm
index 1a5744ffbf..b1b10afed6 100644
--- a/gnu/services/virtualization.scm
+++ b/gnu/services/virtualization.scm
@@ -898,23 +898,44 @@ (define qemu-guest-agent-service-type
 ;;; Secrets for guest VMs.
 ;;;
 
-(define (secret-service-activation port)
-  "Return an activation snippet that fetches sensitive material at local PORT,
+(define (secret-service-shepherd-services port)
+  "Return a Shepherd service that fetches sensitive material at local PORT,
 over TCP.  Reboot upon failure."
-  (with-imported-modules '((gnu build secret-service)
-                           (guix build utils))
-    #~(begin
-        (use-modules (gnu build secret-service))
-        (let ((sent (secret-service-receive-secrets #$port)))
-          (unless sent
-            (sleep 3)
-            (reboot))))))
+  ;; This is a Shepherd service, rather than an activation snippet, to make
+  ;; sure it is started once 'networking' is up so it can accept incoming
+  ;; connections.
+  (list
+   (shepherd-service
+    (documentation "Fetch secrets from the host at startup time.")
+    (provision '(secret-service-client))
+    (requirement '(loopback networking))
+    (modules '((gnu build secret-service)
+               (guix build utils)))
+    (start (with-imported-modules '((gnu build secret-service)
+                                    (guix build utils))
+             #~(lambda ()
+                 ;; Since shepherd's output port goes to /dev/log, write this
+                 ;; message to stderr so it's visible on the Mach console.
+                 (format (current-error-port)
+                         "receiving secrets from the host...~%")
+                 (force-output (current-error-port))
+
+                 (let ((sent (secret-service-receive-secrets #$port)))
+                   (unless sent
+                     (sleep 3)
+                     (reboot))))))
+    (stop #~(const #f)))))
 
 (define secret-service-type
   (service-type
    (name 'secret-service)
-   (extensions (list (service-extension activation-service-type
-                                        secret-service-activation)))
+   (extensions (list (service-extension shepherd-root-service-type
+                                        secret-service-shepherd-services)
+
+                     ;; Make every Shepherd service depend on
+                     ;; 'secret-service-client'.
+                     (service-extension user-processes-service-type
+                                        (const '(secret-service-client)))))
    (description
     "This service fetches secret key and other sensitive material over TCP at
 boot time.  This service is meant to be used by virtual machines (VMs) that
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 15 Nov 2021 22:32:06 GMT) Full text and rfc822 format available.

Message #95 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludo <at> gnu.org>
Subject: [PATCH v2 05/10] services: static-networking: Use Guile-Netlink on
 GNU/Linux.
Date: Mon, 15 Nov 2021 23:30:39 +0100
* gnu/services/base.scm (static-networking-shepherd-service): Define
'set-up-via-ioctl', 'tear-down-via-ioctl', 'set-up-via-netlink',
'tear-down-via-netlink', and 'helpers' and use them in 'start' and
'stop'.  Add (ip *) modules to 'modules'.
---
 gnu/services/base.scm | 102 +++++++++++++++++++++++++++++-------------
 1 file changed, 72 insertions(+), 30 deletions(-)

diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 50865055fe..d5ee03bbbd 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -53,6 +53,7 @@ (define-module (gnu services base)
   #:use-module (gnu packages bash)
   #:use-module ((gnu packages base)
                 #:select (coreutils glibc glibc-utf8-locales))
+  #:autoload   (gnu packages guile-xyz) (guile-netlink)
   #:use-module (gnu packages package-management)
   #:use-module ((gnu packages gnupg) #:select (guile-gcrypt))
   #:use-module (gnu packages linux)
@@ -2336,6 +2337,66 @@ (define static-networking-shepherd-service
     (($ <static-networking> interface ip netmask gateway provision
                             requirement name-servers)
      (let ((loopback? (and provision (memq 'loopback provision))))
+       (define set-up-via-ioctl
+         #~(let* ((addr     (inet-pton AF_INET #$ip))
+                  (sockaddr (make-socket-address AF_INET addr 0))
+                  (mask     (and #$netmask (inet-pton AF_INET #$netmask)))
+                  (maskaddr (and mask
+                                 (make-socket-address AF_INET mask 0)))
+                  (gateway  (and #$gateway
+                                 (inet-pton AF_INET #$gateway)))
+                  (gatewayaddr (and gateway
+                                    (make-socket-address AF_INET
+                                                         gateway 0))))
+             (configure-network-interface #$interface sockaddr
+                                          (logior IFF_UP
+                                                  #$(if loopback?
+                                                        #~IFF_LOOPBACK
+                                                        0))
+                                          #:netmask maskaddr)
+             (when gateway
+               (let ((sock (socket AF_INET SOCK_DGRAM 0)))
+                 (add-network-route/gateway sock gatewayaddr)
+                 (close-port sock)))))
+
+       (define tear-down-via-ioctl
+         #~(let ((sock (socket AF_INET SOCK_STREAM 0)))
+             (when #$gateway
+               (delete-network-route sock
+                                     (make-socket-address AF_INET
+                                                          INADDR_ANY 0)))
+             (set-network-interface-flags sock #$interface 0)
+             (close-port sock)
+             #f))
+
+       (define set-up-via-netlink
+         (with-extensions (list guile-netlink)
+           #~(let ((ip #$(if netmask
+                             #~(ip+netmask->cidr #$ip #$netmask)
+                             ip)))
+               (addr-add #$interface ip)
+               (when #$gateway
+                 (route-add "default" #:device #$interface
+                            #:via #$gateway))
+               (link-set #$interface #:up #t))))
+
+       (define tear-down-via-netlink
+         (with-extensions (list guile-netlink)
+           #~(begin
+               (link-set #$interface #:down #t)
+               (when #$gateway
+                 (route-del "default" #:device #$interface))
+               (addr-del #$interface #$ip)
+               #f)))
+
+       (define helpers
+         #~(define (ip+netmask->cidr ip netmask)
+             ;; Return the CIDR notation (a string) for IP and NETMASK, two
+             ;; IPv4 address strings.
+             (let* ((netmask (inet-pton AF_INET netmask))
+                    (bits    (logcount netmask)))
+               (string-append ip "/" (number->string bits)))))
+
        (shepherd-service
 
         (documentation
@@ -2347,38 +2408,19 @@ (define static-networking-shepherd-service
 
         (start #~(lambda _
                    ;; Return #t if successfully started.
-                   (let* ((addr     (inet-pton AF_INET #$ip))
-                          (sockaddr (make-socket-address AF_INET addr 0))
-                          (mask     (and #$netmask
-                                         (inet-pton AF_INET #$netmask)))
-                          (maskaddr (and mask
-                                         (make-socket-address AF_INET
-                                                              mask 0)))
-                          (gateway  (and #$gateway
-                                         (inet-pton AF_INET #$gateway)))
-                          (gatewayaddr (and gateway
-                                            (make-socket-address AF_INET
-                                                                 gateway 0))))
-                     (configure-network-interface #$interface sockaddr
-                                                  (logior IFF_UP
-                                                          #$(if loopback?
-                                                                #~IFF_LOOPBACK
-                                                                0))
-                                                  #:netmask maskaddr)
-                     (when gateway
-                       (let ((sock (socket AF_INET SOCK_DGRAM 0)))
-                         (add-network-route/gateway sock gatewayaddr)
-                         (close-port sock))))))
+                   #$helpers
+                   (if (string-contains %host-type "-linux")
+                       #$set-up-via-netlink
+                       #$set-up-via-ioctl)))
         (stop #~(lambda _
                   ;; Return #f is successfully stopped.
-                  (let ((sock (socket AF_INET SOCK_STREAM 0)))
-                    (when #$gateway
-                      (delete-network-route sock
-                                            (make-socket-address
-                                             AF_INET INADDR_ANY 0)))
-                    (set-network-interface-flags sock #$interface 0)
-                    (close-port sock)
-                    #f)))
+                  (if (string-contains %host-type "-linux")
+                      #$tear-down-via-netlink
+                      #$tear-down-via-ioctl)))
+        (modules `((ip addr)
+                   (ip link)
+                   (ip route)
+                   ,@%default-modules))
         (respawn? #f))))))
 
 (define (static-networking-etc-files interfaces)
-- 
2.33.0





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 17 Nov 2021 17:15:01 GMT) Full text and rfc822 format available.

Message #98 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Wed, 17 Nov 2021 18:13:51 +0100
Hi!

Ludovic Courtès <ludo <at> gnu.org> skribis:

>   tests: Add 'static-networking' test.
>   tests: openvswitch: Check whether ovs0 is up.
>   doc: Add new "Networking Setup" node for the main setup options.
>   gnu: guile-netlink: Allow cross-compilation.
>   services: static-networking: Use Guile-Netlink on GNU/Linux.
>   services: secret-service: Turn into a Shepherd service.
>   services: static-networking: Change interface to mimic netlink.
>   services: Define '%qemu-static-networking'.
>   services: Define '%loopback-static-networking'.
>   tests: Replace uses of deprecated 'static-networking-service'.

I pushed this as ‘wip-networking-netlink’ to make it easier for people
to test with something like:

  guix time-machine --branch=wip-networking-netlink -- \
    reconfigure …

Useful test scenarios:

  • You’re already using the ‘static-networking-service’ procedure; it’s
    now deprecated but you can reconfigure without changing your config
    file and check that networking works the same as before.

  • Using the new ‘static-networking’ records to define your network,
    particularly with IPv6 connectivity, crazy routes, or anything that
    was not previously possible.

Thanks in advance.  :-)

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 17 Nov 2021 19:37:02 GMT) Full text and rfc822 format available.

Message #101 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jonathan Brielmaier <jonathan.brielmaier <at> web.de>
To: guix-patches <at> gnu.org
Subject: Re: [bug#51440] [PATCH 00/10] Declarative static networking interface
Date: Wed, 17 Nov 2021 20:36:11 +0100
On 17.11.21 18:13, Ludovic Courtès wrote:> Useful test scenarios
Mine is much simpler. I use GNOME and want to end the "war" between
NetworkManager and dnsmasq. At the moment I only configured IPv4 as
Vivien said in IRC that IPv6 is a bit broken.

I stumbled across the missing `(list )` around `static-networking` in
your example. In the doc/manual commit although its correct :)

If one uses %desktop-services don't forget to remove
network-manager-service-type...




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Wed, 17 Nov 2021 19:37:02 GMT) Full text and rfc822 format available.

Message #104 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Vivien Kraus <vivien <at> planete-kraus.eu>
To: 51440 <at> debbugs.gnu.org
Subject: Static IPv6 address is reversed!
Date: Wed, 17 Nov 2021 19:36:20 +0000
Dear guix,

The static networking service looks great, but when I tried to assign
address 2a00:5881:4008:2810::309/64 to my interface, I end up (when
looking at ip -6 address) with 903::1028:840:8158:2a/64.

Since the bytes are reversed, I would look at guile-netlink and check
if all byte orders are correct when using bytevectors :)

g!inggbudey ppHa

Vivien





Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Fri, 10 Dec 2021 10:52:02 GMT) Full text and rfc822 format available.

Message #107 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Vivien Kraus <vivien <at> planete-kraus.eu>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Fri, 10 Dec 2021 11:51:39 +0100
⹁iH

Vivien Kraus <vivien <at> planete-kraus.eu> skribis:

> The static networking service looks great, but when I tried to assign
> address 2a00:5881:4008:2810::309/64 to my interface, I end up (when
> looking at ip -6 address) with 903::1028:840:8158:2a/64.
>
> Since the bytes are reversed, I would look at guile-netlink and check
> if all byte orders are correct when using bytevectors :)

Julien fixed this interesting bug in Guile-Netlink 1.1.1, which is now
in ‘master’ (thanks!).

I rebased ‘wip-networking-netlink’ to get this fix.

Could you give it another try?

Any other issues left?  If not, I think we could go ahead and merge it!

Thanks,
Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Sat, 11 Dec 2021 12:57:02 GMT) Full text and rfc822 format available.

Message #110 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Vivien Kraus <vivien <at> planete-kraus.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Sat, 11 Dec 2021 13:56:10 +0100
[Message part 1 (text/plain, inline)]
Hi,

Le vendredi 10 décembre 2021 à 11:51 +0100, Ludovic Courtès a écrit :
> Vivien Kraus <vivien <at> planete-kraus.eu> skribis:
> 
> > The static networking service looks great, but when I tried to assign
> > address 2a00:5881:4008:2810::309/64 to my interface, I end up (when
> > looking at ip -6 address) with 903::1028:840:8158:2a/64.
> > 
> > Since the bytes are reversed, I would look at guile-netlink and check
> > if all byte orders are correct when using bytevectors :)
> 
> Julien fixed this interesting bug in Guile-Netlink 1.1.1, which is now
> in ‘master’ (thanks!).
> 
> I rebased ‘wip-networking-netlink’ to get this fix.
> 
> Could you give it another try?

The IP seems good.

> Any other issues left?

I have a couple:
- I get an extra IPv6 (inet6 xxxx/64 scope global dynamic mngtmpaddr
valid_lft forever preferred_lft forever) that I did not ask for and
that takes precedence as a source for the default route, which defeats
the purpose. I’m not sure it’s guile-netlink’s fault.
- Now opensmtpd fails to start with: 

Dec 11 12:01:32 localhost smtpd[5368]: info: OpenSMTPD 6.8.0p2 starting
Dec 11 12:01:32 localhost smtpd[5373]: pony express: listen: Address
already in use
Dec 11 12:01:32 localhost smtpd[5369]: smtpd: process ca socket closed

Maybe it’s unrelated, but that’s a problem for me.

Vivien
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Sat, 11 Dec 2021 21:40:01 GMT) Full text and rfc822 format available.

Message #113 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Vivien Kraus <vivien <at> planete-kraus.eu>
Cc: Julien Lepiller <julien <at> lepiller.eu>, 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Sat, 11 Dec 2021 22:39:19 +0100
Hi Vivien,

Vivien Kraus <vivien <at> planete-kraus.eu> skribis:

> Le vendredi 10 décembre 2021 à 11:51 +0100, Ludovic Courtès a écrit :
>> Vivien Kraus <vivien <at> planete-kraus.eu> skribis:

[...]

>> Julien fixed this interesting bug in Guile-Netlink 1.1.1, which is now
>> in ‘master’ (thanks!).
>> 
>> I rebased ‘wip-networking-netlink’ to get this fix.
>> 
>> Could you give it another try?
>
> The IP seems good.

\o/

>> Any other issues left?
>
> I have a couple:
> - I get an extra IPv6 (inet6 xxxx/64 scope global dynamic mngtmpaddr
> valid_lft forever preferred_lft forever) that I did not ask for and
> that takes precedence as a source for the default route, which defeats
> the purpose. I’m not sure it’s guile-netlink’s fault.

Hmm, what’s that IPv6 address?  Is it here even if you do not configure
any IPv6 address in ‘static-networking’?

Julien, could the ‘link-set’ call in ‘network-set-up/linux’ be the
culprit?

    #$@(map (lambda (address)
              #~(begin
                  (addr-add #$(network-address-device address)
                            #$(network-address-value address)
                            #:ipv6?
                            #$(network-address-ipv6? address))
                  ;; FIXME: loopback?
                  (link-set #$(network-address-device address)
                            #:up #t)))
            addresses)

It seems to be the only way to mark the device as “up”, but since it has
arguments that seem redundant with those of ‘addr-add’, I wonder if
something could go wrong here.

Thanks for testing, Vivien!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Sat, 11 Dec 2021 23:30:03 GMT) Full text and rfc822 format available.

Message #116 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Julien Lepiller <julien <at> lepiller.eu>
To: Ludovic Courtès <ludo <at> gnu.org>,
 Vivien Kraus <vivien <at> planete-kraus.eu>
Cc: 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Sat, 11 Dec 2021 17:19:24 -0500
Le 11 décembre 2021 16:39:19 GMT-05:00, "Ludovic Courtès" <ludo <at> gnu.org> a écrit :
>Hi Vivien,
>
>Vivien Kraus <vivien <at> planete-kraus.eu> skribis:
>
>> Le vendredi 10 décembre 2021 à 11:51 +0100, Ludovic Courtès a écrit :
>>> Vivien Kraus <vivien <at> planete-kraus.eu> skribis:
>
>[...]
>
>>> Julien fixed this interesting bug in Guile-Netlink 1.1.1, which is now
>>> in ‘master’ (thanks!).
>>> 
>>> I rebased ‘wip-networking-netlink’ to get this fix.
>>> 
>>> Could you give it another try?
>>
>> The IP seems good.
>
>\o/
>
>>> Any other issues left?
>>
>> I have a couple:
>> - I get an extra IPv6 (inet6 xxxx/64 scope global dynamic mngtmpaddr
>> valid_lft forever preferred_lft forever) that I did not ask for and
>> that takes precedence as a source for the default route, which defeats
>> the purpose. I’m not sure it’s guile-netlink’s fault.
>
>Hmm, what’s that IPv6 address?  Is it here even if you do not configure
>any IPv6 address in ‘static-networking’?
>
>Julien, could the ‘link-set’ call in ‘network-set-up/linux’ be the
>culprit?
>
>    #$@(map (lambda (address)
>              #~(begin
>                  (addr-add #$(network-address-device address)
>                            #$(network-address-value address)
>                            #:ipv6?
>                            #$(network-address-ipv6? address))
>                  ;; FIXME: loopback?
>                  (link-set #$(network-address-device address)
>                            #:up #t)))
>            addresses)
>
>It seems to be the only way to mark the device as “up”, but since it has
>arguments that seem redundant with those of ‘addr-add’, I wonder if
>something could go wrong here.
>
>Thanks for testing, Vivien!
>
>Ludo’.

I don't think so. Setting the interface up will always assign a link-local address (starts with fe80), and that's not under netlink control. Then, maybe once the interface is up, it may react to an RA from the router and get an additional address that way? Not sure.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Sat, 11 Dec 2021 23:33:03 GMT) Full text and rfc822 format available.

Message #119 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Vivien Kraus <vivien <at> planete-kraus.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: Julien Lepiller <julien <at> lepiller.eu>, 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Sun, 12 Dec 2021 00:32:08 +0100
[Message part 1 (text/plain, inline)]
Le samedi 11 décembre 2021 à 22:39 +0100, Ludovic Courtès a écrit :
> > > Any other issues left?
> > 
> > I have a couple:
> > - I get an extra IPv6 (inet6 xxxx/64 scope global dynamic
> > mngtmpaddr
> > valid_lft forever preferred_lft forever) that I did not ask for and
> > that takes precedence as a source for the default route, which
> > defeats
> > the purpose. I’m not sure it’s guile-netlink’s fault.
> 
> Hmm, what’s that IPv6 address?  

So now I’m back to the DHCP setting.

I configured the DHCP server on my router to give anyone 2 IPv6
addresses: one that I configure with a static lease, and another one.
On the luci interface of my router, I see that the default mode for the
DHCP server is "stateful + stateless", which I guess translates to the
two addresses I get on the client machine. In fact, this is the
default, so I didn’t especially chose it that way.

If I keep the analogy, the "stateless" IP looks a lot like the
problematic IP I get in the static configuration.

I switch my DHCP server configuration to "stateful only", and now I
only have the static lease on the DHCP client configuration.

Let’s go back to the static networking configuration.

And now, the parasitic IP address is gone.

So, I guess there are 3 explanations:
1. That IP was committed to disk when I was running the DHCP
configuration, and got activated by default when I switched to the new
static configuration;
2. What guix considers a static client configuration talks to what
librecmc calls the DHCPv6 server and decides whether it’s OK to assign
a stateless IP depending on what the server says;
3. Some network stuff happens way above my understanding.

Anyway, I consider that problem solved for me.

Now I switch back to the DHCP configuration, otherwise the SMTP server
won’t start and I can’t send this email…

Vivien
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Sun, 12 Dec 2021 22:01:01 GMT) Full text and rfc822 format available.

Message #122 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Vivien Kraus <vivien <at> planete-kraus.eu>
Cc: Julien Lepiller <julien <at> lepiller.eu>, 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Sun, 12 Dec 2021 23:00:15 +0100
Hi,

Vivien Kraus <vivien <at> planete-kraus.eu> skribis:

> I switch my DHCP server configuration to "stateful only", and now I
> only have the static lease on the DHCP client configuration.
>
> Let’s go back to the static networking configuration.
>
> And now, the parasitic IP address is gone.

In your initial testing, you did not reboot, right?

The ‘stop’ method of the ‘networking’ Shepherd service created by
‘static-networking-service-type’ only deletes addresses and routes that
it (supposedly) created itself.  Thus, if there are stale addresses
created previously, they’ll stick around.  It could be what happened
here.

[...]

> Anyway, I consider that problem solved for me.

\o/

> Now I switch back to the DHCP configuration, otherwise the SMTP server
> won’t start and I can’t send this email…

Heh.  :-)

Thanks,
Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Sun, 12 Dec 2021 22:27:02 GMT) Full text and rfc822 format available.

Message #125 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Vivien Kraus <vivien <at> planete-kraus.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: Julien Lepiller <julien <at> lepiller.eu>, 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Sun, 12 Dec 2021 23:26:30 +0100
Hi!

Le dimanche 12 décembre 2021 à 23:00 +0100, Ludovic Courtès a écrit :
> In your initial testing, you did not reboot, right?

I always reboot after every reconfiguration, because I can, and usually
when I wildly change the networking configuration like that the
networking service fails to upgrade, and with it everything else, so I
can’t do anything with the machine before rebooting it.

However, as I was trying a NetworkManager-based solution today, I
noticed that the configuration persists after a reboot: NetworkManager
tried to replicate what was there before. So I would not be surprised
if other pieces of networking configuration could survive a reboot.

> > Anyway, I consider that problem solved for me.
> 
> \o/
> 
> > Now I switch back to the DHCP configuration, otherwise the SMTP
> server
> > won’t start and I can’t send this email…
> 
> Heh.  :-)




Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Sun, 12 Dec 2021 23:12:02 GMT) Full text and rfc822 format available.

Notification sent to Ludovic Courtès <ludo <at> gnu.org>:
bug acknowledged by developer. (Sun, 12 Dec 2021 23:12:02 GMT) Full text and rfc822 format available.

Message #130 received at 51440-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Vivien Kraus <vivien <at> planete-kraus.eu>
Cc: Julien Lepiller <julien <at> lepiller.eu>, 51440-done <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Mon, 13 Dec 2021 00:11:41 +0100
I went ahead and pushed this series:

  c8609493ba news: Add entry about 'static-networking-service-type'.
  f73ba627ab tests: Replace uses of deprecated 'static-networking-service'.
  5967aee398 services: Define '%loopback-static-networking'.
  1644f4f1f8 services: Define '%qemu-static-networking'.
  223f1b1eb3 services: static-networking: Change interface to mimic netlink.
  39e3b4b7ce services: secret-service: Turn into a Shepherd service.
  0cc742b261 services: static-networking: Use Guile-Netlink on GNU/Linux.
  1759292c8b gnu: guile-netlink: Allow cross-compilation.
  a4d33fef31 doc: Add new "Networking Setup" node for the main setup options.
  33c498b9ee tests: openvswitch: Check whether ovs0 is up.
  72f140c253 tests: Add 'static-networking' test.

Let me know if anything’s amiss!

Thanks,
Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Mon, 13 Dec 2021 17:30:03 GMT) Full text and rfc822 format available.

Message #133 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Mathieu Othacehe <othacehe <at> gnu.org>
To: 51440 <at> debbugs.gnu.org
Cc: ludo <at> gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Mon, 13 Dec 2021 18:29:09 +0100
Hey Ludo,

>   72f140c253 tests: Add 'static-networking' test.

Looks like there could be an issue with this test, see:
https://ci.guix.gnu.org/build/1979106/log/raw.

Thanks,

Mathieu




Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Tue, 14 Dec 2021 11:24:01 GMT) Full text and rfc822 format available.

Message #136 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Vivien Kraus <vivien <at> planete-kraus.eu>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: Julien Lepiller <julien <at> lepiller.eu>, 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Tue, 14 Dec 2021 12:17:53 +0100
[Message part 1 (text/plain, inline)]
Hi,

Ludovic Courtès <ludo <at> gnu.org> writes:
> Vivien Kraus <vivien <at> planete-kraus.eu> skribis:
>> Now I switch back to the DHCP configuration, otherwise the SMTP server
>> won’t start and I can’t send this email…
>
> Heh.  :-)

That problem is solved if I don’t ask for it to listen to interfaces but
rather to addresses. So now I can fully switch to the new static
networking service. I’m happy I found a solution that checks all boxes
at last :D
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#51440; Package guix-patches. (Tue, 14 Dec 2021 15:04:01 GMT) Full text and rfc822 format available.

Message #139 received at 51440 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Vivien Kraus <vivien <at> planete-kraus.eu>
Cc: Julien Lepiller <julien <at> lepiller.eu>, 51440 <at> debbugs.gnu.org
Subject: Re: bug#51440: [PATCH 00/10] Declarative static networking interface
Date: Tue, 14 Dec 2021 16:03:21 +0100
Hi,

Vivien Kraus <vivien <at> planete-kraus.eu> skribis:

> Ludovic Courtès <ludo <at> gnu.org> writes:
>> Vivien Kraus <vivien <at> planete-kraus.eu> skribis:
>>> Now I switch back to the DHCP configuration, otherwise the SMTP server
>>> won’t start and I can’t send this email…
>>
>> Heh.  :-)
>
> That problem is solved if I don’t ask for it to listen to interfaces but
> rather to addresses. So now I can fully switch to the new static
> networking service. I’m happy I found a solution that checks all boxes
> at last :D

Nice, thanks again for testing and reporting!

Ludo’.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 12 Jan 2022 12:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 102 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.