allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / net / ipv4 / netfilter / ip_set_macipmap.c
blob89e907b309f96a18d0f718faed06bbb3ed6878e1
1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de>
3 * Martin Josefsson <gandalf@wlug.westbo.se>
4 * Copyright (C) 2003-2008 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
11 /* Kernel module implementing an IP set type: the macipmap type */
13 #include <linux/module.h>
14 #include <linux/ip.h>
15 #include <linux/skbuff.h>
16 #include <linux/errno.h>
17 #include <asm/uaccess.h>
18 #include <asm/bitops.h>
19 #include <linux/spinlock.h>
20 #include <linux/if_ether.h>
22 #include <linux/netfilter_ipv4/ip_set_macipmap.h>
24 static int
25 macipmap_utest(struct ip_set *set, const void *data, u_int32_t size)
27 const struct ip_set_macipmap *map = set->data;
28 const struct ip_set_macip *table = map->members;
29 const struct ip_set_req_macipmap *req = data;
31 if (req->ip < map->first_ip || req->ip > map->last_ip)
32 return -ERANGE;
34 DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(req->ip));
35 if (table[req->ip - map->first_ip].match) {
36 return (memcmp(req->ethernet,
37 &table[req->ip - map->first_ip].ethernet,
38 ETH_ALEN) == 0);
39 } else {
40 return (map->flags & IPSET_MACIP_MATCHUNSET ? 1 : 0);
44 static int
45 macipmap_ktest(struct ip_set *set,
46 const struct sk_buff *skb,
47 const u_int32_t *flags)
49 const struct ip_set_macipmap *map = set->data;
50 const struct ip_set_macip *table = map->members;
51 ip_set_ip_t ip;
53 ip = ipaddr(skb, flags);
55 if (ip < map->first_ip || ip > map->last_ip)
56 return 0;
58 DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
59 if (table[ip - map->first_ip].match) {
60 /* Is mac pointer valid?
61 * If so, compare... */
62 return (skb_mac_header(skb) >= skb->head
63 && (skb_mac_header(skb) + ETH_HLEN) <= skb->data
64 && (memcmp(eth_hdr(skb)->h_source,
65 &table[ip - map->first_ip].ethernet,
66 ETH_ALEN) == 0));
67 } else {
68 return (map->flags & IPSET_MACIP_MATCHUNSET ? 1 : 0);
72 /* returns 0 on success */
73 static inline int
74 macipmap_add(struct ip_set *set,
75 ip_set_ip_t ip, const unsigned char *ethernet)
77 struct ip_set_macipmap *map = set->data;
78 struct ip_set_macip *table = map->members;
80 if (ip < map->first_ip || ip > map->last_ip)
81 return -ERANGE;
82 if (table[ip - map->first_ip].match)
83 return -EEXIST;
85 DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
86 memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
87 table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
88 return 0;
91 #define KADT_CONDITION \
92 if (!(skb_mac_header(skb) >= skb->head \
93 && (skb_mac_header(skb) + ETH_HLEN) <= skb->data))\
94 return -EINVAL;
96 UADT(macipmap, add, req->ethernet)
97 KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source)
99 static inline int
100 macipmap_del(struct ip_set *set, ip_set_ip_t ip)
102 struct ip_set_macipmap *map = set->data;
103 struct ip_set_macip *table = map->members;
105 if (ip < map->first_ip || ip > map->last_ip)
106 return -ERANGE;
107 if (!table[ip - map->first_ip].match)
108 return -EEXIST;
110 table[ip - map->first_ip].match = 0;
111 DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
112 return 0;
115 #undef KADT_CONDITION
116 #define KADT_CONDITION
118 UADT(macipmap, del)
119 KADT(macipmap, del, ipaddr)
121 static inline int
122 __macipmap_create(const struct ip_set_req_macipmap_create *req,
123 struct ip_set_macipmap *map)
125 if (req->to - req->from > MAX_RANGE) {
126 ip_set_printk("range too big, %d elements (max %d)",
127 req->to - req->from + 1, MAX_RANGE+1);
128 return -ENOEXEC;
130 map->flags = req->flags;
131 return (req->to - req->from + 1) * sizeof(struct ip_set_macip);
134 BITMAP_CREATE(macipmap)
135 BITMAP_DESTROY(macipmap)
136 BITMAP_FLUSH(macipmap)
138 static inline void
139 __macipmap_list_header(const struct ip_set_macipmap *map,
140 struct ip_set_req_macipmap_create *header)
142 header->flags = map->flags;
145 BITMAP_LIST_HEADER(macipmap)
146 BITMAP_LIST_MEMBERS_SIZE(macipmap, struct ip_set_req_macipmap,
147 (map->last_ip - map->first_ip + 1),
148 ((const struct ip_set_macip *)map->members)[i].match)
151 static void
152 macipmap_list_members(const struct ip_set *set, void *data, char dont_align)
154 const struct ip_set_macipmap *map = set->data;
155 const struct ip_set_macip *table = map->members;
156 uint32_t i, n = 0;
157 struct ip_set_req_macipmap *d;
159 if (dont_align) {
160 memcpy(data, map->members, map->size);
161 return;
164 for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
165 if (table[i].match) {
166 d = data + n * IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
167 d->ip = map->first_ip + i;
168 memcpy(d->ethernet, &table[i].ethernet, ETH_ALEN);
169 n++;
173 IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)
175 MODULE_LICENSE("GPL");
176 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
177 MODULE_DESCRIPTION("macipmap type of IP sets");
179 REGISTER_MODULE(macipmap)