[systemd-devel] Getting delegated IPv6 prefix from systemd-networkd
Topi Miettinen
toiwoton at gmail.com
Sun Oct 23 19:37:02 UTC 2022
On 23.10.2022 13.57, Arseny Maslennikov wrote:
> 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`).
Great idea! Then I think there should be a rough feature parity with
networkd-dispatcher and NetworkManager scripts. The listener can even be
sandboxed easily to the max, which is not the case with the scripts.
-Topi
More information about the systemd-devel
mailing list