can't connect external network using default snat from tenant network

Bug #1386041 reported by Itsuro Oda
64
This bug affects 12 people
Affects Status Importance Assigned to Milestone
neutron
Fix Released
Medium
Itsuro Oda
Juno
Invalid
Medium
Hirofumi Ichihara

Bug Description

See the following example:
---
   ------+----------------- external network 192.168.10.0/24
         |
         | 192.168.10.10
     +---+---+
     | r1 | routes [{nexthop: 10.0.0.2, destination: 20.0.0.0/24}]
     +---+---+
         | 10.0.0.1
         |
    -----+-----+----------- tenant network1 10.0.0.0/24 (gw: 10.0.0.1)
               |
               | 10.0.0.2
           +---+---+
           | r2 | routes [{nexthop: 10.0.0.1, destination: 0.0.0.0/0}]
           +---+---+
               | 20.0.0.1
               |
    -----------+------------ tenant network2 20.0.0.0/24 (gw: 20.0.0.1)
---

Users want to access external network from tenant network2 using default SNAT but can't access.
(tenant network2 is connected to r1 indirectly and set routes properly.)
Users can access external network only from tenant network1 (it is directly connected to r1) currently.

I think it is a bug since this restriction is unnecessary.

It is easy to fix. How about this ?
---
diff --git a/neutron/agent/l3_agent.py b/neutron/agent/l3_agent.py
index ff8ad47..097fa36 100644
--- a/neutron/agent/l3_agent.py
+++ b/neutron/agent/l3_agent.py
@@ -1445,9 +1445,8 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
         rules = [('POSTROUTING', '! -i %(interface_name)s '
                   '! -o %(interface_name)s -m conntrack ! '
                   '--ctstate DNAT -j ACCEPT' %
- {'interface_name': interface_name})]
- for cidr in internal_cidrs:
- rules.extend(self.internal_network_nat_rules(ex_gw_ip, cidr))
+ {'interface_name': interface_name}),
+ ('snat', '-j SNAT --to-source %s' % ex_gw_ip)]
         return rules

     def _snat_redirect_add(self, ri, gateway, sn_port, sn_int):
@@ -1560,11 +1559,6 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
             self.driver.unplug(interface_name, namespace=ri.ns_name,
                                prefix=INTERNAL_DEV_PREFIX)

- def internal_network_nat_rules(self, ex_gw_ip, internal_cidr):
- rules = [('snat', '-s %s -j SNAT --to-source %s' %
- (internal_cidr, ex_gw_ip))]
- return rules
-
     def _create_agent_gateway_port(self, ri, network_id):
         """Create Floating IP gateway port.
---

Tags: l3-ipam-dhcp
Itsuro Oda (oda-g)
tags: added: l3-ipam-dhcp
Akihiro Motoki (amotoki)
Changed in neutron:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Akihiro Motoki (amotoki) wrote :

I think this is the limitation from the initial commit of l3-agent, and it sounds reasonable to relax this limitation to provide more flexibility of the topology of virtual networks.

Regarding the solution mentioned in the bug report,

  + ('snat', '-j SNAT --to-source %s' % ex_gw_ip)]

seems a bit dangerous because this rule tries to apply SNAT for all traffic. Generally speaking we should have more strict match rule to avoid any side effect.

I have not checked the detail behavior of SNAT rules in l3-agent, but it is worth investigated what traffic matches the SNAT rule. IMHO it is better to examine from what interfaces traffic come or similar things. I am afraid traffic from local or traffic handled by OpenSwan are affected by the rule.

Itsuro Oda (oda-g)
Changed in neutron:
assignee: nobody → Itsuro Oda (oda-g)
Revision history for this message
Itsuro Oda (oda-g) wrote :

Hi Akihiro,

How about source CIDR of SNAT is limited as follows ?
* CIDR of internal interfaces (same as original)
* destination of routes which nexthop is inside of internal interfaces' CIDR (addition)

For the example of bug description "snat -s 20.0.0.0/24 -J SNAT --to-source ex_gw_ip" is included by the second rule. Is soluves the problem.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to neutron (master)

Fix proposed to branch: master
Review: https://review.openstack.org/131905

Changed in neutron:
status: Confirmed → In Progress
tags: added: juno-backport-potential
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to neutron (master)

Reviewed: https://review.openstack.org/131905
Committed: https://git.openstack.org/cgit/openstack/neutron/commit/?id=f852a89f1ea5eb6a6deae9cf8c4f63c40e420742
Submitter: Jenkins
Branch: master

commit f852a89f1ea5eb6a6deae9cf8c4f63c40e420742
Author: Itsuro Oda <email address hidden>
Date: Thu Oct 30 08:00:07 2014 +0900

    Enable default SNAT from networks connected to a router indirectly

    Make outgoing packets to an external interface SNATed regardless
    of source address of the packets. As a result of deep review,
    any problem was not found with this change.

    Change-Id: I71a1288633bb6af2951d571540bbb9ec5e1270e2
    Closes-bug: #1386041

Changed in neutron:
status: In Progress → Fix Committed
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to neutron (stable/juno)

Fix proposed to branch: stable/juno
Review: https://review.openstack.org/136294

Alan Pevec (apevec)
tags: removed: juno-backport-potential
Thierry Carrez (ttx)
Changed in neutron:
milestone: none → kilo-1
status: Fix Committed → Fix Released
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Change abandoned on neutron (stable/juno)

Change abandoned by Hirofumi Ichihara (<email address hidden>) on branch: stable/juno
Review: https://review.openstack.org/136294

Thierry Carrez (ttx)
Changed in neutron:
milestone: kilo-1 → 2015.1.0
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.