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,
{
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;
}
.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 */
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)
},
{ .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 },
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,
},
{ },
};
},
{ .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 },
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,
},
{ },
};
},
{ .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 },
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,
},
{ },
};
},
{ .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 },
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,
},
{ },
};
},
{ .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 },
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,
},
{ },
};
},
{ .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 },
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,
},
{ },
};
},
{ .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 },
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,
},
{ },
};
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,
},
{ .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 },
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,
},
{ },
};
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,
},
{ .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,
},
{ },
};
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,
},
{ },
};
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,
},
{ .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,
},
{ },
};
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,
},
{ },
};
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,
},
{ .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,
},
{ },
};
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,
}
+/**
+ * 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
*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;