Merge "Add ipset element and hashsize tunables"
This commit is contained in:
commit
4543a4cefa
|
@ -661,6 +661,15 @@
|
|||
# each rule's purpose. (System must support the iptables comments module.)
|
||||
# comment_iptables_rules = True
|
||||
|
||||
# Maximum number of elements which can be stored in an IPset.
|
||||
# If None is specified, the system default will be used.
|
||||
# ipset_maxelem = 131072
|
||||
|
||||
# Initial hash size for an IPset. Must be a power of 2,
|
||||
# else the kernel will round it up automatically.
|
||||
# If None is specified, the system default will be used.
|
||||
# ipset_hashsize = 2048
|
||||
|
||||
# Use the root helper when listing the namespaces on a system. This may not
|
||||
# be required depending on the security configuration. If the root helper is
|
||||
# not required, set this to False for a performance improvement.
|
||||
|
|
|
@ -63,6 +63,17 @@ IPTABLES_OPTS = [
|
|||
help=_("Add comments to iptables rules.")),
|
||||
]
|
||||
|
||||
IPSET_OPTS = [
|
||||
cfg.IntOpt('ipset_maxelem', default=131072,
|
||||
help=_("Maximum number of elements which can be stored in "
|
||||
"an IPset. If None is specified, the system default "
|
||||
"will be used.")),
|
||||
cfg.IntOpt('ipset_hashsize', default=2048,
|
||||
help=_("Initial hash size for an IPset. Must be a power of 2, "
|
||||
"else the kernel will round it up automatically. If "
|
||||
"None is specified, the system default will be used.")),
|
||||
]
|
||||
|
||||
PROCESS_MONITOR_OPTS = [
|
||||
cfg.StrOpt('check_child_processes_action', default='respawn',
|
||||
choices=['respawn', 'exit'],
|
||||
|
@ -122,6 +133,10 @@ def register_iptables_opts(conf):
|
|||
conf.register_opts(IPTABLES_OPTS, 'AGENT')
|
||||
|
||||
|
||||
def register_ipset_opts(conf):
|
||||
conf.register_opts(IPSET_OPTS, 'AGENT')
|
||||
|
||||
|
||||
def register_process_monitor_opts(conf):
|
||||
conf.register_opts(PROCESS_MONITOR_OPTS, 'AGENT')
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from neutron.agent.common import config
|
||||
from neutron.agent.linux import utils as linux_utils
|
||||
from neutron.common import utils
|
||||
|
||||
|
@ -29,6 +32,7 @@ class IpsetManager(object):
|
|||
def __init__(self, execute=None, namespace=None):
|
||||
self.execute = execute or linux_utils.execute
|
||||
self.namespace = namespace
|
||||
config.register_ipset_opts(cfg.CONF)
|
||||
self.ipset_sets = {}
|
||||
|
||||
@staticmethod
|
||||
|
@ -39,6 +43,15 @@ class IpsetManager(object):
|
|||
name = ethertype + id
|
||||
return name[:IPSET_NAME_MAX_LENGTH]
|
||||
|
||||
@staticmethod
|
||||
def get_hashargs():
|
||||
args = []
|
||||
if cfg.CONF.AGENT.ipset_hashsize:
|
||||
args.extend(['hashsize', str(cfg.CONF.AGENT.ipset_hashsize)])
|
||||
if cfg.CONF.AGENT.ipset_maxelem:
|
||||
args.extend(['maxelem', str(cfg.CONF.AGENT.ipset_maxelem)])
|
||||
return args
|
||||
|
||||
def set_exists(self, id, ethertype):
|
||||
"""Returns true if the id+ethertype pair is known to the manager."""
|
||||
set_name = self.get_name(id, ethertype)
|
||||
|
@ -85,8 +98,10 @@ class IpsetManager(object):
|
|||
def _refresh_set(self, set_name, member_ips, ethertype):
|
||||
new_set_name = set_name + SWAP_SUFFIX
|
||||
set_type = self._get_ipset_set_type(ethertype)
|
||||
process_input = ["create %s hash:ip family %s" % (new_set_name,
|
||||
set_type)]
|
||||
hash_args = ' '.join(self.get_hashargs())
|
||||
process_input = ["create %s hash:ip family %s %s" % (new_set_name,
|
||||
set_type,
|
||||
hash_args)]
|
||||
for ip in member_ips:
|
||||
process_input.append("add %s %s" % (new_set_name, ip))
|
||||
|
||||
|
@ -103,6 +118,7 @@ class IpsetManager(object):
|
|||
def _create_set(self, set_name, ethertype):
|
||||
cmd = ['ipset', 'create', '-exist', set_name, 'hash:ip', 'family',
|
||||
self._get_ipset_set_type(ethertype)]
|
||||
cmd.extend(self.get_hashargs())
|
||||
self._apply(cmd)
|
||||
self.ipset_sets[set_name] = []
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
|
||||
from neutron.agent.common import config as a_cfg
|
||||
from neutron.agent.linux import ipset_manager
|
||||
from neutron.tests import base
|
||||
|
||||
|
@ -25,8 +27,13 @@ FAKE_IPS = ['10.0.0.1', '10.0.0.2', '10.0.0.3', '10.0.0.4',
|
|||
|
||||
|
||||
class BaseIpsetManagerTest(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
def setUp(self, maxelem=None, hashsize=None):
|
||||
super(BaseIpsetManagerTest, self).setUp()
|
||||
cfg.CONF.register_opts(a_cfg.IPSET_OPTS, 'AGENT')
|
||||
cfg.CONF.set_override('ipset_maxelem', maxelem, 'AGENT')
|
||||
cfg.CONF.set_override('ipset_hashsize', hashsize, 'AGENT')
|
||||
self.maxelem = maxelem
|
||||
self.hashsize = hashsize
|
||||
self.ipset = ipset_manager.IpsetManager()
|
||||
self.execute = mock.patch.object(self.ipset, "execute").start()
|
||||
self.expected_calls = []
|
||||
|
@ -36,7 +43,13 @@ class BaseIpsetManagerTest(base.BaseTestCase):
|
|||
self.execute.assert_has_calls(self.expected_calls, any_order=False)
|
||||
|
||||
def expect_set(self, addresses):
|
||||
temp_input = ['create IPv4fake_sgid-new hash:ip family inet']
|
||||
hash_args = []
|
||||
if self.hashsize:
|
||||
hash_args.extend(['hashsize', str(self.hashsize)])
|
||||
if self.maxelem:
|
||||
hash_args.extend(['maxelem', str(self.maxelem)])
|
||||
temp_input = ['create IPv4fake_sgid-new hash:ip family inet %s' %
|
||||
' '.join(hash_args)]
|
||||
temp_input.extend('add IPv4fake_sgid-new %s' % ip for ip in addresses)
|
||||
input = '\n'.join(temp_input)
|
||||
self.expected_calls.extend([
|
||||
|
@ -63,9 +76,14 @@ class BaseIpsetManagerTest(base.BaseTestCase):
|
|||
run_as_root=True) for ip in addresses)
|
||||
|
||||
def expect_create(self):
|
||||
ipset_call = ['ipset', 'create', '-exist', TEST_SET_NAME,
|
||||
'hash:ip', 'family', 'inet']
|
||||
if self.hashsize:
|
||||
ipset_call.extend(['hashsize', str(self.hashsize)])
|
||||
if self.maxelem:
|
||||
ipset_call.extend(['maxelem', str(self.maxelem)])
|
||||
self.expected_calls.append(
|
||||
mock.call(['ipset', 'create', '-exist', TEST_SET_NAME,
|
||||
'hash:ip', 'family', 'inet'],
|
||||
mock.call(ipset_call,
|
||||
process_input=None,
|
||||
run_as_root=True))
|
||||
|
||||
|
@ -85,6 +103,10 @@ class BaseIpsetManagerTest(base.BaseTestCase):
|
|||
|
||||
|
||||
class IpsetManagerTestCase(BaseIpsetManagerTest):
|
||||
"""Run all tests, but with maxelem/hashsize values not configured
|
||||
"""
|
||||
def setUp(self):
|
||||
super(IpsetManagerTestCase, self).setUp()
|
||||
|
||||
def test_set_exists(self):
|
||||
self.add_first_ip()
|
||||
|
@ -117,3 +139,10 @@ class IpsetManagerTestCase(BaseIpsetManagerTest):
|
|||
self.expect_destroy()
|
||||
self.ipset.destroy(TEST_SET_ID, ETHERTYPE)
|
||||
self.verify_mock_calls()
|
||||
|
||||
|
||||
class IpsetManagerTestCaseHashArgs(IpsetManagerTestCase):
|
||||
"""Run all the above tests, but with maxelem/hashsize values configured
|
||||
"""
|
||||
def setUp(self):
|
||||
super(IpsetManagerTestCase, self).setUp(maxelem=131072, hashsize=2048)
|
||||
|
|
Loading…
Reference in New Issue