This repository has been archived by the owner on Dec 14, 2022. It is now read-only.
forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SCTP has this pecualiarity that its packets cannot be just segmented to (P)MTU. Its chunks must be contained in IP segments, padding respected. So we can't just generate a big skb, set gso_size to the fragmentation point and deliver it to IP layer. This patch takes a different approach. SCTP will now build a skb as it would be if it was received using GRO. That is, there will be a cover skb with protocol headers and children ones containing the actual segments, already segmented to a way that respects SCTP RFCs. With that, we can tell skb_segment() to just split based on frag_list, trusting its sizes are already in accordance. This way SCTP can benefit from GSO and instead of passing several packets through the stack, it can pass a single large packet. v2: - Added support for receiving GSO frames, as requested by Dave Miller. - Clear skb->cb if packet is GSO (otherwise it's not used by SCTP) - Added heuristics similar to what we have in TCP for not generating single GSO packets that fills cwnd. v3: - consider sctphdr size in skb_gso_transport_seglen() - rebased due to 5c7cdf3 ("gso: Remove arbitrary checks for unsupported GSO") Signed-off-by: Marcelo Ricardo Leitner <[email protected]> Tested-by: Xin Long <[email protected]> Signed-off-by: David S. Miller <[email protected]>
- Loading branch information
1 parent
3acb50c
commit 90017ac
Showing
14 changed files
with
429 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* sctp_offload - GRO/GSO Offloading for SCTP | ||
* | ||
* Copyright (C) 2015, Marcelo Ricardo Leitner <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/kprobes.h> | ||
#include <linux/socket.h> | ||
#include <linux/sctp.h> | ||
#include <linux/proc_fs.h> | ||
#include <linux/vmalloc.h> | ||
#include <linux/module.h> | ||
#include <linux/kfifo.h> | ||
#include <linux/time.h> | ||
#include <net/net_namespace.h> | ||
|
||
#include <linux/skbuff.h> | ||
#include <net/sctp/sctp.h> | ||
#include <net/sctp/checksum.h> | ||
#include <net/protocol.h> | ||
|
||
static __le32 sctp_gso_make_checksum(struct sk_buff *skb) | ||
{ | ||
skb->ip_summed = CHECKSUM_NONE; | ||
return sctp_compute_cksum(skb, skb_transport_offset(skb)); | ||
} | ||
|
||
static struct sk_buff *sctp_gso_segment(struct sk_buff *skb, | ||
netdev_features_t features) | ||
{ | ||
struct sk_buff *segs = ERR_PTR(-EINVAL); | ||
struct sctphdr *sh; | ||
|
||
sh = sctp_hdr(skb); | ||
if (!pskb_may_pull(skb, sizeof(*sh))) | ||
goto out; | ||
|
||
__skb_pull(skb, sizeof(*sh)); | ||
|
||
if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { | ||
/* Packet is from an untrusted source, reset gso_segs. */ | ||
struct skb_shared_info *pinfo = skb_shinfo(skb); | ||
struct sk_buff *frag_iter; | ||
|
||
pinfo->gso_segs = 0; | ||
if (skb->len != skb->data_len) { | ||
/* Means we have chunks in here too */ | ||
pinfo->gso_segs++; | ||
} | ||
|
||
skb_walk_frags(skb, frag_iter) | ||
pinfo->gso_segs++; | ||
|
||
segs = NULL; | ||
goto out; | ||
} | ||
|
||
segs = skb_segment(skb, features | NETIF_F_HW_CSUM); | ||
if (IS_ERR(segs)) | ||
goto out; | ||
|
||
/* All that is left is update SCTP CRC if necessary */ | ||
if (!(features & NETIF_F_SCTP_CRC)) { | ||
for (skb = segs; skb; skb = skb->next) { | ||
if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
sh = sctp_hdr(skb); | ||
sh->checksum = sctp_gso_make_checksum(skb); | ||
} | ||
} | ||
} | ||
|
||
out: | ||
return segs; | ||
} | ||
|
||
static const struct net_offload sctp_offload = { | ||
.callbacks = { | ||
.gso_segment = sctp_gso_segment, | ||
}, | ||
}; | ||
|
||
int __init sctp_offload_init(void) | ||
{ | ||
return inet_add_offload(&sctp_offload, IPPROTO_SCTP); | ||
} |
Oops, something went wrong.