1de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 2de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * Patrick Schaaf <bof@bof.de> 3de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * Martin Josefsson <gandalf@wlug.westbo.se> 4b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * 6de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * This program is free software; you can redistribute it and/or modify 7de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * it under the terms of the GNU General Public License version 2 as 8de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * published by the Free Software Foundation. 9de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik */ 10de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 11de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik/* Kernel module implementing an IP set type: the bitmap:ip,mac type */ 12de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 13de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/module.h> 14de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/ip.h> 15de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/etherdevice.h> 16de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/skbuff.h> 17de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/errno.h> 18de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/if_ether.h> 19de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/netlink.h> 20de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/jiffies.h> 21de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/timer.h> 22de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <net/netlink.h> 23de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 24de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/netfilter/ipset/pfxlen.h> 25de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/netfilter/ipset/ip_set.h> 26de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik#include <linux/netfilter/ipset/ip_set_bitmap.h> 27de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 2810111a6ef373c377e87730749a0f68210c3fd062Jozsef Kadlecsik#define REVISION_MIN 0 29f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik#define REVISION_MAX 1 /* Counter support added */ 3010111a6ef373c377e87730749a0f68210c3fd062Jozsef Kadlecsik 31de76021a1bb35e3560afccf741d1119a872aea49Jozsef KadlecsikMODULE_LICENSE("GPL"); 32de76021a1bb35e3560afccf741d1119a872aea49Jozsef KadlecsikMODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 3310111a6ef373c377e87730749a0f68210c3fd062Jozsef KadlecsikIP_SET_MODULE_DESC("bitmap:ip,mac", REVISION_MIN, REVISION_MAX); 34de76021a1bb35e3560afccf741d1119a872aea49Jozsef KadlecsikMODULE_ALIAS("ip_set_bitmap:ip,mac"); 35de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 36b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik#define MTYPE bitmap_ipmac 37b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik#define IP_SET_BITMAP_STORED_TIMEOUT 38b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik 39de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikenum { 40de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik MAC_UNSET, /* element is set, without MAC */ 41b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik MAC_FILLED, /* element is set with MAC */ 42de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik}; 43de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 44de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik/* Type structure */ 45de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstruct bitmap_ipmac { 46de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik void *members; /* the set members */ 47b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik void *extensions; /* MAC + data extensions */ 48de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik u32 first_ip; /* host byte order, included in range */ 49de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik u32 last_ip; /* host byte order, included in range */ 50b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik u32 elements; /* number of max elements in the set */ 51de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik u32 timeout; /* timeout value */ 52de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik struct timer_list gc; /* garbage collector */ 53b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik size_t memsize; /* members size */ 54de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik size_t dsize; /* size of element */ 55b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */ 56de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik}; 57de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 58de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik/* ADT structure for generic function args */ 59b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstruct bitmap_ipmac_adt_elem { 60b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik u16 id; 61b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik unsigned char *ether; 62de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik}; 63de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 64b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstruct bitmap_ipmac_elem { 65de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik unsigned char ether[ETH_ALEN]; 66b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik unsigned char filled; 67de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} __attribute__ ((aligned)); 68de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 69b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline u32 70b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikip_to_id(const struct bitmap_ipmac *m, u32 ip) 71de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 72b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return ip - m->first_ip; 73de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 74de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 75b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline struct bitmap_ipmac_elem * 76b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikget_elem(void *extensions, u16 id, size_t dsize) 77de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 78b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return (struct bitmap_ipmac_elem *)(extensions + id * dsize); 79de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 80de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 81b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik/* Common functions */ 82de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 83de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic inline int 84b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e, 85b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik const struct bitmap_ipmac *map) 86de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 87b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik const struct bitmap_ipmac_elem *elem; 88de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 89b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (!test_bit(e->id, map->members)) 90b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return 0; 91b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik elem = get_elem(map->extensions, e->id, map->dsize); 92b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (elem->filled == MAC_FILLED) 93b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return e->ether == NULL || 94b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik ether_addr_equal(e->ether, elem->ether); 95b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik /* Trigger kernel to fill out the ethernet address */ 96b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return -EAGAIN; 97de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 98de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 99b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline int 100b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map) 101de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 102b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik const struct bitmap_ipmac_elem *elem; 103de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 104b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (!test_bit(id, map->members)) 105b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return 0; 106b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik elem = get_elem(map->extensions, id, map->dsize); 107b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik /* Timer not started for the incomplete elements */ 108b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return elem->filled == MAC_FILLED; 109de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 110de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 111b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline int 112b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_is_filled(const struct bitmap_ipmac_elem *elem) 113de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 114b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return elem->filled == MAC_FILLED; 115de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 116de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 117b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline int 118b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_add_timeout(unsigned long *timeout, 119b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik const struct bitmap_ipmac_adt_elem *e, 120b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik const struct ip_set_ext *ext, 121b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct bitmap_ipmac *map, int mode) 122de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 123b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik u32 t = ext->timeout; 124de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 125b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (mode == IPSET_ADD_START_STORED_TIMEOUT) { 126b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (t == map->timeout) 127de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik /* Timeout was not specified, get stored one */ 128b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik t = *timeout; 129b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik ip_set_timeout_set(timeout, t); 130b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } else { 131de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik /* If MAC is unset yet, we store plain timeout value 132de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * because the timer is not activated yet 133de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * and we can reuse it later when MAC is filled out, 134de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik * possibly by the kernel */ 135b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (e->ether) 136b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik ip_set_timeout_set(timeout, t); 137b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik else 138b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik *timeout = t; 139de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } 140de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return 0; 141de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 142de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 143b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline int 144b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e, 145b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct bitmap_ipmac *map, u32 flags) 146de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 147b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct bitmap_ipmac_elem *elem; 148b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik 149b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik elem = get_elem(map->extensions, e->id, map->dsize); 150b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (test_and_set_bit(e->id, map->members)) { 151b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (elem->filled == MAC_FILLED) { 152b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (e->ether && (flags & IPSET_FLAG_EXIST)) 153b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik memcpy(elem->ether, e->ether, ETH_ALEN); 154b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return IPSET_ADD_FAILED; 155b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } else if (!e->ether) 156b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik /* Already added without ethernet address */ 157b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return IPSET_ADD_FAILED; 158b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik /* Fill the MAC address and trigger the timer activation */ 159b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik memcpy(elem->ether, e->ether, ETH_ALEN); 160b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik elem->filled = MAC_FILLED; 161b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return IPSET_ADD_START_STORED_TIMEOUT; 162b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } else if (e->ether) { 163b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik /* We can store MAC too */ 164b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik memcpy(elem->ether, e->ether, ETH_ALEN); 165b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik elem->filled = MAC_FILLED; 166b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return 0; 167b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } else { 168b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik elem->filled = MAC_UNSET; 169b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik /* MAC is not stored yet, don't start timer */ 170b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return IPSET_ADD_STORE_PLAIN_TIMEOUT; 171b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } 172b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik} 173de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 174b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline int 175b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_do_del(const struct bitmap_ipmac_adt_elem *e, 176b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct bitmap_ipmac *map) 177b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik{ 178b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return !test_and_clear_bit(e->id, map->members); 179b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik} 180de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 181b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline unsigned long 182b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikip_set_timeout_stored(struct bitmap_ipmac *map, u32 id, unsigned long *timeout) 183b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik{ 184b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik const struct bitmap_ipmac_elem *elem = 185b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik get_elem(map->extensions, id, map->dsize); 186de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 187b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return elem->filled == MAC_FILLED ? ip_set_timeout_get(timeout) : 188b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik *timeout; 189de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 190de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 191b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline int 192b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map, 193b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik u32 id) 194de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 195b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik const struct bitmap_ipmac_elem *elem = 196b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik get_elem(map->extensions, id, map->dsize); 197de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 198b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return nla_put_ipaddr4(skb, IPSET_ATTR_IP, 199b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik htonl(map->first_ip + id)) || 200b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik (elem->filled == MAC_FILLED && 201b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN, elem->ether)); 202b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik} 203de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 204b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstatic inline int 205b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikbitmap_ipmac_do_head(struct sk_buff *skb, const struct bitmap_ipmac *map) 206b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik{ 207b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) || 208b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); 209de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 210de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 211de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic int 212de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikbitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, 213b66554cf03fe866b3fb7b9f40f430b8ba09f41c8Jozsef Kadlecsik const struct xt_action_param *par, 214b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik enum ipset_adt adt, struct ip_set_adt_opt *opt) 215de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 216de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik struct bitmap_ipmac *map = set->data; 217de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik ipset_adtfn adtfn = set->variant->adt[adt]; 218b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct bitmap_ipmac_adt_elem e = {}; 219b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map); 220b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik u32 ip; 221de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 2220e8a835aa59d08d702af0fcfd296e2218b2e344bJozsef Kadlecsik /* MAC can be src only */ 223ac8cc925d35fc5a05da2bd097e602f20de2478a4Jozsef Kadlecsik if (!(opt->flags & IPSET_DIM_TWO_SRC)) 2240e8a835aa59d08d702af0fcfd296e2218b2e344bJozsef Kadlecsik return 0; 2250e8a835aa59d08d702af0fcfd296e2218b2e344bJozsef Kadlecsik 226b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); 227b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (ip < map->first_ip || ip > map->last_ip) 228de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -IPSET_ERR_BITMAP_RANGE; 229de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 230de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik /* Backward compatibility: we don't check the second flag */ 231de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (skb_mac_header(skb) < skb->head || 232de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik (skb_mac_header(skb) + ETH_HLEN) > skb->data) 233de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -EINVAL; 234de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 235b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik e.id = ip_to_id(map, ip); 236b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik e.ether = eth_hdr(skb)->h_source; 237de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 238b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); 239de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 240de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 241de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic int 242de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikbitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[], 2433d14b171f004f75c2d1e82e10545966f94132705Jozsef Kadlecsik enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 244de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 245de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik const struct bitmap_ipmac *map = set->data; 246de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik ipset_adtfn adtfn = set->variant->adt[adt]; 247b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct bitmap_ipmac_adt_elem e = {}; 248b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct ip_set_ext ext = IP_SET_INIT_UEXT(map); 249b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik u32 ip; 250de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik int ret = 0; 251de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 252de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (unlikely(!tb[IPSET_ATTR_IP] || 253f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 254f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) || 255f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES))) 256de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -IPSET_ERR_PROTOCOL; 257de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 258de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (tb[IPSET_ATTR_LINENO]) 259de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 260de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 261b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) || 262b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik ip_set_get_extensions(set, tb, &ext); 263de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (ret) 264de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return ret; 265de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 266b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (ip < map->first_ip || ip > map->last_ip) 267de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -IPSET_ERR_BITMAP_RANGE; 268de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 269b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik e.id = ip_to_id(map, ip); 270de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (tb[IPSET_ATTR_ETHER]) 271b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik e.ether = nla_data(tb[IPSET_ATTR_ETHER]); 272de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik else 273b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik e.ether = NULL; 274de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 275b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik ret = adtfn(set, &e, &ext, &ext, flags); 276de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 277de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return ip_set_eexist(ret, flags) ? 0 : ret; 278de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 279de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 280de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic bool 281de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikbitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b) 282de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 283de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik const struct bitmap_ipmac *x = a->data; 284de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik const struct bitmap_ipmac *y = b->data; 285de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 286de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return x->first_ip == y->first_ip && 287de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik x->last_ip == y->last_ip && 288b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik x->timeout == y->timeout && 289b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik a->extensions == b->extensions; 290de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 291de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 292b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik/* Plain variant */ 293de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 294b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik/* Timeout variant */ 295de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 296b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsikstruct bitmap_ipmact_elem { 297b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik struct { 298b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik unsigned char ether[ETH_ALEN]; 299b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik unsigned char filled; 300b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } __attribute__ ((aligned)); 301b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik unsigned long timeout; 302b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik}; 303de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 304f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik/* Plain variant with counter */ 305f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik 306f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsikstruct bitmap_ipmacc_elem { 307f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik struct { 308f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik unsigned char ether[ETH_ALEN]; 309f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik unsigned char filled; 310f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik } __attribute__ ((aligned)); 311f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik struct ip_set_counter counter; 312f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik}; 313f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik 314f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik/* Timeout variant with counter */ 315f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik 316f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsikstruct bitmap_ipmacct_elem { 317f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik struct { 318f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik unsigned char ether[ETH_ALEN]; 319f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik unsigned char filled; 320f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik } __attribute__ ((aligned)); 321f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik unsigned long timeout; 322f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik struct ip_set_counter counter; 323f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik}; 324f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik 325b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik#include "ip_set_bitmap_gen.h" 326de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 327de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik/* Create bitmap:ip,mac type of sets */ 328de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 329de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic bool 330de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikinit_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, 331b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik u32 first_ip, u32 last_ip, u32 elements) 332de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 333de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik map->members = ip_set_alloc((last_ip - first_ip + 1) * map->dsize); 334de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (!map->members) 335de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return false; 336b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (map->dsize) { 337b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik map->extensions = ip_set_alloc(map->dsize * elements); 338b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (!map->extensions) { 339b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik kfree(map->members); 340b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik return false; 341b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } 342b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik } 343de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik map->first_ip = first_ip; 344de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik map->last_ip = last_ip; 345b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik map->elements = elements; 346de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik map->timeout = IPSET_NO_TIMEOUT; 347de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 348de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik set->data = map; 349c15f1c83251049182b1771da004d14f29683ab97Jan Engelhardt set->family = NFPROTO_IPV4; 350de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 351de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return true; 352de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 353de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 354de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic int 355de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikbitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], 356de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik u32 flags) 357de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 358f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik u32 first_ip, last_ip, cadt_flags = 0; 359b9fed748185a96b7cfe74afac4bd228e8af16f01Jozsef Kadlecsik u64 elements; 360de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik struct bitmap_ipmac *map; 361de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik int ret; 362de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 363de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (unlikely(!tb[IPSET_ATTR_IP] || 364f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 365f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 366de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -IPSET_ERR_PROTOCOL; 367de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 368de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); 369de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (ret) 370de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return ret; 371de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 372de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (tb[IPSET_ATTR_IP_TO]) { 373de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip); 374de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (ret) 375de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return ret; 376de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (first_ip > last_ip) { 377de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik u32 tmp = first_ip; 378de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 379de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik first_ip = last_ip; 380de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik last_ip = tmp; 381de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } 382de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } else if (tb[IPSET_ATTR_CIDR]) { 383de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 384de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 385de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (cidr >= 32) 386de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -IPSET_ERR_INVALID_CIDR; 387e6146e8684ed6dd4c0ff85ca21bf4324114fbbfaJozsef Kadlecsik ip_set_mask_from_to(first_ip, last_ip, cidr); 388de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } else 389de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -IPSET_ERR_PROTOCOL; 390de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 391b9fed748185a96b7cfe74afac4bd228e8af16f01Jozsef Kadlecsik elements = (u64)last_ip - first_ip + 1; 392de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 393de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (elements > IPSET_BITMAP_MAX_RANGE + 1) 394de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -IPSET_ERR_BITMAP_RANGE_SIZE; 395de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 396de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik map = kzalloc(sizeof(*map), GFP_KERNEL); 397de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik if (!map) 398de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -ENOMEM; 399de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 400b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik map->memsize = bitmap_bytes(0, elements - 1); 401b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik set->variant = &bitmap_ipmac; 402f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik if (tb[IPSET_ATTR_CADT_FLAGS]) 403f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 404f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { 405f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik set->extensions |= IPSET_EXT_COUNTER; 406f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik if (tb[IPSET_ATTR_TIMEOUT]) { 407f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik map->dsize = sizeof(struct bitmap_ipmacct_elem); 408f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik map->offset[IPSET_OFFSET_TIMEOUT] = 409f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik offsetof(struct bitmap_ipmacct_elem, timeout); 410f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik map->offset[IPSET_OFFSET_COUNTER] = 411f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik offsetof(struct bitmap_ipmacct_elem, counter); 412f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik 413f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik if (!init_map_ipmac(set, map, first_ip, last_ip, 414f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik elements)) { 415f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik kfree(map); 416f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik return -ENOMEM; 417f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik } 418f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik map->timeout = ip_set_timeout_uget( 419f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik tb[IPSET_ATTR_TIMEOUT]); 420f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik set->extensions |= IPSET_EXT_TIMEOUT; 421f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik bitmap_ipmac_gc_init(set, bitmap_ipmac_gc); 422f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik } else { 423f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik map->dsize = sizeof(struct bitmap_ipmacc_elem); 424f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik map->offset[IPSET_OFFSET_COUNTER] = 425f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik offsetof(struct bitmap_ipmacc_elem, counter); 426f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik 427f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik if (!init_map_ipmac(set, map, first_ip, last_ip, 428f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik elements)) { 429f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik kfree(map); 430f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik return -ENOMEM; 431f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik } 432f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik } 433f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik } else if (tb[IPSET_ATTR_TIMEOUT]) { 434b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik map->dsize = sizeof(struct bitmap_ipmact_elem); 435b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik map->offset[IPSET_OFFSET_TIMEOUT] = 436b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik offsetof(struct bitmap_ipmact_elem, timeout); 437de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 438b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) { 439de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik kfree(map); 440de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -ENOMEM; 441de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } 442de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 443b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik set->extensions |= IPSET_EXT_TIMEOUT; 444b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik bitmap_ipmac_gc_init(set, bitmap_ipmac_gc); 445de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } else { 446b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik map->dsize = sizeof(struct bitmap_ipmac_elem); 447de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 448b0da3905bb1eb0969470f57b18c978f902475c78Jozsef Kadlecsik if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) { 449de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik kfree(map); 450de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return -ENOMEM; 451de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } 452de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik set->variant = &bitmap_ipmac; 453de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik } 454de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return 0; 455de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 456de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 457de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic struct ip_set_type bitmap_ipmac_type = { 458de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .name = "bitmap:ip,mac", 459de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .protocol = IPSET_PROTOCOL, 460de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .features = IPSET_TYPE_IP | IPSET_TYPE_MAC, 461de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .dimension = IPSET_DIM_TWO, 462c15f1c83251049182b1771da004d14f29683ab97Jan Engelhardt .family = NFPROTO_IPV4, 46310111a6ef373c377e87730749a0f68210c3fd062Jozsef Kadlecsik .revision_min = REVISION_MIN, 46410111a6ef373c377e87730749a0f68210c3fd062Jozsef Kadlecsik .revision_max = REVISION_MAX, 465de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .create = bitmap_ipmac_create, 466de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .create_policy = { 467de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 468de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, 469de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 470de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 471f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 472de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik }, 473de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .adt_policy = { 474de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 47515b4d93f0316caec44e07255c1d73bde4fac12e4Jozsef Kadlecsik [IPSET_ATTR_ETHER] = { .type = NLA_BINARY, 47615b4d93f0316caec44e07255c1d73bde4fac12e4Jozsef Kadlecsik .len = ETH_ALEN }, 477de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 478de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 479f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 480f48d19db12e1cde296ce7a13c38303618e38e304Jozsef Kadlecsik [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 481de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik }, 482de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik .me = THIS_MODULE, 483de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik}; 484de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 485de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic int __init 486de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikbitmap_ipmac_init(void) 487de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 488de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik return ip_set_type_register(&bitmap_ipmac_type); 489de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 490de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 491de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikstatic void __exit 492de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikbitmap_ipmac_fini(void) 493de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik{ 494de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik ip_set_type_unregister(&bitmap_ipmac_type); 495de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik} 496de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsik 497de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikmodule_init(bitmap_ipmac_init); 498de76021a1bb35e3560afccf741d1119a872aea49Jozsef Kadlecsikmodule_exit(bitmap_ipmac_fini); 499