Skip to content

Commit 965943c

Browse files
authored
Merge pull request #87 from stackhpc/upstream/2023.1-2023-11-27
Synchronise 2023.1 with upstream
2 parents c4b34c4 + 87f7b9a commit 965943c

File tree

4 files changed

+92
-29
lines changed

4 files changed

+92
-29
lines changed

neutron/privileged/agent/linux/ip_lib.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,10 @@ def delete_neigh_entry(ip_version, ip_address, mac_address, device, namespace,
525525
if e.code == errno.ENOENT:
526526
return
527527
raise
528+
except OSError as e:
529+
if e.errno == errno.ENOENT:
530+
raise NetworkNamespaceNotFound(netns_name=namespace)
531+
raise
528532

529533

530534
@tenacity.retry(
@@ -712,6 +716,11 @@ def delete_ip_rule(namespace, **kwargs):
712716
try:
713717
with get_iproute(namespace) as ip:
714718
ip.rule('del', **kwargs)
719+
except netlink_exceptions.NetlinkError as e:
720+
# trying to delete a non-existent entry shouldn't raise an error
721+
if e.code == errno.ENOENT:
722+
return
723+
raise
715724
except OSError as e:
716725
if e.errno == errno.ENOENT:
717726
raise NetworkNamespaceNotFound(netns_name=namespace)
@@ -817,6 +826,11 @@ def delete_ip_route(namespace, cidr, ip_version, device=None, via=None,
817826
try:
818827
with get_iproute(namespace) as ip:
819828
ip.route('del', **kwargs)
829+
except netlink_exceptions.NetlinkError as e:
830+
# trying to delete a non-existent entry shouldn't raise an error
831+
if e.code == errno.ESRCH:
832+
return
833+
raise
820834
except OSError as e:
821835
if e.errno == errno.ENOENT:
822836
raise NetworkNamespaceNotFound(netns_name=namespace)
@@ -851,6 +865,11 @@ def _command_bridge_fdb(command, mac, device, dst_ip=None, namespace=None,
851865
kwargs['dst'] = dst_ip
852866
with get_iproute(namespace) as ip:
853867
return priv_linux.make_serializable(ip.fdb(command, **kwargs))
868+
except netlink_exceptions.NetlinkError as e:
869+
# trying to delete a non-existent entry shouldn't raise an error
870+
if command == 'del' and e.code == errno.ENOENT:
871+
return
872+
raise
854873
except OSError as e:
855874
if e.errno == errno.ENOENT:
856875
raise NetworkNamespaceNotFound(netns_name=namespace)
@@ -866,20 +885,20 @@ def add_bridge_fdb(mac, device, dst_ip=None, namespace=None, **kwargs):
866885

867886
@privileged.default.entrypoint
868887
def append_bridge_fdb(mac, device, dst_ip=None, namespace=None, **kwargs):
869-
"""Add a FDB entry"""
888+
"""Append a FDB entry"""
870889
_command_bridge_fdb('append', mac, device, dst_ip=dst_ip,
871890
namespace=namespace, **kwargs)
872891

873892

874893
@privileged.default.entrypoint
875894
def replace_bridge_fdb(mac, device, dst_ip=None, namespace=None, **kwargs):
876-
"""Add a FDB entry"""
895+
"""Replace a FDB entry"""
877896
_command_bridge_fdb('replace', mac, device, dst_ip=dst_ip,
878897
namespace=namespace, **kwargs)
879898

880899

881900
@privileged.default.entrypoint
882901
def delete_bridge_fdb(mac, device, dst_ip=None, namespace=None, **kwargs):
883-
"""Add a FDB entry"""
902+
"""Delete a FDB entry"""
884903
_command_bridge_fdb('del', mac, device, dst_ip=dst_ip,
885904
namespace=namespace, **kwargs)

neutron/tests/functional/agent/linux/test_bridge_lib.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,13 @@ def test_add_delete(self):
211211
namespace=self.namespace)
212212
self._assert_mac(self.MAC1, self.device, present=False)
213213

214+
try:
215+
# This should not raise for a non-existent entry
216+
bridge_lib.FdbInterface.delete(self.MAC1, self.device,
217+
namespace=self.namespace)
218+
except Exception:
219+
self.fail('Delete FDB entry threw unexpected exception')
220+
214221
def test_add_delete_dst(self):
215222
self._assert_mac(self.MAC1, self.device_vxlan, present=False)
216223
bridge_lib.FdbInterface.add(

neutron/tests/functional/privileged/agent/linux/test_ip_lib.py

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -260,19 +260,34 @@ def test_get_link_devices_using_index(self):
260260
index=10000)
261261

262262

263-
class ListIpRulesTestCase(functional_base.BaseSudoTestCase):
264-
265-
RULE_TABLES = {'default': 253, 'main': 254, 'local': 255}
263+
class BaseIpRuleTestCase(functional_base.BaseSudoTestCase):
266264

267265
def setUp(self):
268-
super(ListIpRulesTestCase, self).setUp()
266+
super().setUp()
269267
self.namespace = 'ns_test-' + uuidutils.generate_uuid()
270268
self.ns = priv_ip_lib.create_netns(self.namespace)
271269
self.addCleanup(self._remove_ns)
272270

273271
def _remove_ns(self):
274272
priv_ip_lib.remove_netns(self.namespace)
275273

274+
def _check_rules(self, rules, parameters, values, exception_string=None,
275+
raise_exception=True):
276+
for rule in rules:
277+
if all(rule.get(parameter) == value
278+
for parameter, value in zip(parameters, values)):
279+
return True
280+
else:
281+
if raise_exception:
282+
self.fail('Rule with %s was expected' % exception_string)
283+
else:
284+
return False
285+
286+
287+
class ListIpRulesTestCase(BaseIpRuleTestCase):
288+
289+
RULE_TABLES = {'default': 253, 'main': 254, 'local': 255}
290+
276291
def test_list_default_rules_ipv4(self):
277292
rules_ipv4 = priv_ip_lib.list_ip_rules(self.namespace, 4)
278293
self.assertEqual(3, len(rules_ipv4))
@@ -312,28 +327,7 @@ def test_list_rules_ipv6(self):
312327
self.fail('Rule added (2001:db8::1/64, table 20) not found')
313328

314329

315-
class RuleTestCase(functional_base.BaseSudoTestCase):
316-
317-
def setUp(self):
318-
super(RuleTestCase, self).setUp()
319-
self.namespace = 'ns_test-' + uuidutils.generate_uuid()
320-
self.ns = priv_ip_lib.create_netns(self.namespace)
321-
self.addCleanup(self._remove_ns)
322-
323-
def _remove_ns(self):
324-
priv_ip_lib.remove_netns(self.namespace)
325-
326-
def _check_rules(self, rules, parameters, values, exception_string=None,
327-
raise_exception=True):
328-
for rule in rules:
329-
if all(rule.get(parameter) == value
330-
for parameter, value in zip(parameters, values)):
331-
return True
332-
else:
333-
if raise_exception:
334-
self.fail('Rule with %s was expected' % exception_string)
335-
else:
336-
return False
330+
class AddIpRulesTestCase(BaseIpRuleTestCase):
337331

338332
def test_add_rule_ip(self):
339333
ip_addresses = ['192.168.200.250', '2001::250']
@@ -460,6 +454,23 @@ def test_add_rule_exists(self):
460454
self.assertEqual(4, len(rules))
461455

462456

457+
class DeleteIpRulesTestCase(BaseIpRuleTestCase):
458+
459+
def test_delete_rule_no_entry(self):
460+
iif = 'iif_device'
461+
priv_ip_lib.create_interface(iif, self.namespace, 'dummy')
462+
463+
try:
464+
# This should not raise for a non-existent entry
465+
priv_ip_lib.delete_ip_rule(self.namespace, iifname=iif)
466+
except Exception:
467+
self.fail('Delete IP rule threw unexpected exception')
468+
469+
rules = ip_lib.list_ip_rules(self.namespace, 4)
470+
# There are always 3 rules by default
471+
self.assertEqual(3, len(rules))
472+
473+
463474
class GetIpAddressesTestCase(functional_base.BaseSudoTestCase):
464475

465476
def _remove_ns(self, namespace):
@@ -687,6 +698,21 @@ def test_add_multipath_route(self):
687698
n_cons.IP_VERSION_4, via=multipath)
688699
self._check_routes(['192.168.0.0/24'], gateway=multipath)
689700

701+
def test_delete_route_no_entry(self):
702+
cidr = '192.168.0.0/24'
703+
self.device.addr.add('10.1.0.1/24')
704+
try:
705+
# This should not raise for a non-existent entry
706+
priv_ip_lib.delete_ip_route(self.namespace, cidr,
707+
n_cons.IP_VERSION_4,
708+
device=self.device_name)
709+
except Exception:
710+
self.fail('Delete IP route threw unexpected exception')
711+
712+
routes = ip_lib.list_ip_routes(self.namespace, n_cons.IP_VERSION_4)
713+
# There will be a single interface route since we added an IP
714+
self.assertEqual(1, len(routes))
715+
690716

691717
class GetLinkAttributesTestCase(functional_base.BaseSudoTestCase):
692718

neutron/tests/unit/privileged/agent/linux/test_ip_lib.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ def test_run_iproute_neigh_namespace_not_exists(self):
159159
priv_lib._run_iproute_neigh,
160160
"test_cmd", "eth0", None, test_param="test_value")
161161

162+
def test_run_iproute_neigh_no_entry(self):
163+
with mock.patch.object(iproute, "IPRoute") as iproute_mock:
164+
iproute_mock.side_effect = netlink_exceptions.NetlinkError(
165+
code=errno.ENOENT)
166+
try:
167+
priv_lib._run_iproute_neigh(
168+
"test_cmd", "eth0", None, test_param="test_value")
169+
self.fail("NetlinkError exception not raised")
170+
except netlink_exceptions.NetlinkError as e:
171+
self.assertEqual(errno.ENOENT, e.code)
172+
162173
def test_run_iproute_neigh_error(self):
163174
with mock.patch.object(iproute, "IPRoute") as iproute_mock:
164175
iproute_mock.side_effect = OSError(

0 commit comments

Comments
 (0)