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.h83
1 files changed, 65 insertions, 18 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index ce078cda6b74..612069beda73 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -168,6 +168,12 @@ static inline void dst_use(struct dst_entry *dst, unsigned long time)
168 dst->lastuse = time; 168 dst->lastuse = time;
169} 169}
170 170
171static inline void dst_use_noref(struct dst_entry *dst, unsigned long time)
172{
173 dst->__use++;
174 dst->lastuse = time;
175}
176
171static inline 177static inline
172struct dst_entry * dst_clone(struct dst_entry * dst) 178struct dst_entry * dst_clone(struct dst_entry * dst)
173{ 179{
@@ -177,11 +183,67 @@ struct dst_entry * dst_clone(struct dst_entry * dst)
177} 183}
178 184
179extern 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 */
180static inline void skb_dst_drop(struct sk_buff *skb) 199static inline void skb_dst_drop(struct sk_buff *skb)
181{ 200{
182 if (skb->_skb_dst) 201 if (skb->_skb_refdst) {
183 dst_release(skb_dst(skb)); 202 refdst_drop(skb->_skb_refdst);
184 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_dst_drop(skb);
246 nf_reset(skb);
185} 247}
186 248
187/* Children define the path of the packet through the 249/* Children define the path of the packet through the
@@ -225,21 +287,6 @@ static inline void dst_confirm(struct dst_entry *dst)
225 neigh_confirm(dst->neighbour); 287 neigh_confirm(dst->neighbour);
226} 288}
227 289
228static inline void dst_negative_advice(struct dst_entry **dst_p,
229 struct sock *sk)
230{
231 struct dst_entry * dst = *dst_p;
232 if (dst && dst->ops->negative_advice) {
233 *dst_p = dst->ops->negative_advice(dst);
234
235 if (dst != *dst_p) {
236 extern void sk_reset_txq(struct sock *sk);
237
238 sk_reset_txq(sk);
239 }
240 }
241}
242
243static inline void dst_link_failure(struct sk_buff *skb) 290static inline void dst_link_failure(struct sk_buff *skb)
244{ 291{
245 struct dst_entry *dst = skb_dst(skb); 292 struct dst_entry *dst = skb_dst(skb);