From 5b20d409ef3062b24bbe7667f0daec34523446a6 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Thu, 22 Apr 2010 17:00:42 +0200 Subject: Fifth stage to ipset-5 Rename files in kernel/ and get rid of old ones (2.4.x kernel tree support). --- kernel/ip_set_bitmap_ipmac.c | 179 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 kernel/ip_set_bitmap_ipmac.c (limited to 'kernel/ip_set_bitmap_ipmac.c') diff --git a/kernel/ip_set_bitmap_ipmac.c b/kernel/ip_set_bitmap_ipmac.c new file mode 100644 index 0000000..89e907b --- /dev/null +++ b/kernel/ip_set_bitmap_ipmac.c @@ -0,0 +1,179 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson + * Copyright (C) 2003-2008 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* Kernel module implementing an IP set type: the macipmap type */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int +macipmap_utest(struct ip_set *set, const void *data, u_int32_t size) +{ + const struct ip_set_macipmap *map = set->data; + const struct ip_set_macip *table = map->members; + const struct ip_set_req_macipmap *req = data; + + if (req->ip < map->first_ip || req->ip > map->last_ip) + return -ERANGE; + + DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(req->ip)); + if (table[req->ip - map->first_ip].match) { + return (memcmp(req->ethernet, + &table[req->ip - map->first_ip].ethernet, + ETH_ALEN) == 0); + } else { + return (map->flags & IPSET_MACIP_MATCHUNSET ? 1 : 0); + } +} + +static int +macipmap_ktest(struct ip_set *set, + const struct sk_buff *skb, + const u_int32_t *flags) +{ + const struct ip_set_macipmap *map = set->data; + const struct ip_set_macip *table = map->members; + ip_set_ip_t ip; + + ip = ipaddr(skb, flags); + + if (ip < map->first_ip || ip > map->last_ip) + return 0; + + DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip)); + if (table[ip - map->first_ip].match) { + /* Is mac pointer valid? + * If so, compare... */ + return (skb_mac_header(skb) >= skb->head + && (skb_mac_header(skb) + ETH_HLEN) <= skb->data + && (memcmp(eth_hdr(skb)->h_source, + &table[ip - map->first_ip].ethernet, + ETH_ALEN) == 0)); + } else { + return (map->flags & IPSET_MACIP_MATCHUNSET ? 1 : 0); + } +} + +/* returns 0 on success */ +static inline int +macipmap_add(struct ip_set *set, + ip_set_ip_t ip, const unsigned char *ethernet) +{ + struct ip_set_macipmap *map = set->data; + struct ip_set_macip *table = map->members; + + if (ip < map->first_ip || ip > map->last_ip) + return -ERANGE; + if (table[ip - map->first_ip].match) + return -EEXIST; + + DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip)); + memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN); + table[ip - map->first_ip].match = IPSET_MACIP_ISSET; + return 0; +} + +#define KADT_CONDITION \ + if (!(skb_mac_header(skb) >= skb->head \ + && (skb_mac_header(skb) + ETH_HLEN) <= skb->data))\ + return -EINVAL; + +UADT(macipmap, add, req->ethernet) +KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source) + +static inline int +macipmap_del(struct ip_set *set, ip_set_ip_t ip) +{ + struct ip_set_macipmap *map = set->data; + struct ip_set_macip *table = map->members; + + if (ip < map->first_ip || ip > map->last_ip) + return -ERANGE; + if (!table[ip - map->first_ip].match) + return -EEXIST; + + table[ip - map->first_ip].match = 0; + DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip)); + return 0; +} + +#undef KADT_CONDITION +#define KADT_CONDITION + +UADT(macipmap, del) +KADT(macipmap, del, ipaddr) + +static inline int +__macipmap_create(const struct ip_set_req_macipmap_create *req, + struct ip_set_macipmap *map) +{ + if (req->to - req->from > MAX_RANGE) { + ip_set_printk("range too big, %d elements (max %d)", + req->to - req->from + 1, MAX_RANGE+1); + return -ENOEXEC; + } + map->flags = req->flags; + return (req->to - req->from + 1) * sizeof(struct ip_set_macip); +} + +BITMAP_CREATE(macipmap) +BITMAP_DESTROY(macipmap) +BITMAP_FLUSH(macipmap) + +static inline void +__macipmap_list_header(const struct ip_set_macipmap *map, + struct ip_set_req_macipmap_create *header) +{ + header->flags = map->flags; +} + +BITMAP_LIST_HEADER(macipmap) +BITMAP_LIST_MEMBERS_SIZE(macipmap, struct ip_set_req_macipmap, + (map->last_ip - map->first_ip + 1), + ((const struct ip_set_macip *)map->members)[i].match) + + +static void +macipmap_list_members(const struct ip_set *set, void *data, char dont_align) +{ + const struct ip_set_macipmap *map = set->data; + const struct ip_set_macip *table = map->members; + uint32_t i, n = 0; + struct ip_set_req_macipmap *d; + + if (dont_align) { + memcpy(data, map->members, map->size); + return; + } + + for (i = 0; i < map->last_ip - map->first_ip + 1; i++) + if (table[i].match) { + d = data + n * IPSET_ALIGN(sizeof(struct ip_set_req_macipmap)); + d->ip = map->first_ip + i; + memcpy(d->ethernet, &table[i].ethernet, ETH_ALEN); + n++; + } +} + +IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("macipmap type of IP sets"); + +REGISTER_MODULE(macipmap) -- cgit v1.2.3