Commit eecd227a authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Steffen Klassert

esp4: split esp_output_udp_encap and introduce esp_output_encap

Co-developed-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 25f6802b
...@@ -225,45 +225,62 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto) ...@@ -225,45 +225,62 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)
tail[plen - 1] = 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; struct udphdr *uh;
__be32 *udpdata32; __be32 *udpdata32;
__be16 sport, dport;
struct xfrm_encap_tmpl *encap = x->encap;
struct ip_esp_hdr *esph = esp->esph;
unsigned int len; 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); len = skb->len + esp->tailen - skb_transport_offset(skb);
if (len + sizeof(struct iphdr) >= IP_MAX_MTU) 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->source = sport;
uh->dest = dport; uh->dest = dport;
uh->len = htons(len); uh->len = htons(len);
uh->check = 0; 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) { switch (encap_type) {
default: default:
case UDP_ENCAP_ESPINUDP: case UDP_ENCAP_ESPINUDP:
esph = (struct ip_esp_hdr *)(uh + 1);
break;
case UDP_ENCAP_ESPINUDP_NON_IKE: case UDP_ENCAP_ESPINUDP_NON_IKE:
udpdata32 = (__be32 *)(uh + 1); esph = esp_output_udp_encap(skb, encap_type, esp, sport, dport);
udpdata32[0] = udpdata32[1] = 0;
esph = (struct ip_esp_hdr *)(udpdata32 + 2);
break; break;
} }
*skb_mac_header(skb) = IPPROTO_UDP; if (IS_ERR(esph))
return PTR_ERR(esph);
esp->esph = esph; esp->esph = esph;
return 0; return 0;
...@@ -281,7 +298,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * ...@@ -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 */ /* this is non-NULL only with UDP Encapsulation */
if (x->encap) { if (x->encap) {
int err = esp_output_udp_encap(x, skb, esp); int err = esp_output_encap(x, skb, esp);
if (err < 0) if (err < 0)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment