Commit 374feb97 authored by Florent Fourcot's avatar Florent Fourcot

ipset: add timeout option

Timeout must be enable on the ipset. Then, we can pass an optional value
to each entry that we add in the set.
parent 8176f5cb
......@@ -96,7 +96,7 @@ class IPSet(NetlinkSocket):
def create(self, name, stype='hash:ip', family=socket.AF_INET,
exclusive=True, counters=False, comment=False,
maxelem=IPSET_DEFAULT_MAXELEM, forceadd=False,
hashsize=None):
hashsize=None, timeout=None):
'''
Create an ipset `name` of type `stype`, by default
`hash:ip`.
......@@ -118,6 +118,8 @@ class IPSet(NetlinkSocket):
["IPSET_ATTR_MAXELEM", maxelem]]}
if hashsize is not None:
data['attrs'] += [["IPSET_ATTR_HASHSIZE", hashsize]]
if timeout is not None:
data['attrs'] += [["IPSET_ATTR_TIMEOUT", timeout]]
msg['attrs'] = [['IPSET_ATTR_PROTOCOL', self._proto_version],
['IPSET_ATTR_SETNAME', name],
......@@ -130,7 +132,8 @@ class IPSet(NetlinkSocket):
msg_flags=NLM_F_REQUEST | NLM_F_ACK | excl_flag,
terminate=_nlmsg_error)
def _add_delete(self, name, entry, family, cmd, exclusive, comment=None):
def _add_delete(self, name, entry, family, cmd, exclusive, comment=None,
timeout=None):
if family == socket.AF_INET:
entry_type = 'IPSET_ATTR_IPADDR_IPV4'
elif family == socket.AF_INET6:
......@@ -143,6 +146,8 @@ class IPSet(NetlinkSocket):
if comment is not None:
data_attrs += [["IPSET_ATTR_COMMENT", comment],
["IPSET_ATTR_CADT_LINENO", 0]]
if timeout is not None:
data_attrs += [["IPSET_ATTR_TIMEOUT", timeout]]
msg = ipset_msg()
msg['attrs'] = [['IPSET_ATTR_PROTOCOL', self._proto_version],
['IPSET_ATTR_SETNAME', name],
......@@ -153,12 +158,12 @@ class IPSet(NetlinkSocket):
terminate=_nlmsg_error)
def add(self, name, entry, family=socket.AF_INET, exclusive=True,
comment=None):
comment=None, timeout=None):
'''
Add a member to the ipset
'''
return self._add_delete(name, entry, family, IPSET_CMD_ADD, exclusive,
comment=comment)
comment=comment, timeout=timeout)
def delete(self, name, entry, family=socket.AF_INET, exclusive=True):
'''
......
......@@ -66,7 +66,7 @@ class ipset_msg(nfgen_msg):
(4, 'IPSET_ATTR_PORT', 'hex'),
(4, 'IPSET_ATTR_PORT_FROM', 'hex'),
(5, 'IPSET_ATTR_PORT_TO', 'hex'),
(6, 'IPSET_ATTR_TIMEOUT', 'hex'),
(6, 'IPSET_ATTR_TIMEOUT', 'be32', NLA_F_NET_BYTEORDER),
(7, 'IPSET_ATTR_PROTO', 'recursive'),
(8, 'IPSET_ATTR_CADT_FLAGS', 'be32', NLA_F_NET_BYTEORDER),
(9, 'IPSET_ATTR_CADT_LINENO', 'be32'),
......@@ -96,7 +96,7 @@ class ipset_msg(nfgen_msg):
(4, 'IPSET_ATTR_PORT', 'hex'),
(4, 'IPSET_ATTR_PORT_FROM', 'hex'),
(5, 'IPSET_ATTR_PORT_TO', 'hex'),
(6, 'IPSET_ATTR_TIMEOUT', 'hex'),
(6, 'IPSET_ATTR_TIMEOUT', 'be32', NLA_F_NET_BYTEORDER),
(7, 'IPSET_ATTR_PROTO', 'recursive'),
(8, 'IPSET_ATTR_CADT_FLAGS', 'be32', NLA_F_NET_BYTEORDER),
(9, 'IPSET_ATTR_CADT_LINENO', 'be32'),
......
import errno
from time import sleep
from pyroute2.ipset import IPSet
from pyroute2.netlink.exceptions import NetlinkError
from utils import require_user
......@@ -25,7 +26,8 @@ class TestIPSet(object):
ip = x.get_attr('IPSET_ATTR_IP_FROM').get_attr(ipaddr)
res[ip] = (x.get_attr("IPSET_ATTR_PACKETS"),
x.get_attr("IPSET_ATTR_BYTES"),
x.get_attr("IPSET_ATTR_COMMENT"))
x.get_attr("IPSET_ATTR_COMMENT"),
x.get_attr("IPSET_ATTR_TIMEOUT"))
return res
except:
return {}
......@@ -244,3 +246,20 @@ class TestIPSet(object):
self.ip.rename(name, name_bis)
assert self.get_ipset(name_bis)
self.ip.destroy(name_bis)
def test_timeout(self):
require_user('root')
name = str(uuid4())[:16]
ip = "1.2.3.4"
self.ip.create(name, timeout=1)
self.ip.add(name, ip)
sleep(2)
assert ip not in self.list_ipset(name)
# check that we can overwrite default timeout value
self.ip.add(name, ip, timeout=5)
sleep(2)
assert ip in self.list_ipset(name)
assert self.list_ipset(name)[ip][3] > 0 # timeout
sleep(3)
assert ip not in self.list_ipset(name)
self.ip.destroy(name)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment