patch-2.1.68 linux/net/ipv4/ip_input.c
Next file: linux/net/ipv4/ip_masq.c
Previous file: linux/net/ipv4/ip_gre.c
Back to the patch index
Back to the overall index
- Lines: 174
- Date:
Sun Nov 30 14:00:39 1997
- Orig file:
v2.1.67/linux/net/ipv4/ip_input.c
- Orig date:
Thu Mar 27 14:40:15 1997
diff -u --recursive --new-file v2.1.67/linux/net/ipv4/ip_input.c linux/net/ipv4/ip_input.c
@@ -5,7 +5,7 @@
*
* The Internet Protocol (IP) module.
*
- * Version: @(#)ip.c 1.0.16b 9/1/93
+ * Version: $Id: ip_input.c,v 1.24 1997/10/24 17:15:58 kuznet Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -153,8 +153,7 @@
#endif
#include <linux/firewall.h>
#include <linux/mroute.h>
-#include <net/netlink.h>
-#include <linux/net_alias.h>
+#include <linux/netlink.h>
#include <linux/ipsec.h>
/*
@@ -184,13 +183,55 @@
#define CONFIG_IP_ALWAYS_DEFRAG 1
#endif
+/*
+ * 0 - deliver
+ * 1 - block
+ */
+static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
+{
+ int type;
+
+ type = skb->h.icmph->type;
+ if (type < 32)
+ return test_bit(type, &sk->tp_pinfo.tp_raw4.filter);
+
+ /* Do not block unknown ICMP types */
+ return 0;
+}
+
+int ip_call_ra_chain(struct sk_buff *skb)
+{
+ struct ip_ra_chain *ra;
+ u8 protocol = skb->nh.iph->protocol;
+ struct sock *last = NULL;
+
+ for (ra = ip_ra_chain; ra; ra = ra->next) {
+ struct sock *sk = ra->sk;
+ if (sk && sk->num == protocol) {
+ if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+ skb = ip_defrag(skb);
+ if (skb == NULL)
+ return 1;
+ }
+ if (last) {
+ struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (skb2)
+ raw_rcv(last, skb2);
+ }
+ last = sk;
+ }
+ }
+
+ if (last) {
+ raw_rcv(last, skb);
+ return 1;
+ }
+ return 0;
+}
int ip_local_deliver(struct sk_buff *skb)
{
struct iphdr *iph = skb->nh.iph;
-#ifdef CONFIG_IP_MASQUERADE
- struct device *dev = skb->dev;
-#endif
struct inet_protocol *ipprot;
struct sock *raw_sk=NULL;
unsigned char hash;
@@ -214,7 +255,7 @@
* Do we need to de-masquerade this packet?
*/
{
- int ret = ip_fw_demasquerade(&skb, dev);
+ int ret = ip_fw_demasquerade(&skb);
if (ret < 0) {
kfree_skb(skb, FREE_WRITE);
return 0;
@@ -256,22 +297,23 @@
if((raw_sk = raw_v4_htable[hash]) != NULL) {
struct sock *sknext = NULL;
struct sk_buff *skb1;
- raw_sk = raw_v4_lookup(raw_sk, iph->protocol, iph->saddr, iph->daddr);
+ raw_sk = raw_v4_lookup(raw_sk, iph->protocol, iph->saddr, iph->daddr, skb->dev->ifindex);
if(raw_sk) { /* Any raw sockets */
do {
/* Find the next */
sknext = raw_v4_lookup(raw_sk->next, iph->protocol,
- iph->saddr, iph->daddr);
- if(sknext)
+ iph->saddr, iph->daddr, skb->dev->ifindex);
+ if (iph->protocol != IPPROTO_ICMP || !icmp_filter(raw_sk, skb)) {
+ if (sknext == NULL)
+ break;
skb1 = skb_clone(skb, GFP_ATOMIC);
- else
- break; /* One pending raw socket left */
- if(skb1)
- {
- if(ipsec_sk_policy(raw_sk,skb1))
- raw_rcv(raw_sk, skb1);
- else
- kfree_skb(skb1, FREE_WRITE);
+ if(skb1)
+ {
+ if(ipsec_sk_policy(raw_sk,skb1))
+ raw_rcv(raw_sk, skb1);
+ else
+ kfree_skb(skb1, FREE_WRITE);
+ }
}
raw_sk = sknext;
} while(raw_sk!=NULL);
@@ -350,15 +392,6 @@
struct ip_options * opt = NULL;
int err;
-#ifdef CONFIG_NET_IPV6
- /*
- * Intercept IPv6 frames. We dump ST-II and invalid types just below..
- */
-
- if(iph->version == 6)
- return ipv6_rcv(skb,dev,pt);
-#endif
-
/*
* When interface is in promisc. mode, drop all the crap
* that it receives, do not truing to analyse it.
@@ -398,13 +431,18 @@
* is IP we can trim to the true length of the frame.
* Note this now means skb->len holds ntohs(iph->tot_len).
*/
-
- skb_trim(skb, ntohs(iph->tot_len));
+ __skb_trim(skb, ntohs(iph->tot_len));
if (skb->dst == NULL) {
err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev);
if (err)
goto drop;
+#ifdef CONFIG_CPU_IS_SLOW
+ if (net_cpu_congestion > 10 && !(iph->tos&IPTOS_RELIABILITY) &&
+ IPTOS_PREC(iph->tos) < IPTOS_PREC_INTERNETCONTROL) {
+ goto drop;
+ }
+#endif
}
#ifdef CONFIG_IP_ALWAYS_DEFRAG
@@ -425,12 +463,12 @@
opt = &(IPCB(skb)->opt);
if (opt->srr) {
if (!ipv4_config.source_route) {
- if (ipv4_config.log_martians)
+ if (ipv4_config.log_martians && net_ratelimit())
printk(KERN_INFO "source route option %08lx -> %08lx\n",
ntohl(iph->saddr), ntohl(iph->daddr));
goto drop;
}
- if (RT_LOCALADDR(((struct rtable*)skb->dst)->rt_flags) &&
+ if (((struct rtable*)skb->dst)->rt_type == RTN_LOCAL &&
ip_options_rcv_srr(skb))
goto drop;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov