[IPv4] UFO: prevent generation of chained skb destined to UFO device
Problem:
ip_append_data() could wrongly generate a chained skb for devices which support UFO.
When sk_write_queue is not empty (e.g. MSG_MORE), __instead__ of appending data
into the next nr_frag of the queued skb, a new chained skb is created.
I would normally assume UFO device should get data in nr_frags and not in frag_list.
Later the udp4_hwcsum_outgoing() resets csum to NONE and skb_gso_segment() has oops.
Proposal:
1. Even length is less than mtu, employ ip_ufo_append_data() and append data to the __existed__ skb in the sk_write_queue.
2. ip_ufo_append_data() is fixed due to a wrong manipulation of peek-ing and later enqueue-ing of the same skb.
Now, enqueuing is always performed, because on error the further ip_flush_pending_frames() would release the queued skb.
Signed-off-by: Kostya B
---
net/ipv4/ip_output.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff -uprN -X linux-2.6.25-git11/Documentation/dontdiff linux-2.6.25-git11/net/ipv4/ip_output.c linux-2.6.25-git11-fix/net/ipv4/ip_output.c
--- linux-2.6.25-git11/net/ipv4/ip_output.c 2008-04-28 12:22:00.000000000 +0300
+++ linux-2.6.25-git11-fix/net/ipv4/ip_output.c 2008-04-28 14:02:41.000000000 +0300
@@ -753,23 +753,15 @@ static inline int ip_ufo_append_data(str
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum = 0;
sk->sk_sndmsg_off = 0;
+
+ /* specify the length of each IP datagram fragment*/
+ skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
+ skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+ __skb_queue_tail(&sk->sk_write_queue, skb);
}
- err = skb_append_datato_frags(sk,skb, getfrag, from,
+ return skb_append_datato_frags(sk,skb, getfrag, from,
(length - transhdrlen));
- if (!err) {
- /* specify the length of each IP datagram fragment*/
- skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
- skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
- __skb_queue_tail(&sk->sk_write_queue, skb);
-
- return 0;
- }
- /* There is not enough support do UFO ,
- * so follow normal path
- */
- kfree_skb(skb);
- return err;
}
/*
@@ -863,8 +855,9 @@ int ip_append_data(struct sock *sk,
csummode = CHECKSUM_PARTIAL;
inet->cork.length += length;
- if (((length> mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
- (rt->u.dst.dev->features & NETIF_F_UFO)) {
+ if (((length> mtu) || !skb_queue_empty(&sk->sk_write_queue)) &&
+ (sk->sk_protocol == IPPROTO_UDP) &&
+ (rt->u.dst.dev->features & NETIF_F_UFO)) {
err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
fragheaderlen, transhdrlen, mtu,
---
_________________________________________________________________
Explore the seven wonders of the world
http://search.msn.com/results.aspx?q=7+wonders+world&mkt=en-US&form=QBRE
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
| Justin Piszcz | Linux Software RAID 5 Performance Optimizations: 2.6.19.1: (211MB/s read & 195... |
| Vu Pham | Re: [Scst-devel] Integration of SCST in the mainstream Linux kernel |
| David P. Quigley | [RFC v3] Security Label Support for NFSv4 |
| Greg Kroah-Hartman | [PATCH 004/196] Chinese: add translation of SubmittingPatches |
| YOSHIFUJI Hideaki / | [GIT PULL] [IPV6] COMPAT: Fix SSM applications on 64bit kernels. |
| Pavel Emelyanov | [PATCH][CAN]: Fix copy_from_user() results interpretation. |
| Krzysztof Halasa | Re: [PATCH v2] Re: WAN: new PPP code for generic HDLC |
| Roel Kluin | [PATCH 1] net: fix and typo's |
git: | |
| Peter Stahlir | Git as a filesystem |
| Miklos Vajna | [rfc] git submodules howto |
| Dan Zwell | $GIT_DIR usage |
| Wink Saville | Resolving conflicts |
| GVG GVG | ssh_exchange_identification: Connection closed by remote host |
| Xavier Mertens | newfs: cg 0: bad magic number |
| Laurent CARON | IPSEC VPN between OpenBSD and Linux (OpenSwan) |
| Didier Wiroth | win32-codecs, avi and amd64 question |
| Netfilter kernel module | 8 hours ago | Linux kernel |
| serial driver xmit problem | 11 hours ago | Linux kernel |
| Why Windows is better than Linux | 11 hours ago | Linux general |
| How can I see my kernel messages in vt12? | 18 hours ago | Linux kernel |
| Grub | 1 day ago | Linux general |
| vmalloc_fault handling in x86_64 | 1 day ago | Linux kernel |
| epoll_wait()ing on epoll FD | 1 day ago | Linux kernel |
| Framebuffer in x86_64 causes problems to multiseat | 1 day ago | Linux kernel |
| Difference between 2.4 and 2.6 regarding thread creation | 1 day ago | Linux general |
| Compiling gfs2 on kernel 2.6.27 | 2 days ago | Linux kernel |
