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:ip 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 #include <net/tcp.h> 16 17 #include <linux/netfilter.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 Counters support */ 24 /* 2 Comments support */ 25 /* 3 Forceadd support */ 26 /* 4 skbinfo support */ 27 #define IPSET_TYPE_REV_MAX 5 /* bucketsize, initval support */ 28 29 MODULE_LICENSE("GPL"); 30 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 31 IP_SET_MODULE_DESC("hash:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 32 MODULE_ALIAS("ip_set_hash:ip"); 33 34 /* Type specific function prefix */ 35 #define HTYPE hash_ip 36 #define IP_SET_HASH_WITH_NETMASK 37 38 /* IPv4 variant */ 39 40 /* Member elements */ 41 struct hash_ip4_elem { 42 /* Zero valued IP addresses cannot be stored */ 43 __be32 ip; 44 }; 45 46 /* Common functions */ 47 48 static bool 49 hash_ip4_data_equal(const struct hash_ip4_elem *e1, 50 const struct hash_ip4_elem *e2, 51 u32 *multi) 52 { 53 return e1->ip == e2->ip; 54 } 55 56 static bool 57 hash_ip4_data_list(struct sk_buff *skb, const struct hash_ip4_elem *e) 58 { 59 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, e->ip)) 60 goto nla_put_failure; 61 return false; 62 63 nla_put_failure: 64 return true; 65 } 66 67 static void 68 hash_ip4_data_next(struct hash_ip4_elem *next, const struct hash_ip4_elem *e) 69 { 70 next->ip = e->ip; 71 } 72 73 #define MTYPE hash_ip4 74 #define HOST_MASK 32 75 #include "ip_set_hash_gen.h" 76 77 static int 78 hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb, 79 const struct xt_action_param *par, 80 enum ipset_adt adt, struct ip_set_adt_opt *opt) 81 { 82 const struct hash_ip4 *h = set->data; 83 ipset_adtfn adtfn = set->variant->adt[adt]; 84 struct hash_ip4_elem e = { 0 }; 85 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); 86 __be32 ip; 87 88 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip); 89 ip &= ip_set_netmask(h->netmask); 90 if (ip == 0) 91 return -EINVAL; 92 93 e.ip = ip; 94 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); 95 } 96 97 static int 98 hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], 99 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 100 { 101 const struct hash_ip4 *h = set->data; 102 ipset_adtfn adtfn = set->variant->adt[adt]; 103 struct hash_ip4_elem e = { 0 }; 104 struct ip_set_ext ext = IP_SET_INIT_UEXT(set); 105 u32 ip = 0, ip_to = 0, hosts; 106 int ret = 0; 107 108 if (tb[IPSET_ATTR_LINENO]) 109 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 110 111 if (unlikely(!tb[IPSET_ATTR_IP])) 112 return -IPSET_ERR_PROTOCOL; 113 114 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 115 if (ret) 116 return ret; 117 118 ret = ip_set_get_extensions(set, tb, &ext); 119 if (ret) 120 return ret; 121 122 ip &= ip_set_hostmask(h->netmask); 123 e.ip = htonl(ip); 124 if (e.ip == 0) 125 return -IPSET_ERR_HASH_ELEM; 126 127 if (adt == IPSET_TEST) 128 return adtfn(set, &e, &ext, &ext, flags); 129 130 ip_to = ip; 131 if (tb[IPSET_ATTR_IP_TO]) { 132 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); 133 if (ret) 134 return ret; 135 if (ip > ip_to) 136 swap(ip, ip_to); 137 } else if (tb[IPSET_ATTR_CIDR]) { 138 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 139 140 if (!cidr || cidr > HOST_MASK) 141 return -IPSET_ERR_INVALID_CIDR; 142 ip_set_mask_from_to(ip, ip_to, cidr); 143 } 144 145 hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); 146 147 if (retried) { 148 ip = ntohl(h->next.ip); 149 e.ip = htonl(ip); 150 } 151 for (; ip <= ip_to;) { 152 ret = adtfn(set, &e, &ext, &ext, flags); 153 if (ret && !ip_set_eexist(ret, flags)) 154 return ret; 155 156 ip += hosts; 157 e.ip = htonl(ip); 158 if (e.ip == 0) 159 return 0; 160 161 ret = 0; 162 } 163 return ret; 164 } 165 166 /* IPv6 variant */ 167 168 /* Member elements */ 169 struct hash_ip6_elem { 170 union nf_inet_addr ip; 171 }; 172 173 /* Common functions */ 174 175 static bool 176 hash_ip6_data_equal(const struct hash_ip6_elem *ip1, 177 const struct hash_ip6_elem *ip2, 178 u32 *multi) 179 { 180 return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6); 181 } 182 183 static void 184 hash_ip6_netmask(union nf_inet_addr *ip, u8 prefix) 185 { 186 ip6_netmask(ip, prefix); 187 } 188 189 static bool 190 hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *e) 191 { 192 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6)) 193 goto nla_put_failure; 194 return false; 195 196 nla_put_failure: 197 return true; 198 } 199 200 static void 201 hash_ip6_data_next(struct hash_ip6_elem *next, const struct hash_ip6_elem *e) 202 { 203 } 204 205 #undef MTYPE 206 #undef HOST_MASK 207 208 #define MTYPE hash_ip6 209 #define HOST_MASK 128 210 211 #define IP_SET_EMIT_CREATE 212 #include "ip_set_hash_gen.h" 213 214 static int 215 hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb, 216 const struct xt_action_param *par, 217 enum ipset_adt adt, struct ip_set_adt_opt *opt) 218 { 219 const struct hash_ip6 *h = set->data; 220 ipset_adtfn adtfn = set->variant->adt[adt]; 221 struct hash_ip6_elem e = { { .all = { 0 } } }; 222 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); 223 224 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6); 225 hash_ip6_netmask(&e.ip, h->netmask); 226 if (ipv6_addr_any(&e.ip.in6)) 227 return -EINVAL; 228 229 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); 230 } 231 232 static int 233 hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[], 234 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 235 { 236 const struct hash_ip6 *h = set->data; 237 ipset_adtfn adtfn = set->variant->adt[adt]; 238 struct hash_ip6_elem e = { { .all = { 0 } } }; 239 struct ip_set_ext ext = IP_SET_INIT_UEXT(set); 240 int ret; 241 242 if (tb[IPSET_ATTR_LINENO]) 243 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 244 245 if (unlikely(!tb[IPSET_ATTR_IP])) 246 return -IPSET_ERR_PROTOCOL; 247 if (unlikely(tb[IPSET_ATTR_IP_TO])) 248 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; 249 if (unlikely(tb[IPSET_ATTR_CIDR])) { 250 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 251 252 if (cidr != HOST_MASK) 253 return -IPSET_ERR_INVALID_CIDR; 254 } 255 256 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip); 257 if (ret) 258 return ret; 259 260 ret = ip_set_get_extensions(set, tb, &ext); 261 if (ret) 262 return ret; 263 264 hash_ip6_netmask(&e.ip, h->netmask); 265 if (ipv6_addr_any(&e.ip.in6)) 266 return -IPSET_ERR_HASH_ELEM; 267 268 ret = adtfn(set, &e, &ext, &ext, flags); 269 270 return ip_set_eexist(ret, flags) ? 0 : ret; 271 } 272 273 static struct ip_set_type hash_ip_type __read_mostly = { 274 .name = "hash:ip", 275 .protocol = IPSET_PROTOCOL, 276 .features = IPSET_TYPE_IP, 277 .dimension = IPSET_DIM_ONE, 278 .family = NFPROTO_UNSPEC, 279 .revision_min = IPSET_TYPE_REV_MIN, 280 .revision_max = IPSET_TYPE_REV_MAX, 281 .create_flags[IPSET_TYPE_REV_MAX] = IPSET_CREATE_FLAG_BUCKETSIZE, 282 .create = hash_ip_create, 283 .create_policy = { 284 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 285 [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, 286 [IPSET_ATTR_INITVAL] = { .type = NLA_U32 }, 287 [IPSET_ATTR_BUCKETSIZE] = { .type = NLA_U8 }, 288 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 289 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 290 [IPSET_ATTR_NETMASK] = { .type = NLA_U8 }, 291 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 292 }, 293 .adt_policy = { 294 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 295 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, 296 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 297 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 298 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 299 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 300 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 301 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING, 302 .len = IPSET_MAX_COMMENT_SIZE }, 303 [IPSET_ATTR_SKBMARK] = { .type = NLA_U64 }, 304 [IPSET_ATTR_SKBPRIO] = { .type = NLA_U32 }, 305 [IPSET_ATTR_SKBQUEUE] = { .type = NLA_U16 }, 306 }, 307 .me = THIS_MODULE, 308 }; 309 310 static int __init 311 hash_ip_init(void) 312 { 313 return ip_set_type_register(&hash_ip_type); 314 } 315 316 static void __exit 317 hash_ip_fini(void) 318 { 319 rcu_barrier(); 320 ip_set_type_unregister(&hash_ip_type); 321 } 322 323 module_init(hash_ip_init); 324 module_exit(hash_ip_fini); 325