gre: fix netns vs proto registration ordering
[safe/jmp/linux-2.6] / net / ipv4 / esp4.c
index 091e670..1948895 100644 (file)
@@ -168,7 +168,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
                struct xfrm_encap_tmpl *encap = x->encap;
                struct udphdr *uh;
                __be32 *udpdata32;
-               unsigned int sport, dport;
+               __be16 sport, dport;
                int encap_type;
 
                spin_lock_bh(&x->lock);
@@ -336,7 +336,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        struct scatterlist *asg;
        int err = -EINVAL;
 
-       if (!pskb_may_pull(skb, sizeof(*esph)))
+       if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead)))
                goto out;
 
        if (elen <= 0)
@@ -413,15 +413,16 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
 
 static void esp4_err(struct sk_buff *skb, u32 info)
 {
-       struct iphdr *iph = (struct iphdr*)skb->data;
-       struct ip_esp_hdr *esph = (struct ip_esp_hdr*)(skb->data+(iph->ihl<<2));
+       struct net *net = dev_net(skb->dev);
+       struct iphdr *iph = (struct iphdr *)skb->data;
+       struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
        struct xfrm_state *x;
 
        if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
            icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
                return;
 
-       x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
+       x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
        if (!x)
                return;
        NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
@@ -529,7 +530,7 @@ static int esp_init_authenc(struct xfrm_state *x)
                }
 
                err = crypto_aead_setauthsize(
-                       aead, aalg_desc->uinfo.auth.icv_truncbits / 8);
+                       aead, x->aalg->alg_trunc_len / 8);
                if (err)
                        goto free_key;
        }
@@ -575,7 +576,7 @@ static int esp_init_state(struct xfrm_state *x)
                              crypto_aead_ivsize(aead);
        if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct iphdr);
-       else if (x->props.mode == XFRM_MODE_BEET)
+       else if (x->props.mode == XFRM_MODE_BEET && x->sel.family != AF_INET6)
                x->props.header_len += IPV4_BEET_PHMAXLEN;
        if (x->encap) {
                struct xfrm_encap_tmpl *encap = x->encap;
@@ -614,10 +615,11 @@ static const struct xfrm_type esp_type =
        .output         = esp_output
 };
 
-static struct net_protocol esp4_protocol = {
+static const struct net_protocol esp4_protocol = {
        .handler        =       xfrm4_rcv,
        .err_handler    =       esp4_err,
        .no_policy      =       1,
+       .netns_ok       =       1,
 };
 
 static int __init esp4_init(void)