Merge "iptables: fail to start ovs/linuxbridge agents on missing sysctl knobs"

This commit is contained in:
Jenkins 2016-10-21 02:14:02 +00:00 committed by Gerrit Code Review
commit a6c5737eb7
8 changed files with 82 additions and 21 deletions

View File

@ -8,21 +8,20 @@
[Filters]
# neutron/agent/linux/iptables_manager.py
# neutron/agent/linux/iptables_firewall.py
# "iptables-save", ...
iptables-save: CommandFilter, iptables-save, root
iptables-restore: CommandFilter, iptables-restore, root
ip6tables-save: CommandFilter, ip6tables-save, root
ip6tables-restore: CommandFilter, ip6tables-restore, root
# neutron/agent/linux/iptables_manager.py
# neutron/agent/linux/iptables_firewall.py
# "iptables", "-A", ...
iptables: CommandFilter, iptables, root
ip6tables: CommandFilter, ip6tables, root
# neutron/agent/linux/iptables_manager.py
# "sysctl", "-w", ...
# neutron/agent/linux/iptables_firewall.py
sysctl: CommandFilter, sysctl, root
# neutron/agent/linux/ip_conntrack.py
conntrack: CommandFilter, conntrack, root
conntrack: CommandFilter, conntrack, root

View File

@ -20,10 +20,11 @@ import netaddr
from neutron_lib import constants
from oslo_config import cfg
from oslo_log import log as logging
from oslo_log import versionutils
from oslo_utils import netutils
import six
from neutron._i18n import _LI
from neutron._i18n import _, _LI, _LW
from neutron.agent import firewall
from neutron.agent.linux import ip_conntrack
from neutron.agent.linux import ipset_manager
@ -109,15 +110,22 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
# enabled by default or not (Ubuntu - yes, Redhat - no, for
# example).
LOG.debug("Enabling netfilter for bridges")
utils.execute(['sysctl', '-w',
'net.bridge.bridge-nf-call-arptables=1'],
run_as_root=True)
utils.execute(['sysctl', '-w',
'net.bridge.bridge-nf-call-ip6tables=1'],
run_as_root=True)
utils.execute(['sysctl', '-w',
'net.bridge.bridge-nf-call-iptables=1'],
run_as_root=True)
entries = utils.execute(['sysctl', '-N', 'net.bridge'],
run_as_root=True).splitlines()
for proto in ('arp', 'ip', 'ip6'):
knob = 'net.bridge.bridge-nf-call-%stables' % proto
if 'net.bridge.bridge-nf-call-%stables' % proto not in entries:
raise SystemExit(
_("sysctl value %s not present on this system.") % knob)
enabled = utils.execute(['sysctl', '-b', knob])
if enabled != '1':
versionutils.report_deprecated_feature(
LOG,
_LW('Bridge firewalling is disabled; enabling to make '
'iptables firewall work. This may not work in future '
'releases.'))
utils.execute(
['sysctl', '-w', '%s=1' % knob], run_as_root=True)
@property
def ports(self):

View File

@ -228,6 +228,21 @@ def dhcp_release6_supported():
return True
def bridge_firewalling_enabled():
for proto in ('arp', 'ip', 'ip6'):
knob = 'net.bridge.bridge-nf-call-%stables' % proto
cmd = ['sysctl', '-b', knob]
try:
out = agent_utils.execute(cmd)
except (OSError, RuntimeError, IndexError, ValueError) as e:
LOG.debug("Exception while extracting %(knob)s. "
"Exception: %(e)s", {'knob': knob, 'e': e})
return False
if out == '0':
return False
return True
class KeepalivedIPv6Test(object):
def __init__(self, ha_port, gw_port, gw_vip, default_gw):
self.ha_port = ha_port

View File

@ -256,6 +256,16 @@ def check_dhcp_release6():
return result
def check_bridge_firewalling_enabled():
result = checks.bridge_firewalling_enabled()
if not result:
LOG.error(_LE('Bridge firewalling is not enabled. It may be the case '
'that bridge and/or br_netfilter kernel modules are not '
'loaded. Alternatively, corresponding sysctl settings '
'may be overridden to disable it by default.'))
return result
# Define CLI opts to test specific features, with a callback for the test
OPTS = [
BoolOptCallback('ovs_vxlan', check_ovs_vxlan, default=False,
@ -298,6 +308,9 @@ OPTS = [
help=_('Check ip6tables installation')),
BoolOptCallback('dhcp_release6', check_dhcp_release6,
help=_('Check dhcp_release6 installation')),
BoolOptCallback('bridge_firewalling', check_bridge_firewalling_enabled,
help=_('Check bridge firewalling'),
default=False),
]
@ -343,6 +356,15 @@ def enable_tests_from_config():
if ('sriovnicswitch' in cfg.CONF.ml2.mechanism_drivers and
'qos' in cfg.CONF.ml2.extension_drivers):
cfg.CONF.set_default('vf_extended_management', True)
if cfg.CONF.SECURITYGROUP.firewall_driver in (
'iptables',
'iptables_hybrid',
('neutron.agent.linux.iptables_firewall.'
'IptablesFirewallDriver'),
('neutron.agent.linux.iptables_firewall.'
'OVSHybridIptablesFirewallDriver'),
):
cfg.CONF.set_default('bridge_firewalling', True)
def all_tests_passed():

View File

@ -85,3 +85,6 @@ class SanityTestCaseRoot(functional_base.BaseSudoTestCase):
def test_keepalived_ipv6_support(self):
checks.keepalived_ipv6_supported()
def test_bridge_firewalling_enabled(self):
checks.bridge_firewalling_enabled()

View File

@ -94,6 +94,8 @@ class BaseIptablesFirewallTestCase(base.BaseTestCase):
RAW_TABLE_OUTPUT.splitlines())
self.firewall = iptables_firewall.IptablesFirewallDriver()
self.firewall.iptables = self.iptables_inst
# don't mess with sysctl knobs in unit tests
self.firewall._enabled_netfilter_for_bridges = True
class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):

View File

@ -2746,6 +2746,8 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
context=None, plugin_rpc=self.rpc,
defer_refresh_firewall=defer_refresh_firewall)
self._enforce_order_in_firewall(self.agent.firewall)
# don't mess with sysctl knobs in unit tests
self.agent.firewall._enabled_netfilter_for_bridges = True
def _device(self, device, ip, mac_address, rule):
return {'device': device,
@ -2794,12 +2796,6 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
self.assertThat(kwargs['process_input'],
matchers.MatchesRegex(expected_regex))
expected = ['net.bridge.bridge-nf-call-arptables=1',
'net.bridge.bridge-nf-call-ip6tables=1',
'net.bridge.bridge-nf-call-iptables=1']
for e in expected:
self.utils_exec.assert_any_call(['sysctl', '-w', e],
run_as_root=True)
self.assertEqual(exp_fw_sg_updated_call,
self.agent.firewall.security_group_updated.called)
@ -3123,6 +3119,8 @@ class TestSecurityGroupAgentWithOVSIptables(
context=None, plugin_rpc=self.rpc,
defer_refresh_firewall=defer_refresh_firewall)
self._enforce_order_in_firewall(self.agent.firewall)
# don't mess with sysctl knobs in unit tests
self.agent.firewall._enabled_netfilter_for_bridges = True
def test_prepare_remove_port(self):
self.rpc.security_group_rules_for_devices.return_value = self.devices1

View File

@ -0,0 +1,14 @@
---
deprecations:
- The iptables firewall driver will no longer enable bridge firewalling in
next versions of Neutron. If your distribution overrides the default
value for any of relevant sysctl settings
(``net.bridge.bridge-nf-call-arptables``,
``net.bridge.bridge-nf-call-ip6tables``, and
``net.bridge.bridge-nf-call-iptables``) then make sure you set them back
to upstream kernel default (``1``) using /etc/sysctl.conf or
/etc/sysctl.d/* configuration files.
upgrades:
- On newer Linux kernels (3.18+) you will need to load the ``br_netfilter``
kernel module before starting an Open vSwitch or Linuxbridge agent using
iptables based firewall. Otherwise the agent will fail to start.