00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include <linux/config.h>
00025
#include <linux/types.h>
00026
#include <linux/mm.h>
00027
#include <linux/sched.h>
00028
#include <linux/skbuff.h>
00029
#include <linux/ip.h>
00030
#include <linux/icmp.h>
00031
#include <linux/netdevice.h>
00032
#include <net/sock.h>
00033
#include <net/ip.h>
00034
#include <net/tcp.h>
00035
#include <net/udp.h>
00036
#include <net/icmp.h>
00037
#include <linux/tcp.h>
00038
#include <linux/udp.h>
00039
#include <linux/netfilter_ipv4.h>
00040
#include <net/checksum.h>
00041
#include <linux/route.h>
00042
#include <net/route.h>
00043
00044 static inline int ip_forward_finish(
struct sk_buff *skb)
00045 {
00046
struct ip_options * opt = &(
IPCB(skb)->opt);
00047
00048
IP_INC_STATS_BH(IpForwDatagrams);
00049
00050
if (opt->optlen == 0) {
00051
#ifdef CONFIG_NET_FASTROUTE
00052
struct rtable *rt = (
struct rtable*)skb->
dst;
00053
00054
if (rt->rt_flags&RTCF_FAST && !netdev_fastroute_obstacles) {
00055
struct dst_entry *old_dst;
00056
unsigned h = ((*(u8*)&rt->key.dst)^(*(u8*)&rt->key.src))&NETDEV_FASTROUTE_HMASK;
00057
00058 write_lock_irq(&skb->
dev->fastpath_lock);
00059 old_dst = skb->
dev->fastpath[h];
00060 skb->
dev->fastpath[h] =
dst_clone(&rt->u.dst);
00061 write_unlock_irq(&skb->
dev->fastpath_lock);
00062
00063
dst_release(old_dst);
00064 }
00065
#endif
00066
return (
ip_send(skb));
00067 }
00068
00069
ip_forward_options(skb);
00070
return (
ip_send(skb));
00071 }
00072
00073 int ip_forward(
struct sk_buff *skb)
00074 {
00075
struct net_device *dev2;
00076
struct iphdr *iph;
00077
struct rtable *rt;
00078
struct ip_options * opt = &(
IPCB(skb)->opt);
00079
unsigned short mtu;
00080
00081
if (
IPCB(skb)->opt.router_alert &&
ip_call_ra_chain(skb))
00082
return NET_RX_SUCCESS;
00083
00084
if (skb->
pkt_type != PACKET_HOST)
00085
goto drop;
00086
00087 skb->
ip_summed =
CHECKSUM_NONE;
00088
00089
00090
00091
00092
00093
00094
00095 iph = skb->
nh.iph;
00096 rt = (
struct rtable*)skb->
dst;
00097
00098
if (iph->ttl <= 1)
00099
goto too_many_hops;
00100
00101
if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
00102
goto sr_failed;
00103
00104
00105
00106
00107
00108
00109 skb->
priority =
rt_tos2priority(iph->tos);
00110 dev2 = rt->u.dst.dev;
00111 mtu = rt->u.dst.pmtu;
00112
00113
00114
00115
00116
00117
if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr)
00118
ip_rt_send_redirect(skb);
00119
00120
00121
if (
skb_cow(skb, dev2->hard_header_len))
00122
goto drop;
00123 iph = skb->
nh.iph;
00124
00125
00126
ip_decrease_ttl(iph);
00127
00128
00129
00130
00131
00132
00133
if (skb->
len > mtu && (ntohs(iph->frag_off) &
IP_DF))
00134
goto frag_needed;
00135
00136
#ifdef CONFIG_IP_ROUTE_NAT
00137
if (rt->rt_flags & RTCF_NAT) {
00138
if (
ip_do_nat(skb)) {
00139
kfree_skb(skb);
00140
return NET_RX_BAD;
00141 }
00142 }
00143
#endif
00144
00145
return NF_HOOK(PF_INET,
NF_IP_FORWARD, skb, skb->
dev, dev2,
00146
ip_forward_finish);
00147
00148 frag_needed:
00149
IP_INC_STATS_BH(IpFragFails);
00150
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
00151
goto drop;
00152
00153 sr_failed:
00154
00155
00156
00157
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);
00158
goto drop;
00159
00160 too_many_hops:
00161
00162
icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
00163 drop:
00164
kfree_skb(skb);
00165
return NET_RX_DROP;
00166 }