From ed2e32b03123ae8e7555b997152c1d8d941494f2 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Sun, 17 Nov 2013 16:59:06 -0800 Subject: [PATCH] NVP plugin:fix connectivity to fip from internal nw The current set of NAT rules configured in the NVP logical router prevents instances on an internal network from establishing TCP connections with a floating IP associate with an internal port on the same Neutron network. This patch add a SNAT rule to ensure connections coming from the internal network always appear to the port associate with the floating IP as coming from the external network. Change-Id: I12da12ee136c61fddb04f2b216382b51d751a02c Closes-Bug: 1221419 --- neutron/plugins/nicira/NeutronPlugin.py | 41 +++++++++++++++---------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/neutron/plugins/nicira/NeutronPlugin.py b/neutron/plugins/nicira/NeutronPlugin.py index ab3319bc4..5fe7bbc95 100644 --- a/neutron/plugins/nicira/NeutronPlugin.py +++ b/neutron/plugins/nicira/NeutronPlugin.py @@ -1706,28 +1706,24 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, internal_ip, router_id, min_num_rules_expected=0): try: + # Remove DNAT rule for the floating IP nvplib.delete_nat_rules_by_match( self.cluster, router_id, "DestinationNatRule", max_num_expected=1, min_num_expected=min_num_rules_expected, destination_ip_addresses=floating_ip_address) - # Remove SNAT rule associated with the single fixed_ip - # to floating ip + # Remove SNAT rules for the floating IP nvplib.delete_nat_rules_by_match( self.cluster, router_id, "SourceNatRule", max_num_expected=1, min_num_expected=min_num_rules_expected, source_ip_addresses=internal_ip) - - # Remove No-DNAT rule associated with the single fixed_ip - # to floating ip nvplib.delete_nat_rules_by_match( - self.cluster, router_id, "NoDestinationNatRule", + self.cluster, router_id, "SourceNatRule", max_num_expected=1, min_num_expected=min_num_rules_expected, - source_ip_addresses=internal_ip, - destination_ip_addresses=floating_ip_address) + destination_ip_addresses=internal_ip) except NvpApiClient.NvpApiException: LOG.exception(_("An error occurred while removing NAT rules " @@ -1823,25 +1819,38 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin, # Re-create NAT rules only if a port id is specified if fip.get('port_id'): try: - # Create new NAT rules + # Setup DNAT rules for the floating IP nvplib.create_lrouter_dnat_rule( self.cluster, router_id, internal_ip, order=NVP_FLOATINGIP_NAT_RULES_ORDER, match_criteria={'destination_ip_addresses': floating_ip}) + # Setup SNAT rules for the floating IP + # Create a SNAT rule for enabling connectivity to the + # floating IP from the same network as the internal port + # Find subnet id for internal_ip from fixed_ips + internal_port = self._get_port(context, port_id) + # Cchecks not needed on statements below since otherwise + # _internal_fip_assoc_data would have raised + subnet_ids = [ip['subnet_id'] for ip in + internal_port['fixed_ips'] if + ip['ip_address'] == internal_ip] + internal_subnet_cidr = self._build_ip_address_list( + context, internal_port['fixed_ips'], + subnet_ids=subnet_ids)[0] + nvplib.create_lrouter_snat_rule( + self.cluster, router_id, floating_ip, floating_ip, + order=NVP_NOSNAT_RULES_ORDER - 1, + match_criteria={'source_ip_addresses': + internal_subnet_cidr, + 'destination_ip_addresses': + internal_ip}) # setup snat rule such that src ip of a IP packet when # using floating is the floating ip itself. nvplib.create_lrouter_snat_rule( self.cluster, router_id, floating_ip, floating_ip, order=NVP_FLOATINGIP_NAT_RULES_ORDER, match_criteria={'source_ip_addresses': internal_ip}) - # Add No-DNAT rule to allow fixed_ip to ping floatingip. - nvplib.create_lrouter_nodnat_rule( - self.cluster, router_id, - order=NVP_FLOATINGIP_NAT_RULES_ORDER - 1, - match_criteria={'source_ip_addresses': internal_ip, - 'destination_ip_addresses': - floating_ip}) # Add Floating IP address to router_port nvplib.update_lrouter_port_ips(self.cluster,