netfilter: ipset: fix address ranges at hash:*port* types

The hash:*port* types with IPv4 silently ignored when address ranges
with non TCP/UDP were added/deleted from the set and used the first
address from the range only.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>

authored by Jozsef Kadlecsik and committed by Patrick McHardy 5e0c1eb7 b26fa4e0

+48 -94
+10
include/linux/netfilter/ipset/ip_set_getport.h
··· 18 extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, 19 __be16 *port); 20 21 #endif /*_IP_SET_GETPORT_H*/
··· 18 extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, 19 __be16 *port); 20 21 + static inline bool ip_set_proto_with_ports(u8 proto) 22 + { 23 + switch (proto) { 24 + case IPPROTO_TCP: 25 + case IPPROTO_UDP: 26 + return true; 27 + } 28 + return false; 29 + } 30 + 31 #endif /*_IP_SET_GETPORT_H*/
+10 -24
net/netfilter/ipset/ip_set_hash_ipport.c
··· 150 struct hash_ipport4_elem data = { }; 151 u32 ip, ip_to, p, port, port_to; 152 u32 timeout = h->timeout; 153 int ret; 154 155 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 173 174 if (tb[IPSET_ATTR_PROTO]) { 175 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 176 177 if (data.proto == 0) 178 return -IPSET_ERR_INVALID_PROTO; 179 } else 180 return -IPSET_ERR_MISSING_PROTO; 181 182 - switch (data.proto) { 183 - case IPPROTO_UDP: 184 - case IPPROTO_TCP: 185 - case IPPROTO_ICMP: 186 - break; 187 - default: 188 data.port = 0; 189 - break; 190 - } 191 192 if (tb[IPSET_ATTR_TIMEOUT]) { 193 if (!with_timeout(h->timeout)) ··· 190 } 191 192 if (adt == IPSET_TEST || 193 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 194 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 195 tb[IPSET_ATTR_PORT_TO])) { 196 ret = adtfn(set, &data, timeout); ··· 213 } else 214 ip_to = ip; 215 216 - port = ntohs(data.port); 217 - if (tb[IPSET_ATTR_PORT_TO]) { 218 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 219 if (port > port_to) 220 swap(port, port_to); 221 - } else 222 - port_to = port; 223 224 for (; !before(ip_to, ip); ip++) 225 for (p = port; p <= port_to; p++) { ··· 354 struct hash_ipport6_elem data = { }; 355 u32 port, port_to; 356 u32 timeout = h->timeout; 357 int ret; 358 359 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 379 380 if (tb[IPSET_ATTR_PROTO]) { 381 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 382 383 if (data.proto == 0) 384 return -IPSET_ERR_INVALID_PROTO; 385 } else 386 return -IPSET_ERR_MISSING_PROTO; 387 388 - switch (data.proto) { 389 - case IPPROTO_UDP: 390 - case IPPROTO_TCP: 391 - case IPPROTO_ICMPV6: 392 - break; 393 - default: 394 data.port = 0; 395 - break; 396 - } 397 398 if (tb[IPSET_ATTR_TIMEOUT]) { 399 if (!with_timeout(h->timeout)) ··· 395 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 396 } 397 398 - if (adt == IPSET_TEST || 399 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 400 - !tb[IPSET_ATTR_PORT_TO]) { 401 ret = adtfn(set, &data, timeout); 402 return ip_set_eexist(ret, flags) ? 0 : ret; 403 }
··· 150 struct hash_ipport4_elem data = { }; 151 u32 ip, ip_to, p, port, port_to; 152 u32 timeout = h->timeout; 153 + bool with_ports = false; 154 int ret; 155 156 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 172 173 if (tb[IPSET_ATTR_PROTO]) { 174 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 175 + with_ports = ip_set_proto_with_ports(data.proto); 176 177 if (data.proto == 0) 178 return -IPSET_ERR_INVALID_PROTO; 179 } else 180 return -IPSET_ERR_MISSING_PROTO; 181 182 + if (!(with_ports || data.proto == IPPROTO_ICMP)) 183 data.port = 0; 184 185 if (tb[IPSET_ATTR_TIMEOUT]) { 186 if (!with_timeout(h->timeout)) ··· 195 } 196 197 if (adt == IPSET_TEST || 198 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 199 tb[IPSET_ATTR_PORT_TO])) { 200 ret = adtfn(set, &data, timeout); ··· 219 } else 220 ip_to = ip; 221 222 + port_to = port = ntohs(data.port); 223 + if (with_ports && tb[IPSET_ATTR_PORT_TO]) { 224 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 225 if (port > port_to) 226 swap(port, port_to); 227 + } 228 229 for (; !before(ip_to, ip); ip++) 230 for (p = port; p <= port_to; p++) { ··· 361 struct hash_ipport6_elem data = { }; 362 u32 port, port_to; 363 u32 timeout = h->timeout; 364 + bool with_ports = false; 365 int ret; 366 367 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 385 386 if (tb[IPSET_ATTR_PROTO]) { 387 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 388 + with_ports = ip_set_proto_with_ports(data.proto); 389 390 if (data.proto == 0) 391 return -IPSET_ERR_INVALID_PROTO; 392 } else 393 return -IPSET_ERR_MISSING_PROTO; 394 395 + if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 396 data.port = 0; 397 398 if (tb[IPSET_ATTR_TIMEOUT]) { 399 if (!with_timeout(h->timeout)) ··· 407 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 408 } 409 410 + if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 411 ret = adtfn(set, &data, timeout); 412 return ip_set_eexist(ret, flags) ? 0 : ret; 413 }
+10 -24
net/netfilter/ipset/ip_set_hash_ipportip.c
··· 154 struct hash_ipportip4_elem data = { }; 155 u32 ip, ip_to, p, port, port_to; 156 u32 timeout = h->timeout; 157 int ret; 158 159 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 181 182 if (tb[IPSET_ATTR_PROTO]) { 183 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 184 185 if (data.proto == 0) 186 return -IPSET_ERR_INVALID_PROTO; 187 } else 188 return -IPSET_ERR_MISSING_PROTO; 189 190 - switch (data.proto) { 191 - case IPPROTO_UDP: 192 - case IPPROTO_TCP: 193 - case IPPROTO_ICMP: 194 - break; 195 - default: 196 data.port = 0; 197 - break; 198 - } 199 200 if (tb[IPSET_ATTR_TIMEOUT]) { 201 if (!with_timeout(h->timeout)) ··· 198 } 199 200 if (adt == IPSET_TEST || 201 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 202 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 203 tb[IPSET_ATTR_PORT_TO])) { 204 ret = adtfn(set, &data, timeout); ··· 221 } else 222 ip_to = ip; 223 224 - port = ntohs(data.port); 225 - if (tb[IPSET_ATTR_PORT_TO]) { 226 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 227 if (port > port_to) 228 swap(port, port_to); 229 - } else 230 - port_to = port; 231 232 for (; !before(ip_to, ip); ip++) 233 for (p = port; p <= port_to; p++) { ··· 368 struct hash_ipportip6_elem data = { }; 369 u32 port, port_to; 370 u32 timeout = h->timeout; 371 int ret; 372 373 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 397 398 if (tb[IPSET_ATTR_PROTO]) { 399 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 400 401 if (data.proto == 0) 402 return -IPSET_ERR_INVALID_PROTO; 403 } else 404 return -IPSET_ERR_MISSING_PROTO; 405 406 - switch (data.proto) { 407 - case IPPROTO_UDP: 408 - case IPPROTO_TCP: 409 - case IPPROTO_ICMPV6: 410 - break; 411 - default: 412 data.port = 0; 413 - break; 414 - } 415 416 if (tb[IPSET_ATTR_TIMEOUT]) { 417 if (!with_timeout(h->timeout)) ··· 413 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 414 } 415 416 - if (adt == IPSET_TEST || 417 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 418 - !tb[IPSET_ATTR_PORT_TO]) { 419 ret = adtfn(set, &data, timeout); 420 return ip_set_eexist(ret, flags) ? 0 : ret; 421 }
··· 154 struct hash_ipportip4_elem data = { }; 155 u32 ip, ip_to, p, port, port_to; 156 u32 timeout = h->timeout; 157 + bool with_ports = false; 158 int ret; 159 160 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 180 181 if (tb[IPSET_ATTR_PROTO]) { 182 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 183 + with_ports = ip_set_proto_with_ports(data.proto); 184 185 if (data.proto == 0) 186 return -IPSET_ERR_INVALID_PROTO; 187 } else 188 return -IPSET_ERR_MISSING_PROTO; 189 190 + if (!(with_ports || data.proto == IPPROTO_ICMP)) 191 data.port = 0; 192 193 if (tb[IPSET_ATTR_TIMEOUT]) { 194 if (!with_timeout(h->timeout)) ··· 203 } 204 205 if (adt == IPSET_TEST || 206 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 207 tb[IPSET_ATTR_PORT_TO])) { 208 ret = adtfn(set, &data, timeout); ··· 227 } else 228 ip_to = ip; 229 230 + port_to = port = ntohs(data.port); 231 + if (with_ports && tb[IPSET_ATTR_PORT_TO]) { 232 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 233 if (port > port_to) 234 swap(port, port_to); 235 + } 236 237 for (; !before(ip_to, ip); ip++) 238 for (p = port; p <= port_to; p++) { ··· 375 struct hash_ipportip6_elem data = { }; 376 u32 port, port_to; 377 u32 timeout = h->timeout; 378 + bool with_ports = false; 379 int ret; 380 381 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 403 404 if (tb[IPSET_ATTR_PROTO]) { 405 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 406 + with_ports = ip_set_proto_with_ports(data.proto); 407 408 if (data.proto == 0) 409 return -IPSET_ERR_INVALID_PROTO; 410 } else 411 return -IPSET_ERR_MISSING_PROTO; 412 413 + if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 414 data.port = 0; 415 416 if (tb[IPSET_ATTR_TIMEOUT]) { 417 if (!with_timeout(h->timeout)) ··· 425 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 426 } 427 428 + if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 429 ret = adtfn(set, &data, timeout); 430 return ip_set_eexist(ret, flags) ? 0 : ret; 431 }
+10 -24
net/netfilter/ipset/ip_set_hash_ipportnet.c
··· 174 struct hash_ipportnet4_elem data = { .cidr = HOST_MASK }; 175 u32 ip, ip_to, p, port, port_to; 176 u32 timeout = h->timeout; 177 int ret; 178 179 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 209 210 if (tb[IPSET_ATTR_PROTO]) { 211 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 212 213 if (data.proto == 0) 214 return -IPSET_ERR_INVALID_PROTO; 215 } else 216 return -IPSET_ERR_MISSING_PROTO; 217 218 - switch (data.proto) { 219 - case IPPROTO_UDP: 220 - case IPPROTO_TCP: 221 - case IPPROTO_ICMP: 222 - break; 223 - default: 224 data.port = 0; 225 - break; 226 - } 227 228 if (tb[IPSET_ATTR_TIMEOUT]) { 229 if (!with_timeout(h->timeout)) ··· 226 } 227 228 if (adt == IPSET_TEST || 229 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 230 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 231 tb[IPSET_ATTR_PORT_TO])) { 232 ret = adtfn(set, &data, timeout); ··· 249 } else 250 ip_to = ip; 251 252 - port = ntohs(data.port); 253 - if (tb[IPSET_ATTR_PORT_TO]) { 254 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 255 if (port > port_to) 256 swap(port, port_to); 257 - } else 258 - port_to = port; 259 260 for (; !before(ip_to, ip); ip++) 261 for (p = port; p <= port_to; p++) { ··· 422 struct hash_ipportnet6_elem data = { .cidr = HOST_MASK }; 423 u32 port, port_to; 424 u32 timeout = h->timeout; 425 int ret; 426 427 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 459 460 if (tb[IPSET_ATTR_PROTO]) { 461 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 462 463 if (data.proto == 0) 464 return -IPSET_ERR_INVALID_PROTO; 465 } else 466 return -IPSET_ERR_MISSING_PROTO; 467 468 - switch (data.proto) { 469 - case IPPROTO_UDP: 470 - case IPPROTO_TCP: 471 - case IPPROTO_ICMPV6: 472 - break; 473 - default: 474 data.port = 0; 475 - break; 476 - } 477 478 if (tb[IPSET_ATTR_TIMEOUT]) { 479 if (!with_timeout(h->timeout)) ··· 475 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 476 } 477 478 - if (adt == IPSET_TEST || 479 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 480 - !tb[IPSET_ATTR_PORT_TO]) { 481 ret = adtfn(set, &data, timeout); 482 return ip_set_eexist(ret, flags) ? 0 : ret; 483 }
··· 174 struct hash_ipportnet4_elem data = { .cidr = HOST_MASK }; 175 u32 ip, ip_to, p, port, port_to; 176 u32 timeout = h->timeout; 177 + bool with_ports = false; 178 int ret; 179 180 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 208 209 if (tb[IPSET_ATTR_PROTO]) { 210 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 211 + with_ports = ip_set_proto_with_ports(data.proto); 212 213 if (data.proto == 0) 214 return -IPSET_ERR_INVALID_PROTO; 215 } else 216 return -IPSET_ERR_MISSING_PROTO; 217 218 + if (!(with_ports || data.proto == IPPROTO_ICMP)) 219 data.port = 0; 220 221 if (tb[IPSET_ATTR_TIMEOUT]) { 222 if (!with_timeout(h->timeout)) ··· 231 } 232 233 if (adt == IPSET_TEST || 234 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 235 tb[IPSET_ATTR_PORT_TO])) { 236 ret = adtfn(set, &data, timeout); ··· 255 } else 256 ip_to = ip; 257 258 + port_to = port = ntohs(data.port); 259 + if (with_ports && tb[IPSET_ATTR_PORT_TO]) { 260 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 261 if (port > port_to) 262 swap(port, port_to); 263 + } 264 265 for (; !before(ip_to, ip); ip++) 266 for (p = port; p <= port_to; p++) { ··· 429 struct hash_ipportnet6_elem data = { .cidr = HOST_MASK }; 430 u32 port, port_to; 431 u32 timeout = h->timeout; 432 + bool with_ports = false; 433 int ret; 434 435 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || ··· 465 466 if (tb[IPSET_ATTR_PROTO]) { 467 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 468 + with_ports = ip_set_proto_with_ports(data.proto); 469 470 if (data.proto == 0) 471 return -IPSET_ERR_INVALID_PROTO; 472 } else 473 return -IPSET_ERR_MISSING_PROTO; 474 475 + if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 476 data.port = 0; 477 478 if (tb[IPSET_ATTR_TIMEOUT]) { 479 if (!with_timeout(h->timeout)) ··· 487 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 488 } 489 490 + if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 491 ret = adtfn(set, &data, timeout); 492 return ip_set_eexist(ret, flags) ? 0 : ret; 493 }
+8 -22
net/netfilter/ipset/ip_set_hash_netport.c
··· 170 struct hash_netport4_elem data = { .cidr = HOST_MASK }; 171 u32 port, port_to; 172 u32 timeout = h->timeout; 173 int ret; 174 175 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 199 200 if (tb[IPSET_ATTR_PROTO]) { 201 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 202 203 if (data.proto == 0) 204 return -IPSET_ERR_INVALID_PROTO; 205 } else 206 return -IPSET_ERR_MISSING_PROTO; 207 208 - switch (data.proto) { 209 - case IPPROTO_UDP: 210 - case IPPROTO_TCP: 211 - case IPPROTO_ICMP: 212 - break; 213 - default: 214 data.port = 0; 215 - break; 216 - } 217 218 if (tb[IPSET_ATTR_TIMEOUT]) { 219 if (!with_timeout(h->timeout)) ··· 215 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 216 } 217 218 - if (adt == IPSET_TEST || 219 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 220 - !tb[IPSET_ATTR_PORT_TO]) { 221 ret = adtfn(set, &data, timeout); 222 return ip_set_eexist(ret, flags) ? 0 : ret; 223 } ··· 383 struct hash_netport6_elem data = { .cidr = HOST_MASK }; 384 u32 port, port_to; 385 u32 timeout = h->timeout; 386 int ret; 387 388 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 412 413 if (tb[IPSET_ATTR_PROTO]) { 414 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 415 416 if (data.proto == 0) 417 return -IPSET_ERR_INVALID_PROTO; 418 } else 419 return -IPSET_ERR_MISSING_PROTO; 420 421 - switch (data.proto) { 422 - case IPPROTO_UDP: 423 - case IPPROTO_TCP: 424 - case IPPROTO_ICMPV6: 425 - break; 426 - default: 427 data.port = 0; 428 - break; 429 - } 430 431 if (tb[IPSET_ATTR_TIMEOUT]) { 432 if (!with_timeout(h->timeout)) ··· 428 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 429 } 430 431 - if (adt == IPSET_TEST || 432 - !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || 433 - !tb[IPSET_ATTR_PORT_TO]) { 434 ret = adtfn(set, &data, timeout); 435 return ip_set_eexist(ret, flags) ? 0 : ret; 436 }
··· 170 struct hash_netport4_elem data = { .cidr = HOST_MASK }; 171 u32 port, port_to; 172 u32 timeout = h->timeout; 173 + bool with_ports = false; 174 int ret; 175 176 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 198 199 if (tb[IPSET_ATTR_PROTO]) { 200 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 201 + with_ports = ip_set_proto_with_ports(data.proto); 202 203 if (data.proto == 0) 204 return -IPSET_ERR_INVALID_PROTO; 205 } else 206 return -IPSET_ERR_MISSING_PROTO; 207 208 + if (!(with_ports || data.proto == IPPROTO_ICMP)) 209 data.port = 0; 210 211 if (tb[IPSET_ATTR_TIMEOUT]) { 212 if (!with_timeout(h->timeout)) ··· 220 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 221 } 222 223 + if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 224 ret = adtfn(set, &data, timeout); 225 return ip_set_eexist(ret, flags) ? 0 : ret; 226 } ··· 390 struct hash_netport6_elem data = { .cidr = HOST_MASK }; 391 u32 port, port_to; 392 u32 timeout = h->timeout; 393 + bool with_ports = false; 394 int ret; 395 396 if (unlikely(!tb[IPSET_ATTR_IP] || ··· 418 419 if (tb[IPSET_ATTR_PROTO]) { 420 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 421 + with_ports = ip_set_proto_with_ports(data.proto); 422 423 if (data.proto == 0) 424 return -IPSET_ERR_INVALID_PROTO; 425 } else 426 return -IPSET_ERR_MISSING_PROTO; 427 428 + if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 429 data.port = 0; 430 431 if (tb[IPSET_ATTR_TIMEOUT]) { 432 if (!with_timeout(h->timeout)) ··· 440 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 441 } 442 443 + if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 444 ret = adtfn(set, &data, timeout); 445 return ip_set_eexist(ret, flags) ? 0 : ret; 446 }