root/net/netfilter/ipset/ip_set_bitmap_port.c

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

DEFINITIONS

This source file includes following definitions.
  1. port_to_id
  2. bitmap_port_do_test
  3. bitmap_port_gc_test
  4. bitmap_port_do_add
  5. bitmap_port_do_del
  6. bitmap_port_do_list
  7. bitmap_port_do_head
  8. bitmap_port_kadt
  9. bitmap_port_uadt
  10. bitmap_port_same_set
  11. init_map_port
  12. bitmap_port_create
  13. bitmap_port_init
  14. bitmap_port_fini

   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 bitmap:port type */
   5 
   6 #include <linux/module.h>
   7 #include <linux/ip.h>
   8 #include <linux/skbuff.h>
   9 #include <linux/errno.h>
  10 #include <linux/netlink.h>
  11 #include <linux/jiffies.h>
  12 #include <linux/timer.h>
  13 #include <net/netlink.h>
  14 
  15 #include <linux/netfilter/ipset/ip_set.h>
  16 #include <linux/netfilter/ipset/ip_set_bitmap.h>
  17 #include <linux/netfilter/ipset/ip_set_getport.h>
  18 
  19 #define IPSET_TYPE_REV_MIN      0
  20 /*                              1          Counter support added */
  21 /*                              2          Comment support added */
  22 #define IPSET_TYPE_REV_MAX      3       /* skbinfo support added */
  23 
  24 MODULE_LICENSE("GPL");
  25 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
  26 IP_SET_MODULE_DESC("bitmap:port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
  27 MODULE_ALIAS("ip_set_bitmap:port");
  28 
  29 #define MTYPE           bitmap_port
  30 
  31 /* Type structure */
  32 struct bitmap_port {
  33         unsigned long *members; /* the set members */
  34         u16 first_port;         /* host byte order, included in range */
  35         u16 last_port;          /* host byte order, included in range */
  36         u32 elements;           /* number of max elements in the set */
  37         size_t memsize;         /* members size */
  38         struct timer_list gc;   /* garbage collection */
  39         struct ip_set *set;     /* attached to this ip_set */
  40         unsigned char extensions[0]     /* data extensions */
  41                 __aligned(__alignof__(u64));
  42 };
  43 
  44 /* ADT structure for generic function args */
  45 struct bitmap_port_adt_elem {
  46         u16 id;
  47 };
  48 
  49 static inline u16
  50 port_to_id(const struct bitmap_port *m, u16 port)
  51 {
  52         return port - m->first_port;
  53 }
  54 
  55 /* Common functions */
  56 
  57 static inline int
  58 bitmap_port_do_test(const struct bitmap_port_adt_elem *e,
  59                     const struct bitmap_port *map, size_t dsize)
  60 {
  61         return !!test_bit(e->id, map->members);
  62 }
  63 
  64 static inline int
  65 bitmap_port_gc_test(u16 id, const struct bitmap_port *map, size_t dsize)
  66 {
  67         return !!test_bit(id, map->members);
  68 }
  69 
  70 static inline int
  71 bitmap_port_do_add(const struct bitmap_port_adt_elem *e,
  72                    struct bitmap_port *map, u32 flags, size_t dsize)
  73 {
  74         return !!test_bit(e->id, map->members);
  75 }
  76 
  77 static inline int
  78 bitmap_port_do_del(const struct bitmap_port_adt_elem *e,
  79                    struct bitmap_port *map)
  80 {
  81         return !test_and_clear_bit(e->id, map->members);
  82 }
  83 
  84 static inline int
  85 bitmap_port_do_list(struct sk_buff *skb, const struct bitmap_port *map, u32 id,
  86                     size_t dsize)
  87 {
  88         return nla_put_net16(skb, IPSET_ATTR_PORT,
  89                              htons(map->first_port + id));
  90 }
  91 
  92 static inline int
  93 bitmap_port_do_head(struct sk_buff *skb, const struct bitmap_port *map)
  94 {
  95         return nla_put_net16(skb, IPSET_ATTR_PORT, htons(map->first_port)) ||
  96                nla_put_net16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port));
  97 }
  98 
  99 static int
 100 bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
 101                  const struct xt_action_param *par,
 102                  enum ipset_adt adt, struct ip_set_adt_opt *opt)
 103 {
 104         struct bitmap_port *map = set->data;
 105         ipset_adtfn adtfn = set->variant->adt[adt];
 106         struct bitmap_port_adt_elem e = { .id = 0 };
 107         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
 108         __be16 __port;
 109         u16 port = 0;
 110 
 111         if (!ip_set_get_ip_port(skb, opt->family,
 112                                 opt->flags & IPSET_DIM_ONE_SRC, &__port))
 113                 return -EINVAL;
 114 
 115         port = ntohs(__port);
 116 
 117         if (port < map->first_port || port > map->last_port)
 118                 return -IPSET_ERR_BITMAP_RANGE;
 119 
 120         e.id = port_to_id(map, port);
 121 
 122         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
 123 }
 124 
 125 static int
 126 bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
 127                  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 128 {
 129         struct bitmap_port *map = set->data;
 130         ipset_adtfn adtfn = set->variant->adt[adt];
 131         struct bitmap_port_adt_elem e = { .id = 0 };
 132         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
 133         u32 port;       /* wraparound */
 134         u16 port_to;
 135         int ret = 0;
 136 
 137         if (tb[IPSET_ATTR_LINENO])
 138                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
 139 
 140         if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
 141                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO)))
 142                 return -IPSET_ERR_PROTOCOL;
 143 
 144         port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
 145         if (port < map->first_port || port > map->last_port)
 146                 return -IPSET_ERR_BITMAP_RANGE;
 147         ret = ip_set_get_extensions(set, tb, &ext);
 148         if (ret)
 149                 return ret;
 150 
 151         if (adt == IPSET_TEST) {
 152                 e.id = port_to_id(map, port);
 153                 return adtfn(set, &e, &ext, &ext, flags);
 154         }
 155 
 156         if (tb[IPSET_ATTR_PORT_TO]) {
 157                 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
 158                 if (port > port_to) {
 159                         swap(port, port_to);
 160                         if (port < map->first_port)
 161                                 return -IPSET_ERR_BITMAP_RANGE;
 162                 }
 163         } else {
 164                 port_to = port;
 165         }
 166 
 167         if (port_to > map->last_port)
 168                 return -IPSET_ERR_BITMAP_RANGE;
 169 
 170         for (; port <= port_to; port++) {
 171                 e.id = port_to_id(map, port);
 172                 ret = adtfn(set, &e, &ext, &ext, flags);
 173 
 174                 if (ret && !ip_set_eexist(ret, flags))
 175                         return ret;
 176 
 177                 ret = 0;
 178         }
 179         return ret;
 180 }
 181 
 182 static bool
 183 bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
 184 {
 185         const struct bitmap_port *x = a->data;
 186         const struct bitmap_port *y = b->data;
 187 
 188         return x->first_port == y->first_port &&
 189                x->last_port == y->last_port &&
 190                a->timeout == b->timeout &&
 191                a->extensions == b->extensions;
 192 }
 193 
 194 /* Plain variant */
 195 
 196 struct bitmap_port_elem {
 197 };
 198 
 199 #include "ip_set_bitmap_gen.h"
 200 
 201 /* Create bitmap:ip type of sets */
 202 
 203 static bool
 204 init_map_port(struct ip_set *set, struct bitmap_port *map,
 205               u16 first_port, u16 last_port)
 206 {
 207         map->members = bitmap_zalloc(map->elements, GFP_KERNEL | __GFP_NOWARN);
 208         if (!map->members)
 209                 return false;
 210         map->first_port = first_port;
 211         map->last_port = last_port;
 212         set->timeout = IPSET_NO_TIMEOUT;
 213 
 214         map->set = set;
 215         set->data = map;
 216         set->family = NFPROTO_UNSPEC;
 217 
 218         return true;
 219 }
 220 
 221 static int
 222 bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
 223                    u32 flags)
 224 {
 225         struct bitmap_port *map;
 226         u16 first_port, last_port;
 227         u32 elements;
 228 
 229         if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
 230                      !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
 231                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
 232                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
 233                 return -IPSET_ERR_PROTOCOL;
 234 
 235         first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
 236         last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
 237         if (first_port > last_port)
 238                 swap(first_port, last_port);
 239 
 240         elements = last_port - first_port + 1;
 241         set->dsize = ip_set_elem_len(set, tb, 0, 0);
 242         map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
 243         if (!map)
 244                 return -ENOMEM;
 245 
 246         map->elements = elements;
 247         map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
 248         set->variant = &bitmap_port;
 249         if (!init_map_port(set, map, first_port, last_port)) {
 250                 kfree(map);
 251                 return -ENOMEM;
 252         }
 253         if (tb[IPSET_ATTR_TIMEOUT]) {
 254                 set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 255                 bitmap_port_gc_init(set, bitmap_port_gc);
 256         }
 257         return 0;
 258 }
 259 
 260 static struct ip_set_type bitmap_port_type = {
 261         .name           = "bitmap:port",
 262         .protocol       = IPSET_PROTOCOL,
 263         .features       = IPSET_TYPE_PORT,
 264         .dimension      = IPSET_DIM_ONE,
 265         .family         = NFPROTO_UNSPEC,
 266         .revision_min   = IPSET_TYPE_REV_MIN,
 267         .revision_max   = IPSET_TYPE_REV_MAX,
 268         .create         = bitmap_port_create,
 269         .create_policy  = {
 270                 [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
 271                 [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
 272                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 273                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
 274         },
 275         .adt_policy     = {
 276                 [IPSET_ATTR_PORT]       = { .type = NLA_U16 },
 277                 [IPSET_ATTR_PORT_TO]    = { .type = NLA_U16 },
 278                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
 279                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
 280                 [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
 281                 [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
 282                 [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING,
 283                                             .len  = IPSET_MAX_COMMENT_SIZE },
 284                 [IPSET_ATTR_SKBMARK]    = { .type = NLA_U64 },
 285                 [IPSET_ATTR_SKBPRIO]    = { .type = NLA_U32 },
 286                 [IPSET_ATTR_SKBQUEUE]   = { .type = NLA_U16 },
 287         },
 288         .me             = THIS_MODULE,
 289 };
 290 
 291 static int __init
 292 bitmap_port_init(void)
 293 {
 294         return ip_set_type_register(&bitmap_port_type);
 295 }
 296 
 297 static void __exit
 298 bitmap_port_fini(void)
 299 {
 300         rcu_barrier();
 301         ip_set_type_unregister(&bitmap_port_type);
 302 }
 303 
 304 module_init(bitmap_port_init);
 305 module_exit(bitmap_port_fini);

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