Enable to configure conntrack driver
This patch enables to configure conntrack driver. Initially, "conntrack-tools" is being used to manage connection, however, it's costly and down performance[1]. The alternative can be found here[2] with need to improve reliability and stability. [1] https://bugs.launchpad.net/neutron/+bug/1630832 [2] https://review.openstack.org/#/c/389654/ Partial-Bug: #1664294 Co-Authored-By: Nguyen Phuong An <AnNP@vn.fujitsu.com> Change-Id: Id0597f74bef67b85776445e7bc591eb085f55acc
This commit is contained in:
parent
2074e1a3d5
commit
8f6a1b90af
|
@ -37,6 +37,10 @@ FWaaSOpts = [
|
|||
'agent_version',
|
||||
default=FWAAS_V1,
|
||||
help=_("Firewall agent class")),
|
||||
cfg.StrOpt(
|
||||
'conntrack_driver',
|
||||
default='conntrack',
|
||||
help=_("Name of the FWaaS Conntrack Driver")),
|
||||
]
|
||||
cfg.CONF.register_opts(FWaaSOpts, 'fwaas')
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright (c) 2017 Fujitsu Limited
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ConntrackDriverBase(object):
|
||||
"""Base Driver for Conntrack"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def initialize(self, *args, **kwargs):
|
||||
"""Initialize the driver"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_entries(self, rules, namespace):
|
||||
"""Delete conntrack entries specified by list of rules"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def flush_entries(self, namespace):
|
||||
"""Delete all conntrack entries within namespace"""
|
|
@ -13,10 +13,12 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron.agent.linux import iptables_manager
|
||||
from neutron.agent.linux import utils as linux_utils
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import excutils
|
||||
|
||||
from neutron.agent.linux import iptables_manager
|
||||
from neutron.common import utils
|
||||
from neutron_fwaas._i18n import _LE
|
||||
from neutron_fwaas.common import fwaas_constants as f_const
|
||||
from neutron_fwaas.extensions import firewall as fw_ext
|
||||
|
@ -56,6 +58,27 @@ class IptablesFwaasDriver(fwaas_base.FwaasDriverBase):
|
|||
def __init__(self):
|
||||
LOG.debug("Initializing fwaas iptables driver")
|
||||
self.pre_firewall = None
|
||||
conntrack_cls = self._load_firewall_extension_driver(
|
||||
'neutron_fwaas.services.firewall.drivers.linux',
|
||||
cfg.CONF.fwaas.conntrack_driver)
|
||||
self.conntrack = conntrack_cls()
|
||||
self.conntrack.initialize()
|
||||
|
||||
@staticmethod
|
||||
def _load_firewall_extension_driver(namespace, driver):
|
||||
"""Loads driver using alias or class name
|
||||
:param namespace: namespace where alias is defined
|
||||
:param driver: driver alias or class name
|
||||
:returns driver that is loaded
|
||||
:raises ImportError if fails to load driver
|
||||
"""
|
||||
|
||||
try:
|
||||
return utils.load_class_by_alias_or_classname(namespace,
|
||||
driver)
|
||||
except ImportError:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_LE("Driver '%s' not found."), driver)
|
||||
|
||||
def create_firewall(self, agent_mode, apply_list, firewall):
|
||||
LOG.debug('Creating firewall %(fw_id)s for tenant %(tid)s',
|
||||
|
@ -257,26 +280,6 @@ class IptablesFwaasDriver(fwaas_base.FwaasDriverBase):
|
|||
def _find_new_rules(self, pre_firewall, firewall):
|
||||
return self._find_removed_rules(firewall, pre_firewall)
|
||||
|
||||
def _get_conntrack_cmd_from_rule(self, ipt_mgr, rule=None):
|
||||
prefixcmd = ['ip', 'netns', 'exec'] + [ipt_mgr.namespace]
|
||||
cmd = ['conntrack', '-D']
|
||||
if rule:
|
||||
conntrack_filter = self._get_conntrack_filter_from_rule(rule)
|
||||
exec_cmd = prefixcmd + cmd + conntrack_filter
|
||||
else:
|
||||
exec_cmd = prefixcmd + cmd
|
||||
return exec_cmd
|
||||
|
||||
def _remove_conntrack_by_cmd(self, cmd):
|
||||
if cmd:
|
||||
try:
|
||||
linux_utils.execute(cmd, run_as_root=True,
|
||||
check_exit_code=True,
|
||||
extra_ok_codes=[1])
|
||||
except RuntimeError:
|
||||
LOG.exception(
|
||||
_LE("Failed execute conntrack command %s"), str(cmd))
|
||||
|
||||
def _remove_conntrack_new_firewall(self, agent_mode, apply_list, firewall):
|
||||
"""Remove conntrack when create new firewall"""
|
||||
routers_list = list(set(apply_list))
|
||||
|
@ -285,8 +288,7 @@ class IptablesFwaasDriver(fwaas_base.FwaasDriverBase):
|
|||
agent_mode, router_info)
|
||||
for ipt_if_prefix in ipt_if_prefix_list:
|
||||
ipt_mgr = ipt_if_prefix['ipt']
|
||||
cmd = self._get_conntrack_cmd_from_rule(ipt_mgr)
|
||||
self._remove_conntrack_by_cmd(cmd)
|
||||
self.conntrack.flush_entries(ipt_mgr.namespace)
|
||||
|
||||
def _remove_conntrack_updated_firewall(self, agent_mode,
|
||||
apply_list, pre_firewall, firewall):
|
||||
|
@ -302,27 +304,8 @@ class IptablesFwaasDriver(fwaas_base.FwaasDriverBase):
|
|||
i_rules = self._find_new_rules(pre_firewall, firewall)
|
||||
r_rules = self._find_removed_rules(pre_firewall, firewall)
|
||||
removed_conntrack_rules_list = ch_rules + i_rules + r_rules
|
||||
for rule in removed_conntrack_rules_list:
|
||||
cmd = self._get_conntrack_cmd_from_rule(ipt_mgr, rule)
|
||||
self._remove_conntrack_by_cmd(cmd)
|
||||
|
||||
def _get_conntrack_filter_from_rule(self, rule):
|
||||
"""Get conntrack filter from rule.
|
||||
The key for get conntrack filter is protocol, destination_port
|
||||
and source_port. If we want to take more keys, add to the list.
|
||||
"""
|
||||
conntrack_filter = []
|
||||
keys = [['-p', 'protocol'], ['-f', 'ip_version'],
|
||||
['--dport', 'destination_port'], ['--sport', 'source_port']]
|
||||
for key in keys:
|
||||
if rule.get(key[1]):
|
||||
if key[1] == 'ip_version':
|
||||
conntrack_filter.append(key[0])
|
||||
conntrack_filter.append('ipv' + str(rule.get(key[1])))
|
||||
else:
|
||||
conntrack_filter.append(key[0])
|
||||
conntrack_filter.append(rule.get(key[1]))
|
||||
return conntrack_filter
|
||||
self.conntrack.delete_entries(removed_conntrack_rules_list,
|
||||
ipt_mgr.namespace)
|
||||
|
||||
def _remove_default_chains(self, nsid):
|
||||
"""Remove fwaas default policy chain."""
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
# Copyright (c) 2017 Fujitsu Limited
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from neutron.agent.linux import utils as linux_utils
|
||||
|
||||
from neutron_fwaas._i18n import _
|
||||
from neutron_fwaas.services.firewall.drivers import conntrack_base
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ConntrackLegacy(conntrack_base.ConntrackDriverBase):
|
||||
def initialize(self, execute=None):
|
||||
LOG.debug('Initialize Conntrack Legacy')
|
||||
self.execute = execute or linux_utils.execute
|
||||
|
||||
def flush_entries(self, namespace):
|
||||
prefixcmd = ['ip', 'netns', 'exec', namespace] if namespace else []
|
||||
cmd = prefixcmd + ['conntrack', '-D']
|
||||
self._execute_command(cmd)
|
||||
|
||||
def delete_entries(self, rules, namespace):
|
||||
for rule in rules:
|
||||
cmd = self._get_conntrack_cmd_from_rule(rule, namespace)
|
||||
self._execute_command(cmd)
|
||||
|
||||
def _execute_command(self, cmd):
|
||||
try:
|
||||
self.execute(cmd,
|
||||
run_as_root=True,
|
||||
check_exit_code=True,
|
||||
extra_ok_codes=[1])
|
||||
except RuntimeError:
|
||||
msg = _("Failed execute conntrack command %s") % cmd
|
||||
raise RuntimeError(msg)
|
||||
|
||||
def _get_conntrack_cmd_from_rule(self, rule, namespace):
|
||||
prefixcmd = (['ip', 'netns', 'exec', namespace]
|
||||
if namespace else [])
|
||||
cmd = ['conntrack', '-D']
|
||||
if rule:
|
||||
conntrack_filter = self._get_conntrack_filter_from_rule(rule)
|
||||
exec_cmd = prefixcmd + cmd + conntrack_filter
|
||||
else:
|
||||
exec_cmd = prefixcmd + cmd
|
||||
return exec_cmd
|
||||
|
||||
def _get_conntrack_filter_from_rule(self, rule):
|
||||
"""Get conntrack filter from rule
|
||||
|
||||
The key for get conntrack filter is protocol, destination_port
|
||||
and source_port. If we want to take more keys, add to the list.
|
||||
"""
|
||||
conntrack_filter = []
|
||||
keys = [['-p', 'protocol'], ['-f', 'ip_version'],
|
||||
['--dport', 'destination_port'], ['--sport', 'source_port']]
|
||||
for arg_key, rule_key in keys:
|
||||
val = rule.get(rule_key)
|
||||
if val:
|
||||
if rule_key == 'ip_version':
|
||||
conntrack_filter.append(arg_key)
|
||||
conntrack_filter.append('ipv' + str(val))
|
||||
else:
|
||||
conntrack_filter.append(arg_key)
|
||||
conntrack_filter.append(val)
|
||||
return conntrack_filter
|
|
@ -34,13 +34,15 @@ FW_LEGACY = 'legacy'
|
|||
class IptablesFwaasTestCase(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(IptablesFwaasTestCase, self).setUp()
|
||||
self.utils_exec_p = mock.patch(
|
||||
'neutron.agent.linux.utils.execute')
|
||||
self.utils_exec = self.utils_exec_p.start()
|
||||
self.conntrack_driver = mock.Mock()
|
||||
self.conntrack_driver.initialize = mock.Mock()
|
||||
self.conntrack_driver.delete_entries = mock.Mock()
|
||||
self.conntrack_driver.flush_entries = mock.Mock()
|
||||
self.iptables_cls_p = mock.patch(
|
||||
'neutron.agent.linux.iptables_manager.IptablesManager')
|
||||
self.iptables_cls_p.start()
|
||||
self.firewall = fwaas.IptablesFwaasDriver()
|
||||
self.firewall.conntrack = self.conntrack_driver
|
||||
|
||||
def _fake_rules_v4(self, fwid, apply_list):
|
||||
rule_list = []
|
||||
|
@ -285,11 +287,8 @@ class IptablesFwaasTestCase(base.BaseTestCase):
|
|||
self.firewall.create_firewall(FW_LEGACY, apply_list, firewall)
|
||||
for router_info_inst in apply_list:
|
||||
namespace = router_info_inst.iptables_manager.namespace
|
||||
cmd = ['ip', 'netns', 'exec', namespace, 'conntrack', '-D']
|
||||
calls = [
|
||||
mock.call(cmd, run_as_root=True, check_exit_code=True,
|
||||
extra_ok_codes=[1])]
|
||||
self.utils_exec.assert_has_calls(calls)
|
||||
calls = [mock.call(namespace)]
|
||||
self.conntrack_driver.flush_entries.assert_has_calls(calls)
|
||||
|
||||
def test_remove_conntrack_inserted_rule(self):
|
||||
apply_list = self._fake_apply_list()
|
||||
|
@ -305,18 +304,35 @@ class IptablesFwaasTestCase(base.BaseTestCase):
|
|||
rule_list.insert(2, insert_rule)
|
||||
firewall = self._fake_firewall(rule_list)
|
||||
self.firewall.update_firewall(FW_LEGACY, apply_list, firewall)
|
||||
rules_changed = [
|
||||
{'destination_port': '23',
|
||||
'position': '2',
|
||||
'protocol': 'tcp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'id': 'fake-fw-rule3'},
|
||||
{'destination_port': '23',
|
||||
'position': '3',
|
||||
'protocol': 'tcp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'id': 'fake-fw-rule3'}
|
||||
]
|
||||
rules_inserted = [
|
||||
{'id': 'fake-fw-rule',
|
||||
'protocol': 'icmp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'deny',
|
||||
'position': '2'}
|
||||
]
|
||||
for router_info_inst in apply_list:
|
||||
namespace = router_info_inst.iptables_manager.namespace
|
||||
cmd1 = ['ip', 'netns', 'exec', namespace, 'conntrack',
|
||||
'-D', '-p', 'tcp', '-f', 'ipv4', '--dport', '23']
|
||||
cmd2 = ['ip', 'netns', 'exec', namespace, 'conntrack',
|
||||
'-D', '-p', 'icmp', '-f', 'ipv4']
|
||||
calls = [
|
||||
mock.call(cmd1, run_as_root=True, check_exit_code=True,
|
||||
extra_ok_codes=[1]),
|
||||
mock.call(cmd2, run_as_root=True, check_exit_code=True,
|
||||
extra_ok_codes=[1])]
|
||||
self.utils_exec.assert_has_calls(calls)
|
||||
self.conntrack_driver.delete_entries.assert_called_once_with(
|
||||
rules_changed + rules_inserted, namespace
|
||||
)
|
||||
|
||||
def test_remove_conntrack_removed_rule(self):
|
||||
apply_list = self._fake_apply_list()
|
||||
|
@ -328,18 +344,36 @@ class IptablesFwaasTestCase(base.BaseTestCase):
|
|||
rule_list.remove(remove_rule)
|
||||
firewall = self._fake_firewall(rule_list)
|
||||
self.firewall.update_firewall(FW_LEGACY, apply_list, firewall)
|
||||
rules_changed = [
|
||||
{'destination_port': '23',
|
||||
'position': '2',
|
||||
'protocol': 'tcp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'id': 'fake-fw-rule3'},
|
||||
{'destination_port': '23',
|
||||
'position': '1',
|
||||
'protocol': 'tcp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'id': 'fake-fw-rule3'}
|
||||
]
|
||||
rules_removed = [
|
||||
{'enabled': True,
|
||||
'position': '1',
|
||||
'protocol': 'tcp',
|
||||
'id': 'fake-fw-rule2',
|
||||
'ip_version': 4,
|
||||
'action': 'deny',
|
||||
'destination_port': '22'}
|
||||
]
|
||||
for router_info_inst in apply_list:
|
||||
namespace = router_info_inst.iptables_manager.namespace
|
||||
cmd1 = ['ip', 'netns', 'exec', namespace, 'conntrack',
|
||||
'-D', '-p', 'tcp', '-f', 'ipv4', '--dport', '23']
|
||||
cmd2 = ['ip', 'netns', 'exec', namespace, 'conntrack',
|
||||
'-D', '-p', 'tcp', '-f', 'ipv4', '--dport', '22']
|
||||
calls = [
|
||||
mock.call(cmd1, run_as_root=True, check_exit_code=True,
|
||||
extra_ok_codes=[1]),
|
||||
mock.call(cmd2, run_as_root=True, check_exit_code=True,
|
||||
extra_ok_codes=[1])]
|
||||
self.utils_exec.assert_has_calls(calls)
|
||||
self.conntrack_driver.delete_entries.assert_called_once_with(
|
||||
rules_changed + rules_removed, namespace
|
||||
)
|
||||
|
||||
def test_remove_conntrack_changed_rule(self):
|
||||
apply_list = self._fake_apply_list()
|
||||
|
@ -349,20 +383,28 @@ class IptablesFwaasTestCase(base.BaseTestCase):
|
|||
income_rule = {'enabled': True,
|
||||
'action': 'deny',
|
||||
'ip_version': 4,
|
||||
'protocol': 'icmp',
|
||||
'id': 'fake-fw-rule2'}
|
||||
rule_list[1] = income_rule
|
||||
'protocol': 'tcp',
|
||||
'id': 'fake-fw-rule3'}
|
||||
rule_list[2] = income_rule
|
||||
firewall = self._fake_firewall(rule_list)
|
||||
self.firewall.update_firewall(FW_LEGACY, apply_list, firewall)
|
||||
rules_changed = [
|
||||
{'id': 'fake-fw-rule3',
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'position': '2',
|
||||
'destination_port': '23',
|
||||
'ip_version': 4,
|
||||
'protocol': 'tcp'},
|
||||
{'position': '2',
|
||||
'enabled': True,
|
||||
'action': 'deny',
|
||||
'id': 'fake-fw-rule3',
|
||||
'ip_version': 4,
|
||||
'protocol': 'tcp'}
|
||||
]
|
||||
for router_info_inst in apply_list:
|
||||
namespace = router_info_inst.iptables_manager.namespace
|
||||
cmd1 = ['ip', 'netns', 'exec', namespace, 'conntrack', '-D',
|
||||
'-p', 'tcp', '-f', 'ipv4', '--dport', '22']
|
||||
cmd2 = ['ip', 'netns', 'exec', namespace, 'conntrack', '-D',
|
||||
'-p', 'icmp', '-f', 'ipv4']
|
||||
calls = [
|
||||
mock.call(cmd1, run_as_root=True, check_exit_code=True,
|
||||
extra_ok_codes=[1]),
|
||||
mock.call(cmd2, run_as_root=True, check_exit_code=True,
|
||||
extra_ok_codes=[1])]
|
||||
self.utils_exec.assert_has_calls(calls)
|
||||
self.conntrack_driver.delete_entries.assert_called_once_with(
|
||||
rules_changed, namespace
|
||||
)
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
# Copyright (c) 2017 Fujitsu Limited
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from neutron.tests import base
|
||||
from neutron_fwaas.services.firewall.drivers.linux import legacy_conntrack
|
||||
|
||||
|
||||
FW_RULES = [
|
||||
{'position': '2',
|
||||
'protocol': 'icmp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'id': 'fake-fw-rule1'},
|
||||
{'source_port': '1',
|
||||
'destination_port': '2',
|
||||
'position': '2',
|
||||
'protocol': 'tcp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'id': 'fake-fw-rule2'},
|
||||
{'source_port': '1',
|
||||
'destination_port': '2',
|
||||
'position': '3',
|
||||
'protocol': 'udp',
|
||||
'ip_version': 4,
|
||||
'enabled': True,
|
||||
'action': 'reject',
|
||||
'id': 'fake-fw-rule3'},
|
||||
]
|
||||
|
||||
ROUTER_NAMESPACE = 'qrouter-fake-namespace'
|
||||
|
||||
|
||||
class ConntrackLegacyTestCase(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(ConntrackLegacyTestCase, self).setUp()
|
||||
self.utils_exec = mock.Mock()
|
||||
self.conntrack_driver = legacy_conntrack.ConntrackLegacy()
|
||||
self.conntrack_driver.initialize(execute=self.utils_exec)
|
||||
|
||||
def test_excecute_command_failed(self):
|
||||
with testtools.ExpectedException(RuntimeError):
|
||||
self.conntrack_driver._execute_command(['fake', 'command'])
|
||||
raise RuntimeError("Failed execute conntrack command fake command")
|
||||
|
||||
def test_flush_entries(self):
|
||||
self.conntrack_driver.flush_entries(ROUTER_NAMESPACE)
|
||||
self.utils_exec.assert_called_with(
|
||||
['ip', 'netns', 'exec', ROUTER_NAMESPACE,
|
||||
'conntrack', '-D'],
|
||||
check_exit_code=True,
|
||||
extra_ok_codes=[1],
|
||||
run_as_root=True)
|
||||
|
||||
def test_delete_entries(self):
|
||||
self.conntrack_driver.delete_entries(FW_RULES, ROUTER_NAMESPACE)
|
||||
calls = [
|
||||
mock.call(['ip', 'netns', 'exec', ROUTER_NAMESPACE,
|
||||
'conntrack', '-D', '-p', 'icmp', '-f', 'ipv4'],
|
||||
check_exit_code=True,
|
||||
extra_ok_codes=[1],
|
||||
run_as_root=True),
|
||||
mock.call(['ip', 'netns', 'exec', ROUTER_NAMESPACE,
|
||||
'conntrack', '-D', '-p', 'tcp', '-f', 'ipv4',
|
||||
'--dport', '2', '--sport', '1'],
|
||||
check_exit_code=True,
|
||||
extra_ok_codes=[1],
|
||||
run_as_root=True),
|
||||
mock.call(['ip', 'netns', 'exec', ROUTER_NAMESPACE,
|
||||
'conntrack', '-D', '-p', 'udp', '-f', 'ipv4',
|
||||
'--dport', '2', '--sport', '1'],
|
||||
check_exit_code=True,
|
||||
extra_ok_codes=[1],
|
||||
run_as_root=True),
|
||||
|
||||
]
|
||||
self.utils_exec.assert_has_calls(calls)
|
|
@ -51,6 +51,8 @@ oslo.config.opts =
|
|||
neutron.agent.l3.extensions =
|
||||
fwaas = neutron_fwaas.services.firewall.agents.l3reference.firewall_l3_agent:L3WithFWaaS
|
||||
fwaas_v2 = neutron_fwaas.services.firewall.agents.l3reference.firewall_l3_agent_v2:L3WithFWaaS
|
||||
neutron_fwaas.services.firewall.drivers.linux =
|
||||
conntrack = neutron_fwaas.services.firewall.drivers.linux.legacy_conntrack:ConntrackLegacy
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
|
|
Loading…
Reference in New Issue