summary refs log tree commit diff
path: root/net/ipv4
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-30 15:40:17 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-30 15:40:17 -0700
commite37a72de84d27ee8bc0e7dbb5c2f1774ed306dbb (patch)
treef9da35cbd79b52a5bd08d4a0f960bde6af741da0 /net/ipv4
parent93fdf10d4c28edaa1b9f80e7f9c3002359186d00 (diff)
parentf83ef8c0b58dac17211a4c0b6df0e2b1bd6637b1 (diff)
downloadlinux-e37a72de84d27ee8bc0e7dbb5c2f1774ed306dbb.tar.gz
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [IPV6]: Added GSO support for TCPv6
  [NET]: Generalise TSO-specific bits from skb_setup_caps
  [IPV6]: Added GSO support for TCPv6
  [IPV6]: Remove redundant length check on input
  [NETFILTER]: SCTP conntrack: fix crash triggered by packet without chunks
  [TG3]: Update version and reldate
  [TG3]: Add TSO workaround using GSO
  [TG3]: Turn on hw fix for ASF problems
  [TG3]: Add rx BD workaround
  [TG3]: Add tg3_netif_stop() in vlan functions
  [TCP]: Reset gso_segs if packet is dodgy
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_sctp.c2
-rw-r--r--net/ipv4/tcp.c17
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_output.c9
5 files changed, 20 insertions, 14 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 0c872fd0849d..ca0e714613fb 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -743,7 +743,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
 	if (!err) {
 		/* specify the length of each IP datagram fragment*/
 		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
-		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
+		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 		__skb_queue_tail(&sk->sk_write_queue, skb);
 
 		return 0;
@@ -1088,7 +1088,7 @@ ssize_t	ip_append_page(struct sock *sk, struct page *page,
 	if ((sk->sk_protocol == IPPROTO_UDP) &&
 	    (rt->u.dst.dev->features & NETIF_F_UFO)) {
 		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
-		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
+		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 	}
 
 
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index 0416073c5600..2d3612cd5f18 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -254,7 +254,7 @@ static int do_basic_checks(struct ip_conntrack *conntrack,
 	}
 
 	DEBUGP("Basic checks passed\n");
-	return 0;
+	return count == 0;
 }
 
 static int new_state(enum ip_conntrack_dir dir,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index a97450e9eb34..804458712d88 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -642,7 +642,7 @@ static inline int select_size(struct sock *sk, struct tcp_sock *tp)
 	int tmp = tp->mss_cache;
 
 	if (sk->sk_route_caps & NETIF_F_SG) {
-		if (sk->sk_route_caps & NETIF_F_TSO)
+		if (sk_can_gso(sk))
 			tmp = 0;
 		else {
 			int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
@@ -2165,13 +2165,19 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
 	if (!pskb_may_pull(skb, thlen))
 		goto out;
 
-	segs = NULL;
-	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
-		goto out;
-
 	oldlen = (u16)~skb->len;
 	__skb_pull(skb, thlen);
 
+	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
+		/* Packet is from an untrusted source, reset gso_segs. */
+		int mss = skb_shinfo(skb)->gso_size;
+
+		skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
+
+		segs = NULL;
+		goto out;
+	}
+
 	segs = skb_segment(skb, features);
 	if (IS_ERR(segs))
 		goto out;
@@ -2208,6 +2214,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
 out:
 	return segs;
 }
+EXPORT_SYMBOL(tcp_tso_segment);
 
 extern void __skb_cb_too_small_for_tcp(int, int);
 extern struct tcp_congestion_ops tcp_reno;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index e02a84cf9a53..8355b729fa95 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -241,6 +241,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 		goto failure;
 
 	/* OK, now commit destination to socket.  */
+	sk->sk_gso_type = SKB_GSO_TCPV4;
 	sk_setup_caps(sk, &rt->u.dst);
 
 	if (!tp->write_seq)
@@ -883,6 +884,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 	if (!newsk)
 		goto exit;
 
+	newsk->sk_gso_type = SKB_GSO_TCPV4;
 	sk_setup_caps(newsk, dst);
 
 	newtp		      = tcp_sk(newsk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5a7cb4a9c867..5c08ea20a18d 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -510,8 +510,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
 
 static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
 {
-	if (skb->len <= mss_now ||
-	    !(sk->sk_route_caps & NETIF_F_TSO)) {
+	if (skb->len <= mss_now || !sk_can_gso(sk)) {
 		/* Avoid the costly divide in the normal
 		 * non-TSO case.
 		 */
@@ -525,7 +524,7 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned
 		factor /= mss_now;
 		skb_shinfo(skb)->gso_segs = factor;
 		skb_shinfo(skb)->gso_size = mss_now;
-		skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+		skb_shinfo(skb)->gso_type = sk->sk_gso_type;
 	}
 }
 
@@ -824,9 +823,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
 
 	mss_now = tp->mss_cache;
 
-	if (large_allowed &&
-	    (sk->sk_route_caps & NETIF_F_TSO) &&
-	    !tp->urg_mode)
+	if (large_allowed && sk_can_gso(sk) && !tp->urg_mode)
 		doing_tso = 1;
 
 	if (dst) {