Ensure that port update set correct tag in OVS

Fixes bug 1044556.

This patch also ensures that the local vlan mapping is updated correctly.
This was problematic in the event that the OVS agent would start and a port
was in administrative state down.

Change-Id: I4e5145547e73a58fee3f08a129fda6bc0ec42b72
This commit is contained in:
Gary Kotton 2012-09-01 01:53:59 -04:00
parent 50dbbb779c
commit 81f0983c00
3 changed files with 38 additions and 25 deletions

View File

@ -199,17 +199,13 @@ class OVSQuantumAgent(object):
def port_update(self, context, **kwargs): def port_update(self, context, **kwargs):
LOG.debug("port_update received") LOG.debug("port_update received")
port = kwargs.get('port') port = kwargs.get('port')
network_type = kwargs.get('network_type')
segmentation_id = kwargs.get('segmentation_id')
physical_network = kwargs.get('physical_network')
vif_port = self.int_br.get_vif_port_by_id(port['id']) vif_port = self.int_br.get_vif_port_by_id(port['id'])
if vif_port: self.treat_vif_port(vif_port, port['id'], port['network_id'],
if port['admin_state_up']: network_type, physical_network,
vlan_id = kwargs.get('vlan_id') segmentation_id, port['admin_state_up'])
# create the networking for the port
self.int_br.set_db_attribute("Port", vif_port.port_name,
"tag", str(vlan_id))
self.int_br.delete_flows(in_port=vif_port.ofport)
else:
self.int_br.clear_db_attribute("Port", vif_port.port_name,
"tag")
def tunnel_update(self, context, **kwargs): def tunnel_update(self, context, **kwargs):
LOG.debug("tunnel_update received") LOG.debug("tunnel_update received")
@ -607,6 +603,17 @@ class OVSQuantumAgent(object):
'added': added, 'added': added,
'removed': removed} 'removed': removed}
def treat_vif_port(self, vif_port, port_id, network_id, network_type,
physical_network, segmentation_id, admin_state_up):
if vif_port:
if admin_state_up:
self.port_bound(vif_port, network_id, network_type,
physical_network, segmentation_id)
else:
self.port_dead(vif_port)
else:
LOG.debug("No VIF port for port %s defined on agent.", port_id)
def treat_devices_added(self, devices): def treat_devices_added(self, devices):
resync = False resync = False
for device in devices: for device in devices:
@ -619,19 +626,19 @@ class OVSQuantumAgent(object):
LOG.debug("Unable to get port details for %s: %s", device, e) LOG.debug("Unable to get port details for %s: %s", device, e)
resync = True resync = True
continue continue
port = self.int_br.get_vif_port_by_id(details['device'])
if 'port_id' in details: if 'port_id' in details:
LOG.info("Port %s updated. Details: %s", device, details) LOG.info("Port %s updated. Details: %s", device, details)
port = self.int_br.get_vif_port_by_id(details['port_id']) self.treat_vif_port(port, details['port_id'],
if port: details['network_id'],
if details['admin_state_up']: details['network_type'],
self.port_bound(port, details['network_id'], details['physical_network'],
details['network_type'], details['segmentation_id'],
details['physical_network'], details['admin_state_up'])
details['segmentation_id'])
else:
self.port_unbound(port, details['network_id'])
else: else:
LOG.debug("Device %s not defined on plugin", device) LOG.debug("Device %s not defined on plugin", device)
if (port and int(port.ofport) != -1):
self.port_dead(port)
return resync return resync
def treat_devices_removed(self, devices): def treat_devices_removed(self, devices):

View File

@ -151,11 +151,14 @@ class AgentNotifierApi(proxy.RpcProxy):
network_id=network_id), network_id=network_id),
topic=self.topic_network_delete) topic=self.topic_network_delete)
def port_update(self, context, port, vlan_id): def port_update(self, context, port, network_type, segmentation_id,
physical_network):
self.fanout_cast(context, self.fanout_cast(context,
self.make_msg('port_update', self.make_msg('port_update',
port=port, port=port,
vlan_id=vlan_id), network_type=network_type,
segmentation_id=segmentation_id,
physical_network=physical_network),
topic=self.topic_port_update) topic=self.topic_port_update)
def tunnel_update(self, context, tunnel_ip, tunnel_id): def tunnel_update(self, context, tunnel_ip, tunnel_id):
@ -425,10 +428,10 @@ class OVSQuantumPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
if original_port['admin_state_up'] != port['admin_state_up']: if original_port['admin_state_up'] != port['admin_state_up']:
binding = ovs_db_v2.get_network_binding(None, binding = ovs_db_v2.get_network_binding(None,
port['network_id']) port['network_id'])
# REVISIT(rkukura): Either all binding data or no
# binding data needed.
self.notifier.port_update(self.rpc_context, port, self.notifier.port_update(self.rpc_context, port,
binding.segmentation_id) binding.network_type,
binding.segmentation_id,
binding.physical_network)
return port return port
def delete_port(self, context, id, l3_port_check=True): def delete_port(self, context, id, l3_port_check=True):

View File

@ -75,7 +75,10 @@ class rpcApiTestCase(unittest2.TestCase):
topics.PORT, topics.PORT,
topics.UPDATE), topics.UPDATE),
'port_update', rpc_method='fanout_cast', 'port_update', rpc_method='fanout_cast',
port='fake_port', vlan_id='fake_vlan_id') port='fake_port',
network_type='fake_network_type',
segmentation_id='fake_segmentation_id',
physical_network='fake_physical_network')
def test_tunnel_update(self): def test_tunnel_update(self):
rpcapi = povs.AgentNotifierApi(topics.AGENT) rpcapi = povs.AgentNotifierApi(topics.AGENT)