patch-2.2.4 linux/net/ipv6/tcp_ipv6.c

Next file: linux/net/ipv6/udp.c
Previous file: linux/net/ipv6/sit.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.3/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: tcp_ipv6.c,v 1.96 1999/03/05 13:23:13 davem Exp $
+ *	$Id: tcp_ipv6.c,v 1.100 1999/03/21 05:22:59 davem Exp $
  *
  *	Based on: 
  *	linux/net/ipv4/tcp.c
@@ -376,12 +376,13 @@
 	struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
 	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	struct inet6_ifaddr *ifa;
 	struct in6_addr *saddr = NULL;
+	struct in6_addr saddr_buf;
 	struct flowi fl;
 	struct dst_entry *dst;
 	struct sk_buff *buff;
 	int addr_type;
+	int err;
 
 	if (sk->state != TCP_CLOSE) 
 		return(-EISCONN);
@@ -428,7 +429,6 @@
 	if (addr_type == IPV6_ADDR_MAPPED) {
 		u32 exthdrlen = tp->ext_header_len;
 		struct sockaddr_in sin;
-		int err;
 
 		SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
 
@@ -472,9 +472,9 @@
 
 	dst = ip6_route_output(sk, &fl);
 
-	if (dst->error) {
+	if ((err = dst->error) != 0) {
 		dst_release(dst);
-		return dst->error;
+		return err;
 	}
 
 	if (fl.oif == 0 && addr_type&IPV6_ADDR_LINKLOCAL) {
@@ -489,18 +489,17 @@
 	ip6_dst_store(sk, dst, NULL);
 
 	if (saddr == NULL) {
-		ifa = ipv6_get_saddr(dst, &np->daddr);
-
-		if (ifa == NULL)
-			return -ENETUNREACH;
-		
-		saddr = &ifa->addr;
+		err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf);
+		if (err)
+			return err;
 
-		/* set the source address */
-		ipv6_addr_copy(&np->rcv_saddr, saddr);
-		ipv6_addr_copy(&np->saddr, saddr);
+		saddr = &saddr_buf;
 	}
 
+	/* set the source address */
+	ipv6_addr_copy(&np->rcv_saddr, saddr);
+	ipv6_addr_copy(&np->saddr, saddr);
+
 	tp->ext_header_len = 0;
 	if (np->opt)
 		tp->ext_header_len = np->opt->opt_flen+np->opt->opt_nflen;
@@ -535,7 +534,6 @@
 
 static int tcp_v6_sendmsg(struct sock *sk, struct msghdr *msg, int len)
 {
-	struct tcp_opt *tp;
 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
 	int retval = -EINVAL;
 
@@ -564,14 +562,7 @@
 			goto out;
 	}
 
-	lock_sock(sk);
-	retval = tcp_do_sendmsg(sk, msg->msg_iovlen, msg->msg_iov, 
-				msg->msg_flags);
-	/* Push out partial tail frames if needed. */
-	tp = &(sk->tp_pinfo.af_tcp);
-	if(tp->send_head && tcp_snd_test(sk, tp->send_head))
-		tcp_write_xmit(sk);
-	release_sock(sk);
+	retval = tcp_do_sendmsg(sk, msg);
 
 out:
 	return retval;
@@ -610,11 +601,14 @@
 	np = &sk->net_pinfo.af_inet6;
 	if (type == ICMPV6_PKT_TOOBIG) {
 		struct dst_entry *dst = NULL;
-		/* icmp should have updated the destination cache entry */
+
+		if (atomic_read(&sk->sock_readers))
+			return;
 
 		if (sk->state == TCP_LISTEN)
 			return;
 
+		/* icmp should have updated the destination cache entry */
 		if (sk->dst_cache)
 			dst = dst_check(&sk->dst_cache, np->dst_cookie);
 
@@ -639,8 +633,7 @@
 
 		if (dst->error) {
 			sk->err_soft = -dst->error;
-		} else if (tp->pmtu_cookie > dst->pmtu
-			   && !atomic_read(&sk->sock_readers)) {
+		} else if (tp->pmtu_cookie > dst->pmtu) {
 			tcp_sync_mss(sk, dst->pmtu);
 			tcp_simple_retransmit(sk);
 		} /* else let the usual retransmit timer handle it */
@@ -1201,6 +1194,11 @@
 	if (skb->protocol == __constant_htons(ETH_P_IP))
 		return tcp_v4_do_rcv(sk, skb);
 
+#ifdef CONFIG_FILTER
+	if (sk->filter && sk_filter(skb, sk->filter))
+		goto discard;
+#endif /* CONFIG_FILTER */
+
 	/*
 	 *	socket locking is here for SMP purposes as backlog rcv
 	 *	is currently called with bh processing disabled.
@@ -1428,6 +1426,9 @@
 {
 	struct in6_addr *saddr;
 	struct in6_addr *daddr;
+
+	if (skb->protocol == __constant_htons(ETH_P_IP))
+		return ipv4_specific.get_sock(skb, th);
 
 	saddr = &skb->nh.ipv6h->saddr;
 	daddr = &skb->nh.ipv6h->daddr;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)