patch-2.2.4 linux/net/ipv6/udp.c
Next file: linux/net/ipx/Makefile
Previous file: linux/net/ipv6/tcp_ipv6.c
Back to the patch index
Back to the overall index
- Lines: 127
- Date:
Sun Mar 21 07:22:00 1999
- Orig file:
v2.2.3/linux/net/ipv6/udp.c
- Orig date:
Thu Nov 19 09:56:29 1998
diff -u --recursive --new-file v2.2.3/linux/net/ipv6/udp.c linux/net/ipv6/udp.c
@@ -7,7 +7,7 @@
*
* Based on linux/ipv4/udp.c
*
- * $Id: udp.c,v 1.37 1998/11/08 11:17:10 davem Exp $
+ * $Id: udp.c,v 1.38 1999/03/21 05:23:00 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -201,8 +201,8 @@
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
struct in6_addr *daddr;
+ struct in6_addr saddr;
struct dst_entry *dst;
- struct inet6_ifaddr *ifa;
struct flowi fl;
int addr_type;
int err;
@@ -284,28 +284,29 @@
dst = ip6_route_output(sk, &fl);
- if (dst->error) {
+ if ((err = dst->error) != 0) {
dst_release(dst);
- return dst->error;
+ return err;
}
ip6_dst_store(sk, dst, fl.nl_u.ip6_u.daddr);
/* get the source adddress used in the apropriate device */
- ifa = ipv6_get_saddr(dst, daddr);
+ err = ipv6_get_saddr(dst, daddr, &saddr);
- if(ipv6_addr_any(&np->saddr))
- ipv6_addr_copy(&np->saddr, &ifa->addr);
+ if (err == 0) {
+ if(ipv6_addr_any(&np->saddr))
+ ipv6_addr_copy(&np->saddr, &saddr);
- if(ipv6_addr_any(&np->rcv_saddr)) {
- ipv6_addr_copy(&np->rcv_saddr, &ifa->addr);
- sk->rcv_saddr = 0xffffffff;
+ if(ipv6_addr_any(&np->rcv_saddr)) {
+ ipv6_addr_copy(&np->rcv_saddr, &saddr);
+ sk->rcv_saddr = 0xffffffff;
+ }
+ sk->state = TCP_ESTABLISHED;
}
- sk->state = TCP_ESTABLISHED;
-
- return(0);
+ return err;
}
static void udpv6_close(struct sock *sk, long timeout)
@@ -317,7 +318,7 @@
destroy_sock(sk);
}
-#if defined(CONFIG_FILTER) || !defined(HAVE_CSUM_COPY_USER)
+#ifndef HAVE_CSUM_COPY_USER
#undef CONFIG_UDP_DELAY_CSUM
#endif
@@ -352,11 +353,11 @@
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
#else
- if (sk->no_check || skb->ip_summed==CHECKSUM_UNNECESSARY) {
+ if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
} else if (copied > msg->msg_iov[0].iov_len || (msg->msg_flags&MSG_TRUNC)) {
- if (csum_fold(csum_partial(skb->h.raw, ntohs(skb->h.uh->len), skb->csum))) {
+ if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
/* Error for blocking case is chosen to masquerade
as some normal condition.
*/
@@ -373,7 +374,7 @@
csum = csum_and_copy_to_user((char*)&skb->h.uh[1], msg->msg_iov[0].iov_base, copied, csum, &err);
if (err)
goto out_free;
- if (csum_fold(csum)) {
+ if ((unsigned short)csum_fold(csum)) {
/* Error for blocking case is chosen to masquerade
as some normal condition.
*/
@@ -454,6 +455,17 @@
static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
{
+#if defined(CONFIG_FILTER) && defined(CONFIG_UDP_DELAY_CSUM)
+ if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
+ if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
+ udp_stats_in6.UdpInErrors++;
+ ipv6_statistics.Ip6InDiscards++;
+ kfree_skb(skb);
+ return 0;
+ }
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+#endif
if (sock_queue_rcv_skb(sk,skb)<0) {
udp_stats_in6.UdpInErrors++;
ipv6_statistics.Ip6InDiscards++;
@@ -627,14 +639,13 @@
if (sk == NULL) {
#ifdef CONFIG_UDP_DELAY_CSUM
if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
- csum_fold(csum_partial((char*)uh, len, skb->csum)))
+ (unsigned short)csum_fold(csum_partial((char*)uh, len, skb->csum)))
goto discard;
#endif
-
udp_stats_in6.UdpNoPorts++;
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
-
+
kfree_skb(skb);
return(0);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)