Message ID | 20190221104243.7704-2-kai.heng.feng@canonical.com |
---|---|
State | New |
Headers | show |
Series | Fix kernel panic in netfilter | expand |
On 21.02.19 11:42, Kai-Heng Feng wrote: > From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> > > BugLink: https://bugs.launchpad.net/bugs/1811394 > > Fix wraparound bug which could lead to memory exhaustion when adding an > x.x.x.x-255.255.255.255 range to any hash:*net* types. > > Fixes Netfilter's bugzilla id #1212, reported by Thomas Schwark. > > Fixes: 48596a8ddc46 ("netfilter: ipset: Fix adding an IPv4 range containing more than 2^31 addresses") > Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> > (cherry picked from commit 0b8d9073539e217f79ec1bff65eb205ac796723d) > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- Cherry-pick, tested. > net/netfilter/ipset/ip_set_hash_ipportnet.c | 26 +++++++-------- > net/netfilter/ipset/ip_set_hash_net.c | 9 +++-- > net/netfilter/ipset/ip_set_hash_netiface.c | 9 +++-- > net/netfilter/ipset/ip_set_hash_netnet.c | 28 ++++++++-------- > net/netfilter/ipset/ip_set_hash_netport.c | 19 ++++++----- > net/netfilter/ipset/ip_set_hash_netportnet.c | 35 ++++++++++---------- > 6 files changed, 63 insertions(+), 63 deletions(-) > > diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c > index 0f164e986bf1..88b83d6d3084 100644 > --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c > +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c > @@ -168,7 +168,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], > struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 }; > struct ip_set_ext ext = IP_SET_INIT_UEXT(set); > u32 ip = 0, ip_to = 0, p = 0, port, port_to; > - u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2; > + u32 ip2_from = 0, ip2_to = 0, ip2; > bool with_ports = false; > u8 cidr; > int ret; > @@ -269,22 +269,21 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], > ip_set_mask_from_to(ip2_from, ip2_to, e.cidr + 1); > } > > - if (retried) > + if (retried) { > ip = ntohl(h->next.ip); > + p = ntohs(h->next.port); > + ip2 = ntohl(h->next.ip2); > + } else { > + p = port; > + ip2 = ip2_from; > + } > for (; ip <= ip_to; ip++) { > e.ip = htonl(ip); > - p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) > - : port; > for (; p <= port_to; p++) { > e.port = htons(p); > - ip2 = retried && > - ip == ntohl(h->next.ip) && > - p == ntohs(h->next.port) > - ? ntohl(h->next.ip2) : ip2_from; > - while (ip2 <= ip2_to) { > + do { > e.ip2 = htonl(ip2); > - ip2_last = ip_set_range_to_cidr(ip2, ip2_to, > - &cidr); > + ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr); > e.cidr = cidr - 1; > ret = adtfn(set, &e, &ext, &ext, flags); > > @@ -292,9 +291,10 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], > return ret; > > ret = 0; > - ip2 = ip2_last + 1; > - } > + } while (ip2++ < ip2_to); > + ip2 = ip2_from; > } > + p = port; > } > return ret; > } > diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c > index 1c67a1761e45..5449e23af13a 100644 > --- a/net/netfilter/ipset/ip_set_hash_net.c > +++ b/net/netfilter/ipset/ip_set_hash_net.c > @@ -143,7 +143,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], > ipset_adtfn adtfn = set->variant->adt[adt]; > struct hash_net4_elem e = { .cidr = HOST_MASK }; > struct ip_set_ext ext = IP_SET_INIT_UEXT(set); > - u32 ip = 0, ip_to = 0, last; > + u32 ip = 0, ip_to = 0; > int ret; > > if (tb[IPSET_ATTR_LINENO]) > @@ -193,16 +193,15 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], > } > if (retried) > ip = ntohl(h->next.ip); > - while (ip <= ip_to) { > + do { > e.ip = htonl(ip); > - last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); > + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr); > ret = adtfn(set, &e, &ext, &ext, flags); > if (ret && !ip_set_eexist(ret, flags)) > return ret; > > ret = 0; > - ip = last + 1; > - } > + } while (ip++ < ip_to); > return ret; > } > > diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c > index d417074f1c1a..f5164c1efce2 100644 > --- a/net/netfilter/ipset/ip_set_hash_netiface.c > +++ b/net/netfilter/ipset/ip_set_hash_netiface.c > @@ -200,7 +200,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], > ipset_adtfn adtfn = set->variant->adt[adt]; > struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 }; > struct ip_set_ext ext = IP_SET_INIT_UEXT(set); > - u32 ip = 0, ip_to = 0, last; > + u32 ip = 0, ip_to = 0; > int ret; > > if (tb[IPSET_ATTR_LINENO]) > @@ -255,17 +255,16 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], > > if (retried) > ip = ntohl(h->next.ip); > - while (ip <= ip_to) { > + do { > e.ip = htonl(ip); > - last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); > + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr); > ret = adtfn(set, &e, &ext, &ext, flags); > > if (ret && !ip_set_eexist(ret, flags)) > return ret; > > ret = 0; > - ip = last + 1; > - } > + } while (ip++ < ip_to); > return ret; > } > > diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c > index 7f9ae2e9645b..5a2b923bd81f 100644 > --- a/net/netfilter/ipset/ip_set_hash_netnet.c > +++ b/net/netfilter/ipset/ip_set_hash_netnet.c > @@ -169,8 +169,8 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[], > ipset_adtfn adtfn = set->variant->adt[adt]; > struct hash_netnet4_elem e = { }; > struct ip_set_ext ext = IP_SET_INIT_UEXT(set); > - u32 ip = 0, ip_to = 0, last; > - u32 ip2 = 0, ip2_from = 0, ip2_to = 0, last2; > + u32 ip = 0, ip_to = 0; > + u32 ip2 = 0, ip2_from = 0, ip2_to = 0; > int ret; > > if (tb[IPSET_ATTR_LINENO]) > @@ -247,27 +247,27 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[], > ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]); > } > > - if (retried) > + if (retried) { > ip = ntohl(h->next.ip[0]); > + ip2 = ntohl(h->next.ip[1]); > + } else { > + ip2 = ip2_from; > + } > > - while (ip <= ip_to) { > + do { > e.ip[0] = htonl(ip); > - last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); > - ip2 = (retried && > - ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1]) > - : ip2_from; > - while (ip2 <= ip2_to) { > + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); > + do { > e.ip[1] = htonl(ip2); > - last2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]); > + ip2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]); > ret = adtfn(set, &e, &ext, &ext, flags); > if (ret && !ip_set_eexist(ret, flags)) > return ret; > > ret = 0; > - ip2 = last2 + 1; > - } > - ip = last + 1; > - } > + } while (ip2++ < ip2_to); > + ip2 = ip2_from; > + } while (ip++ < ip_to); > return ret; > } > > diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c > index e6ef382febe4..1a187be9ebc8 100644 > --- a/net/netfilter/ipset/ip_set_hash_netport.c > +++ b/net/netfilter/ipset/ip_set_hash_netport.c > @@ -161,7 +161,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], > ipset_adtfn adtfn = set->variant->adt[adt]; > struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 }; > struct ip_set_ext ext = IP_SET_INIT_UEXT(set); > - u32 port, port_to, p = 0, ip = 0, ip_to = 0, last; > + u32 port, port_to, p = 0, ip = 0, ip_to = 0; > bool with_ports = false; > u8 cidr; > int ret; > @@ -239,25 +239,26 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], > ip_set_mask_from_to(ip, ip_to, e.cidr + 1); > } > > - if (retried) > + if (retried) { > ip = ntohl(h->next.ip); > - while (ip <= ip_to) { > + p = ntohs(h->next.port); > + } else { > + p = port; > + } > + do { > e.ip = htonl(ip); > - last = ip_set_range_to_cidr(ip, ip_to, &cidr); > + ip = ip_set_range_to_cidr(ip, ip_to, &cidr); > e.cidr = cidr - 1; > - p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) > - : port; > for (; p <= port_to; p++) { > e.port = htons(p); > ret = adtfn(set, &e, &ext, &ext, flags); > - > if (ret && !ip_set_eexist(ret, flags)) > return ret; > > ret = 0; > } > - ip = last + 1; > - } > + p = port; > + } while (ip++ < ip_to); > return ret; > } > > diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c > index 8602f2595a1a..d391485a6acd 100644 > --- a/net/netfilter/ipset/ip_set_hash_netportnet.c > +++ b/net/netfilter/ipset/ip_set_hash_netportnet.c > @@ -184,8 +184,8 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], > ipset_adtfn adtfn = set->variant->adt[adt]; > struct hash_netportnet4_elem e = { }; > struct ip_set_ext ext = IP_SET_INIT_UEXT(set); > - u32 ip = 0, ip_to = 0, ip_last, p = 0, port, port_to; > - u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2; > + u32 ip = 0, ip_to = 0, p = 0, port, port_to; > + u32 ip2_from = 0, ip2_to = 0, ip2; > bool with_ports = false; > int ret; > > @@ -288,33 +288,34 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], > ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]); > } > > - if (retried) > + if (retried) { > ip = ntohl(h->next.ip[0]); > + p = ntohs(h->next.port); > + ip2 = ntohl(h->next.ip[1]); > + } else { > + p = port; > + ip2 = ip2_from; > + } > > - while (ip <= ip_to) { > + do { > e.ip[0] = htonl(ip); > - ip_last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); > - p = retried && ip == ntohl(h->next.ip[0]) ? ntohs(h->next.port) > - : port; > + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); > for (; p <= port_to; p++) { > e.port = htons(p); > - ip2 = (retried && ip == ntohl(h->next.ip[0]) && > - p == ntohs(h->next.port)) ? ntohl(h->next.ip[1]) > - : ip2_from; > - while (ip2 <= ip2_to) { > + do { > e.ip[1] = htonl(ip2); > - ip2_last = ip_set_range_to_cidr(ip2, ip2_to, > - &e.cidr[1]); > + ip2 = ip_set_range_to_cidr(ip2, ip2_to, > + &e.cidr[1]); > ret = adtfn(set, &e, &ext, &ext, flags); > if (ret && !ip_set_eexist(ret, flags)) > return ret; > > ret = 0; > - ip2 = ip2_last + 1; > - } > + } while (ip2++ < ip2_to); > + ip2 = ip2_from; > } > - ip = ip_last + 1; > - } > + p = port; > + } while (ip++ < ip_to); > return ret; > } > >
Clean cherry-pick and with positive user feedback.
Acked-by: Po-Hsu Lin <po-hsu.lin@canonical.com>
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 0f164e986bf1..88b83d6d3084 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -168,7 +168,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); u32 ip = 0, ip_to = 0, p = 0, port, port_to; - u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2; + u32 ip2_from = 0, ip2_to = 0, ip2; bool with_ports = false; u8 cidr; int ret; @@ -269,22 +269,21 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ip_set_mask_from_to(ip2_from, ip2_to, e.cidr + 1); } - if (retried) + if (retried) { ip = ntohl(h->next.ip); + p = ntohs(h->next.port); + ip2 = ntohl(h->next.ip2); + } else { + p = port; + ip2 = ip2_from; + } for (; ip <= ip_to; ip++) { e.ip = htonl(ip); - p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) - : port; for (; p <= port_to; p++) { e.port = htons(p); - ip2 = retried && - ip == ntohl(h->next.ip) && - p == ntohs(h->next.port) - ? ntohl(h->next.ip2) : ip2_from; - while (ip2 <= ip2_to) { + do { e.ip2 = htonl(ip2); - ip2_last = ip_set_range_to_cidr(ip2, ip2_to, - &cidr); + ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr); e.cidr = cidr - 1; ret = adtfn(set, &e, &ext, &ext, flags); @@ -292,9 +291,10 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], return ret; ret = 0; - ip2 = ip2_last + 1; - } + } while (ip2++ < ip2_to); + ip2 = ip2_from; } + p = port; } return ret; } diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index 1c67a1761e45..5449e23af13a 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c @@ -143,7 +143,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_net4_elem e = { .cidr = HOST_MASK }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); - u32 ip = 0, ip_to = 0, last; + u32 ip = 0, ip_to = 0; int ret; if (tb[IPSET_ATTR_LINENO]) @@ -193,16 +193,15 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], } if (retried) ip = ntohl(h->next.ip); - while (ip <= ip_to) { + do { e.ip = htonl(ip); - last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr); ret = adtfn(set, &e, &ext, &ext, flags); if (ret && !ip_set_eexist(ret, flags)) return ret; ret = 0; - ip = last + 1; - } + } while (ip++ < ip_to); return ret; } diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index d417074f1c1a..f5164c1efce2 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c @@ -200,7 +200,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); - u32 ip = 0, ip_to = 0, last; + u32 ip = 0, ip_to = 0; int ret; if (tb[IPSET_ATTR_LINENO]) @@ -255,17 +255,16 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], if (retried) ip = ntohl(h->next.ip); - while (ip <= ip_to) { + do { e.ip = htonl(ip); - last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr); ret = adtfn(set, &e, &ext, &ext, flags); if (ret && !ip_set_eexist(ret, flags)) return ret; ret = 0; - ip = last + 1; - } + } while (ip++ < ip_to); return ret; } diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c index 7f9ae2e9645b..5a2b923bd81f 100644 --- a/net/netfilter/ipset/ip_set_hash_netnet.c +++ b/net/netfilter/ipset/ip_set_hash_netnet.c @@ -169,8 +169,8 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[], ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_netnet4_elem e = { }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); - u32 ip = 0, ip_to = 0, last; - u32 ip2 = 0, ip2_from = 0, ip2_to = 0, last2; + u32 ip = 0, ip_to = 0; + u32 ip2 = 0, ip2_from = 0, ip2_to = 0; int ret; if (tb[IPSET_ATTR_LINENO]) @@ -247,27 +247,27 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[], ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]); } - if (retried) + if (retried) { ip = ntohl(h->next.ip[0]); + ip2 = ntohl(h->next.ip[1]); + } else { + ip2 = ip2_from; + } - while (ip <= ip_to) { + do { e.ip[0] = htonl(ip); - last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); - ip2 = (retried && - ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1]) - : ip2_from; - while (ip2 <= ip2_to) { + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); + do { e.ip[1] = htonl(ip2); - last2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]); + ip2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]); ret = adtfn(set, &e, &ext, &ext, flags); if (ret && !ip_set_eexist(ret, flags)) return ret; ret = 0; - ip2 = last2 + 1; - } - ip = last + 1; - } + } while (ip2++ < ip2_to); + ip2 = ip2_from; + } while (ip++ < ip_to); return ret; } diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index e6ef382febe4..1a187be9ebc8 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c @@ -161,7 +161,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); - u32 port, port_to, p = 0, ip = 0, ip_to = 0, last; + u32 port, port_to, p = 0, ip = 0, ip_to = 0; bool with_ports = false; u8 cidr; int ret; @@ -239,25 +239,26 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], ip_set_mask_from_to(ip, ip_to, e.cidr + 1); } - if (retried) + if (retried) { ip = ntohl(h->next.ip); - while (ip <= ip_to) { + p = ntohs(h->next.port); + } else { + p = port; + } + do { e.ip = htonl(ip); - last = ip_set_range_to_cidr(ip, ip_to, &cidr); + ip = ip_set_range_to_cidr(ip, ip_to, &cidr); e.cidr = cidr - 1; - p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) - : port; for (; p <= port_to; p++) { e.port = htons(p); ret = adtfn(set, &e, &ext, &ext, flags); - if (ret && !ip_set_eexist(ret, flags)) return ret; ret = 0; } - ip = last + 1; - } + p = port; + } while (ip++ < ip_to); return ret; } diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c index 8602f2595a1a..d391485a6acd 100644 --- a/net/netfilter/ipset/ip_set_hash_netportnet.c +++ b/net/netfilter/ipset/ip_set_hash_netportnet.c @@ -184,8 +184,8 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_netportnet4_elem e = { }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); - u32 ip = 0, ip_to = 0, ip_last, p = 0, port, port_to; - u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2; + u32 ip = 0, ip_to = 0, p = 0, port, port_to; + u32 ip2_from = 0, ip2_to = 0, ip2; bool with_ports = false; int ret; @@ -288,33 +288,34 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]); } - if (retried) + if (retried) { ip = ntohl(h->next.ip[0]); + p = ntohs(h->next.port); + ip2 = ntohl(h->next.ip[1]); + } else { + p = port; + ip2 = ip2_from; + } - while (ip <= ip_to) { + do { e.ip[0] = htonl(ip); - ip_last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); - p = retried && ip == ntohl(h->next.ip[0]) ? ntohs(h->next.port) - : port; + ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); for (; p <= port_to; p++) { e.port = htons(p); - ip2 = (retried && ip == ntohl(h->next.ip[0]) && - p == ntohs(h->next.port)) ? ntohl(h->next.ip[1]) - : ip2_from; - while (ip2 <= ip2_to) { + do { e.ip[1] = htonl(ip2); - ip2_last = ip_set_range_to_cidr(ip2, ip2_to, - &e.cidr[1]); + ip2 = ip_set_range_to_cidr(ip2, ip2_to, + &e.cidr[1]); ret = adtfn(set, &e, &ext, &ext, flags); if (ret && !ip_set_eexist(ret, flags)) return ret; ret = 0; - ip2 = ip2_last + 1; - } + } while (ip2++ < ip2_to); + ip2 = ip2_from; } - ip = ip_last + 1; - } + p = port; + } while (ip++ < ip_to); return ret; }