diff options
Diffstat (limited to 'include/net/dst.h')
-rw-r--r-- | include/net/dst.h | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index 5a900ddcf10..387cb3cfde7 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -36,8 +36,7 @@ struct sk_buff; -struct dst_entry -{ +struct dst_entry { struct rcu_head rcu_head; struct dst_entry *child; struct net_device *dev; @@ -111,6 +110,12 @@ dst_metric(const struct dst_entry *dst, int metric) return dst->metrics[metric-1]; } +static inline u32 +dst_feature(const struct dst_entry *dst, u32 feature) +{ + return (dst ? dst_metric(dst, RTAX_FEATURES) & feature : 0); +} + static inline u32 dst_mtu(const struct dst_entry *dst) { u32 mtu = dst_metric(dst, RTAX_MTU); @@ -136,7 +141,7 @@ static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric, static inline u32 dst_allfrag(const struct dst_entry *dst) { - int ret = dst_metric(dst, RTAX_FEATURES) & RTAX_FEATURE_ALLFRAG; + int ret = dst_feature(dst, RTAX_FEATURE_ALLFRAG); /* Yes, _exactly_. This is paranoia. */ barrier(); return ret; @@ -222,11 +227,19 @@ static inline void dst_confirm(struct dst_entry *dst) neigh_confirm(dst->neighbour); } -static inline void dst_negative_advice(struct dst_entry **dst_p) +static inline void dst_negative_advice(struct dst_entry **dst_p, + struct sock *sk) { struct dst_entry * dst = *dst_p; - if (dst && dst->ops->negative_advice) + if (dst && dst->ops->negative_advice) { *dst_p = dst->ops->negative_advice(dst); + + if (dst != *dst_p) { + extern void sk_reset_txq(struct sock *sk); + + sk_reset_txq(sk); + } + } } static inline void dst_link_failure(struct sk_buff *skb) |