]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
esp4: split esp_output_udp_encap and introduce esp_output_encap
authorSabrina Dubroca <sd@queasysnail.net>
Mon, 25 Nov 2019 13:49:01 +0000 (14:49 +0100)
committerSteffen Klassert <steffen.klassert@secunet.com>
Mon, 9 Dec 2019 08:59:07 +0000 (09:59 +0100)
Co-developed-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/ipv4/esp4.c

index c5d826642229392d943307bb7a919774edc74ba0..033c61d27148ffd31b31f4b40251a1ba2e7ff98a 100644 (file)
@@ -225,45 +225,62 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)
        tail[plen - 1] = proto;
 }
 
-static int esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)
+static struct ip_esp_hdr *esp_output_udp_encap(struct sk_buff *skb,
+                                              int encap_type,
+                                              struct esp_info *esp,
+                                              __be16 sport,
+                                              __be16 dport)
 {
-       int encap_type;
        struct udphdr *uh;
        __be32 *udpdata32;
-       __be16 sport, dport;
-       struct xfrm_encap_tmpl *encap = x->encap;
-       struct ip_esp_hdr *esph = esp->esph;
        unsigned int len;
 
-       spin_lock_bh(&x->lock);
-       sport = encap->encap_sport;
-       dport = encap->encap_dport;
-       encap_type = encap->encap_type;
-       spin_unlock_bh(&x->lock);
-
        len = skb->len + esp->tailen - skb_transport_offset(skb);
        if (len + sizeof(struct iphdr) >= IP_MAX_MTU)
-               return -EMSGSIZE;
+               return ERR_PTR(-EMSGSIZE);
 
-       uh = (struct udphdr *)esph;
+       uh = (struct udphdr *)esp->esph;
        uh->source = sport;
        uh->dest = dport;
        uh->len = htons(len);
        uh->check = 0;
 
+       *skb_mac_header(skb) = IPPROTO_UDP;
+
+       if (encap_type == UDP_ENCAP_ESPINUDP_NON_IKE) {
+               udpdata32 = (__be32 *)(uh + 1);
+               udpdata32[0] = udpdata32[1] = 0;
+               return (struct ip_esp_hdr *)(udpdata32 + 2);
+       }
+
+       return (struct ip_esp_hdr *)(uh + 1);
+}
+
+static int esp_output_encap(struct xfrm_state *x, struct sk_buff *skb,
+                           struct esp_info *esp)
+{
+       struct xfrm_encap_tmpl *encap = x->encap;
+       struct ip_esp_hdr *esph;
+       __be16 sport, dport;
+       int encap_type;
+
+       spin_lock_bh(&x->lock);
+       sport = encap->encap_sport;
+       dport = encap->encap_dport;
+       encap_type = encap->encap_type;
+       spin_unlock_bh(&x->lock);
+
        switch (encap_type) {
        default:
        case UDP_ENCAP_ESPINUDP:
-               esph = (struct ip_esp_hdr *)(uh + 1);
-               break;
        case UDP_ENCAP_ESPINUDP_NON_IKE:
-               udpdata32 = (__be32 *)(uh + 1);
-               udpdata32[0] = udpdata32[1] = 0;
-               esph = (struct ip_esp_hdr *)(udpdata32 + 2);
+               esph = esp_output_udp_encap(skb, encap_type, esp, sport, dport);
                break;
        }
 
-       *skb_mac_header(skb) = IPPROTO_UDP;
+       if (IS_ERR(esph))
+               return PTR_ERR(esph);
+
        esp->esph = esph;
 
        return 0;
@@ -281,7 +298,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
 
        /* this is non-NULL only with UDP Encapsulation */
        if (x->encap) {
-               int err = esp_output_udp_encap(x, skb, esp);
+               int err = esp_output_encap(x, skb, esp);
 
                if (err < 0)
                        return err;