[LXD] Floating IP addresses


The command structure looks wrong here.
It should be:

  • lxc network forward <action> <network> ...
  • lxc network forward port <action> <network> <listen_address> ...

Yep thats a copy/paste error, fixed.


Yes indeed, fixed.

I agree except potentially with the many:many port range option.

It may be that the user wants something like:

listen ports: 80-81
target ports: 90-91

As long as there is a 1:1 mapping between each of the listen and target ports, then it could be valid. This is similar to what the proxy device does. It also makes the listen and target port ordering important when they are specified by the user.

I’m happy ofc to make the target port a single port only, if you don’t think that scenario should be supported.

@stgraber I think this rationale for using ipv{n}.nat.address on ovn networks may have an issue. This is because unlike bridge networks that share a common router (the host itself), ovn networks each have their own virtual router.

This presents two issues:

  1. Any SNAT we perform for outbound traffic from the network’s virtual router onto the uplink network will require the virtual router to respond to ARP/NDP neighbour requests for that IP so that return packets can make it back.
  2. By extension of 1. this means that we cannot share SNAT addresses between multiple ovn networks (as you cannot have multiple ARP/NDP neighbour responders for the same IP on different virtual routers).

So I wonder what the original intention of this feature was, over, just changing the ovn networks volatile.network.ipv{n}.address which would both change the virtual router’s IP and the SNAT source address?

Ah yeah, I guess we can allow port ranges in that case so long as they’re both the same size. This is a case where we’ll need to expand them for the bridged case as there’s no way to do that with netfilter ranges I believe.

Yep thats what the proxy does right now for all combinations, and what we’re going to look at optimising for the other scenarios in

volatile.network.ipv{n}.address only lets you set it to something on the uplink subnet, my interest is in being able to set it to an external address.

OK, cool, so it’ll still be a per-network address (i.e it cannot be shared across multiple networks).

But I think due to the need for the virtual router to respond to ARP/NDP neighbour requests for that address (which would then suggest its already in the uplink’s subnet anyway) should we then restrict this setting to only being used when the uplink network’s ovn.ingress_mode is routed?

We’ll also need to get the BGP advertiser to advertise that address as should be routed towards that router.

Yeah, I think that’s fine.

Thanks. I’ve clarified the rationale around that and added a statement about that requirement.

@tomp reviewed and approved!

1 Like

The PR that adds SNAT support for ovn networks is here:

And the associated tests here:

I’ve removed the per-driver API extensions for this feature and gone with a single API extension so it can also be referenced in the shared API struct docs.

@stgraber I was thinking about the CLI command structure more, and I believe there is a small problem with the current proposal.

We state in the API struct definitions that effectively you cannot create an “empty” forward, i.e a listen address with no default target and no port specifications.

// Target address to forward all unmatched ports to (optional if Ports not-empty)
// Example:

However in the commands the default_target_address is (correctly) optional, but adding port specifications requires a separate command.

lxc network forward add <network> <listen_address> [<default_target_address>]
lxc network forward port add <network> <listen_address> <target_address> <protocol> <port range>[,<port range>]

Allowing me to run just:

lxc network forward add <network> <listen_address> 

And with no port specifications, this will either always fail or allow an empty forward to be created, and based on the current API spec it will always fails.

So we either need to allow an empty forward to be created, or make a small change to the forward add command to allow one or more port specifications (using a similar argument style as the proxy device uses) to be added:


lxc network forward add <network> <listen_address> [<default_target_address>] [ports...]

Which would then look something like this (default target only):

lxc network forward add ovn0

or with a default target and multiple port specifications:

lxc network forward add ovn0 tcp:80,81,90-91:,91-94 udp:53: 

or with just port specifications and not default target:

lxc network forward add ovn0 tcp:80,81,90-91:,91-94 udp:53: 

This would then prevent running the command without any target specifications like:

lxc network forward add ovn0

I feel like allowing for an empty forward is likely best here.
It will also effectively allow you to “reserve” an address, making it unusable by instances, so this feels like a good side benefit :slight_smile:

1 Like

@stgraber should lxc network forward add be infact lxc network forward create to keep with convention as we’re creating a resource.

And only lxc network forward port add should be “add” as its adding a port to and existing resource?

As we have lxc network <network> forward delete but conventially “delete” is paired with “create” and “remove” paired with “add”.

yes, create/delete for forward add/remove for port.

1 Like

Thanks, I’ve also made some changes to the CLI part of the spec as it was not providing support for custom target ports.