1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 3 4 /* Kernel module implementing an IP set type: the hash:net 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/ipset/pfxlen.h> 18 #include <linux/netfilter/ipset/ip_set.h> 19 #include <linux/netfilter/ipset/ip_set_hash.h> 20 21 #define IPSET_TYPE_REV_MIN 0 22 /* 1 Range as input support for IPv4 added */ 23 /* 2 nomatch flag support added */ 24 /* 3 Counters support added */ 25 /* 4 Comments support added */ 26 /* 5 Forceadd support added */ 27 #define IPSET_TYPE_REV_MAX 6 /* skbinfo mapping support added */ 28 29 MODULE_LICENSE("GPL"); 30 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 31 IP_SET_MODULE_DESC("hash:net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 32 MODULE_ALIAS("ip_set_hash:net"); 33 34 /* Type specific function prefix */ 35 #define HTYPE hash_net 36 #define IP_SET_HASH_WITH_NETS 37 38 /* IPv4 variant */ 39 40 /* Member elements */ 41 struct hash_net4_elem { 42 __be32 ip; 43 u16 padding0; 44 u8 nomatch; 45 u8 cidr; 46 }; 47 48 /* Common functions */ 49 50 static bool 51 hash_net4_data_equal(const struct hash_net4_elem *ip1, 52 const struct hash_net4_elem *ip2, 53 u32 *multi) 54 { 55 return ip1->ip == ip2->ip && 56 ip1->cidr == ip2->cidr; 57 } 58 59 static int 60 hash_net4_do_data_match(const struct hash_net4_elem *elem) 61 { 62 return elem->nomatch ? -ENOTEMPTY : 1; 63 } 64 65 static void 66 hash_net4_data_set_flags(struct hash_net4_elem *elem, u32 flags) 67 { 68 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH; 69 } 70 71 static void 72 hash_net4_data_reset_flags(struct hash_net4_elem *elem, u8 *flags) 73 { 74 swap(*flags, elem->nomatch); 75 } 76 77 static void 78 hash_net4_data_netmask(struct hash_net4_elem *elem, u8 cidr) 79 { 80 elem->ip &= ip_set_netmask(cidr); 81 elem->cidr = cidr; 82 } 83 84 static bool 85 hash_net4_data_list(struct sk_buff *skb, const struct hash_net4_elem *data) 86 { 87 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0; 88 89 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) || 90 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) || 91 (flags && 92 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags)))) 93 goto nla_put_failure; 94 return false; 95 96 nla_put_failure: 97 return true; 98 } 99 100 static void 101 hash_net4_data_next(struct hash_net4_elem *next, 102 const struct hash_net4_elem *d) 103 { 104 next->ip = d->ip; 105 } 106 107 #define MTYPE hash_net4 108 #define HOST_MASK 32 109 #include "ip_set_hash_gen.h" 110 111 static int 112 hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb, 113 const struct xt_action_param *par, 114 enum ipset_adt adt, struct ip_set_adt_opt *opt) 115 { 116 const struct hash_net4 *h = set->data; 117 ipset_adtfn adtfn = set->variant->adt[adt]; 118 struct hash_net4_elem e = { 119 .cidr = INIT_CIDR(h->nets[0].cidr[0], HOST_MASK), 120 }; 121 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); 122 123 if (e.cidr == 0) 124 return -EINVAL; 125 if (adt == IPSET_TEST) 126 e.cidr = HOST_MASK; 127 128 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip); 129 e.ip &= ip_set_netmask(e.cidr); 130 131 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); 132 } 133 134 static int 135 hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], 136 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 137 { 138 const struct hash_net4 *h = set->data; 139 ipset_adtfn adtfn = set->variant->adt[adt]; 140 struct hash_net4_elem e = { .cidr = HOST_MASK }; 141 struct ip_set_ext ext = IP_SET_INIT_UEXT(set); 142 u32 ip = 0, ip_to = 0; 143 int ret; 144 145 if (tb[IPSET_ATTR_LINENO]) 146 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 147 148 if (unlikely(!tb[IPSET_ATTR_IP] || 149 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 150 return -IPSET_ERR_PROTOCOL; 151 152 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 153 if (ret) 154 return ret; 155 156 ret = ip_set_get_extensions(set, tb, &ext); 157 if (ret) 158 return ret; 159 160 if (tb[IPSET_ATTR_CIDR]) { 161 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 162 if (!e.cidr || e.cidr > HOST_MASK) 163 return -IPSET_ERR_INVALID_CIDR; 164 } 165 166 if (tb[IPSET_ATTR_CADT_FLAGS]) { 167 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 168 169 if (cadt_flags & IPSET_FLAG_NOMATCH) 170 flags |= (IPSET_FLAG_NOMATCH << 16); 171 } 172 173 if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { 174 e.ip = htonl(ip & ip_set_hostmask(e.cidr)); 175 ret = adtfn(set, &e, &ext, &ext, flags); 176 return ip_set_enomatch(ret, flags, adt, set) ? -ret : 177 ip_set_eexist(ret, flags) ? 0 : ret; 178 } 179 180 ip_to = ip; 181 if (tb[IPSET_ATTR_IP_TO]) { 182 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); 183 if (ret) 184 return ret; 185 if (ip_to < ip) 186 swap(ip, ip_to); 187 if (ip + UINT_MAX == ip_to) 188 return -IPSET_ERR_HASH_RANGE; 189 } 190 if (retried) 191 ip = ntohl(h->next.ip); 192 do { 193 e.ip = htonl(ip); 194 ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr); 195 ret = adtfn(set, &e, &ext, &ext, flags); 196 if (ret && !ip_set_eexist(ret, flags)) 197 return ret; 198 199 ret = 0; 200 } while (ip++ < ip_to); 201 return ret; 202 } 203 204 /* IPv6 variant */ 205 206 struct hash_net6_elem { 207 union nf_inet_addr ip; 208 u16 padding0; 209 u8 nomatch; 210 u8 cidr; 211 }; 212 213 /* Common functions */ 214 215 static bool 216 hash_net6_data_equal(const struct hash_net6_elem *ip1, 217 const struct hash_net6_elem *ip2, 218 u32 *multi) 219 { 220 return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) && 221 ip1->cidr == ip2->cidr; 222 } 223 224 static int 225 hash_net6_do_data_match(const struct hash_net6_elem *elem) 226 { 227 return elem->nomatch ? -ENOTEMPTY : 1; 228 } 229 230 static void 231 hash_net6_data_set_flags(struct hash_net6_elem *elem, u32 flags) 232 { 233 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH; 234 } 235 236 static void 237 hash_net6_data_reset_flags(struct hash_net6_elem *elem, u8 *flags) 238 { 239 swap(*flags, elem->nomatch); 240 } 241 242 static void 243 hash_net6_data_netmask(struct hash_net6_elem *elem, u8 cidr) 244 { 245 ip6_netmask(&elem->ip, cidr); 246 elem->cidr = cidr; 247 } 248 249 static bool 250 hash_net6_data_list(struct sk_buff *skb, const struct hash_net6_elem *data) 251 { 252 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0; 253 254 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) || 255 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) || 256 (flags && 257 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags)))) 258 goto nla_put_failure; 259 return false; 260 261 nla_put_failure: 262 return true; 263 } 264 265 static void 266 hash_net6_data_next(struct hash_net6_elem *next, 267 const struct hash_net6_elem *d) 268 { 269 } 270 271 #undef MTYPE 272 #undef HOST_MASK 273 274 #define MTYPE hash_net6 275 #define HOST_MASK 128 276 #define IP_SET_EMIT_CREATE 277 #include "ip_set_hash_gen.h" 278 279 static int 280 hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb, 281 const struct xt_action_param *par, 282 enum ipset_adt adt, struct ip_set_adt_opt *opt) 283 { 284 const struct hash_net6 *h = set->data; 285 ipset_adtfn adtfn = set->variant->adt[adt]; 286 struct hash_net6_elem e = { 287 .cidr = INIT_CIDR(h->nets[0].cidr[0], HOST_MASK), 288 }; 289 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); 290 291 if (e.cidr == 0) 292 return -EINVAL; 293 if (adt == IPSET_TEST) 294 e.cidr = HOST_MASK; 295 296 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6); 297 ip6_netmask(&e.ip, e.cidr); 298 299 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); 300 } 301 302 static int 303 hash_net6_uadt(struct ip_set *set, struct nlattr *tb[], 304 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 305 { 306 ipset_adtfn adtfn = set->variant->adt[adt]; 307 struct hash_net6_elem e = { .cidr = HOST_MASK }; 308 struct ip_set_ext ext = IP_SET_INIT_UEXT(set); 309 int ret; 310 311 if (tb[IPSET_ATTR_LINENO]) 312 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 313 314 if (unlikely(!tb[IPSET_ATTR_IP] || 315 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 316 return -IPSET_ERR_PROTOCOL; 317 if (unlikely(tb[IPSET_ATTR_IP_TO])) 318 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; 319 320 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip); 321 if (ret) 322 return ret; 323 324 ret = ip_set_get_extensions(set, tb, &ext); 325 if (ret) 326 return ret; 327 328 if (tb[IPSET_ATTR_CIDR]) { 329 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 330 if (!e.cidr || e.cidr > HOST_MASK) 331 return -IPSET_ERR_INVALID_CIDR; 332 } 333 334 ip6_netmask(&e.ip, e.cidr); 335 336 if (tb[IPSET_ATTR_CADT_FLAGS]) { 337 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 338 339 if (cadt_flags & IPSET_FLAG_NOMATCH) 340 flags |= (IPSET_FLAG_NOMATCH << 16); 341 } 342 343 ret = adtfn(set, &e, &ext, &ext, flags); 344 345 return ip_set_enomatch(ret, flags, adt, set) ? -ret : 346 ip_set_eexist(ret, flags) ? 0 : ret; 347 } 348 349 static struct ip_set_type hash_net_type __read_mostly = { 350 .name = "hash:net", 351 .protocol = IPSET_PROTOCOL, 352 .features = IPSET_TYPE_IP | IPSET_TYPE_NOMATCH, 353 .dimension = IPSET_DIM_ONE, 354 .family = NFPROTO_UNSPEC, 355 .revision_min = IPSET_TYPE_REV_MIN, 356 .revision_max = IPSET_TYPE_REV_MAX, 357 .create = hash_net_create, 358 .create_policy = { 359 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 360 [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, 361 [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, 362 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 363 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 364 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 365 }, 366 .adt_policy = { 367 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 368 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, 369 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 370 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 371 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 372 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 373 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 374 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 375 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING, 376 .len = IPSET_MAX_COMMENT_SIZE }, 377 [IPSET_ATTR_SKBMARK] = { .type = NLA_U64 }, 378 [IPSET_ATTR_SKBPRIO] = { .type = NLA_U32 }, 379 [IPSET_ATTR_SKBQUEUE] = { .type = NLA_U16 }, 380 }, 381 .me = THIS_MODULE, 382 }; 383 384 static int __init 385 hash_net_init(void) 386 { 387 return ip_set_type_register(&hash_net_type); 388 } 389 390 static void __exit 391 hash_net_fini(void) 392 { 393 rcu_barrier(); 394 ip_set_type_unregister(&hash_net_type); 395 } 396 397 module_init(hash_net_init); 398 module_exit(hash_net_fini); 399