|
@@ -174,6 +174,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
|
|
struct hash_ipportnet4_elem data = { .cidr = HOST_MASK };
|
|
|
u32 ip, ip_to, p, port, port_to;
|
|
|
u32 timeout = h->timeout;
|
|
|
+ bool with_ports = false;
|
|
|
int ret;
|
|
|
|
|
|
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
|
|
@@ -208,21 +209,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
|
|
|
|
|
if (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)
|
|
|
return -IPSET_ERR_INVALID_PROTO;
|
|
|
} else
|
|
|
return -IPSET_ERR_MISSING_PROTO;
|
|
|
|
|
|
- switch (data.proto) {
|
|
|
- case IPPROTO_UDP:
|
|
|
- case IPPROTO_TCP:
|
|
|
- case IPPROTO_ICMP:
|
|
|
- break;
|
|
|
- default:
|
|
|
+ if (!(with_ports || data.proto == IPPROTO_ICMP))
|
|
|
data.port = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
|
|
|
if (tb[IPSET_ATTR_TIMEOUT]) {
|
|
|
if (!with_timeout(h->timeout))
|
|
@@ -231,7 +226,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
|
|
}
|
|
|
|
|
|
if (adt == IPSET_TEST ||
|
|
|
- !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
|
|
|
!(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
|
|
|
tb[IPSET_ATTR_PORT_TO])) {
|
|
|
ret = adtfn(set, &data, timeout);
|
|
@@ -255,13 +249,12 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
|
|
|
} else
|
|
|
ip_to = ip;
|
|
|
|
|
|
- port = ntohs(data.port);
|
|
|
- if (tb[IPSET_ATTR_PORT_TO]) {
|
|
|
+ port_to = port = ntohs(data.port);
|
|
|
+ if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
|
|
|
port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
|
|
|
if (port > port_to)
|
|
|
swap(port, port_to);
|
|
|
- } else
|
|
|
- port_to = port;
|
|
|
+ }
|
|
|
|
|
|
for (; !before(ip_to, ip); ip++)
|
|
|
for (p = port; p <= port_to; p++) {
|
|
@@ -429,6 +422,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
|
|
|
struct hash_ipportnet6_elem data = { .cidr = HOST_MASK };
|
|
|
u32 port, port_to;
|
|
|
u32 timeout = h->timeout;
|
|
|
+ bool with_ports = false;
|
|
|
int ret;
|
|
|
|
|
|
if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
|
|
@@ -465,21 +459,15 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
|
|
|
|
|
|
if (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)
|
|
|
return -IPSET_ERR_INVALID_PROTO;
|
|
|
} else
|
|
|
return -IPSET_ERR_MISSING_PROTO;
|
|
|
|
|
|
- switch (data.proto) {
|
|
|
- case IPPROTO_UDP:
|
|
|
- case IPPROTO_TCP:
|
|
|
- case IPPROTO_ICMPV6:
|
|
|
- break;
|
|
|
- default:
|
|
|
+ if (!(with_ports || data.proto == IPPROTO_ICMPV6))
|
|
|
data.port = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
|
|
|
if (tb[IPSET_ATTR_TIMEOUT]) {
|
|
|
if (!with_timeout(h->timeout))
|
|
@@ -487,9 +475,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
|
|
|
timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
|
|
|
}
|
|
|
|
|
|
- if (adt == IPSET_TEST ||
|
|
|
- !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) ||
|
|
|
- !tb[IPSET_ATTR_PORT_TO]) {
|
|
|
+ if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
|
|
|
ret = adtfn(set, &data, timeout);
|
|
|
return ip_set_eexist(ret, flags) ? 0 : ret;
|
|
|
}
|