mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-09 14:14:58 +02:00
ipset; update to ipset-6.3 (genl)
* Handle EAGAIN from autoloading code. * Turn one nfgenmsg site into genlmsg to avoid protocol mismatch
This commit is contained in:
@@ -21,6 +21,10 @@ Enhancements:
|
|||||||
* revision reporting fixes
|
* revision reporting fixes
|
||||||
- update to ipset 6.2
|
- update to ipset 6.2
|
||||||
* list:set timeout variant fixes
|
* list:set timeout variant fixes
|
||||||
|
- update to ipset 6.3
|
||||||
|
* bitmap:ip,mac type requires "src" for MAC, enforce it
|
||||||
|
- ipset-genl: handle EAGAIN return value emitted from autoloader
|
||||||
|
- ipset-genl: resolve nfgenmsg remains and fix spurious protocol abort
|
||||||
|
|
||||||
|
|
||||||
v1.33 (2011-02-02)
|
v1.33 (2011-02-02)
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* The protocol version */
|
/* The protocol version */
|
||||||
#define IPSET_PROTOCOL 60
|
#define IPSET_PROTOCOL 6
|
||||||
|
|
||||||
/* The max length of strings including NUL: set and type identifiers */
|
/* The max length of strings including NUL: set and type identifiers */
|
||||||
#define IPSET_MAXNAMELEN 32
|
#define IPSET_MAXNAMELEN 32
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
|
|
||||||
/* The protocol version */
|
/* The protocol version */
|
||||||
#define IPSET_PROTOCOL 60
|
#define IPSET_PROTOCOL 6
|
||||||
|
|
||||||
/* The max length of strings including NUL: set and type identifiers */
|
/* The max length of strings including NUL: set and type identifiers */
|
||||||
#define IPSET_MAXNAMELEN 32
|
#define IPSET_MAXNAMELEN 32
|
||||||
|
@@ -344,6 +344,10 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
|
|||||||
ipset_adtfn adtfn = set->variant->adt[adt];
|
ipset_adtfn adtfn = set->variant->adt[adt];
|
||||||
struct ipmac data;
|
struct ipmac data;
|
||||||
|
|
||||||
|
/* MAC can be src only */
|
||||||
|
if (!(flags & IPSET_DIM_TWO_SRC))
|
||||||
|
return 0;
|
||||||
|
|
||||||
data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
|
data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
|
||||||
if (data.id < map->first_ip || data.id > map->last_ip)
|
if (data.id < map->first_ip || data.id > map->last_ip)
|
||||||
return -IPSET_ERR_BITMAP_RANGE;
|
return -IPSET_ERR_BITMAP_RANGE;
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include <net/genetlink.h>
|
#include <net/genetlink.h>
|
||||||
#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
|
#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
|
||||||
|
|
||||||
|
struct genlmsg_buf;
|
||||||
|
|
||||||
static LIST_HEAD(ip_set_type_list); /* all registered set types */
|
static LIST_HEAD(ip_set_type_list); /* all registered set types */
|
||||||
static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */
|
static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */
|
||||||
static DEFINE_RWLOCK(ip_set_ref_lock); /* protects the set refs */
|
static DEFINE_RWLOCK(ip_set_ref_lock); /* protects the set refs */
|
||||||
@@ -82,14 +84,14 @@ find_set_type(const char *name, u8 family, u8 revision)
|
|||||||
static int
|
static int
|
||||||
try_to_load_type(const char *name)
|
try_to_load_type(const char *name)
|
||||||
{
|
{
|
||||||
nfnl_unlock();
|
genl_unlock();
|
||||||
pr_debug("try to load ip_set_%s\n", name);
|
pr_debug("try to load ip_set_%s\n", name);
|
||||||
if (request_module("ip_set_%s", name) < 0) {
|
if (request_module("ip_set_%s", name) < 0) {
|
||||||
pr_warning("Can't find ip_set type %s\n", name);
|
pr_warning("Can't find ip_set type %s\n", name);
|
||||||
nfnl_lock();
|
genl_lock();
|
||||||
return -IPSET_ERR_FIND_TYPE;
|
return -IPSET_ERR_FIND_TYPE;
|
||||||
}
|
}
|
||||||
nfnl_lock();
|
genl_lock();
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,8 +101,10 @@ find_set_type_get(const char *name, u8 family, u8 revision,
|
|||||||
struct ip_set_type **found)
|
struct ip_set_type **found)
|
||||||
{
|
{
|
||||||
struct ip_set_type *type;
|
struct ip_set_type *type;
|
||||||
|
unsigned int retry = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
retry:
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
*found = find_set_type(name, family, revision);
|
*found = find_set_type(name, family, revision);
|
||||||
if (*found) {
|
if (*found) {
|
||||||
@@ -115,7 +119,10 @@ find_set_type_get(const char *name, u8 family, u8 revision,
|
|||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
return try_to_load_type(name);
|
err = try_to_load_type(name);
|
||||||
|
if (err == -EAGAIN && retry++ == 0)
|
||||||
|
goto retry;
|
||||||
|
return err;
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
@@ -131,7 +138,10 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
|
|||||||
{
|
{
|
||||||
struct ip_set_type *type;
|
struct ip_set_type *type;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
unsigned int retry = 0;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
retry:
|
||||||
*min = 255; *max = 0;
|
*min = 255; *max = 0;
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(type, &ip_set_type_list, list)
|
list_for_each_entry_rcu(type, &ip_set_type_list, list)
|
||||||
@@ -147,7 +157,10 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
|
|||||||
if (found)
|
if (found)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return try_to_load_type(name);
|
err = try_to_load_type(name);
|
||||||
|
if (err == -EAGAIN && retry++ == 0)
|
||||||
|
goto retry;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define family_name(f) ((f) == AF_INET ? "inet" : \
|
#define family_name(f) ((f) == AF_INET ? "inet" : \
|
||||||
@@ -482,9 +495,9 @@ ip_set_nfnl_get(const char *name)
|
|||||||
struct ip_set *s;
|
struct ip_set *s;
|
||||||
ip_set_id_t index;
|
ip_set_id_t index;
|
||||||
|
|
||||||
nfnl_lock();
|
genl_lock();
|
||||||
index = ip_set_get_byname(name, &s);
|
index = ip_set_get_byname(name, &s);
|
||||||
nfnl_unlock();
|
genl_unlock();
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
@@ -502,12 +515,12 @@ ip_set_nfnl_get_byindex(ip_set_id_t index)
|
|||||||
if (index > ip_set_max)
|
if (index > ip_set_max)
|
||||||
return IPSET_INVALID_ID;
|
return IPSET_INVALID_ID;
|
||||||
|
|
||||||
nfnl_lock();
|
genl_lock();
|
||||||
if (ip_set_list[index])
|
if (ip_set_list[index])
|
||||||
__ip_set_get(index);
|
__ip_set_get(index);
|
||||||
else
|
else
|
||||||
index = IPSET_INVALID_ID;
|
index = IPSET_INVALID_ID;
|
||||||
nfnl_unlock();
|
genl_unlock();
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
@@ -523,9 +536,9 @@ EXPORT_SYMBOL_GPL(ip_set_nfnl_get_byindex);
|
|||||||
void
|
void
|
||||||
ip_set_nfnl_put(ip_set_id_t index)
|
ip_set_nfnl_put(ip_set_id_t index)
|
||||||
{
|
{
|
||||||
nfnl_lock();
|
genl_lock();
|
||||||
ip_set_put_byindex(index);
|
ip_set_put_byindex(index);
|
||||||
nfnl_unlock();
|
genl_unlock();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
|
EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
|
||||||
|
|
||||||
@@ -548,11 +561,11 @@ flag_exist(const struct genlmsghdr *ghdr)
|
|||||||
return ghdr->reserved & NLM_F_EXCL ? 0 : IPSET_FLAG_EXIST;
|
return ghdr->reserved & NLM_F_EXCL ? 0 : IPSET_FLAG_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nlmsghdr *
|
static struct genlmsg_buf *
|
||||||
start_msg(struct sk_buff *skb, u32 pid, u32 seq, unsigned int flags,
|
start_msg(struct sk_buff *skb, u32 pid, u32 seq, unsigned int flags,
|
||||||
enum ipset_cmd cmd)
|
enum ipset_cmd cmd)
|
||||||
{
|
{
|
||||||
void *nlh;
|
struct genlmsg_buf *nlh;
|
||||||
|
|
||||||
nlh = genlmsg_put(skb, pid, seq, &ip_set_netlink_subsys, flags, cmd);
|
nlh = genlmsg_put(skb, pid, seq, &ip_set_netlink_subsys, flags, cmd);
|
||||||
if (nlh == NULL)
|
if (nlh == NULL)
|
||||||
@@ -950,10 +963,11 @@ ip_set_dump_done(struct netlink_callback *cb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
dump_attrs(void *phdr)
|
dump_attrs(struct genlmsg_buf *phdr)
|
||||||
{
|
{
|
||||||
const struct nlattr *attr;
|
const struct nlattr *attr;
|
||||||
const struct nlmsghdr *nlh = phdr - GENL_HDRLEN - NLMSG_HDRLEN;
|
const struct nlmsghdr *nlh =
|
||||||
|
(const void *)phdr - GENL_HDRLEN - NLMSG_HDRLEN;
|
||||||
int rem;
|
int rem;
|
||||||
|
|
||||||
pr_debug("dump nlmsg\n");
|
pr_debug("dump nlmsg\n");
|
||||||
@@ -999,14 +1013,14 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
|
|||||||
{
|
{
|
||||||
ip_set_id_t index = IPSET_INVALID_ID, max;
|
ip_set_id_t index = IPSET_INVALID_ID, max;
|
||||||
struct ip_set *set = NULL;
|
struct ip_set *set = NULL;
|
||||||
struct nlmsghdr *nlh = NULL;
|
struct genlmsg_buf *nlh = NULL;
|
||||||
unsigned int flags = NETLINK_CB(cb->skb).pid ? NLM_F_MULTI : 0;
|
unsigned int flags = NETLINK_CB(cb->skb).pid ? NLM_F_MULTI : 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (cb->args[0] == DUMP_INIT) {
|
if (cb->args[0] == DUMP_INIT) {
|
||||||
ret = dump_init(cb);
|
ret = dump_init(cb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
nlh = nlmsg_hdr(cb->skb);
|
struct nlmsghdr *nlh = nlmsg_hdr(cb->skb);
|
||||||
/* We have to create and send the error message
|
/* We have to create and send the error message
|
||||||
* manually :-( */
|
* manually :-( */
|
||||||
if (nlh->nlmsg_flags & NLM_F_ACK)
|
if (nlh->nlmsg_flags & NLM_F_ACK)
|
||||||
@@ -1159,7 +1173,7 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
|
|||||||
struct sk_buff *skb2;
|
struct sk_buff *skb2;
|
||||||
struct nlmsgerr *errmsg;
|
struct nlmsgerr *errmsg;
|
||||||
size_t payload = sizeof(*errmsg) + nlmsg_len(nlh);
|
size_t payload = sizeof(*errmsg) + nlmsg_len(nlh);
|
||||||
int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg));
|
int min_len = NLMSG_SPACE(sizeof(struct genlmsghdr));
|
||||||
struct nlattr *cda[IPSET_ATTR_CMD_MAX+1];
|
struct nlattr *cda[IPSET_ATTR_CMD_MAX+1];
|
||||||
struct nlattr *cmdattr;
|
struct nlattr *cmdattr;
|
||||||
u32 *errline;
|
u32 *errline;
|
||||||
@@ -1342,7 +1356,7 @@ ip_set_header(struct sk_buff *skb, struct genl_info *info)
|
|||||||
struct nlattr *const *attr = info->attrs;
|
struct nlattr *const *attr = info->attrs;
|
||||||
const struct nlmsghdr *nlh = info->nlhdr;
|
const struct nlmsghdr *nlh = info->nlhdr;
|
||||||
struct sk_buff *skb2;
|
struct sk_buff *skb2;
|
||||||
struct nlmsghdr *nlh2;
|
struct genlmsg_buf *nlh2;
|
||||||
ip_set_id_t index;
|
ip_set_id_t index;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -1355,7 +1369,7 @@ ip_set_header(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
set = ip_set_list[index];
|
set = ip_set_list[index];
|
||||||
|
|
||||||
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
skb2 = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
if (skb2 == NULL)
|
if (skb2 == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -1377,7 +1391,7 @@ ip_set_header(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
nlmsg_cancel(skb2, nlh2);
|
genlmsg_cancel(skb2, nlh2);
|
||||||
nlmsg_failure:
|
nlmsg_failure:
|
||||||
kfree_skb(skb2);
|
kfree_skb(skb2);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
@@ -1399,7 +1413,7 @@ ip_set_type(struct sk_buff *skb, struct genl_info *info)
|
|||||||
const struct nlmsghdr *nlh = info->nlhdr;
|
const struct nlmsghdr *nlh = info->nlhdr;
|
||||||
|
|
||||||
struct sk_buff *skb2;
|
struct sk_buff *skb2;
|
||||||
void *nlh2;
|
struct genlmsg_buf *nlh2;
|
||||||
u8 family, min, max;
|
u8 family, min, max;
|
||||||
const char *typename;
|
const char *typename;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -1458,7 +1472,7 @@ ip_set_protocol(struct sk_buff *skb, struct genl_info *info)
|
|||||||
const struct nlmsghdr *nlh = info->nlhdr;
|
const struct nlmsghdr *nlh = info->nlhdr;
|
||||||
|
|
||||||
struct sk_buff *skb2;
|
struct sk_buff *skb2;
|
||||||
void *nlh2;
|
struct genlmsg_buf *nlh2;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (unlikely(attr[IPSET_ATTR_PROTOCOL] == NULL))
|
if (unlikely(attr[IPSET_ATTR_PROTOCOL] == NULL))
|
||||||
@@ -1633,9 +1647,9 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
|
req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
|
||||||
nfnl_lock();
|
genl_lock();
|
||||||
req_get->set.index = find_set_id(req_get->set.name);
|
req_get->set.index = find_set_id(req_get->set.name);
|
||||||
nfnl_unlock();
|
genl_unlock();
|
||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_GET_BYINDEX: {
|
case IP_SET_OP_GET_BYINDEX: {
|
||||||
@@ -1646,12 +1660,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
|
|||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
nfnl_lock();
|
genl_lock();
|
||||||
strncpy(req_get->set.name,
|
strncpy(req_get->set.name,
|
||||||
ip_set_list[req_get->set.index]
|
ip_set_list[req_get->set.index]
|
||||||
? ip_set_list[req_get->set.index]->name : "",
|
? ip_set_list[req_get->set.index]->name : "",
|
||||||
IPSET_MAXNAMELEN);
|
IPSET_MAXNAMELEN);
|
||||||
nfnl_unlock();
|
genl_unlock();
|
||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@@ -310,8 +310,8 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
|
|||||||
!id_eq(map, i + 1, refid)) ||
|
!id_eq(map, i + 1, refid)) ||
|
||||||
(before < 0 &&
|
(before < 0 &&
|
||||||
(i == 0 || !id_eq(map, i - 1, refid)))) {
|
(i == 0 || !id_eq(map, i - 1, refid)))) {
|
||||||
ret = -IPSET_ERR_EXIST;
|
ret = -IPSET_ERR_EXIST;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
e->timeout = ip_set_timeout_set(timeout);
|
e->timeout = ip_set_timeout_set(timeout);
|
||||||
ip_set_put_byindex(id);
|
ip_set_put_byindex(id);
|
||||||
|
@@ -302,9 +302,10 @@ matched by the kernel, it will automatically fill out the missing MAC address wi
|
|||||||
source MAC address from the packet. If the entry was specified with a timeout value,
|
source MAC address from the packet. If the entry was specified with a timeout value,
|
||||||
the timer starts off when the IP and MAC address pair is complete.
|
the timer starts off when the IP and MAC address pair is complete.
|
||||||
.PP
|
.PP
|
||||||
Please note, the \fBset\fR match and \fBSET\fR target netfilter kernel modules
|
The \fBbitmap:ip,mac\fR type of sets require two \fBsrc/dst\fR parameters of
|
||||||
\fBalways\fR use the source MAC address from the packet to match, add or delete
|
the \fBset\fR match and \fBSET\fR target netfilter kernel modules and the second
|
||||||
entries from a \fBbitmap:ip,mac\fR type of set.
|
one must be \fBsrc\fR to match, add or delete entries because the \fBset\fR match
|
||||||
|
and \fBSET\fR target have access to the source MAC address only.
|
||||||
.PP
|
.PP
|
||||||
Examples:
|
Examples:
|
||||||
.IP
|
.IP
|
||||||
|
@@ -115,6 +115,7 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par)
|
|||||||
if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) {
|
if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) {
|
||||||
pr_warning("Protocol error: set match dimension "
|
pr_warning("Protocol error: set match dimension "
|
||||||
"is over the limit!\n");
|
"is over the limit!\n");
|
||||||
|
ip_set_nfnl_put(info->match_set.index);
|
||||||
return CHECK_FAIL(-ERANGE); /* error */
|
return CHECK_FAIL(-ERANGE); /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,6 +180,8 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
|
|||||||
if (index == IPSET_INVALID_ID) {
|
if (index == IPSET_INVALID_ID) {
|
||||||
pr_warning("Cannot find del_set index %u as target\n",
|
pr_warning("Cannot find del_set index %u as target\n",
|
||||||
info->del_set.index);
|
info->del_set.index);
|
||||||
|
if (info->add_set.index != IPSET_INVALID_ID)
|
||||||
|
ip_set_nfnl_put(info->add_set.index);
|
||||||
return CHECK_FAIL(-ENOENT); /* error */
|
return CHECK_FAIL(-ENOENT); /* error */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,6 +189,10 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
|
|||||||
info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) {
|
info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) {
|
||||||
pr_warning("Protocol error: SET target dimension "
|
pr_warning("Protocol error: SET target dimension "
|
||||||
"is over the limit!\n");
|
"is over the limit!\n");
|
||||||
|
if (info->add_set.index != IPSET_INVALID_ID)
|
||||||
|
ip_set_nfnl_put(info->add_set.index);
|
||||||
|
if (info->del_set.index != IPSET_INVALID_ID)
|
||||||
|
ip_set_nfnl_put(info->del_set.index);
|
||||||
return CHECK_FAIL(-ERANGE); /* error */
|
return CHECK_FAIL(-ERANGE); /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +253,7 @@ set_match_checkentry(const struct xt_mtchk_param *par)
|
|||||||
if (info->match_set.dim > IPSET_DIM_MAX) {
|
if (info->match_set.dim > IPSET_DIM_MAX) {
|
||||||
pr_warning("Protocol error: set match dimension "
|
pr_warning("Protocol error: set match dimension "
|
||||||
"is over the limit!\n");
|
"is over the limit!\n");
|
||||||
|
ip_set_nfnl_put(info->match_set.index);
|
||||||
return CHECK_FAIL(-ERANGE); /* error */
|
return CHECK_FAIL(-ERANGE); /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +286,7 @@ set_target(struct sk_buff *skb, const struct xt_action_param *par)
|
|||||||
if (info->del_set.index != IPSET_INVALID_ID)
|
if (info->del_set.index != IPSET_INVALID_ID)
|
||||||
ip_set_del(info->del_set.index,
|
ip_set_del(info->del_set.index,
|
||||||
skb, par->family,
|
skb, par->family,
|
||||||
info->add_set.dim,
|
info->del_set.dim,
|
||||||
info->del_set.flags);
|
info->del_set.flags);
|
||||||
|
|
||||||
return XT_CONTINUE;
|
return XT_CONTINUE;
|
||||||
@@ -309,13 +317,19 @@ set_target_checkentry(const struct xt_tgchk_param *par)
|
|||||||
if (index == IPSET_INVALID_ID) {
|
if (index == IPSET_INVALID_ID) {
|
||||||
pr_warning("Cannot find del_set index %u as target\n",
|
pr_warning("Cannot find del_set index %u as target\n",
|
||||||
info->del_set.index);
|
info->del_set.index);
|
||||||
|
if (info->add_set.index != IPSET_INVALID_ID)
|
||||||
|
ip_set_nfnl_put(info->add_set.index);
|
||||||
return CHECK_FAIL(-ENOENT); /* error */
|
return CHECK_FAIL(-ENOENT); /* error */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info->add_set.dim > IPSET_DIM_MAX ||
|
if (info->add_set.dim > IPSET_DIM_MAX ||
|
||||||
info->del_set.flags > IPSET_DIM_MAX) {
|
info->del_set.dim > IPSET_DIM_MAX) {
|
||||||
pr_warning("Protocol error: SET target dimension "
|
pr_warning("Protocol error: SET target dimension "
|
||||||
"is over the limit!\n");
|
"is over the limit!\n");
|
||||||
|
if (info->add_set.index != IPSET_INVALID_ID)
|
||||||
|
ip_set_nfnl_put(info->add_set.index);
|
||||||
|
if (info->del_set.index != IPSET_INVALID_ID)
|
||||||
|
ip_set_nfnl_put(info->del_set.index);
|
||||||
return CHECK_FAIL(-ERANGE); /* error */
|
return CHECK_FAIL(-ERANGE); /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user