Commit b2c31abe authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by David S. Miller

[IPSEC]: Support draft-ietf-ipsec-udp-encaps-00/01, some ipec impls need it.

parent a318dc62
......@@ -31,6 +31,7 @@ struct udphdr {
#define UDP_ENCAP 100 /* Set the socket to accept encapsulated packets */
/* UDP encapsulation types */
#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */
#ifdef __KERNEL__
......
......@@ -31,6 +31,7 @@ int esp_output(struct sk_buff *skb)
struct esp_data *esp;
struct sk_buff *trailer;
struct udphdr *uh = NULL;
u32 *udpdata32;
struct xfrm_encap_tmpl *encap = NULL;
int blksize;
int clen;
......@@ -97,6 +98,14 @@ int esp_output(struct sk_buff *skb)
esph = (struct ip_esp_hdr*)(uh+1);
top_iph->protocol = IPPROTO_UDP;
break;
case UDP_ENCAP_ESPINUDP_NON_IKE:
uh = (struct udphdr*) esph;
udpdata32 = (u32*)(uh+1);
udpdata32[0] = udpdata32[1] = 0;
esph = (struct ip_esp_hdr*)(udpdata32+2);
alen += 2;
top_iph->protocol = IPPROTO_UDP;
break;
default:
printk(KERN_INFO
"esp_output(): Unhandled encap: %u\n",
......@@ -132,6 +141,14 @@ int esp_output(struct sk_buff *skb)
esph = (struct ip_esp_hdr*)(uh+1);
top_iph->protocol = IPPROTO_UDP;
break;
case UDP_ENCAP_ESPINUDP_NON_IKE:
uh = (struct udphdr*) esph;
udpdata32 = (u32*)(uh+1);
udpdata32[0] = udpdata32[1] = 0;
esph = (struct ip_esp_hdr*)(udpdata32+2);
alen += 2;
top_iph->protocol = IPPROTO_UDP;
break;
default:
printk(KERN_INFO
"esp_output(): Unhandled encap: %u\n",
......@@ -294,6 +311,7 @@ int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
switch (decap->decap_type) {
case UDP_ENCAP_ESPINUDP:
case UDP_ENCAP_ESPINUDP_NON_IKE:
if ((void*)uh == (void*)esph) {
printk(KERN_DEBUG
......@@ -354,6 +372,7 @@ int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct
switch (encap->encap_type) {
case UDP_ENCAP_ESPINUDP:
case UDP_ENCAP_ESPINUDP_NON_IKE:
/*
* 1) if the NAT-T peer's IP or port changed then
* advertize the change to the keying daemon.
......@@ -534,6 +553,9 @@ int esp_init_state(struct xfrm_state *x, void *args)
case UDP_ENCAP_ESPINUDP:
x->props.header_len += sizeof(struct udphdr);
break;
case UDP_ENCAP_ESPINUDP_NON_IKE:
x->props.header_len += sizeof(struct udphdr) + 2 * sizeof(u32);
break;
default:
printk (KERN_INFO
"esp_init_state(): Unhandled encap type: %u\n",
......
......@@ -975,6 +975,7 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
/* Must be an IKE packet.. pass it through */
return 1;
decaps:
/* At this point we are sure that this is an ESPinUDP packet,
* so we need to remove 'len' bytes from the packet (the UDP
* header and optional ESP marker bytes) and then modify the
......@@ -1002,6 +1003,20 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
/* and let the caller know to send this into the ESP processor... */
return -1;
case UDP_ENCAP_ESPINUDP_NON_IKE:
/* Check if this is a keepalive packet. If so, eat it. */
if (len == 1 && udpdata[0] == 0xff) {
return 0;
} else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
udpdata32[0] == 0 && udpdata32[1] == 0) {
/* ESP Packet with Non-IKE marker */
len = sizeof(struct udphdr) + 2 * sizeof(u32);
goto decaps;
} else
/* Must be an IKE packet.. pass it through */
return 1;
default:
if (net_ratelimit())
printk(KERN_INFO "udp_encap_rcv(): Unhandled UDP encap type: %u\n",
......
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