aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/inetpeer.h
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-10 01:36:36 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-11 05:08:47 -0400
commit97bab73f987e2781129cd6f4b6379bf44d808cc6 (patch)
tree40b10c4c021c8b5524c19f79fcfe4b0799b59952 /include/net/inetpeer.h
parentc0efc887dcadbdbfe171f028acfab9c7c00e9dde (diff)
inet: Hide route peer accesses behind helpers.
We encode the pointer(s) into an unsigned long with one state bit. The state bit is used so we can store the inetpeer tree root to use when resolving the peer later. Later the peer roots will be per-FIB table, and this change works to facilitate that. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/inetpeer.h')
-rw-r--r--include/net/inetpeer.h54
1 files changed, 54 insertions, 0 deletions
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index b84b32fd5df1..d432489e7109 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -71,6 +71,60 @@ struct inet_peer_base {
71 int total; 71 int total;
72}; 72};
73 73
74#define INETPEER_BASE_BIT 0x1UL
75
76static inline struct inet_peer *inetpeer_ptr(unsigned long val)
77{
78 BUG_ON(val & INETPEER_BASE_BIT);
79 return (struct inet_peer *) val;
80}
81
82static inline struct inet_peer_base *inetpeer_base_ptr(unsigned long val)
83{
84 if (!(val & INETPEER_BASE_BIT))
85 return NULL;
86 val &= ~INETPEER_BASE_BIT;
87 return (struct inet_peer_base *) val;
88}
89
90static inline bool inetpeer_ptr_is_peer(unsigned long val)
91{
92 return !(val & INETPEER_BASE_BIT);
93}
94
95static inline void __inetpeer_ptr_set_peer(unsigned long *val, struct inet_peer *peer)
96{
97 /* This implicitly clears INETPEER_BASE_BIT */
98 *val = (unsigned long) peer;
99}
100
101static inline bool inetpeer_ptr_set_peer(unsigned long *ptr, struct inet_peer *peer)
102{
103 unsigned long val = (unsigned long) peer;
104 unsigned long orig = *ptr;
105
106 if (!(orig & INETPEER_BASE_BIT) || !val ||
107 cmpxchg(ptr, orig, val) != orig)
108 return false;
109 return true;
110}
111
112static inline void inetpeer_init_ptr(unsigned long *ptr, struct inet_peer_base *base)
113{
114 *ptr = (unsigned long) base | INETPEER_BASE_BIT;
115}
116
117static inline void inetpeer_transfer_peer(unsigned long *to, unsigned long *from)
118{
119 unsigned long val = *from;
120
121 *to = val;
122 if (inetpeer_ptr_is_peer(val)) {
123 struct inet_peer *peer = inetpeer_ptr(val);
124 atomic_inc(&peer->refcnt);
125 }
126}
127
74extern void inet_peer_base_init(struct inet_peer_base *); 128extern void inet_peer_base_init(struct inet_peer_base *);
75 129
76void inet_initpeers(void) __init; 130void inet_initpeers(void) __init;