From: Ben Hutchings <hidden> Date: 2012-01-12 20:42:14
skb_checksum_help() does:
if (unlikely(skb_shinfo(skb)->gso_size)) {
/* Let GSO fix up the checksum. */
goto out_set_summed;
}
...
out_set_summed:
skb->ip_summed = CHECKSUM_NONE;
out:
return ret;
but skb_gso_segment() requires that skb->ip_summed == CHECKSUM_PARTIAL
and WARNs if not. I don't think there's any case where it's valid to
call both. Shouldn't skb_checksum_help() also WARN and return an error
code instead of muddling on?
Inspecting the callers of skb_checksum_help(), it looks like sch_netem's
'corrupt' option and xt_CHECKSUM might trigger this case.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
From: Herbert Xu <herbert@gondor.apana.org.au> Date: 2012-01-12 22:03:28
On Thu, Jan 12, 2012 at 08:42:10PM +0000, Ben Hutchings wrote:
skb_checksum_help() does:
if (unlikely(skb_shinfo(skb)->gso_size)) {
/* Let GSO fix up the checksum. */
goto out_set_summed;
}
...
out_set_summed:
skb->ip_summed = CHECKSUM_NONE;
out:
return ret;
but skb_gso_segment() requires that skb->ip_summed == CHECKSUM_PARTIAL
and WARNs if not. I don't think there's any case where it's valid to
call both. Shouldn't skb_checksum_help() also WARN and return an error
code instead of muddling on?
From: Stephen Hemminger <hidden> Date: 2012-01-12 22:10:17
On Thu, 12 Jan 2012 20:42:10 +0000
Ben Hutchings [off-list ref] wrote:
skb_checksum_help() does:
if (unlikely(skb_shinfo(skb)->gso_size)) {
/* Let GSO fix up the checksum. */
goto out_set_summed;
}
...
out_set_summed:
skb->ip_summed = CHECKSUM_NONE;
out:
return ret;
but skb_gso_segment() requires that skb->ip_summed == CHECKSUM_PARTIAL
and WARNs if not. I don't think there's any case where it's valid to
call both. Shouldn't skb_checksum_help() also WARN and return an error
code instead of muddling on?
Inspecting the callers of skb_checksum_help(), it looks like sch_netem's
'corrupt' option and xt_CHECKSUM might trigger this case.
Ben.
Netem needs to check for GSO manually segment before calling skb_checksum_help.
I'll sort it out.
From: Stephen Hemminger <hidden> Date: 2012-01-13 00:57:20
Probably something like this is needed (untested).
This issue was discovered when looking at the skb_checksum path for the
netem corruption operation, but it is a general problem.
Network emulation operations like corruption and drop want to operate
on a per-packet (not per-segment) basis. This patch does GSO in software
if necessary to break up packets. Code is similar to logic in xfrm_output.
Although it appears that the operation is not work conserving, it is okay
because the higher level qdisc operations account for packets by incrementing
by gso_size.
Signed-off-by: Stephen Hemminger <redacted>
@@ -355,6 +357,41 @@ static int tfifo_enqueue(struct sk_buffreturnqdisc_reshape_fail(nskb,sch);}+staticintnetem_enqueue_gso(structsk_buff*skb,structQdisc*sch)+{+structsk_buff*segs;+intrc;++segs=skb_gso_segment(skb,0);+kfree_skb(skb);++if(IS_ERR(segs)){+sch->qstats.drops++;+returnNET_XMIT_DROP;+}++do{+structsk_buff*nskb=segs->next;+intret;++segs->next=NULL;+ret=netem_enqueue(segs,sch);+if(ret==NET_XMIT_DROP){+while((segs=nskb)){+nskb=segs->next;+segs->next=NULL;+kfree_skb(segs);+}+returnret;+}++segs=nskb;+}while(segs);++returnNET_XMIT_SUCCESS;+}++/**Insertoneskbintoqdisc.*Note:parentdependsonreturnvaluetoaccountforqueuelength.
@@ -370,6 +407,10 @@ static int netem_enqueue(struct sk_buffintret;intcount=1;+/* Want to operate on per-packet basis */+if(skb_is_gso(skb))+returnnetem_enqueue_gso(skb,sch);+/* Random duplication */if(q->duplicate&&q->duplicate>=get_crandom(&q->dup_cor))++count;
From: Eric Dumazet <hidden> Date: 2012-01-13 15:54:57
Le jeudi 12 janvier 2012 à 16:57 -0800, Stephen Hemminger a écrit :
Probably something like this is needed (untested).
This issue was discovered when looking at the skb_checksum path for the
netem corruption operation, but it is a general problem.
Network emulation operations like corruption and drop want to operate
on a per-packet (not per-segment) basis. This patch does GSO in software
if necessary to break up packets. Code is similar to logic in xfrm_output.
Although it appears that the operation is not work conserving, it is okay
because the higher level qdisc operations account for packets by incrementing
by gso_size.
gso_size ok, but what about qlen ?
We end up splitting one GSO skb in multiple segments, but shouldnt we
instruct upper qdisc(s) that qlen was increased, sort of
qdisc_tree_increase_qlen() call ?
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Stephen Hemminger <hidden> Date: 2012-01-13 19:20:28
On Fri, 13 Jan 2012 16:54:57 +0100
Eric Dumazet [off-list ref] wrote:
Le jeudi 12 janvier 2012 à 16:57 -0800, Stephen Hemminger a écrit :
quoted
Probably something like this is needed (untested).
This issue was discovered when looking at the skb_checksum path for the
netem corruption operation, but it is a general problem.
Network emulation operations like corruption and drop want to operate
on a per-packet (not per-segment) basis. This patch does GSO in software
if necessary to break up packets. Code is similar to logic in xfrm_output.
Although it appears that the operation is not work conserving, it is okay
because the higher level qdisc operations account for packets by incrementing
by gso_size.
gso_size ok, but what about qlen ?
We end up splitting one GSO skb in multiple segments, but shouldnt we
instruct upper qdisc(s) that qlen was increased, sort of
qdisc_tree_increase_qlen() call ?
Also, does pkt_len need to be set in cb after de-gso?
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Eric Dumazet <hidden> Date: 2012-01-13 23:44:11
Le vendredi 13 janvier 2012 à 11:20 -0800, Stephen Hemminger a écrit :
Also, does pkt_len need to be set in cb after de-gso?
Yes, most probably :)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Hagen Paul Pfeifer <hidden> Date: 2012-01-14 16:06:48
* Stephen Hemminger | 2012-01-12 16:57:20 [-0800]:
Probably something like this is needed (untested).
This issue was discovered when looking at the skb_checksum path for the
netem corruption operation, but it is a general problem.
Network emulation operations like corruption and drop want to operate
on a per-packet (not per-segment) basis. This patch does GSO in software
if necessary to break up packets. Code is similar to logic in xfrm_output.
Although it appears that the operation is not work conserving, it is okay
because the higher level qdisc operations account for packets by incrementing
by gso_size.
Thanks Stephen! Corruption is currently unusable if GSO is enabled. We disable
GSO/TSO on all our test machines therefore.
I have a larger set of patches for the corruption option for this merge
window. We will now test your patch (and the hopefully following qdisc len
updated patch).
Hagen