import time
+import netaddr
from oslo.config import cfg
from ryu.app.ofctl import api as ryu_api
from ryu.base import app_manager
except Exception:
LOG.exception(_("Failed reporting state!"))
+ def _create_tunnel_port_name(self, tunnel_type, ip_address):
+ try:
+ ip_hex = '%08x' % netaddr.IPAddress(ip_address, version=4)
+ return '%s-%s' % (tunnel_type, ip_hex)
+ except Exception:
+ LOG.warn(_("Unable to create tunnel port. Invalid remote IP: %s"),
+ ip_address)
+
def ryu_send_msg(self, msg):
result = ryu_api.send_msg(self.ryuapp, msg)
LOG.info(_("ryu send_msg() result: %s"), result)
if not self.enable_tunneling:
return
tunnel_ip = kwargs.get('tunnel_ip')
- tunnel_id = kwargs.get('tunnel_id', tunnel_ip)
tunnel_type = kwargs.get('tunnel_type')
if not tunnel_type:
LOG.error(_("No tunnel_type specified, cannot create tunnels"))
return
if tunnel_ip == self.local_ip:
return
- tun_name = '%s-%s' % (tunnel_type, tunnel_id)
+ tun_name = self._create_tunnel_port_name(tunnel_type, tunnel_ip)
+ if not tun_name:
+ return
self.setup_tunnel_port(tun_name, tunnel_ip, tunnel_type)
def create_rpc_dispatcher(self):
self.ryu_send_msg(msg)
return ofport
- def cleanup_tunnel_port(self, tun_ofport, tunnel_type):
- # Check if this tunnel port is still used
- for lvm in self.local_vlan_map.values():
- if tun_ofport in lvm.tun_ofports:
- break
- # If not, remove it
- else:
- for remote_ip, ofport in self.tun_br_ofports[tunnel_type].items():
- if ofport == tun_ofport:
- port_name = '%s-%s' % (tunnel_type, remote_ip)
- self.tun_br.delete_port(port_name)
- self.tun_br_ofports[tunnel_type].pop(remote_ip, None)
-
def treat_devices_added(self, devices):
resync = False
self.sg_agent.prepare_devices_filter(devices)
tunnels = details['tunnels']
for tunnel in tunnels:
if self.local_ip != tunnel['ip_address']:
- tunnel_id = tunnel.get('id', tunnel['ip_address'])
- tun_name = '%s-%s' % (tunnel_type, tunnel_id)
+ tun_name = self._create_tunnel_port_name(
+ tunnel_type, tunnel['ip_address'])
+ if not tun_name:
+ continue
self.setup_tunnel_port(tun_name,
tunnel['ip_address'],
tunnel_type)
import contextlib
import mock
+import netaddr
from oslo.config import cfg
import testtools
def setUp(self):
super(OFAAgentTestCase, self).setUp()
+ self.fake_oflib_of = fake_oflib.patch_fake_oflib_of().start()
+ self.mod_agent = importutils.import_module(self._AGENT_NAME)
cfg.CONF.set_default('firewall_driver',
'neutron.agent.firewall.NoopFirewallDriver',
group='SECURITYGROUP')
- self.fake_oflib_of = fake_oflib.patch_fake_oflib_of().start()
- self.mod_agent = importutils.import_module(self._AGENT_NAME)
self.ryuapp = mock.Mock()
cfg.CONF.register_cli_opts([
cfg.StrOpt('ofp-listen-host', default='',
)
def test_network_delete(self):
- with contextlib.nested(
- mock.patch.object(self.agent, "reclaim_local_vlan"),
- mock.patch.object(self.agent.tun_br, "cleanup_tunnel_port")
- ) as (recl_fn, clean_tun_fn):
+ with mock.patch.object(self.agent,
+ "reclaim_local_vlan") as recl_fn:
self.agent.network_delete("unused_context",
network_id="123")
self.assertFalse(recl_fn.called)
self.agent.local_vlan_map["123"] = "LVM object"
self.agent.network_delete("unused_context",
network_id="123")
- self.assertFalse(clean_tun_fn.called)
recl_fn.assert_called_with("123")
def test_port_update(self):
{'type': p_const.TYPE_GRE, 'ip': 'remote_ip'})
self.assertEqual(ofport, 0)
+ def _create_tunnel_port_name(self, tunnel_ip, tunnel_type):
+ tunnel_ip_hex = '%08x' % netaddr.IPAddress(tunnel_ip, version=4)
+ return '%s-%s' % (tunnel_type, tunnel_ip_hex)
+
+ def test_tunnel_sync_with_valid_ip_address_and_gre_type(self):
+ tunnel_ip = '100.101.102.103'
+ self.agent.tunnel_types = ['gre']
+ tun_name = self._create_tunnel_port_name(tunnel_ip,
+ self.agent.tunnel_types[0])
+ fake_tunnel_details = {'tunnels': [{'ip_address': tunnel_ip}]}
+ with contextlib.nested(
+ mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync',
+ return_value=fake_tunnel_details),
+ mock.patch.object(self.agent, 'setup_tunnel_port')
+ ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn):
+ self.agent.tunnel_sync()
+ expected_calls = [mock.call(tun_name, tunnel_ip,
+ self.agent.tunnel_types[0])]
+ setup_tunnel_port_fn.assert_has_calls(expected_calls)
+
+ def test_tunnel_sync_with_valid_ip_address_and_vxlan_type(self):
+ tunnel_ip = '100.101.31.15'
+ self.agent.tunnel_types = ['vxlan']
+ tun_name = self._create_tunnel_port_name(tunnel_ip,
+ self.agent.tunnel_types[0])
+ fake_tunnel_details = {'tunnels': [{'ip_address': tunnel_ip}]}
+ with contextlib.nested(
+ mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync',
+ return_value=fake_tunnel_details),
+ mock.patch.object(self.agent, 'setup_tunnel_port')
+ ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn):
+ self.agent.tunnel_sync()
+ expected_calls = [mock.call(tun_name, tunnel_ip,
+ self.agent.tunnel_types[0])]
+ setup_tunnel_port_fn.assert_has_calls(expected_calls)
+
+ def test_tunnel_sync_invalid_ip_address(self):
+ tunnel_ip = '100.100.100.100'
+ self.agent.tunnel_types = ['vxlan']
+ tun_name = self._create_tunnel_port_name(tunnel_ip,
+ self.agent.tunnel_types[0])
+ fake_tunnel_details = {'tunnels': [{'ip_address': '300.300.300.300'},
+ {'ip_address': tunnel_ip}]}
+ with contextlib.nested(
+ mock.patch.object(self.agent.plugin_rpc, 'tunnel_sync',
+ return_value=fake_tunnel_details),
+ mock.patch.object(self.agent, 'setup_tunnel_port')
+ ) as (tunnel_sync_rpc_fn, setup_tunnel_port_fn):
+ self.agent.tunnel_sync()
+ setup_tunnel_port_fn.assert_called_once_with(
+ tun_name, tunnel_ip, self.agent.tunnel_types[0])
+
+ def test_tunnel_update(self):
+ tunnel_ip = '10.10.10.10'
+ self.agent.tunnel_types = ['gre']
+ tun_name = self._create_tunnel_port_name(tunnel_ip,
+ self.agent.tunnel_types[0])
+ kwargs = {'tunnel_ip': tunnel_ip,
+ 'tunnel_type': self.agent.tunnel_types[0]}
+ self.agent.setup_tunnel_port = mock.Mock()
+ self.agent.enable_tunneling = True
+ self.agent.l2_pop = False
+ self.agent.tunnel_update(context=None, **kwargs)
+ expected_calls = [mock.call(tun_name, tunnel_ip,
+ self.agent.tunnel_types[0])]
+ self.agent.setup_tunnel_port.assert_has_calls(expected_calls)
+
class AncillaryBridgesTest(OFAAgentTestCase):