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
- Lines: 147
- Date:
Thu Apr 18 12:50:04 1996
- Orig file:
v1.3.90/linux/net/ipv4/udp.c
- Orig date:
Fri Apr 12 15:52:12 1996
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