Skip to content

Commit

Permalink
net: tso: add UDP segmentation support
Browse files Browse the repository at this point in the history
Note that like TCP, we do not support additional encapsulations,
and that checksums must be offloaded to the NIC.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Jun 19, 2020
1 parent 761b331 commit 3d5b459
Showing 1 changed file with 18 additions and 11 deletions.
29 changes: 18 additions & 11 deletions net/core/tso.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ EXPORT_SYMBOL(tso_count_descs);
void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
int size, bool is_last)
{
struct tcphdr *tcph;
int hdr_len = skb_transport_offset(skb) + tso->tlen;
int mac_hdr_len = skb_network_offset(skb);

Expand All @@ -32,21 +31,29 @@ void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,

iph->payload_len = htons(size + tso->tlen);
}
tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
put_unaligned_be32(tso->tcp_seq, &tcph->seq);
hdr += skb_transport_offset(skb);
if (tso->tlen != sizeof(struct udphdr)) {
struct tcphdr *tcph = (struct tcphdr *)hdr;

if (!is_last) {
/* Clear all special flags for not last packet */
tcph->psh = 0;
tcph->fin = 0;
tcph->rst = 0;
put_unaligned_be32(tso->tcp_seq, &tcph->seq);

if (!is_last) {
/* Clear all special flags for not last packet */
tcph->psh = 0;
tcph->fin = 0;
tcph->rst = 0;
}
} else {
struct udphdr *uh = (struct udphdr *)hdr;

uh->len = htons(sizeof(*uh) + size);
}
}
EXPORT_SYMBOL(tso_build_hdr);

void tso_build_data(const struct sk_buff *skb, struct tso_t *tso, int size)
{
tso->tcp_seq += size;
tso->tcp_seq += size; /* not worth avoiding this operation for UDP */
tso->size -= size;
tso->data += size;

Expand All @@ -64,12 +71,12 @@ EXPORT_SYMBOL(tso_build_data);

int tso_start(struct sk_buff *skb, struct tso_t *tso)
{
int tlen = tcp_hdrlen(skb);
int tlen = skb_is_gso_tcp(skb) ? tcp_hdrlen(skb) : sizeof(struct udphdr);
int hdr_len = skb_transport_offset(skb) + tlen;

tso->tlen = tlen;
tso->ip_id = ntohs(ip_hdr(skb)->id);
tso->tcp_seq = ntohl(tcp_hdr(skb)->seq);
tso->tcp_seq = (tlen != sizeof(struct udphdr)) ? ntohl(tcp_hdr(skb)->seq) : 0;
tso->next_frag_idx = 0;
tso->ipv6 = vlan_get_protocol(skb) == htons(ETH_P_IPV6);

Expand Down

0 comments on commit 3d5b459

Please sign in to comment.