Blame view
net/ipv6/xfrm6_mode_tunnel.c
3.03 KB
b59f45d0b [IPSEC] xfrm: Abs... |
1 2 3 4 5 6 |
/* * xfrm6_mode_tunnel.c - Tunnel mode encapsulation for IPv6. * * Copyright (C) 2002 USAGI/WIDE Project * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> */ |
5a0e3ad6a include cleanup: ... |
7 |
#include <linux/gfp.h> |
b59f45d0b [IPSEC] xfrm: Abs... |
8 9 10 11 12 13 14 15 |
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/skbuff.h> #include <linux/stringify.h> #include <net/dsfield.h> #include <net/dst.h> #include <net/inet_ecn.h> |
abbf46ae0 ipv6: Use ip6_dst... |
16 |
#include <net/ip6_route.h> |
b59f45d0b [IPSEC] xfrm: Abs... |
17 18 19 20 21 |
#include <net/ipv6.h> #include <net/xfrm.h> static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) { |
b71d1d426 inet: constify ip... |
22 |
const struct ipv6hdr *outer_iph = ipv6_hdr(skb); |
39b89160d [SK_BUFF]: Introd... |
23 |
struct ipv6hdr *inner_iph = ipipv6_hdr(skb); |
b59f45d0b [IPSEC] xfrm: Abs... |
24 25 26 27 28 29 30 |
if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) IP6_ECN_set_ce(inner_iph); } /* Add encapsulation header. * |
ceb1eec82 [IPSEC]: Move IP ... |
31 |
* The top IP header will be constructed per RFC 2401. |
b59f45d0b [IPSEC] xfrm: Abs... |
32 |
*/ |
195ad6a3a [IPSEC]: Rename t... |
33 |
static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) |
b59f45d0b [IPSEC] xfrm: Abs... |
34 |
{ |
adf30907d net: skb->dst acc... |
35 |
struct dst_entry *dst = skb_dst(skb); |
36cf9acf9 [IPSEC]: Separate... |
36 |
struct ipv6hdr *top_iph; |
b59f45d0b [IPSEC] xfrm: Abs... |
37 |
int dsfield; |
7b277b1a5 [IPSEC]: Set skb-... |
38 |
skb_set_network_header(skb, -x->props.header_len); |
37fedd3aa [IPSEC]: Use IPv6... |
39 40 |
skb->mac_header = skb->network_header + offsetof(struct ipv6hdr, nexthdr); |
36cf9acf9 [IPSEC]: Separate... |
41 |
skb->transport_header = skb->network_header + sizeof(*top_iph); |
0660e03f6 [SK_BUFF]: Introd... |
42 |
top_iph = ipv6_hdr(skb); |
b59f45d0b [IPSEC] xfrm: Abs... |
43 44 |
top_iph->version = 6; |
36cf9acf9 [IPSEC]: Separate... |
45 46 47 |
memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl, sizeof(top_iph->flow_lbl)); |
adf30907d net: skb->dst acc... |
48 |
top_iph->nexthdr = xfrm_af2proto(skb_dst(skb)->ops->family); |
36cf9acf9 [IPSEC]: Separate... |
49 |
|
a947b0a93 xfrm: allow to av... |
50 51 52 53 54 |
if (x->props.extra_flags & XFRM_SA_XFLAG_DONT_ENCAP_DSCP) dsfield = 0; else dsfield = XFRM_MODE_SKB_CB(skb)->tos; dsfield = INET_ECN_encapsulate(dsfield, XFRM_MODE_SKB_CB(skb)->tos); |
b59f45d0b [IPSEC] xfrm: Abs... |
55 56 57 |
if (x->props.flags & XFRM_STATE_NOECN) dsfield &= ~INET_ECN_MASK; ipv6_change_dsfield(top_iph, 0, dsfield); |
abbf46ae0 ipv6: Use ip6_dst... |
58 |
top_iph->hop_limit = ip6_dst_hoplimit(dst->child); |
4e3fd7a06 net: remove ipv6_... |
59 60 |
top_iph->saddr = *(struct in6_addr *)&x->props.saddr; top_iph->daddr = *(struct in6_addr *)&x->id.daddr; |
b59f45d0b [IPSEC] xfrm: Abs... |
61 62 |
return 0; } |
195ad6a3a [IPSEC]: Rename t... |
63 |
static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) |
b59f45d0b [IPSEC] xfrm: Abs... |
64 65 |
{ int err = -EINVAL; |
227620e29 [IPSEC]: Separate... |
66 |
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) |
b59f45d0b [IPSEC] xfrm: Abs... |
67 68 69 |
goto out; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto out; |
0d4bfa297 ipv6: fix warning... |
70 71 |
err = skb_unclone(skb, GFP_ATOMIC); if (err) |
b59f45d0b [IPSEC] xfrm: Abs... |
72 |
goto out; |
227620e29 [IPSEC]: Separate... |
73 74 75 76 77 |
if (x->props.flags & XFRM_STATE_DECAP_DSCP) ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)), ipipv6_hdr(skb)); if (!(x->props.flags & XFRM_STATE_NOECN)) ipip6_ecn_decapsulate(skb); |
c1d2bbe1c [SK_BUFF]: Introd... |
78 |
skb_reset_network_header(skb); |
03606895c ipsec: be careful... |
79 |
skb_mac_header_rebuild(skb); |
b59f45d0b [IPSEC] xfrm: Abs... |
80 81 82 83 84 85 86 |
err = 0; out: return err; } static struct xfrm_mode xfrm6_tunnel_mode = { |
195ad6a3a [IPSEC]: Rename t... |
87 |
.input2 = xfrm6_mode_tunnel_input, |
227620e29 [IPSEC]: Separate... |
88 |
.input = xfrm_prepare_input, |
195ad6a3a [IPSEC]: Rename t... |
89 |
.output2 = xfrm6_mode_tunnel_output, |
36cf9acf9 [IPSEC]: Separate... |
90 |
.output = xfrm6_prepare_output, |
b59f45d0b [IPSEC] xfrm: Abs... |
91 92 |
.owner = THIS_MODULE, .encap = XFRM_MODE_TUNNEL, |
1bfcb10f6 [IPSEC]: Add miss... |
93 |
.flags = XFRM_MODE_FLAG_TUNNEL, |
b59f45d0b [IPSEC] xfrm: Abs... |
94 |
}; |
195ad6a3a [IPSEC]: Rename t... |
95 |
static int __init xfrm6_mode_tunnel_init(void) |
b59f45d0b [IPSEC] xfrm: Abs... |
96 97 98 |
{ return xfrm_register_mode(&xfrm6_tunnel_mode, AF_INET6); } |
195ad6a3a [IPSEC]: Rename t... |
99 |
static void __exit xfrm6_mode_tunnel_exit(void) |
b59f45d0b [IPSEC] xfrm: Abs... |
100 101 102 103 104 105 |
{ int err; err = xfrm_unregister_mode(&xfrm6_tunnel_mode, AF_INET6); BUG_ON(err); } |
195ad6a3a [IPSEC]: Rename t... |
106 107 |
module_init(xfrm6_mode_tunnel_init); module_exit(xfrm6_mode_tunnel_exit); |
b59f45d0b [IPSEC] xfrm: Abs... |
108 109 |
MODULE_LICENSE("GPL"); MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_TUNNEL); |