aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2004-07-05 02:02:18 -0700
committerDavid S. Miller <davem@kernel.bkbits.net>2004-07-05 02:02:18 -0700
commit9ef1284b33efbe5da07badc3221f3b834bad1b8a (patch)
tree0be2355a60b4e0cb2e318aca8c52a161a2fdfa72 /net
parent5a5f73530cefd996f47cbbf3b74c4cac3fc9ea19 (diff)
downloadhistory-9ef1284b33efbe5da07badc3221f3b834bad1b8a.tar.gz
[AH4]: Harmonization of output function.
This is another step towards the union of the tunnel mode encapsulation between transforms. As there are significant differences between the tunnel encapsulation of IPv4 and IPv6, I'll be dealing with IPv4 only for now. This particular patch rearranges the code in ah_output to isolate the tunnel mode encapsulation. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/ah4.c38
1 files changed, 18 insertions, 20 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index b3d2aa9d2e302c..9bf3a59751811e 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -86,29 +86,23 @@ static int ah_output(struct sk_buff **pskb)
top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
top_iph->ihl = 5;
top_iph->version = 4;
- top_iph->tos = 0;
- top_iph->tot_len = htons((*pskb)->len);
- top_iph->frag_off = 0;
+ top_iph->tos = iph->tos;
+ if (x->props.flags & XFRM_STATE_NOECN)
+ IP_ECN_clear(top_iph);
+ top_iph->frag_off = iph->frag_off & ~htons(IP_MF|IP_OFFSET);
if (!(iph->frag_off&htons(IP_DF)))
__ip_select_ident(top_iph, dst, 0);
- top_iph->ttl = 0;
- top_iph->protocol = IPPROTO_AH;
- top_iph->check = 0;
+ top_iph->ttl = iph->ttl;
top_iph->saddr = x->props.saddr.a4;
top_iph->daddr = x->id.daddr.a4;
+ memcpy(&tmp_iph, top_iph, 20);
+ memset(&(IPCB(*pskb)->opt), 0, sizeof(struct ip_options));
ah = (struct ip_auth_hdr*)(top_iph+1);
ah->nexthdr = IPPROTO_IPIP;
} else {
memcpy(&tmp_iph, (*pskb)->data, iph->ihl*4);
top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
memcpy(top_iph, &tmp_iph, iph->ihl*4);
- iph = &tmp_iph.iph;
- top_iph->tos = 0;
- top_iph->tot_len = htons((*pskb)->len);
- top_iph->frag_off = 0;
- top_iph->ttl = 0;
- top_iph->protocol = IPPROTO_AH;
- top_iph->check = 0;
if (top_iph->ihl != 5) {
err = ip_clear_mutable_options(top_iph, &top_iph->daddr);
if (err)
@@ -117,6 +111,15 @@ static int ah_output(struct sk_buff **pskb)
ah = (struct ip_auth_hdr*)((char*)top_iph+iph->ihl*4);
ah->nexthdr = iph->protocol;
}
+
+ iph = &tmp_iph.iph;
+ top_iph->tos = 0;
+ top_iph->tot_len = htons((*pskb)->len);
+ top_iph->frag_off = 0;
+ top_iph->ttl = 0;
+ top_iph->protocol = IPPROTO_AH;
+ top_iph->check = 0;
+
ahp = x->data;
ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
ahp->icv_trunc_len) >> 2) - 2;
@@ -127,13 +130,8 @@ static int ah_output(struct sk_buff **pskb)
ahp->icv(ahp, *pskb, ah->auth_data);
top_iph->tos = iph->tos;
top_iph->ttl = iph->ttl;
- if (x->props.mode) {
- if (x->props.flags & XFRM_STATE_NOECN)
- IP_ECN_clear(top_iph);
- top_iph->frag_off = iph->frag_off&~htons(IP_MF|IP_OFFSET);
- memset(&(IPCB(*pskb)->opt), 0, sizeof(struct ip_options));
- } else {
- top_iph->frag_off = iph->frag_off;
+ top_iph->frag_off = iph->frag_off;
+ if (!x->props.mode) {
top_iph->daddr = iph->daddr;
if (iph->ihl != 5)
memcpy(top_iph+1, iph+1, iph->ihl*4 - sizeof(struct iphdr));