1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de>
3 * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 /* Kernel module for IP set management */
12 #include <linux/version.h>
13 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
14 #include <linux/config.h>
16 #include <linux/module.h>
17 #include <linux/moduleparam.h>
18 #include <linux/kmod.h>
20 #include <linux/skbuff.h>
21 #include <linux/random.h>
22 #include <linux/netfilter_ipv4/ip_set_jhash.h>
23 #include <linux/errno.h>
24 #include <linux/capability.h>
25 #include <asm/uaccess.h>
26 #include <asm/bitops.h>
27 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
28 #include <asm/semaphore.h>
30 #include <linux/semaphore.h>
32 #include <linux/spinlock.h>
34 #define ASSERT_READ_LOCK(x)
35 #define ASSERT_WRITE_LOCK(x)
36 #include <linux/netfilter.h>
37 #include <linux/netfilter_ipv4/ip_set.h>
39 static struct list_head set_type_list
; /* all registered sets */
40 static struct ip_set
**ip_set_list
; /* all individual sets */
41 static DEFINE_RWLOCK(ip_set_lock
); /* protects the lists and the hash */
42 static struct semaphore ip_set_app_mutex
; /* serializes user access */
43 static ip_set_id_t ip_set_max
= CONFIG_IP_NF_SET_MAX
;
44 static int protocol_version
= IP_SET_PROTOCOL_VERSION
;
46 #define STREQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
47 #define DONT_ALIGN (protocol_version == IP_SET_PROTOCOL_UNALIGNED)
48 #define ALIGNED(len) IPSET_VALIGN(len, DONT_ALIGN)
51 * Sets are identified either by the index in ip_set_list or by id.
52 * The id never changes. The index may change by swapping and used
53 * by external references (set/SET netfilter modules, etc.)
55 * Userspace requests are serialized by ip_set_mutex and sets can
56 * be deleted only from userspace. Therefore ip_set_list locking
57 * must obey the following rules:
59 * - kernel requests: read and write locking mandatory
60 * - user requests: read locking optional, write locking mandatory
64 __ip_set_get(ip_set_id_t index
)
66 atomic_inc(&ip_set_list
[index
]->ref
);
70 __ip_set_put(ip_set_id_t index
)
72 atomic_dec(&ip_set_list
[index
]->ref
);
75 /* Add, del and test set entries from kernel */
78 ip_set_testip_kernel(ip_set_id_t index
,
79 const struct sk_buff
*skb
,
80 const u_int32_t
*flags
)
85 read_lock_bh(&ip_set_lock
);
86 set
= ip_set_list
[index
];
88 DP("set %s, index %u", set
->name
, index
);
90 read_lock_bh(&set
->lock
);
91 res
= set
->type
->testip_kernel(set
, skb
, flags
);
92 read_unlock_bh(&set
->lock
);
94 read_unlock_bh(&ip_set_lock
);
96 return (res
< 0 ? 0 : res
);
100 ip_set_addip_kernel(ip_set_id_t index
,
101 const struct sk_buff
*skb
,
102 const u_int32_t
*flags
)
108 read_lock_bh(&ip_set_lock
);
109 set
= ip_set_list
[index
];
111 DP("set %s, index %u", set
->name
, index
);
113 write_lock_bh(&set
->lock
);
114 res
= set
->type
->addip_kernel(set
, skb
, flags
);
115 write_unlock_bh(&set
->lock
);
117 read_unlock_bh(&ip_set_lock
);
118 /* Retry function called without holding any lock */
121 && (res
= set
->type
->retry(set
)) == 0)
128 ip_set_delip_kernel(ip_set_id_t index
,
129 const struct sk_buff
*skb
,
130 const u_int32_t
*flags
)
135 read_lock_bh(&ip_set_lock
);
136 set
= ip_set_list
[index
];
138 DP("set %s, index %u", set
->name
, index
);
140 write_lock_bh(&set
->lock
);
141 res
= set
->type
->delip_kernel(set
, skb
, flags
);
142 write_unlock_bh(&set
->lock
);
144 read_unlock_bh(&ip_set_lock
);
149 /* Register and deregister settype */
151 static inline struct ip_set_type
*
152 find_set_type(const char *name
)
154 struct ip_set_type
*set_type
;
156 list_for_each_entry(set_type
, &set_type_list
, list
)
157 if (STREQ(set_type
->typename
, name
))
163 ip_set_register_set_type(struct ip_set_type
*set_type
)
167 if (set_type
->protocol_version
!= IP_SET_PROTOCOL_VERSION
) {
168 ip_set_printk("'%s' uses wrong protocol version %u (want %u)",
170 set_type
->protocol_version
,
171 IP_SET_PROTOCOL_VERSION
);
175 write_lock_bh(&ip_set_lock
);
176 if (find_set_type(set_type
->typename
)) {
178 ip_set_printk("'%s' already registered!",
183 if (!try_module_get(THIS_MODULE
)) {
187 list_add(&set_type
->list
, &set_type_list
);
188 DP("'%s' registered.", set_type
->typename
);
190 write_unlock_bh(&ip_set_lock
);
195 ip_set_unregister_set_type(struct ip_set_type
*set_type
)
197 write_lock_bh(&ip_set_lock
);
198 if (!find_set_type(set_type
->typename
)) {
199 ip_set_printk("'%s' not registered?",
203 list_del(&set_type
->list
);
204 module_put(THIS_MODULE
);
205 DP("'%s' unregistered.", set_type
->typename
);
207 write_unlock_bh(&ip_set_lock
);
212 __ip_set_get_byname(const char *name
, struct ip_set
**set
)
214 ip_set_id_t i
, index
= IP_SET_INVALID_ID
;
216 for (i
= 0; i
< ip_set_max
; i
++) {
217 if (ip_set_list
[i
] != NULL
218 && STREQ(ip_set_list
[i
]->name
, name
)) {
221 *set
= ip_set_list
[i
];
229 __ip_set_put_byindex(ip_set_id_t index
)
231 if (ip_set_list
[index
])
240 * Find set by name, reference it once. The reference makes sure the
241 * thing pointed to, does not go away under our feet. Drop the reference
242 * later, using ip_set_put().
245 ip_set_get_byname(const char *name
)
247 ip_set_id_t i
, index
= IP_SET_INVALID_ID
;
249 down(&ip_set_app_mutex
);
250 for (i
= 0; i
< ip_set_max
; i
++) {
251 if (ip_set_list
[i
] != NULL
252 && STREQ(ip_set_list
[i
]->name
, name
)) {
258 up(&ip_set_app_mutex
);
263 * Find set by index, reference it once. The reference makes sure the
264 * thing pointed to, does not go away under our feet. Drop the reference
265 * later, using ip_set_put().
268 ip_set_get_byindex(ip_set_id_t index
)
270 down(&ip_set_app_mutex
);
272 if (index
>= ip_set_max
)
273 return IP_SET_INVALID_ID
;
275 if (ip_set_list
[index
])
278 index
= IP_SET_INVALID_ID
;
280 up(&ip_set_app_mutex
);
285 * Find the set id belonging to the index.
286 * We are protected by the mutex, so we do not need to use
287 * ip_set_lock. There is no need to reference the sets either.
290 ip_set_id(ip_set_id_t index
)
292 if (index
>= ip_set_max
|| !ip_set_list
[index
])
293 return IP_SET_INVALID_ID
;
295 return ip_set_list
[index
]->id
;
299 * If the given set pointer points to a valid set, decrement
300 * reference count by 1. The caller shall not assume the index
301 * to be valid, after calling this function.
304 ip_set_put_byindex(ip_set_id_t index
)
306 down(&ip_set_app_mutex
);
307 if (ip_set_list
[index
])
309 up(&ip_set_app_mutex
);
312 /* Find a set by name or index */
314 ip_set_find_byname(const char *name
)
316 ip_set_id_t i
, index
= IP_SET_INVALID_ID
;
318 for (i
= 0; i
< ip_set_max
; i
++) {
319 if (ip_set_list
[i
] != NULL
320 && STREQ(ip_set_list
[i
]->name
, name
)) {
329 ip_set_find_byindex(ip_set_id_t index
)
331 if (index
>= ip_set_max
|| ip_set_list
[index
] == NULL
)
332 index
= IP_SET_INVALID_ID
;
342 ip_set_addip(struct ip_set
*set
, const void *data
, u_int32_t size
)
348 write_lock_bh(&set
->lock
);
349 res
= set
->type
->addip(set
, data
, size
);
350 write_unlock_bh(&set
->lock
);
351 } while (res
== -EAGAIN
353 && (res
= set
->type
->retry(set
)) == 0);
359 ip_set_delip(struct ip_set
*set
, const void *data
, u_int32_t size
)
365 write_lock_bh(&set
->lock
);
366 res
= set
->type
->delip(set
, data
, size
);
367 write_unlock_bh(&set
->lock
);
373 ip_set_testip(struct ip_set
*set
, const void *data
, u_int32_t size
)
379 read_lock_bh(&set
->lock
);
380 res
= set
->type
->testip(set
, data
, size
);
381 read_unlock_bh(&set
->lock
);
383 return (res
> 0 ? -EEXIST
: res
);
386 static struct ip_set_type
*
387 find_set_type_rlock(const char *typename
)
389 struct ip_set_type
*type
;
391 read_lock_bh(&ip_set_lock
);
392 type
= find_set_type(typename
);
394 read_unlock_bh(&ip_set_lock
);
400 find_free_id(const char *name
,
406 *id
= IP_SET_INVALID_ID
;
407 for (i
= 0; i
< ip_set_max
; i
++) {
408 if (ip_set_list
[i
] == NULL
) {
409 if (*id
== IP_SET_INVALID_ID
)
411 } else if (STREQ(name
, ip_set_list
[i
]->name
))
415 if (*id
== IP_SET_INVALID_ID
)
416 /* No free slot remained */
418 /* Check that index is usable as id (swapping) */
420 for (i
= 0; i
< ip_set_max
; i
++) {
421 if (ip_set_list
[i
] != NULL
422 && ip_set_list
[i
]->id
== *id
) {
434 ip_set_create(const char *name
,
435 const char *typename
,
441 ip_set_id_t index
= 0, id
;
444 DP("setname: %s, typename: %s, id: %u", name
, typename
, restore
);
447 * First, and without any locks, allocate and initialize
448 * a normal base set structure.
450 set
= kmalloc(sizeof(struct ip_set
), GFP_KERNEL
);
453 rwlock_init(&set
->lock
);
454 strncpy(set
->name
, name
, IP_SET_MAXNAMELEN
);
455 atomic_set(&set
->ref
, 0);
458 * Next, take the &ip_set_lock, check that we know the type,
459 * and take a reference on the type, to make sure it
460 * stays available while constructing our new set.
462 * After referencing the type, we drop the &ip_set_lock,
463 * and let the new set construction run without locks.
465 set
->type
= find_set_type_rlock(typename
);
466 if (set
->type
== NULL
) {
467 /* Try loading the module */
468 char modulename
[IP_SET_MAXNAMELEN
+ strlen("ip_set_") + 1];
469 strcpy(modulename
, "ip_set_");
470 strcat(modulename
, typename
);
471 DP("try to load %s", modulename
);
472 request_module(modulename
);
473 set
->type
= find_set_type_rlock(typename
);
475 if (set
->type
== NULL
) {
476 ip_set_printk("no set type '%s', set '%s' not created",
481 if (!try_module_get(set
->type
->me
)) {
482 read_unlock_bh(&ip_set_lock
);
486 read_unlock_bh(&ip_set_lock
);
488 /* Check request size */
489 if (size
!= set
->type
->header_size
) {
490 ip_set_printk("data length wrong (want %lu, have %lu)",
491 (long unsigned)set
->type
->header_size
,
492 (long unsigned)size
);
497 * Without holding any locks, create private part.
499 res
= set
->type
->create(set
, data
, size
);
503 /* BTW, res==0 here. */
506 * Here, we have a valid, constructed set. &ip_set_lock again,
507 * find free id/index and check that it is not already in
510 write_lock_bh(&ip_set_lock
);
511 if ((res
= find_free_id(set
->name
, &index
, &id
)) != 0) {
516 /* Make sure restore gets the same index */
517 if (restore
!= IP_SET_INVALID_ID
&& index
!= restore
) {
518 DP("Can't restore, sets are screwed up");
524 * Finally! Add our shiny new set to the list, and be done.
526 DP("create: '%s' created with index %u, id %u!", set
->name
, index
, id
);
528 ip_set_list
[index
] = set
;
529 write_unlock_bh(&ip_set_lock
);
533 write_unlock_bh(&ip_set_lock
);
534 set
->type
->destroy(set
);
536 module_put(set
->type
->me
);
543 * Destroy a given existing set
546 ip_set_destroy_set(ip_set_id_t index
)
548 struct ip_set
*set
= ip_set_list
[index
];
551 DP("set: %s", set
->name
);
552 write_lock_bh(&ip_set_lock
);
553 ip_set_list
[index
] = NULL
;
554 write_unlock_bh(&ip_set_lock
);
556 /* Must call it without holding any lock */
557 set
->type
->destroy(set
);
558 module_put(set
->type
->me
);
563 * Destroy a set - or all sets
564 * Sets must not be referenced/used.
567 ip_set_destroy(ip_set_id_t index
)
571 /* ref modification always protected by the mutex */
572 if (index
!= IP_SET_INVALID_ID
) {
573 if (atomic_read(&ip_set_list
[index
]->ref
))
575 ip_set_destroy_set(index
);
577 for (i
= 0; i
< ip_set_max
; i
++) {
578 if (ip_set_list
[i
] != NULL
579 && (atomic_read(&ip_set_list
[i
]->ref
)))
583 for (i
= 0; i
< ip_set_max
; i
++) {
584 if (ip_set_list
[i
] != NULL
)
585 ip_set_destroy_set(i
);
592 ip_set_flush_set(struct ip_set
*set
)
594 DP("set: %s %u", set
->name
, set
->id
);
596 write_lock_bh(&set
->lock
);
597 set
->type
->flush(set
);
598 write_unlock_bh(&set
->lock
);
602 * Flush data in a set - or in all sets
605 ip_set_flush(ip_set_id_t index
)
607 if (index
!= IP_SET_INVALID_ID
) {
608 IP_SET_ASSERT(ip_set_list
[index
]);
609 ip_set_flush_set(ip_set_list
[index
]);
613 for (i
= 0; i
< ip_set_max
; i
++)
614 if (ip_set_list
[i
] != NULL
)
615 ip_set_flush_set(ip_set_list
[i
]);
623 ip_set_rename(ip_set_id_t index
, const char *name
)
625 struct ip_set
*set
= ip_set_list
[index
];
629 DP("set: %s to %s", set
->name
, name
);
630 write_lock_bh(&ip_set_lock
);
631 for (i
= 0; i
< ip_set_max
; i
++) {
632 if (ip_set_list
[i
] != NULL
633 && STREQ(ip_set_list
[i
]->name
, name
)) {
638 strncpy(set
->name
, name
, IP_SET_MAXNAMELEN
);
640 write_unlock_bh(&ip_set_lock
);
645 * Swap two sets so that name/index points to the other.
646 * References are also swapped.
649 ip_set_swap(ip_set_id_t from_index
, ip_set_id_t to_index
)
651 struct ip_set
*from
= ip_set_list
[from_index
];
652 struct ip_set
*to
= ip_set_list
[to_index
];
653 char from_name
[IP_SET_MAXNAMELEN
];
656 DP("set: %s to %s", from
->name
, to
->name
);
657 /* Features must not change.
658 * Not an artifical restriction anymore, as we must prevent
659 * possible loops created by swapping in setlist type of sets. */
660 if (from
->type
->features
!= to
->type
->features
)
663 /* No magic here: ref munging protected by the mutex */
664 write_lock_bh(&ip_set_lock
);
665 strncpy(from_name
, from
->name
, IP_SET_MAXNAMELEN
);
666 from_ref
= atomic_read(&from
->ref
);
668 strncpy(from
->name
, to
->name
, IP_SET_MAXNAMELEN
);
669 atomic_set(&from
->ref
, atomic_read(&to
->ref
));
670 strncpy(to
->name
, from_name
, IP_SET_MAXNAMELEN
);
671 atomic_set(&to
->ref
, from_ref
);
673 ip_set_list
[from_index
] = to
;
674 ip_set_list
[to_index
] = from
;
676 write_unlock_bh(&ip_set_lock
);
685 ip_set_list_set(ip_set_id_t index
, void *data
, int *used
, int len
)
687 struct ip_set
*set
= ip_set_list
[index
];
688 struct ip_set_list
*set_list
;
690 /* Pointer to our header */
691 set_list
= data
+ *used
;
693 DP("set: %s, used: %d len %u %p %p", set
->name
, *used
, len
, data
, data
+ *used
);
695 /* Get and ensure header size */
696 if (*used
+ ALIGNED(sizeof(struct ip_set_list
)) > len
)
698 *used
+= ALIGNED(sizeof(struct ip_set_list
));
700 read_lock_bh(&set
->lock
);
701 /* Get and ensure set specific header size */
702 set_list
->header_size
= ALIGNED(set
->type
->header_size
);
703 if (*used
+ set_list
->header_size
> len
)
706 /* Fill in the header */
707 set_list
->index
= index
;
708 set_list
->binding
= IP_SET_INVALID_ID
;
709 set_list
->ref
= atomic_read(&set
->ref
);
711 /* Fill in set spefific header data */
712 set
->type
->list_header(set
, data
+ *used
);
713 *used
+= set_list
->header_size
;
715 /* Get and ensure set specific members size */
716 set_list
->members_size
= set
->type
->list_members_size(set
, DONT_ALIGN
);
717 if (*used
+ set_list
->members_size
> len
)
720 /* Fill in set spefific members data */
721 set
->type
->list_members(set
, data
+ *used
, DONT_ALIGN
);
722 *used
+= set_list
->members_size
;
723 read_unlock_bh(&set
->lock
);
726 set_list
->bindings_size
= 0;
731 read_unlock_bh(&set
->lock
);
733 DP("not enough mem, try again");
741 ip_set_save_marker(void *data
, int *used
, int len
)
743 struct ip_set_save
*set_save
;
745 DP("used %u, len %u", *used
, len
);
746 /* Get and ensure header size */
747 if (*used
+ ALIGNED(sizeof(struct ip_set_save
)) > len
)
750 /* Marker: just for backward compatibility */
751 set_save
= data
+ *used
;
752 set_save
->index
= IP_SET_INVALID_ID
;
753 set_save
->header_size
= 0;
754 set_save
->members_size
= 0;
755 *used
+= ALIGNED(sizeof(struct ip_set_save
));
761 ip_set_save_set(ip_set_id_t index
, void *data
, int *used
, int len
)
764 struct ip_set_save
*set_save
;
766 /* Pointer to our header */
767 set_save
= data
+ *used
;
769 /* Get and ensure header size */
770 if (*used
+ ALIGNED(sizeof(struct ip_set_save
)) > len
)
772 *used
+= ALIGNED(sizeof(struct ip_set_save
));
774 set
= ip_set_list
[index
];
775 DP("set: %s, used: %d(%d) %p %p", set
->name
, *used
, len
,
778 read_lock_bh(&set
->lock
);
779 /* Get and ensure set specific header size */
780 set_save
->header_size
= ALIGNED(set
->type
->header_size
);
781 if (*used
+ set_save
->header_size
> len
)
784 /* Fill in the header */
785 set_save
->index
= index
;
786 set_save
->binding
= IP_SET_INVALID_ID
;
788 /* Fill in set spefific header data */
789 set
->type
->list_header(set
, data
+ *used
);
790 *used
+= set_save
->header_size
;
792 DP("set header filled: %s, used: %d(%lu) %p %p", set
->name
, *used
,
793 (unsigned long)set_save
->header_size
, data
, data
+ *used
);
794 /* Get and ensure set specific members size */
795 set_save
->members_size
= set
->type
->list_members_size(set
, DONT_ALIGN
);
796 if (*used
+ set_save
->members_size
> len
)
799 /* Fill in set spefific members data */
800 set
->type
->list_members(set
, data
+ *used
, DONT_ALIGN
);
801 *used
+= set_save
->members_size
;
802 read_unlock_bh(&set
->lock
);
803 DP("set members filled: %s, used: %d(%lu) %p %p", set
->name
, *used
,
804 (unsigned long)set_save
->members_size
, data
, data
+ *used
);
808 read_unlock_bh(&set
->lock
);
810 DP("not enough mem, try again");
818 ip_set_restore(void *data
, int len
)
821 int line
= 0, used
= 0, members_size
;
823 struct ip_set_restore
*set_restore
;
826 /* Loop to restore sets */
830 DP("%d %zu %d", used
, ALIGNED(sizeof(struct ip_set_restore
)), len
);
831 /* Get and ensure header size */
832 if (used
+ ALIGNED(sizeof(struct ip_set_restore
)) > len
)
834 set_restore
= data
+ used
;
835 used
+= ALIGNED(sizeof(struct ip_set_restore
));
837 /* Ensure data size */
839 + set_restore
->header_size
840 + set_restore
->members_size
> len
)
844 if (set_restore
->index
== IP_SET_INVALID_ID
) {
849 /* Try to create the set */
850 DP("restore %s %s", set_restore
->name
, set_restore
->typename
);
851 res
= ip_set_create(set_restore
->name
,
852 set_restore
->typename
,
855 set_restore
->header_size
);
859 used
+= ALIGNED(set_restore
->header_size
);
861 index
= ip_set_find_byindex(set_restore
->index
);
862 DP("index %u, restore_index %u", index
, set_restore
->index
);
863 if (index
!= set_restore
->index
)
865 /* Try to restore members data */
866 set
= ip_set_list
[index
];
868 DP("members_size %lu reqsize %lu",
869 (unsigned long)set_restore
->members_size
,
870 (unsigned long)set
->type
->reqsize
);
871 while (members_size
+ ALIGNED(set
->type
->reqsize
) <=
872 set_restore
->members_size
) {
874 DP("members: %d, line %d", members_size
, line
);
875 res
= ip_set_addip(set
,
876 data
+ used
+ members_size
,
878 if (!(res
== 0 || res
== -EEXIST
))
880 members_size
+= ALIGNED(set
->type
->reqsize
);
883 DP("members_size %lu %d",
884 (unsigned long)set_restore
->members_size
, members_size
);
885 if (members_size
!= set_restore
->members_size
)
887 used
+= set_restore
->members_size
;
898 ip_set_sockfn_set(struct sock
*sk
, int optval
, void *user
, unsigned int len
)
901 int res
= 0; /* Assume OK */
904 struct ip_set_req_adt
*req_adt
;
905 ip_set_id_t index
= IP_SET_INVALID_ID
;
906 int (*adtfn
)(struct ip_set
*set
,
907 const void *data
, u_int32_t size
);
909 int (*fn
)(struct ip_set
*set
,
910 const void *data
, u_int32_t size
);
912 { { ip_set_addip
}, { ip_set_delip
}, { ip_set_testip
},
915 DP("optval=%d, user=%p, len=%d", optval
, user
, len
);
916 if (!capable(CAP_NET_ADMIN
))
918 if (optval
!= SO_IP_SET
)
920 if (len
<= sizeof(unsigned)) {
921 ip_set_printk("short userdata (want >%zu, got %u)",
922 sizeof(unsigned), len
);
927 DP("out of mem for %u bytes", len
);
930 if (copy_from_user(data
, user
, len
) != 0) {
934 if (down_interruptible(&ip_set_app_mutex
)) {
939 op
= (unsigned *)data
;
942 if (*op
< IP_SET_OP_VERSION
) {
943 /* Check the version at the beginning of operations */
944 struct ip_set_req_version
*req_version
= data
;
945 if (!(req_version
->version
== IP_SET_PROTOCOL_UNALIGNED
946 || req_version
->version
== IP_SET_PROTOCOL_VERSION
)) {
950 protocol_version
= req_version
->version
;
954 case IP_SET_OP_CREATE
:{
955 struct ip_set_req_create
*req_create
= data
;
956 offset
= ALIGNED(sizeof(struct ip_set_req_create
));
959 ip_set_printk("short CREATE data (want >=%zu, got %u)",
964 req_create
->name
[IP_SET_MAXNAMELEN
- 1] = '\0';
965 req_create
->typename
[IP_SET_MAXNAMELEN
- 1] = '\0';
966 res
= ip_set_create(req_create
->name
,
967 req_create
->typename
,
973 case IP_SET_OP_DESTROY
:{
974 struct ip_set_req_std
*req_destroy
= data
;
976 if (len
!= sizeof(struct ip_set_req_std
)) {
977 ip_set_printk("invalid DESTROY data (want %zu, got %u)",
978 sizeof(struct ip_set_req_std
), len
);
982 if (STREQ(req_destroy
->name
, IPSET_TOKEN_ALL
)) {
983 /* Destroy all sets */
984 index
= IP_SET_INVALID_ID
;
986 req_destroy
->name
[IP_SET_MAXNAMELEN
- 1] = '\0';
987 index
= ip_set_find_byname(req_destroy
->name
);
989 if (index
== IP_SET_INVALID_ID
) {
995 res
= ip_set_destroy(index
);
998 case IP_SET_OP_FLUSH
:{
999 struct ip_set_req_std
*req_flush
= data
;
1001 if (len
!= sizeof(struct ip_set_req_std
)) {
1002 ip_set_printk("invalid FLUSH data (want %zu, got %u)",
1003 sizeof(struct ip_set_req_std
), len
);
1007 if (STREQ(req_flush
->name
, IPSET_TOKEN_ALL
)) {
1008 /* Flush all sets */
1009 index
= IP_SET_INVALID_ID
;
1011 req_flush
->name
[IP_SET_MAXNAMELEN
- 1] = '\0';
1012 index
= ip_set_find_byname(req_flush
->name
);
1014 if (index
== IP_SET_INVALID_ID
) {
1019 res
= ip_set_flush(index
);
1022 case IP_SET_OP_RENAME
:{
1023 struct ip_set_req_create
*req_rename
= data
;
1025 if (len
!= sizeof(struct ip_set_req_create
)) {
1026 ip_set_printk("invalid RENAME data (want %zu, got %u)",
1027 sizeof(struct ip_set_req_create
), len
);
1032 req_rename
->name
[IP_SET_MAXNAMELEN
- 1] = '\0';
1033 req_rename
->typename
[IP_SET_MAXNAMELEN
- 1] = '\0';
1035 index
= ip_set_find_byname(req_rename
->name
);
1036 if (index
== IP_SET_INVALID_ID
) {
1040 res
= ip_set_rename(index
, req_rename
->typename
);
1043 case IP_SET_OP_SWAP
:{
1044 struct ip_set_req_create
*req_swap
= data
;
1045 ip_set_id_t to_index
;
1047 if (len
!= sizeof(struct ip_set_req_create
)) {
1048 ip_set_printk("invalid SWAP data (want %zu, got %u)",
1049 sizeof(struct ip_set_req_create
), len
);
1054 req_swap
->name
[IP_SET_MAXNAMELEN
- 1] = '\0';
1055 req_swap
->typename
[IP_SET_MAXNAMELEN
- 1] = '\0';
1057 index
= ip_set_find_byname(req_swap
->name
);
1058 if (index
== IP_SET_INVALID_ID
) {
1062 to_index
= ip_set_find_byname(req_swap
->typename
);
1063 if (to_index
== IP_SET_INVALID_ID
) {
1067 res
= ip_set_swap(index
, to_index
);
1071 break; /* Set identified by id */
1074 /* There we may have add/del/test/bind/unbind/test_bind operations */
1075 if (*op
< IP_SET_OP_ADD_IP
|| *op
> IP_SET_OP_TEST_IP
) {
1079 adtfn
= adtfn_table
[*op
- IP_SET_OP_ADD_IP
].fn
;
1081 if (len
< ALIGNED(sizeof(struct ip_set_req_adt
))) {
1082 ip_set_printk("short data in adt request (want >=%zu, got %u)",
1083 ALIGNED(sizeof(struct ip_set_req_adt
)), len
);
1089 index
= ip_set_find_byindex(req_adt
->index
);
1090 if (index
== IP_SET_INVALID_ID
) {
1095 struct ip_set
*set
= ip_set_list
[index
];
1096 size_t offset
= ALIGNED(sizeof(struct ip_set_req_adt
));
1100 if (len
- offset
!= set
->type
->reqsize
) {
1101 ip_set_printk("data length wrong (want %lu, have %zu)",
1102 (long unsigned)set
->type
->reqsize
,
1107 res
= adtfn(set
, data
+ offset
, len
- offset
);
1111 up(&ip_set_app_mutex
);
1116 DP("final result %d", res
);
1121 ip_set_sockfn_get(struct sock
*sk
, int optval
, void *user
, int *len
)
1125 ip_set_id_t index
= IP_SET_INVALID_ID
;
1129 DP("optval=%d, user=%p, len=%d", optval
, user
, *len
);
1130 if (!capable(CAP_NET_ADMIN
))
1132 if (optval
!= SO_IP_SET
)
1134 if (*len
< sizeof(unsigned)) {
1135 ip_set_printk("short userdata (want >=%zu, got %d)",
1136 sizeof(unsigned), *len
);
1139 data
= vmalloc(*len
);
1141 DP("out of mem for %d bytes", *len
);
1144 if (copy_from_user(data
, user
, *len
) != 0) {
1148 if (down_interruptible(&ip_set_app_mutex
)) {
1153 op
= (unsigned *) data
;
1156 if (*op
< IP_SET_OP_VERSION
) {
1157 /* Check the version at the beginning of operations */
1158 struct ip_set_req_version
*req_version
= data
;
1159 if (!(req_version
->version
== IP_SET_PROTOCOL_UNALIGNED
1160 || req_version
->version
== IP_SET_PROTOCOL_VERSION
)) {
1164 protocol_version
= req_version
->version
;
1168 case IP_SET_OP_VERSION
: {
1169 struct ip_set_req_version
*req_version
= data
;
1171 if (*len
!= sizeof(struct ip_set_req_version
)) {
1172 ip_set_printk("invalid VERSION (want %zu, got %d)",
1173 sizeof(struct ip_set_req_version
),
1179 req_version
->version
= IP_SET_PROTOCOL_VERSION
;
1180 res
= copy_to_user(user
, req_version
,
1181 sizeof(struct ip_set_req_version
));
1184 case IP_SET_OP_GET_BYNAME
: {
1185 struct ip_set_req_get_set
*req_get
= data
;
1187 if (*len
!= sizeof(struct ip_set_req_get_set
)) {
1188 ip_set_printk("invalid GET_BYNAME (want %zu, got %d)",
1189 sizeof(struct ip_set_req_get_set
), *len
);
1193 req_get
->set
.name
[IP_SET_MAXNAMELEN
- 1] = '\0';
1194 index
= ip_set_find_byname(req_get
->set
.name
);
1195 req_get
->set
.index
= index
;
1198 case IP_SET_OP_GET_BYINDEX
: {
1199 struct ip_set_req_get_set
*req_get
= data
;
1201 if (*len
!= sizeof(struct ip_set_req_get_set
)) {
1202 ip_set_printk("invalid GET_BYINDEX (want %zu, got %d)",
1203 sizeof(struct ip_set_req_get_set
), *len
);
1207 req_get
->set
.name
[IP_SET_MAXNAMELEN
- 1] = '\0';
1208 index
= ip_set_find_byindex(req_get
->set
.index
);
1209 strncpy(req_get
->set
.name
,
1210 index
== IP_SET_INVALID_ID
? ""
1211 : ip_set_list
[index
]->name
, IP_SET_MAXNAMELEN
);
1214 case IP_SET_OP_ADT_GET
: {
1215 struct ip_set_req_adt_get
*req_get
= data
;
1217 if (*len
!= sizeof(struct ip_set_req_adt_get
)) {
1218 ip_set_printk("invalid ADT_GET (want %zu, got %d)",
1219 sizeof(struct ip_set_req_adt_get
), *len
);
1223 req_get
->set
.name
[IP_SET_MAXNAMELEN
- 1] = '\0';
1224 index
= ip_set_find_byname(req_get
->set
.name
);
1225 if (index
!= IP_SET_INVALID_ID
) {
1226 req_get
->set
.index
= index
;
1227 strncpy(req_get
->typename
,
1228 ip_set_list
[index
]->type
->typename
,
1229 IP_SET_MAXNAMELEN
- 1);
1236 case IP_SET_OP_MAX_SETS
: {
1237 struct ip_set_req_max_sets
*req_max_sets
= data
;
1240 if (*len
!= sizeof(struct ip_set_req_max_sets
)) {
1241 ip_set_printk("invalid MAX_SETS (want %zu, got %d)",
1242 sizeof(struct ip_set_req_max_sets
), *len
);
1247 if (STREQ(req_max_sets
->set
.name
, IPSET_TOKEN_ALL
)) {
1248 req_max_sets
->set
.index
= IP_SET_INVALID_ID
;
1250 req_max_sets
->set
.name
[IP_SET_MAXNAMELEN
- 1] = '\0';
1251 req_max_sets
->set
.index
=
1252 ip_set_find_byname(req_max_sets
->set
.name
);
1253 if (req_max_sets
->set
.index
== IP_SET_INVALID_ID
) {
1258 req_max_sets
->max_sets
= ip_set_max
;
1259 req_max_sets
->sets
= 0;
1260 for (i
= 0; i
< ip_set_max
; i
++) {
1261 if (ip_set_list
[i
] != NULL
)
1262 req_max_sets
->sets
++;
1266 case IP_SET_OP_LIST_SIZE
:
1267 case IP_SET_OP_SAVE_SIZE
: {
1268 struct ip_set_req_setnames
*req_setnames
= data
;
1269 struct ip_set_name_list
*name_list
;
1274 if (*len
< ALIGNED(sizeof(struct ip_set_req_setnames
))) {
1275 ip_set_printk("short LIST_SIZE (want >=%zu, got %d)",
1276 ALIGNED(sizeof(struct ip_set_req_setnames
)),
1282 req_setnames
->size
= 0;
1283 used
= ALIGNED(sizeof(struct ip_set_req_setnames
));
1284 for (i
= 0; i
< ip_set_max
; i
++) {
1285 if (ip_set_list
[i
] == NULL
)
1287 name_list
= data
+ used
;
1288 used
+= ALIGNED(sizeof(struct ip_set_name_list
));
1289 if (used
> copylen
) {
1293 set
= ip_set_list
[i
];
1294 /* Fill in index, name, etc. */
1295 name_list
->index
= i
;
1296 name_list
->id
= set
->id
;
1297 strncpy(name_list
->name
,
1299 IP_SET_MAXNAMELEN
- 1);
1300 strncpy(name_list
->typename
,
1301 set
->type
->typename
,
1302 IP_SET_MAXNAMELEN
- 1);
1303 DP("filled %s of type %s, index %u\n",
1304 name_list
->name
, name_list
->typename
,
1306 if (!(req_setnames
->index
== IP_SET_INVALID_ID
1307 || req_setnames
->index
== i
))
1310 req_setnames
->size
+=
1311 (*op
== IP_SET_OP_LIST_SIZE
?
1312 ALIGNED(sizeof(struct ip_set_list
)) :
1313 ALIGNED(sizeof(struct ip_set_save
)))
1314 + ALIGNED(set
->type
->header_size
)
1315 + set
->type
->list_members_size(set
, DONT_ALIGN
);
1317 if (copylen
!= used
) {
1323 case IP_SET_OP_LIST
: {
1324 struct ip_set_req_list
*req_list
= data
;
1328 if (*len
< sizeof(struct ip_set_req_list
)) {
1329 ip_set_printk("short LIST (want >=%zu, got %d)",
1330 sizeof(struct ip_set_req_list
), *len
);
1334 index
= req_list
->index
;
1335 if (index
!= IP_SET_INVALID_ID
1336 && ip_set_find_byindex(index
) != index
) {
1341 if (index
== IP_SET_INVALID_ID
) {
1343 for (i
= 0; i
< ip_set_max
&& res
== 0; i
++) {
1344 if (ip_set_list
[i
] != NULL
)
1345 res
= ip_set_list_set(i
, data
, &used
, *len
);
1348 /* List an individual set */
1349 res
= ip_set_list_set(index
, data
, &used
, *len
);
1353 else if (copylen
!= used
) {
1359 case IP_SET_OP_SAVE
: {
1360 struct ip_set_req_list
*req_save
= data
;
1364 if (*len
< sizeof(struct ip_set_req_list
)) {
1365 ip_set_printk("short SAVE (want >=%zu, got %d)",
1366 sizeof(struct ip_set_req_list
), *len
);
1370 index
= req_save
->index
;
1371 if (index
!= IP_SET_INVALID_ID
1372 && ip_set_find_byindex(index
) != index
) {
1377 #define SETLIST(set) (strcmp(set->type->typename, "setlist") == 0)
1380 if (index
== IP_SET_INVALID_ID
) {
1381 /* Save all sets: ugly setlist type dependency */
1384 for (i
= 0; i
< ip_set_max
&& res
== 0; i
++) {
1385 if (ip_set_list
[i
] != NULL
1386 && !(setlist
^ SETLIST(ip_set_list
[i
])))
1387 res
= ip_set_save_set(i
, data
, &used
, *len
);
1394 /* Save an individual set */
1395 res
= ip_set_save_set(index
, data
, &used
, *len
);
1398 res
= ip_set_save_marker(data
, &used
, *len
);
1402 else if (copylen
!= used
) {
1408 case IP_SET_OP_RESTORE
: {
1409 struct ip_set_req_setnames
*req_restore
= data
;
1410 size_t offset
= ALIGNED(sizeof(struct ip_set_req_setnames
));
1413 if (*len
< offset
|| *len
!= req_restore
->size
) {
1414 ip_set_printk("invalid RESTORE (want =%lu, got %d)",
1415 (long unsigned)req_restore
->size
, *len
);
1419 line
= ip_set_restore(data
+ offset
, req_restore
->size
- offset
);
1420 DP("ip_set_restore: %d", line
);
1423 req_restore
->size
= line
;
1424 copylen
= sizeof(struct ip_set_req_setnames
);
1432 } /* end of switch(op) */
1435 DP("set %s, copylen %d", index
!= IP_SET_INVALID_ID
1436 && ip_set_list
[index
]
1437 ? ip_set_list
[index
]->name
1438 : ":all:", copylen
);
1439 res
= copy_to_user(user
, data
, copylen
);
1442 up(&ip_set_app_mutex
);
1447 DP("final result %d", res
);
1451 static struct nf_sockopt_ops so_set
= {
1453 .set_optmin
= SO_IP_SET
,
1454 .set_optmax
= SO_IP_SET
+ 1,
1455 .set
= &ip_set_sockfn_set
,
1456 .get_optmin
= SO_IP_SET
,
1457 .get_optmax
= SO_IP_SET
+ 1,
1458 .get
= &ip_set_sockfn_get
,
1459 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
1462 .owner
= THIS_MODULE
,
1466 static int max_sets
;
1468 module_param(max_sets
, int, 0600);
1469 MODULE_PARM_DESC(max_sets
, "maximal number of sets");
1470 MODULE_LICENSE("GPL");
1471 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
1472 MODULE_DESCRIPTION("module implementing core IP set support");
1479 /* For the -rt branch, DECLARE_MUTEX/init_MUTEX avoided */
1480 sema_init(&ip_set_app_mutex
, 1);
1483 ip_set_max
= max_sets
;
1484 if (ip_set_max
>= IP_SET_INVALID_ID
)
1485 ip_set_max
= IP_SET_INVALID_ID
- 1;
1487 ip_set_list
= vmalloc(sizeof(struct ip_set
*) * ip_set_max
);
1489 printk(KERN_ERR
"Unable to create ip_set_list\n");
1492 memset(ip_set_list
, 0, sizeof(struct ip_set
*) * ip_set_max
);
1494 INIT_LIST_HEAD(&set_type_list
);
1496 res
= nf_register_sockopt(&so_set
);
1498 ip_set_printk("SO_SET registry failed: %d", res
);
1503 printk("ip_set version %u loaded\n", IP_SET_PROTOCOL_VERSION
);
1510 /* There can't be any existing set or binding */
1511 nf_unregister_sockopt(&so_set
);
1513 DP("these are the famous last words");
1516 EXPORT_SYMBOL(ip_set_register_set_type
);
1517 EXPORT_SYMBOL(ip_set_unregister_set_type
);
1519 EXPORT_SYMBOL(ip_set_get_byname
);
1520 EXPORT_SYMBOL(ip_set_get_byindex
);
1521 EXPORT_SYMBOL(ip_set_put_byindex
);
1522 EXPORT_SYMBOL(ip_set_id
);
1523 EXPORT_SYMBOL(__ip_set_get_byname
);
1524 EXPORT_SYMBOL(__ip_set_put_byindex
);
1526 EXPORT_SYMBOL(ip_set_addip_kernel
);
1527 EXPORT_SYMBOL(ip_set_delip_kernel
);
1528 EXPORT_SYMBOL(ip_set_testip_kernel
);
1530 module_init(ip_set_init
);
1531 module_exit(ip_set_fini
);