• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5  *
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  */
10 #ifndef _IP_SET_H
11 #define _IP_SET_H
12 
13 #include <linux/ip.h>
14 #include <linux/ipv6.h>
15 #include <linux/netlink.h>
16 #include <linux/netfilter.h>
17 #include <linux/netfilter/x_tables.h>
18 #include <linux/stringify.h>
19 #include <linux/vmalloc.h>
20 #include <net/netlink.h>
21 #include <uapi/linux/netfilter/ipset/ip_set.h>
22 
23 #define _IP_SET_MODULE_DESC(a, b, c)		\
24 	MODULE_DESCRIPTION(a " type of IP sets, revisions " b "-" c)
25 #define IP_SET_MODULE_DESC(a, b, c)		\
26 	_IP_SET_MODULE_DESC(a, __stringify(b), __stringify(c))
27 
28 /* Set features */
29 enum ip_set_feature {
30 	IPSET_TYPE_IP_FLAG = 0,
31 	IPSET_TYPE_IP = (1 << IPSET_TYPE_IP_FLAG),
32 	IPSET_TYPE_PORT_FLAG = 1,
33 	IPSET_TYPE_PORT = (1 << IPSET_TYPE_PORT_FLAG),
34 	IPSET_TYPE_MAC_FLAG = 2,
35 	IPSET_TYPE_MAC = (1 << IPSET_TYPE_MAC_FLAG),
36 	IPSET_TYPE_IP2_FLAG = 3,
37 	IPSET_TYPE_IP2 = (1 << IPSET_TYPE_IP2_FLAG),
38 	IPSET_TYPE_NAME_FLAG = 4,
39 	IPSET_TYPE_NAME = (1 << IPSET_TYPE_NAME_FLAG),
40 	IPSET_TYPE_IFACE_FLAG = 5,
41 	IPSET_TYPE_IFACE = (1 << IPSET_TYPE_IFACE_FLAG),
42 	IPSET_TYPE_NOMATCH_FLAG = 6,
43 	IPSET_TYPE_NOMATCH = (1 << IPSET_TYPE_NOMATCH_FLAG),
44 	/* Strictly speaking not a feature, but a flag for dumping:
45 	 * this settype must be dumped last */
46 	IPSET_DUMP_LAST_FLAG = 7,
47 	IPSET_DUMP_LAST = (1 << IPSET_DUMP_LAST_FLAG),
48 };
49 
50 /* Set extensions */
51 enum ip_set_extension {
52 	IPSET_EXT_NONE = 0,
53 	IPSET_EXT_BIT_TIMEOUT = 1,
54 	IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT),
55 	IPSET_EXT_BIT_COUNTER = 2,
56 	IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER),
57 };
58 
59 /* Extension offsets */
60 enum ip_set_offset {
61 	IPSET_OFFSET_TIMEOUT = 0,
62 	IPSET_OFFSET_COUNTER,
63 	IPSET_OFFSET_MAX,
64 };
65 
66 #define SET_WITH_TIMEOUT(s)	((s)->extensions & IPSET_EXT_TIMEOUT)
67 #define SET_WITH_COUNTER(s)	((s)->extensions & IPSET_EXT_COUNTER)
68 
69 struct ip_set_ext {
70 	unsigned long timeout;
71 	u64 packets;
72 	u64 bytes;
73 };
74 
75 struct ip_set;
76 
77 typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
78 			   const struct ip_set_ext *ext,
79 			   struct ip_set_ext *mext, u32 cmdflags);
80 
81 /* Kernel API function options */
82 struct ip_set_adt_opt {
83 	u8 family;		/* Actual protocol family */
84 	u8 dim;			/* Dimension of match/target */
85 	u8 flags;		/* Direction and negation flags */
86 	u32 cmdflags;		/* Command-like flags */
87 	struct ip_set_ext ext;	/* Extensions */
88 };
89 
90 /* Set type, variant-specific part */
91 struct ip_set_type_variant {
92 	/* Kernelspace: test/add/del entries
93 	 *		returns negative error code,
94 	 *			zero for no match/success to add/delete
95 	 *			positive for matching element */
96 	int (*kadt)(struct ip_set *set, const struct sk_buff *skb,
97 		    const struct xt_action_param *par,
98 		    enum ipset_adt adt, struct ip_set_adt_opt *opt);
99 
100 	/* Userspace: test/add/del entries
101 	 *		returns negative error code,
102 	 *			zero for no match/success to add/delete
103 	 *			positive for matching element */
104 	int (*uadt)(struct ip_set *set, struct nlattr *tb[],
105 		    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried);
106 
107 	/* Low level add/del/test functions */
108 	ipset_adtfn adt[IPSET_ADT_MAX];
109 
110 	/* When adding entries and set is full, try to resize the set */
111 	int (*resize)(struct ip_set *set, bool retried);
112 	/* Destroy the set */
113 	void (*destroy)(struct ip_set *set);
114 	/* Flush the elements */
115 	void (*flush)(struct ip_set *set);
116 	/* Expire entries before listing */
117 	void (*expire)(struct ip_set *set);
118 	/* List set header data */
119 	int (*head)(struct ip_set *set, struct sk_buff *skb);
120 	/* List elements */
121 	int (*list)(const struct ip_set *set, struct sk_buff *skb,
122 		    struct netlink_callback *cb);
123 
124 	/* Return true if "b" set is the same as "a"
125 	 * according to the create set parameters */
126 	bool (*same_set)(const struct ip_set *a, const struct ip_set *b);
127 };
128 
129 /* The core set type structure */
130 struct ip_set_type {
131 	struct list_head list;
132 
133 	/* Typename */
134 	char name[IPSET_MAXNAMELEN];
135 	/* Protocol version */
136 	u8 protocol;
137 	/* Set features to control swapping */
138 	u8 features;
139 	/* Set type dimension */
140 	u8 dimension;
141 	/*
142 	 * Supported family: may be NFPROTO_UNSPEC for both
143 	 * NFPROTO_IPV4/NFPROTO_IPV6.
144 	 */
145 	u8 family;
146 	/* Type revisions */
147 	u8 revision_min, revision_max;
148 
149 	/* Create set */
150 	int (*create)(struct ip_set *set, struct nlattr *tb[], u32 flags);
151 
152 	/* Attribute policies */
153 	const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1];
154 	const struct nla_policy adt_policy[IPSET_ATTR_ADT_MAX + 1];
155 
156 	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
157 	struct module *me;
158 };
159 
160 /* register and unregister set type */
161 extern int ip_set_type_register(struct ip_set_type *set_type);
162 extern void ip_set_type_unregister(struct ip_set_type *set_type);
163 
164 /* A generic IP set */
165 struct ip_set {
166 	/* The name of the set */
167 	char name[IPSET_MAXNAMELEN];
168 	/* Lock protecting the set data */
169 	rwlock_t lock;
170 	/* References to the set */
171 	u32 ref;
172 	/* The core set type */
173 	struct ip_set_type *type;
174 	/* The type variant doing the real job */
175 	const struct ip_set_type_variant *variant;
176 	/* The actual INET family of the set */
177 	u8 family;
178 	/* The type revision */
179 	u8 revision;
180 	/* Extensions */
181 	u8 extensions;
182 	/* The type specific data */
183 	void *data;
184 };
185 
186 struct ip_set_counter {
187 	atomic64_t bytes;
188 	atomic64_t packets;
189 };
190 
191 static inline void
ip_set_add_bytes(u64 bytes,struct ip_set_counter * counter)192 ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
193 {
194 	atomic64_add((long long)bytes, &(counter)->bytes);
195 }
196 
197 static inline void
ip_set_add_packets(u64 packets,struct ip_set_counter * counter)198 ip_set_add_packets(u64 packets, struct ip_set_counter *counter)
199 {
200 	atomic64_add((long long)packets, &(counter)->packets);
201 }
202 
203 static inline u64
ip_set_get_bytes(const struct ip_set_counter * counter)204 ip_set_get_bytes(const struct ip_set_counter *counter)
205 {
206 	return (u64)atomic64_read(&(counter)->bytes);
207 }
208 
209 static inline u64
ip_set_get_packets(const struct ip_set_counter * counter)210 ip_set_get_packets(const struct ip_set_counter *counter)
211 {
212 	return (u64)atomic64_read(&(counter)->packets);
213 }
214 
215 static inline void
ip_set_update_counter(struct ip_set_counter * counter,const struct ip_set_ext * ext,struct ip_set_ext * mext,u32 flags)216 ip_set_update_counter(struct ip_set_counter *counter,
217 		      const struct ip_set_ext *ext,
218 		      struct ip_set_ext *mext, u32 flags)
219 {
220 	if (ext->packets != ULLONG_MAX &&
221 	    !(flags & IPSET_FLAG_SKIP_COUNTER_UPDATE)) {
222 		ip_set_add_bytes(ext->bytes, counter);
223 		ip_set_add_packets(ext->packets, counter);
224 	}
225 	if (flags & IPSET_FLAG_MATCH_COUNTERS) {
226 		mext->packets = ip_set_get_packets(counter);
227 		mext->bytes = ip_set_get_bytes(counter);
228 	}
229 }
230 
231 static inline bool
ip_set_put_counter(struct sk_buff * skb,struct ip_set_counter * counter)232 ip_set_put_counter(struct sk_buff *skb, struct ip_set_counter *counter)
233 {
234 	return nla_put_net64(skb, IPSET_ATTR_BYTES,
235 			     cpu_to_be64(ip_set_get_bytes(counter))) ||
236 	       nla_put_net64(skb, IPSET_ATTR_PACKETS,
237 			     cpu_to_be64(ip_set_get_packets(counter)));
238 }
239 
240 static inline void
ip_set_init_counter(struct ip_set_counter * counter,const struct ip_set_ext * ext)241 ip_set_init_counter(struct ip_set_counter *counter,
242 		    const struct ip_set_ext *ext)
243 {
244 	if (ext->bytes != ULLONG_MAX)
245 		atomic64_set(&(counter)->bytes, (long long)(ext->bytes));
246 	if (ext->packets != ULLONG_MAX)
247 		atomic64_set(&(counter)->packets, (long long)(ext->packets));
248 }
249 
250 /* register and unregister set references */
251 extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set);
252 extern void ip_set_put_byindex(ip_set_id_t index);
253 extern const char *ip_set_name_byindex(ip_set_id_t index);
254 extern ip_set_id_t ip_set_nfnl_get(const char *name);
255 extern ip_set_id_t ip_set_nfnl_get_byindex(ip_set_id_t index);
256 extern void ip_set_nfnl_put(ip_set_id_t index);
257 
258 /* API for iptables set match, and SET target */
259 
260 extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb,
261 		      const struct xt_action_param *par,
262 		      struct ip_set_adt_opt *opt);
263 extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb,
264 		      const struct xt_action_param *par,
265 		      struct ip_set_adt_opt *opt);
266 extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb,
267 		       const struct xt_action_param *par,
268 		       struct ip_set_adt_opt *opt);
269 
270 /* Utility functions */
271 extern void *ip_set_alloc(size_t size);
272 extern void ip_set_free(void *members);
273 extern int ip_set_get_ipaddr4(struct nlattr *nla,  __be32 *ipaddr);
274 extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
275 extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
276 				 struct ip_set_ext *ext);
277 
278 static inline int
ip_set_get_hostipaddr4(struct nlattr * nla,u32 * ipaddr)279 ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
280 {
281 	__be32 ip;
282 	int ret = ip_set_get_ipaddr4(nla, &ip);
283 
284 	if (ret)
285 		return ret;
286 	*ipaddr = ntohl(ip);
287 	return 0;
288 }
289 
290 /* Ignore IPSET_ERR_EXIST errors if asked to do so? */
291 static inline bool
ip_set_eexist(int ret,u32 flags)292 ip_set_eexist(int ret, u32 flags)
293 {
294 	return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST);
295 }
296 
297 /* Match elements marked with nomatch */
298 static inline bool
ip_set_enomatch(int ret,u32 flags,enum ipset_adt adt)299 ip_set_enomatch(int ret, u32 flags, enum ipset_adt adt)
300 {
301 	return adt == IPSET_TEST &&
302 	       ret == -ENOTEMPTY && ((flags >> 16) & IPSET_FLAG_NOMATCH);
303 }
304 
305 /* Check the NLA_F_NET_BYTEORDER flag */
306 static inline bool
ip_set_attr_netorder(struct nlattr * tb[],int type)307 ip_set_attr_netorder(struct nlattr *tb[], int type)
308 {
309 	return tb[type] && (tb[type]->nla_type & NLA_F_NET_BYTEORDER);
310 }
311 
312 static inline bool
ip_set_optattr_netorder(struct nlattr * tb[],int type)313 ip_set_optattr_netorder(struct nlattr *tb[], int type)
314 {
315 	return !tb[type] || (tb[type]->nla_type & NLA_F_NET_BYTEORDER);
316 }
317 
318 /* Useful converters */
319 static inline u32
ip_set_get_h32(const struct nlattr * attr)320 ip_set_get_h32(const struct nlattr *attr)
321 {
322 	return ntohl(nla_get_be32(attr));
323 }
324 
325 static inline u16
ip_set_get_h16(const struct nlattr * attr)326 ip_set_get_h16(const struct nlattr *attr)
327 {
328 	return ntohs(nla_get_be16(attr));
329 }
330 
331 #define ipset_nest_start(skb, attr) nla_nest_start(skb, attr | NLA_F_NESTED)
332 #define ipset_nest_end(skb, start)  nla_nest_end(skb, start)
333 
nla_put_ipaddr4(struct sk_buff * skb,int type,__be32 ipaddr)334 static inline int nla_put_ipaddr4(struct sk_buff *skb, int type, __be32 ipaddr)
335 {
336 	struct nlattr *__nested = ipset_nest_start(skb, type);
337 	int ret;
338 
339 	if (!__nested)
340 		return -EMSGSIZE;
341 	ret = nla_put_net32(skb, IPSET_ATTR_IPADDR_IPV4, ipaddr);
342 	if (!ret)
343 		ipset_nest_end(skb, __nested);
344 	return ret;
345 }
346 
nla_put_ipaddr6(struct sk_buff * skb,int type,const struct in6_addr * ipaddrptr)347 static inline int nla_put_ipaddr6(struct sk_buff *skb, int type,
348 				  const struct in6_addr *ipaddrptr)
349 {
350 	struct nlattr *__nested = ipset_nest_start(skb, type);
351 	int ret;
352 
353 	if (!__nested)
354 		return -EMSGSIZE;
355 	ret = nla_put(skb, IPSET_ATTR_IPADDR_IPV6,
356 		      sizeof(struct in6_addr), ipaddrptr);
357 	if (!ret)
358 		ipset_nest_end(skb, __nested);
359 	return ret;
360 }
361 
362 /* Get address from skbuff */
363 static inline __be32
ip4addr(const struct sk_buff * skb,bool src)364 ip4addr(const struct sk_buff *skb, bool src)
365 {
366 	return src ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr;
367 }
368 
369 static inline void
ip4addrptr(const struct sk_buff * skb,bool src,__be32 * addr)370 ip4addrptr(const struct sk_buff *skb, bool src, __be32 *addr)
371 {
372 	*addr = src ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr;
373 }
374 
375 static inline void
ip6addrptr(const struct sk_buff * skb,bool src,struct in6_addr * addr)376 ip6addrptr(const struct sk_buff *skb, bool src, struct in6_addr *addr)
377 {
378 	memcpy(addr, src ? &ipv6_hdr(skb)->saddr : &ipv6_hdr(skb)->daddr,
379 	       sizeof(*addr));
380 }
381 
382 /* Calculate the bytes required to store the inclusive range of a-b */
383 static inline int
bitmap_bytes(u32 a,u32 b)384 bitmap_bytes(u32 a, u32 b)
385 {
386 	return 4 * ((((b - a + 8) / 8) + 3) / 4);
387 }
388 
389 #include <linux/netfilter/ipset/ip_set_timeout.h>
390 
391 #define IP_SET_INIT_KEXT(skb, opt, map)			\
392 	{ .bytes = (skb)->len, .packets = 1,		\
393 	  .timeout = ip_set_adt_opt_timeout(opt, map) }
394 
395 #define IP_SET_INIT_UEXT(map)				\
396 	{ .bytes = ULLONG_MAX, .packets = ULLONG_MAX,	\
397 	  .timeout = (map)->timeout }
398 
399 #endif /*_IP_SET_H */
400