144d362409d5469aed47d19e7908d19bd194493aThomas Graf/*
244d362409d5469aed47d19e7908d19bd194493aThomas Graf * netlink/list.h	Netlink List Utilities
344d362409d5469aed47d19e7908d19bd194493aThomas Graf *
444d362409d5469aed47d19e7908d19bd194493aThomas Graf *	This library is free software; you can redistribute it and/or
544d362409d5469aed47d19e7908d19bd194493aThomas Graf *	modify it under the terms of the GNU Lesser General Public
644d362409d5469aed47d19e7908d19bd194493aThomas Graf *	License as published by the Free Software Foundation version 2.1
744d362409d5469aed47d19e7908d19bd194493aThomas Graf *	of the License.
844d362409d5469aed47d19e7908d19bd194493aThomas Graf *
944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */
1144d362409d5469aed47d19e7908d19bd194493aThomas Graf
1244d362409d5469aed47d19e7908d19bd194493aThomas Graf#ifndef NETLINK_LIST_H_
1344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NETLINK_LIST_H_
1444d362409d5469aed47d19e7908d19bd194493aThomas Graf
1544d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_list_head
1644d362409d5469aed47d19e7908d19bd194493aThomas Graf{
1744d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_list_head *	next;
1844d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_list_head *	prev;
1944d362409d5469aed47d19e7908d19bd194493aThomas Graf};
2044d362409d5469aed47d19e7908d19bd194493aThomas Graf
21ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Grafstatic inline void NL_INIT_LIST_HEAD(struct nl_list_head *list)
22ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf{
23ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	list->next = list;
24ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf	list->prev = list;
25ef858fb492dfe98e3ae194264fbc73649cf8493aThomas Graf}
2644d362409d5469aed47d19e7908d19bd194493aThomas Graf
2744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __nl_list_add(struct nl_list_head *obj,
2844d362409d5469aed47d19e7908d19bd194493aThomas Graf				 struct nl_list_head *prev,
2944d362409d5469aed47d19e7908d19bd194493aThomas Graf				 struct nl_list_head *next)
3044d362409d5469aed47d19e7908d19bd194493aThomas Graf{
3144d362409d5469aed47d19e7908d19bd194493aThomas Graf	prev->next = obj;
3244d362409d5469aed47d19e7908d19bd194493aThomas Graf	obj->prev = prev;
3344d362409d5469aed47d19e7908d19bd194493aThomas Graf	next->prev = obj;
3444d362409d5469aed47d19e7908d19bd194493aThomas Graf	obj->next = next;
3544d362409d5469aed47d19e7908d19bd194493aThomas Graf}
3644d362409d5469aed47d19e7908d19bd194493aThomas Graf
3744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void nl_list_add_tail(struct nl_list_head *obj,
3844d362409d5469aed47d19e7908d19bd194493aThomas Graf				    struct nl_list_head *head)
3944d362409d5469aed47d19e7908d19bd194493aThomas Graf{
4044d362409d5469aed47d19e7908d19bd194493aThomas Graf	__nl_list_add(obj, head->prev, head);
4144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
4244d362409d5469aed47d19e7908d19bd194493aThomas Graf
4344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void nl_list_add_head(struct nl_list_head *obj,
4444d362409d5469aed47d19e7908d19bd194493aThomas Graf				    struct nl_list_head *head)
4544d362409d5469aed47d19e7908d19bd194493aThomas Graf{
4644d362409d5469aed47d19e7908d19bd194493aThomas Graf	__nl_list_add(obj, head, head->next);
4744d362409d5469aed47d19e7908d19bd194493aThomas Graf}
4844d362409d5469aed47d19e7908d19bd194493aThomas Graf
4944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void nl_list_del(struct nl_list_head *obj)
5044d362409d5469aed47d19e7908d19bd194493aThomas Graf{
5144d362409d5469aed47d19e7908d19bd194493aThomas Graf	obj->next->prev = obj->prev;
5244d362409d5469aed47d19e7908d19bd194493aThomas Graf	obj->prev->next = obj->next;
5344d362409d5469aed47d19e7908d19bd194493aThomas Graf}
5444d362409d5469aed47d19e7908d19bd194493aThomas Graf
5544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline int nl_list_empty(struct nl_list_head *head)
5644d362409d5469aed47d19e7908d19bd194493aThomas Graf{
5744d362409d5469aed47d19e7908d19bd194493aThomas Graf	return head->next == head;
5844d362409d5469aed47d19e7908d19bd194493aThomas Graf}
5944d362409d5469aed47d19e7908d19bd194493aThomas Graf
6044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_container_of(ptr, type, member) ({			\
6144d362409d5469aed47d19e7908d19bd194493aThomas Graf        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
6244d362409d5469aed47d19e7908d19bd194493aThomas Graf        (type *)( (char *)__mptr - ((size_t) &((type *)0)->member));})
6344d362409d5469aed47d19e7908d19bd194493aThomas Graf
6444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_list_entry(ptr, type, member) \
6544d362409d5469aed47d19e7908d19bd194493aThomas Graf	nl_container_of(ptr, type, member)
6644d362409d5469aed47d19e7908d19bd194493aThomas Graf
6744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_list_at_tail(pos, head, member) \
6844d362409d5469aed47d19e7908d19bd194493aThomas Graf	((pos)->member.next == (head))
6944d362409d5469aed47d19e7908d19bd194493aThomas Graf
7044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_list_at_head(pos, head, member) \
7144d362409d5469aed47d19e7908d19bd194493aThomas Graf	((pos)->member.prev == (head))
7244d362409d5469aed47d19e7908d19bd194493aThomas Graf
7344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define NL_LIST_HEAD(name) \
7444d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_list_head name = { &(name), &(name) }
7544d362409d5469aed47d19e7908d19bd194493aThomas Graf
76535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf#define nl_list_first_entry(head, type, member)			\
77535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	nl_list_entry((head)->next, type, member)
78535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
7944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_list_for_each_entry(pos, head, member)				\
8044d362409d5469aed47d19e7908d19bd194493aThomas Graf	for (pos = nl_list_entry((head)->next, typeof(*pos), member);	\
8144d362409d5469aed47d19e7908d19bd194493aThomas Graf	     &(pos)->member != (head); 	\
8244d362409d5469aed47d19e7908d19bd194493aThomas Graf	     (pos) = nl_list_entry((pos)->member.next, typeof(*(pos)), member))
8344d362409d5469aed47d19e7908d19bd194493aThomas Graf
8444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_list_for_each_entry_safe(pos, n, head, member)			\
8544d362409d5469aed47d19e7908d19bd194493aThomas Graf	for (pos = nl_list_entry((head)->next, typeof(*pos), member),	\
8644d362409d5469aed47d19e7908d19bd194493aThomas Graf		n = nl_list_entry(pos->member.next, typeof(*pos), member);	\
8744d362409d5469aed47d19e7908d19bd194493aThomas Graf	     &(pos)->member != (head); 					\
8844d362409d5469aed47d19e7908d19bd194493aThomas Graf	     pos = n, n = nl_list_entry(n->member.next, typeof(*n), member))
8944d362409d5469aed47d19e7908d19bd194493aThomas Graf
9044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define nl_init_list_head(head) \
9144d362409d5469aed47d19e7908d19bd194493aThomas Graf	do { (head)->next = (head); (head)->prev = (head); } while (0)
9244d362409d5469aed47d19e7908d19bd194493aThomas Graf
9344d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif
94