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
ip_forward.c
Go to the documentation of this file.
1
/*
2
* INET An implementation of the TCP/IP protocol suite for the LINUX
3
* operating system. INET is implemented using the BSD Socket
4
* interface as the means of communication with the user level.
5
*
6
* The IP forwarding functionality.
7
*
8
* Authors: see ip.c
9
*
10
* Fixes:
11
* Many : Split from ip.c , see ip_input.c for
12
* history.
13
* Dave Gregorich : NULL ip_rt_put fix for multicast
14
* routing.
15
* Jos Vos : Add call_out_firewall before sending,
16
* use output device for accounting.
17
* Jos Vos : Call forward firewall after routing
18
* (always use output device).
19
* Mike McLagan : Routing by source
20
*/
21
22
#include <linux/types.h>
23
#include <
linux/mm.h
>
24
#include <
linux/skbuff.h
>
25
#include <linux/ip.h>
26
#include <linux/icmp.h>
27
#include <linux/netdevice.h>
28
#include <linux/slab.h>
29
#include <
net/sock.h
>
30
#include <
net/ip.h
>
31
#include <
net/tcp.h
>
32
#include <
net/udp.h
>
33
#include <
net/icmp.h
>
34
#include <linux/tcp.h>
35
#include <linux/udp.h>
36
#include <linux/netfilter_ipv4.h>
37
#include <
net/checksum.h
>
38
#include <
linux/route.h
>
39
#include <
net/route.h
>
40
#include <
net/xfrm.h
>
41
42
static
int
ip_forward_finish(
struct
sk_buff
*
skb
)
43
{
44
struct
ip_options
*
opt
= &(
IPCB
(skb)->opt);
45
46
IP_INC_STATS_BH
(dev_net(skb_dst(skb)->
dev
),
IPSTATS_MIB_OUTFORWDATAGRAMS
);
47
IP_ADD_STATS_BH
(dev_net(skb_dst(skb)->
dev
),
IPSTATS_MIB_OUTOCTETS
, skb->
len
);
48
49
if
(
unlikely
(opt->
optlen
))
50
ip_forward_options
(skb);
51
52
return
dst_output(skb);
53
}
54
55
int
ip_forward
(
struct
sk_buff
*skb)
56
{
57
struct
iphdr
*iph;
/* Our header */
58
struct
rtable
*rt;
/* Route we use */
59
struct
ip_options
*opt = &(
IPCB
(skb)->opt);
60
61
if
(skb_warn_if_lro(skb))
62
goto
drop;
63
64
if
(!xfrm4_policy_check(
NULL
,
XFRM_POLICY_FWD
, skb))
65
goto
drop;
66
67
if
(
IPCB
(skb)->opt.router_alert &&
ip_call_ra_chain
(skb))
68
return
NET_RX_SUCCESS
;
69
70
if
(skb->
pkt_type
!=
PACKET_HOST
)
71
goto
drop;
72
73
skb_forward_csum(skb);
74
75
/*
76
* According to the RFC, we must first decrease the TTL field. If
77
* that reaches zero, we must reply an ICMP control message telling
78
* that the packet's lifetime expired.
79
*/
80
if
(ip_hdr(skb)->
ttl
<= 1)
81
goto
too_many_hops;
82
83
if
(!xfrm4_route_forward(skb))
84
goto
drop;
85
86
rt = skb_rtable(skb);
87
88
if
(opt->
is_strictroute
&& rt->
rt_uses_gateway
)
89
goto
sr_failed;
90
91
if
(
unlikely
(skb->
len
> dst_mtu(&rt->
dst
) && !skb_is_gso(skb) &&
92
(ip_hdr(skb)->frag_off &
htons
(
IP_DF
))) && !skb->
local_df
) {
93
IP_INC_STATS
(dev_net(rt->
dst
.dev),
IPSTATS_MIB_FRAGFAILS
);
94
icmp_send
(skb,
ICMP_DEST_UNREACH
,
ICMP_FRAG_NEEDED
,
95
htonl
(dst_mtu(&rt->
dst
)));
96
goto
drop;
97
}
98
99
/* We are about to mangle packet. Copy it! */
100
if
(skb_cow(skb,
LL_RESERVED_SPACE
(rt->
dst
.dev)+rt->
dst
.header_len))
101
goto
drop;
102
iph = ip_hdr(skb);
103
104
/* Decrease ttl after skb cow done */
105
ip_decrease_ttl(iph);
106
107
/*
108
* We now generate an ICMP HOST REDIRECT giving the route
109
* we calculated.
110
*/
111
if
(rt->
rt_flags
&
RTCF_DOREDIRECT
&& !opt->
srr
&& !skb_sec_path(skb))
112
ip_rt_send_redirect
(skb);
113
114
skb->
priority
= rt_tos2priority(iph->
tos
);
115
116
return
NF_HOOK
(
NFPROTO_IPV4
,
NF_INET_FORWARD
, skb, skb->
dev
,
117
rt->
dst
.dev, ip_forward_finish);
118
119
sr_failed:
120
/*
121
* Strict routing permits no gatewaying
122
*/
123
icmp_send
(skb,
ICMP_DEST_UNREACH
,
ICMP_SR_FAILED
, 0);
124
goto
drop;
125
126
too_many_hops:
127
/* Tell the sender its packet died... */
128
IP_INC_STATS_BH
(dev_net(skb_dst(skb)->
dev
),
IPSTATS_MIB_INHDRERRORS
);
129
icmp_send
(skb,
ICMP_TIME_EXCEEDED
,
ICMP_EXC_TTL
, 0);
130
drop:
131
kfree_skb
(skb);
132
return
NET_RX_DROP
;
133
}
Generated on Thu Jan 10 2013 14:58:25 for Linux Kernel by
1.8.2