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

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)