linux/net/netfilter/ipset/ip_set_bitmap_ip.c
<<
>>
Prefs
   1/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
   2 *                         Patrick Schaaf <bof@bof.de>
   3 * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 */
   9
  10/* Kernel module implementing an IP set type: the bitmap:ip type */
  11
  12#include <linux/module.h>
  13#include <linux/ip.h>
  14#include <linux/skbuff.h>
  15#include <linux/errno.h>
  16#include <linux/bitops.h>
  17#include <linux/spinlock.h>
  18#include <linux/netlink.h>
  19#include <linux/jiffies.h>
  20#include <linux/timer.h>
  21#include <net/netlink.h>
  22#include <net/tcp.h>
  23
  24#include <linux/netfilter/ipset/pfxlen.h>
  25#include <linux/netfilter/ipset/ip_set.h>
  26#include <linux/netfilter/ipset/ip_set_bitmap.h>
  27#define IP_SET_BITMAP_TIMEOUT
  28#include <linux/netfilter/ipset/ip_set_timeout.h>
  29
  30#define REVISION_MIN    0
  31#define REVISION_MAX    0
  32
  33MODULE_LICENSE("GPL");
  34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
  35IP_SET_MODULE_DESC("bitmap:ip", REVISION_MIN, REVISION_MAX);
  36MODULE_ALIAS("ip_set_bitmap:ip");
  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        u32 timeout;            /* timeout parameter */
  48        struct timer_list gc;   /* garbage collection */
  49};
  50
  51/* Base variant */
  52
  53static inline u32
  54ip_to_id(const struct bitmap_ip *m, u32 ip)
  55{
  56        return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip)/m->hosts;
  57}
  58
  59static int
  60bitmap_ip_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
  61{
  62        const struct bitmap_ip *map = set->data;
  63        u16 id = *(u16 *)value;
  64
  65        return !!test_bit(id, map->members);
  66}
  67
  68static int
  69bitmap_ip_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
  70{
  71        struct bitmap_ip *map = set->data;
  72        u16 id = *(u16 *)value;
  73
  74        if (test_and_set_bit(id, map->members))
  75                return -IPSET_ERR_EXIST;
  76
  77        return 0;
  78}
  79
  80static int
  81bitmap_ip_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
  82{
  83        struct bitmap_ip *map = set->data;
  84        u16 id = *(u16 *)value;
  85
  86        if (!test_and_clear_bit(id, map->members))
  87                return -IPSET_ERR_EXIST;
  88
  89        return 0;
  90}
  91
  92static int
  93bitmap_ip_list(const struct ip_set *set,
  94               struct sk_buff *skb, struct netlink_callback *cb)
  95{
  96        const struct bitmap_ip *map = set->data;
  97        struct nlattr *atd, *nested;
  98        u32 id, first = cb->args[2];
  99
 100        atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
 101        if (!atd)
 102                return -EMSGSIZE;
 103        for (; cb->args[2] < map->elements; cb->args[2]++) {
 104                id = cb->args[2];
 105                if (!test_bit(id, map->members))
 106                        continue;
 107                nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
 108                if (!nested) {
 109                        if (id == first) {
 110                                nla_nest_cancel(skb, atd);
 111                                return -EMSGSIZE;
 112                        } else
 113                                goto nla_put_failure;
 114                }
 115                if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
 116                                    htonl(map->first_ip + id * map->hosts)))
 117                        goto nla_put_failure;
 118                ipset_nest_end(skb, nested);
 119        }
 120        ipset_nest_end(skb, atd);
 121        /* Set listing finished */
 122        cb->args[2] = 0;
 123        return 0;
 124
 125nla_put_failure:
 126        nla_nest_cancel(skb, nested);
 127        ipset_nest_end(skb, atd);
 128        if (unlikely(id == first)) {
 129                cb->args[2] = 0;
 130                return -EMSGSIZE;
 131        }
 132        return 0;
 133}
 134
 135/* Timeout variant */
 136
 137static int
 138bitmap_ip_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
 139{
 140        const struct bitmap_ip *map = set->data;
 141        const unsigned long *members = map->members;
 142        u16 id = *(u16 *)value;
 143
 144        return ip_set_timeout_test(members[id]);
 145}
 146
 147static int
 148bitmap_ip_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
 149{
 150        struct bitmap_ip *map = set->data;
 151        unsigned long *members = map->members;
 152        u16 id = *(u16 *)value;
 153
 154        if (ip_set_timeout_test(members[id]) && !(flags & IPSET_FLAG_EXIST))
 155                return -IPSET_ERR_EXIST;
 156
 157        members[id] = ip_set_timeout_set(timeout);
 158
 159        return 0;
 160}
 161
 162static int
 163bitmap_ip_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
 164{
 165        struct bitmap_ip *map = set->data;
 166        unsigned long *members = map->members;
 167        u16 id = *(u16 *)value;
 168        int ret = -IPSET_ERR_EXIST;
 169
 170        if (ip_set_timeout_test(members[id]))
 171                ret = 0;
 172
 173        members[id] = IPSET_ELEM_UNSET;
 174        return ret;
 175}
 176
 177static int
 178bitmap_ip_tlist(const struct ip_set *set,
 179                struct sk_buff *skb, struct netlink_callback *cb)
 180{
 181        const struct bitmap_ip *map = set->data;
 182        struct nlattr *adt, *nested;
 183        u32 id, first = cb->args[2];
 184        const unsigned long *members = map->members;
 185
 186        adt = ipset_nest_start(skb, IPSET_ATTR_ADT);
 187        if (!adt)
 188                return -EMSGSIZE;
 189        for (; cb->args[2] < map->elements; cb->args[2]++) {
 190                id = cb->args[2];
 191                if (!ip_set_timeout_test(members[id]))
 192                        continue;
 193                nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
 194                if (!nested) {
 195                        if (id == first) {
 196                                nla_nest_cancel(skb, adt);
 197                                return -EMSGSIZE;
 198                        } else
 199                                goto nla_put_failure;
 200                }
 201                if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
 202                                    htonl(map->first_ip + id * map->hosts)) ||
 203                    nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
 204                                  htonl(ip_set_timeout_get(members[id]))))
 205                        goto nla_put_failure;
 206                ipset_nest_end(skb, nested);
 207        }
 208        ipset_nest_end(skb, adt);
 209
 210        /* Set listing finished */
 211        cb->args[2] = 0;
 212
 213        return 0;
 214
 215nla_put_failure:
 216        nla_nest_cancel(skb, nested);
 217        ipset_nest_end(skb, adt);
 218        if (unlikely(id == first)) {
 219                cb->args[2] = 0;
 220                return -EMSGSIZE;
 221        }
 222        return 0;
 223}
 224
 225static int
 226bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
 227               const struct xt_action_param *par,
 228               enum ipset_adt adt, const struct ip_set_adt_opt *opt)
 229{
 230        struct bitmap_ip *map = set->data;
 231        ipset_adtfn adtfn = set->variant->adt[adt];
 232        u32 ip;
 233
 234        ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
 235        if (ip < map->first_ip || ip > map->last_ip)
 236                return -IPSET_ERR_BITMAP_RANGE;
 237
 238        ip = ip_to_id(map, ip);
 239
 240        return adtfn(set, &ip, opt_timeout(opt, map), opt->cmdflags);
 241}
 242
 243static int
 244bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
 245               enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 246{
 247        struct bitmap_ip *map = set->data;
 248        ipset_adtfn adtfn = set->variant->adt[adt];
 249        u32 timeout = map->timeout;
 250        u32 ip, ip_to, id;
 251        int ret = 0;
 252
 253        if (unlikely(!tb[IPSET_ATTR_IP] ||
 254                     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
 255                return -IPSET_ERR_PROTOCOL;
 256
 257        if (tb[IPSET_ATTR_LINENO])
 258                *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 259
 260        ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
 261        if (ret)
 262                return ret;
 263
 264        if (ip < map->first_ip || ip > map->last_ip)
 265                return -IPSET_ERR_BITMAP_RANGE;
 266
 267        if (tb[IPSET_ATTR_TIMEOUT]) {
 268                if (!with_timeout(map->timeout))
 269                        return -IPSET_ERR_TIMEOUT;
 270                timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 271        }
 272
 273        if (adt == IPSET_TEST) {
 274                id = ip_to_id(map, ip);
 275                return adtfn(set, &id, timeout, flags);
 276        }
 277
 278        if (tb[IPSET_ATTR_IP_TO]) {
 279                ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
 280                if (ret)
 281                        return ret;
 282                if (ip > ip_to) {
 283                        swap(ip, ip_to);
 284                        if (ip < map->first_ip)
 285                                return -IPSET_ERR_BITMAP_RANGE;
 286                }
 287        } else if (tb[IPSET_ATTR_CIDR]) {
 288                u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 289
 290                if (!cidr || cidr > 32)
 291                        return -IPSET_ERR_INVALID_CIDR;
 292                ip_set_mask_from_to(ip, ip_to, cidr);
 293        } else
 294                ip_to = ip;
 295
 296        if (ip_to > map->last_ip)
 297                return -IPSET_ERR_BITMAP_RANGE;
 298
 299        for (; !before(ip_to, ip); ip += map->hosts) {
 300                id = ip_to_id(map, ip);
 301                ret = adtfn(set, &id, timeout, flags);
 302
 303                if (ret && !ip_set_eexist(ret, flags))
 304                        return ret;
 305                else
 306                        ret = 0;
 307        }
 308        return ret;
 309}
 310
 311static void
 312bitmap_ip_destroy(struct ip_set *set)
 313{
 314        struct bitmap_ip *map = set->data;
 315
 316        if (with_timeout(map->timeout))
 317                del_timer_sync(&map->gc);
 318
 319        ip_set_free(map->members);
 320        kfree(map);
 321
 322        set->data = NULL;
 323}
 324
 325static void
 326bitmap_ip_flush(struct ip_set *set)
 327{
 328        struct bitmap_ip *map = set->data;
 329
 330        memset(map->members, 0, map->memsize);
 331}
 332
 333static int
 334bitmap_ip_head(struct ip_set *set, struct sk_buff *skb)
 335{
 336        const struct bitmap_ip *map = set->data;
 337        struct nlattr *nested;
 338
 339        nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
 340        if (!nested)
 341                goto nla_put_failure;
 342        if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
 343            nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
 344            (map->netmask != 32 &&
 345             nla_put_u8(skb, IPSET_ATTR_NETMASK, map->netmask)) ||
 346            nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
 347            nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
 348                          htonl(sizeof(*map) + map->memsize)) ||
 349            (with_timeout(map->timeout) &&
 350             nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))))
 351                goto nla_put_failure;
 352        ipset_nest_end(skb, nested);
 353
 354        return 0;
 355nla_put_failure:
 356        return -EMSGSIZE;
 357}
 358
 359static bool
 360bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
 361{
 362        const struct bitmap_ip *x = a->data;
 363        const struct bitmap_ip *y = b->data;
 364
 365        return x->first_ip == y->first_ip &&
 366               x->last_ip == y->last_ip &&
 367               x->netmask == y->netmask &&
 368               x->timeout == y->timeout;
 369}
 370
 371static const struct ip_set_type_variant bitmap_ip = {
 372        .kadt   = bitmap_ip_kadt,
 373        .uadt   = bitmap_ip_uadt,
 374        .adt    = {
 375                [IPSET_ADD] = bitmap_ip_add,
 376                [IPSET_DEL] = bitmap_ip_del,
 377                [IPSET_TEST] = bitmap_ip_test,
 378        },
 379        .destroy = bitmap_ip_destroy,
 380        .flush  = bitmap_ip_flush,
 381        .head   = bitmap_ip_head,
 382        .list   = bitmap_ip_list,
 383        .same_set = bitmap_ip_same_set,
 384};
 385
 386static const struct ip_set_type_variant bitmap_tip = {
 387        .kadt   = bitmap_ip_kadt,
 388        .uadt   = bitmap_ip_uadt,
 389        .adt    = {
 390                [IPSET_ADD] = bitmap_ip_tadd,
 391                [IPSET_DEL] = bitmap_ip_tdel,
 392                [IPSET_TEST] = bitmap_ip_ttest,
 393        },
 394        .destroy = bitmap_ip_destroy,
 395        .flush  = bitmap_ip_flush,
 396        .head   = bitmap_ip_head,
 397        .list   = bitmap_ip_tlist,
 398        .same_set = bitmap_ip_same_set,
 399};
 400
 401static void
 402bitmap_ip_gc(unsigned long ul_set)
 403{
 404        struct ip_set *set = (struct ip_set *) ul_set;
 405        struct bitmap_ip *map = set->data;
 406        unsigned long *table = map->members;
 407        u32 id;
 408
 409        /* We run parallel with other readers (test element)
 410         * but adding/deleting new entries is locked out */
 411        read_lock_bh(&set->lock);
 412        for (id = 0; id < map->elements; id++)
 413                if (ip_set_timeout_expired(table[id]))
 414                        table[id] = IPSET_ELEM_UNSET;
 415        read_unlock_bh(&set->lock);
 416
 417        map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
 418        add_timer(&map->gc);
 419}
 420
 421static void
 422bitmap_ip_gc_init(struct ip_set *set)
 423{
 424        struct bitmap_ip *map = set->data;
 425
 426        init_timer(&map->gc);
 427        map->gc.data = (unsigned long) set;
 428        map->gc.function = bitmap_ip_gc;
 429        map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
 430        add_timer(&map->gc);
 431}
 432
 433/* Create bitmap:ip type of sets */
 434
 435static bool
 436init_map_ip(struct ip_set *set, struct bitmap_ip *map,
 437            u32 first_ip, u32 last_ip,
 438            u32 elements, u32 hosts, u8 netmask)
 439{
 440        map->members = ip_set_alloc(map->memsize);
 441        if (!map->members)
 442                return false;
 443        map->first_ip = first_ip;
 444        map->last_ip = last_ip;
 445        map->elements = elements;
 446        map->hosts = hosts;
 447        map->netmask = netmask;
 448        map->timeout = IPSET_NO_TIMEOUT;
 449
 450        set->data = map;
 451        set->family = NFPROTO_IPV4;
 452
 453        return true;
 454}
 455
 456static int
 457bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 458{
 459        struct bitmap_ip *map;
 460        u32 first_ip, last_ip, hosts;
 461        u64 elements;
 462        u8 netmask = 32;
 463        int ret;
 464
 465        if (unlikely(!tb[IPSET_ATTR_IP] ||
 466                     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
 467                return -IPSET_ERR_PROTOCOL;
 468
 469        ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
 470        if (ret)
 471                return ret;
 472
 473        if (tb[IPSET_ATTR_IP_TO]) {
 474                ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
 475                if (ret)
 476                        return ret;
 477                if (first_ip > last_ip) {
 478                        u32 tmp = first_ip;
 479
 480                        first_ip = last_ip;
 481                        last_ip = tmp;
 482                }
 483        } else if (tb[IPSET_ATTR_CIDR]) {
 484                u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 485
 486                if (cidr >= 32)
 487                        return -IPSET_ERR_INVALID_CIDR;
 488                ip_set_mask_from_to(first_ip, last_ip, cidr);
 489        } else
 490                return -IPSET_ERR_PROTOCOL;
 491
 492        if (tb[IPSET_ATTR_NETMASK]) {
 493                netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
 494
 495                if (netmask > 32)
 496                        return -IPSET_ERR_INVALID_NETMASK;
 497
 498                first_ip &= ip_set_hostmask(netmask);
 499                last_ip |= ~ip_set_hostmask(netmask);
 500        }
 501
 502        if (netmask == 32) {
 503                hosts = 1;
 504                elements = (u64)last_ip - first_ip + 1;
 505        } else {
 506                u8 mask_bits;
 507                u32 mask;
 508
 509                mask = range_to_mask(first_ip, last_ip, &mask_bits);
 510
 511                if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) ||
 512                    netmask <= mask_bits)
 513                        return -IPSET_ERR_BITMAP_RANGE;
 514
 515                pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
 516                hosts = 2 << (32 - netmask - 1);
 517                elements = 2 << (netmask - mask_bits - 1);
 518        }
 519        if (elements > IPSET_BITMAP_MAX_RANGE + 1)
 520                return -IPSET_ERR_BITMAP_RANGE_SIZE;
 521
 522        pr_debug("hosts %u, elements %llu\n",
 523                 hosts, (unsigned long long)elements);
 524
 525        map = kzalloc(sizeof(*map), GFP_KERNEL);
 526        if (!map)
 527                return -ENOMEM;
 528
 529        if (tb[IPSET_ATTR_TIMEOUT]) {
 530                map->memsize = elements * sizeof(unsigned long);
 531
 532                if (!init_map_ip(set, map, first_ip, last_ip,
 533                                 elements, hosts, netmask)) {
 534                        kfree(map);
 535                        return -ENOMEM;
 536                }
 537
 538                map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 539                set->variant = &bitmap_tip;
 540
 541                bitmap_ip_gc_init(set);
 542        } else {
 543                map->memsize = bitmap_bytes(0, elements - 1);
 544
 545                if (!init_map_ip(set, map, first_ip, last_ip,
 546                                 elements, hosts, netmask)) {
 547                        kfree(map);
 548                        return -ENOMEM;
 549                }
 550
 551                set->variant = &bitmap_ip;
 552        }
 553        return 0;
 554}
 555
 556static struct ip_set_type bitmap_ip_type __read_mostly = {
 557        .name           = "bitmap:ip",
 558        .protocol       = IPSET_PROTOCOL,
 559        .features       = IPSET_TYPE_IP,
 560        .dimension      = IPSET_DIM_ONE,
 561        .family         = NFPROTO_IPV4,
 562        .revision_min   = REVISION_MIN,
 563        .revision_max   = REVISION_MAX,
 564        .create         = bitmap_ip_create,
 565        .create_policy  = {
 566                [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
 567                [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
 568                [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
 569                [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
 570                [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 571        },
 572        .adt_policy     = {
 573                [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
 574                [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
 575                [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
 576                [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 577                [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
 578        },
 579        .me             = THIS_MODULE,
 580};
 581
 582static int __init
 583bitmap_ip_init(void)
 584{
 585        return ip_set_type_register(&bitmap_ip_type);
 586}
 587
 588static void __exit
 589bitmap_ip_fini(void)
 590{
 591        ip_set_type_unregister(&bitmap_ip_type);
 592}
 593
 594module_init(bitmap_ip_init);
 595module_exit(bitmap_ip_fini);
 596