This spec describes an extension to associate floating IPs via router interfaces, rather than the router gateway port.
For some use cases [1], it can be useful to make floating IP translation happens on non-gateway router interfaces.
Introduce “router-interface-fip” extension, which allows users to associate floating IPs via router interfaces.
Consider the topology like the following diagram. This extension allows to associate floating-ip-B to fixed-ip-X.
+-----------------------+
| network4 |
| (external=True) |
+------------------+----+
|
|
|router gateway port
|(its primary address is gw-ip)
+---------+--------------------------------------------+
| floating-ip-A |
| |
| router |
| (enable_snat=True) |
| |
| floating-ip-B |
+----+-----------------+--------------------+----------+
|router |router |router
|interface |interface |interface
| | |
| | |
+-----------+-----+ +------+----------+ +----+------------+
| network1 | | network2 | | network3 |
| (external=False)| | (external=False)| | (external=True) |
+-----+-----------+ +--------+--------+ +------+----------+
| | |
+---+-------+ +---+-------+ +---+-------+
|fixed-ip-X | |fixed-ip-Y | |fixed-ip-Z |
+-----------+ +-----------+ +-----------+
VM-X VM-Y VM-Z
In case multiple floating ip addresses are associated to a fixed ip address, a datapath should be careful which floating ip to use for SNAT:
A few interesting cases:
For API, at least following changes are necessary:
The datapath needs to be updated to perform actual address translations.
In case of MidoNet, latest versions have the basic support already. [2]
The following is an example of a pseudo rules for logical router’s PREROUTING/POSTROUTING processing:
PREROUTING
// floating ip dnat
[per FIP]
(dst) matches (fip) -> float dnat, ACCEPT
// rev-snat for the default snat
[if default SNAT is enabled on the router]
rev-snat, ACCEPT
POSTROUTING
// floating ip snat
// multiple rules in order to implement priority (which FIP to use)
// Note: "fip port" below is a router port, either the router gateway
// port or router interface, which owns the corresponding FIP
// configured.
[per FIP]
(outport, src) matches (fip port, fip) -> float snat, ACCEPT
----- ordering barrier
[per FIP]
(src) matches (fip) -> float snat, ACCEPT // gateway port
----- ordering barrier
[per FIP]
(src) matches (fip) -> float snat, ACCEPT // non gateway port
----- ordering barrier
// do not apply default snat if it came from external-like network
// (router interfaces with FIPs, and the gateway port)
// Note: iptables based implementations need to "emulate" inport
// match (eg. using marks in PREROUTING) as it isn't available
// in POSTROUTING.
[per FIP port]
(inport) matches (fip port) -> ACCEPT
[if default SNAT is enabled on the router]
inport == the gateway port -> ACCEPT
----- ordering barrier
// apply the default snat for the gateway port
[if default SNAT is enabled on the router]
outport == the gateway port -> default snat, ACCEPT
// for non-float -> float traffic (cf. bug 1428887)
// "dst-rewritten" condition here means float dnat was applied in
// prerouting. in case of iptables based implementations,
// "--ctstate DNAT" might be used.
[if default SNAT is enabled on the router]
dst-rewritten -> default snat, ACCEPT
// non-float -> non-float in tenant traffic would come here