Flush ebtables arp protect chains before deleting them

When a port is removed, the linuxbridge agent cleans up the chains
neutronARP-* and neutronMAC-*, but in some cases this chains still
contains rules and ebtables fails with `CHAIN_USER_DEL failed (Device or
resource busy)`. Flushing the chains before deleting them, fixes that
issue.

Change-Id: Icfcf8c5406cfdc47fabf012e82ed56c345a73af8
Closes-Bug: #1887281
(cherry picked from commit 2207b88544)
This commit is contained in:
Lukas Steiner 2020-07-12 14:10:26 +02:00 committed by Dmitriy Rabotyagov
parent ab25c89834
commit 6fe4286f9b
2 changed files with 25 additions and 5 deletions

View File

@ -87,8 +87,7 @@ def _delete_arp_spoofing_protection(vifs, current_rules, table, chain):
ebtables(['-D', chain, '-i', vif, '-j',
chain_name(vif), '-p', 'ARP'], table=table)
for vif in vifs:
if chain_exists(chain_name(vif), current_rules):
ebtables(['-X', chain_name(vif)], table=table)
chain_delete(chain_name(vif), table, current_rules)
_delete_mac_spoofing_protection(vifs, current_rules, table=table,
chain=chain)
@ -154,6 +153,13 @@ def chain_exists(chain, current_rules):
return False
def chain_delete(chain, table, current_rules):
# flush and delete chain if exists
if chain_exists(chain, current_rules):
ebtables(['-F', chain], table=table)
ebtables(['-X', chain], table=table)
def vif_jump_present(vif, current_rules):
searches = (('-i %s' % vif), ('-j %s' % chain_name(vif)), ('-p ARP'))
for line in current_rules:
@ -212,9 +218,7 @@ def _delete_mac_spoofing_protection(vifs, current_rules, table, chain):
ebtables(['-D', chain, '-i', vif, '-j',
_mac_chain_name(vif)], table=table)
for vif in vifs:
chain = _mac_chain_name(vif)
if chain_exists(chain, current_rules):
ebtables(['-X', chain], table=table)
chain_delete(_mac_chain_name(vif), table, current_rules)
# Used to scope ebtables commands in testing

View File

@ -136,11 +136,19 @@ class TestLinuxBridgeARPSpoofing(base.BaseTestCase):
'-p', 'ARP'],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.call(['ebtables', '-t', 'nat', '--concurrent', '-F',
spoof_chain],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.call(['ebtables', '-t', 'nat', '--concurrent', '-X',
spoof_chain],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.ANY,
mock.call(['ebtables', '-t', 'nat', '--concurrent', '-F',
mac_chain],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.call(['ebtables', '-t', 'nat', '--concurrent', '-X',
mac_chain],
check_exit_code=True, extra_ok_codes=None,
@ -154,11 +162,19 @@ class TestLinuxBridgeARPSpoofing(base.BaseTestCase):
'-p', 'ARP'],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.call(['ebtables', '-t', 'filter', '--concurrent', '-F',
spoof_chain],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.call(['ebtables', '-t', 'filter', '--concurrent', '-X',
spoof_chain],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.ANY,
mock.call(['ebtables', '-t', 'filter', '--concurrent', '-F',
mac_chain],
check_exit_code=True, extra_ok_codes=None,
log_fail_as_error=True, run_as_root=True),
mock.call(['ebtables', '-t', 'filter', '--concurrent', '-X',
mac_chain],
check_exit_code=True, extra_ok_codes=None,