1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (C) 2011-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 3 4 /* Kernel module implementing an IP set type: the hash:net,iface type */ 5 6 #include <linux/jhash.h> 7 #include <linux/module.h> 8 #include <linux/ip.h> 9 #include <linux/skbuff.h> 10 #include <linux/errno.h> 11 #include <linux/random.h> 12 #include <net/ip.h> 13 #include <net/ipv6.h> 14 #include <net/netlink.h> 15 16 #include <linux/netfilter.h> 17 #include <linux/netfilter_bridge.h> 18 #include <linux/netfilter/ipset/pfxlen.h> 19 #include <linux/netfilter/ipset/ip_set.h> 20 #include <linux/netfilter/ipset/ip_set_hash.h> 21 22 #define IPSET_TYPE_REV_MIN 0 23 /* 1 nomatch flag support added */ 24 /* 2 /0 support added */ 25 /* 3 Counters support added */ 26 /* 4 Comments support added */ 27 /* 5 Forceadd support added */ 28 #define IPSET_TYPE_REV_MAX 6 /* skbinfo support added */ 29 30 MODULE_LICENSE("GPL"); 31 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 32 IP_SET_MODULE_DESC("hash:net,iface", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 33 MODULE_ALIAS("ip_set_hash:net,iface"); 34 35 /* Type specific function prefix */ 36 #define HTYPE hash_netiface 37 #define IP_SET_HASH_WITH_NETS 38 #define IP_SET_HASH_WITH_MULTI 39 #define IP_SET_HASH_WITH_NET0 40 41 #define STRLCPY(a, b) strlcpy(a, b, IFNAMSIZ) 42 43 /* IPv4 variant */ 44 45 struct hash_netiface4_elem_hashed { 46 __be32 ip; 47 u8 physdev; 48 u8 cidr; 49 u8 nomatch; 50 u8 elem; 51 }; 52 53 /* Member elements */ 54 struct hash_netiface4_elem { 55 __be32 ip; 56 u8 physdev; 57 u8 cidr; 58 u8 nomatch; 59 u8 elem; 60 char iface[IFNAMSIZ]; 61 }; 62 63 /* Common functions */ 64 65 static inline bool 66 hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1, 67 const struct hash_netiface4_elem *ip2, 68 u32 *multi) 69 { 70 return ip1->ip == ip2->ip && 71 ip1->cidr == ip2->cidr && 72 (++*multi) && 73 ip1->physdev == ip2->physdev && 74 strcmp(ip1->iface, ip2->iface) == 0; 75 } 76 77 static inline int 78 hash_netiface4_do_data_match(const struct hash_netiface4_elem *elem) 79 { 80 return elem->nomatch ? -ENOTEMPTY : 1; 81 } 82 83 static inline void 84 hash_netiface4_data_set_flags(struct hash_netiface4_elem *elem, u32 flags) 85 { 86 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH; 87 } 88 89 static inline void 90 hash_netiface4_data_reset_flags(struct hash_netiface4_elem *elem, u8 *flags) 91 { 92 swap(*flags, elem->nomatch); 93 } 94 95 static inline void 96 hash_netiface4_data_netmask(struct hash_netiface4_elem *elem, u8 cidr) 97 { 98 elem->ip &= ip_set_netmask(cidr); 99 elem->cidr = cidr; 100 } 101 102 static bool 103 hash_netiface4_data_list(struct sk_buff *skb, 104 const struct hash_netiface4_elem *data) 105 { 106 u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0; 107 108 if (data->nomatch) 109 flags |= IPSET_FLAG_NOMATCH; 110 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) || 111 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) || 112 nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) || 113 (flags && 114 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags)))) 115 goto nla_put_failure; 116 return false; 117 118 nla_put_failure: 119 return true; 120 } 121 122 static inline void 123 hash_netiface4_data_next(struct hash_netiface4_elem *next, 124 const struct hash_netiface4_elem *d) 125 { 126 next->ip = d->ip; 127 } 128 129 #define MTYPE hash_netiface4 130 #define HOST_MASK 32 131 #define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed) 132 #include "ip_set_hash_gen.h" 133 134 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 135 static const char *get_physindev_name(const struct sk_buff *skb) 136 { 137 struct net_device *dev = nf_bridge_get_physindev(skb); 138 139 return dev ? dev->name : NULL; 140 } 141 142 static const char *get_physoutdev_name(const struct sk_buff *skb) 143 { 144 struct net_device *dev = nf_bridge_get_physoutdev(skb); 145 146 return dev ? dev->name : NULL; 147 } 148 #endif 149 150 static int 151 hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, 152 const struct xt_action_param *par, 153 enum ipset_adt adt, struct ip_set_adt_opt *opt) 154 { 155 struct hash_netiface4 *h = set->data; 156 ipset_adtfn adtfn = set->variant->adt[adt]; 157 struct hash_netiface4_elem e = { 158 .cidr = INIT_CIDR(h->nets[0].cidr[0], HOST_MASK), 159 .elem = 1, 160 }; 161 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); 162 163 if (adt == IPSET_TEST) 164 e.cidr = HOST_MASK; 165 166 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip); 167 e.ip &= ip_set_netmask(e.cidr); 168 169 #define IFACE(dir) (par->state->dir ? par->state->dir->name : "") 170 #define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC) 171 172 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 173 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 174 const char *eiface = SRCDIR ? get_physindev_name(skb) : 175 get_physoutdev_name(skb); 176 177 if (!eiface) 178 return -EINVAL; 179 STRLCPY(e.iface, eiface); 180 e.physdev = 1; 181 #endif 182 } else { 183 STRLCPY(e.iface, SRCDIR ? IFACE(in) : IFACE(out)); 184 } 185 186 if (strlen(e.iface) == 0) 187 return -EINVAL; 188 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); 189 } 190 191 static int 192 hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], 193 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 194 { 195 struct hash_netiface4 *h = set->data; 196 ipset_adtfn adtfn = set->variant->adt[adt]; 197 struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 }; 198 struct ip_set_ext ext = IP_SET_INIT_UEXT(set); 199 u32 ip = 0, ip_to = 0; 200 int ret; 201 202 if (tb[IPSET_ATTR_LINENO]) 203 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 204 205 if (unlikely(!tb[IPSET_ATTR_IP] || 206 !tb[IPSET_ATTR_IFACE] || 207 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 208 return -IPSET_ERR_PROTOCOL; 209 210 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 211 if (ret) 212 return ret; 213 214 ret = ip_set_get_extensions(set, tb, &ext); 215 if (ret) 216 return ret; 217 218 if (tb[IPSET_ATTR_CIDR]) { 219 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 220 if (e.cidr > HOST_MASK) 221 return -IPSET_ERR_INVALID_CIDR; 222 } 223 nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ); 224 225 if (tb[IPSET_ATTR_CADT_FLAGS]) { 226 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 227 228 if (cadt_flags & IPSET_FLAG_PHYSDEV) 229 e.physdev = 1; 230 if (cadt_flags & IPSET_FLAG_NOMATCH) 231 flags |= (IPSET_FLAG_NOMATCH << 16); 232 } 233 if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { 234 e.ip = htonl(ip & ip_set_hostmask(e.cidr)); 235 ret = adtfn(set, &e, &ext, &ext, flags); 236 return ip_set_enomatch(ret, flags, adt, set) ? -ret : 237 ip_set_eexist(ret, flags) ? 0 : ret; 238 } 239 240 if (tb[IPSET_ATTR_IP_TO]) { 241 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); 242 if (ret) 243 return ret; 244 if (ip_to < ip) 245 swap(ip, ip_to); 246 if (ip + UINT_MAX == ip_to) 247 return -IPSET_ERR_HASH_RANGE; 248 } else { 249 ip_set_mask_from_to(ip, ip_to, e.cidr); 250 } 251 252 if (retried) 253 ip = ntohl(h->next.ip); 254 do { 255 e.ip = htonl(ip); 256 ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr); 257 ret = adtfn(set, &e, &ext, &ext, flags); 258 259 if (ret && !ip_set_eexist(ret, flags)) 260 return ret; 261 262 ret = 0; 263 } while (ip++ < ip_to); 264 return ret; 265 } 266 267 /* IPv6 variant */ 268 269 struct hash_netiface6_elem_hashed { 270 union nf_inet_addr ip; 271 u8 physdev; 272 u8 cidr; 273 u8 nomatch; 274 u8 elem; 275 }; 276 277 struct hash_netiface6_elem { 278 union nf_inet_addr ip; 279 u8 physdev; 280 u8 cidr; 281 u8 nomatch; 282 u8 elem; 283 char iface[IFNAMSIZ]; 284 }; 285 286 /* Common functions */ 287 288 static inline bool 289 hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1, 290 const struct hash_netiface6_elem *ip2, 291 u32 *multi) 292 { 293 return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) && 294 ip1->cidr == ip2->cidr && 295 (++*multi) && 296 ip1->physdev == ip2->physdev && 297 strcmp(ip1->iface, ip2->iface) == 0; 298 } 299 300 static inline int 301 hash_netiface6_do_data_match(const struct hash_netiface6_elem *elem) 302 { 303 return elem->nomatch ? -ENOTEMPTY : 1; 304 } 305 306 static inline void 307 hash_netiface6_data_set_flags(struct hash_netiface6_elem *elem, u32 flags) 308 { 309 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH; 310 } 311 312 static inline void 313 hash_netiface6_data_reset_flags(struct hash_netiface6_elem *elem, u8 *flags) 314 { 315 swap(*flags, elem->nomatch); 316 } 317 318 static inline void 319 hash_netiface6_data_netmask(struct hash_netiface6_elem *elem, u8 cidr) 320 { 321 ip6_netmask(&elem->ip, cidr); 322 elem->cidr = cidr; 323 } 324 325 static bool 326 hash_netiface6_data_list(struct sk_buff *skb, 327 const struct hash_netiface6_elem *data) 328 { 329 u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0; 330 331 if (data->nomatch) 332 flags |= IPSET_FLAG_NOMATCH; 333 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) || 334 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) || 335 nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) || 336 (flags && 337 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags)))) 338 goto nla_put_failure; 339 return false; 340 341 nla_put_failure: 342 return true; 343 } 344 345 static inline void 346 hash_netiface6_data_next(struct hash_netiface6_elem *next, 347 const struct hash_netiface6_elem *d) 348 { 349 } 350 351 #undef MTYPE 352 #undef HOST_MASK 353 354 #define MTYPE hash_netiface6 355 #define HOST_MASK 128 356 #define HKEY_DATALEN sizeof(struct hash_netiface6_elem_hashed) 357 #define IP_SET_EMIT_CREATE 358 #include "ip_set_hash_gen.h" 359 360 static int 361 hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb, 362 const struct xt_action_param *par, 363 enum ipset_adt adt, struct ip_set_adt_opt *opt) 364 { 365 struct hash_netiface6 *h = set->data; 366 ipset_adtfn adtfn = set->variant->adt[adt]; 367 struct hash_netiface6_elem e = { 368 .cidr = INIT_CIDR(h->nets[0].cidr[0], HOST_MASK), 369 .elem = 1, 370 }; 371 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); 372 373 if (adt == IPSET_TEST) 374 e.cidr = HOST_MASK; 375 376 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6); 377 ip6_netmask(&e.ip, e.cidr); 378 379 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 380 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 381 const char *eiface = SRCDIR ? get_physindev_name(skb) : 382 get_physoutdev_name(skb); 383 384 if (!eiface) 385 return -EINVAL; 386 STRLCPY(e.iface, eiface); 387 e.physdev = 1; 388 #endif 389 } else { 390 STRLCPY(e.iface, SRCDIR ? IFACE(in) : IFACE(out)); 391 } 392 393 if (strlen(e.iface) == 0) 394 return -EINVAL; 395 396 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); 397 } 398 399 static int 400 hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], 401 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 402 { 403 ipset_adtfn adtfn = set->variant->adt[adt]; 404 struct hash_netiface6_elem e = { .cidr = HOST_MASK, .elem = 1 }; 405 struct ip_set_ext ext = IP_SET_INIT_UEXT(set); 406 int ret; 407 408 if (tb[IPSET_ATTR_LINENO]) 409 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 410 411 if (unlikely(!tb[IPSET_ATTR_IP] || 412 !tb[IPSET_ATTR_IFACE] || 413 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 414 return -IPSET_ERR_PROTOCOL; 415 if (unlikely(tb[IPSET_ATTR_IP_TO])) 416 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; 417 418 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip); 419 if (ret) 420 return ret; 421 422 ret = ip_set_get_extensions(set, tb, &ext); 423 if (ret) 424 return ret; 425 426 if (tb[IPSET_ATTR_CIDR]) { 427 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 428 if (e.cidr > HOST_MASK) 429 return -IPSET_ERR_INVALID_CIDR; 430 } 431 432 ip6_netmask(&e.ip, e.cidr); 433 434 nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ); 435 436 if (tb[IPSET_ATTR_CADT_FLAGS]) { 437 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 438 439 if (cadt_flags & IPSET_FLAG_PHYSDEV) 440 e.physdev = 1; 441 if (cadt_flags & IPSET_FLAG_NOMATCH) 442 flags |= (IPSET_FLAG_NOMATCH << 16); 443 } 444 445 ret = adtfn(set, &e, &ext, &ext, flags); 446 447 return ip_set_enomatch(ret, flags, adt, set) ? -ret : 448 ip_set_eexist(ret, flags) ? 0 : ret; 449 } 450 451 static struct ip_set_type hash_netiface_type __read_mostly = { 452 .name = "hash:net,iface", 453 .protocol = IPSET_PROTOCOL, 454 .features = IPSET_TYPE_IP | IPSET_TYPE_IFACE | 455 IPSET_TYPE_NOMATCH, 456 .dimension = IPSET_DIM_TWO, 457 .family = NFPROTO_UNSPEC, 458 .revision_min = IPSET_TYPE_REV_MIN, 459 .revision_max = IPSET_TYPE_REV_MAX, 460 .create = hash_netiface_create, 461 .create_policy = { 462 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 463 [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, 464 [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, 465 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 466 [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, 467 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 468 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 469 }, 470 .adt_policy = { 471 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 472 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, 473 [IPSET_ATTR_IFACE] = { .type = NLA_NUL_STRING, 474 .len = IFNAMSIZ - 1 }, 475 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 476 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 477 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 478 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 479 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 480 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 481 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING, 482 .len = IPSET_MAX_COMMENT_SIZE }, 483 [IPSET_ATTR_SKBMARK] = { .type = NLA_U64 }, 484 [IPSET_ATTR_SKBPRIO] = { .type = NLA_U32 }, 485 [IPSET_ATTR_SKBQUEUE] = { .type = NLA_U16 }, 486 }, 487 .me = THIS_MODULE, 488 }; 489 490 static int __init 491 hash_netiface_init(void) 492 { 493 return ip_set_type_register(&hash_netiface_type); 494 } 495 496 static void __exit 497 hash_netiface_fini(void) 498 { 499 rcu_barrier(); 500 ip_set_type_unregister(&hash_netiface_type); 501 } 502 503 module_init(hash_netiface_init); 504 module_exit(hash_netiface_fini); 505