rtc-mxc: remove unnecessary clock source for rtc subsystem
[safe/jmp/linux-2.6] / net / ipv4 / esp4.c
index c404722..14ca1f1 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);
@@ -199,7 +199,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
        }
 
        esph->spi = x->id.spi;
-       esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+       esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
 
        sg_init_table(sg, nfrags);
        skb_to_sgvec(skb, sg,
@@ -210,7 +210,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
        aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
        aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
        aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
-       aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
+       aead_givcrypt_set_giv(req, esph->enc_data,
+                             XFRM_SKB_CB(skb)->seq.output);
 
        ESP_SKB_CB(skb)->tmp = tmp;
        err = crypto_aead_givencrypt(req);
@@ -335,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)
@@ -412,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, skb->mark, (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",
@@ -439,32 +441,53 @@ static void esp_destroy(struct xfrm_state *x)
        kfree(esp);
 }
 
-static int esp_init_state(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x)
 {
-       struct esp_data *esp = NULL;
+       struct esp_data *esp = x->data;
+       struct crypto_aead *aead;
+       int err;
+
+       aead = crypto_alloc_aead(x->aead->alg_name, 0, 0);
+       err = PTR_ERR(aead);
+       if (IS_ERR(aead))
+               goto error;
+
+       esp->aead = aead;
+
+       err = crypto_aead_setkey(aead, x->aead->alg_key,
+                                (x->aead->alg_key_len + 7) / 8);
+       if (err)
+               goto error;
+
+       err = crypto_aead_setauthsize(aead, x->aead->alg_icv_len / 8);
+       if (err)
+               goto error;
+
+error:
+       return err;
+}
+
+static int esp_init_authenc(struct xfrm_state *x)
+{
+       struct esp_data *esp = x->data;
        struct crypto_aead *aead;
        struct crypto_authenc_key_param *param;
        struct rtattr *rta;
        char *key;
        char *p;
        char authenc_name[CRYPTO_MAX_ALG_NAME];
-       u32 align;
        unsigned int keylen;
        int err;
 
+       err = -EINVAL;
        if (x->ealg == NULL)
-               return -EINVAL;
+               goto error;
 
+       err = -ENAMETOOLONG;
        if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)",
                     x->aalg ? x->aalg->alg_name : "digest_null",
                     x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME)
-               return -ENAMETOOLONG;
-
-       esp = kzalloc(sizeof(*esp), GFP_KERNEL);
-       if (esp == NULL)
-               return -ENOMEM;
-
-       x->data = esp;
+               goto error;
 
        aead = crypto_alloc_aead(authenc_name, 0, 0);
        err = PTR_ERR(aead);
@@ -507,13 +530,11 @@ static int esp_init_state(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;
        }
 
-       esp->padlen = 0;
-
        param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
        memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8);
 
@@ -522,14 +543,40 @@ static int esp_init_state(struct xfrm_state *x)
 free_key:
        kfree(key);
 
+error:
+       return err;
+}
+
+static int esp_init_state(struct xfrm_state *x)
+{
+       struct esp_data *esp;
+       struct crypto_aead *aead;
+       u32 align;
+       int err;
+
+       esp = kzalloc(sizeof(*esp), GFP_KERNEL);
+       if (esp == NULL)
+               return -ENOMEM;
+
+       x->data = esp;
+
+       if (x->aead)
+               err = esp_init_aead(x);
+       else
+               err = esp_init_authenc(x);
+
        if (err)
                goto error;
 
+       aead = esp->aead;
+
+       esp->padlen = 0;
+
        x->props.header_len = sizeof(struct ip_esp_hdr) +
                              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;
@@ -555,7 +602,7 @@ error:
        return err;
 }
 
-static struct xfrm_type esp_type =
+static const struct xfrm_type esp_type =
 {
        .description    = "ESP4",
        .owner          = THIS_MODULE,
@@ -568,10 +615,11 @@ static 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)