]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/ipv4/route.c
ipv4: Kill ip_rt_frag_needed().
[mirror_ubuntu-bionic-kernel.git] / net / ipv4 / route.c
index 4cd35c3904d4a3b06368b398072a33dc5692d04a..4f5834c4a667fbfebe428363dc0a71e904dbc3d8 100644 (file)
@@ -677,7 +677,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)) ||
-               (rth->peer && rth->peer->pmtu_expires);
+               (rt_has_peer(rth) && rt_peer_ptr(rth)->pmtu_expires);
 }
 
 static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2)
@@ -935,7 +935,7 @@ static void rt_cache_invalidate(struct net *net)
 
        get_random_bytes(&shuffle, sizeof(shuffle));
        atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
-       inetpeer_invalidate_tree(net, AF_INET);
+       inetpeer_invalidate_tree(net->ipv4.peers);
 }
 
 /*
@@ -1325,12 +1325,16 @@ static u32 rt_peer_genid(void)
 
 void rt_bind_peer(struct rtable *rt, __be32 daddr, int create)
 {
-       struct net *net = dev_net(rt->dst.dev);
+       struct inet_peer_base *base;
        struct inet_peer *peer;
 
-       peer = inet_getpeer_v4(net, daddr, create);
+       base = inetpeer_base_ptr(rt->_peer);
+       if (!base)
+               return;
+
+       peer = inet_getpeer_v4(base, daddr, create);
 
-       if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL)
+       if (!rt_set_peer(rt, peer))
                inet_putpeer(peer);
        else
                rt->rt_peer_genid = rt_peer_genid();
@@ -1533,8 +1537,10 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
                                                rt_genid(dev_net(dst->dev)));
                        rt_del(hash, rt);
                        ret = NULL;
-               } else if (rt->peer && peer_pmtu_expired(rt->peer)) {
-                       dst_metric_set(dst, RTAX_MTU, rt->peer->pmtu_orig);
+               } 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;
@@ -1658,67 +1664,6 @@ out:     kfree_skb(skb);
        return 0;
 }
 
-/*
- *     The last two values are not from the RFC but
- *     are needed for AMPRnet AX.25 paths.
- */
-
-static const unsigned short mtu_plateau[] =
-{32000, 17914, 8166, 4352, 2002, 1492, 576, 296, 216, 128 };
-
-static inline unsigned short guess_mtu(unsigned short old_mtu)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(mtu_plateau); i++)
-               if (old_mtu > mtu_plateau[i])
-                       return mtu_plateau[i];
-       return 68;
-}
-
-unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
-                                unsigned short new_mtu,
-                                struct net_device *dev)
-{
-       unsigned short old_mtu = ntohs(iph->tot_len);
-       unsigned short est_mtu = 0;
-       struct inet_peer *peer;
-
-       peer = inet_getpeer_v4(net, iph->daddr, 1);
-       if (peer) {
-               unsigned short mtu = new_mtu;
-
-               if (new_mtu < 68 || new_mtu >= old_mtu) {
-                       /* BSD 4.2 derived systems incorrectly adjust
-                        * tot_len by the IP header length, and report
-                        * a zero MTU in the ICMP message.
-                        */
-                       if (mtu == 0 &&
-                           old_mtu >= 68 + (iph->ihl << 2))
-                               old_mtu -= iph->ihl << 2;
-                       mtu = guess_mtu(old_mtu);
-               }
-
-               if (mtu < ip_rt_min_pmtu)
-                       mtu = ip_rt_min_pmtu;
-               if (!peer->pmtu_expires || mtu < peer->pmtu_learned) {
-                       unsigned long pmtu_expires;
-
-                       pmtu_expires = jiffies + ip_rt_mtu_expires;
-                       if (!pmtu_expires)
-                               pmtu_expires = 1UL;
-
-                       est_mtu = mtu;
-                       peer->pmtu_learned = mtu;
-                       peer->pmtu_expires = pmtu_expires;
-                       atomic_inc(&__rt_peer_genid);
-               }
-
-               inet_putpeer(peer);
-       }
-       return est_mtu ? : new_mtu;
-}
-
 static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer)
 {
        unsigned long expires = ACCESS_ONCE(peer->pmtu_expires);
@@ -1796,14 +1741,13 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
 static void ipv4_dst_destroy(struct dst_entry *dst)
 {
        struct rtable *rt = (struct rtable *) dst;
-       struct inet_peer *peer = rt->peer;
 
        if (rt->fi) {
                fib_info_put(rt->fi);
                rt->fi = NULL;
        }
-       if (peer) {
-               rt->peer = NULL;
+       if (rt_has_peer(rt)) {
+               struct inet_peer *peer = rt_peer_ptr(rt);
                inet_putpeer(peer);
        }
 }
@@ -1816,8 +1760,11 @@ 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->peer && peer_pmtu_cleaned(rt->peer))
-               dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig);
+       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);
+       }
 }
 
 static int ip_rt_bug(struct sk_buff *skb)
@@ -1919,7 +1866,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
 static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
                            struct fib_info *fi)
 {
-       struct net *net = dev_net(rt->dst.dev);
+       struct inet_peer_base *base;
        struct inet_peer *peer;
        int create = 0;
 
@@ -1929,8 +1876,12 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
        if (fl4 && (fl4->flowi4_flags & FLOWI_FLAG_PRECOW_METRICS))
                create = 1;
 
-       rt->peer = peer = inet_getpeer_v4(net, rt->rt_dst, create);
+       base = inetpeer_base_ptr(rt->_peer);
+       BUG_ON(!base);
+
+       peer = inet_getpeer_v4(base, rt->rt_dst, create);
        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,
@@ -2046,7 +1997,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        rth->rt_gateway = daddr;
        rth->rt_spec_dst= spec_dst;
        rth->rt_peer_genid = 0;
-       rth->peer = NULL;
+       rt_init_peer(rth, dev_net(dev)->ipv4.peers);
        rth->fi = NULL;
        if (our) {
                rth->dst.input= ip_local_deliver;
@@ -2174,7 +2125,7 @@ static int __mkroute_input(struct sk_buff *skb,
        rth->rt_gateway = daddr;
        rth->rt_spec_dst= spec_dst;
        rth->rt_peer_genid = 0;
-       rth->peer = NULL;
+       rt_init_peer(rth, dev_net(rth->dst.dev)->ipv4.peers);
        rth->fi = NULL;
 
        rth->dst.input = ip_forward;
@@ -2357,7 +2308,7 @@ local_input:
        rth->rt_gateway = daddr;
        rth->rt_spec_dst= spec_dst;
        rth->rt_peer_genid = 0;
-       rth->peer = NULL;
+       rt_init_peer(rth, net->ipv4.peers);
        rth->fi = NULL;
        if (res.type == RTN_UNREACHABLE) {
                rth->dst.input= ip_error;
@@ -2561,7 +2512,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
        rth->rt_gateway = fl4->daddr;
        rth->rt_spec_dst= fl4->saddr;
        rth->rt_peer_genid = 0;
-       rth->peer = NULL;
+       rt_init_peer(rth, dev_net(dev_out)->ipv4.peers);
        rth->fi = NULL;
 
        RT_CACHE_STAT_INC(out_slow_tot);
@@ -2898,9 +2849,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
                rt->rt_src = ort->rt_src;
                rt->rt_gateway = ort->rt_gateway;
                rt->rt_spec_dst = ort->rt_spec_dst;
-               rt->peer = ort->peer;
-               if (rt->peer)
-                       atomic_inc(&rt->peer->refcnt);
+               rt_transfer_peer(rt, ort);
                rt->fi = ort->fi;
                if (rt->fi)
                        atomic_inc(&rt->fi->fib_clntref);
@@ -2938,7 +2887,6 @@ static int rt_fill_info(struct net *net,
        struct rtmsg *r;
        struct nlmsghdr *nlh;
        unsigned long expires = 0;
-       const struct inet_peer *peer = rt->peer;
        u32 id = 0, ts = 0, tsage = 0, error;
 
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
@@ -2994,8 +2942,9 @@ static int rt_fill_info(struct net *net,
                goto nla_put_failure;
 
        error = rt->dst.error;
-       if (peer) {
-               inet_peer_refcheck(rt->peer);
+       if (rt_has_peer(rt)) {
+               const struct inet_peer *peer = rt_peer_ptr(rt);
+               inet_peer_refcheck(peer);
                id = atomic_read(&peer->ip_id_count) & 0xffff;
                if (peer->tcp_ts_stamp) {
                        ts = peer->tcp_ts;
@@ -3401,7 +3350,7 @@ static void __net_exit ipv4_inetpeer_exit(struct net *net)
        struct inet_peer_base *bp = net->ipv4.peers;
 
        net->ipv4.peers = NULL;
-       __inetpeer_invalidate_tree(bp);
+       inetpeer_invalidate_tree(bp);
        kfree(bp);
 }