patch-1.3.91 linux/net/ipv4/raw.c

Next file: linux/net/ipv4/tcp_input.c
Previous file: linux/net/ipv4/ip_output.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.90/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
@@ -109,6 +109,33 @@
 	return;
 }
 
+static inline void raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
+{
+	/* Charge it to the socket. */
+	
+	if (sock_queue_rcv_skb(sk,skb)<0)
+	{
+		ip_statistics.IpInDiscards++;
+		skb->sk=NULL;
+		kfree_skb(skb, FREE_READ);
+		return;
+	}
+
+	ip_statistics.IpInDelivers++;
+}
+
+/*
+ * This is the prot->rcv() function. It's called when we have
+ * backlogged packets from core/sock.c if we couldn't receive it
+ * when the packet arrived.
+ */
+static int raw_rcv_redo(struct sk_buff *skb, struct device *dev, struct options *opt,
+	__u32 daddr, unsigned short len,
+	__u32 saddr, int redo, struct inet_protocol * protocol)
+{
+	raw_rcv_skb(skb->sk, skb);
+	return 0;
+}
 
 /*
  *	This should be the easiest of all, all we do is
@@ -137,17 +164,11 @@
 		skb->ip_hdr->tot_len=ntohs(skb->ip_hdr->tot_len-4*skb->ip_hdr->ihl);
 #endif
 	
-	/* Charge it to the socket. */
-	
-	if(sock_queue_rcv_skb(sk,skb)<0)
-	{
-		ip_statistics.IpInDiscards++;
-		skb->sk=NULL;
-		kfree_skb(skb, FREE_READ);
-		return(0);
+	if (sk->users) {
+		__skb_queue_tail(&sk->back_log, skb);
+		return 0;
 	}
-
-	ip_statistics.IpInDelivers++;
+	raw_rcv_skb(sk, skb);
 	return 0;
 }
 
@@ -357,7 +378,7 @@
 	NULL,
 	NULL,
 	NULL,
-	NULL,
+	raw_rcv_redo,
 	datagram_select,
 #ifdef CONFIG_IP_MROUTE	
 	ipmr_ioctl,

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this