patch-2.3.15 linux/net/ipv4/ip_forward.c
Next file: linux/net/ipv4/ip_fragment.c
Previous file: linux/net/ipv4/igmp.c
Back to the patch index
Back to the overall index
- Lines: 240
- Date:
Mon Aug 23 10:01:02 1999
- Orig file:
v2.3.14/linux/net/ipv4/ip_forward.c
- Orig date:
Wed Aug 18 11:38:48 1999
diff -u --recursive --new-file v2.3.14/linux/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c
@@ -5,7 +5,7 @@
*
* The IP forwarding functionality.
*
- * Version: $Id: ip_forward.c,v 1.43 1999/03/21 05:22:37 davem Exp $
+ * Version: $Id: ip_forward.c,v 1.45 1999/08/20 11:05:16 davem Exp $
*
* Authors: see ip.c
*
@@ -36,37 +36,41 @@
#include <net/icmp.h>
#include <linux/tcp.h>
#include <linux/udp.h>
-#include <linux/firewall.h>
-#include <linux/ip_fw.h>
-#ifdef CONFIG_IP_MASQUERADE
-#include <net/ip_masq.h>
-#endif
+#include <linux/netfilter_ipv4.h>
#include <net/checksum.h>
#include <linux/route.h>
#include <net/route.h>
-#ifdef CONFIG_IP_TRANSPARENT_PROXY
-/*
- * Check the packet against our socket administration to see
- * if it is related to a connection on our system.
- * Needed for transparent proxying.
- */
-
-int ip_chksock(struct sk_buff *skb)
+static inline int ip_forward_finish(struct sk_buff *skb)
{
- switch (skb->nh.iph->protocol) {
- case IPPROTO_ICMP:
- return icmp_chkaddr(skb);
- case IPPROTO_TCP:
- return tcp_chkaddr(skb);
- case IPPROTO_UDP:
- return udp_chkaddr(skb);
- default:
+ struct ip_options * opt = &(IPCB(skb)->opt);
+
+ ip_statistics.IpForwDatagrams++;
+
+ if (opt->optlen == 0) {
+#ifdef CONFIG_NET_FASTROUTE
+ struct rtable *rt = (struct rtable*)skb->dst;
+
+ if (rt->rt_flags&RTCF_FAST && !netdev_fastroute_obstacles) {
+ struct dst_entry *old_dst;
+ unsigned h = ((*(u8*)&rt->key.dst)^(*(u8*)&rt->key.src))&NETDEV_FASTROUTE_HMASK;
+
+ write_lock_irq(&skb->dev->fastpath_lock);
+ old_dst = skb->dev->fastpath[h];
+ skb->dev->fastpath[h] = dst_clone(&rt->u.dst);
+ write_unlock_irq(&skb->dev->fastpath_lock);
+
+ dst_release(old_dst);
+ }
+#endif
+ ip_send(skb);
return 0;
}
-}
-#endif
+ ip_forward_options(skb);
+ ip_send(skb);
+ return 0;
+}
int ip_forward(struct sk_buff *skb)
{
@@ -75,9 +79,6 @@
struct rtable *rt; /* Route we use */
struct ip_options * opt = &(IPCB(skb)->opt);
unsigned short mtu;
-#if defined(CONFIG_FIREWALL) || defined(CONFIG_IP_MASQUERADE)
- int fw_res = 0;
-#endif
if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
return 0;
@@ -94,20 +95,6 @@
iph = skb->nh.iph;
rt = (struct rtable*)skb->dst;
-#ifdef CONFIG_CPU_IS_SLOW
- if (net_cpu_congestion > 1 && !(iph->tos&IPTOS_RELIABILITY) &&
- IPTOS_PREC(iph->tos) < IPTOS_PREC_INTERNETCONTROL) {
- if (((xtime.tv_usec&0xF)<<net_cpu_congestion) > 0x1C)
- goto drop;
- }
-#endif
-
-
-#ifdef CONFIG_IP_TRANSPARENT_PROXY
- if (ip_chksock(skb))
- goto local_pkt;
-#endif
-
if (iph->ttl <= 1)
goto too_many_hops;
@@ -123,10 +110,6 @@
dev2 = rt->u.dst.dev;
mtu = rt->u.dst.pmtu;
-#ifdef CONFIG_NET_SECURITY
- call_fw_firewall(PF_SECURITY, dev2, NULL, &mtu, NULL);
-#endif
-
/*
* We now generate an ICMP HOST REDIRECT giving the route
* we calculated.
@@ -160,121 +143,8 @@
}
#endif
-#ifdef CONFIG_IP_MASQUERADE
- if(!(IPCB(skb)->flags&IPSKB_MASQUERADED)) {
- /*
- * Check that any ICMP packets are not for a
- * masqueraded connection. If so rewrite them
- * and skip the firewall checks
- */
- if (iph->protocol == IPPROTO_ICMP) {
- __u32 maddr;
-#ifdef CONFIG_IP_MASQUERADE_ICMP
- struct icmphdr *icmph = (struct icmphdr *)((char*)iph + (iph->ihl << 2));
- if ((icmph->type==ICMP_DEST_UNREACH)||
- (icmph->type==ICMP_SOURCE_QUENCH)||
- (icmph->type==ICMP_TIME_EXCEEDED))
- {
-#endif
- maddr = inet_select_addr(dev2, rt->rt_gateway, RT_SCOPE_UNIVERSE);
- fw_res = ip_fw_masq_icmp(&skb, maddr);
- if (fw_res < 0) {
- kfree_skb(skb);
- return -1;
- }
-
- if (fw_res)
- /* ICMP matched - skip firewall */
- goto skip_call_fw_firewall;
-#ifdef CONFIG_IP_MASQUERADE_ICMP
- }
-#endif
- }
- if (rt->rt_flags&RTCF_MASQ)
- goto skip_call_fw_firewall;
-#endif /* CONFIG_IP_MASQUERADE */
-
-#ifdef CONFIG_FIREWALL
- fw_res=call_fw_firewall(PF_INET, dev2, iph, NULL, &skb);
- switch (fw_res) {
- case FW_ACCEPT:
- case FW_MASQUERADE:
- break;
- case FW_REJECT:
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
- /* fall thru */
- default:
- kfree_skb(skb);
- return -1;
- }
-#endif
-
-#ifdef CONFIG_IP_MASQUERADE
- }
-
-skip_call_fw_firewall:
- /*
- * If this fragment needs masquerading, make it so...
- * (Don't masquerade de-masqueraded fragments)
- */
- if (!(IPCB(skb)->flags&IPSKB_MASQUERADED) &&
- (fw_res==FW_MASQUERADE || rt->rt_flags&RTCF_MASQ)) {
- u32 maddr;
-
-#ifdef CONFIG_IP_ROUTE_NAT
- maddr = (rt->rt_flags&RTCF_MASQ) ? rt->rt_src_map : 0;
-
- if (maddr == 0)
-#endif
- maddr = inet_select_addr(dev2, rt->rt_gateway, RT_SCOPE_UNIVERSE);
-
- if (ip_fw_masquerade(&skb, maddr) < 0) {
- kfree_skb(skb);
- return -1;
- } else {
- /*
- * Masquerader may have changed skb
- */
- iph = skb->nh.iph;
- opt = &(IPCB(skb)->opt);
- }
- }
-#endif
-
-
-#ifdef CONFIG_FIREWALL
- if ((fw_res = call_out_firewall(PF_INET, dev2, iph, NULL,&skb)) < FW_ACCEPT) {
- /* FW_ACCEPT and FW_MASQUERADE are treated equal:
- masquerading is only supported via forward rules */
- if (fw_res == FW_REJECT)
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
- kfree_skb(skb);
- return -1;
- }
-#endif
-
- ip_statistics.IpForwDatagrams++;
-
- if (opt->optlen == 0) {
-#ifdef CONFIG_NET_FASTROUTE
- if (rt->rt_flags&RTCF_FAST && !netdev_fastroute_obstacles) {
- unsigned h = ((*(u8*)&rt->key.dst)^(*(u8*)&rt->key.src))&NETDEV_FASTROUTE_HMASK;
- /* Time to switch to functional programming :-) */
- dst_release_irqwait(xchg(&skb->dev->fastpath[h], dst_clone(&rt->u.dst)));
- }
-#endif
- ip_send(skb);
- return 0;
- }
-
- ip_forward_options(skb);
- ip_send(skb);
- return 0;
-
-#ifdef CONFIG_IP_TRANSPARENT_PROXY
-local_pkt:
- return ip_local_deliver(skb);
-#endif
+ return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev2,
+ ip_forward_finish);
frag_needed:
ip_statistics.IpFragFails++;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)