aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
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
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')
-rw-r--r--include/net/inetpeer.h54
-rw-r--r--include/net/ip6_fib.h32
-rw-r--r--include/net/ip6_route.h6
-rw-r--r--include/net/route.h42
4 files changed, 126 insertions, 8 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;
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 0ae759a6c76e..3ac5f155c690 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -107,7 +107,7 @@ struct rt6_info {
107 u32 rt6i_peer_genid; 107 u32 rt6i_peer_genid;
108 108
109 struct inet6_dev *rt6i_idev; 109 struct inet6_dev *rt6i_idev;
110 struct inet_peer *rt6i_peer; 110 unsigned long _rt6i_peer;
111 111
112#ifdef CONFIG_XFRM 112#ifdef CONFIG_XFRM
113 u32 rt6i_flow_cache_genid; 113 u32 rt6i_flow_cache_genid;
@@ -118,6 +118,36 @@ struct rt6_info {
118 u8 rt6i_protocol; 118 u8 rt6i_protocol;
119}; 119};
120 120
121static inline struct inet_peer *rt6_peer_ptr(struct rt6_info *rt)
122{
123 return inetpeer_ptr(rt->_rt6i_peer);
124}
125
126static inline bool rt6_has_peer(struct rt6_info *rt)
127{
128 return inetpeer_ptr_is_peer(rt->_rt6i_peer);
129}
130
131static inline void __rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
132{
133 __inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
134}
135
136static inline bool rt6_set_peer(struct rt6_info *rt, struct inet_peer *peer)
137{
138 return inetpeer_ptr_set_peer(&rt->_rt6i_peer, peer);
139}
140
141static inline void rt6_init_peer(struct rt6_info *rt, struct inet_peer_base *base)
142{
143 inetpeer_init_ptr(&rt->_rt6i_peer, base);
144}
145
146static inline void rt6_transfer_peer(struct rt6_info *rt, struct rt6_info *ort)
147{
148 inetpeer_transfer_peer(&rt->_rt6i_peer, &ort->_rt6i_peer);
149}
150
121static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) 151static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
122{ 152{
123 return ((struct rt6_info *)dst)->rt6i_idev; 153 return ((struct rt6_info *)dst)->rt6i_idev;
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 73d750288121..f88a85cf31c3 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -57,11 +57,11 @@ extern void rt6_bind_peer(struct rt6_info *rt, int create);
57 57
58static inline struct inet_peer *__rt6_get_peer(struct rt6_info *rt, int create) 58static inline struct inet_peer *__rt6_get_peer(struct rt6_info *rt, int create)
59{ 59{
60 if (rt->rt6i_peer) 60 if (rt6_has_peer(rt))
61 return rt->rt6i_peer; 61 return rt6_peer_ptr(rt);
62 62
63 rt6_bind_peer(rt, create); 63 rt6_bind_peer(rt, create);
64 return rt->rt6i_peer; 64 return rt6_peer_ptr(rt);
65} 65}
66 66
67static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt) 67static inline struct inet_peer *rt6_get_peer(struct rt6_info *rt)
diff --git a/include/net/route.h b/include/net/route.h
index 433fc6c1d404..6340c37677fc 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -67,10 +67,44 @@ struct rtable {
67 /* Miscellaneous cached information */ 67 /* Miscellaneous cached information */
68 __be32 rt_spec_dst; /* RFC1122 specific destination */ 68 __be32 rt_spec_dst; /* RFC1122 specific destination */
69 u32 rt_peer_genid; 69 u32 rt_peer_genid;
70 struct inet_peer *peer; /* long-living peer info */ 70 unsigned long _peer; /* long-living peer info */
71 struct fib_info *fi; /* for client ref to shared metrics */ 71 struct fib_info *fi; /* for client ref to shared metrics */
72}; 72};
73 73
74static inline struct inet_peer *rt_peer_ptr(struct rtable *rt)
75{
76 return inetpeer_ptr(rt->_peer);
77}
78
79static inline bool rt_has_peer(struct rtable *rt)
80{
81 return inetpeer_ptr_is_peer(rt->_peer);
82}
83
84static inline void __rt_set_peer(struct rtable *rt, struct inet_peer *peer)
85{
86 __inetpeer_ptr_set_peer(&rt->_peer, peer);
87}
88
89static inline bool rt_set_peer(struct rtable *rt, struct inet_peer *peer)
90{
91 return inetpeer_ptr_set_peer(&rt->_peer, peer);
92}
93
94static inline void rt_init_peer(struct rtable *rt, struct inet_peer_base *base)
95{
96 inetpeer_init_ptr(&rt->_peer, base);
97}
98
99static inline void rt_transfer_peer(struct rtable *rt, struct rtable *ort)
100{
101 rt->_peer = ort->_peer;
102 if (rt_has_peer(ort)) {
103 struct inet_peer *peer = rt_peer_ptr(ort);
104 atomic_inc(&peer->refcnt);
105 }
106}
107
74static inline bool rt_is_input_route(const struct rtable *rt) 108static inline bool rt_is_input_route(const struct rtable *rt)
75{ 109{
76 return rt->rt_route_iif != 0; 110 return rt->rt_route_iif != 0;
@@ -298,11 +332,11 @@ extern void rt_bind_peer(struct rtable *rt, __be32 daddr, int create);
298 332
299static inline struct inet_peer *__rt_get_peer(struct rtable *rt, __be32 daddr, int create) 333static inline struct inet_peer *__rt_get_peer(struct rtable *rt, __be32 daddr, int create)
300{ 334{
301 if (rt->peer) 335 if (rt_has_peer(rt))
302 return rt->peer; 336 return rt_peer_ptr(rt);
303 337
304 rt_bind_peer(rt, daddr, create); 338 rt_bind_peer(rt, daddr, create);
305 return rt->peer; 339 return rt_peer_ptr(rt);
306} 340}
307 341
308static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) 342static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr)