]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/netfilter/ipset/ip_set_hash_ipport.c
netfilter: ipset: fix address ranges at hash:*port* types
[mv-sheeva.git] / net / netfilter / ipset / ip_set_hash_ipport.c
index adbe787ea5dcc7210c319b29d49c32c2a9bb4069..b9214145d357ff7b4cfd8731f62f21970d7c8463 100644 (file)
@@ -150,6 +150,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
        struct hash_ipport4_elem data = { };
        u32 ip, ip_to, p, port, port_to;
        u32 timeout = h->timeout;
+       bool with_ports = false;
        int ret;
 
        if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -172,21 +173,15 @@ hash_ipport4_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))
@@ -195,7 +190,6 @@ hash_ipport4_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);
@@ -219,13 +213,12 @@ hash_ipport4_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++) {
@@ -361,6 +354,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
        struct hash_ipport6_elem data = { };
        u32 port, port_to;
        u32 timeout = h->timeout;
+       bool with_ports = false;
        int ret;
 
        if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -385,21 +379,15 @@ hash_ipport6_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))
@@ -407,9 +395,7 @@ hash_ipport6_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;
        }