diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2018-11-26 10:54:36 +0100 |
---|---|---|
committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2018-11-26 10:54:36 +0100 |
commit | 3713072d3bcb5dc1cfbb7c5fa3e24b8a73fd4104 (patch) | |
tree | 0d43a750fb5ebc63aefc1d7ba6af327c58062ef6 /include/libipset | |
parent | a680d3fdbb637fae53c60e4a30f028bd5ed1fe4b (diff) |
Implement sorting for hash types in the ipset tool
Support listing/saving with sorted entries for the hash types.
(bitmap and list types are automatically sorted.)
Diffstat (limited to 'include/libipset')
-rw-r--r-- | include/libipset/list_sort.h | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/include/libipset/list_sort.h b/include/libipset/list_sort.h new file mode 100644 index 0000000..70b1fca --- /dev/null +++ b/include/libipset/list_sort.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_LIST_SORT_H +#define _LINUX_LIST_SORT_H + +/* List manipulations from include/linux/list.h */ +struct list_head { + struct list_head *next, *prev; +}; + +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +#define container_of(ptr, type, member) ({ \ + typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + // entry->next = (void *) 0; + // entry->prev = (void *) 0; +} + +static inline void __list_splice(const struct list_head *list, + struct list_head *prev, + struct list_head *next) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +static inline void list_splice(const struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head, head->next); +} + +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +#ifndef unlikely +#define unlikely(x) (!!(x) == 0) +#endif + +extern void +list_sort(void *priv, struct list_head *head, + int (*cmp)(void *priv, struct list_head *a, + struct list_head *b)); +#endif |