diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in
index 9cb7644925b2b4859e2d9a283eda8a1388007cc6..5eea5c6cae3cd5355ffc0a3e1d85e8f89c52e04c 100644
--- a/docs/formatnwfilter.html.in
+++ b/docs/formatnwfilter.html.in
@@ -528,6 +528,11 @@
IPV6_MASK: IPv6 mask in numbers format (FFFF:FFFF:FC00::) or CIDR mask (0-128)
STRING: A string
BOOLEAN: 'true', 'yes', '1' or 'false', 'no', '0'
+ IPSETFLAGS: The source and destination flags of the ipset described
+ by up to 6 'src' or 'dst' elements selecting features from either
+ the source or destination part of the packet header; example:
+ src,src,dst. The number of 'selectors' to provide here depends
+ on the type of ipset that is referenced.
@@ -1169,6 +1174,16 @@
STRING |
TCP-only: format of mask/flags with mask and flags each being a comma separated list of SYN,ACK,URG,PSH,FIN,RST or NONE or ALL |
+
+ ipset (Since 0.9.13) |
+ STRING |
+ The name of an IPSet managed outside of libvirt |
+
+
+ ipsetflags (Since 0.9.13) |
+ IPSETFLAGS |
+ flags for the IPSet; requires ipset attribute |
+
@@ -1269,6 +1284,16 @@
STRING |
comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE |
+
+ ipset (Since 0.9.13) |
+ STRING |
+ The name of an IPSet managed outside of libvirt |
+
+
+ ipsetflags (Since 0.9.13) |
+ IPSETFLAGS |
+ flags for the IPSet; requires ipset attribute |
+
@@ -1358,6 +1383,16 @@
STRING |
comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE |
+
+ ipset (Since 0.9.13) |
+ STRING |
+ The name of an IPSet managed outside of libvirt |
+
+
+ ipsetflags (Since 0.9.13) |
+ IPSETFLAGS |
+ flags for the IPSet; requires ipset attribute |
+
@@ -1459,6 +1494,16 @@
STRING |
TCP-only: format of mask/flags with mask and flags each being a comma separated list of SYN,ACK,URG,PSH,FIN,RST or NONE or ALL |
+
+ ipset (Since 0.9.13) |
+ STRING |
+ The name of an IPSet managed outside of libvirt |
+
+
+ ipsetflags (Since 0.9.13) |
+ IPSETFLAGS |
+ flags for the IPSet; requires ipset attribute |
+
@@ -1545,6 +1590,16 @@
STRING |
comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE |
+
+ ipset (Since 0.9.13) |
+ STRING |
+ The name of an IPSet managed outside of libvirt |
+
+
+ ipsetflags (Since 0.9.13) |
+ IPSETFLAGS |
+ flags for the IPSet; requires ipset attribute |
+
@@ -1619,6 +1674,16 @@
STRING |
comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE |
+
+ ipset (Since 0.9.13) |
+ STRING |
+ The name of an IPSet managed outside of libvirt |
+
+
+ ipsetflags (Since 0.9.13) |
+ IPSETFLAGS |
+ flags for the IPSet; requires ipset attribute |
+
diff --git a/docs/schemas/nwfilter.rng b/docs/schemas/nwfilter.rng
index 13fd9b95f0e4c9afb3e303906a37d366d9f161c8..cfd9ba57c77cf10bd965f3266b9dc638f1d769c4 100644
--- a/docs/schemas/nwfilter.rng
+++ b/docs/schemas/nwfilter.rng
@@ -485,6 +485,14 @@
+
+
+
+
+
+
+
+
@@ -1060,4 +1068,19 @@
((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)/((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)
+
+
+
+
+
+ [a-zA-Z0-9_\.:\-\+ ]{1,31}
+
+
+
+
+
+
+ (src|dst)(,(src|dst)){0,5}
+
+
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index 58115926aaba44600968ec2aa50b9eda8f245ca2..0d6d0b697d072ec565fd89eb7c5a56900297baa7 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -183,6 +183,8 @@ static const char dstportstart_str[] = "dstportstart";
static const char dstportend_str[] = "dstportend";
static const char dscp_str[] = "dscp";
static const char state_str[] = "state";
+static const char ipset_str[] = "ipset";
+static const char ipsetflags_str[] = "ipsetflags";
#define SRCMACADDR srcmacaddr_str
#define SRCMACMASK srcmacmask_str
@@ -206,6 +208,8 @@ static const char state_str[] = "state";
#define DSTPORTEND dstportend_str
#define DSCP dscp_str
#define STATE state_str
+#define IPSET ipset_str
+#define IPSETFLAGS ipsetflags_str
/**
@@ -980,6 +984,97 @@ tcpFlagsFormatter(virBufferPtr buf,
return true;
}
+static bool
+ipsetValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, union data *val,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ const char *errmsg = NULL;
+
+ if (virStrcpy(item->u.ipset.setname, val->c,
+ sizeof(item->u.ipset.setname)) == NULL) {
+ errmsg = _("ipset name is too long");
+ goto arg_err_exit;
+ }
+
+ if (item->u.ipset.setname[strspn(item->u.ipset.setname,
+ VALID_IPSETNAME)] != 0) {
+ errmsg = _("ipset name contains invalid characters");
+ goto arg_err_exit;
+ }
+
+ return true;
+
+arg_err_exit:
+ virNWFilterReportError(VIR_ERR_INVALID_ARG,
+ "%s", errmsg);
+ return false;
+}
+
+static bool
+ipsetFormatter(virBufferPtr buf,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ virBufferAdd(buf, item->u.ipset.setname, -1);
+
+ return true;
+}
+
+static bool
+ipsetFlagsValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, union data *val,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED, nwItemDesc *item)
+{
+ const char *errmsg = NULL;
+ size_t idx = 0;
+
+ item->u.ipset.numFlags = 0;
+ item->u.ipset.flags = 0;
+
+ errmsg = _("malformed ipset flags");
+
+ while (item->u.ipset.numFlags < 6) {
+ if (STRCASEEQLEN(&val->c[idx], "src", 3)) {
+ item->u.ipset.flags |= (1 << item->u.ipset.numFlags);
+ } else if (!STRCASEEQLEN(&val->c[idx], "dst", 3)) {
+ goto arg_err_exit;
+ }
+ item->u.ipset.numFlags++;
+ idx += 3;
+ if (val->c[idx] != ',')
+ break;
+ idx++;
+ }
+
+ if (val->c[idx] != '\0')
+ goto arg_err_exit;
+
+ return true;
+
+arg_err_exit:
+ virNWFilterReportError(VIR_ERR_INVALID_ARG,
+ "%s", errmsg);
+ return false;
+}
+
+static bool
+ipsetFlagsFormatter(virBufferPtr buf,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ uint8_t ctr;
+
+ for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
+ if (ctr != 0)
+ virBufferAddLit(buf, ",");
+ if ((item->u.ipset.flags & (1 << ctr)))
+ virBufferAddLit(buf, "src");
+ else
+ virBufferAddLit(buf, "dst");
+ }
+
+ return true;
+}
#define COMMON_MAC_PROPS(STRUCT) \
{\
@@ -1411,6 +1506,20 @@ static const virXMLAttr2Struct ipv6Attributes[] = {
.dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataState),\
.validator = stateValidator,\
.formatter = stateFormatter,\
+ },\
+ {\
+ .name = IPSET,\
+ .datatype = DATATYPE_IPSETNAME,\
+ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataIPSet),\
+ .validator = ipsetValidator,\
+ .formatter = ipsetFormatter,\
+ },\
+ {\
+ .name = IPSETFLAGS,\
+ .datatype = DATATYPE_IPSETFLAGS,\
+ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataIPSetFlags),\
+ .validator = ipsetFlagsValidator,\
+ .formatter = ipsetFlagsFormatter,\
}
#define COMMON_PORT_PROPS(STRUCT) \
@@ -1853,6 +1962,8 @@ virNWFilterRuleDetailsParse(xmlNodePtr node,
break;
case DATATYPE_STRING:
+ case DATATYPE_IPSETFLAGS:
+ case DATATYPE_IPSETNAME:
if (!validator) {
/* not supported */
rc = -1;
@@ -1964,6 +2075,19 @@ err_exit:
goto cleanup;
}
+static void
+virNWFilterRuleDefFixupIPSet(ipHdrDataDefPtr ipHdr)
+{
+ if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
+ !HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
+ ipHdr->dataIPSetFlags.flags = NWFILTER_ENTRY_ITEM_FLAG_EXISTS;
+ ipHdr->dataIPSetFlags.u.ipset.numFlags = 1;
+ ipHdr->dataIPSetFlags.u.ipset.flags = 1;
+ } else {
+ ipHdr->dataIPSet.flags = 0;
+ ipHdr->dataIPSetFlags.flags = 0;
+ }
+}
static void
virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
@@ -2017,6 +2141,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ipHdrFilter.ipHdr.dataDstIPMask,
rule->p.ipHdrFilter.ipHdr.dataDstIPAddr);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ipHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
@@ -2024,6 +2149,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask,
rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ipv6HdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
@@ -2047,6 +2173,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.tcpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.tcpHdrFilter.portData.dataDstPortEnd,
rule->p.tcpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.tcpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDP:
@@ -2065,6 +2192,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.udpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.udpHdrFilter.portData.dataDstPortEnd,
rule->p.udpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.udpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE:
@@ -2077,6 +2205,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.udpliteHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPTo,
rule->p.udpliteHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.udpliteHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ESP:
@@ -2089,6 +2218,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.espHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPTo,
rule->p.espHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.espHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_AH:
@@ -2101,6 +2231,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.ahHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPTo,
rule->p.ahHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ahHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_SCTP:
@@ -2119,6 +2250,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.sctpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.sctpHdrFilter.portData.dataDstPortEnd,
rule->p.sctpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.sctpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ICMP:
@@ -2133,6 +2265,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.icmpHdrFilter.ipHdr.dataDstIPFrom);
COPY_NEG_SIGN(rule->p.icmpHdrFilter.dataICMPCode,
rule->p.icmpHdrFilter.dataICMPType);
+ virNWFilterRuleDefFixupIPSet(&rule->p.icmpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ALL:
@@ -2156,6 +2289,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
rule->p.igmpHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.igmpHdrFilter.ipHdr.dataDstIPTo,
rule->p.igmpHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.igmpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_LAST:
@@ -3120,7 +3254,7 @@ virNWFilterRuleDefDetailsFormat(virBufferPtr buf,
virBufferAsprintf(buf, " %s='",
att[i].name);
- if (att[i].formatter) {
+ if (att[i].formatter && !(flags & NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
if (!att[i].formatter(buf, def, item)) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("formatter for %s %s reported error"),
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index a9a55c7e68ec19ef33b4283c96a57b6a249da1c0..a52826d2c3897038ba21b8cd02f14d372f515467 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -79,6 +79,7 @@ enum virNWFilterEntryItemFlags {
# define MAX_COMMENT_LENGTH 256
+# define MAX_IPSET_NAME_LENGTH 32 /* incl. terminating '\0' */
# define HAS_ENTRY_ITEM(data) \
(((data)->flags) & NWFILTER_ENTRY_ITEM_FLAG_EXISTS)
@@ -103,8 +104,10 @@ enum attrDatatype {
DATATYPE_BOOLEAN = (1 << 12),
DATATYPE_UINT32 = (1 << 13),
DATATYPE_UINT32_HEX = (1 << 14),
+ DATATYPE_IPSETNAME = (1 << 15),
+ DATATYPE_IPSETFLAGS = (1 << 16),
- DATATYPE_LAST = (1 << 15),
+ DATATYPE_LAST = (1 << 17),
};
# define NWFILTER_MAC_BGA "01:80:c2:00:00:00"
@@ -136,9 +139,16 @@ struct _nwItemDesc {
uint8_t mask;
uint8_t flags;
} tcpFlags;
+ struct {
+ char setname[MAX_IPSET_NAME_LENGTH];
+ uint8_t numFlags;
+ uint8_t flags;
+ } ipset;
} u;
};
+# define VALID_IPSETNAME \
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:-+ "
typedef struct _ethHdrDataDef ethHdrDataDef;
typedef ethHdrDataDef *ethHdrDataDefPtr;
@@ -232,6 +242,8 @@ struct _ipHdrDataDef {
nwItemDesc dataState;
nwItemDesc dataConnlimitAbove;
nwItemDesc dataComment;
+ nwItemDesc dataIPSet;
+ nwItemDesc dataIPSetFlags;
};
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c
index 28f48bd54c6e2426fcfaa24d2577d09b7dee8bd9..1b0bbf42da6c5dce272838fb712dfb80206c2618 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -256,10 +256,13 @@ static int
_printDataType(virNWFilterVarCombIterPtr vars,
char *buf, int bufsize,
nwItemDescPtr item,
- bool asHex)
+ bool asHex, bool directionIn)
{
int done;
char *data;
+ uint8_t ctr;
+ virBuffer vb = VIR_BUFFER_INITIALIZER;
+ char *flags;
if (printVar(vars, buf, bufsize, item, &done) < 0)
return -1;
@@ -346,6 +349,48 @@ _printDataType(virNWFilterVarCombIterPtr vars,
}
break;
+ case DATATYPE_IPSETNAME:
+ if (virStrcpy(buf, item->u.ipset.setname, bufsize) == NULL) {
+ virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Buffer to small for ipset name"));
+ return -1;
+ }
+ break;
+
+ case DATATYPE_IPSETFLAGS:
+ for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
+ if (ctr != 0)
+ virBufferAddLit(&vb, ",");
+ if ((item->u.ipset.flags & (1 << ctr))) {
+ if (directionIn)
+ virBufferAddLit(&vb, "dst");
+ else
+ virBufferAddLit(&vb, "src");
+ } else {
+ if (directionIn)
+ virBufferAddLit(&vb, "src");
+ else
+ virBufferAddLit(&vb, "dst");
+ }
+ }
+
+ if (virBufferError(&vb)) {
+ virReportOOMError();
+ virBufferFreeAndReset(&vb);
+ return -1;
+ }
+
+ flags = virBufferContentAndReset(&vb);
+
+ if (virStrcpy(buf, flags, bufsize) == NULL) {
+ virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Buffer too small for IPSETFLAGS type"));
+ VIR_FREE(flags);
+ return -1;
+ }
+ VIR_FREE(flags);
+ break;
+
default:
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("Unhandled datatype %x"), item->datatype);
@@ -362,16 +407,23 @@ printDataType(virNWFilterVarCombIterPtr vars,
char *buf, int bufsize,
nwItemDescPtr item)
{
- return _printDataType(vars, buf, bufsize, item, 0);
+ return _printDataType(vars, buf, bufsize, item, 0, 0);
}
+static int
+printDataTypeDirection(virNWFilterVarCombIterPtr vars,
+ char *buf, int bufsize,
+ nwItemDescPtr item, bool directionIn)
+{
+ return _printDataType(vars, buf, bufsize, item, 0, directionIn);
+}
static int
printDataTypeAsHex(virNWFilterVarCombIterPtr vars,
char *buf, int bufsize,
nwItemDescPtr item)
{
- return _printDataType(vars, buf, bufsize, item, 1);
+ return _printDataType(vars, buf, bufsize, item, 1, 0);
}
@@ -927,6 +979,7 @@ iptablesHandleIpHdr(virBufferPtr buf,
char ipaddr[INET6_ADDRSTRLEN],
number[MAX(INT_BUFSIZE_BOUND(uint32_t),
INT_BUFSIZE_BOUND(int))];
+ char str[MAX_IPSET_NAME_LENGTH];
const char *src = "--source";
const char *dst = "--destination";
const char *srcrange = "--src-range";
@@ -938,6 +991,26 @@ iptablesHandleIpHdr(virBufferPtr buf,
dstrange = "--src-range";
}
+ if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
+ HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
+
+ if (printDataType(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSet) < 0)
+ goto err_exit;
+
+ virBufferAsprintf(afterStateMatch,
+ " -m set --match-set \"%s\" ",
+ str);
+
+ if (printDataTypeDirection(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSetFlags, directionIn) < 0)
+ goto err_exit;
+
+ virBufferAdd(afterStateMatch, str, -1);
+ }
+
if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPAddr)) {
if (printDataType(vars,
diff --git a/tests/nwfilterxml2xmlin/ipset-test.xml b/tests/nwfilterxml2xmlin/ipset-test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2a46508f9ee4e54148a9cf8ca900d69aea35c078
--- /dev/null
+++ b/tests/nwfilterxml2xmlin/ipset-test.xml
@@ -0,0 +1,24 @@
+
+ 5c6d49af-b071-6127-b4ec-6f8ed4b55335
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/nwfilterxml2xmlout/ipset-test.xml b/tests/nwfilterxml2xmlout/ipset-test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..03d9a0e68daf49dd5b02ad46d90caeb91bafa413
--- /dev/null
+++ b/tests/nwfilterxml2xmlout/ipset-test.xml
@@ -0,0 +1,24 @@
+
+ 5c6d49af-b071-6127-b4ec-6f8ed4b55335
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/nwfilterxml2xmltest.c b/tests/nwfilterxml2xmltest.c
index 5fd8df823304583bd72fedc84553eedec1e1f48e..224ca93b856c55589c1e12d1897b58b15ed134e4 100644
--- a/tests/nwfilterxml2xmltest.c
+++ b/tests/nwfilterxml2xmltest.c
@@ -157,6 +157,8 @@ mymain(void)
DO_TEST("iter-test2", false);
DO_TEST("iter-test3", false);
+ DO_TEST("ipset-test", false);
+
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}