root/net/netfilter/ipset/ip_set_bitmap_ip.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ip_to_id
  2. bitmap_ip_do_test
  3. bitmap_ip_gc_test
  4. bitmap_ip_do_add
  5. bitmap_ip_do_del
  6. bitmap_ip_do_list
  7. bitmap_ip_do_head
  8. bitmap_ip_kadt
  9. bitmap_ip_uadt
  10. bitmap_ip_same_set
  11. init_map_ip
  12. bitmap_ip_create
  13. bitmap_ip_init
  14. bitmap_ip_fini

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
   3  *                         Patrick Schaaf <bof@bof.de>
   4  * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org>
   5  */
   6 
   7 /* Kernel module implementing an IP set type: the bitmap:ip type */
   8 
   9 #include <linux/module.h>
  10 #include <linux/ip.h>
  11 #include <linux/skbuff.h>
  12 #include <linux/errno.h>
  13 #include <linux/bitops.h>
  14 #include <linux/spinlock.h>
  15 #include <linux/netlink.h>
  16 #include <linux/jiffies.h>
  17 #include <linux/timer.h>
  18 #include <net/netlink.h>
  19 #include <net/tcp.h>
  20 
  21 #include <linux/netfilter/ipset/pfxlen.h>
  22 #include <linux/netfilter/ipset/ip_set.h>
  23 #include <linux/netfilter/ipset/ip_set_bitmap.h>
  24 
  25 #define IPSET_TYPE_REV_MIN      0
  26 /*                              1          Counter support added */
  27 /*                              2          Comment support added */
  28 #define IPSET_TYPE_REV_MAX      3       /* skbinfo support added */
  29 
  30 MODULE_LICENSE("GPL");
  31 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
  32 IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
  33 MODULE_ALIAS("ip_set_bitmap:ip");
  34 
  35 #define MTYPE           bitmap_ip
  36 #define HOST_MASK       32
  37 
  38 /* Type structure */
  39 struct bitmap_ip {
  40         unsigned long *members; /* the set members */
  41         u32 first_ip;           /* host byte order, included in range */
  42         u32 last_ip;            /* host byte order, included in range */
  43         u32 elements;           /* number of max elements in the set */
  44         u32 hosts;              /* number of hosts in a subnet */
  45         size_t memsize;         /* members size */
  46         u8 netmask;             /* subnet netmask */
  47         struct timer_list gc;   /* garbage collection */
  48         struct ip_set *set;     /* attached to this ip_set */
  49         unsigned char extensions[0]     /* data extensions */
  50                 __aligned(__alignof__(u64));
  51 };
  52 
  53 /* ADT structure for generic function args */
  54 struct bitmap_ip_adt_elem {
  55         u16 id;
  56 };
  57 
  58 static inline u32
  59 ip_to_id(const struct bitmap_ip *m, u32 ip)
  60 {
  61         return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip) / m->hosts;
  62 }
  63 
  64 /* Common functions */
  65 
  66 static inline int
  67 bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e,
  68                   struct bitmap_ip *map, size_t dsize)
  69 {
  70         return !!test_bit(e->id, map->members);
  71 }
  72 
  73 static inline int
  74 bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map, size_t dsize)
  75 {
  76         return !!test_bit(id, map->members);
  77 }
  78 
  79 static inline int
  80 bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map,
  81                  u32 flags, size_t dsize)
  82 {
  83         return !!test_bit(e->id, map->members);
  84 }
  85 
  86 static inline int
  87 bitmap_ip_do_del(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
  88 {
  89         return !test_and_clear_bit(e->id, map->members);
  90 }
  91 
  92 static inline int
  93 bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id,
  94                   size_t dsize)
  95 {
  96         return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
  97                         htonl(map->first_ip + id * map->hosts));
  98 }
  99 
 100 static inline int
 101 bitmap_ip_do_head(struct sk_buff *skb, const struct bitmap_ip *map)
 102 {
 103         return nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
 104                nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
 105                (map->netmask != 32 &&
 106                 nla_put_u8(skb, IPSET_ATTR_NETMASK, map->netmask));
 107 }
 108 
 109 static int
 110 bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
 111                const struct xt_action_param *par,
 112                enum ipset_adt adt, struct ip_set_adt_opt *opt)
 113 {
 114         struct bitmap_ip *map = set->data;
 115         ipset_adtfn adtfn = set->variant->adt[adt];
 116         struct bitmap_ip_adt_elem e = { .id = 0 };
 117         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
 118         u32 ip;
 119 
 120         ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
 121         if (ip < map->first_ip || ip > map->last_ip)
 122                 return -IPSET_ERR_BITMAP_RANGE;
 123 
 124         e.id = ip_to_id(map, ip);
 125 
 126         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
 127 }
 128 
 129 static int
 130 bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
 131                enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 132 {
 133         struct bitmap_ip *map = set->data;
 134         ipset_adtfn adtfn = set->variant->adt[adt];
 135         u32 ip = 0, ip_to = 0;
 136         struct bitmap_ip_adt_elem e = { .id = 0 };
 137         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 138         int ret = 0;
 139 
 140         if (tb[IPSET_ATTR_LINENO])
 141                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 142 
 143         if (unlikely(!tb[IPSET_ATTR_IP]))
 144                 return -IPSET_ERR_PROTOCOL;
 145 
 146         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
 147         if (ret)
 148                 return ret;
 149 
 150         ret = ip_set_get_extensions(set, tb, &ext);
 151         if (ret)
 152                 return ret;
 153 
 154         if (ip < map->first_ip || ip > map->last_ip)
 155                 return -IPSET_ERR_BITMAP_RANGE;
 156 
 157         if (adt == IPSET_TEST) {
 158                 e.id = ip_to_id(map, ip);
 159                 return adtfn(set, &e, &ext, &ext, flags);
 160         }
 161 
 162         if (tb[IPSET_ATTR_IP_TO]) {
 163                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
 164                 if (ret)
 165                         return ret;
 166                 if (ip > ip_to) {
 167                         swap(ip, ip_to);
 168                         if (ip < map->first_ip)
 169                                 return -IPSET_ERR_BITMAP_RANGE;
 170                 }
 171         } else if (tb[IPSET_ATTR_CIDR]) {
 172                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 173 
 174                 if (!cidr || cidr > HOST_MASK)
 175                         return -IPSET_ERR_INVALID_CIDR;
 176                 ip_set_mask_from_to(ip, ip_to, cidr);
 177         } else {
 178                 ip_to = ip;
 179         }
 180 
 181         if (ip_to > map->last_ip)
 182                 return -IPSET_ERR_BITMAP_RANGE;
 183 
 184         for (; !before(ip_to, ip); ip += map->hosts) {
 185                 e.id = ip_to_id(map, ip);
 186                 ret = adtfn(set, &e, &ext, &ext, flags);
 187 
 188                 if (ret && !ip_set_eexist(ret, flags))
 189                         return ret;
 190 
 191                 ret = 0;
 192         }
 193         return ret;
 194 }
 195 
 196 static bool
 197 bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
 198 {
 199         const struct bitmap_ip *x = a->data;
 200         const struct bitmap_ip *y = b->data;
 201 
 202         return x->first_ip == y->first_ip &&
 203                x->last_ip == y->last_ip &&
 204                x->netmask == y->netmask &&
 205                a->timeout == b->timeout &&
 206                a->extensions == b->extensions;
 207 }
 208 
 209 /* Plain variant */
 210 
 211 struct bitmap_ip_elem {
 212 };
 213 
 214 #include "ip_set_bitmap_gen.h"
 215 
 216 /* Create bitmap:ip type of sets */
 217 
 218 static bool
 219 init_map_ip(struct ip_set *set, struct bitmap_ip *map,
 220             u32 first_ip, u32 last_ip,
 221             u32 elements, u32 hosts, u8 netmask)
 222 {
 223         map->members = bitmap_zalloc(elements, GFP_KERNEL | __GFP_NOWARN);
 224         if (!map->members)
 225                 return false;
 226         map->first_ip = first_ip;
 227         map->last_ip = last_ip;
 228         map->elements = elements;
 229         map->hosts = hosts;
 230         map->netmask = netmask;
 231         set->timeout = IPSET_NO_TIMEOUT;
 232 
 233         map->set = set;
 234         set->data = map;
 235         set->family = NFPROTO_IPV4;
 236 
 237         return true;
 238 }
 239 
 240 static int
 241 bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
 242                  u32 flags)
 243 {
 244         struct bitmap_ip *map;
 245         u32 first_ip = 0, last_ip = 0, hosts;
 246         u64 elements;
 247         u8 netmask = 32;
 248         int ret;
 249 
 250         if (unlikely(!tb[IPSET_ATTR_IP] ||
 251                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
 252                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
 253                 return -IPSET_ERR_PROTOCOL;
 254 
 255         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
 256         if (ret)
 257                 return ret;
 258 
 259         if (tb[IPSET_ATTR_IP_TO]) {
 260                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
 261                 if (ret)
 262                         return ret;
 263                 if (first_ip > last_ip)
 264                         swap(first_ip, last_ip);
 265         } else if (tb[IPSET_ATTR_CIDR]) {
 266                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 267 
 268                 if (cidr >= HOST_MASK)
 269                         return -IPSET_ERR_INVALID_CIDR;
 270                 ip_set_mask_from_to(first_ip, last_ip, cidr);
 271         } else {
 272                 return -IPSET_ERR_PROTOCOL;
 273         }
 274 
 275         if (tb[IPSET_ATTR_NETMASK]) {
 276                 netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
 277 
 278                 if (netmask > HOST_MASK)
 279                         return -IPSET_ERR_INVALID_NETMASK;
 280 
 281                 first_ip &= ip_set_hostmask(netmask);
 282                 last_ip |= ~ip_set_hostmask(netmask);
 283         }
 284 
 285         if (netmask == 32) {
 286                 hosts = 1;
 287                 elements = (u64)last_ip - first_ip + 1;
 288         } else {
 289                 u8 mask_bits;
 290                 u32 mask;
 291 
 292                 mask = range_to_mask(first_ip, last_ip, &mask_bits);
 293 
 294                 if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) ||
 295                     netmask <= mask_bits)
 296                         return -IPSET_ERR_BITMAP_RANGE;
 297 
 298                 pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
 299                 hosts = 2 << (32 - netmask - 1);
 300                 elements = 2 << (netmask - mask_bits - 1);
 301         }
 302         if (elements > IPSET_BITMAP_MAX_RANGE + 1)
 303                 return -IPSET_ERR_BITMAP_RANGE_SIZE;
 304 
 305         pr_debug("hosts %u, elements %llu\n",
 306                  hosts, (unsigned long long)elements);
 307 
 308         set->dsize = ip_set_elem_len(set, tb, 0, 0);
 309         map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
 310         if (!map)
 311                 return -ENOMEM;
 312 
 313         map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
 314         set->variant = &bitmap_ip;
 315         if (!init_map_ip(set, map, first_ip, last_ip,
 316                          elements, hosts, netmask)) {
 317                 kfree(map);
 318                 return -ENOMEM;
 319         }
 320         if (tb[IPSET_ATTR_TIMEOUT]) {
 321                 set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 322                 bitmap_ip_gc_init(set, bitmap_ip_gc);
 323         }
 324         return 0;
 325 }
 326 
 327 static struct ip_set_type bitmap_ip_type __read_mostly = {
 328         .name           = "bitmap:ip",
 329         .protocol       = IPSET_PROTOCOL,
 330         .features       = IPSET_TYPE_IP,
 331         .dimension      = IPSET_DIM_ONE,
 332         .family         = NFPROTO_IPV4,
 333         .revision_min   = IPSET_TYPE_REV_MIN,
 334         .revision_max   = IPSET_TYPE_REV_MAX,
 335         .create         = bitmap_ip_create,
 336         .create_policy  = {
 337                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
 338                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
 339                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
 340                 [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
 341                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 342                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
 343         },
 344         .adt_policy     = {
 345                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
 346                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
 347                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
 348                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 349                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
 350                 [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
 351                 [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
 352                 [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING,
 353                                             .len  = IPSET_MAX_COMMENT_SIZE },
 354                 [IPSET_ATTR_SKBMARK]    = { .type = NLA_U64 },
 355                 [IPSET_ATTR_SKBPRIO]    = { .type = NLA_U32 },
 356                 [IPSET_ATTR_SKBQUEUE]   = { .type = NLA_U16 },
 357         },
 358         .me             = THIS_MODULE,
 359 };
 360 
 361 static int __init
 362 bitmap_ip_init(void)
 363 {
 364         return ip_set_type_register(&bitmap_ip_type);
 365 }
 366 
 367 static void __exit
 368 bitmap_ip_fini(void)
 369 {
 370         rcu_barrier();
 371         ip_set_type_unregister(&bitmap_ip_type);
 372 }
 373 
 374 module_init(bitmap_ip_init);
 375 module_exit(bitmap_ip_fini);

/* [<][>][^][v][top][bottom][index][help] */