Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding VRF and VXLAN support for systemd-networkd (LP: #1764716, LP: #1773522) #272

Closed
wants to merge 0 commits into from

Conversation

netdever
Copy link

@netdever netdever commented Apr 15, 2022

Description

Adding VRF and VXLAN support for systemd-networkd.

Checklist

  • Runs make check successfully.
  • Retains 100% code coverage (make check-coverage).
  • New/changed keys in YAML format are documented.
  • (Optional) Adds example YAML for new feature.
  • (Optional) Closes an open bug in Launchpad. LP#1764716, LP#1773522

@codecov-commenter
Copy link

codecov-commenter commented Apr 15, 2022

Codecov Report

Merging #272 (c8ed0cf) into main (6b9a3b7) will decrease coverage by 0.82%.
The diff coverage is 66.54%.

@@            Coverage Diff             @@
##             main     #272      +/-   ##
==========================================
- Coverage   99.06%   98.24%   -0.83%     
==========================================
  Files          61       63       +2     
  Lines       11160    11471     +311     
==========================================
+ Hits        11056    11270     +214     
- Misses        104      201      +97     
Impacted Files Coverage Δ
src/parse-nm.c 100.00% <ø> (ø)
src/parse.c 97.97% <38.23%> (-1.87%) ⬇️
src/netplan.c 90.97% <45.71%> (-9.03%) ⬇️
src/networkd.c 95.62% <57.53%> (-4.38%) ⬇️
src/validation.c 98.51% <75.00%> (-1.10%) ⬇️
netplan/configmanager.py 100.00% <100.00%> (ø)
src/types.c 100.00% <100.00%> (ø)
tests/generator/base.py 100.00% <100.00%> (ø)
tests/generator/test_bridges.py 100.00% <100.00%> (ø)
tests/generator/test_ethernets.py 100.00% <100.00%> (ø)
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6b9a3b7...c8ed0cf. Read the comment docs.

src/parse-nm.c Outdated Show resolved Hide resolved
@schopin-pro schopin-pro added the schema change This PR includes a change to netplan's YAML schema, which needs sign-off label Apr 19, 2022
@netdever netdever force-pushed the main branch 3 times, most recently from d5e03cc to 9890f2c Compare April 27, 2022 15:29
@slyon slyon self-requested a review May 4, 2022 08:04
@slyon slyon changed the title Adding VRF and VXLAN support for systemd-networkd Adding VRF and VXLAN support for systemd-networkd (LP: #1764716, LP: #1773522) May 4, 2022
Copy link
Collaborator

@slyon slyon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @netdever
Thank you very much for your contribution to netplan, this is highly appreciated, especially as the two LP bugs that you're addressing have been long-standing feature requests!

I did an initial review and mentioned some smaller issues and questions in inline comments.

I am now also thinking about bigger changes that might be needed:

network:
  version: 2
  renderer: networkd
  vrfs:
    vrf-test:
      interfaces:
        - bond0
        - br0
        - br-bond0
        - tun0
      table: auto # or a specific integer
  • Similarly, I need to thinkg about the linking of VXLAN devices, as the ethX.vxlans.names = [...] seems to be a bit cumbersome. Is there a specific reason why you went for this nestring structure?
  • Overall, I want to review all the new YAML settings in detail, to make sure we implement a simple and easily comprehensible wording. There is nothing to change about this right now... for the current stage we can just go with systemd-networkd's naming scheme and we can easily change/adopt that, once agreed upon (but before we merge the PR :))
  • NetworkManager also supports (most) VRF/VXLAN settings that are implemented in this PR for the systemd-networkd backend renderer. With all the parsing code already in place, it should be relatively easy to implement those in src/nm.c. Would you be interested in doing that? But it could also be done as part of a separate PR, in which case we should at least log a warning from the NetworkManager backend renderer, that those settings are not currently supported on that backend.
  • Finally, I'd really love to see some actuall integration tests (in tests/integration/...) that make use of those new VRF and VXLAN features and check the fully configured system at runtime, to make sure the settings are actually applied. Is that something you could add do your PR? The tests are being run as autopkgtests, as can be seen (and reproduced locally) in ".github/workflows/autopkgtest.yml`.

doc/netplan.md Outdated
Comment on lines 1449 to 1462
``udp-checksum`` (scalar)
: Takes a boolean. When true, transmitting UDP checksums when doing VXLAN/IPv4 is turned on.

``udp6-zero-checksum-tx`` (scalar)
: Takes a boolean. When true, sending zero checksums in VXLAN/IPv6 is turned on.

``udp6-zero-checksum-rx`` (scalar)
: Takes a boolean. When true, receiving zero checksums in VXLAN/IPv6 is turned on.

``remote-checksum-tx`` (scalar)
: Takes a boolean. When true, remote transmit checksum offload of VXLAN is turned on.

``remote-checksum-rx`` (scalar)
: Takes a boolean. When true, remote receive checksum offload in VXLAN is turned on.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should bundle those up as individual Flags somehow, e.g. checksums: [udp6-zero-rx, udp6-zero-tx, remote-rx, remote-tx, udp]

Similar to how it is done for optional-addresses

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave this a shot but hit some snags. I'm not sure optional-addresses behaves the same way, but I could be missing something.

doc/netplan.md Outdated Show resolved Hide resolved
Comment on lines 115 to 122
@property
def vxlans(self):
return self.network['vxlans']

@property
def vrfs(self):
return self.network['vrfs']

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configmanager.py will go away once we land PR #255 So this might need to be re-worked to make it play nice with the new and consolidated YAML parser from that PR (depending on which PR will be merged first...)

This is just a FYI for you right now. The vrf/vxlan configmanager code is good as-is for now. We shouldn't put too much effort into it, though as it will go away.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fingers crossed this gets merged first :)

src/abi.h Outdated
Comment on lines 356 to 360
gboolean udp_checksum;
gboolean udp6_zero_checksum_tx;
gboolean udp6_zero_checksum_rx;
gboolean remote_checksum_tx;
gboolean remote_checksum_rx;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe those could be bundled as flags/enum, similar to NetplanOptionalAddressFlag

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had some trouble trying to bundle these myself, so leaving as is for now. Any help would be appreciated if we feel it's necessary to make this change.

src/abi.h Outdated Show resolved Hide resolved
src/abi.h Outdated Show resolved Hide resolved
src/netplan.c Outdated
YAML_BOOL_FALSE(def, event, emitter, "group-policy-extension", def->vxlan_params.group_policy_extension);
YAML_BOOL_FALSE(def, event, emitter, "generic-protocol-extension", def->vxlan_params.generic_protocol_extension);
YAML_UINT_0(def, event, emitter, "destination-port", def->vxlan_params.destination_port);
YAML_STRING(def, event, emitter, "port-range", def->vxlan_params.port_range);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which way would we specify a "port-range" value? Can you give an example for this?

It seems like NetworkManager uses two separate settings for this:

  • source-port-max
  • source-port-min

Combining those into a single "port-range" sounds nice, but I'm wondering about the syntax?

https://networkmanager.dev/docs/api/latest/nm-settings-nmcli.html#id-1.2.9.4.43

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my testing, I could only specify an integer for PortRange= using systemd-networkd. Obviously that's not a "range." Documentation is lacking for this parameter in systemd-networkd.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found and answer in systemd's source code: https://github.com/systemd/systemd/blob/main/src/basic/parse-util.c#L259

the parse_range() util allows giving a range like this: "1-2892" from LOWER to UPPER bound, separated by dash.

I think we should potentially use a source-port-range: [1, 2892] syntax in netplan, i.e. an explicit list with exactly two elements (LOWER, UPPER).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I was able to get this to work as described. There isn't validation for it yet, though.

src/netplan.c Outdated
Comment on lines 236 to 238
YAML_STRING(def, event, emitter, "remote", def->vxlan_params.remote);
YAML_STRING(def, event, emitter, "local", def->vxlan_params.local);
YAML_STRING(def, event, emitter, "group", def->vxlan_params.group);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC Networkmanager uses a single setting to specify "remote" and "group", I wonder if we could do the same? Would the "remote" and "group" settings ever be used at the same time? Or can we deduct from the setting's value which one was meant by the user?

https://networkmanager.dev/docs/api/latest/nm-settings-nmcli.html#id-1.2.9.4.43

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ineed, Group= will always be a multicast IP address (i.e. from a reserved IPv4/6 range), so we can implicitly derive this information, therefore I'd like to reduce those two fields to just a single remote field, that is than translated to Remote= or Group= for systemd-networkd depending on if it is a multicast IP or not.

src/abi.h Outdated
guint destination_port;
char* port_range;
guint flow_label;
gboolean ip_do_not_fragment;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beware that the gboolean variable cannot hold a TRUE, FALSE or UNSET (i.e. kernel's default) value, as described in the netplan.md documentation. I think we need a NetplanTristate type here, as is currently being drafted in #270 (src/types.h). We should probably copy and use that type definition into this PR, too, so it can be merged later on (depending on which PR lands first).

The same problem applies to neigh-suppress and potentially other boolean values, that are also supposed to have an "unset" state.

src/parse-nm.c Outdated Show resolved Hide resolved
src/abi.h Outdated Show resolved Hide resolved
doc/netplan.md Outdated Show resolved Hide resolved
@netdever
Copy link
Author

netdever commented May 6, 2022

  • Linking of VRFs now looks more like the example in the linked LP bug.
  • Linking of VXLANs to source interfaces no longer requires the names subvar.
  • VXLAN source-port-range now works as suggested (lacks validation)

src/abi.h Outdated
/* netplan-feature: vxlan */
guint vxlan_vni;
GArray* vxlans;
gboolean neigh_suppress;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a rather generic [Bridge] setting, not necessarily related to VXLANs.. Is it required for VXLAN? If so, we should implement it as a generic bridge feature (and probably use a tristate type, too).

Otherwise, I'd like to just drop it from this PR, as it seems unrelated. Especially, as there is currently no implementation in any backend (neither networkd.c nor nm.c for this neigh_suppress variable).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neighbor suppression (arp-nd-suppression) is required for VXLAN configuration. It is disabled by default, but many implementations, specifically those utilizing EVPN, will need it to be enabled. In systemd-networkd, it looks like this:

root@host1:~# cat /run/systemd/network/10-netplan-vxlan10.network 
[Match]
Name=vxlan10

[Link]
MTUBytes=8950

[Network]
LinkLocalAddressing=no
IPv6AcceptRA=no
ConfigureWithoutCarrier=yes
Bridge=bridge10

[Bridge]
NeighborSuppression=True

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command to enable this feature is bridge link set dev vxlan10 neigh_suppress on

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your comments about this. Being a [Bridge] setting in sd-networkd, I still wonder if this is a setting that should be set on the VXLAN device itself, or rather on a bridge device that is a parent interface to the vxlan?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a VXLAN setting (ie. you cannot enable it on the master Bridge interface). It may be confusing for netplan to have it as a bridge setting, especially since enslaving a VXLAN to a Bridge is not technically a requirement.

root@host1:~# bridge link set dev bridge10 neigh_suppress on
RTNETLINK answers: Operation not supported

@slyon
Copy link
Collaborator

slyon commented Jul 4, 2022

This PR got closed by accident after rebasing on top of the current main branch and then pushing the wrong branch to netdever/main. I do not have write access to netdever's branch anymore. So I created a copy of this in #285

A backup of netdever's original branch is still available here: https://github.com/slyon/netplan/tree/vrf-vxlan-netdever-BACKUP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
schema change This PR includes a change to netplan's YAML schema, which needs sign-off
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants