* patches
@ 2004-07-30 1:19 David S. Miller
2004-07-30 1:24 ` patches Herbert Xu
2004-07-30 1:26 ` patches Herbert Xu
0 siblings, 2 replies; 6+ messages in thread
From: David S. Miller @ 2004-07-30 1:19 UTC (permalink / raw)
To: herbert; +Cc: netdev, yoshfuji
The patches in the threads with subject:
1) [AH6] Rearrange routing headers
and
2) [IPSEC] Move generic encap code into xfrm6_output
I've simply lost track of. Herbert, can you resend the
patches that I should be reviewing and applying to
my tree?
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: patches
2004-07-30 1:19 patches David S. Miller
@ 2004-07-30 1:24 ` Herbert Xu
2004-07-30 2:20 ` patches David S. Miller
2004-07-30 1:26 ` patches Herbert Xu
1 sibling, 1 reply; 6+ messages in thread
From: Herbert Xu @ 2004-07-30 1:24 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, yoshfuji
[-- Attachment #1: Type: text/plain, Size: 540 bytes --]
On Thu, Jul 29, 2004 at 06:19:48PM -0700, David S. Miller wrote:
>
> I've simply lost track of. Herbert, can you resend the
> patches that I should be reviewing and applying to
> my tree?
Yes it has been a bit chaotic.
Here is the routing headers patch again.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[-- Attachment #2: p --]
[-- Type: text/plain, Size: 1877 bytes --]
===== net/ipv6/ah6.c 1.34 vs edited =====
--- 1.34/net/ipv6/ah6.c 2004-07-24 14:52:21 +10:00
+++ edited/net/ipv6/ah6.c 2004-07-24 18:35:47 +10:00
@@ -31,6 +31,7 @@
#include <net/ah.h>
#include <linux/crypto.h>
#include <linux/pfkeyv2.h>
+#include <linux/string.h>
#include <net/icmp.h>
#include <net/ipv6.h>
#include <net/xfrm.h>
@@ -74,6 +75,45 @@
return 0;
}
+/**
+ * ipv6_rearrange_rthdr - rearrange IPv6 routing header
+ * @iph: IPv6 header
+ * @rthdr: routing header
+ *
+ * Rearrange the destination address in @iph and the addresses in @rthdr
+ * so that they appear in the order they will at the final destination.
+ * See Appendix A2 of RFC 2402 for details.
+ */
+static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
+{
+ int segments, segments_left;
+ struct in6_addr *addrs;
+ struct in6_addr final_addr;
+
+ segments_left = rthdr->segments_left;
+ if (segments_left == 0)
+ return;
+ rthdr->segments_left = 0;
+
+ /* The value of rthdr->hdrlen has been verified either by the system
+ * call if it is locally generated, or by ipv6_rthdr_rcv() for incoming
+ * packets. So we can assume that it is even and that segments is
+ * greater than or equal to segments_left.
+ *
+ * For the same reason we can assume that this option is of type 0.
+ */
+ segments = rthdr->hdrlen >> 1;
+
+ addrs = ((struct rt0_hdr *)rthdr)->addr;
+ ipv6_addr_copy(&final_addr, addrs + segments - 1);
+
+ addrs += segments - segments_left;
+ memmove(addrs + 1, addrs, (segments_left - 1) * sizeof(*addrs));
+
+ ipv6_addr_copy(addrs, &iph->daddr);
+ ipv6_addr_copy(&iph->daddr, &final_addr);
+}
+
static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len)
{
union {
@@ -101,7 +141,7 @@
break;
case NEXTHDR_ROUTING:
- exthdr.rth->segments_left = 0;
+ ipv6_rearrange_rthdr(iph, exthdr.rth);
break;
default :
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: patches
2004-07-30 1:19 patches David S. Miller
2004-07-30 1:24 ` patches Herbert Xu
@ 2004-07-30 1:26 ` Herbert Xu
2004-07-30 2:30 ` patches David S. Miller
1 sibling, 1 reply; 6+ messages in thread
From: Herbert Xu @ 2004-07-30 1:26 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, yoshfuji
[-- Attachment #1: Type: text/plain, Size: 438 bytes --]
On Thu, Jul 29, 2004 at 06:19:48PM -0700, David S. Miller wrote:
>
> 2) [IPSEC] Move generic encap code into xfrm6_output
And here is the current gencap patch.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[-- Attachment #2: p --]
[-- Type: text/plain, Size: 17590 bytes --]
===== net/ipv6/Makefile 1.17 vs edited =====
--- 1.17/net/ipv6/Makefile 2004-06-18 15:25:06 +10:00
+++ edited/net/ipv6/Makefile 2004-07-29 07:33:44 +10:00
@@ -11,7 +11,7 @@
ip6_flowlabel.o ipv6_syms.o
ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
- xfrm6_tunnel.o
+ xfrm6_tunnel.o xfrm6_output.o
ipv6-objs += $(ipv6-y)
obj-$(CONFIG_INET6_AH) += ah6.o
===== net/ipv6/ah6.c 1.34 vs edited =====
--- 1.34/net/ipv6/ah6.c 2004-07-25 15:26:11 +10:00
+++ edited/net/ipv6/ah6.c 2004-07-29 07:33:44 +10:00
@@ -118,70 +118,55 @@
int ah6_output(struct sk_buff **pskb)
{
int err;
- int hdr_len = sizeof(struct ipv6hdr);
+ int extlen;
struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
- struct ipv6hdr *iph = NULL;
+ struct ipv6hdr *top_iph;
struct ip_auth_hdr *ah;
struct ah_data *ahp;
u8 nexthdr;
-
- if ((*pskb)->ip_summed == CHECKSUM_HW) {
- err = skb_checksum_help(pskb, 0);
- if (err)
- goto error_nolock;
- }
-
- spin_lock_bh(&x->lock);
- err = xfrm_state_check(x, *pskb);
- if (err)
- goto error;
-
- if (x->props.mode) {
- err = xfrm6_tunnel_check_size(*pskb);
- if (err)
- goto error;
-
- iph = (*pskb)->nh.ipv6h;
- (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
- (*pskb)->nh.ipv6h->version = 6;
- (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
- (*pskb)->nh.ipv6h->nexthdr = IPPROTO_AH;
- ipv6_addr_copy(&(*pskb)->nh.ipv6h->saddr,
- (struct in6_addr *) &x->props.saddr);
- ipv6_addr_copy(&(*pskb)->nh.ipv6h->daddr,
- (struct in6_addr *) &x->id.daddr);
- ah = (struct ip_auth_hdr*)((*pskb)->nh.ipv6h+1);
- ah->nexthdr = IPPROTO_IPV6;
- } else {
- u8 *prevhdr;
-
- hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
- nexthdr = *prevhdr;
- *prevhdr = IPPROTO_AH;
- iph = kmalloc(hdr_len, GFP_ATOMIC);
- if (!iph) {
+ char tmp_base[8];
+ struct {
+ struct in6_addr daddr;
+ char hdrs[0];
+ } *tmp_ext;
+
+ top_iph = (struct ipv6hdr *)(*pskb)->data;
+ top_iph->payload_len = htons((*pskb)->len - sizeof(*top_iph));
+
+ nexthdr = *(*pskb)->nh.raw;
+ *(*pskb)->nh.raw = IPPROTO_AH;
+
+ /* When there are no extension headers, we only need to save the first
+ * 8 bytes of the base IP header.
+ */
+ memcpy(tmp_base, top_iph, sizeof(tmp_base));
+
+ tmp_ext = NULL;
+ extlen = (*pskb)->h.raw - (unsigned char *)(top_iph + 1);
+ if (extlen) {
+ extlen += sizeof(*tmp_ext);
+ tmp_ext = kmalloc(extlen, GFP_ATOMIC);
+ if (!tmp_ext) {
err = -ENOMEM;
goto error;
}
- memcpy(iph, (*pskb)->data, hdr_len);
- (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
- iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
- memcpy((*pskb)->nh.ipv6h, iph, hdr_len);
- err = ipv6_clear_mutable_options((*pskb)->nh.ipv6h, hdr_len);
+ memcpy(tmp_ext, &top_iph->daddr, extlen);
+ err = ipv6_clear_mutable_options(top_iph,
+ extlen - sizeof(*tmp_ext) +
+ sizeof(*top_iph));
if (err)
goto error_free_iph;
-
- ah = (struct ip_auth_hdr*)((*pskb)->nh.raw+hdr_len);
- (*pskb)->h.raw = (unsigned char*) ah;
- ah->nexthdr = nexthdr;
}
- (*pskb)->nh.ipv6h->priority = 0;
- (*pskb)->nh.ipv6h->flow_lbl[0] = 0;
- (*pskb)->nh.ipv6h->flow_lbl[1] = 0;
- (*pskb)->nh.ipv6h->flow_lbl[2] = 0;
- (*pskb)->nh.ipv6h->hop_limit = 0;
+ ah = (struct ip_auth_hdr *)(*pskb)->h.raw;
+ ah->nexthdr = nexthdr;
+
+ top_iph->priority = 0;
+ top_iph->flow_lbl[0] = 0;
+ top_iph->flow_lbl[1] = 0;
+ top_iph->flow_lbl[2] = 0;
+ top_iph->hop_limit = 0;
ahp = x->data;
ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) +
@@ -192,35 +177,16 @@
ah->seq_no = htonl(++x->replay.oseq);
ahp->icv(ahp, *pskb, ah->auth_data);
- if (x->props.mode) {
- (*pskb)->nh.ipv6h->hop_limit = iph->hop_limit;
- (*pskb)->nh.ipv6h->priority = iph->priority;
- (*pskb)->nh.ipv6h->flow_lbl[0] = iph->flow_lbl[0];
- (*pskb)->nh.ipv6h->flow_lbl[1] = iph->flow_lbl[1];
- (*pskb)->nh.ipv6h->flow_lbl[2] = iph->flow_lbl[2];
- if (x->props.flags & XFRM_STATE_NOECN)
- IP6_ECN_clear((*pskb)->nh.ipv6h);
- } else {
- memcpy((*pskb)->nh.ipv6h, iph, hdr_len);
- kfree (iph);
- }
-
- (*pskb)->nh.raw = (*pskb)->data;
+ err = 0;
- x->curlft.bytes += (*pskb)->len;
- x->curlft.packets++;
- spin_unlock_bh(&x->lock);
- if (((*pskb)->dst = dst_pop(dst)) == NULL) {
- err = -EHOSTUNREACH;
- goto error_nolock;
- }
- return NET_XMIT_BYPASS;
+ memcpy(top_iph, tmp_base, sizeof(tmp_base));
+ if (tmp_ext) {
+ memcpy(&top_iph->daddr, tmp_ext, extlen);
error_free_iph:
- kfree(iph);
+ kfree(tmp_ext);
+ }
+
error:
- spin_unlock_bh(&x->lock);
-error_nolock:
- kfree_skb(*pskb);
return err;
}
===== net/ipv6/esp6.c 1.30 vs edited =====
--- 1.30/net/ipv6/esp6.c 2004-06-23 06:53:57 +10:00
+++ edited/net/ipv6/esp6.c 2004-07-29 07:33:44 +10:00
@@ -41,10 +41,10 @@
int esp6_output(struct sk_buff **pskb)
{
int err;
- int hdr_len = 0;
+ int hdr_len;
struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
- struct ipv6hdr *iph = NULL, *top_iph;
+ struct ipv6hdr *top_iph;
struct ipv6_esp_hdr *esph;
struct crypto_tfm *tfm;
struct esp_data *esp;
@@ -53,37 +53,13 @@
int clen;
int alen;
int nfrags;
- u8 *prevhdr;
- u8 nexthdr = 0;
- if ((*pskb)->ip_summed == CHECKSUM_HW) {
- err = skb_checksum_help(pskb, 0);
- if (err)
- goto error_nolock;
- }
-
- spin_lock_bh(&x->lock);
- err = xfrm_state_check(x, *pskb);
- if (err)
- goto error;
+ esp = x->data;
+ hdr_len = (*pskb)->h.raw - (*pskb)->data +
+ sizeof(*esph) + esp->conf.ivlen;
- if (x->props.mode) {
- err = xfrm6_tunnel_check_size(*pskb);
- if (err)
- goto error;
- } else {
- /* Strip IP header in transport mode. Save it. */
- hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
- nexthdr = *prevhdr;
- *prevhdr = IPPROTO_ESP;
- iph = kmalloc(hdr_len, GFP_ATOMIC);
- if (!iph) {
- err = -ENOMEM;
- goto error;
- }
- memcpy(iph, (*pskb)->nh.raw, hdr_len);
- __skb_pull(*pskb, hdr_len);
- }
+ /* Strip IP+ESP header. */
+ __skb_pull(*pskb, hdr_len);
/* Now skb is pure payload to encrypt */
err = -ENOMEM;
@@ -91,7 +67,6 @@
/* Round to block size */
clen = (*pskb)->len;
- esp = x->data;
alen = esp->auth.icv_trunc_len;
tfm = esp->conf.tfm;
blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3;
@@ -100,7 +75,6 @@
clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
if ((nfrags = skb_cow_data(*pskb, clen-(*pskb)->len+alen, &trailer)) < 0) {
- if (!x->props.mode && iph) kfree(iph);
goto error;
}
@@ -113,34 +87,11 @@
*(u8*)(trailer->tail + clen-(*pskb)->len - 2) = (clen - (*pskb)->len)-2;
pskb_put(*pskb, trailer, clen - (*pskb)->len);
- if (x->props.mode) {
- iph = (*pskb)->nh.ipv6h;
- top_iph = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
- esph = (struct ipv6_esp_hdr*)(top_iph+1);
- *(u8*)(trailer->tail - 1) = IPPROTO_IPV6;
- top_iph->version = 6;
- top_iph->priority = iph->priority;
- top_iph->flow_lbl[0] = iph->flow_lbl[0];
- top_iph->flow_lbl[1] = iph->flow_lbl[1];
- top_iph->flow_lbl[2] = iph->flow_lbl[2];
- if (x->props.flags & XFRM_STATE_NOECN)
- IP6_ECN_clear(top_iph);
- top_iph->nexthdr = IPPROTO_ESP;
- top_iph->payload_len = htons((*pskb)->len + alen - sizeof(struct ipv6hdr));
- top_iph->hop_limit = iph->hop_limit;
- ipv6_addr_copy(&top_iph->saddr,
- (struct in6_addr *)&x->props.saddr);
- ipv6_addr_copy(&top_iph->daddr,
- (struct in6_addr *)&x->id.daddr);
- } else {
- esph = (struct ipv6_esp_hdr*)skb_push(*pskb, x->props.header_len);
- (*pskb)->h.raw = (unsigned char*)esph;
- top_iph = (struct ipv6hdr*)skb_push(*pskb, hdr_len);
- memcpy(top_iph, iph, hdr_len);
- kfree(iph);
- top_iph->payload_len = htons((*pskb)->len + alen - sizeof(struct ipv6hdr));
- *(u8*)(trailer->tail - 1) = nexthdr;
- }
+ top_iph = (struct ipv6hdr *)__skb_push(*pskb, hdr_len);
+ esph = (struct ipv6_esp_hdr *)(*pskb)->h.raw;
+ top_iph->payload_len = htons((*pskb)->len + alen - sizeof(*top_iph));
+ *(u8*)(trailer->tail - 1) = *(*pskb)->nh.raw;
+ *(*pskb)->nh.raw = IPPROTO_ESP;
esph->spi = x->id.spi;
esph->seq_no = htonl(++x->replay.oseq);
@@ -173,21 +124,9 @@
pskb_put(*pskb, trailer, alen);
}
- (*pskb)->nh.raw = (*pskb)->data;
-
- x->curlft.bytes += (*pskb)->len;
- x->curlft.packets++;
- spin_unlock_bh(&x->lock);
- if (((*pskb)->dst = dst_pop(dst)) == NULL) {
- err = -EHOSTUNREACH;
- goto error_nolock;
- }
- return NET_XMIT_BYPASS;
+ err = 0;
error:
- spin_unlock_bh(&x->lock);
-error_nolock:
- kfree_skb(*pskb);
return err;
}
===== net/ipv6/ipcomp6.c 1.13 vs edited =====
--- 1.13/net/ipv6/ipcomp6.c 2004-07-23 05:14:21 +10:00
+++ edited/net/ipv6/ipcomp6.c 2004-07-29 07:33:44 +10:00
@@ -123,52 +123,14 @@
int err;
struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
- struct ipv6hdr *iph, *top_iph;
- int hdr_len = 0;
+ struct ipv6hdr *top_iph;
+ int hdr_len;
struct ipv6_comp_hdr *ipch;
struct ipcomp_data *ipcd = x->data;
- u8 *prevhdr;
- u8 nexthdr = 0;
int plen, dlen;
u8 *start, *scratch = ipcd->scratch;
- if ((*pskb)->ip_summed == CHECKSUM_HW) {
- err = skb_checksum_help(pskb, 0);
- if (err)
- goto error_nolock;
- }
-
- spin_lock_bh(&x->lock);
-
- err = xfrm_state_check(x, *pskb);
- if (err)
- goto error;
-
- if (x->props.mode) {
- err = xfrm6_tunnel_check_size(*pskb);
- if (err)
- goto error;
-
- hdr_len = sizeof(struct ipv6hdr);
- nexthdr = IPPROTO_IPV6;
- iph = (*pskb)->nh.ipv6h;
- top_iph = (struct ipv6hdr *)skb_push(*pskb, sizeof(struct ipv6hdr));
- top_iph->version = 6;
- top_iph->priority = iph->priority;
- top_iph->flow_lbl[0] = iph->flow_lbl[0];
- top_iph->flow_lbl[1] = iph->flow_lbl[1];
- top_iph->flow_lbl[2] = iph->flow_lbl[2];
- top_iph->nexthdr = IPPROTO_IPV6; /* initial */
- top_iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
- top_iph->hop_limit = iph->hop_limit;
- memcpy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr, sizeof(struct in6_addr));
- memcpy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr, sizeof(struct in6_addr));
- (*pskb)->nh.raw = (*pskb)->data; /* == top_iph */
- (*pskb)->h.raw = (*pskb)->nh.raw + hdr_len;
- } else {
- hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
- nexthdr = *prevhdr;
- }
+ hdr_len = (*pskb)->h.raw - (*pskb)->data;
/* check whether datagram len is larger than threshold */
if (((*pskb)->len - hdr_len) < ipcd->threshold) {
@@ -184,7 +146,7 @@
/* compression */
plen = (*pskb)->len - hdr_len;
dlen = IPCOMP_SCRATCH_SIZE;
- start = (*pskb)->data + hdr_len;
+ start = (*pskb)->h.raw;
err = crypto_comp_compress(ipcd->tfm, start, plen, scratch, &dlen);
if (err) {
@@ -197,39 +159,21 @@
pskb_trim(*pskb, hdr_len + dlen + sizeof(struct ip_comp_hdr));
/* insert ipcomp header and replace datagram */
- top_iph = (*pskb)->nh.ipv6h;
+ top_iph = (struct ipv6hdr *)(*pskb)->data;
- if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
- IP6_ECN_clear(top_iph);
top_iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
- (*pskb)->nh.raw = (*pskb)->data; /* top_iph */
- ip6_find_1stfragopt(*pskb, &prevhdr);
- *prevhdr = IPPROTO_COMP;
- ipch = (struct ipv6_comp_hdr *)((unsigned char *)top_iph + hdr_len);
- ipch->nexthdr = nexthdr;
+ ipch = (struct ipv6_comp_hdr *)start;
+ ipch->nexthdr = *(*pskb)->nh.raw;
ipch->flags = 0;
ipch->cpi = htons((u16 )ntohl(x->id.spi));
+ *(*pskb)->nh.raw = IPPROTO_COMP;
- (*pskb)->h.raw = (unsigned char*)ipch;
out_ok:
- x->curlft.bytes += (*pskb)->len;
- x->curlft.packets++;
- spin_unlock_bh(&x->lock);
-
- if (((*pskb)->dst = dst_pop(dst)) == NULL) {
- err = -EHOSTUNREACH;
- goto error_nolock;
- }
- err = NET_XMIT_BYPASS;
+ err = 0;
-out_exit:
- return err;
error:
- spin_unlock_bh(&x->lock);
-error_nolock:
- kfree_skb(*pskb);
- goto out_exit;
+ return err;
}
static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
===== net/ipv6/xfrm6_policy.c 1.19 vs edited =====
--- 1.19/net/ipv6/xfrm6_policy.c 2004-06-18 15:25:06 +10:00
+++ edited/net/ipv6/xfrm6_policy.c 2004-07-29 07:33:44 +10:00
@@ -157,7 +157,7 @@
/* Copy neighbour for reachability confirmation */
dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
dst_prev->input = rt->u.dst.input;
- dst_prev->output = dst_prev->xfrm->type->output;
+ dst_prev->output = xfrm6_output;
/* Sheit... I remember I did this right. Apparently,
* it was magically lost, so this code needs audit */
x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
===== net/ipv6/xfrm6_tunnel.c 1.2 vs edited =====
--- 1.2/net/ipv6/xfrm6_tunnel.c 2004-06-20 05:48:05 +10:00
+++ edited/net/ipv6/xfrm6_tunnel.c 2004-07-29 07:33:44 +10:00
@@ -365,46 +365,12 @@
static int xfrm6_tunnel_output(struct sk_buff **pskb)
{
struct sk_buff *skb = *pskb;
- struct dst_entry *dst = skb->dst;
- struct xfrm_state *x = dst->xfrm;
- struct ipv6hdr *iph, *top_iph;
- int err;
+ struct ipv6hdr *top_iph;
- if ((err = xfrm6_tunnel_check_size(skb)) != 0)
- goto error_nolock;
-
- iph = skb->nh.ipv6h;
-
- top_iph = (struct ipv6hdr *)skb_push(skb, x->props.header_len);
- top_iph->version = 6;
- top_iph->priority = iph->priority;
- top_iph->flow_lbl[0] = iph->flow_lbl[0];
- top_iph->flow_lbl[1] = iph->flow_lbl[1];
- top_iph->flow_lbl[2] = iph->flow_lbl[2];
- top_iph->nexthdr = IPPROTO_IPV6;
+ top_iph = (struct ipv6hdr *)skb->data;
top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
- top_iph->hop_limit = iph->hop_limit;
- memcpy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr, sizeof(struct in6_addr));
- memcpy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr, sizeof(struct in6_addr));
- skb->nh.raw = skb->data;
- skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
-
- x->curlft.bytes += skb->len;
- x->curlft.packets++;
-
- spin_unlock_bh(&x->lock);
-
- if ((skb->dst = dst_pop(dst)) == NULL) {
- kfree_skb(skb);
- err = -EHOSTUNREACH;
- goto error_nolock;
- }
-
- return NET_XMIT_BYPASS;
-error_nolock:
- kfree_skb(skb);
- return err;
+ return 0;
}
static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
--- /dev/null 2004-06-14 11:16:19.000000000 +1000
+++ linux-2.6/net/ipv6/xfrm6_output.c 2004-07-29 07:33:47.000000000 +1000
@@ -0,0 +1,123 @@
+/*
+ * xfrm6_output.c - Common IPsec encapsulation code for IPv6.
+ * Copyright (C) 2002 USAGI/WIDE Project
+ * Copyright (c) 2004 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <net/inet_ecn.h>
+#include <net/ipv6.h>
+#include <net/xfrm.h>
+
+/* Add encapsulation header.
+ *
+ * In transport mode, the IP header and mutable extension headers will be moved
+ * forward to make space for the encapsulation header.
+ *
+ * In tunnel mode, the top IP header will be constructed per RFC 2401.
+ * The following fields in it shall be filled in by x->type->output:
+ * payload_len
+ *
+ * On exit, skb->h will be set to the start of the encapsulation header to be
+ * filled in by x->type->output and skb->nh will be set to the nextheader field
+ * of the extension header directly preceding the encapsulation header, or in
+ * its absence, that of the top IP header. The value of skb->data will always
+ * point to the top IP header.
+ */
+static void xfrm6_encap(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb->dst;
+ struct xfrm_state *x = dst->xfrm;
+ struct ipv6hdr *iph, *top_iph;
+
+ skb_push(skb, x->props.header_len);
+ iph = skb->nh.ipv6h;
+
+ if (!x->props.mode) {
+ u8 *prevhdr;
+ int hdr_len;
+
+ hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+ skb->nh.raw = prevhdr - x->props.header_len;
+ skb->h.raw = skb->data + hdr_len;
+ memmove(skb->data, iph, hdr_len);
+ return;
+ }
+
+ skb->nh.raw = skb->data;
+ top_iph = skb->nh.ipv6h;
+ skb->nh.raw = &top_iph->nexthdr;
+ skb->h.ipv6h = top_iph + 1;
+
+ top_iph->version = 6;
+ top_iph->priority = iph->priority;
+ if (x->props.flags & XFRM_STATE_NOECN)
+ IP6_ECN_clear(top_iph);
+ top_iph->flow_lbl[0] = iph->flow_lbl[0];
+ top_iph->flow_lbl[1] = iph->flow_lbl[1];
+ top_iph->flow_lbl[2] = iph->flow_lbl[2];
+ top_iph->nexthdr = IPPROTO_IPV6;
+ top_iph->hop_limit = iph->hop_limit;
+ ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+ ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
+}
+
+int xfrm6_output(struct sk_buff **pskb)
+{
+ struct sk_buff *skb = *pskb;
+ struct dst_entry *dst = skb->dst;
+ struct xfrm_state *x = dst->xfrm;
+ int err;
+
+ if (skb->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(pskb, 0);
+ skb = *pskb;
+ if (err)
+ goto error_nolock;
+ }
+
+ spin_lock_bh(&x->lock);
+ err = xfrm_state_check(x, skb);
+ if (err)
+ goto error;
+
+ if (x->props.mode) {
+ err = xfrm6_tunnel_check_size(skb);
+ if (err)
+ goto error;
+ }
+
+ xfrm6_encap(skb);
+
+ err = x->type->output(pskb);
+ skb = *pskb;
+ if (err)
+ goto error;
+
+ x->curlft.bytes += skb->len;
+ x->curlft.packets++;
+
+ spin_unlock_bh(&x->lock);
+
+ skb->nh.raw = skb->data;
+
+ if (!(skb->dst = dst_pop(dst))) {
+ err = -EHOSTUNREACH;
+ goto error_nolock;
+ }
+ err = NET_XMIT_BYPASS;
+
+out_exit:
+ return err;
+error:
+ spin_unlock_bh(&x->lock);
+error_nolock:
+ kfree_skb(skb);
+ goto out_exit;
+}
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: patches
2004-07-30 1:24 ` patches Herbert Xu
@ 2004-07-30 2:20 ` David S. Miller
2004-07-30 2:22 ` patches Herbert Xu
0 siblings, 1 reply; 6+ messages in thread
From: David S. Miller @ 2004-07-30 2:20 UTC (permalink / raw)
To: Herbert Xu; +Cc: netdev, yoshfuji
On Fri, 30 Jul 2004 11:24:31 +1000
Herbert Xu <herbert@gondor.apana.org.au> wrote:
> Here is the routing headers patch again.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Applied.
Based upon reading of the rest of the thread about
this patch I understand that:
1) Direction checking suggested by Yoshifuji is unecessary
because on input segments_left will be zero in the type 0
routing header.
2) Both ipv4 and ipv6 erroneously do the xfrm route lookup
using the first hop destination not the final destination.
And this needs to be fixed with a followon patch.
Is this correct?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: patches
2004-07-30 2:20 ` patches David S. Miller
@ 2004-07-30 2:22 ` Herbert Xu
0 siblings, 0 replies; 6+ messages in thread
From: Herbert Xu @ 2004-07-30 2:22 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, yoshfuji
On Thu, Jul 29, 2004 at 07:20:46PM -0700, David S. Miller wrote:
>
> Based upon reading of the rest of the thread about
> this patch I understand that:
>
> 1) Direction checking suggested by Yoshifuji is unecessary
> because on input segments_left will be zero in the type 0
> routing header.
>
> 2) Both ipv4 and ipv6 erroneously do the xfrm route lookup
> using the first hop destination not the final destination.
> And this needs to be fixed with a followon patch.
>
> Is this correct?
Yes.
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: patches
2004-07-30 1:26 ` patches Herbert Xu
@ 2004-07-30 2:30 ` David S. Miller
0 siblings, 0 replies; 6+ messages in thread
From: David S. Miller @ 2004-07-30 2:30 UTC (permalink / raw)
To: Herbert Xu; +Cc: netdev, yoshfuji
On Fri, 30 Jul 2004 11:26:02 +1000
Herbert Xu <herbert@gondor.apana.org.au> wrote:
> On Thu, Jul 29, 2004 at 06:19:48PM -0700, David S. Miller wrote:
> >
> > 2) [IPSEC] Move generic encap code into xfrm6_output
>
> And here is the current gencap patch.
I like this patch very much. Great cleanup Herbert.
Applied.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-07-30 2:30 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-30 1:19 patches David S. Miller
2004-07-30 1:24 ` patches Herbert Xu
2004-07-30 2:20 ` patches David S. Miller
2004-07-30 2:22 ` patches Herbert Xu
2004-07-30 1:26 ` patches Herbert Xu
2004-07-30 2:30 ` patches David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).