Merge "DVR: Look at all SNAT ports for a subnet match" into stable/ocata
This commit is contained in:
commit
d0af332bda
@ -38,16 +38,17 @@ class DvrRouterBase(router.RouterInfo):
|
|||||||
"""Return the SNAT port for the given internal interface port."""
|
"""Return the SNAT port for the given internal interface port."""
|
||||||
if snat_ports is None:
|
if snat_ports is None:
|
||||||
snat_ports = self.get_snat_interfaces()
|
snat_ports = self.get_snat_interfaces()
|
||||||
fixed_ip = int_port['fixed_ips'][0]
|
if not snat_ports:
|
||||||
subnet_id = fixed_ip['subnet_id']
|
return
|
||||||
if snat_ports:
|
fixed_ips = int_port['fixed_ips']
|
||||||
match_port = [p for p in snat_ports
|
subnet_ids = [fixed_ip['subnet_id'] for fixed_ip in fixed_ips]
|
||||||
if p['fixed_ips'][0]['subnet_id'] == subnet_id]
|
for p in snat_ports:
|
||||||
if match_port:
|
for ip in p['fixed_ips']:
|
||||||
return match_port[0]
|
if ip['subnet_id'] in subnet_ids:
|
||||||
else:
|
return p
|
||||||
LOG.error(_LE('DVR: SNAT port not found in the list '
|
|
||||||
'%(snat_list)s for the given router '
|
LOG.error(_LE('DVR: SNAT port not found in the list '
|
||||||
' internal port %(int_p)s'), {
|
'%(snat_list)s for the given router '
|
||||||
'snat_list': snat_ports,
|
'internal port %(int_p)s'), {
|
||||||
'int_p': int_port})
|
'snat_list': snat_ports,
|
||||||
|
'int_p': int_port})
|
||||||
|
@ -132,18 +132,29 @@ def get_subnet_id(port):
|
|||||||
|
|
||||||
|
|
||||||
def router_append_interface(router, count=1, ip_version=4, ra_mode=None,
|
def router_append_interface(router, count=1, ip_version=4, ra_mode=None,
|
||||||
addr_mode=None, dual_stack=False):
|
addr_mode=None, dual_stack=False, same_port=False):
|
||||||
interfaces = router[lib_constants.INTERFACE_KEY]
|
interfaces = router[lib_constants.INTERFACE_KEY]
|
||||||
current = sum(
|
current = sum(
|
||||||
[netaddr.IPNetwork(subnet['cidr']).version == ip_version
|
[netaddr.IPNetwork(subnet['cidr']).version == ip_version
|
||||||
for p in interfaces for subnet in p['subnets']])
|
for p in interfaces for subnet in p['subnets']])
|
||||||
|
|
||||||
|
# If dual_stack=True, create IPv4 and IPv6 subnets on each port
|
||||||
|
# If same_port=True, create ip_version number of subnets on a single port
|
||||||
|
# Else create just an ip_version subnet on each port
|
||||||
|
if dual_stack:
|
||||||
|
ip_versions = [4, 6]
|
||||||
|
elif same_port:
|
||||||
|
ip_versions = [ip_version] * count
|
||||||
|
count = 1
|
||||||
|
else:
|
||||||
|
ip_versions = [ip_version]
|
||||||
|
|
||||||
mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
|
mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
|
||||||
mac_address.dialect = netaddr.mac_unix
|
mac_address.dialect = netaddr.mac_unix
|
||||||
for i in range(current, current + count):
|
for i in range(current, current + count):
|
||||||
fixed_ips = []
|
fixed_ips = []
|
||||||
subnets = []
|
subnets = []
|
||||||
for loop_version in (4, 6):
|
for loop_version in ip_versions:
|
||||||
if loop_version == 4 and (ip_version == 4 or dual_stack):
|
if loop_version == 4 and (ip_version == 4 or dual_stack):
|
||||||
ip_pool = '35.4.%i.4'
|
ip_pool = '35.4.%i.4'
|
||||||
cidr_pool = '35.4.%i.0/24'
|
cidr_pool = '35.4.%i.0/24'
|
||||||
|
@ -887,6 +887,38 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||||||
self.assertNotEqual(test_port, res_ip)
|
self.assertNotEqual(test_port, res_ip)
|
||||||
self.assertIsNone(res_ip)
|
self.assertIsNone(res_ip)
|
||||||
|
|
||||||
|
def test_get_snat_port_for_internal_port_ipv6_same_port(self):
|
||||||
|
router = l3_test_common.prepare_router_data(ip_version=4,
|
||||||
|
enable_snat=True,
|
||||||
|
num_internal_ports=1)
|
||||||
|
ri = dvr_router.DvrEdgeRouter(mock.sentinel.agent,
|
||||||
|
HOSTNAME,
|
||||||
|
router['id'],
|
||||||
|
router,
|
||||||
|
**self.ri_kwargs)
|
||||||
|
|
||||||
|
# Add two additional IPv6 prefixes on the same interface
|
||||||
|
l3_test_common.router_append_interface(router, count=2, ip_version=6,
|
||||||
|
same_port=True)
|
||||||
|
internal_ports = ri.router.get(lib_constants.INTERFACE_KEY, [])
|
||||||
|
with mock.patch.object(ri, 'get_snat_interfaces') as get_interfaces:
|
||||||
|
get_interfaces.return_value = internal_ports
|
||||||
|
# get the second internal interface in the list
|
||||||
|
res_port = ri.get_snat_port_for_internal_port(internal_ports[1])
|
||||||
|
self.assertEqual(internal_ports[1], res_port)
|
||||||
|
|
||||||
|
# tweak the first subnet_id, should still find port based
|
||||||
|
# on second subnet_id
|
||||||
|
test_port = copy.deepcopy(res_port)
|
||||||
|
test_port['fixed_ips'][0]['subnet_id'] = 1234
|
||||||
|
res_ip = ri.get_snat_port_for_internal_port(test_port)
|
||||||
|
self.assertEqual(internal_ports[1], res_ip)
|
||||||
|
|
||||||
|
# tweak the second subnet_id, shouldn't match now
|
||||||
|
test_port['fixed_ips'][1]['subnet_id'] = 1234
|
||||||
|
res_ip = ri.get_snat_port_for_internal_port(test_port)
|
||||||
|
self.assertIsNone(res_ip)
|
||||||
|
|
||||||
def test_process_cent_router(self):
|
def test_process_cent_router(self):
|
||||||
router = l3_test_common.prepare_router_data()
|
router = l3_test_common.prepare_router_data()
|
||||||
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||||
|
Loading…
Reference in New Issue
Block a user