Commit feec0cb3 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

ipv6: gro: support sit protocol

Tom Herbert added SIT support to GRO with commit
19424e05 ("sit: Add gro callbacks to sit_offload"),
later reverted by Herbert Xu.

The problem came because Tom patch was building GRO
packets without proper meta data : If packets were locally
delivered, we would not care.

But if packets needed to be forwarded, GSO engine was not
able to segment individual segments.

With the following patch, we correctly set skb->encapsulation
and inner network header. We also update gso_type.

Tested:

Server :
netserver
modprobe dummy
ifconfig dummy0 8.0.0.1 netmask 255.255.255.0 up
arp -s 8.0.0.100 4e:32:51:04:47:e5
iptables -I INPUT -s 10.246.7.151 -j TEE --gateway 8.0.0.100
ifconfig sixtofour0
sixtofour0 Link encap:IPv6-in-IPv4
          inet6 addr: 2002:af6:798::1/128 Scope:Global
          inet6 addr: 2002:af6:798::/128 Scope:Global
          UP RUNNING NOARP  MTU:1480  Metric:1
          RX packets:411169 errors:0 dropped:0 overruns:0 frame:0
          TX packets:409414 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:20319631739 (20.3 GB)  TX bytes:29529556 (29.5 MB)

Client :
netperf -H 2002:af6:798::1 -l 1000 &

Checked on server traffic copied on dummy0 and verify segments were
properly rebuilt, with proper IP headers, TCP checksums...

tcpdump on eth0 shows proper GRO aggregation takes place.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarTom Herbert <tom@herbertland.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8f3af277
...@@ -264,6 +264,9 @@ static int ipv6_gro_complete(struct sk_buff *skb, int nhoff) ...@@ -264,6 +264,9 @@ static int ipv6_gro_complete(struct sk_buff *skb, int nhoff)
struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + nhoff); struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + nhoff);
int err = -ENOSYS; int err = -ENOSYS;
if (skb->encapsulation)
skb_set_inner_network_header(skb, nhoff);
iph->payload_len = htons(skb->len - nhoff - sizeof(*iph)); iph->payload_len = htons(skb->len - nhoff - sizeof(*iph));
rcu_read_lock(); rcu_read_lock();
...@@ -280,6 +283,13 @@ static int ipv6_gro_complete(struct sk_buff *skb, int nhoff) ...@@ -280,6 +283,13 @@ static int ipv6_gro_complete(struct sk_buff *skb, int nhoff)
return err; return err;
} }
static int sit_gro_complete(struct sk_buff *skb, int nhoff)
{
skb->encapsulation = 1;
skb_shinfo(skb)->gso_type |= SKB_GSO_SIT;
return ipv6_gro_complete(skb, nhoff);
}
static struct packet_offload ipv6_packet_offload __read_mostly = { static struct packet_offload ipv6_packet_offload __read_mostly = {
.type = cpu_to_be16(ETH_P_IPV6), .type = cpu_to_be16(ETH_P_IPV6),
.callbacks = { .callbacks = {
...@@ -292,6 +302,8 @@ static struct packet_offload ipv6_packet_offload __read_mostly = { ...@@ -292,6 +302,8 @@ static struct packet_offload ipv6_packet_offload __read_mostly = {
static const struct net_offload sit_offload = { static const struct net_offload sit_offload = {
.callbacks = { .callbacks = {
.gso_segment = ipv6_gso_segment, .gso_segment = ipv6_gso_segment,
.gro_receive = ipv6_gro_receive,
.gro_complete = sit_gro_complete,
}, },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment