#include <net/xfrm.h>
#include <net/mip6.h>
-static xfrm_address_t *mip6_xfrm_addr(struct xfrm_state *x, xfrm_address_t *addr)
-{
- return x->coaddr;
-}
-
static inline unsigned int calc_padlen(unsigned int len, unsigned int n)
{
return (n - len + 16) & 0x7;
{
struct ipv6hdr *iph = ipv6_hdr(skb);
struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
+ int err = destopt->nexthdr;
+ spin_lock(&x->lock);
if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) &&
!ipv6_addr_any((struct in6_addr *)x->coaddr))
- return -ENOENT;
+ err = -ENOENT;
+ spin_unlock(&x->lock);
- return destopt->nexthdr;
+ return err;
}
/* Destination Option Header is inserted.
u8 nexthdr;
int len;
+ skb_push(skb, -skb_network_offset(skb));
iph = ipv6_hdr(skb);
- iph->payload_len = htons(skb->len - sizeof(*iph));
nexthdr = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_DSTOPTS;
.description = "MIP6DESTOPT",
.owner = THIS_MODULE,
.proto = IPPROTO_DSTOPTS,
- .flags = XFRM_TYPE_NON_FRAGMENT,
+ .flags = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR,
.init_state = mip6_destopt_init_state,
.destructor = mip6_destopt_destroy,
.input = mip6_destopt_input,
.output = mip6_destopt_output,
.reject = mip6_destopt_reject,
.hdr_offset = mip6_destopt_offset,
- .local_addr = mip6_xfrm_addr,
};
static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
{
struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
+ int err = rt2->rt_hdr.nexthdr;
+ spin_lock(&x->lock);
if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) &&
!ipv6_addr_any((struct in6_addr *)x->coaddr))
- return -ENOENT;
+ err = -ENOENT;
+ spin_unlock(&x->lock);
- return rt2->rt_hdr.nexthdr;
+ return err;
}
/* Routing Header type 2 is inserted.
struct rt2_hdr *rt2;
u8 nexthdr;
+ skb_push(skb, -skb_network_offset(skb));
iph = ipv6_hdr(skb);
- iph->payload_len = htons(skb->len - sizeof(*iph));
nexthdr = *skb_mac_header(skb);
*skb_mac_header(skb) = IPPROTO_ROUTING;
.description = "MIP6RT",
.owner = THIS_MODULE,
.proto = IPPROTO_ROUTING,
- .flags = XFRM_TYPE_NON_FRAGMENT,
+ .flags = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR,
.init_state = mip6_rthdr_init_state,
.destructor = mip6_rthdr_destroy,
.input = mip6_rthdr_input,
.output = mip6_rthdr_output,
.hdr_offset = mip6_rthdr_offset,
- .remote_addr = mip6_xfrm_addr,
};
static int __init mip6_init(void)