ipv4: Prepare for change of rt->rt_iif encoding.
authorDavid S. Miller <davem@davemloft.net>
Mon, 23 Jul 2012 23:29:00 +0000 (16:29 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 23 Jul 2012 23:36:26 +0000 (16:36 -0700)
Use inet_iif() consistently, and for TCP record the input interface of
cached RX dst in inet sock.

rt->rt_iif is going to be encoded differently, so that we can
legitimately cache input routes in the FIB info more aggressively.

When the input interface is "use SKB device index" the rt->rt_iif will
be set to zero.

This forces us to move the TCP RX dst cache installation into the ipv4
specific code, and as well it should since doing the route caching for
ipv6 is pointless at the moment since it is not inspected in the ipv6
input paths yet.

Also, remove the unlikely on dst->obsolete, all ipv4 dsts have
obsolete set to a non-zero value to force invocation of the check
callback.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/inet_sock.h
net/dccp/ipv4.c
net/ipv4/icmp.c
net/ipv4/ip_sockglue.c
net/ipv4/route.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/sched/cls_route.c
net/sched/em_meta.c
net/sctp/protocol.c

index 924d7b98ab60573690fa60d46c5b251230e32654..613cfa4016728300da88a8fc6f1f664de99da5cc 100644 (file)
@@ -172,6 +172,7 @@ struct inet_sock {
        int                     uc_index;
        int                     mc_index;
        __be32                  mc_addr;
+       int                     rx_dst_ifindex;
        struct ip_mc_socklist __rcu     *mc_list;
        struct inet_cork_full   cork;
 };
index 25428d0c50c96a5ec622cbf9e5651de1e2ebe2e9..176ecdba4a22c0e3b4ec1b2c102032b4d64e763e 100644 (file)
@@ -481,7 +481,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
        struct rtable *rt;
        const struct iphdr *iph = ip_hdr(skb);
        struct flowi4 fl4 = {
-               .flowi4_oif = skb_rtable(skb)->rt_iif,
+               .flowi4_oif = inet_iif(skb),
                .daddr = iph->saddr,
                .saddr = iph->daddr,
                .flowi4_tos = RT_CONN_FLAGS(sk),
index f2a06beffbd34a350d618bc46bdfcdb7b1ea878f..f2eccd531746bea19eb269fa0d75266b20f69ebc 100644 (file)
@@ -571,7 +571,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                rcu_read_lock();
                if (rt_is_input_route(rt) &&
                    net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr)
-                       dev = dev_get_by_index_rcu(net, rt->rt_iif);
+                       dev = dev_get_by_index_rcu(net, inet_iif(skb_in));
 
                if (dev)
                        saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
index de29f46f68b02f69d9b7f9cc8094136cff545d74..5eea4a811042adaf3df8e65308c2aeeb23c845e9 100644 (file)
@@ -1027,10 +1027,9 @@ e_inval:
 void ipv4_pktinfo_prepare(struct sk_buff *skb)
 {
        struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb);
-       const struct rtable *rt = skb_rtable(skb);
 
-       if (rt) {
-               pktinfo->ipi_ifindex = rt->rt_iif;
+       if (skb_rtable(skb)) {
+               pktinfo->ipi_ifindex = inet_iif(skb);
                pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
        } else {
                pktinfo->ipi_ifindex = 0;
index 34017be87c8546d47f033b906696a422fc19121f..f6be78119396a1f65286e567060e3b7eabbac319 100644 (file)
@@ -848,7 +848,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
                if (log_martians &&
                    peer->rate_tokens == ip_rt_redirect_number)
                        net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n",
-                                            &ip_hdr(skb)->saddr, rt->rt_iif,
+                                            &ip_hdr(skb)->saddr, inet_iif(skb),
                                             &ip_hdr(skb)->daddr, &rt->rt_gateway);
 #endif
        }
index 21d7f8f3a7a55c92f96f5c47e891b652e1b02672..3e07a64ca44e7d45879dee37a73522ce1f97d354 100644 (file)
@@ -5391,18 +5391,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
-       if (sk->sk_rx_dst) {
-               struct dst_entry *dst = sk->sk_rx_dst;
-               if (unlikely(dst->obsolete)) {
-                       if (dst->ops->check(dst, 0) == NULL) {
-                               dst_release(dst);
-                               sk->sk_rx_dst = NULL;
-                       }
-               }
-       }
-       if (unlikely(sk->sk_rx_dst == NULL))
-               sk->sk_rx_dst = dst_clone(skb_dst(skb));
-
        /*
         *      Header prediction.
         *      The code loosely follows the one in the famous
index bc5432e3c778b1e2c02926f93c7488f2649e6abc..3e30548ac32a263ddb4f377c09d4b62dbc418f1e 100644 (file)
@@ -1618,6 +1618,20 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 
        if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
                sock_rps_save_rxhash(sk, skb);
+               if (sk->sk_rx_dst) {
+                       struct dst_entry *dst = sk->sk_rx_dst;
+                       if (dst->ops->check(dst, 0) == NULL) {
+                               dst_release(dst);
+                               sk->sk_rx_dst = NULL;
+                       }
+               }
+               if (unlikely(sk->sk_rx_dst == NULL)) {
+                       struct inet_sock *icsk = inet_sk(sk);
+                       struct rtable *rt = skb_rtable(skb);
+
+                       sk->sk_rx_dst = dst_clone(&rt->dst);
+                       icsk->rx_dst_ifindex = inet_iif(skb);
+               }
                if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
                        rsk = sk;
                        goto reset;
@@ -1700,14 +1714,12 @@ void tcp_v4_early_demux(struct sk_buff *skb)
                skb->destructor = sock_edemux;
                if (sk->sk_state != TCP_TIME_WAIT) {
                        struct dst_entry *dst = sk->sk_rx_dst;
+                       struct inet_sock *icsk = inet_sk(sk);
                        if (dst)
                                dst = dst_check(dst, 0);
-                       if (dst) {
-                               struct rtable *rt = (struct rtable *) dst;
-
-                               if (rt->rt_iif == dev->ifindex)
-                                       skb_dst_set_noref(skb, dst);
-                       }
+                       if (dst &&
+                           icsk->rx_dst_ifindex == dev->ifindex)
+                               skb_dst_set_noref(skb, dst);
                }
        }
 }
index 36fec422740154b4addb97e20410da27f1e98622..44f405cb9aafa54d07ecbd99d006778f71e5634e 100644 (file)
@@ -143,7 +143,7 @@ static int route4_classify(struct sk_buff *skb, const struct tcf_proto *tp,
        if (head == NULL)
                goto old_method;
 
-       iif = ((struct rtable *)dst)->rt_iif;
+       iif = inet_iif(skb);
 
        h = route4_fastmap_hash(id, iif);
        if (id == head->fastmap[h].id &&
index 4790c696cbce8364af6552d2028ed0a1880e3a21..4ab6e33255736b90374d3dc53da60e79c277ebb9 100644 (file)
@@ -264,7 +264,7 @@ META_COLLECTOR(int_rtiif)
        if (unlikely(skb_rtable(skb) == NULL))
                *err = -1;
        else
-               dst->value = skb_rtable(skb)->rt_iif;
+               dst->value = inet_iif(skb);
 }
 
 /**************************************************************************
index 9c90811d11345b6fb4a55b5878a9ec168bd3f17c..1f89c4e696457fc02948066052713cac4d2f46fc 100644 (file)
@@ -568,7 +568,7 @@ static void sctp_v4_get_saddr(struct sctp_sock *sk,
 /* What interface did this skb arrive on? */
 static int sctp_v4_skb_iif(const struct sk_buff *skb)
 {
-       return skb_rtable(skb)->rt_iif;
+       return inet_iif(skb);
 }
 
 /* Was this packet marked by Explicit Congestion Notification? */