Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/ipv4/ip_output: Reserve some additional space in headroom of outgoing SKBs during IPv4 fragmentation #11

Merged
merged 2 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,14 @@ static inline bool dev_xmit_complete(int rc)
* to allocate 16 more bytes (5 - TLS header, 8 - IV, 3 - alignment).
*/
#define TLS_MAX_HDR 16
/*
* For fast transformation of HTTP/1.1 responses into HTTP/2 format, Tempesta
* uses zero-copy in-place rewriting of the response data, right in original
* skb. HTTP/2 data is almost always smaller of its source HTTP/1.1 data, but
* for the sake of robustness we use 32-byte initial offset in front of skb
* data. Thus, in order to guarantee the stack headers to fit, we should
* increase the total space for them.
*/
#define HTTP2_MAX_OFFSET 32
#else
#define TLS_MAX_HDR 0
#define HTTP2_MAX_OFFSET 0
#endif
#if !IS_ENABLED(CONFIG_NET_IPIP) && !IS_ENABLED(CONFIG_NET_IPGRE) && \
!IS_ENABLED(CONFIG_IPV6_SIT) && !IS_ENABLED(CONFIG_IPV6_TUNNEL)
#define MAX_HEADER (LL_MAX_HEADER + TLS_MAX_HDR + HTTP2_MAX_OFFSET)
#define MAX_HEADER (LL_MAX_HEADER + TLS_MAX_HDR)
#else
#define MAX_HEADER (LL_MAX_HEADER + 48 + TLS_MAX_HDR + HTTP2_MAX_OFFSET)
#define MAX_HEADER (LL_MAX_HEADER + 48 + TLS_MAX_HDR)
#endif

/*
Expand Down
31 changes: 31 additions & 0 deletions net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@
#include <linux/netfilter_bridge.h>
#include <linux/netlink.h>
#include <linux/tcp.h>
#ifdef CONFIG_SECURITY_TEMPESTA
#include <net/tcp.h>
#endif

static int
ip_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
Expand Down Expand Up @@ -702,7 +705,31 @@ struct sk_buff *ip_frag_next(struct sk_buff *skb, struct ip_frag_state *state)
}

/* Allocate buffer */
#ifdef CONFIG_SECURITY_TEMPESTA
/*
* Since Tempesta FW tries to reuse incoming SKBs containing the response
* from the backend, sometimes we might encounter an SKB with quite a small
* head room, which is not big enough to accommodate all the transport headers
* and TLS overhead.
* It usually the case when working over loopback, tun/tap, bridge or similar
* interfaces with small MTU. The issue is specific to aforementioned ifaces
* because the outgoing SKB would be injected back to the stack.
* In order not to reallocate sk_buffs' headroom on RX path,
* allocate and reserve a little bit more memory on TX path.
* Even though it would introduce some memory overhead, it's still
* cheaper than doing transformation.
*
* It seems like no such actions are required for IPv6 counterparts:
* ip6_fragment() / ip6_frag_next() due to the fact that the
* lowest acceptable MTU (1280) is sufficient to fit all the headers.
*
* When receiving SKBs from the outter world, the NIC driver should
* allocate and reserve all necessary space by itself.
*/
skb2 = alloc_skb(len + state->hlen + MAX_TCP_HEADER, GFP_ATOMIC);
#else
skb2 = alloc_skb(len + state->hlen + state->ll_rs, GFP_ATOMIC);
#endif
if (!skb2)
return ERR_PTR(-ENOMEM);

Expand All @@ -711,7 +738,11 @@ struct sk_buff *ip_frag_next(struct sk_buff *skb, struct ip_frag_state *state)
*/

ip_copy_metadata(skb2, skb);
#ifdef CONFIG_SECURITY_TEMPESTA
skb_reserve(skb2, MAX_TCP_HEADER);
#else
skb_reserve(skb2, state->ll_rs);
#endif
skb_put(skb2, len + state->hlen);
skb_reset_network_header(skb2);
skb2->transport_header = skb2->network_header + state->hlen;
Expand Down