[RFE] "External network not reachable from subnet" could take static routes into account

Bug #2072505 reported by Florian Haas
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
neutron
New
Wishlist
Unassigned

Bug Description

When deciding whether a floating IP can be assigned to a port, the check on whether to accept the API call, or return HTTP 400 with an "External network not reachable from subnet" error message, does not take static routes on a router into account — when arguably it should, or at least could.

This applies mainly to situations where users want to use a Nova server (for example, a virtual security appliance) as a firewall, router, or gateway for other servers.

To illustrate, suppose a regular user is dealing with

* an external network,
* an "outer" internal network,
* a Neutron router connecting the two (that is, the router has the external network as its gateway, and has an interface to the "outer" subnet),
* an "inner" internal network,
* a Nova server (let's call that the "gateway"), which connects the "inner" and "outer" networks,
* another Nova server (the "worker") that sits on the "inner" network.

(Suppose further, for the sake of discussion, that the "gateway" runs some kind of web application firewall or other virtual security appliance, and the "worker" is a general-purpose Linux instance.)

Now one can give the Neutron router a static route so that traffic to the "inner" network uses the "gateway" as its nexthop. Provided the "gateway" does its forwarding correctly, this means that the "worker" has internet connectivity via the "gateway" (which, in turn, achieves this via the router).

This, too, works fine for outbound connections originating with the "worker".

If one now wants to assign a floating IP to the "worker", then routing-wise there really should be no problem: the router should take care of SNAT/DNAT, it would translate the floating IP into a private IP on the "inner" network, would consult its routing table, and send packets for that "inner" network to the "gateway" to handle, per the static route that's been set.

But when one tries to associate a floating IP to the "worker" in this scenario, one gets the "External network not reachable from subnet" error, because the associated internal check[1] does not take the existing static route into account.

This appears to have been an issue in other contexts as well: the defunct Tricircle project appears to have worked around this limitation via a service plugin that just omitted that check.[2]

One of the questions that were raised in discussing this on the list was how Neutron could determine that the "inner" network is indeed accessible through the "gateway" VM. This is considering that from Neutron's perspective, it's just a VM with two legs in each of the two networks, and forwarding inside the "gateway" VM is opaque.

However, from the router's perspective, that should not really matter.

Currently, simplifying in very broad strokes, the router checks its own interfaces_info map to determine if it is connected to a specific subnet. It then checks whether that subnet's netmask matches the private IP of the floating/fixed IP association.

Neutron can't really check if that private IP address is actually "accessible": a user could shell into that server and disable the interface, and the router would be none the wiser. It would just keep sending packets the server's way, and they would time out.

Now, if the router, when determining whether it can host a floating IP, were to also check its own routes map to see if

* the private IP (on the "inner" network) matched a route destination, and
* the route nexthop matched a subnet that the router was directly
connected to (namely, the "outer" network),

it could be just as sufficient a plausibility check for routing purposes.

After all, what users expect of the router is to create DNAT/SNAT rules for the floating IP addresses, and with said information from routes this should be possible, with as much plausibility checking as for directly connected subnets.

So I guess the feature enhancement would boil down to this:

1. Make Neutron routers consult their own static routes when determining whether they are eligible for hosting a floating IP.
2. Possibly add a configuration flag to be able to toggle this on and off.

References:
[1] get_router_for_floatingip():
https://opendev.org/openstack/neutron/src/commit/ebed620aafdff75a05fb5d42add6eee571663528/neutron/db/l3_db.py#L1270

[2] get_router_for_floatingip():
https://opendev.org/openstack/tricircle/src/commit/8db8fb30f5757c46a953962d8c2133743cfffdb3/tricircle/network/local_l3_plugin.py#L30

Original openstack-discuss thread: https://<email address hidden>/thread/7OINJKMEV5P2KDKJCEYH672EQUKX57A3/

Florian Haas (fghaas)
description: updated
Revision history for this message
Slawek Kaplonski (slaweq) wrote :

This request sounds reasonable for me but I see one potential issue with implementation of the new, less strict check. Now it is pretty easy to get routers which needs to be checked if any of them provides connectivity from the internal port to the external network where FIP is as we can find easily router(s) to which internal subnet is connected.
But, if we would want to check also static routes, number of routers to check may increase significantly as for example in the above use case, from the info about internal (inner) port to which FIP should be associated there is no easy way to find router used for that as it is not connected to that subnet at all.

Of course this concern which I described is not blocking issue for this RFE and for sure it can be solved somehow. I am most likely +1 for this RFE :)

One idea maybe could be to implement some kind of 'force=true' flag in the API for the /v2.0/floatingips/ endpoint and once this flag is set, Neutron will not perform any checks and will "trust" user that they know what they are doing without checking it.

yatin (yatinkarel)
Changed in neutron:
importance: Undecided → Wishlist
Revision history for this message
yatin (yatinkarel) wrote :

Hello Florian:

Thanks for the report, can you propose this rfe in NeutronDrivers meeting[1] in the "On Demand Agenda" section when you are available to join. The meetings runs on Friday's (if there is any topic) at 1400UTC.

[1] https://wiki.openstack.org/wiki/Meetings/NeutronDrivers

yatin (yatinkarel)
summary: - "External network not reachable from subnet" could take static routes
- into account
+ [RFE] "External network not reachable from subnet" could take static
+ routes into account
Revision history for this message
Ihar Hrachyshka (ihar-hrachyshka) wrote :

BTW I think this was proposed a long time ago here: https://bugs.launchpad.net/neutron/+bug/1616317

tags: added: rfe-triaged
Revision history for this message
Brian Haley (brian-haley) wrote :

Hi Florian - I put this on the agenda for today's drivers meeting, will you be able to attend?

https://wiki.openstack.org/wiki/Meetings/NeutronDrivers

Revision history for this message
Brian Haley (brian-haley) wrote :

Hi Florian,

I realize it might have been too short of a timeframe to get you to join the meeting today, but we did discuss this for a little bit and had some questions. See [0] for a full transcript.

Basically, we had concerns about how this would be implemented with both OVN and OVS (with and without DVR). For that reason, a spec describing how this will be done in both of these backends would need to be drafted.

For example, "what happens in the FIP assignation, so if OVN cannot route this packet, what happens?"

Also, "with DVR floating IP traffic does not go through router namespace but directly from a compute node (fip namespace) so this is a concern as well - the "gateway" server might be skipped", so this DVR node must also have connectivity to the gateway.

[0] https://meetings.opendev.org/meetings/neutron_drivers/2024/neutron_drivers.2024-07-19-14.00.log.txt

Revision history for this message
Florian Haas (fghaas) wrote :

Hi Brian, apologies for the slow reply, I was away on annual leave. I'm back now, and will read up a bit on OVS vs. OVN implications of my suggestion. Thanks for looking into this!

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.