Commit 5d86a97e authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPCOMP]: Exclude IPCOMP header from props.header_len

This is another patch on the way towards a unified XFRM tunnel
encapsulation function.

This patch changes the value of props.header_len for IPCOMP to
exclude the IPCOMP header.  The reason is that the IPCOMP header
is added only if the packet is compressible.  That is, if the
size of the compressed payload plus the size of the IPCOMP header
is less than that of the original payload.

This means that the IPCOMP encapsulation does not impose any
overhead at all as far as the MTU is concerned.  The current
code incorrectly reduces the MTU by the size of the IPCOMP
header.

As a side-effect, this means that we don't have to move the
IP header around when IPCOMP is used.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 4167d838
...@@ -114,8 +114,8 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) ...@@ -114,8 +114,8 @@ static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb)
goto out; goto out;
} }
memcpy(start, scratch, dlen); memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen);
pskb_trim(skb, ihlen + dlen); pskb_trim(skb, ihlen + dlen + sizeof(struct ip_comp_hdr));
out: out:
return err; return err;
...@@ -148,13 +148,9 @@ static int ipcomp_output(struct sk_buff **pskb) ...@@ -148,13 +148,9 @@ static int ipcomp_output(struct sk_buff **pskb)
int err; int err;
struct dst_entry *dst = (*pskb)->dst; struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm; struct xfrm_state *x = dst->xfrm;
struct iphdr *iph, *top_iph; struct iphdr *iph;
struct ip_comp_hdr *ipch; struct ip_comp_hdr *ipch;
struct ipcomp_data *ipcd = x->data; struct ipcomp_data *ipcd = x->data;
union {
struct iphdr iph;
char buf[60];
} tmp_iph;
int hdr_len = 0; int hdr_len = 0;
if ((*pskb)->ip_summed == CHECKSUM_HW) { if ((*pskb)->ip_summed == CHECKSUM_HW) {
...@@ -211,19 +207,15 @@ static int ipcomp_output(struct sk_buff **pskb) ...@@ -211,19 +207,15 @@ static int ipcomp_output(struct sk_buff **pskb)
/* Install ipcomp header, convert into ipcomp datagram. */ /* Install ipcomp header, convert into ipcomp datagram. */
iph = (*pskb)->nh.iph; iph = (*pskb)->nh.iph;
memcpy(&tmp_iph, iph, iph->ihl * 4);
top_iph = (struct iphdr *)skb_push(*pskb, sizeof(struct ip_comp_hdr));
memcpy(top_iph, &tmp_iph, iph->ihl * 4);
iph = top_iph;
if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN)) if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
IP_ECN_clear(iph); IP_ECN_clear(iph);
iph->tot_len = htons((*pskb)->len); iph->tot_len = htons((*pskb)->len);
iph->protocol = IPPROTO_COMP;
iph->check = 0; iph->check = 0;
ipch = (struct ip_comp_hdr *)((char *)iph + iph->ihl * 4); ipch = (struct ip_comp_hdr *)((char *)iph + iph->ihl * 4);
ipch->nexthdr = x->props.mode ? IPPROTO_IPIP : tmp_iph.iph.protocol; ipch->nexthdr = x->props.mode ? IPPROTO_IPIP : iph->protocol;
ipch->flags = 0; ipch->flags = 0;
ipch->cpi = htons((u16 )ntohl(x->id.spi)); ipch->cpi = htons((u16 )ntohl(x->id.spi));
iph->protocol = IPPROTO_COMP;
ip_send_check(iph); ip_send_check(iph);
(*pskb)->nh.raw = (*pskb)->data; (*pskb)->nh.raw = (*pskb)->data;
...@@ -365,7 +357,7 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args) ...@@ -365,7 +357,7 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args)
goto error; goto error;
memset(ipcd, 0, sizeof(*ipcd)); memset(ipcd, 0, sizeof(*ipcd));
x->props.header_len = sizeof(struct ip_comp_hdr); x->props.header_len = 0;
if (x->props.mode) if (x->props.mode)
x->props.header_len += sizeof(struct iphdr); x->props.header_len += sizeof(struct iphdr);
......
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