Import 2.3.13
[davej-history.git] / net / ipv4 / ip_forward.c
blob08ebbc2f1e7608f5061842e508836b063eab9206
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.
6 * The IP forwarding functionality.
7 *
8 * Version: $Id: ip_forward.c,v 1.43 1999/03/21 05:22:37 davem Exp $
10 * Authors: see ip.c
12 * Fixes:
13 * Many : Split from ip.c , see ip_input.c for
14 * history.
15 * Dave Gregorich : NULL ip_rt_put fix for multicast
16 * routing.
17 * Jos Vos : Add call_out_firewall before sending,
18 * use output device for accounting.
19 * Jos Vos : Call forward firewall after routing
20 * (always use output device).
21 * Mike McLagan : Routing by source
24 #include <linux/config.h>
25 #include <linux/types.h>
26 #include <linux/mm.h>
27 #include <linux/sched.h>
28 #include <linux/skbuff.h>
29 #include <linux/ip.h>
30 #include <linux/icmp.h>
31 #include <linux/netdevice.h>
32 #include <net/sock.h>
33 #include <net/ip.h>
34 #include <net/tcp.h>
35 #include <net/udp.h>
36 #include <net/icmp.h>
37 #include <linux/tcp.h>
38 #include <linux/udp.h>
39 #include <linux/firewall.h>
40 #include <linux/ip_fw.h>
41 #ifdef CONFIG_IP_MASQUERADE
42 #include <net/ip_masq.h>
43 #endif
44 #include <net/checksum.h>
45 #include <linux/route.h>
46 #include <net/route.h>
48 #ifdef CONFIG_IP_TRANSPARENT_PROXY
50 * Check the packet against our socket administration to see
51 * if it is related to a connection on our system.
52 * Needed for transparent proxying.
55 int ip_chksock(struct sk_buff *skb)
57 switch (skb->nh.iph->protocol) {
58 case IPPROTO_ICMP:
59 return icmp_chkaddr(skb);
60 case IPPROTO_TCP:
61 return tcp_chkaddr(skb);
62 case IPPROTO_UDP:
63 return udp_chkaddr(skb);
64 default:
65 return 0;
68 #endif
71 int ip_forward(struct sk_buff *skb)
73 struct device *dev2; /* Output device */
74 struct iphdr *iph; /* Our header */
75 struct rtable *rt; /* Route we use */
76 struct ip_options * opt = &(IPCB(skb)->opt);
77 unsigned short mtu;
78 #if defined(CONFIG_FIREWALL) || defined(CONFIG_IP_MASQUERADE)
79 int fw_res = 0;
80 #endif
82 if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
83 return 0;
85 if (skb->pkt_type != PACKET_HOST)
86 goto drop;
89 * According to the RFC, we must first decrease the TTL field. If
90 * that reaches zero, we must reply an ICMP control message telling
91 * that the packet's lifetime expired.
94 iph = skb->nh.iph;
95 rt = (struct rtable*)skb->dst;
97 #ifdef CONFIG_CPU_IS_SLOW
98 if (net_cpu_congestion > 1 && !(iph->tos&IPTOS_RELIABILITY) &&
99 IPTOS_PREC(iph->tos) < IPTOS_PREC_INTERNETCONTROL) {
100 if (((xtime.tv_usec&0xF)<<net_cpu_congestion) > 0x1C)
101 goto drop;
103 #endif
106 #ifdef CONFIG_IP_TRANSPARENT_PROXY
107 if (ip_chksock(skb))
108 goto local_pkt;
109 #endif
111 if (iph->ttl <= 1)
112 goto too_many_hops;
114 if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
115 goto sr_failed;
118 * Having picked a route we can now send the frame out
119 * after asking the firewall permission to do so.
122 skb->priority = rt_tos2priority(iph->tos);
123 dev2 = rt->u.dst.dev;
124 mtu = rt->u.dst.pmtu;
126 #ifdef CONFIG_NET_SECURITY
127 call_fw_firewall(PF_SECURITY, dev2, NULL, &mtu, NULL);
128 #endif
131 * We now generate an ICMP HOST REDIRECT giving the route
132 * we calculated.
134 if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr)
135 ip_rt_send_redirect(skb);
137 /* We are about to mangle packet. Copy it! */
138 if ((skb = skb_cow(skb, dev2->hard_header_len)) == NULL)
139 return -1;
140 iph = skb->nh.iph;
141 opt = &(IPCB(skb)->opt);
143 /* Decrease ttl after skb cow done */
144 ip_decrease_ttl(iph);
147 * We now may allocate a new buffer, and copy the datagram into it.
148 * If the indicated interface is up and running, kick it.
151 if (skb->len > mtu && (ntohs(iph->frag_off) & IP_DF))
152 goto frag_needed;
154 #ifdef CONFIG_IP_ROUTE_NAT
155 if (rt->rt_flags & RTCF_NAT) {
156 if (ip_do_nat(skb)) {
157 kfree_skb(skb);
158 return -1;
161 #endif
163 #ifdef CONFIG_IP_MASQUERADE
164 if(!(IPCB(skb)->flags&IPSKB_MASQUERADED)) {
166 * Check that any ICMP packets are not for a
167 * masqueraded connection. If so rewrite them
168 * and skip the firewall checks
170 if (iph->protocol == IPPROTO_ICMP) {
171 __u32 maddr;
172 #ifdef CONFIG_IP_MASQUERADE_ICMP
173 struct icmphdr *icmph = (struct icmphdr *)((char*)iph + (iph->ihl << 2));
174 if ((icmph->type==ICMP_DEST_UNREACH)||
175 (icmph->type==ICMP_SOURCE_QUENCH)||
176 (icmph->type==ICMP_TIME_EXCEEDED))
178 #endif
179 maddr = inet_select_addr(dev2, rt->rt_gateway, RT_SCOPE_UNIVERSE);
180 fw_res = ip_fw_masq_icmp(&skb, maddr);
181 if (fw_res < 0) {
182 kfree_skb(skb);
183 return -1;
186 if (fw_res)
187 /* ICMP matched - skip firewall */
188 goto skip_call_fw_firewall;
189 #ifdef CONFIG_IP_MASQUERADE_ICMP
191 #endif
193 if (rt->rt_flags&RTCF_MASQ)
194 goto skip_call_fw_firewall;
195 #endif /* CONFIG_IP_MASQUERADE */
197 #ifdef CONFIG_FIREWALL
198 fw_res=call_fw_firewall(PF_INET, dev2, iph, NULL, &skb);
199 switch (fw_res) {
200 case FW_ACCEPT:
201 case FW_MASQUERADE:
202 break;
203 case FW_REJECT:
204 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
205 /* fall thru */
206 default:
207 kfree_skb(skb);
208 return -1;
210 #endif
212 #ifdef CONFIG_IP_MASQUERADE
215 skip_call_fw_firewall:
217 * If this fragment needs masquerading, make it so...
218 * (Don't masquerade de-masqueraded fragments)
220 if (!(IPCB(skb)->flags&IPSKB_MASQUERADED) &&
221 (fw_res==FW_MASQUERADE || rt->rt_flags&RTCF_MASQ)) {
222 u32 maddr;
224 #ifdef CONFIG_IP_ROUTE_NAT
225 maddr = (rt->rt_flags&RTCF_MASQ) ? rt->rt_src_map : 0;
227 if (maddr == 0)
228 #endif
229 maddr = inet_select_addr(dev2, rt->rt_gateway, RT_SCOPE_UNIVERSE);
231 if (ip_fw_masquerade(&skb, maddr) < 0) {
232 kfree_skb(skb);
233 return -1;
234 } else {
236 * Masquerader may have changed skb
238 iph = skb->nh.iph;
239 opt = &(IPCB(skb)->opt);
242 #endif
245 #ifdef CONFIG_FIREWALL
246 if ((fw_res = call_out_firewall(PF_INET, dev2, iph, NULL,&skb)) < FW_ACCEPT) {
247 /* FW_ACCEPT and FW_MASQUERADE are treated equal:
248 masquerading is only supported via forward rules */
249 if (fw_res == FW_REJECT)
250 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
251 kfree_skb(skb);
252 return -1;
254 #endif
256 ip_statistics.IpForwDatagrams++;
258 if (opt->optlen == 0) {
259 #ifdef CONFIG_NET_FASTROUTE
260 if (rt->rt_flags&RTCF_FAST && !netdev_fastroute_obstacles) {
261 unsigned h = ((*(u8*)&rt->key.dst)^(*(u8*)&rt->key.src))&NETDEV_FASTROUTE_HMASK;
262 /* Time to switch to functional programming :-) */
263 dst_release_irqwait(xchg(&skb->dev->fastpath[h], dst_clone(&rt->u.dst)));
265 #endif
266 ip_send(skb);
267 return 0;
270 ip_forward_options(skb);
271 ip_send(skb);
272 return 0;
274 #ifdef CONFIG_IP_TRANSPARENT_PROXY
275 local_pkt:
276 return ip_local_deliver(skb);
277 #endif
279 frag_needed:
280 ip_statistics.IpFragFails++;
281 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
282 goto drop;
284 sr_failed:
286 * Strict routing permits no gatewaying
288 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);
289 goto drop;
291 too_many_hops:
292 /* Tell the sender its packet died... */
293 icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
294 drop:
295 kfree_skb(skb);
296 return -1;