Commit 1a0c8330 authored by David S. Miller's avatar David S. Miller
parents a769f496 961ed183
...@@ -18,4 +18,14 @@ static inline bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src, ...@@ -18,4 +18,14 @@ static inline bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src,
extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src,
__be16 *port); __be16 *port);
static inline bool ip_set_proto_with_ports(u8 proto)
{
switch (proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
return true;
}
return false;
}
#endif /*_IP_SET_GETPORT_H*/ #endif /*_IP_SET_GETPORT_H*/
...@@ -387,7 +387,7 @@ ipt_do_table(struct sk_buff *skb, ...@@ -387,7 +387,7 @@ ipt_do_table(struct sk_buff *skb,
verdict = (unsigned)(-v) - 1; verdict = (unsigned)(-v) - 1;
break; break;
} }
if (*stackptr == 0) { if (*stackptr <= origptr) {
e = get_entry(table_base, e = get_entry(table_base,
private->underflow[hook]); private->underflow[hook]);
pr_debug("Underflow (this is normal) " pr_debug("Underflow (this is normal) "
...@@ -427,10 +427,10 @@ ipt_do_table(struct sk_buff *skb, ...@@ -427,10 +427,10 @@ ipt_do_table(struct sk_buff *skb,
/* Verdict */ /* Verdict */
break; break;
} while (!acpar.hotdrop); } while (!acpar.hotdrop);
xt_info_rdunlock_bh();
pr_debug("Exiting %s; resetting sp from %u to %u\n", pr_debug("Exiting %s; resetting sp from %u to %u\n",
__func__, *stackptr, origptr); __func__, *stackptr, origptr);
*stackptr = origptr; *stackptr = origptr;
xt_info_rdunlock_bh();
#ifdef DEBUG_ALLOW_ALL #ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT; return NF_ACCEPT;
#else #else
......
...@@ -664,8 +664,11 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input, ...@@ -664,8 +664,11 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input,
char buffer[PROC_WRITELEN+1]; char buffer[PROC_WRITELEN+1];
unsigned long nodenum; unsigned long nodenum;
if (copy_from_user(buffer, input, PROC_WRITELEN)) if (size > PROC_WRITELEN)
return -EIO;
if (copy_from_user(buffer, input, size))
return -EFAULT; return -EFAULT;
buffer[size] = 0;
if (*buffer == '+') { if (*buffer == '+') {
nodenum = simple_strtoul(buffer+1, NULL, 10); nodenum = simple_strtoul(buffer+1, NULL, 10);
......
...@@ -410,7 +410,7 @@ ip6t_do_table(struct sk_buff *skb, ...@@ -410,7 +410,7 @@ ip6t_do_table(struct sk_buff *skb,
verdict = (unsigned)(-v) - 1; verdict = (unsigned)(-v) - 1;
break; break;
} }
if (*stackptr == 0) if (*stackptr <= origptr)
e = get_entry(table_base, e = get_entry(table_base,
private->underflow[hook]); private->underflow[hook]);
else else
...@@ -441,8 +441,8 @@ ip6t_do_table(struct sk_buff *skb, ...@@ -441,8 +441,8 @@ ip6t_do_table(struct sk_buff *skb,
break; break;
} while (!acpar.hotdrop); } while (!acpar.hotdrop);
xt_info_rdunlock_bh();
*stackptr = origptr; *stackptr = origptr;
xt_info_rdunlock_bh();
#ifdef DEBUG_ALLOW_ALL #ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT; return NF_ACCEPT;
......
...@@ -94,16 +94,28 @@ static int ...@@ -94,16 +94,28 @@ static int
find_set_type_get(const char *name, u8 family, u8 revision, 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;
int err;
rcu_read_lock(); rcu_read_lock();
*found = find_set_type(name, family, revision); *found = find_set_type(name, family, revision);
if (*found) { if (*found) {
int err = !try_module_get((*found)->me); err = !try_module_get((*found)->me) ? -EFAULT : 0;
rcu_read_unlock(); goto unlock;
return err ? -EFAULT : 0; }
/* Make sure the type is loaded but we don't support the revision */
list_for_each_entry_rcu(type, &ip_set_type_list, list)
if (STREQ(type->name, name)) {
err = -IPSET_ERR_FIND_TYPE;
goto unlock;
} }
rcu_read_unlock(); rcu_read_unlock();
return try_to_load_type(name); return try_to_load_type(name);
unlock:
rcu_read_unlock();
return err;
} }
/* Find a given set type by name and family. /* Find a given set type by name and family.
...@@ -116,7 +128,7 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max) ...@@ -116,7 +128,7 @@ 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;
*min = *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)
if (STREQ(type->name, name) && if (STREQ(type->name, name) &&
...@@ -124,7 +136,7 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max) ...@@ -124,7 +136,7 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
found = true; found = true;
if (type->revision < *min) if (type->revision < *min)
*min = type->revision; *min = type->revision;
else if (type->revision > *max) if (type->revision > *max)
*max = type->revision; *max = type->revision;
} }
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -150,6 +150,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -150,6 +150,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_ipport4_elem data = { }; struct hash_ipport4_elem data = { };
u32 ip, ip_to, p, port, port_to; u32 ip, ip_to, p, port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -172,21 +173,15 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -172,21 +173,15 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMP))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -195,7 +190,6 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -195,7 +190,6 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST ||
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
tb[IPSET_ATTR_PORT_TO])) { tb[IPSET_ATTR_PORT_TO])) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
...@@ -219,13 +213,12 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -219,13 +213,12 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
} else } else
ip_to = ip; ip_to = ip;
port = ntohs(data.port); port_to = port = ntohs(data.port);
if (tb[IPSET_ATTR_PORT_TO]) { if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
if (port > port_to) if (port > port_to)
swap(port, port_to); swap(port, port_to);
} else }
port_to = port;
for (; !before(ip_to, ip); ip++) for (; !before(ip_to, ip); ip++)
for (p = port; p <= port_to; p++) { for (p = port; p <= port_to; p++) {
...@@ -361,6 +354,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -361,6 +354,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_ipport6_elem data = { }; struct hash_ipport6_elem data = { };
u32 port, port_to; u32 port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -385,21 +379,15 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -385,21 +379,15 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMPV6))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -407,9 +395,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -407,9 +395,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!tb[IPSET_ATTR_PORT_TO]) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
return ip_set_eexist(ret, flags) ? 0 : ret; return ip_set_eexist(ret, flags) ? 0 : ret;
} }
......
...@@ -154,6 +154,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -154,6 +154,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_ipportip4_elem data = { }; struct hash_ipportip4_elem data = { };
u32 ip, ip_to, p, port, port_to; u32 ip, ip_to, p, port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
...@@ -180,21 +181,15 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -180,21 +181,15 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMP))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -203,7 +198,6 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -203,7 +198,6 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST ||
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
tb[IPSET_ATTR_PORT_TO])) { tb[IPSET_ATTR_PORT_TO])) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
...@@ -227,13 +221,12 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -227,13 +221,12 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
} else } else
ip_to = ip; ip_to = ip;
port = ntohs(data.port); port_to = port = ntohs(data.port);
if (tb[IPSET_ATTR_PORT_TO]) { if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
if (port > port_to) if (port > port_to)
swap(port, port_to); swap(port, port_to);
} else }
port_to = port;
for (; !before(ip_to, ip); ip++) for (; !before(ip_to, ip); ip++)
for (p = port; p <= port_to; p++) { for (p = port; p <= port_to; p++) {
...@@ -375,6 +368,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -375,6 +368,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_ipportip6_elem data = { }; struct hash_ipportip6_elem data = { };
u32 port, port_to; u32 port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
...@@ -403,21 +397,15 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -403,21 +397,15 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMPV6))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -425,9 +413,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -425,9 +413,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!tb[IPSET_ATTR_PORT_TO]) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
return ip_set_eexist(ret, flags) ? 0 : ret; return ip_set_eexist(ret, flags) ? 0 : ret;
} }
......
...@@ -174,6 +174,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -174,6 +174,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_ipportnet4_elem data = { .cidr = HOST_MASK }; struct hash_ipportnet4_elem data = { .cidr = HOST_MASK };
u32 ip, ip_to, p, port, port_to; u32 ip, ip_to, p, port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
...@@ -208,21 +209,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -208,21 +209,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMP))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -231,7 +226,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -231,7 +226,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST ||
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
tb[IPSET_ATTR_PORT_TO])) { tb[IPSET_ATTR_PORT_TO])) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
...@@ -255,13 +249,12 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -255,13 +249,12 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
} else } else
ip_to = ip; ip_to = ip;
port = ntohs(data.port); port_to = port = ntohs(data.port);
if (tb[IPSET_ATTR_PORT_TO]) { if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
if (port > port_to) if (port > port_to)
swap(port, port_to); swap(port, port_to);
} else }
port_to = port;
for (; !before(ip_to, ip); ip++) for (; !before(ip_to, ip); ip++)
for (p = port; p <= port_to; p++) { for (p = port; p <= port_to; p++) {
...@@ -429,6 +422,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -429,6 +422,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_ipportnet6_elem data = { .cidr = HOST_MASK }; struct hash_ipportnet6_elem data = { .cidr = HOST_MASK };
u32 port, port_to; u32 port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
...@@ -465,21 +459,15 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -465,21 +459,15 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMPV6))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -487,9 +475,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -487,9 +475,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!tb[IPSET_ATTR_PORT_TO]) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
return ip_set_eexist(ret, flags) ? 0 : ret; return ip_set_eexist(ret, flags) ? 0 : ret;
} }
......
...@@ -170,6 +170,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -170,6 +170,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_netport4_elem data = { .cidr = HOST_MASK }; struct hash_netport4_elem data = { .cidr = HOST_MASK };
u32 port, port_to; u32 port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -198,21 +199,15 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -198,21 +199,15 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMP))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMP:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -220,9 +215,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -220,9 +215,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!tb[IPSET_ATTR_PORT_TO]) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
return ip_set_eexist(ret, flags) ? 0 : ret; return ip_set_eexist(ret, flags) ? 0 : ret;
} }
...@@ -390,6 +383,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -390,6 +383,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_netport6_elem data = { .cidr = HOST_MASK }; struct hash_netport6_elem data = { .cidr = HOST_MASK };
u32 port, port_to; u32 port, port_to;
u32 timeout = h->timeout; u32 timeout = h->timeout;
bool with_ports = false;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -418,21 +412,15 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -418,21 +412,15 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
if (tb[IPSET_ATTR_PROTO]) { if (tb[IPSET_ATTR_PROTO]) {
data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
with_ports = ip_set_proto_with_ports(data.proto);
if (data.proto == 0) if (data.proto == 0)
return -IPSET_ERR_INVALID_PROTO; return -IPSET_ERR_INVALID_PROTO;
} else } else
return -IPSET_ERR_MISSING_PROTO; return -IPSET_ERR_MISSING_PROTO;
switch (data.proto) { if (!(with_ports || data.proto == IPPROTO_ICMPV6))
case IPPROTO_UDP:
case IPPROTO_TCP:
case IPPROTO_ICMPV6:
break;
default:
data.port = 0; data.port = 0;
break;
}
if (tb[IPSET_ATTR_TIMEOUT]) { if (tb[IPSET_ATTR_TIMEOUT]) {
if (!with_timeout(h->timeout)) if (!with_timeout(h->timeout))
...@@ -440,9 +428,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -440,9 +428,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
} }
if (adt == IPSET_TEST || if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
!(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
!tb[IPSET_ATTR_PORT_TO]) {
ret = adtfn(set, &data, timeout); ret = adtfn(set, &data, timeout);
return ip_set_eexist(ret, flags) ? 0 : ret; return ip_set_eexist(ret, flags) ? 0 : ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment