linux/net/netfilter/ipset/ip_set_bitmap_ip.c
<<
>>
Prefs
   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
  30MODULE_LICENSE("GPL");
  31MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
  32IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
  33MODULE_ALIAS("ip_set_bitmap:ip");
  34
  35#define MTYPE           bitmap_ip
  36#define HOST_MASK       32
  37
  38/* Type structure */
  39struct bitmap_ip {
  40        void *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 */
  54struct bitmap_ip_adt_elem {
  55        u16 id;
  56};
  57
  58static inline u32
  59ip_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
  66static inline int
  67bitmap_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
  73static inline int
  74bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map, size_t dsize)
  75{
  76        return !!test_bit(id, map->members);
  77}
  78
  79static inline int
  80bitmap_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
  86static inline int
  87bitmap_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
  92static inline int
  93bitmap_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
 100static inline int
 101bitmap_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
 109static int
 110bitmap_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
 129static int
 130bitmap_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
 196static bool
 197bitmap_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
 211struct bitmap_ip_elem {
 212};
 213
 214#include "ip_set_bitmap_gen.h"
 215
 216/* Create bitmap:ip type of sets */
 217
 218static bool
 219init_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 = ip_set_alloc(map->memsize);
 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
 240static int
 241bitmap_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 = bitmap_bytes(0, elements - 1);
 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
 327static 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
 361static int __init
 362bitmap_ip_init(void)
 363{
 364        return ip_set_type_register(&bitmap_ip_type);
 365}
 366
 367static void __exit
 368bitmap_ip_fini(void)
 369{
 370        rcu_barrier();
 371        ip_set_type_unregister(&bitmap_ip_type);
 372}
 373
 374module_init(bitmap_ip_init);
 375module_exit(bitmap_ip_fini);
 376