diff --git a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py index c536f8f2c42..61e2b6f1d08 100644 --- a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py @@ -355,7 +355,10 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase): # Append IP's to bridge if necessary if ips: for ip in ips: - dst_device.addr.add(cidr=ip['cidr']) + # If bridge ip address already exists, then don't add + # otherwise will report error + if not dst_device.addr.list(to=ip['cidr']): + dst_device.addr.add(cidr=ip['cidr']) if gateway: # Ensure that the gateway can be updated by changing the metric diff --git a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py index b44f4862930..ede6dc9eacd 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py @@ -415,7 +415,19 @@ class TestLinuxBridgeManager(base.BaseTestCase): ip_version=4, dynamic=False) with mock.patch.object(ip_lib.IpAddrCommand, 'add') as add_fn,\ - mock.patch.object(ip_lib.IpAddrCommand, 'delete') as del_fn: + mock.patch.object(ip_lib.IpAddrCommand, 'delete') as del_fn,\ + mock.patch.object(ip_lib.IpAddrCommand, 'list') as list_fn: + # 'list' actually returns a dict, but we're only simulating + # whether the device exists or not + list_fn.side_effect = [True, False] + + self.lbm._update_interface_ip_details("br0", "eth0", + [ipdict], None) + self.assertFalse(add_fn.called) + self.assertTrue(del_fn.called) + + add_fn.reset_mock() + del_fn.reset_mock() self.lbm._update_interface_ip_details("br0", "eth0", [ipdict], None) self.assertTrue(add_fn.called)