summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libipset/parse.h2
-rw-r--r--kernel/include/linux/netfilter/ipset/ip_set_timeout.h4
-rw-r--r--kernel/net/netfilter/xt_set.c15
-rw-r--r--lib/ipset_bitmap_ip.c4
-rw-r--r--lib/ipset_bitmap_ipmac.c4
-rw-r--r--lib/ipset_bitmap_port.c4
-rw-r--r--lib/ipset_hash_ip.c4
-rw-r--r--lib/ipset_hash_ipport.c4
-rw-r--r--lib/ipset_hash_ipportip.c4
-rw-r--r--lib/ipset_hash_ipportnet.c6
-rw-r--r--lib/ipset_hash_net.c6
-rw-r--r--lib/ipset_hash_netiface.c6
-rw-r--r--lib/ipset_hash_netport.c6
-rw-r--r--lib/ipset_list_set.c4
-rw-r--r--lib/parse.c31
15 files changed, 75 insertions, 29 deletions
diff --git a/include/libipset/parse.h b/include/libipset/parse.h
index d18e3cc..85aa291 100644
--- a/include/libipset/parse.h
+++ b/include/libipset/parse.h
@@ -72,6 +72,8 @@ extern int ipset_parse_after(struct ipset_session *session,
enum ipset_opt opt, const char *str);
extern int ipset_parse_setname(struct ipset_session *session,
enum ipset_opt opt, const char *str);
+extern int ipset_parse_timeout(struct ipset_session *session,
+ enum ipset_opt opt, const char *str);
extern int ipset_parse_uint32(struct ipset_session *session,
enum ipset_opt opt, const char *str);
extern int ipset_parse_uint8(struct ipset_session *session,
diff --git a/kernel/include/linux/netfilter/ipset/ip_set_timeout.h b/kernel/include/linux/netfilter/ipset/ip_set_timeout.h
index 4792320..9fba34f 100644
--- a/kernel/include/linux/netfilter/ipset/ip_set_timeout.h
+++ b/kernel/include/linux/netfilter/ipset/ip_set_timeout.h
@@ -30,6 +30,10 @@ ip_set_timeout_uget(struct nlattr *tb)
{
unsigned int timeout = ip_set_get_h32(tb);
+ /* Normalize to fit into jiffies */
+ if (timeout > UINT_MAX/1000)
+ timeout = UINT_MAX/1000;
+
/* Userspace supplied TIMEOUT parameter: adjust crazy size */
return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout;
}
diff --git a/kernel/net/netfilter/xt_set.c b/kernel/net/netfilter/xt_set.c
index 0ec8138..e97a31b 100644
--- a/kernel/net/netfilter/xt_set.c
+++ b/kernel/net/netfilter/xt_set.c
@@ -44,6 +44,14 @@ const struct ip_set_adt_opt n = { \
.cmdflags = cfs, \
.timeout = t, \
}
+#define ADT_MOPT(n, f, d, fs, cfs, t) \
+struct ip_set_adt_opt n = { \
+ .family = f, \
+ .dim = d, \
+ .flags = fs, \
+ .cmdflags = cfs, \
+ .timeout = t, \
+}
/* Revision 0 interface: backward compatible with netfilter/iptables */
@@ -296,11 +304,14 @@ static unsigned int
set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_set_info_target_v2 *info = par->targinfo;
- ADT_OPT(add_opt, par->family, info->add_set.dim,
- info->add_set.flags, info->flags, info->timeout);
+ ADT_MOPT(add_opt, par->family, info->add_set.dim,
+ info->add_set.flags, info->flags, info->timeout);
ADT_OPT(del_opt, par->family, info->del_set.dim,
info->del_set.flags, 0, UINT_MAX);
+ /* Normalize to fit into jiffies */
+ if (add_opt.timeout > UINT_MAX/1000)
+ add_opt.timeout = UINT_MAX/1000;
if (info->add_set.index != IPSET_INVALID_ID)
ip_set_add(info->add_set.index, skb, par, &add_opt);
if (info->del_set.index != IPSET_INVALID_ID)
diff --git a/lib/ipset_bitmap_ip.c b/lib/ipset_bitmap_ip.c
index 8b8220d..9e97b67 100644
--- a/lib/ipset_bitmap_ip.c
+++ b/lib/ipset_bitmap_ip.c
@@ -21,7 +21,7 @@ static const struct ipset_arg bitmap_ip_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Backward compatibility */
{ .name = { "from", NULL },
@@ -42,7 +42,7 @@ static const struct ipset_arg bitmap_ip_create_args[] = {
static const struct ipset_arg bitmap_ip_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
diff --git a/lib/ipset_bitmap_ipmac.c b/lib/ipset_bitmap_ipmac.c
index d822bf6..2a58019 100644
--- a/lib/ipset_bitmap_ipmac.c
+++ b/lib/ipset_bitmap_ipmac.c
@@ -17,7 +17,7 @@ static const struct ipset_arg bitmap_ipmac_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Backward compatibility */
{ .name = { "from", NULL },
@@ -38,7 +38,7 @@ static const struct ipset_arg bitmap_ipmac_create_args[] = {
static const struct ipset_arg bitmap_ipmac_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
diff --git a/lib/ipset_bitmap_port.c b/lib/ipset_bitmap_port.c
index 69be809..3101b22 100644
--- a/lib/ipset_bitmap_port.c
+++ b/lib/ipset_bitmap_port.c
@@ -17,7 +17,7 @@ static const struct ipset_arg bitmap_port_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Backward compatibility */
{ .name = { "from", NULL },
@@ -34,7 +34,7 @@ static const struct ipset_arg bitmap_port_create_args[] = {
static const struct ipset_arg bitmap_port_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
diff --git a/lib/ipset_hash_ip.c b/lib/ipset_hash_ip.c
index 912b991..e885b13 100644
--- a/lib/ipset_hash_ip.c
+++ b/lib/ipset_hash_ip.c
@@ -39,7 +39,7 @@ static const struct ipset_arg hash_ip_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Ignored options: backward compatibilty */
{ .name = { "probes", NULL },
@@ -60,7 +60,7 @@ static const struct ipset_arg hash_ip_create_args[] = {
static const struct ipset_arg hash_ip_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
diff --git a/lib/ipset_hash_ipport.c b/lib/ipset_hash_ipport.c
index 748e452..54664e1 100644
--- a/lib/ipset_hash_ipport.c
+++ b/lib/ipset_hash_ipport.c
@@ -36,7 +36,7 @@ static const struct ipset_arg hash_ipport_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Backward compatibility */
{ .name = { "probes", NULL },
@@ -65,7 +65,7 @@ static const struct ipset_arg hash_ipport_create_args[] = {
static const struct ipset_arg hash_ipport_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
diff --git a/lib/ipset_hash_ipportip.c b/lib/ipset_hash_ipportip.c
index 7c046a3..4599b01 100644
--- a/lib/ipset_hash_ipportip.c
+++ b/lib/ipset_hash_ipportip.c
@@ -36,7 +36,7 @@ static const struct ipset_arg hash_ipportip_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Backward compatibility */
{ .name = { "probes", NULL },
@@ -65,7 +65,7 @@ static const struct ipset_arg hash_ipportip_create_args[] = {
static const struct ipset_arg hash_ipportip_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
diff --git a/lib/ipset_hash_ipportnet.c b/lib/ipset_hash_ipportnet.c
index 0813b7d..af85639 100644
--- a/lib/ipset_hash_ipportnet.c
+++ b/lib/ipset_hash_ipportnet.c
@@ -36,7 +36,7 @@ static const struct ipset_arg hash_ipportnet_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Backward compatibility */
{ .name = { "probes", NULL },
@@ -65,7 +65,7 @@ static const struct ipset_arg hash_ipportnet_create_args[] = {
static const struct ipset_arg hash_ipportnet_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
@@ -255,7 +255,7 @@ struct ipset_type ipset_hash_ipportnet2 = {
static const struct ipset_arg hash_ipportnet3_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ .name = { "nomatch", NULL },
.has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH,
diff --git a/lib/ipset_hash_net.c b/lib/ipset_hash_net.c
index 0fd2608..5829f50 100644
--- a/lib/ipset_hash_net.c
+++ b/lib/ipset_hash_net.c
@@ -35,7 +35,7 @@ static const struct ipset_arg hash_net_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
/* Ignored options: backward compatibilty */
{ .name = { "probes", NULL },
@@ -52,7 +52,7 @@ static const struct ipset_arg hash_net_create_args[] = {
static const struct ipset_arg hash_net_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
@@ -165,7 +165,7 @@ struct ipset_type ipset_hash_net1 = {
static const struct ipset_arg hash_net2_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ .name = { "nomatch", NULL },
.has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH,
diff --git a/lib/ipset_hash_netiface.c b/lib/ipset_hash_netiface.c
index 880ba7d..7fca5fe 100644
--- a/lib/ipset_hash_netiface.c
+++ b/lib/ipset_hash_netiface.c
@@ -36,7 +36,7 @@ static const struct ipset_arg hash_netiface_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
@@ -44,7 +44,7 @@ static const struct ipset_arg hash_netiface_create_args[] = {
static const struct ipset_arg hash_netiface_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
@@ -121,7 +121,7 @@ struct ipset_type ipset_hash_netiface0 = {
static const struct ipset_arg hash_netiface1_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ .name = { "nomatch", NULL },
.has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH,
diff --git a/lib/ipset_hash_netport.c b/lib/ipset_hash_netport.c
index b910c81..d8d220e 100644
--- a/lib/ipset_hash_netport.c
+++ b/lib/ipset_hash_netport.c
@@ -36,7 +36,7 @@ static const struct ipset_arg hash_netport_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
@@ -44,7 +44,7 @@ static const struct ipset_arg hash_netport_create_args[] = {
static const struct ipset_arg hash_netport_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
@@ -201,7 +201,7 @@ struct ipset_type ipset_hash_netport2 = {
static const struct ipset_arg hash_netport3_add_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ .name = { "nomatch", NULL },
.has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH,
diff --git a/lib/ipset_list_set.c b/lib/ipset_list_set.c
index d95290b..67c29b6 100644
--- a/lib/ipset_list_set.c
+++ b/lib/ipset_list_set.c
@@ -17,7 +17,7 @@ static const struct ipset_arg list_set_create_args[] = {
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ },
};
@@ -25,7 +25,7 @@ static const struct ipset_arg list_set_create_args[] = {
static const struct ipset_arg list_set_adt_args[] = {
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
- .parse = ipset_parse_uint32, .print = ipset_print_number,
+ .parse = ipset_parse_timeout, .print = ipset_print_number,
},
{ .name = { "before", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NAMEREF,
diff --git a/lib/parse.c b/lib/parse.c
index 30efdb6..2cbd30e 100644
--- a/lib/parse.c
+++ b/lib/parse.c
@@ -1130,6 +1130,35 @@ ipset_parse_ip4_net6(struct ipset_session *session,
}
/**
+ * ipset_parse_timeout - parse timeout parameter
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Parse string as a timeout parameter. We have to take into account
+ * the jiffies storage in kernel.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_timeout(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
+{
+ int err;
+ unsigned long long num = 0;
+
+ assert(session);
+ assert(opt == IPSET_OPT_TIMEOUT);
+ assert(str);
+
+ err = string_to_number_ll(session, str, 0, UINT_MAX/1000, &num);
+ if (err == 0)
+ return ipset_session_data_set(session, opt, &num);
+
+ return err;
+}
+
+/**
* ipset_parse_iptimeout - parse IPv4|IPv6 address and timeout
* @session: session structure
* @opt: option kind of the data
@@ -1171,7 +1200,7 @@ ipset_parse_iptimeout(struct ipset_session *session,
*a++ = '\0';
err = parse_ip(session, opt, tmp, IPADDR_ANY);
if (!err)
- err = ipset_parse_uint32(session, IPSET_OPT_TIMEOUT, a);
+ err = ipset_parse_timeout(session, IPSET_OPT_TIMEOUT, a);
free(saved);
return err;