This is a proposal regarding how Floating IP will be supported in OpenStack using OVN.
The complete proposal can also be found at https://review.openstack.org/#/c/274274/. The additions proposed to the OVN Northbound Schema and Southbound Flows are outlined here as well. The proposal assumes the availability of conntrack NAT support in kernel. OVN Floating IP Design and Setup ================================ OpenStack/Neutron provides support for "Floating IP" where a VM/container can be accessed from the external network using that "Floating IP" assigned to the VM. Neutron provides a 1-1 mapping between the "Fixed IP" assigned to the VM and the "Floating IP". Floating IP support for OVN is provided by utilizing the NAT capabilities provided by OVS. Inbound traffic is DNATed (Floating IP --> Fixed IP) and outbound traffic is SNATed (Fixed IP --> Floating IP). In the example below Fixed IP=10.1.1.5 is mapped to FloatingIP=172.16.0.5 OVN Bridge Setup ---------------- ------------ ------------ | VM | |FloatingIP| | 10.1.1.5 | |172.16.0.5| | MAC[VM] | | MAC[FIP] | ------|----- -----|----- | [UP] [UP] | ----------|----------------------------------------------------|-------- | ---------------- | | | | LSwitch | (BR-INT) | | | | 10.1.1.X | | | | | | | | | |L2 Flow Tables| | | | ---------------- | | | \ | | | lRouterPort \ lRouterPortExt | | | 10.1.1.1 \ --------------------- | 172.16.0.2 | | | MAC[PrvtRtr] \ { } | MAC[ExtRtr] | | | \| LRouter | | | | | | | | ------------------ | | | Flow Tables | \ / | LSwitch | | | | 10.1.1.X (Prv) |-------| (EXT) | | | | 172.16.X.X (Ext) | | | | | { 0.0.0.0 (Wildcard)} | L2 Flows | | | --------------------- |(diff from norm)| | | -----------------| | | (localnet) | | | (port) | | ----------------------------------------------------------|------------- | ------------------ | | | (BR-EXT) | | | ------------------ | chassis | [172.16.0.4] --------- | To Internet | | Physical Net | <-------------| Phy |--------------------------------- ... | Router| 172.16.0.1 (default gateway) | | --------- OVN NorthDB Changes =================== Map from VM Fixed IP to Floating IP, new options field in lport. Logical_Port TABLE ------------------ Type: floatingip: A port representing a Floating IP. router-external: A connection to an External Logical Router. Options: Options for floating ip ports: options: floatingip-port optional string Required: The name of Logical_Port to which this Floating IP port is connected. OVN Southbound Flows: Additions =============================== LSwitch (Tenant Private/10.1.1.X) Flows --------------------------------- There is no changes to the flows associated with a Logical Switch associated with a private (tenant) network. LSwitch EXT Flows: Additions ---------------------------- 1. Support for ARP replies to Floating IP addresses hosted by the hypervisor. Only the hypervisor hosting the corresponding VM should respond to the ARP. 2. ls_in_port_sec: Ingress on lRouterPortExt must admit all frames with eth.dst == MAC[FIP] for each Floating IP (and probably all SNAT VMs in the future). 3. ls_in_l2_lkup: If the destination MAC of ip but non-ARP frames that ingress on the localnet port matches one of Floating IP MACs the frame will be output to lrouterPortExt. i.e. not arp and ingress == localnet and eth.dst == MAC[FIP], \ action=(outport = lrouterPortExt) TODO: Determine the condition under which a Logical Switch should program these flows in ovn-northd. Option 1: Perform this action on all Logical Switches which have a localnet port (No changes needed in North DB). Option 2: Create a new <options> column for Logical Switch. LRouter Flows: Additions ------------------------ New stage (ip_nat) added to the Logical Router Ingress Pipeline. PIPELINE_STAGE(ROUTER, IN, ADMISSION, 0, "lr_in_admission") \ PIPELINE_STAGE(ROUTER, IN, IP_INPUT, 1, "lr_in_ip_input") \ PIPELINE_STAGE(ROUTER, IN, IP_NAT, 2, "lr_in_ip_nat") \ PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 3, "lr_in_ip_routing") \ PIPELINE_STAGE(ROUTER, IN, ARP, 4, "lr_in_arp") \ New stage (ip_nat) added to the Logical router egress Pipeline PIPELINE_STAGE(ROUTER, OUT, IP_NAT, 0, "lr_out_ip_nat") PIPELINE_STAGE(ROUTER, OUT, DELIVERY, 1, "lr_out_delivery") 1. lr_in_admission: Ingress on lRouterPortExt must admit frames with eth.dst == MAC[FIP] for each Floating IP. 2. lr_in_ip_nat: All flows added to this stages are recirculated immediately so that the next table processes the modified frames. Frames ingress on port lRouterPortExt are DNAT(ed) from Floating IP to Fixed IP (if dnat applicable): in_port == lRouterPortExt && ip && ip.dst == 172.16.0.5, \ actions = ct(commit,table=lr_in_ip_routing,nat(dst=10.1.1.5) 3. lr_out_ip_nat: Frames ingress from non-external router ports are SNAT(ed) from Fixed IP to Floating IP (if snat is applicable). The Source MAC is changed to the Source MAC of the FloatingIP Port: in_port != lRouterPortExt && out_port != lRouterPortExt && ip && \ ip.src == 10.1.1.5, actions = ct(commit, table=lr_out_delivery, \ eth.src=lFloatingipPort.mac, nat(src=172.16.0.5)) Packet Traversal ================ Inbound Packet (from external) with Floating IP Processing ---------------------------------------------------------- It is assumed that the ARP request for the Floating IP will be broadcast to all the hosts/hypervisors. 1. An ARP for Floating IP 172.16.0.5 is broadcast in the physical network. 2. The Hypervisor hosting that Floating IP replies with 172.16.0.5@MAC[FIP] based on (LSwitch EXT Flows: Additions) 3. The data packet frame containing ip.dst=172.16.0.5 and eth.dst=MAC[FIP] arrives at BR-EXT and ingress(es) on the localnet port, 4. ls_in_l2_lkup sets the outport as lRouterPortExt. 6. Frame ingress in LRouter flow table from lRouterPortExt - the lr_in_admission stage allows all Floating IP MACs. 7. lr_in_ip_nat performs dnat on applicable ip frames and recirculates the frame: in_port == lRouterPortExt && ip && ip.dst == 172.16.0.5, \ actions = ct(commit,table=lr_in_ip_routing,nat(dst=10.1.1.5) 8. From this point on, normal routing and l2_lookup will route the frame to the VM. Outbound Packet (from VM) ------------------------- The outbound frame from VM (with Fixed to Floating IP mapping) arrives at LRouter from LSwitch (Private). 1. Frame contains eth.dst=MAC[PrvtRtr], ip.src=10.1.1.5, ip.dst=172.16.0.10, where 172.16.0.10 is a valid endpoint in the physical network. 2. lr_in_ip_routing recieves the SNAT(ed) frame and routes based on the ip.dst=172.16.0.10. 3. lr_in_out_nat performs snat on applicable ip frames and recirculates the frame: in_port != lRouterPortExt && out_port != lRouterPortExt && ip && \ ip.src == 10.1.1.5, actions = ct(commit, table=lr_out_delivery, \ eth.src=lFloatingipPort.mac, nat(src=172.16.0.5)) Amitabha (azbiswas) and Chandra (chandrav) _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev