[systemd-devel] Getting delegated IPv6 prefix from systemd-networkd

Arseny Maslennikov arseny at altlinux.org
Sun Oct 23 10:57:14 UTC 2022


On Sun, Oct 23, 2022 at 09:30:16AM +0300, Topi Miettinen wrote:
> On 22.10.2022 15.55, Ian Pilcher wrote:
> > On 10/19/22 17:05, Ian Pilcher wrote:
> > > (I know that systemd-networkd can allocate subnets from the delegated
> > > prefix to local interfaces, but that's not what I need to do in this
> > > case.)
> > > 
> > > Is there an API of some sort that my scripts can use?  A file that I can
> > > monitor/parse?  A command that I can run?
> > > 
> > 
> > Anyone?
> > 
> 
> For firewall integration, perhaps PR #24570 (once merged) could be useful
> for you. Then the assigned prefix can be used in NFTables rules with NFT
> sets.

Topi, thank you for the effort, this looks great at first glance! What's
especially cool about this solution is it seems to relieve networkd from
the burden of maintaining a special custom API, reusing a Linux feature
instead.

> 
> myif.network:
> [DHCPPrefixDelegation]
> NFTSet=inet:myfilter:myif_ipv6_address
> 
> nftables.conf:
> table inet myfilter {
>         set myif_ipv6_address {
>                 type ipv6_addr
>                 flags interval
>         }
> 
>         chain myservice_input {
>                 ip saddr @myif_ipv6_address accept
>                 drop
>         }
> }
> 
> This is better than using networkd-dispatcher or NetworkManager scripts,
> since the sets will be updated immediately by networkd when the addresses
> are available, but of course it can't cover all possible cases where scripts
> could be used.

On the other hand, scripts (or daemons running indefinitely) can query
the data stored in the nft sets and monitor modifications to those sets.
That way, the set objects can be used as a generic communication medium,
not necessarily being part of firewall state. (This might even work for
people who prefer some alternatives to nftables: they won't have to use
the rule engine. Those ppl can argue the same way about ipset, though)

The following example shows how to monitor nft objects with a shell and
nft(1) CLI:

  [root at host ~]# nft -j monitor elements | grep --color -F 'baobab' &
  [1] 1547610
  [root at host ~]# nft --json list set inet default baobab | jq '.nftables[1:]'
  [
    {
      "set": {
        "family": "inet",
        "name": "baobab",
        "table": "default",
        "type": "ipv6_addr",
        "handle": 11,
        "flags": [
          "interval"
        ],
        "elem": [
          {
            "prefix": {
              "addr": "2001:db8:8::",
              "len": 48
            }
          },
          {
            "prefix": {
              "addr": "2001:db8:9::",
              "len": 48
            }
          }
        ]
      }
    }
  ]
  [root at host ~]# 
  [root at host ~]# nft add element inet default baobab '{' 2001:db8:a::/48 '}' >/dev/null 2>&1
  {"add": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:a::", "len": 48}}]}}}}
  [root at host ~]# nft flush set inet default baobab >/dev/null 2>&1
  {"delete": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:a::", "len": 48}}]}}}}
  {"delete": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:9::", "len": 48}}]}}}}
  {"delete": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:8::", "len": 48}}]}}}}
  [root at host ~]# nft add element inet default baobab '{' 2001:db8:9::/48 '}' >/dev/null 2>&1
  {"add": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:9::", "len": 48}}]}}}}
  [root at host ~]# nft add element inet default baobab '{' 2001:db8:8::/48 '}' >/dev/null 2>&1
  {"add": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:8::", "len": 48}}]}}}}
  [root at host ~]# nft add element inet default baobab '{' 2001:db8:a::/48 '}' >/dev/null 2>&1
  {"add": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:a::", "len": 48}}]}}}}
  [root at host ~]# nft flush set inet default baobab >/dev/null 2>&1
  {"delete": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:a::", "len": 48}}]}}}}
  {"delete": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:9::", "len": 48}}]}}}}
  {"delete": {"element": {"family": "inet", "table": "default", "name": "baobab", "elem": {"set": [{"prefix": {"addr": "2001:db8:8::", "len": 48}}]}}}}

We can see that the json-encoded events printed after each modification
command are actually printed by the backgrounded `nft monitor` job.

This watches for changes to set elements; the sets being
deleted/recreated themselves can be monitored in a similar way (`nft
monitor sets`).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20221023/976c8a8a/attachment.sig>


More information about the systemd-devel mailing list