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

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

diff -u --recursive --new-file v1.3.90/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
@@ -135,8 +135,6 @@
 	restore_flags(flags);
 }
 
-static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len);
-
 #define min(a,b)	((a)<(b)?(a):(b))
 
 
@@ -583,6 +581,37 @@
 	destroy_sock(sk);
 }
 
+static inline void udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
+{
+	/*
+	 *	Charge it to the socket, dropping if the queue is full.
+	 */
+
+	/* I assume this includes the IP options, as per RFC1122 (4.1.3.2). */
+	/* If not, please let me know. -- MS */
+
+	if (sock_queue_rcv_skb(sk,skb)<0) {
+		udp_statistics.UdpInErrors++;
+		ip_statistics.IpInDiscards++;
+		ip_statistics.IpInDelivers--;
+		skb->sk = NULL;
+		kfree_skb(skb, FREE_WRITE);
+		return;
+	}
+	udp_statistics.UdpInDatagrams++;
+}
+
+
+static inline void udp_deliver(struct sock *sk, struct sk_buff *skb)
+{
+	skb->sk = sk;
+
+	if (sk->users) {
+		__skb_queue_tail(&sk->back_log, skb);
+		return;
+	}
+	udp_queue_rcv_skb(sk, skb);
+}
 
 /*
  *	All we need to do is get the socket, and then do a checksum. 
@@ -595,8 +624,23 @@
   	struct sock *sk;
   	struct udphdr *uh;
 	unsigned short ulen;
-	int addr_type = IS_MYADDR;
-	
+	int addr_type;
+
+	/*
+	 * If we're doing a "redo" (the socket was busy last time
+	 * around), we can just queue the packet now..
+	 */
+	if (redo) {
+		udp_queue_rcv_skb(skb->sk, skb);
+		return 0;
+	}
+
+	/*
+	 * First time through the loop.. Do all the setup stuff
+	 * (including finding out the socket we go to etc)
+	 */
+
+	addr_type = IS_MYADDR;
 	if(!dev || dev->pa_addr!=daddr)
 		addr_type=ip_chk_addr(daddr);
 		
@@ -651,9 +695,18 @@
 		return(0);
 	}
 
+	/*
+	 *	These are supposed to be switched. 
+	 */
+	 
+	skb->daddr = saddr;
+	skb->saddr = daddr;
 
 	len=ulen;
 
+	skb->dev = dev;
+	skb_trim(skb,len);
+
 #ifdef CONFIG_IP_MULTICAST
 	if (addr_type!=IS_MYADDR)
 	{
@@ -675,7 +728,7 @@
 				else
 					skb1=skb;
 				if(skb1)
-					udp_deliver(sk, uh, skb1, dev,saddr,daddr,len);
+					udp_deliver(sk, skb1);
 				sk=sknext;
 			}
 			while(sknext!=NULL);
@@ -712,43 +765,9 @@
 		kfree_skb(skb, FREE_WRITE);
 		return(0);
   	}
-	return udp_deliver(sk,uh,skb,dev, saddr, daddr, len);
-}
-
-static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len)
-{
-	skb->sk = sk;
-	skb->dev = dev;
-	skb_trim(skb,len);
-
-	/*
-	 *	These are supposed to be switched. 
-	 */
-	 
-	skb->daddr = saddr;
-	skb->saddr = daddr;
-
-
-	/*
-	 *	Charge it to the socket, dropping if the queue is full.
-	 */
-
-	/* I assume this includes the IP options, as per RFC1122 (4.1.3.2). */
-	/* If not, please let me know. -- MS */
-
-	if (sock_queue_rcv_skb(sk,skb)<0) 
-	{
-		udp_statistics.UdpInErrors++;
-		ip_statistics.IpInDiscards++;
-		ip_statistics.IpInDelivers--;
-		skb->sk = NULL;
-		kfree_skb(skb, FREE_WRITE);
-		return(0);
-	}
-  	udp_statistics.UdpInDatagrams++;
-	return(0);
+	udp_deliver(sk, skb);
+	return 0;
 }
-
 
 struct proto udp_prot = {
 	udp_close,

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