* [PATCH 0/5] ipset: Extend netmask support for userspace
@ 2017-03-21 18:39 Josh Hunt
2017-03-21 18:39 ` [PATCH 1/5] ipset: netmask: expand to support cidr and full mask Josh Hunt
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Josh Hunt @ 2017-03-21 18:39 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, coreteam, Josh Hunt
These are the userspace changes to add the ability to specify a netmask
or wildcard mask for the set during creation instead of just a cidr
value.
Example usage:
Legacy behavior:
ipset create foo hash:ip family inet6 netmask 64
New netmask support (equivalent to legacy example):
ipset create foo hash:ip family inet6 netmask ffff:ffff:ffff:ffff::
New wildcard mask support:
ipset create foo hash:ip family inet6 netmask ffff:ffff:ffff:0:0:ffff:ffff:ffff
The 3 mask types are supported for ipv4 sets as well.
Josh Hunt (5):
ipset: netmask: expand to support cidr and full mask
ipset: hash:ip: add support for new netmask types
ipset: hash:ipport: netmask support
hash:ip: add new netmask support to man page
hash:ip,port: add netmask support to man page
include/libipset/data.h | 5 +-
include/libipset/linux_ip_set.h | 5 ++
include/libipset/print.h | 3 +
lib/data.c | 25 +++++-
lib/debug.c | 1 +
lib/ipset_hash_ip.c | 166 ++++++++++++++++++++++++++++++++++
lib/ipset_hash_ipport.c | 194 ++++++++++++++++++++++++++++++++++++++++
lib/parse.c | 68 ++++++++++++--
lib/print.c | 39 +++++++-
lib/session.c | 8 ++
src/ipset.8 | 90 +++++++++++++++++--
11 files changed, 583 insertions(+), 21 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/5] ipset: netmask: expand to support cidr and full mask
2017-03-21 18:39 [PATCH 0/5] ipset: Extend netmask support for userspace Josh Hunt
@ 2017-03-21 18:39 ` Josh Hunt
2017-03-27 20:08 ` Jozsef Kadlecsik
2017-03-21 18:39 ` [PATCH 2/5] ipset: hash:ip: add support for new netmask types Josh Hunt
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Josh Hunt @ 2017-03-21 18:39 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, coreteam, Josh Hunt
Convert netmask to store cidr and netmask.
Signed-off-by: Josh Hunt <johunt@akamai.com>
---
include/libipset/data.h | 5 ++-
include/libipset/linux_ip_set.h | 5 +++
include/libipset/print.h | 3 ++
lib/data.c | 25 +++++++++++++--
lib/debug.c | 1 +
lib/parse.c | 68 ++++++++++++++++++++++++++++++++++++-----
lib/print.c | 39 +++++++++++++++++++++--
lib/session.c | 8 +++++
8 files changed, 141 insertions(+), 13 deletions(-)
diff --git a/include/libipset/data.h b/include/libipset/data.h
index ca21890..0314cfb 100644
--- a/include/libipset/data.h
+++ b/include/libipset/data.h
@@ -37,6 +37,7 @@ enum ipset_opt {
IPSET_OPT_RESIZE,
IPSET_OPT_SIZE,
IPSET_OPT_FORCEADD,
+ IPSET_OPT_NETMASK_MASK,
/* Create-specific options, filled out by the kernel */
IPSET_OPT_ELEMENTS,
IPSET_OPT_REFERENCES,
@@ -66,6 +67,7 @@ enum ipset_opt {
IPSET_OPT_SKBMARK,
IPSET_OPT_SKBPRIO,
IPSET_OPT_SKBQUEUE,
+ IPSET_OPT_NETMASK_FLAG,
/* Internal options */
IPSET_OPT_FLAGS = 48, /* IPSET_FLAG_EXIST| */
IPSET_OPT_CADT_FLAGS, /* IPSET_FLAG_BEFORE| */
@@ -101,7 +103,8 @@ enum ipset_opt {
| IPSET_FLAG(IPSET_OPT_COUNTERS)\
| IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)\
| IPSET_FLAG(IPSET_OPT_FORCEADD)\
- | IPSET_FLAG(IPSET_OPT_SKBINFO))
+ | IPSET_FLAG(IPSET_OPT_SKBINFO)\
+ | IPSET_FLAG(IPSET_OPT_NETMASK_MASK))
#define IPSET_ADT_FLAGS \
(IPSET_FLAG(IPSET_OPT_IP) \
diff --git a/include/libipset/linux_ip_set.h b/include/libipset/linux_ip_set.h
index def91b9..4f93886 100644
--- a/include/libipset/linux_ip_set.h
+++ b/include/libipset/linux_ip_set.h
@@ -84,6 +84,7 @@ enum {
IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */
IPSET_ATTR_MARK, /* 10 */
IPSET_ATTR_MARKMASK, /* 11 */
+ IPSET_ATTR_NETMASK_MASK,/* 12 */
/* Reserve empty slots */
IPSET_ATTR_CADT_MAX = 16,
/* Create-only specific attributes */
@@ -199,6 +200,8 @@ enum ipset_cadt_flags {
IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD),
IPSET_FLAG_BIT_WITH_SKBINFO = 6,
IPSET_FLAG_WITH_SKBINFO = (1 << IPSET_FLAG_BIT_WITH_SKBINFO),
+ IPSET_FLAG_BIT_WITH_NETMASK = 7,
+ IPSET_FLAG_WITH_NETMASK = (1 << IPSET_FLAG_BIT_WITH_NETMASK),
IPSET_FLAG_CADT_MAX = 15,
};
@@ -206,6 +209,8 @@ enum ipset_cadt_flags {
enum ipset_create_flags {
IPSET_CREATE_FLAG_BIT_FORCEADD = 0,
IPSET_CREATE_FLAG_FORCEADD = (1 << IPSET_CREATE_FLAG_BIT_FORCEADD),
+ IPSET_CREATE_FLAG_BIT_NETMASK = 1,
+ IPSET_CREATE_FLAG_NETMASK = (1 << IPSET_CREATE_FLAG_BIT_NETMASK),
IPSET_CREATE_FLAG_BIT_MAX = 7,
};
diff --git a/include/libipset/print.h b/include/libipset/print.h
index 2103ce1..f9e77d3 100644
--- a/include/libipset/print.h
+++ b/include/libipset/print.h
@@ -74,6 +74,9 @@ extern int ipset_print_flag(char *buf, unsigned int len,
extern int ipset_print_elem(char *buf, unsigned int len,
const struct ipset_data *data,
enum ipset_opt opt, uint8_t env);
+extern int ipset_print_netmask(char *buf, unsigned int len,
+ const struct ipset_data *data,
+ enum ipset_opt opt, uint8_t env);
#define ipset_print_portnum ipset_print_number
diff --git a/lib/data.c b/lib/data.c
index 8372a2f..951a124 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -24,6 +24,11 @@
* We always store the data in host order, *except* IP addresses.
*/
+struct ipset_netmask {
+ uint8_t cidr;
+ union nf_inet_addr mask;
+};
+
struct ipset_data {
/* Option bits: which fields are set */
uint64_t bits;
@@ -51,7 +56,7 @@ struct ipset_data {
struct {
uint8_t probes;
uint8_t resize;
- uint8_t netmask;
+ struct ipset_netmask netmask;
uint32_t hashsize;
uint32_t maxelem;
uint32_t markmask;
@@ -295,7 +300,13 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
data->create.markmask = *(const uint32_t *) value;
break;
case IPSET_OPT_NETMASK:
- data->create.netmask = *(const uint8_t *) value;
+ data->create.netmask.cidr = *(const uint8_t *) value;
+ break;
+ case IPSET_OPT_NETMASK_MASK:
+ if (!(data->family == NFPROTO_IPV4 ||
+ data->family == NFPROTO_IPV6))
+ return -1;
+ copy_addr(data->family, &data->create.netmask.mask, value);
break;
case IPSET_OPT_PROBES:
data->create.probes = *(const uint8_t *) value;
@@ -318,6 +329,9 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
case IPSET_OPT_SKBINFO:
cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_SKBINFO);
break;
+ case IPSET_OPT_NETMASK_FLAG:
+ cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_NETMASK);
+ break;
/* Create-specific options, filled out by the kernel */
case IPSET_OPT_ELEMENTS:
data->create.elements = *(const uint32_t *) value;
@@ -495,7 +509,9 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt)
case IPSET_OPT_MARKMASK:
return &data->create.markmask;
case IPSET_OPT_NETMASK:
- return &data->create.netmask;
+ return &data->create.netmask.cidr;
+ case IPSET_OPT_NETMASK_MASK:
+ return &data->create.netmask.mask;
case IPSET_OPT_PROBES:
return &data->create.probes;
case IPSET_OPT_RESIZE:
@@ -558,6 +574,7 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt)
case IPSET_OPT_CREATE_COMMENT:
case IPSET_OPT_FORCEADD:
case IPSET_OPT_SKBINFO:
+ case IPSET_OPT_NETMASK_FLAG:
return &data->cadt_flags;
default:
return NULL;
@@ -581,6 +598,7 @@ ipset_data_sizeof(enum ipset_opt opt, uint8_t family)
case IPSET_OPT_IP_TO:
case IPSET_OPT_IP2:
case IPSET_OPT_IP2_TO:
+ case IPSET_OPT_NETMASK_MASK:
return family == NFPROTO_IPV4 ? sizeof(uint32_t)
: sizeof(struct in6_addr);
case IPSET_OPT_MARK:
@@ -623,6 +641,7 @@ ipset_data_sizeof(enum ipset_opt opt, uint8_t family)
case IPSET_OPT_NOMATCH:
case IPSET_OPT_COUNTERS:
case IPSET_OPT_FORCEADD:
+ case IPSET_OPT_NETMASK_FLAG:
return sizeof(uint32_t);
case IPSET_OPT_ADT_COMMENT:
return IPSET_MAX_COMMENT_SIZE + 1;
diff --git a/lib/debug.c b/lib/debug.c
index 6f831ec..a32f709 100644
--- a/lib/debug.c
+++ b/lib/debug.c
@@ -40,6 +40,7 @@ static const struct ipset_attrname createattr2name[] = {
[IPSET_ATTR_MAXELEM] = { .name = "MAXELEM" },
[IPSET_ATTR_MARKMASK] = { .name = "MARKMASK" },
[IPSET_ATTR_NETMASK] = { .name = "NETMASK" },
+ [IPSET_ATTR_NETMASK_MASK] = { .name = "NETMASK_MASK" },
[IPSET_ATTR_PROBES] = { .name = "PROBES" },
[IPSET_ATTR_RESIZE] = { .name = "RESIZE" },
[IPSET_ATTR_SIZE] = { .name = "SIZE" },
diff --git a/lib/parse.c b/lib/parse.c
index 88d2888..5c41c37 100644
--- a/lib/parse.c
+++ b/lib/parse.c
@@ -1654,7 +1654,35 @@ ipset_parse_uint8(struct ipset_session *session,
}
/**
+ * ipset_cidr_to_mask - convert cidr value to mask stored in nf_inet_addr
+ * @addr: store resulting mask here
+ * @cidr: value to convert to mask
+ * @family: INET family type
+ *
+ * Parse cidr value and convert it into a mask stored in an nf_inet_addr.
+ */
+static void
+ipset_cidr_to_mask(union nf_inet_addr *addr, uint8_t cidr, uint8_t family)
+{
+ uint8_t i;
+ uint8_t addrsize = (family == NFPROTO_IPV4) ? 1 : 4;
+
+ for (i=0; i < addrsize; i++) {
+ if (!cidr) {
+ addr->all[i] = 0;
+ } else if (cidr >= 32) {
+ addr->all[i] = 0xffffffff;
+ cidr -= 32;
+ } else {
+ addr->all[i] = htonl(~((1 << (32 - cidr)) - 1));
+ break;
+ }
+ }
+}
+
+/**
* ipset_parse_netmask - parse string as a CIDR netmask value
+ * or netmask value
* @session: session structure
* @opt: option kind of the data
* @str: string to parse
@@ -1669,12 +1697,13 @@ int
ipset_parse_netmask(struct ipset_session *session,
enum ipset_opt opt, const char *str)
{
- uint8_t family, cidr;
+ uint8_t family, cidr = 0;
struct ipset_data *data;
int err = 0;
+ union nf_inet_addr netmask = {};
assert(session);
- assert(opt == IPSET_OPT_NETMASK);
+ assert(opt == IPSET_OPT_NETMASK_MASK || opt == IPSET_OPT_NETMASK);
assert(str);
data = ipset_session_data(session);
@@ -1684,16 +1713,41 @@ ipset_parse_netmask(struct ipset_session *session,
ipset_data_set(data, IPSET_OPT_FAMILY, &family);
}
+ /* Try to parse input as CIDR first */
err = string_to_cidr(session, str, 1,
family == NFPROTO_IPV4 ? 32 : 128,
&cidr);
- if (err)
- return syntax_err("netmask is out of the inclusive range "
- "of 1-%u",
- family == NFPROTO_IPV4 ? 32 : 128);
+ if (opt == IPSET_OPT_NETMASK) {
+ if (err)
+ return syntax_err("netmask is out of the inclusive range "
+ "of 1-%u",
+ family == NFPROTO_IPV4 ? 32 : 128);
+
+ return ipset_data_set(data, opt, &cidr);
+ } else {
+
+ /* If that fails, attempt to parse as an IP addr */
+ if (err) {
+ /* Store mask value as input by user */
+ err = parse_ipaddr(session, opt, str, family);
+ if (err)
+ return err;
- return ipset_data_set(data, opt, &cidr);
+ /* Check if it's a CIDR and store if it is */
+ netmask = *(const union nf_inet_addr *) ipset_data_get(data, IPSET_OPT_NETMASK_MASK);
+ } else {
+ ipset_cidr_to_mask(&netmask, cidr, family);
+
+ err = ipset_data_set(data, opt, &netmask);
+ if (err)
+ return err;
+ }
+
+ ipset_data_set(data, IPSET_OPT_NETMASK_FLAG, &family);
+
+ return ipset_data_set(data, IPSET_OPT_NETMASK, &cidr);
+ }
}
/**
diff --git a/lib/print.c b/lib/print.c
index 7dd229e..cc450c6 100644
--- a/lib/print.c
+++ b/lib/print.c
@@ -241,6 +241,39 @@ SNPRINTF_IP(32, 4)
SNPRINTF_IP(128, 6)
/**
+ * ipset_print_netmask - print netmask in either CIDR or address to string
+ * @buf: printing buffer
+ * @len: length of available buffer space
+ * @data: data blob
+ * @opt: the option kind
+ * @env: environment flags
+ *
+ * If the netmask can be represented as a CIDR print that, otherwise print
+ * the mask value.
+ *
+ * Return length of printed string or error size.
+ */
+int
+ipset_print_netmask(char *buf, unsigned int len,
+ const struct ipset_data *data, enum ipset_opt opt,
+ uint8_t env)
+{
+ uint8_t cidr;
+
+ assert(buf);
+ assert(len > 0);
+ assert(data);
+ assert(opt == IPSET_OPT_NETMASK_MASK);
+
+ cidr = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_NETMASK);
+
+ if (cidr)
+ return snprintf(buf, len, "%u", cidr);
+ else
+ return ipset_print_ip(buf, len, data, opt, env);
+}
+
+/**
* ipset_print_ip - print IPv4|IPv6 address to string
* @buf: printing buffer
* @len: length of available buffer space
@@ -265,7 +298,7 @@ ipset_print_ip(char *buf, unsigned int len,
assert(buf);
assert(len > 0);
assert(data);
- assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2);
+ assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2 || opt == IPSET_OPT_NETMASK_MASK);
D("len: %u", len);
family = ipset_data_family(data);
@@ -944,7 +977,6 @@ ipset_print_data(char *buf, unsigned int len,
case IPSET_OPT_HASHSIZE:
case IPSET_OPT_MAXELEM:
case IPSET_OPT_MARKMASK:
- case IPSET_OPT_NETMASK:
case IPSET_OPT_PROBES:
case IPSET_OPT_RESIZE:
case IPSET_OPT_TIMEOUT:
@@ -953,6 +985,9 @@ ipset_print_data(char *buf, unsigned int len,
case IPSET_OPT_SIZE:
size = ipset_print_number(buf, len, data, opt, env);
break;
+ case IPSET_OPT_NETMASK_MASK:
+ size = ipset_print_netmask(buf, len, data, opt, env);
+ break;
default:
return -1;
}
diff --git a/lib/session.c b/lib/session.c
index 1bdaaa7..55eab83 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -414,6 +414,10 @@ static const struct ipset_attr_policy create_attrs[] = {
.type = MNL_TYPE_U32,
.opt = IPSET_OPT_MEMSIZE,
},
+ [IPSET_ATTR_NETMASK_MASK] = {
+ .type = MNL_TYPE_NESTED,
+ .opt = IPSET_OPT_NETMASK_MASK,
+ },
};
static const struct ipset_attr_policy adt_attrs[] = {
@@ -1494,6 +1498,10 @@ rawdata2attr(struct ipset_session *session, struct nlmsghdr *nlh,
if (attr->type == MNL_TYPE_NESTED) {
/* IP addresses */
struct nlattr *nested;
+
+ if (type == IPSET_ATTR_NETMASK_MASK)
+ family = ipset_data_family(session->data);
+
int atype = family == NFPROTO_IPV4 ? IPSET_ATTR_IPADDR_IPV4
: IPSET_ATTR_IPADDR_IPV6;
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/5] ipset: hash:ip: add support for new netmask types
2017-03-21 18:39 [PATCH 0/5] ipset: Extend netmask support for userspace Josh Hunt
2017-03-21 18:39 ` [PATCH 1/5] ipset: netmask: expand to support cidr and full mask Josh Hunt
@ 2017-03-21 18:39 ` Josh Hunt
2017-03-21 18:39 ` [PATCH 3/5] ipset: hash:ipport: netmask support Josh Hunt
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Josh Hunt @ 2017-03-21 18:39 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, coreteam, Josh Hunt
Uses new netmask support added in previous commit to allow user to
specify cidr, netmask, or wildcard mask as arguments to the netmask
parameter at creation time.
Signed-off-by: Josh Hunt <johunt@akamai.com>
---
lib/ipset_hash_ip.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/lib/ipset_hash_ip.c b/lib/ipset_hash_ip.c
index 2bff34f..36afc59 100644
--- a/lib/ipset_hash_ip.c
+++ b/lib/ipset_hash_ip.c
@@ -669,6 +669,171 @@ static struct ipset_type ipset_hash_ip4 = {
.description = "skbinfo support",
};
+/* Parse commandline arguments */
+static const struct ipset_arg hash_ip_create_args5[] = {
+ { .name = { "family", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family, .print = ipset_print_family,
+ },
+ /* Alias: family inet */
+ { .name = { "-4", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ /* Alias: family inet6 */
+ { .name = { "-6", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ { .name = { "hashsize", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "maxelem", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "netmask", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NETMASK_MASK,
+ .parse = ipset_parse_netmask, .print = ipset_print_netmask,
+ },
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
+ },
+ { .name = { "counters", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ { .name = { "comment", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ { .name = { "forceadd", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FORCEADD,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ { .name = { "skbinfo", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_SKBINFO,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ /* Ignored options: backward compatibilty */
+ { .name = { "probes", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
+ .parse = ipset_parse_ignored, .print = ipset_print_number,
+ },
+ { .name = { "resize", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
+ .parse = ipset_parse_ignored, .print = ipset_print_number,
+ },
+ { .name = { "gc", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_GC,
+ .parse = ipset_parse_ignored, .print = ipset_print_number,
+ },
+ { },
+};
+
+static const struct ipset_arg hash_ip_add_args5[] = {
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
+ },
+ { .name = { "packets", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
+ .parse = ipset_parse_uint64, .print = ipset_print_number,
+ },
+ { .name = { "bytes", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
+ .parse = ipset_parse_uint64, .print = ipset_print_number,
+ },
+ { .name = { "comment", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_ADT_COMMENT,
+ .parse = ipset_parse_comment, .print = ipset_print_comment,
+ },
+ { .name = { "skbmark", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBMARK,
+ .parse = ipset_parse_skbmark, .print = ipset_print_skbmark,
+ },
+ { .name = { "skbprio", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBPRIO,
+ .parse = ipset_parse_skbprio, .print = ipset_print_skbprio,
+ },
+ { .name = { "skbqueue", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBQUEUE,
+ .parse = ipset_parse_uint16, .print = ipset_print_number,
+ },
+ { },
+};
+
+
+static const char hash_ip_usage5[] =
+"create SETNAME hash:ip\n"
+" [family inet|inet6]\n"
+" [hashsize VALUE] [maxelem VALUE]\n"
+" [netmask CIDR or MASK] [timeout VALUE]\n"
+" [counters] [comment] [forceadd] [skbinfo]\n"
+"add SETNAME IP [timeout VALUE]\n"
+" [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+" [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del SETNAME IP\n"
+"test SETNAME IP\n\n"
+"where depending on the INET family\n"
+" IP is a valid IPv4 or IPv6 address (or hostname),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
+" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
+" is supported for IPv4.\n";
+
+static struct ipset_type ipset_hash_ip5 = {
+ .name = "hash:ip",
+ .alias = { "iphash", NULL },
+ .revision = 5,
+ .family = NFPROTO_IPSET_IPV46,
+ .dimension = IPSET_DIM_ONE,
+ .elem = {
+ [IPSET_DIM_ONE - 1] = {
+ .parse = ipset_parse_ip4_single6,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP
+ },
+ },
+ .args = {
+ [IPSET_CREATE] = hash_ip_create_args5,
+ [IPSET_ADD] = hash_ip_add_args5,
+ },
+ .mandatory = {
+ [IPSET_CREATE] = 0,
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP),
+ },
+ .full = {
+ [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+ | IPSET_FLAG(IPSET_OPT_MAXELEM)
+ | IPSET_FLAG(IPSET_OPT_NETMASK)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+ | IPSET_FLAG(IPSET_OPT_COUNTERS)
+ | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+ | IPSET_FLAG(IPSET_OPT_FORCEADD)
+ | IPSET_FLAG(IPSET_OPT_SKBINFO)
+ | IPSET_FLAG(IPSET_OPT_NETMASK_MASK),
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+ | IPSET_FLAG(IPSET_OPT_PACKETS)
+ | IPSET_FLAG(IPSET_OPT_BYTES)
+ | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+ | IPSET_FLAG(IPSET_OPT_SKBMARK)
+ | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+ | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_IP_TO),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP),
+ },
+
+ .usage = hash_ip_usage5,
+ .description = "netmask wildcardmask support",
+};
+
void _init(void);
void _init(void)
{
@@ -677,4 +842,5 @@ void _init(void)
ipset_type_add(&ipset_hash_ip2);
ipset_type_add(&ipset_hash_ip3);
ipset_type_add(&ipset_hash_ip4);
+ ipset_type_add(&ipset_hash_ip5);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/5] ipset: hash:ipport: netmask support
2017-03-21 18:39 [PATCH 0/5] ipset: Extend netmask support for userspace Josh Hunt
2017-03-21 18:39 ` [PATCH 1/5] ipset: netmask: expand to support cidr and full mask Josh Hunt
2017-03-21 18:39 ` [PATCH 2/5] ipset: hash:ip: add support for new netmask types Josh Hunt
@ 2017-03-21 18:39 ` Josh Hunt
2017-03-27 20:12 ` Jozsef Kadlecsik
2017-03-21 18:39 ` [PATCH 4/5] hash:ip: add new netmask support to man page Josh Hunt
2017-03-21 18:39 ` [PATCH 5/5] hash:ip,port: add " Josh Hunt
4 siblings, 1 reply; 8+ messages in thread
From: Josh Hunt @ 2017-03-21 18:39 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, coreteam, Josh Hunt
Adds netmask support to hash:ipport sets.
Signed-off-by: Josh Hunt <johunt@akamai.com>
---
lib/ipset_hash_ipport.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 194 insertions(+)
diff --git a/lib/ipset_hash_ipport.c b/lib/ipset_hash_ipport.c
index 2166922..a2cf79e 100644
--- a/lib/ipset_hash_ipport.c
+++ b/lib/ipset_hash_ipport.c
@@ -787,6 +787,199 @@ static struct ipset_type ipset_hash_ipport5 = {
.description = "skbinfo support",
};
+/* Parse commandline arguments */
+static const struct ipset_arg hash_ipport_create_args6[] = {
+ { .name = { "family", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family, .print = ipset_print_family,
+ },
+ /* Alias: family inet */
+ { .name = { "-4", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ /* Alias: family inet6 */
+ { .name = { "-6", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ { .name = { "hashsize", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "maxelem", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
+ },
+ { .name = { "counters", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ { .name = { "comment", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ { .name = { "forceadd", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FORCEADD,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ { .name = { "skbinfo", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_SKBINFO,
+ .parse = ipset_parse_flag, .print = ipset_print_flag,
+ },
+ { .name = { "netmask", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NETMASK_MASK,
+ .parse = ipset_parse_netmask, .print = ipset_print_netmask,
+ },
+ /* Backward compatibility */
+ { .name = { "probes", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
+ .parse = ipset_parse_ignored, .print = ipset_print_number,
+ },
+ { .name = { "resize", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
+ .parse = ipset_parse_ignored, .print = ipset_print_number,
+ },
+ { .name = { "from", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
+ .parse = ipset_parse_ignored,
+ },
+ { .name = { "to", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
+ .parse = ipset_parse_ignored,
+ },
+ { .name = { "network", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
+ .parse = ipset_parse_ignored,
+ },
+ { },
+};
+
+static const struct ipset_arg hash_ipport_add_args6[] = {
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
+ },
+ { .name = { "packets", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
+ .parse = ipset_parse_uint64, .print = ipset_print_number,
+ },
+ { .name = { "bytes", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
+ .parse = ipset_parse_uint64, .print = ipset_print_number,
+ },
+ { .name = { "comment", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_ADT_COMMENT,
+ .parse = ipset_parse_comment, .print = ipset_print_comment,
+ },
+ { .name = { "skbmark", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBMARK,
+ .parse = ipset_parse_skbmark, .print = ipset_print_skbmark,
+ },
+ { .name = { "skbprio", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBPRIO,
+ .parse = ipset_parse_skbprio, .print = ipset_print_skbprio,
+ },
+ { .name = { "skbqueue", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBQUEUE,
+ .parse = ipset_parse_uint16, .print = ipset_print_number,
+ },
+ { },
+};
+
+static const char hash_ipport_usage6[] =
+"create SETNAME hash:ip,port\n"
+" [family inet|inet6]\n"
+" [hashsize VALUE] [maxelem VALUE]\n"
+" [timeout VALUE] [counters] [comment]\n"
+" [forceadd] [skbinfo] [netmask CIDR or MASK]\n"
+"add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
+" [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
+" [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
+"del SETNAME IP,PROTO:PORT\n"
+"test SETNAME IP,PROTO:PORT\n\n"
+"where depending on the INET family\n"
+" IP is a valid IPv4 or IPv6 address (or hostname).\n"
+" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
+" is supported for IPv4.\n"
+" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
+" port range is supported both for IPv4 and IPv6.\n";
+
+static struct ipset_type ipset_hash_ipport6 = {
+ .name = "hash:ip,port",
+ .alias = { "ipporthash", NULL },
+ .revision = 6,
+ .family = NFPROTO_IPSET_IPV46,
+ .dimension = IPSET_DIM_TWO,
+ .elem = {
+ [IPSET_DIM_ONE - 1] = {
+ .parse = ipset_parse_ip4_single6,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP
+ },
+ [IPSET_DIM_TWO - 1] = {
+ .parse = ipset_parse_proto_port,
+ .print = ipset_print_proto_port,
+ .opt = IPSET_OPT_PORT
+ },
+ },
+ .args = {
+ [IPSET_CREATE] = hash_ipport_create_args6,
+ [IPSET_ADD] = hash_ipport_add_args6,
+ },
+ .mandatory = {
+ [IPSET_CREATE] = 0,
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ },
+ .full = {
+ [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+ | IPSET_FLAG(IPSET_OPT_MAXELEM)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+ | IPSET_FLAG(IPSET_OPT_COUNTERS)
+ | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
+ | IPSET_FLAG(IPSET_OPT_FORCEADD)
+ | IPSET_FLAG(IPSET_OPT_SKBINFO)
+ | IPSET_FLAG(IPSET_OPT_NETMASK)
+ | IPSET_FLAG(IPSET_OPT_NETMASK_MASK),
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PORT_TO)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+ | IPSET_FLAG(IPSET_OPT_PACKETS)
+ | IPSET_FLAG(IPSET_OPT_BYTES)
+ | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
+ | IPSET_FLAG(IPSET_OPT_SKBMARK)
+ | IPSET_FLAG(IPSET_OPT_SKBPRIO)
+ | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_IP_TO)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PORT_TO)
+ | IPSET_FLAG(IPSET_OPT_PROTO),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO),
+ },
+
+ .usage = hash_ipport_usage6,
+ .usagefn = ipset_port_usage,
+ .description = "netmask support",
+};
+
void _init(void);
void _init(void)
{
@@ -795,4 +988,5 @@ void _init(void)
ipset_type_add(&ipset_hash_ipport3);
ipset_type_add(&ipset_hash_ipport4);
ipset_type_add(&ipset_hash_ipport5);
+ ipset_type_add(&ipset_hash_ipport6);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/5] hash:ip: add new netmask support to man page
2017-03-21 18:39 [PATCH 0/5] ipset: Extend netmask support for userspace Josh Hunt
` (2 preceding siblings ...)
2017-03-21 18:39 ` [PATCH 3/5] ipset: hash:ipport: netmask support Josh Hunt
@ 2017-03-21 18:39 ` Josh Hunt
2017-03-21 18:39 ` [PATCH 5/5] hash:ip,port: add " Josh Hunt
4 siblings, 0 replies; 8+ messages in thread
From: Josh Hunt @ 2017-03-21 18:39 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, coreteam, Josh Hunt
Updates hash:ip create options to list new mask param to netmask,
describe how it works, and provide examples.
Signed-off-by: Josh Hunt <johunt@akamai.com>
---
src/ipset.8 | 43 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/src/ipset.8 b/src/ipset.8
index cd8c3ad..56cc9ea 100644
--- a/src/ipset.8
+++ b/src/ipset.8
@@ -504,7 +504,7 @@ The \fBhash:ip\fR set type uses a hash to store IP host addresses (default) or
network addresses. Zero valued IP address cannot be stored in a \fBhash:ip\fR
type of set.
.PP
-\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBnetmask\fP \fIcidr\fP ] [ \fBtimeout\fR \fIvalue\fR ] [ \fBcounters\fP ] [ \fBcomment\fP ] [ \fBskbinfo\fP ]
+\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBnetmask\fP { \fIcidr\fP | \fImask\fP } ] [ \fBtimeout\fR \fIvalue\fR ] [ \fBcounters\fP ] [ \fBcomment\fP ] [ \fBskbinfo\fP ]
.PP
\fIADD\-ENTRY\fR := \fIipaddr\fR
.PP
@@ -516,12 +516,17 @@ type of set.
.PP
Optional \fBcreate\fR options:
.TP
-\fBnetmask\fP \fIcidr\fP
-When the optional \fBnetmask\fP parameter specified, network addresses will be
-stored in the set instead of IP host addresses. The \fIcidr\fP prefix value must be
-between 1\-32 for IPv4 and between 1\-128 for IPv6. An IP address will be in the set
-if the network address, which is resulted by masking the address with the netmask,
-can be found in the set.
+\fBnetmask\fP { \fIcidr\fP | \fImask\fP }
+The optional \fBnetmask\fP parameter supports two different mask types: \fIcidr\fP,
+\fImask\fP.
+.TP
+\fIcidr\fP
+When the optional \fBnetmask\fP parameter is specified and a \fIcidr\fP argument is
+given, network addresses will be stored in the set instead of IP host addresses. The
+\fIcidr\fP prefix value must be between 1\-32 for IPv4 and between 1\-128 for IPv6.
+An IP address will be in the set if the network address, which is resulted by masking
+the address with the netmask, can be found in the set.
+.IP
Examples:
.IP
ipset create foo hash:ip netmask 30
@@ -529,6 +534,30 @@ ipset create foo hash:ip netmask 30
ipset add foo 192.168.1.0/24
.IP
ipset test foo 192.168.1.2
+.TP
+\fImask\fP
+A \fImask\fP argument to \fBnetmask\fP, like \fIcidr\fP, applies the defined mask
+against the address to be added to the set. The difference with \fImask\fP is that
+it can support conventional netmask values like 255.255.255.0 for IPv4 addresses,
+but it can also support wildcard masks. Allowing the user to define a \fImask\fP
+of any bits to apply to the address. Wildcard masks prove to be very useful for
+IPv6 addressing.
+.IP
+Conventional Mask Examples:
+.IP
+ipset create foo hash:ip netmask 255.255.255.0
+.IP
+ipset add foo 192.168.1.2
+.IP
+ipset test foo 192.168.1.20
+.IP
+Wildcard Mask Examples:
+.IP
+ipset create foo hash:ip family inet6 netmask ffff:ffff:ffff:0:0:ffff::
+.IP
+ipset add foo 1:2:3:4:5:6:7:8
+.IP
+ipset test foo 1:2:3:a:b:6:c:d
.SS hash:mac
The \fBhash:mac\fR set type uses a hash to store MAC addresses. Zero valued MAC addresses cannot be stored in a \fBhash:mac\fR
type of set.
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/5] hash:ip,port: add netmask support to man page
2017-03-21 18:39 [PATCH 0/5] ipset: Extend netmask support for userspace Josh Hunt
` (3 preceding siblings ...)
2017-03-21 18:39 ` [PATCH 4/5] hash:ip: add new netmask support to man page Josh Hunt
@ 2017-03-21 18:39 ` Josh Hunt
4 siblings, 0 replies; 8+ messages in thread
From: Josh Hunt @ 2017-03-21 18:39 UTC (permalink / raw)
To: kadlec; +Cc: netfilter-devel, coreteam, Josh Hunt
Adds netmask to hash:ip,port create options, describe how it works, and
provide examples.
Signed-off-by: Josh Hunt <johunt@akamai.com>
---
src/ipset.8 | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/src/ipset.8 b/src/ipset.8
index 56cc9ea..d0ca810 100644
--- a/src/ipset.8
+++ b/src/ipset.8
@@ -710,7 +710,7 @@ The \fBhash:ip,port\fR set type uses a hash to store IP address and port number
The port number is interpreted together with a protocol (default TCP) and zero
protocol number cannot be used.
.PP
-\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] [ \fBcounters\fP ] [ \fBcomment\fP ] [ \fBskbinfo\fP ]
+\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBnetmask\fP { \fIcidr\fP | \fImask\fP } ] [ \fBtimeout\fR \fIvalue\fR ] [ \fBcounters\fP ] [ \fBcomment\fP ] [ \fBskbinfo\fP ]
.PP
\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR
.PP
@@ -761,6 +761,51 @@ ipset add foo 192.168.1.1,udp:53
ipset add foo 192.168.1.1,vrrp:0
.IP
ipset test foo 192.168.1.1,80
+.TP
+Optional \fBcreate\fR options:
+.TP
+\fBnetmask\fP { \fIcidr\fP | \fImask\fP }
+The optional \fBnetmask\fP parameter supports two different mask types: \fIcidr\fP,
+\fImask\fP.
+.TP
+\fIcidr\fP
+When the optional \fBnetmask\fP parameter is specified and a \fIcidr\fP argument is
+given, network addresses will be stored in the set instead of IP host addresses. The
+\fIcidr\fP prefix value must be between 1\-32 for IPv4 and between 1\-128 for IPv6.
+An IP address will be in the set if the network address, which is resulted by masking
+the address with the netmask, can be found in the set.
+.IP
+Examples:
+.IP
+ipset create foo hash:ip,port netmask 30
+.IP
+ipset add foo 192.168.1.0/24,80
+.IP
+ipset test foo 192.168.1.2,80
+.TP
+\fImask\fP
+A \fImask\fP argument to \fBnetmask\fP, like \fIcidr\fP, applies the defined mask
+against the address to be added to the set. The difference with \fImask\fP is that
+it can support conventional netmask values like 255.255.255.0 for IPv4 addresses,
+but it can also support wildcard masks. Allowing the user to define a \fImask\fP
+of any bits to apply to the address. Wildcard masks prove to be very useful for
+IPv6 addressing.
+.IP
+Conventional Mask Examples:
+.IP
+ipset create foo hash:ip,port netmask 255.255.255.0
+.IP
+ipset add foo 192.168.1.2,22
+.IP
+ipset test foo 192.168.1.20,22
+.IP
+Wildcard Mask Examples:
+.IP
+ipset create foo hash:ip,port family inet6 netmask ffff:ffff:ffff:0:0:ffff::
+.IP
+ipset add foo 1:2:3:4:5:6:7:8,udp:53
+.IP
+ipset test foo 1:2:3:a:b:6:c:d,udp:53
.SS hash:net,port
The \fBhash:net,port\fR set type uses a hash to store different sized IP network
address and port pairs. The port number is interpreted together with a protocol
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/5] ipset: netmask: expand to support cidr and full mask
2017-03-21 18:39 ` [PATCH 1/5] ipset: netmask: expand to support cidr and full mask Josh Hunt
@ 2017-03-27 20:08 ` Jozsef Kadlecsik
0 siblings, 0 replies; 8+ messages in thread
From: Jozsef Kadlecsik @ 2017-03-27 20:08 UTC (permalink / raw)
To: Josh Hunt; +Cc: netfilter-devel, coreteam
On Tue, 21 Mar 2017, Josh Hunt wrote:
> Convert netmask to store cidr and netmask.
>
> Signed-off-by: Josh Hunt <johunt@akamai.com>
> ---
> include/libipset/data.h | 5 ++-
> include/libipset/linux_ip_set.h | 5 +++
> include/libipset/print.h | 3 ++
> lib/data.c | 25 +++++++++++++--
> lib/debug.c | 1 +
> lib/parse.c | 68 ++++++++++++++++++++++++++++++++++++-----
> lib/print.c | 39 +++++++++++++++++++++--
> lib/session.c | 8 +++++
> 8 files changed, 141 insertions(+), 13 deletions(-)
>
> diff --git a/include/libipset/data.h b/include/libipset/data.h
> index ca21890..0314cfb 100644
> --- a/include/libipset/data.h
> +++ b/include/libipset/data.h
> @@ -37,6 +37,7 @@ enum ipset_opt {
> IPSET_OPT_RESIZE,
> IPSET_OPT_SIZE,
> IPSET_OPT_FORCEADD,
> + IPSET_OPT_NETMASK_MASK,
> /* Create-specific options, filled out by the kernel */
> IPSET_OPT_ELEMENTS,
> IPSET_OPT_REFERENCES,
> @@ -66,6 +67,7 @@ enum ipset_opt {
> IPSET_OPT_SKBMARK,
> IPSET_OPT_SKBPRIO,
> IPSET_OPT_SKBQUEUE,
> + IPSET_OPT_NETMASK_FLAG,
> /* Internal options */
> IPSET_OPT_FLAGS = 48, /* IPSET_FLAG_EXIST| */
> IPSET_OPT_CADT_FLAGS, /* IPSET_FLAG_BEFORE| */
> @@ -101,7 +103,8 @@ enum ipset_opt {
> | IPSET_FLAG(IPSET_OPT_COUNTERS)\
> | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)\
> | IPSET_FLAG(IPSET_OPT_FORCEADD)\
> - | IPSET_FLAG(IPSET_OPT_SKBINFO))
> + | IPSET_FLAG(IPSET_OPT_SKBINFO)\
> + | IPSET_FLAG(IPSET_OPT_NETMASK_MASK))
>
> #define IPSET_ADT_FLAGS \
> (IPSET_FLAG(IPSET_OPT_IP) \
> diff --git a/include/libipset/linux_ip_set.h b/include/libipset/linux_ip_set.h
> index def91b9..4f93886 100644
> --- a/include/libipset/linux_ip_set.h
> +++ b/include/libipset/linux_ip_set.h
> @@ -84,6 +84,7 @@ enum {
> IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */
> IPSET_ATTR_MARK, /* 10 */
> IPSET_ATTR_MARKMASK, /* 11 */
> + IPSET_ATTR_NETMASK_MASK,/* 12 */
> /* Reserve empty slots */
> IPSET_ATTR_CADT_MAX = 16,
> /* Create-only specific attributes */
> @@ -199,6 +200,8 @@ enum ipset_cadt_flags {
> IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD),
> IPSET_FLAG_BIT_WITH_SKBINFO = 6,
> IPSET_FLAG_WITH_SKBINFO = (1 << IPSET_FLAG_BIT_WITH_SKBINFO),
> + IPSET_FLAG_BIT_WITH_NETMASK = 7,
> + IPSET_FLAG_WITH_NETMASK = (1 << IPSET_FLAG_BIT_WITH_NETMASK),
> IPSET_FLAG_CADT_MAX = 15,
> };
>
> @@ -206,6 +209,8 @@ enum ipset_cadt_flags {
> enum ipset_create_flags {
> IPSET_CREATE_FLAG_BIT_FORCEADD = 0,
> IPSET_CREATE_FLAG_FORCEADD = (1 << IPSET_CREATE_FLAG_BIT_FORCEADD),
> + IPSET_CREATE_FLAG_BIT_NETMASK = 1,
> + IPSET_CREATE_FLAG_NETMASK = (1 << IPSET_CREATE_FLAG_BIT_NETMASK),
> IPSET_CREATE_FLAG_BIT_MAX = 7,
> };
>
> diff --git a/include/libipset/print.h b/include/libipset/print.h
> index 2103ce1..f9e77d3 100644
> --- a/include/libipset/print.h
> +++ b/include/libipset/print.h
> @@ -74,6 +74,9 @@ extern int ipset_print_flag(char *buf, unsigned int len,
> extern int ipset_print_elem(char *buf, unsigned int len,
> const struct ipset_data *data,
> enum ipset_opt opt, uint8_t env);
> +extern int ipset_print_netmask(char *buf, unsigned int len,
> + const struct ipset_data *data,
> + enum ipset_opt opt, uint8_t env);
>
> #define ipset_print_portnum ipset_print_number
>
> diff --git a/lib/data.c b/lib/data.c
> index 8372a2f..951a124 100644
> --- a/lib/data.c
> +++ b/lib/data.c
> @@ -24,6 +24,11 @@
> * We always store the data in host order, *except* IP addresses.
> */
>
> +struct ipset_netmask {
> + uint8_t cidr;
> + union nf_inet_addr mask;
> +};
> +
> struct ipset_data {
> /* Option bits: which fields are set */
> uint64_t bits;
> @@ -51,7 +56,7 @@ struct ipset_data {
> struct {
> uint8_t probes;
> uint8_t resize;
> - uint8_t netmask;
> + struct ipset_netmask netmask;
> uint32_t hashsize;
> uint32_t maxelem;
> uint32_t markmask;
> @@ -295,7 +300,13 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
> data->create.markmask = *(const uint32_t *) value;
> break;
> case IPSET_OPT_NETMASK:
> - data->create.netmask = *(const uint8_t *) value;
> + data->create.netmask.cidr = *(const uint8_t *) value;
> + break;
> + case IPSET_OPT_NETMASK_MASK:
> + if (!(data->family == NFPROTO_IPV4 ||
> + data->family == NFPROTO_IPV6))
> + return -1;
> + copy_addr(data->family, &data->create.netmask.mask, value);
> break;
> case IPSET_OPT_PROBES:
> data->create.probes = *(const uint8_t *) value;
> @@ -318,6 +329,9 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
> case IPSET_OPT_SKBINFO:
> cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_SKBINFO);
> break;
> + case IPSET_OPT_NETMASK_FLAG:
> + cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_NETMASK);
> + break;
> /* Create-specific options, filled out by the kernel */
> case IPSET_OPT_ELEMENTS:
> data->create.elements = *(const uint32_t *) value;
> @@ -495,7 +509,9 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt)
> case IPSET_OPT_MARKMASK:
> return &data->create.markmask;
> case IPSET_OPT_NETMASK:
> - return &data->create.netmask;
> + return &data->create.netmask.cidr;
> + case IPSET_OPT_NETMASK_MASK:
> + return &data->create.netmask.mask;
> case IPSET_OPT_PROBES:
> return &data->create.probes;
> case IPSET_OPT_RESIZE:
> @@ -558,6 +574,7 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt)
> case IPSET_OPT_CREATE_COMMENT:
> case IPSET_OPT_FORCEADD:
> case IPSET_OPT_SKBINFO:
> + case IPSET_OPT_NETMASK_FLAG:
> return &data->cadt_flags;
> default:
> return NULL;
> @@ -581,6 +598,7 @@ ipset_data_sizeof(enum ipset_opt opt, uint8_t family)
> case IPSET_OPT_IP_TO:
> case IPSET_OPT_IP2:
> case IPSET_OPT_IP2_TO:
> + case IPSET_OPT_NETMASK_MASK:
> return family == NFPROTO_IPV4 ? sizeof(uint32_t)
> : sizeof(struct in6_addr);
> case IPSET_OPT_MARK:
> @@ -623,6 +641,7 @@ ipset_data_sizeof(enum ipset_opt opt, uint8_t family)
> case IPSET_OPT_NOMATCH:
> case IPSET_OPT_COUNTERS:
> case IPSET_OPT_FORCEADD:
> + case IPSET_OPT_NETMASK_FLAG:
> return sizeof(uint32_t);
> case IPSET_OPT_ADT_COMMENT:
> return IPSET_MAX_COMMENT_SIZE + 1;
> diff --git a/lib/debug.c b/lib/debug.c
> index 6f831ec..a32f709 100644
> --- a/lib/debug.c
> +++ b/lib/debug.c
> @@ -40,6 +40,7 @@ static const struct ipset_attrname createattr2name[] = {
> [IPSET_ATTR_MAXELEM] = { .name = "MAXELEM" },
> [IPSET_ATTR_MARKMASK] = { .name = "MARKMASK" },
> [IPSET_ATTR_NETMASK] = { .name = "NETMASK" },
> + [IPSET_ATTR_NETMASK_MASK] = { .name = "NETMASK_MASK" },
> [IPSET_ATTR_PROBES] = { .name = "PROBES" },
> [IPSET_ATTR_RESIZE] = { .name = "RESIZE" },
> [IPSET_ATTR_SIZE] = { .name = "SIZE" },
> diff --git a/lib/parse.c b/lib/parse.c
> index 88d2888..5c41c37 100644
> --- a/lib/parse.c
> +++ b/lib/parse.c
> @@ -1654,7 +1654,35 @@ ipset_parse_uint8(struct ipset_session *session,
> }
>
> /**
> + * ipset_cidr_to_mask - convert cidr value to mask stored in nf_inet_addr
> + * @addr: store resulting mask here
> + * @cidr: value to convert to mask
> + * @family: INET family type
> + *
> + * Parse cidr value and convert it into a mask stored in an nf_inet_addr.
> + */
> +static void
> +ipset_cidr_to_mask(union nf_inet_addr *addr, uint8_t cidr, uint8_t family)
> +{
> + uint8_t i;
> + uint8_t addrsize = (family == NFPROTO_IPV4) ? 1 : 4;
> +
> + for (i=0; i < addrsize; i++) {
> + if (!cidr) {
> + addr->all[i] = 0;
> + } else if (cidr >= 32) {
> + addr->all[i] = 0xffffffff;
> + cidr -= 32;
> + } else {
> + addr->all[i] = htonl(~((1 << (32 - cidr)) - 1));
> + break;
> + }
> + }
> +}
If either IPSET_ATTR_NETMASK or IPSET_ATTR_NETMASK_MASK is passed then
I think ipset_cidr_to_mask() is unnecessary.
> +/**
> * ipset_parse_netmask - parse string as a CIDR netmask value
> + * or netmask value
> * @session: session structure
> * @opt: option kind of the data
> * @str: string to parse
> @@ -1669,12 +1697,13 @@ int
> ipset_parse_netmask(struct ipset_session *session,
> enum ipset_opt opt, const char *str)
> {
> - uint8_t family, cidr;
> + uint8_t family, cidr = 0;
> struct ipset_data *data;
> int err = 0;
> + union nf_inet_addr netmask = {};
>
> assert(session);
> - assert(opt == IPSET_OPT_NETMASK);
> + assert(opt == IPSET_OPT_NETMASK_MASK || opt == IPSET_OPT_NETMASK);
> assert(str);
>
> data = ipset_session_data(session);
> @@ -1684,16 +1713,41 @@ ipset_parse_netmask(struct ipset_session *session,
> ipset_data_set(data, IPSET_OPT_FAMILY, &family);
> }
>
> + /* Try to parse input as CIDR first */
> err = string_to_cidr(session, str, 1,
> family == NFPROTO_IPV4 ? 32 : 128,
> &cidr);
>
> - if (err)
> - return syntax_err("netmask is out of the inclusive range "
> - "of 1-%u",
> - family == NFPROTO_IPV4 ? 32 : 128);
> + if (opt == IPSET_OPT_NETMASK) {
> + if (err)
> + return syntax_err("netmask is out of the inclusive range "
> + "of 1-%u",
> + family == NFPROTO_IPV4 ? 32 : 128);
> +
> + return ipset_data_set(data, opt, &cidr);
> + } else {
> +
> + /* If that fails, attempt to parse as an IP addr */
> + if (err) {
> + /* Store mask value as input by user */
> + err = parse_ipaddr(session, opt, str, family);
> + if (err)
> + return err;
>
> - return ipset_data_set(data, opt, &cidr);
> + /* Check if it's a CIDR and store if it is */
> + netmask = *(const union nf_inet_addr *) ipset_data_get(data, IPSET_OPT_NETMASK_MASK);
> + } else {
> + ipset_cidr_to_mask(&netmask, cidr, family);
> +
> + err = ipset_data_set(data, opt, &netmask);
> + if (err)
> + return err;
> + }
> +
> + ipset_data_set(data, IPSET_OPT_NETMASK_FLAG, &family);
> +
> + return ipset_data_set(data, IPSET_OPT_NETMASK, &cidr);
> + }
> }
The parser should work with IPSET_OPT_NETMASK only and depending on the
value, it should set either IPSET_OPT_NETMASK (cidr is parsed) or
both IPSET_OPT_NETMASK_MASK (wildcard mask is passed) and
IPSET_CREATE_FLAG_NETMASK.
> /**
> diff --git a/lib/print.c b/lib/print.c
> index 7dd229e..cc450c6 100644
> --- a/lib/print.c
> +++ b/lib/print.c
> @@ -241,6 +241,39 @@ SNPRINTF_IP(32, 4)
> SNPRINTF_IP(128, 6)
>
> /**
> + * ipset_print_netmask - print netmask in either CIDR or address to string
> + * @buf: printing buffer
> + * @len: length of available buffer space
> + * @data: data blob
> + * @opt: the option kind
> + * @env: environment flags
> + *
> + * If the netmask can be represented as a CIDR print that, otherwise print
> + * the mask value.
> + *
> + * Return length of printed string or error size.
> + */
> +int
> +ipset_print_netmask(char *buf, unsigned int len,
> + const struct ipset_data *data, enum ipset_opt opt,
> + uint8_t env)
> +{
> + uint8_t cidr;
> +
> + assert(buf);
> + assert(len > 0);
> + assert(data);
> + assert(opt == IPSET_OPT_NETMASK_MASK);
> +
> + cidr = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_NETMASK);
> +
> + if (cidr)
> + return snprintf(buf, len, "%u", cidr);
> + else
> + return ipset_print_ip(buf, len, data, opt, env);
> +}
> +
> +/**
> * ipset_print_ip - print IPv4|IPv6 address to string
> * @buf: printing buffer
> * @len: length of available buffer space
> @@ -265,7 +298,7 @@ ipset_print_ip(char *buf, unsigned int len,
> assert(buf);
> assert(len > 0);
> assert(data);
> - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2);
> + assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2 || opt == IPSET_OPT_NETMASK_MASK);
>
> D("len: %u", len);
> family = ipset_data_family(data);
> @@ -944,7 +977,6 @@ ipset_print_data(char *buf, unsigned int len,
> case IPSET_OPT_HASHSIZE:
> case IPSET_OPT_MAXELEM:
> case IPSET_OPT_MARKMASK:
> - case IPSET_OPT_NETMASK:
> case IPSET_OPT_PROBES:
> case IPSET_OPT_RESIZE:
> case IPSET_OPT_TIMEOUT:
> @@ -953,6 +985,9 @@ ipset_print_data(char *buf, unsigned int len,
> case IPSET_OPT_SIZE:
> size = ipset_print_number(buf, len, data, opt, env);
> break;
> + case IPSET_OPT_NETMASK_MASK:
> + size = ipset_print_netmask(buf, len, data, opt, env);
> + break;
> default:
> return -1;
> }
> diff --git a/lib/session.c b/lib/session.c
> index 1bdaaa7..55eab83 100644
> --- a/lib/session.c
> +++ b/lib/session.c
> @@ -414,6 +414,10 @@ static const struct ipset_attr_policy create_attrs[] = {
> .type = MNL_TYPE_U32,
> .opt = IPSET_OPT_MEMSIZE,
> },
> + [IPSET_ATTR_NETMASK_MASK] = {
> + .type = MNL_TYPE_NESTED,
> + .opt = IPSET_OPT_NETMASK_MASK,
> + },
> };
>
> static const struct ipset_attr_policy adt_attrs[] = {
> @@ -1494,6 +1498,10 @@ rawdata2attr(struct ipset_session *session, struct nlmsghdr *nlh,
> if (attr->type == MNL_TYPE_NESTED) {
> /* IP addresses */
> struct nlattr *nested;
> +
> + if (type == IPSET_ATTR_NETMASK_MASK)
> + family = ipset_data_family(session->data);
> +
> int atype = family == NFPROTO_IPV4 ? IPSET_ATTR_IPADDR_IPV4
> : IPSET_ATTR_IPADDR_IPV6;
>
> --
> 1.9.1
Best regards,
Jozsef
-
E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
H-1525 Budapest 114, POB. 49, Hungary
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/5] ipset: hash:ipport: netmask support
2017-03-21 18:39 ` [PATCH 3/5] ipset: hash:ipport: netmask support Josh Hunt
@ 2017-03-27 20:12 ` Jozsef Kadlecsik
0 siblings, 0 replies; 8+ messages in thread
From: Jozsef Kadlecsik @ 2017-03-27 20:12 UTC (permalink / raw)
To: Josh Hunt; +Cc: netfilter-devel, coreteam
On Tue, 21 Mar 2017, Josh Hunt wrote:
> Adds netmask support to hash:ipport sets.
>
> Signed-off-by: Josh Hunt <johunt@akamai.com>
> ---
> lib/ipset_hash_ipport.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 194 insertions(+)
>
> diff --git a/lib/ipset_hash_ipport.c b/lib/ipset_hash_ipport.c
> index 2166922..a2cf79e 100644
> --- a/lib/ipset_hash_ipport.c
> +++ b/lib/ipset_hash_ipport.c
> @@ -787,6 +787,199 @@ static struct ipset_type ipset_hash_ipport5 = {
> .description = "skbinfo support",
> };
>
> +/* Parse commandline arguments */
> +static const struct ipset_arg hash_ipport_create_args6[] = {
> + { .name = { "family", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
> + .parse = ipset_parse_family, .print = ipset_print_family,
> + },
> + /* Alias: family inet */
> + { .name = { "-4", NULL },
> + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
> + .parse = ipset_parse_family,
> + },
> + /* Alias: family inet6 */
> + { .name = { "-6", NULL },
> + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
> + .parse = ipset_parse_family,
> + },
> + { .name = { "hashsize", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
> + .parse = ipset_parse_uint32, .print = ipset_print_number,
> + },
> + { .name = { "maxelem", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
> + .parse = ipset_parse_uint32, .print = ipset_print_number,
> + },
> + { .name = { "timeout", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
> + .parse = ipset_parse_timeout, .print = ipset_print_number,
> + },
> + { .name = { "counters", NULL },
> + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS,
> + .parse = ipset_parse_flag, .print = ipset_print_flag,
> + },
> + { .name = { "comment", NULL },
> + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_CREATE_COMMENT,
> + .parse = ipset_parse_flag, .print = ipset_print_flag,
> + },
> + { .name = { "forceadd", NULL },
> + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FORCEADD,
> + .parse = ipset_parse_flag, .print = ipset_print_flag,
> + },
> + { .name = { "skbinfo", NULL },
> + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_SKBINFO,
> + .parse = ipset_parse_flag, .print = ipset_print_flag,
> + },
> + { .name = { "netmask", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NETMASK_MASK,
> + .parse = ipset_parse_netmask, .print = ipset_print_netmask,
With the modified parser you can use IPSET_OPT_NETMASK here - and the same
comment for the hash:ip,port type.
> + },
> + /* Backward compatibility */
> + { .name = { "probes", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
> + .parse = ipset_parse_ignored, .print = ipset_print_number,
> + },
> + { .name = { "resize", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE,
> + .parse = ipset_parse_ignored, .print = ipset_print_number,
> + },
> + { .name = { "from", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
> + .parse = ipset_parse_ignored,
> + },
> + { .name = { "to", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO,
> + .parse = ipset_parse_ignored,
> + },
> + { .name = { "network", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP,
> + .parse = ipset_parse_ignored,
> + },
> + { },
> +};
> +
> +static const struct ipset_arg hash_ipport_add_args6[] = {
> + { .name = { "timeout", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
> + .parse = ipset_parse_timeout, .print = ipset_print_number,
> + },
> + { .name = { "packets", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS,
> + .parse = ipset_parse_uint64, .print = ipset_print_number,
> + },
> + { .name = { "bytes", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES,
> + .parse = ipset_parse_uint64, .print = ipset_print_number,
> + },
> + { .name = { "comment", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_ADT_COMMENT,
> + .parse = ipset_parse_comment, .print = ipset_print_comment,
> + },
> + { .name = { "skbmark", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBMARK,
> + .parse = ipset_parse_skbmark, .print = ipset_print_skbmark,
> + },
> + { .name = { "skbprio", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBPRIO,
> + .parse = ipset_parse_skbprio, .print = ipset_print_skbprio,
> + },
> + { .name = { "skbqueue", NULL },
> + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SKBQUEUE,
> + .parse = ipset_parse_uint16, .print = ipset_print_number,
> + },
> + { },
> +};
> +
> +static const char hash_ipport_usage6[] =
> +"create SETNAME hash:ip,port\n"
> +" [family inet|inet6]\n"
> +" [hashsize VALUE] [maxelem VALUE]\n"
> +" [timeout VALUE] [counters] [comment]\n"
> +" [forceadd] [skbinfo] [netmask CIDR or MASK]\n"
> +"add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
> +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n"
> +" [skbmark VALUE] [skbprio VALUE] [skbqueue VALUE]\n"
> +"del SETNAME IP,PROTO:PORT\n"
> +"test SETNAME IP,PROTO:PORT\n\n"
> +"where depending on the INET family\n"
> +" IP is a valid IPv4 or IPv6 address (or hostname).\n"
> +" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
> +" is supported for IPv4.\n"
> +" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
> +" port range is supported both for IPv4 and IPv6.\n";
> +
> +static struct ipset_type ipset_hash_ipport6 = {
> + .name = "hash:ip,port",
> + .alias = { "ipporthash", NULL },
> + .revision = 6,
> + .family = NFPROTO_IPSET_IPV46,
> + .dimension = IPSET_DIM_TWO,
> + .elem = {
> + [IPSET_DIM_ONE - 1] = {
> + .parse = ipset_parse_ip4_single6,
> + .print = ipset_print_ip,
> + .opt = IPSET_OPT_IP
> + },
> + [IPSET_DIM_TWO - 1] = {
> + .parse = ipset_parse_proto_port,
> + .print = ipset_print_proto_port,
> + .opt = IPSET_OPT_PORT
> + },
> + },
> + .args = {
> + [IPSET_CREATE] = hash_ipport_create_args6,
> + [IPSET_ADD] = hash_ipport_add_args6,
> + },
> + .mandatory = {
> + [IPSET_CREATE] = 0,
> + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
> + | IPSET_FLAG(IPSET_OPT_PROTO)
> + | IPSET_FLAG(IPSET_OPT_PORT),
> + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
> + | IPSET_FLAG(IPSET_OPT_PROTO)
> + | IPSET_FLAG(IPSET_OPT_PORT),
> + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
> + | IPSET_FLAG(IPSET_OPT_PROTO)
> + | IPSET_FLAG(IPSET_OPT_PORT),
> + },
> + .full = {
> + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
> + | IPSET_FLAG(IPSET_OPT_MAXELEM)
> + | IPSET_FLAG(IPSET_OPT_TIMEOUT)
> + | IPSET_FLAG(IPSET_OPT_COUNTERS)
> + | IPSET_FLAG(IPSET_OPT_CREATE_COMMENT)
> + | IPSET_FLAG(IPSET_OPT_FORCEADD)
> + | IPSET_FLAG(IPSET_OPT_SKBINFO)
> + | IPSET_FLAG(IPSET_OPT_NETMASK)
> + | IPSET_FLAG(IPSET_OPT_NETMASK_MASK),
> + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
> + | IPSET_FLAG(IPSET_OPT_IP_TO)
> + | IPSET_FLAG(IPSET_OPT_PORT)
> + | IPSET_FLAG(IPSET_OPT_PORT_TO)
> + | IPSET_FLAG(IPSET_OPT_PROTO)
> + | IPSET_FLAG(IPSET_OPT_TIMEOUT)
> + | IPSET_FLAG(IPSET_OPT_PACKETS)
> + | IPSET_FLAG(IPSET_OPT_BYTES)
> + | IPSET_FLAG(IPSET_OPT_ADT_COMMENT)
> + | IPSET_FLAG(IPSET_OPT_SKBMARK)
> + | IPSET_FLAG(IPSET_OPT_SKBPRIO)
> + | IPSET_FLAG(IPSET_OPT_SKBQUEUE),
> + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
> + | IPSET_FLAG(IPSET_OPT_IP_TO)
> + | IPSET_FLAG(IPSET_OPT_PORT)
> + | IPSET_FLAG(IPSET_OPT_PORT_TO)
> + | IPSET_FLAG(IPSET_OPT_PROTO),
> + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
> + | IPSET_FLAG(IPSET_OPT_PORT)
> + | IPSET_FLAG(IPSET_OPT_PROTO),
> + },
> +
> + .usage = hash_ipport_usage6,
> + .usagefn = ipset_port_usage,
> + .description = "netmask support",
> +};
> +
> void _init(void);
> void _init(void)
> {
> @@ -795,4 +988,5 @@ void _init(void)
> ipset_type_add(&ipset_hash_ipport3);
> ipset_type_add(&ipset_hash_ipport4);
> ipset_type_add(&ipset_hash_ipport5);
> + ipset_type_add(&ipset_hash_ipport6);
> }
> --
> 1.9.1
Best regards,
Jozsef
-
E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
H-1525 Budapest 114, POB. 49, Hungary
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2017-03-27 20:12 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-21 18:39 [PATCH 0/5] ipset: Extend netmask support for userspace Josh Hunt
2017-03-21 18:39 ` [PATCH 1/5] ipset: netmask: expand to support cidr and full mask Josh Hunt
2017-03-27 20:08 ` Jozsef Kadlecsik
2017-03-21 18:39 ` [PATCH 2/5] ipset: hash:ip: add support for new netmask types Josh Hunt
2017-03-21 18:39 ` [PATCH 3/5] ipset: hash:ipport: netmask support Josh Hunt
2017-03-27 20:12 ` Jozsef Kadlecsik
2017-03-21 18:39 ` [PATCH 4/5] hash:ip: add new netmask support to man page Josh Hunt
2017-03-21 18:39 ` [PATCH 5/5] hash:ip,port: add " Josh Hunt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.