[XFRM] STATE: Add a hook to find offset to be inserted header in outbound.
authorMasahide NAKAMURA <nakam@linux-ipv6.org>
Thu, 24 Aug 2006 00:57:28 +0000 (17:57 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Fri, 22 Sep 2006 22:06:36 +0000 (15:06 -0700)
On current kernel, ip6_find_1stfragopt() is used by IPv6 IPsec to find
offset to be inserted header in outbound for transport mode. (BTW, no
usage may be needed for IPv4 case.)  Mobile IPv6 requires another
logic for routing header and destination options header
respectively. This patch is common platform for the offset and adopts
it to IPsec.

Based on MIPL2 kernel patch.

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/xfrm.h
net/ipv6/ah6.c
net/ipv6/esp6.c
net/ipv6/ipcomp6.c
net/ipv6/ipv6_syms.c
net/ipv6/xfrm6_mode_transport.c
net/ipv6/xfrm6_output.c

index d9c40e713184b9adc3e3fad4cef3d061db2db449..eed48f832ce150772b437bd21a5f8e2b611680f0 100644 (file)
@@ -265,6 +265,7 @@ struct xfrm_type
        void                    (*destructor)(struct xfrm_state *);
        int                     (*input)(struct xfrm_state *, struct sk_buff *skb);
        int                     (*output)(struct xfrm_state *, struct sk_buff *pskb);
+       int                     (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
        /* Estimate maximal size of result of transformation of a dgram */
        u32                     (*get_max_size)(struct xfrm_state *, int size);
 };
@@ -960,6 +961,8 @@ extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
 extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
 extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
 extern int xfrm6_output(struct sk_buff *skb);
+extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
+                                u8 **prevhdr);
 
 #ifdef CONFIG_XFRM
 extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type);
index 60954fc7eb36eb0a013e661248a647e10352651e..6c0aa51319a55049b65db1bcb8101bc8fb3e777a 100644 (file)
@@ -435,7 +435,8 @@ static struct xfrm_type ah6_type =
        .init_state     = ah6_init_state,
        .destructor     = ah6_destroy,
        .input          = ah6_input,
-       .output         = ah6_output
+       .output         = ah6_output,
+       .hdr_offset     = xfrm6_find_1stfragopt,
 };
 
 static struct inet6_protocol ah6_protocol = {
index 2b8e52e1d0ab87b6d936bbce9d2d258c935f76d5..ae50b95111510cb2c978fd93d0ffa0a69fc1d93d 100644 (file)
@@ -379,7 +379,8 @@ static struct xfrm_type esp6_type =
        .destructor     = esp6_destroy,
        .get_max_size   = esp6_get_max_size,
        .input          = esp6_input,
-       .output         = esp6_output
+       .output         = esp6_output,
+       .hdr_offset     = xfrm6_find_1stfragopt,
 };
 
 static struct inet6_protocol esp6_protocol = {
index 19eba8d9f851e38d7f69f0a2354c09361b19f52e..ad9c6e824e629e02c8c37a4e17c94ea5dab50b35 100644 (file)
@@ -461,6 +461,7 @@ static struct xfrm_type ipcomp6_type =
        .destructor     = ipcomp6_destroy,
        .input          = ipcomp6_input,
        .output         = ipcomp6_output,
+       .hdr_offset     = xfrm6_find_1stfragopt,
 };
 
 static struct inet6_protocol ipcomp6_protocol = 
index dd4d1ce777699e66b57f2bfd097c09a4cbe000ea..e1a741612888acd75b99a2d338080222de7fa155 100644 (file)
@@ -31,6 +31,7 @@ EXPORT_SYMBOL(ipv6_chk_addr);
 EXPORT_SYMBOL(in6_dev_finish_destroy);
 #ifdef CONFIG_XFRM
 EXPORT_SYMBOL(xfrm6_rcv);
+EXPORT_SYMBOL(xfrm6_find_1stfragopt);
 #endif
 EXPORT_SYMBOL(rt6_lookup);
 EXPORT_SYMBOL(ipv6_push_nfrag_opts);
index 711d713e36d843228b4ef71a00e472c8df443994..a5dce216024d5725851f1069c081bb09e29cb905 100644 (file)
@@ -35,7 +35,7 @@ static int xfrm6_transport_output(struct sk_buff *skb)
        skb_push(skb, x->props.header_len);
        iph = skb->nh.ipv6h;
 
-       hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+       hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
        skb->nh.raw = prevhdr - x->props.header_len;
        skb->h.raw = skb->data + hdr_len;
        memmove(skb->data, iph, hdr_len);
index 26f18869f77b1376708d4deadb61e36269df4009..b4628fbf8ff598013f484147286a98fbe62653ff 100644 (file)
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
+int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
+                         u8 **prevhdr)
+{
+       return ip6_find_1stfragopt(skb, prevhdr);
+}
+
 static int xfrm6_tunnel_check_size(struct sk_buff *skb)
 {
        int mtu, ret = 0;