Re: [systemd-devel] systemd-networkd not sending periodic router advertisements

2022-10-11 Thread Mike Gilbert
On Sat, Oct 8, 2022 at 10:55 AM Marcel Menzel  wrote:
>
> Hello List,
>
> after switching from radvd to systemd-networkd for router advertisements, I 
> noticed my Android device losing IPv6 connection after a while and not 
> displaying any IPv6 Addresses anymore in the network overview.
>
> I am aware with IPv6 issues on Android on certain vendors / ROMs, but after 
> trying to troubleshoot it, I noticed systemd-networkd not sending periodic 
> router advertisements into my network compared to radvd.
>
> In radvd, there's the MinRtrAdvInterval and MaxRtrAdvInterval config option, 
> whileas for systemd-networkd I wasn't able to find any of these options. 
> Trying to adjust timers for PreferredLifetimeSec, ValidLifetimeSec or 
> RouterLifetimeSec I still wasn't able to get networkd to send out periodic 
> RAs (either with the defaults or my own values).
>
> There will only be sent a router advertisement for client initiated router 
> solicitations, like with the rdisc6 tool. I confirmed this with radvdump and 
> tcpdump. As soon as I re-start radvd, IPv6 Adresses re-appear on my Android 
> device. Multicast snooping has been disabled on all of my bridges. My 
> sd-networkd .network config file for one bridge looks like this:
>
> [Match]
> Name=br0
>
> [Network]
> Address=fe80::1/64
> Address=2a0f:85c1:beef:2031::/64
> IPv6AcceptRA=false
> IPv6SendRA=yes
> IPv6PrivacyExtensions=no
>
> [IPv6SendRA]
> RouterLifetimeSec = 60
> EmitDNS = yes
> DNS = fd00:0:0:10::4
> EmitDomains = no
>
> [IPv6Prefix]
> Prefix=2a0f:85c1:beef:2031::/64
> PreferredLifetimeSec=60
> ValidLifetimeSec=300
>
> Did I miss an option for enabling periodic RAs or isn't there simply a way to 
> achieve this?`

systemd-networkd sends periodic RAs on my home network. I am running
systemd-251.5.

The period is not directly configurable. It basically picks a random
number between 200 and 600 seconds by default. However, this time can
be reduced to as little as 4 seconds by setting RouterLifetimeSec to
some low value.

I have IPv6SendRA enabled directly on an ethernet interface; I wonder
if there is some conflict with trying to enable it on a bridge.
Perhaps you need to set the proper scope for your manually assigned
link-local address? Something like:

[Address]
Address=fe80::1/64
Scope=link


Re: [systemd-devel] Is it possible to let systemd create a listening socket and yet be able to have that socket activate nothing, at least temporarily?

2022-10-11 Thread Klaus Ebbe Grue
Hi Lennart,

> Can't you run your upgrade script in idempotent way as a helper
> service that is pulled in by your main daemon and ordered before it,
> but conditions itself out if it already did its job? that's usually
> the most robust way, since then it's sufficient to just restart your
> daemon or reboot, and everything will always catch up correctly.

> i.e. if you have foo-daemon.socket + foo-daemon.service then define
> foo-upgrade.service that is pulled in from foo-daemon.service via
> `Wants=foo-upgrade.service` + `After=foo-upgrade.service`. And then
> add `ConditionFileExists=!/some/touch/file` to `foo-upgrade.service` to
> make it a NOP if things have already been updated, using a touch
> file. (some better, smarter condition check might work as well, see
> man pages of things systemd can check for you).

That is a great pattern!

A Type=oneshot seems useful for the upgrade process.

For the record, I have appended what ended up working.

Thanks!

Cheers,
Klaus

---

The following three unit files open a listening socket, run the myupgrade 
service,
and only then start the /usr/bin/mydaemon service. The socket listens while the
myupgrade service runs so that clients can connect. But the clients are queued
until myupgrade has finished and /usr/bin/mydaemon starts accepting
connections.

mydeamon.service:
[Unit]
Description=service that does something
After=mydaemon.socket
Requires=mydaemon.socket
After=myupgrade.service
Wants=myupgrade.service
[Install]
WantedBy=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/mydaemon

myupgrade.service:
[Unit]
Description=service to run before mydaemon
[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c "echo goodnight;sleep 60;echo goodmorning"

mydeamon.socket
[Unit]
Description=mydaemon listen socket
[Socket]
ListenStream=
[Install]
WantedBy=sockets.target