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.
11 /* Kernel module implementing an IP set type: the macipmap type */
13 #include <linux/module.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>
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
)
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
,
40 return (map
->flags
& IPSET_MACIP_MATCHUNSET
? 1 : 0);
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
;
53 ip
= ipaddr(skb
, flags
);
55 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
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
,
68 return (map
->flags
& IPSET_MACIP_MATCHUNSET
? 1 : 0);
72 /* returns 0 on success */
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
)
82 if (table
[ip
- map
->first_ip
].match
)
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
;
91 #define KADT_CONDITION \
92 if (!(skb_mac_header(skb) >= skb->head \
93 && (skb_mac_header(skb) + ETH_HLEN) <= skb->data))\
96 UADT(macipmap
, add
, req
->ethernet
)
97 KADT(macipmap
, add
, ipaddr
, eth_hdr(skb
)->h_source
)
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
)
107 if (!table
[ip
- map
->first_ip
].match
)
110 table
[ip
- map
->first_ip
].match
= 0;
111 DP("set: %s, ip: %u.%u.%u.%u", set
->name
, HIPQUAD(ip
));
115 #undef KADT_CONDITION
116 #define KADT_CONDITION
119 KADT(macipmap
, del
, ipaddr
)
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);
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
)
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
)
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
;
157 struct ip_set_req_macipmap
*d
;
160 memcpy(data
, map
->members
, map
->size
);
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
);
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
)