Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
ipv4
xfrm4_output.c
Go to the documentation of this file.
1
/*
2
* xfrm4_output.c - Common IPsec encapsulation code for IPv4.
3
* Copyright (c) 2004 Herbert Xu <
[email protected]
>
4
*
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version
8
* 2 of the License, or (at your option) any later version.
9
*/
10
11
#include <linux/if_ether.h>
12
#include <linux/kernel.h>
13
#include <linux/module.h>
14
#include <
linux/skbuff.h
>
15
#include <linux/netfilter_ipv4.h>
16
#include <
net/dst.h
>
17
#include <
net/ip.h
>
18
#include <
net/xfrm.h
>
19
#include <
net/icmp.h
>
20
21
static
int
xfrm4_tunnel_check_size(
struct
sk_buff
*
skb
)
22
{
23
int
mtu,
ret
= 0;
24
struct
dst_entry
*
dst
;
25
26
if
(
IPCB
(skb)->
flags
&
IPSKB_XFRM_TUNNEL_SIZE
)
27
goto
out
;
28
29
if
(!(ip_hdr(skb)->frag_off &
htons
(
IP_DF
)) || skb->
local_df
)
30
goto
out
;
31
32
dst = skb_dst(skb);
33
mtu = dst_mtu(dst);
34
if
(skb->
len
> mtu) {
35
if
(skb->
sk
)
36
ip_local_error
(skb->
sk
,
EMSGSIZE
, ip_hdr(skb)->
daddr
,
37
inet_sk(skb->
sk
)->inet_dport, mtu);
38
else
39
icmp_send
(skb,
ICMP_DEST_UNREACH
,
40
ICMP_FRAG_NEEDED
,
htonl
(mtu));
41
ret = -
EMSGSIZE
;
42
}
43
out
:
44
return
ret
;
45
}
46
47
int
xfrm4_extract_output
(
struct
xfrm_state
*
x
,
struct
sk_buff
*skb)
48
{
49
int
err
;
50
51
err = xfrm4_tunnel_check_size(skb);
52
if
(err)
53
return
err
;
54
55
XFRM_MODE_SKB_CB
(skb)->protocol = ip_hdr(skb)->protocol;
56
57
return
xfrm4_extract_header
(skb);
58
}
59
60
int
xfrm4_prepare_output
(
struct
xfrm_state
*
x
,
struct
sk_buff
*skb)
61
{
62
int
err
;
63
64
err =
xfrm_inner_extract_output
(x, skb);
65
if
(err)
66
return
err
;
67
68
memset
(
IPCB
(skb), 0,
sizeof
(*
IPCB
(skb)));
69
IPCB
(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE |
IPSKB_XFRM_TRANSFORMED
;
70
71
skb->
protocol
=
htons
(
ETH_P_IP
);
72
73
return
x->
outer_mode
->output2(x, skb);
74
}
75
EXPORT_SYMBOL
(
xfrm4_prepare_output
);
76
77
int
xfrm4_output_finish
(
struct
sk_buff
*skb)
78
{
79
#ifdef CONFIG_NETFILTER
80
if
(!skb_dst(skb)->xfrm) {
81
IPCB
(skb)->flags |=
IPSKB_REROUTED
;
82
return
dst_output(skb);
83
}
84
85
IPCB
(skb)->flags |=
IPSKB_XFRM_TRANSFORMED
;
86
#endif
87
88
skb->
protocol
=
htons
(
ETH_P_IP
);
89
return
xfrm_output
(skb);
90
}
91
92
int
xfrm4_output
(
struct
sk_buff
*skb)
93
{
94
struct
dst_entry
*dst = skb_dst(skb);
95
struct
xfrm_state
*
x
= dst->xfrm;
96
97
return
NF_HOOK_COND
(
NFPROTO_IPV4
,
NF_INET_POST_ROUTING
, skb,
98
NULL
, dst->
dev
,
99
x->
outer_mode
->afinfo->output_finish,
100
!(
IPCB
(skb)->
flags
&
IPSKB_REROUTED
));
101
}
Generated on Thu Jan 10 2013 14:59:04 for Linux Kernel by
1.8.2