aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/dst.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/dst.h')
-rw-r--r--include/net/dst.h92
1 files changed, 69 insertions, 23 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index 39c4a5963e12..02386505033d 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -83,8 +83,6 @@ struct dst_entry {
83 * (L1_CACHE_SIZE would be too much) 83 * (L1_CACHE_SIZE would be too much)
84 */ 84 */
85#ifdef CONFIG_64BIT 85#ifdef CONFIG_64BIT
86 long __pad_to_align_refcnt[2];
87#else
88 long __pad_to_align_refcnt[1]; 86 long __pad_to_align_refcnt[1];
89#endif 87#endif
90 /* 88 /*
@@ -170,6 +168,12 @@ static inline void dst_use(struct dst_entry *dst, unsigned long time)
170 dst->lastuse = time; 168 dst->lastuse = time;
171} 169}
172 170
171static inline void dst_use_noref(struct dst_entry *dst, unsigned long time)
172{
173 dst->__use++;
174 dst->lastuse = time;
175}
176
173static inline 177static inline
174struct dst_entry * dst_clone(struct dst_entry * dst) 178struct dst_entry * dst_clone(struct dst_entry * dst)
175{ 179{
@@ -179,22 +183,79 @@ struct dst_entry * dst_clone(struct dst_entry * dst)
179} 183}
180 184
181extern void dst_release(struct dst_entry *dst); 185extern void dst_release(struct dst_entry *dst);
186
187static inline void refdst_drop(unsigned long refdst)
188{
189 if (!(refdst & SKB_DST_NOREF))
190 dst_release((struct dst_entry *)(refdst & SKB_DST_PTRMASK));
191}
192
193/**
194 * skb_dst_drop - drops skb dst
195 * @skb: buffer
196 *
197 * Drops dst reference count if a reference was taken.
198 */
182static inline void skb_dst_drop(struct sk_buff *skb) 199static inline void skb_dst_drop(struct sk_buff *skb)
183{ 200{
184 if (skb->_skb_dst) 201 if (skb->_skb_refdst) {
185 dst_release(skb_dst(skb)); 202 refdst_drop(skb->_skb_refdst);
186 skb->_skb_dst = 0UL; 203 skb->_skb_refdst = 0UL;
204 }
205}
206
207static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb)
208{
209 nskb->_skb_refdst = oskb->_skb_refdst;
210 if (!(nskb->_skb_refdst & SKB_DST_NOREF))
211 dst_clone(skb_dst(nskb));
212}
213
214/**
215 * skb_dst_force - makes sure skb dst is refcounted
216 * @skb: buffer
217 *
218 * If dst is not yet refcounted, let's do it
219 */
220static inline void skb_dst_force(struct sk_buff *skb)
221{
222 if (skb_dst_is_noref(skb)) {
223 WARN_ON(!rcu_read_lock_held());
224 skb->_skb_refdst &= ~SKB_DST_NOREF;
225 dst_clone(skb_dst(skb));
226 }
227}
228
229
230/**
231 * skb_tunnel_rx - prepare skb for rx reinsert
232 * @skb: buffer
233 * @dev: tunnel device
234 *
235 * After decapsulation, packet is going to re-enter (netif_rx()) our stack,
236 * so make some cleanups, and perform accounting.
237 */
238static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
239{
240 skb->dev = dev;
241 /* TODO : stats should be SMP safe */
242 dev->stats.rx_packets++;
243 dev->stats.rx_bytes += skb->len;
244 skb->rxhash = 0;
245 skb_set_queue_mapping(skb, 0);
246 skb_dst_drop(skb);
247 nf_reset(skb);
187} 248}
188 249
189/* Children define the path of the packet through the 250/* Children define the path of the packet through the
190 * Linux networking. Thus, destinations are stackable. 251 * Linux networking. Thus, destinations are stackable.
191 */ 252 */
192 253
193static inline struct dst_entry *dst_pop(struct dst_entry *dst) 254static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
194{ 255{
195 struct dst_entry *child = dst_clone(dst->child); 256 struct dst_entry *child = skb_dst(skb)->child;
196 257
197 dst_release(dst); 258 skb_dst_drop(skb);
198 return child; 259 return child;
199} 260}
200 261
@@ -227,21 +288,6 @@ static inline void dst_confirm(struct dst_entry *dst)
227 neigh_confirm(dst->neighbour); 288 neigh_confirm(dst->neighbour);
228} 289}
229 290
230static inline void dst_negative_advice(struct dst_entry **dst_p,
231 struct sock *sk)
232{
233 struct dst_entry * dst = *dst_p;
234 if (dst && dst->ops->negative_advice) {
235 *dst_p = dst->ops->negative_advice(dst);
236
237 if (dst != *dst_p) {
238 extern void sk_reset_txq(struct sock *sk);
239
240 sk_reset_txq(sk);
241 }
242 }
243}
244
245static inline void dst_link_failure(struct sk_buff *skb) 291static inline void dst_link_failure(struct sk_buff *skb)
246{ 292{
247 struct dst_entry *dst = skb_dst(skb); 293 struct dst_entry *dst = skb_dst(skb);