Loading include/net/inetpeer.h +0 −4 Original line number Diff line number Diff line Loading @@ -36,10 +36,6 @@ struct inet_peer { u32 metrics[RTAX_MAX]; u32 rate_tokens; /* rate limiting for ICMP */ unsigned long rate_last; unsigned long pmtu_expires; u32 pmtu_orig; u32 pmtu_learned; struct inetpeer_addr_base redirect_learned; union { struct list_head gc_list; struct rcu_head gc_rcu; Loading include/net/route.h +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ struct rtable { __be32 rt_gateway; /* Miscellaneous cached information */ u32 rt_peer_genid; u32 rt_pmtu; unsigned long _peer; /* long-living peer info */ struct fib_info *fi; /* for client ref to shared metrics */ }; Loading net/ipv4/inetpeer.c +0 −3 Original line number Diff line number Diff line Loading @@ -511,9 +511,6 @@ relookup: p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; p->rate_tokens = 0; p->rate_last = 0; p->pmtu_expires = 0; p->pmtu_orig = 0; memset(&p->redirect_learned, 0, sizeof(p->redirect_learned)); INIT_LIST_HEAD(&p->gc_list); /* Link the node. */ Loading net/ipv4/route.c +39 −146 Original line number Diff line number Diff line Loading @@ -669,7 +669,7 @@ static inline int rt_fast_clean(struct rtable *rth) static inline int rt_valuable(struct rtable *rth) { return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) || (rt_has_peer(rth) && rt_peer_ptr(rth)->pmtu_expires); rth->dst.expires; } static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2) Loading Loading @@ -1242,13 +1242,6 @@ skip_hashing: return rt; } static atomic_t __rt_peer_genid = ATOMIC_INIT(0); static u32 rt_peer_genid(void) { return atomic_read(&__rt_peer_genid); } void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) { struct inet_peer_base *base; Loading @@ -1262,8 +1255,6 @@ void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) if (peer) { if (!rt_set_peer(rt, peer)) inet_putpeer(peer); else rt->rt_peer_genid = rt_peer_genid(); } } Loading Loading @@ -1323,30 +1314,6 @@ static void rt_del(unsigned int hash, struct rtable *rt) spin_unlock_bh(rt_hash_lock_addr(hash)); } static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) { struct rtable *rt = (struct rtable *) dst; __be32 orig_gw = rt->rt_gateway; struct neighbour *n; dst_confirm(&rt->dst); rt->rt_gateway = peer->redirect_learned.a4; n = ipv4_neigh_lookup(&rt->dst, NULL, &rt->rt_gateway); if (!n) { rt->rt_gateway = orig_gw; return; } if (!(n->nud_state & NUD_VALID)) { neigh_event_send(n, NULL); } else { rt->rt_flags |= RTCF_REDIRECTED; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } neigh_release(n); } /* called in rcu_read_lock() section */ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, __be32 saddr, struct net_device *dev) Loading @@ -1355,7 +1322,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, struct in_device *in_dev = __in_dev_get_rcu(dev); __be32 skeys[2] = { saddr, 0 }; int ikeys[2] = { dev->ifindex, 0 }; struct inet_peer *peer; struct net *net; if (!in_dev) Loading Loading @@ -1388,6 +1354,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rthp = &rt_hash_table[hash].chain; while ((rt = rcu_dereference(*rthp)) != NULL) { struct neighbour *n; rthp = &rt->dst.rt_next; if (rt->rt_key_dst != daddr || Loading @@ -1401,13 +1369,16 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rt->rt_gateway != old_gw) continue; peer = rt_get_peer_create(rt, rt->rt_dst); if (peer) { if (peer->redirect_learned.a4 != new_gw) { peer->redirect_learned.a4 = new_gw; atomic_inc(&__rt_peer_genid); n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); if (n) { if (!(n->nud_state & NUD_VALID)) { neigh_event_send(n, NULL); } else { rt->rt_gateway = new_gw; rt->rt_flags |= RTCF_REDIRECTED; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } check_peer_redir(&rt->dst, peer); neigh_release(n); } } } Loading @@ -1425,23 +1396,6 @@ reject_redirect: ; } static bool peer_pmtu_expired(struct inet_peer *peer) { unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); return orig && time_after_eq(jiffies, orig) && cmpxchg(&peer->pmtu_expires, orig, 0) == orig; } static bool peer_pmtu_cleaned(struct inet_peer *peer) { unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); return orig && cmpxchg(&peer->pmtu_expires, orig, 0) == orig; } static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) { struct rtable *rt = (struct rtable *)dst; Loading @@ -1451,16 +1405,13 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) if (dst->obsolete > 0) { ip_rt_put(rt); ret = NULL; } else if (rt->rt_flags & RTCF_REDIRECTED) { } else if ((rt->rt_flags & RTCF_REDIRECTED) || rt->dst.expires) { unsigned int hash = rt_hash(rt->rt_key_dst, rt->rt_key_src, rt->rt_oif, rt_genid(dev_net(dst->dev))); rt_del(hash, rt); ret = NULL; } else if (rt_has_peer(rt)) { struct inet_peer *peer = rt_peer_ptr(rt); if (peer_pmtu_expired(peer)) dst_metric_set(dst, RTAX_MTU, peer->pmtu_orig); } } return ret; Loading Loading @@ -1604,50 +1555,17 @@ out: kfree_skb(skb); return 0; } static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer) { unsigned long expires = ACCESS_ONCE(peer->pmtu_expires); if (!expires) return; if (time_before(jiffies, expires)) { u32 orig_dst_mtu = dst_mtu(dst); if (peer->pmtu_learned < orig_dst_mtu) { if (!peer->pmtu_orig) peer->pmtu_orig = dst_metric_raw(dst, RTAX_MTU); dst_metric_set(dst, RTAX_MTU, peer->pmtu_learned); } } else if (cmpxchg(&peer->pmtu_expires, expires, 0) == expires) dst_metric_set(dst, RTAX_MTU, peer->pmtu_orig); } static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) { struct rtable *rt = (struct rtable *) dst; struct inet_peer *peer; dst_confirm(dst); peer = rt_get_peer_create(rt, rt->rt_dst); if (peer) { unsigned long pmtu_expires = ACCESS_ONCE(peer->pmtu_expires); if (mtu < ip_rt_min_pmtu) mtu = ip_rt_min_pmtu; if (!pmtu_expires || mtu < peer->pmtu_learned) { pmtu_expires = jiffies + ip_rt_mtu_expires; if (!pmtu_expires) pmtu_expires = 1UL; peer->pmtu_learned = mtu; peer->pmtu_expires = pmtu_expires; atomic_inc(&__rt_peer_genid); rt->rt_peer_genid = rt_peer_genid(); } check_peer_pmtu(dst, peer); } rt->rt_pmtu = mtu; dst_set_expires(&rt->dst, ip_rt_mtu_expires); } void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, Loading Loading @@ -1679,30 +1597,12 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) } EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); static void ipv4_validate_peer(struct rtable *rt) { if (rt->rt_peer_genid != rt_peer_genid()) { struct inet_peer *peer = rt_get_peer(rt, rt->rt_dst); if (peer) { check_peer_pmtu(&rt->dst, peer); if (peer->redirect_learned.a4 && peer->redirect_learned.a4 != rt->rt_gateway) check_peer_redir(&rt->dst, peer); } rt->rt_peer_genid = rt_peer_genid(); } } static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) { struct rtable *rt = (struct rtable *) dst; if (rt_is_expired(rt)) return NULL; ipv4_validate_peer(rt); return dst; } Loading @@ -1728,11 +1628,8 @@ static void ipv4_link_failure(struct sk_buff *skb) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); rt = skb_rtable(skb); if (rt && rt_has_peer(rt)) { struct inet_peer *peer = rt_peer_ptr(rt); if (peer_pmtu_cleaned(peer)) dst_metric_set(&rt->dst, RTAX_MTU, peer->pmtu_orig); } if (rt) dst_set_expires(&rt->dst, 0); } static int ip_rt_bug(struct sk_buff *skb) Loading Loading @@ -1812,7 +1709,13 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst) static unsigned int ipv4_mtu(const struct dst_entry *dst) { const struct rtable *rt = (const struct rtable *) dst; unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); unsigned int mtu = rt->rt_pmtu; if (mtu && time_after_eq(jiffies, rt->dst.expires)) mtu = 0; if (!mtu) mtu = dst_metric_raw(dst, RTAX_MTU); if (mtu && rt_is_output_route(rt)) return mtu; Loading Loading @@ -1843,19 +1746,10 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, peer = inet_getpeer_v4(base, rt->rt_dst, 0); if (peer) { __rt_set_peer(rt, peer); rt->rt_peer_genid = rt_peer_genid(); if (inet_metrics_new(peer)) memcpy(peer->metrics, fi->fib_metrics, sizeof(u32) * RTAX_MAX); dst_init_metrics(&rt->dst, peer->metrics, false); check_peer_pmtu(&rt->dst, peer); if (peer->redirect_learned.a4 && peer->redirect_learned.a4 != rt->rt_gateway) { rt->rt_gateway = peer->redirect_learned.a4; rt->rt_flags |= RTCF_REDIRECTED; } } else { if (fi->fib_metrics != (u32 *) dst_default_metrics) { rt->fi = fi; Loading Loading @@ -1955,8 +1849,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_iif = dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_pmtu = 0; rth->rt_gateway = daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, dev_net(dev)->ipv4.peers); rth->fi = NULL; if (our) { Loading Loading @@ -2081,8 +1975,8 @@ static int __mkroute_input(struct sk_buff *skb, rth->rt_iif = in_dev->dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_pmtu = 0; rth->rt_gateway = daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, &res->table->tb_peers); rth->fi = NULL; Loading Loading @@ -2260,8 +2154,8 @@ local_input: rth->rt_iif = dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_pmtu = 0; rth->rt_gateway = daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, net->ipv4.peers); rth->fi = NULL; if (res.type == RTN_UNREACHABLE) { Loading Loading @@ -2337,7 +2231,6 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_mark == skb->mark && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { ipv4_validate_peer(rth); if (noref) { dst_use_noref(&rth->dst, jiffies); skb_dst_set_noref(skb, &rth->dst); Loading Loading @@ -2459,8 +2352,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_iif = orig_oif ? : dev_out->ifindex; rth->rt_oif = orig_oif; rth->rt_mark = fl4->flowi4_mark; rth->rt_pmtu = 0; rth->rt_gateway = fl4->daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, (res->table ? &res->table->tb_peers : dev_net(dev_out)->ipv4.peers)); Loading Loading @@ -2717,7 +2610,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) (IPTOS_RT_MASK | RTO_ONLINK)) && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { ipv4_validate_peer(rth); dst_use(&rth->dst, jiffies); RT_CACHE_STAT_INC(out_hit); rcu_read_unlock_bh(); Loading Loading @@ -2794,6 +2686,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or rt->rt_iif = ort->rt_iif; rt->rt_oif = ort->rt_oif; rt->rt_mark = ort->rt_mark; rt->rt_pmtu = ort->rt_pmtu; rt->rt_genid = rt_genid(net); rt->rt_flags = ort->rt_flags; Loading Loading @@ -2896,14 +2789,14 @@ static int rt_fill_info(struct net *net, const struct inet_peer *peer = rt_peer_ptr(rt); inet_peer_refcheck(peer); id = atomic_read(&peer->ip_id_count) & 0xffff; expires = ACCESS_ONCE(peer->pmtu_expires); } expires = rt->dst.expires; if (expires) { if (time_before(jiffies, expires)) expires -= jiffies; else expires = 0; } } if (rt_is_input_route(rt)) { #ifdef CONFIG_IP_MROUTE Loading net/ipv4/xfrm4_policy.c +1 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.rt.rt_src = rt->rt_src; xdst->u.rt.rt_dst = rt->rt_dst; xdst->u.rt.rt_gateway = rt->rt_gateway; xdst->u.rt.rt_pmtu = rt->rt_pmtu; return 0; } Loading Loading
include/net/inetpeer.h +0 −4 Original line number Diff line number Diff line Loading @@ -36,10 +36,6 @@ struct inet_peer { u32 metrics[RTAX_MAX]; u32 rate_tokens; /* rate limiting for ICMP */ unsigned long rate_last; unsigned long pmtu_expires; u32 pmtu_orig; u32 pmtu_learned; struct inetpeer_addr_base redirect_learned; union { struct list_head gc_list; struct rcu_head gc_rcu; Loading
include/net/route.h +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ struct rtable { __be32 rt_gateway; /* Miscellaneous cached information */ u32 rt_peer_genid; u32 rt_pmtu; unsigned long _peer; /* long-living peer info */ struct fib_info *fi; /* for client ref to shared metrics */ }; Loading
net/ipv4/inetpeer.c +0 −3 Original line number Diff line number Diff line Loading @@ -511,9 +511,6 @@ relookup: p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; p->rate_tokens = 0; p->rate_last = 0; p->pmtu_expires = 0; p->pmtu_orig = 0; memset(&p->redirect_learned, 0, sizeof(p->redirect_learned)); INIT_LIST_HEAD(&p->gc_list); /* Link the node. */ Loading
net/ipv4/route.c +39 −146 Original line number Diff line number Diff line Loading @@ -669,7 +669,7 @@ static inline int rt_fast_clean(struct rtable *rth) static inline int rt_valuable(struct rtable *rth) { return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) || (rt_has_peer(rth) && rt_peer_ptr(rth)->pmtu_expires); rth->dst.expires; } static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2) Loading Loading @@ -1242,13 +1242,6 @@ skip_hashing: return rt; } static atomic_t __rt_peer_genid = ATOMIC_INIT(0); static u32 rt_peer_genid(void) { return atomic_read(&__rt_peer_genid); } void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) { struct inet_peer_base *base; Loading @@ -1262,8 +1255,6 @@ void rt_bind_peer(struct rtable *rt, __be32 daddr, int create) if (peer) { if (!rt_set_peer(rt, peer)) inet_putpeer(peer); else rt->rt_peer_genid = rt_peer_genid(); } } Loading Loading @@ -1323,30 +1314,6 @@ static void rt_del(unsigned int hash, struct rtable *rt) spin_unlock_bh(rt_hash_lock_addr(hash)); } static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) { struct rtable *rt = (struct rtable *) dst; __be32 orig_gw = rt->rt_gateway; struct neighbour *n; dst_confirm(&rt->dst); rt->rt_gateway = peer->redirect_learned.a4; n = ipv4_neigh_lookup(&rt->dst, NULL, &rt->rt_gateway); if (!n) { rt->rt_gateway = orig_gw; return; } if (!(n->nud_state & NUD_VALID)) { neigh_event_send(n, NULL); } else { rt->rt_flags |= RTCF_REDIRECTED; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } neigh_release(n); } /* called in rcu_read_lock() section */ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, __be32 saddr, struct net_device *dev) Loading @@ -1355,7 +1322,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, struct in_device *in_dev = __in_dev_get_rcu(dev); __be32 skeys[2] = { saddr, 0 }; int ikeys[2] = { dev->ifindex, 0 }; struct inet_peer *peer; struct net *net; if (!in_dev) Loading Loading @@ -1388,6 +1354,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rthp = &rt_hash_table[hash].chain; while ((rt = rcu_dereference(*rthp)) != NULL) { struct neighbour *n; rthp = &rt->dst.rt_next; if (rt->rt_key_dst != daddr || Loading @@ -1401,13 +1369,16 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rt->rt_gateway != old_gw) continue; peer = rt_get_peer_create(rt, rt->rt_dst); if (peer) { if (peer->redirect_learned.a4 != new_gw) { peer->redirect_learned.a4 = new_gw; atomic_inc(&__rt_peer_genid); n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); if (n) { if (!(n->nud_state & NUD_VALID)) { neigh_event_send(n, NULL); } else { rt->rt_gateway = new_gw; rt->rt_flags |= RTCF_REDIRECTED; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } check_peer_redir(&rt->dst, peer); neigh_release(n); } } } Loading @@ -1425,23 +1396,6 @@ reject_redirect: ; } static bool peer_pmtu_expired(struct inet_peer *peer) { unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); return orig && time_after_eq(jiffies, orig) && cmpxchg(&peer->pmtu_expires, orig, 0) == orig; } static bool peer_pmtu_cleaned(struct inet_peer *peer) { unsigned long orig = ACCESS_ONCE(peer->pmtu_expires); return orig && cmpxchg(&peer->pmtu_expires, orig, 0) == orig; } static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) { struct rtable *rt = (struct rtable *)dst; Loading @@ -1451,16 +1405,13 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) if (dst->obsolete > 0) { ip_rt_put(rt); ret = NULL; } else if (rt->rt_flags & RTCF_REDIRECTED) { } else if ((rt->rt_flags & RTCF_REDIRECTED) || rt->dst.expires) { unsigned int hash = rt_hash(rt->rt_key_dst, rt->rt_key_src, rt->rt_oif, rt_genid(dev_net(dst->dev))); rt_del(hash, rt); ret = NULL; } else if (rt_has_peer(rt)) { struct inet_peer *peer = rt_peer_ptr(rt); if (peer_pmtu_expired(peer)) dst_metric_set(dst, RTAX_MTU, peer->pmtu_orig); } } return ret; Loading Loading @@ -1604,50 +1555,17 @@ out: kfree_skb(skb); return 0; } static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer) { unsigned long expires = ACCESS_ONCE(peer->pmtu_expires); if (!expires) return; if (time_before(jiffies, expires)) { u32 orig_dst_mtu = dst_mtu(dst); if (peer->pmtu_learned < orig_dst_mtu) { if (!peer->pmtu_orig) peer->pmtu_orig = dst_metric_raw(dst, RTAX_MTU); dst_metric_set(dst, RTAX_MTU, peer->pmtu_learned); } } else if (cmpxchg(&peer->pmtu_expires, expires, 0) == expires) dst_metric_set(dst, RTAX_MTU, peer->pmtu_orig); } static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) { struct rtable *rt = (struct rtable *) dst; struct inet_peer *peer; dst_confirm(dst); peer = rt_get_peer_create(rt, rt->rt_dst); if (peer) { unsigned long pmtu_expires = ACCESS_ONCE(peer->pmtu_expires); if (mtu < ip_rt_min_pmtu) mtu = ip_rt_min_pmtu; if (!pmtu_expires || mtu < peer->pmtu_learned) { pmtu_expires = jiffies + ip_rt_mtu_expires; if (!pmtu_expires) pmtu_expires = 1UL; peer->pmtu_learned = mtu; peer->pmtu_expires = pmtu_expires; atomic_inc(&__rt_peer_genid); rt->rt_peer_genid = rt_peer_genid(); } check_peer_pmtu(dst, peer); } rt->rt_pmtu = mtu; dst_set_expires(&rt->dst, ip_rt_mtu_expires); } void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, Loading Loading @@ -1679,30 +1597,12 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) } EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); static void ipv4_validate_peer(struct rtable *rt) { if (rt->rt_peer_genid != rt_peer_genid()) { struct inet_peer *peer = rt_get_peer(rt, rt->rt_dst); if (peer) { check_peer_pmtu(&rt->dst, peer); if (peer->redirect_learned.a4 && peer->redirect_learned.a4 != rt->rt_gateway) check_peer_redir(&rt->dst, peer); } rt->rt_peer_genid = rt_peer_genid(); } } static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) { struct rtable *rt = (struct rtable *) dst; if (rt_is_expired(rt)) return NULL; ipv4_validate_peer(rt); return dst; } Loading @@ -1728,11 +1628,8 @@ static void ipv4_link_failure(struct sk_buff *skb) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); rt = skb_rtable(skb); if (rt && rt_has_peer(rt)) { struct inet_peer *peer = rt_peer_ptr(rt); if (peer_pmtu_cleaned(peer)) dst_metric_set(&rt->dst, RTAX_MTU, peer->pmtu_orig); } if (rt) dst_set_expires(&rt->dst, 0); } static int ip_rt_bug(struct sk_buff *skb) Loading Loading @@ -1812,7 +1709,13 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst) static unsigned int ipv4_mtu(const struct dst_entry *dst) { const struct rtable *rt = (const struct rtable *) dst; unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); unsigned int mtu = rt->rt_pmtu; if (mtu && time_after_eq(jiffies, rt->dst.expires)) mtu = 0; if (!mtu) mtu = dst_metric_raw(dst, RTAX_MTU); if (mtu && rt_is_output_route(rt)) return mtu; Loading Loading @@ -1843,19 +1746,10 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4, peer = inet_getpeer_v4(base, rt->rt_dst, 0); if (peer) { __rt_set_peer(rt, peer); rt->rt_peer_genid = rt_peer_genid(); if (inet_metrics_new(peer)) memcpy(peer->metrics, fi->fib_metrics, sizeof(u32) * RTAX_MAX); dst_init_metrics(&rt->dst, peer->metrics, false); check_peer_pmtu(&rt->dst, peer); if (peer->redirect_learned.a4 && peer->redirect_learned.a4 != rt->rt_gateway) { rt->rt_gateway = peer->redirect_learned.a4; rt->rt_flags |= RTCF_REDIRECTED; } } else { if (fi->fib_metrics != (u32 *) dst_default_metrics) { rt->fi = fi; Loading Loading @@ -1955,8 +1849,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_iif = dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_pmtu = 0; rth->rt_gateway = daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, dev_net(dev)->ipv4.peers); rth->fi = NULL; if (our) { Loading Loading @@ -2081,8 +1975,8 @@ static int __mkroute_input(struct sk_buff *skb, rth->rt_iif = in_dev->dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_pmtu = 0; rth->rt_gateway = daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, &res->table->tb_peers); rth->fi = NULL; Loading Loading @@ -2260,8 +2154,8 @@ local_input: rth->rt_iif = dev->ifindex; rth->rt_oif = 0; rth->rt_mark = skb->mark; rth->rt_pmtu = 0; rth->rt_gateway = daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, net->ipv4.peers); rth->fi = NULL; if (res.type == RTN_UNREACHABLE) { Loading Loading @@ -2337,7 +2231,6 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->rt_mark == skb->mark && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { ipv4_validate_peer(rth); if (noref) { dst_use_noref(&rth->dst, jiffies); skb_dst_set_noref(skb, &rth->dst); Loading Loading @@ -2459,8 +2352,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_iif = orig_oif ? : dev_out->ifindex; rth->rt_oif = orig_oif; rth->rt_mark = fl4->flowi4_mark; rth->rt_pmtu = 0; rth->rt_gateway = fl4->daddr; rth->rt_peer_genid = 0; rt_init_peer(rth, (res->table ? &res->table->tb_peers : dev_net(dev_out)->ipv4.peers)); Loading Loading @@ -2717,7 +2610,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) (IPTOS_RT_MASK | RTO_ONLINK)) && net_eq(dev_net(rth->dst.dev), net) && !rt_is_expired(rth)) { ipv4_validate_peer(rth); dst_use(&rth->dst, jiffies); RT_CACHE_STAT_INC(out_hit); rcu_read_unlock_bh(); Loading Loading @@ -2794,6 +2686,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or rt->rt_iif = ort->rt_iif; rt->rt_oif = ort->rt_oif; rt->rt_mark = ort->rt_mark; rt->rt_pmtu = ort->rt_pmtu; rt->rt_genid = rt_genid(net); rt->rt_flags = ort->rt_flags; Loading Loading @@ -2896,14 +2789,14 @@ static int rt_fill_info(struct net *net, const struct inet_peer *peer = rt_peer_ptr(rt); inet_peer_refcheck(peer); id = atomic_read(&peer->ip_id_count) & 0xffff; expires = ACCESS_ONCE(peer->pmtu_expires); } expires = rt->dst.expires; if (expires) { if (time_before(jiffies, expires)) expires -= jiffies; else expires = 0; } } if (rt_is_input_route(rt)) { #ifdef CONFIG_IP_MROUTE Loading
net/ipv4/xfrm4_policy.c +1 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.rt.rt_src = rt->rt_src; xdst->u.rt.rt_dst = rt->rt_dst; xdst->u.rt.rt_gateway = rt->rt_gateway; xdst->u.rt.rt_pmtu = rt->rt_pmtu; return 0; } Loading