]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/ipv4/xfrm4_policy.c
ipv4: fix race condition between route lookup and invalidation
[linux.git] / net / ipv4 / xfrm4_policy.c
index 2b144b92ae46a430d184fca120616166e8010f53..35b84b52b7027b35f65b36d6a0160913e8df2c5a 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/inetdevice.h>
-#include <linux/if_tunnel.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
@@ -69,17 +68,6 @@ static int xfrm4_get_saddr(struct net *net, int oif,
        return 0;
 }
 
-static int xfrm4_get_tos(const struct flowi *fl)
-{
-       return IPTOS_RT_MASK & fl->u.ip4.flowi4_tos; /* Strip ECN bits */
-}
-
-static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
-                          int nfheader_len)
-{
-       return 0;
-}
-
 static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
                          const struct flowi *fl)
 {
@@ -97,8 +85,12 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST |
                                              RTCF_LOCAL);
        xdst->u.rt.rt_type = rt->rt_type;
-       xdst->u.rt.rt_gateway = rt->rt_gateway;
        xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
+       xdst->u.rt.rt_gw_family = rt->rt_gw_family;
+       if (rt->rt_gw_family == AF_INET)
+               xdst->u.rt.rt_gw4 = rt->rt_gw4;
+       else if (rt->rt_gw_family == AF_INET6)
+               xdst->u.rt.rt_gw6 = rt->rt_gw6;
        xdst->u.rt.rt_pmtu = rt->rt_pmtu;
        xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked;
        INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
@@ -107,120 +99,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        return 0;
 }
 
-static void
-_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
-{
-       const struct iphdr *iph = ip_hdr(skb);
-       int ihl = iph->ihl;
-       u8 *xprth = skb_network_header(skb) + ihl * 4;
-       struct flowi4 *fl4 = &fl->u.ip4;
-       int oif = 0;
-
-       if (skb_dst(skb))
-               oif = skb_dst(skb)->dev->ifindex;
-
-       memset(fl4, 0, sizeof(struct flowi4));
-       fl4->flowi4_mark = skb->mark;
-       fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
-
-       fl4->flowi4_proto = iph->protocol;
-       fl4->daddr = reverse ? iph->saddr : iph->daddr;
-       fl4->saddr = reverse ? iph->daddr : iph->saddr;
-       fl4->flowi4_tos = iph->tos;
-
-       if (!ip_is_fragment(iph)) {
-               switch (iph->protocol) {
-               case IPPROTO_UDP:
-               case IPPROTO_UDPLITE:
-               case IPPROTO_TCP:
-               case IPPROTO_SCTP:
-               case IPPROTO_DCCP:
-                       if (xprth + 4 < skb->data ||
-                           pskb_may_pull(skb, xprth + 4 - skb->data)) {
-                               __be16 *ports;
-
-                               xprth = skb_network_header(skb) + ihl * 4;
-                               ports = (__be16 *)xprth;
-
-                               fl4->fl4_sport = ports[!!reverse];
-                               fl4->fl4_dport = ports[!reverse];
-                       }
-                       break;
-
-               case IPPROTO_ICMP:
-                       if (xprth + 2 < skb->data ||
-                           pskb_may_pull(skb, xprth + 2 - skb->data)) {
-                               u8 *icmp;
-
-                               xprth = skb_network_header(skb) + ihl * 4;
-                               icmp = xprth;
-
-                               fl4->fl4_icmp_type = icmp[0];
-                               fl4->fl4_icmp_code = icmp[1];
-                       }
-                       break;
-
-               case IPPROTO_ESP:
-                       if (xprth + 4 < skb->data ||
-                           pskb_may_pull(skb, xprth + 4 - skb->data)) {
-                               __be32 *ehdr;
-
-                               xprth = skb_network_header(skb) + ihl * 4;
-                               ehdr = (__be32 *)xprth;
-
-                               fl4->fl4_ipsec_spi = ehdr[0];
-                       }
-                       break;
-
-               case IPPROTO_AH:
-                       if (xprth + 8 < skb->data ||
-                           pskb_may_pull(skb, xprth + 8 - skb->data)) {
-                               __be32 *ah_hdr;
-
-                               xprth = skb_network_header(skb) + ihl * 4;
-                               ah_hdr = (__be32 *)xprth;
-
-                               fl4->fl4_ipsec_spi = ah_hdr[1];
-                       }
-                       break;
-
-               case IPPROTO_COMP:
-                       if (xprth + 4 < skb->data ||
-                           pskb_may_pull(skb, xprth + 4 - skb->data)) {
-                               __be16 *ipcomp_hdr;
-
-                               xprth = skb_network_header(skb) + ihl * 4;
-                               ipcomp_hdr = (__be16 *)xprth;
-
-                               fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
-                       }
-                       break;
-
-               case IPPROTO_GRE:
-                       if (xprth + 12 < skb->data ||
-                           pskb_may_pull(skb, xprth + 12 - skb->data)) {
-                               __be16 *greflags;
-                               __be32 *gre_hdr;
-
-                               xprth = skb_network_header(skb) + ihl * 4;
-                               greflags = (__be16 *)xprth;
-                               gre_hdr = (__be32 *)xprth;
-
-                               if (greflags[0] & GRE_KEY) {
-                                       if (greflags[0] & GRE_CSUM)
-                                               gre_hdr++;
-                                       fl4->fl4_gre_key = gre_hdr[1];
-                               }
-                       }
-                       break;
-
-               default:
-                       fl4->fl4_ipsec_spi = 0;
-                       break;
-               }
-       }
-}
-
 static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk,
                              struct sk_buff *skb, u32 mtu)
 {
@@ -273,9 +151,6 @@ static const struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
        .dst_ops =              &xfrm4_dst_ops_template,
        .dst_lookup =           xfrm4_dst_lookup,
        .get_saddr =            xfrm4_get_saddr,
-       .decode_session =       _decode_session4,
-       .get_tos =              xfrm4_get_tos,
-       .init_path =            xfrm4_init_path,
        .fill_dst =             xfrm4_fill_dst,
        .blackhole_route =      ipv4_blackhole_route,
 };