Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: tso: add support for IPv6

Adding IPv6 for the TSO helper API is trivial:
* Don't play with the id (which doesn't exist in IPv6)
* Correctly update the payload_len (don't include the
length of the IP header itself)

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

emmanuel.grumbach@intel.com and committed by
David S. Miller
8941faa1 61b9da92

+14 -5
+1
include/net/tso.h
··· 8 8 void *data; 9 9 size_t size; 10 10 u16 ip_id; 11 + bool ipv6; 11 12 u32 tcp_seq; 12 13 }; 13 14
+13 -5
net/core/tso.c
··· 1 1 #include <linux/export.h> 2 + #include <linux/if_vlan.h> 2 3 #include <net/ip.h> 3 4 #include <net/tso.h> 4 5 #include <asm/unaligned.h> ··· 15 14 void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso, 16 15 int size, bool is_last) 17 16 { 18 - struct iphdr *iph; 19 17 struct tcphdr *tcph; 20 18 int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); 21 19 int mac_hdr_len = skb_network_offset(skb); 22 20 23 21 memcpy(hdr, skb->data, hdr_len); 24 - iph = (struct iphdr *)(hdr + mac_hdr_len); 25 - iph->id = htons(tso->ip_id); 26 - iph->tot_len = htons(size + hdr_len - mac_hdr_len); 22 + if (!tso->ipv6) { 23 + struct iphdr *iph = (void *)(hdr + mac_hdr_len); 24 + 25 + iph->id = htons(tso->ip_id); 26 + iph->tot_len = htons(size + hdr_len - mac_hdr_len); 27 + tso->ip_id++; 28 + } else { 29 + struct ipv6hdr *iph = (void *)(hdr + mac_hdr_len); 30 + 31 + iph->payload_len = htons(size + tcp_hdrlen(skb)); 32 + } 27 33 tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb)); 28 34 put_unaligned_be32(tso->tcp_seq, &tcph->seq); 29 - tso->ip_id++; 30 35 31 36 if (!is_last) { 32 37 /* Clear all special flags for not last packet */ ··· 68 61 tso->ip_id = ntohs(ip_hdr(skb)->id); 69 62 tso->tcp_seq = ntohl(tcp_hdr(skb)->seq); 70 63 tso->next_frag_idx = 0; 64 + tso->ipv6 = vlan_get_protocol(skb) == htons(ETH_P_IPV6); 71 65 72 66 /* Build first data */ 73 67 tso->size = skb_headlen(skb) - hdr_len;