Blame view
net/ipv4/xfrm4_mode_tunnel.c
2.96 KB
b59f45d0b [IPSEC] xfrm: Abs... |
1 2 3 4 5 |
/* * xfrm4_mode_tunnel.c - Tunnel mode encapsulation for IPv4. * * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> */ |
5a0e3ad6a include cleanup: ... |
6 |
#include <linux/gfp.h> |
b59f45d0b [IPSEC] xfrm: Abs... |
7 8 9 10 11 12 13 14 15 16 17 18 |
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/skbuff.h> #include <linux/stringify.h> #include <net/dst.h> #include <net/inet_ecn.h> #include <net/ip.h> #include <net/xfrm.h> static inline void ipip_ecn_decapsulate(struct sk_buff *skb) { |
b0061ce49 [SK_BUFF]: Introd... |
19 |
struct iphdr *inner_iph = ipip_hdr(skb); |
b59f45d0b [IPSEC] xfrm: Abs... |
20 |
|
227620e29 [IPSEC]: Separate... |
21 |
if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) |
b59f45d0b [IPSEC] xfrm: Abs... |
22 23 24 25 26 |
IP_ECN_set_ce(inner_iph); } /* Add encapsulation header. * |
ceb1eec82 [IPSEC]: Move IP ... |
27 |
* The top IP header will be constructed per RFC 2401. |
b59f45d0b [IPSEC] xfrm: Abs... |
28 |
*/ |
195ad6a3a [IPSEC]: Rename t... |
29 |
static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) |
b59f45d0b [IPSEC] xfrm: Abs... |
30 |
{ |
adf30907d net: skb->dst acc... |
31 |
struct dst_entry *dst = skb_dst(skb); |
36cf9acf9 [IPSEC]: Separate... |
32 |
struct iphdr *top_iph; |
b59f45d0b [IPSEC] xfrm: Abs... |
33 |
int flags; |
7b277b1a5 [IPSEC]: Set skb-... |
34 |
skb_set_network_header(skb, -x->props.header_len); |
37fedd3aa [IPSEC]: Use IPv6... |
35 36 |
skb->mac_header = skb->network_header + offsetof(struct iphdr, protocol); |
36cf9acf9 [IPSEC]: Separate... |
37 |
skb->transport_header = skb->network_header + sizeof(*top_iph); |
eddc9ec53 [SK_BUFF]: Introd... |
38 |
top_iph = ip_hdr(skb); |
b59f45d0b [IPSEC] xfrm: Abs... |
39 40 41 |
top_iph->ihl = 5; top_iph->version = 4; |
adf30907d net: skb->dst acc... |
42 |
top_iph->protocol = xfrm_af2proto(skb_dst(skb)->ops->family); |
c82f963ef [IPSEC]: IPv6 ove... |
43 |
|
b59f45d0b [IPSEC] xfrm: Abs... |
44 |
/* DS disclosed */ |
36cf9acf9 [IPSEC]: Separate... |
45 46 |
top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos, XFRM_MODE_SKB_CB(skb)->tos); |
b59f45d0b [IPSEC] xfrm: Abs... |
47 |
|
36cf9acf9 [IPSEC]: Separate... |
48 |
flags = x->props.flags; |
b59f45d0b [IPSEC] xfrm: Abs... |
49 50 |
if (flags & XFRM_STATE_NOECN) IP_ECN_clear(top_iph); |
36cf9acf9 [IPSEC]: Separate... |
51 |
top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? |
fe833fca2 xfrm: fix fragmen... |
52 |
0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); |
36cf9acf9 [IPSEC]: Separate... |
53 |
ip_select_ident(top_iph, dst->child, NULL); |
b59f45d0b [IPSEC] xfrm: Abs... |
54 |
|
323e126f0 ipv4: Don't pre-s... |
55 |
top_iph->ttl = ip4_dst_hoplimit(dst->child); |
b59f45d0b [IPSEC] xfrm: Abs... |
56 57 58 |
top_iph->saddr = x->props.saddr.a4; top_iph->daddr = x->id.daddr.a4; |
b59f45d0b [IPSEC] xfrm: Abs... |
59 |
|
b59f45d0b [IPSEC] xfrm: Abs... |
60 61 |
return 0; } |
195ad6a3a [IPSEC]: Rename t... |
62 |
static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) |
b59f45d0b [IPSEC] xfrm: Abs... |
63 |
{ |
39f69c6f9 [SK_BUFF] xfrm: U... |
64 |
const unsigned char *old_mac; |
b59f45d0b [IPSEC] xfrm: Abs... |
65 |
int err = -EINVAL; |
227620e29 [IPSEC]: Separate... |
66 67 |
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP) goto out; |
c82f963ef [IPSEC]: IPv6 ove... |
68 |
|
b59f45d0b [IPSEC] xfrm: Abs... |
69 70 71 72 73 74 |
if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto out; if (skb_cloned(skb) && (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) goto out; |
227620e29 [IPSEC]: Separate... |
75 76 77 78 |
if (x->props.flags & XFRM_STATE_DECAP_DSCP) ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb)); if (!(x->props.flags & XFRM_STATE_NOECN)) ipip_ecn_decapsulate(skb); |
98e399f82 [SK_BUFF]: Introd... |
79 |
old_mac = skb_mac_header(skb); |
39f69c6f9 [SK_BUFF] xfrm: U... |
80 |
skb_set_mac_header(skb, -skb->mac_len); |
98e399f82 [SK_BUFF]: Introd... |
81 |
memmove(skb_mac_header(skb), old_mac, skb->mac_len); |
c1d2bbe1c [SK_BUFF]: Introd... |
82 |
skb_reset_network_header(skb); |
b59f45d0b [IPSEC] xfrm: Abs... |
83 84 85 86 87 88 89 |
err = 0; out: return err; } static struct xfrm_mode xfrm4_tunnel_mode = { |
195ad6a3a [IPSEC]: Rename t... |
90 |
.input2 = xfrm4_mode_tunnel_input, |
227620e29 [IPSEC]: Separate... |
91 |
.input = xfrm_prepare_input, |
195ad6a3a [IPSEC]: Rename t... |
92 |
.output2 = xfrm4_mode_tunnel_output, |
36cf9acf9 [IPSEC]: Separate... |
93 |
.output = xfrm4_prepare_output, |
b59f45d0b [IPSEC] xfrm: Abs... |
94 95 |
.owner = THIS_MODULE, .encap = XFRM_MODE_TUNNEL, |
1bfcb10f6 [IPSEC]: Add miss... |
96 |
.flags = XFRM_MODE_FLAG_TUNNEL, |
b59f45d0b [IPSEC] xfrm: Abs... |
97 |
}; |
195ad6a3a [IPSEC]: Rename t... |
98 |
static int __init xfrm4_mode_tunnel_init(void) |
b59f45d0b [IPSEC] xfrm: Abs... |
99 100 101 |
{ return xfrm_register_mode(&xfrm4_tunnel_mode, AF_INET); } |
195ad6a3a [IPSEC]: Rename t... |
102 |
static void __exit xfrm4_mode_tunnel_exit(void) |
b59f45d0b [IPSEC] xfrm: Abs... |
103 104 105 106 107 108 |
{ int err; err = xfrm_unregister_mode(&xfrm4_tunnel_mode, AF_INET); BUG_ON(err); } |
195ad6a3a [IPSEC]: Rename t... |
109 110 |
module_init(xfrm4_mode_tunnel_init); module_exit(xfrm4_mode_tunnel_exit); |
b59f45d0b [IPSEC] xfrm: Abs... |
111 112 |
MODULE_LICENSE("GPL"); MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TUNNEL); |