[SCSI] libfc,fcoe,fnic: Separate rport and lport max retry counts
[safe/jmp/linux-2.6] / net / ipv6 / esp6.c
index dc821ac..c2f2501 100644 (file)
@@ -188,7 +188,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
        *skb_mac_header(skb) = IPPROTO_ESP;
 
        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,
@@ -199,7 +199,8 @@ static int esp6_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);
@@ -281,7 +282,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
        struct scatterlist *sg;
        struct scatterlist *asg;
 
-       if (!pskb_may_pull(skb, sizeof(*esph))) {
+       if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead))) {
                ret = -EINVAL;
                goto out;
        }
@@ -355,6 +356,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
 static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                     int type, int code, int offset, __be32 info)
 {
+       struct net *net = dev_net(skb->dev);
        struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
        struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset);
        struct xfrm_state *x;
@@ -363,11 +365,11 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
            type != ICMPV6_PKT_TOOBIG)
                return;
 
-       x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
+       x = xfrm_state_lookup(net, (xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
        if (!x)
                return;
-       printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/" NIP6_FMT "\n",
-                       ntohl(esph->spi), NIP6(iph->daddr));
+       printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
+                       ntohl(esph->spi), &iph->daddr);
        xfrm_state_put(x);
 }
 
@@ -382,35 +384,53 @@ static void esp6_destroy(struct xfrm_state *x)
        kfree(esp);
 }
 
-static int esp6_init_state(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x)
+{
+       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 = NULL;
+       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;
-
-       if (x->encap)
-               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);
@@ -458,8 +478,6 @@ static int esp6_init_state(struct xfrm_state *x)
                        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);
 
@@ -468,13 +486,46 @@ static int esp6_init_state(struct xfrm_state *x)
 free_key:
        kfree(key);
 
+error:
+       return err;
+}
+
+static int esp6_init_state(struct xfrm_state *x)
+{
+       struct esp_data *esp;
+       struct crypto_aead *aead;
+       u32 align;
+       int err;
+
+       if (x->encap)
+               return -EINVAL;
+
+       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);
        switch (x->props.mode) {
        case XFRM_MODE_BEET:
+               if (x->sel.family != AF_INET6)
+                       x->props.header_len += IPV4_BEET_PHMAXLEN +
+                                              (sizeof(struct ipv6hdr) - sizeof(struct iphdr));
+               break;
        case XFRM_MODE_TRANSPORT:
                break;
        case XFRM_MODE_TUNNEL:
@@ -493,7 +544,7 @@ error:
        return err;
 }
 
-static struct xfrm_type esp6_type =
+static const struct xfrm_type esp6_type =
 {
        .description    = "ESP6",
        .owner          = THIS_MODULE,