Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8921ca8 authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller
Browse files

ip4ip6: Support for GSO/GRO

parent 815d22e5
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -39,6 +39,11 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family,
int inet_recv_error(struct sock *sk, struct msghdr *msg, int len,
		    int *addr_len);

struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb);
int inet_gro_complete(struct sk_buff *skb, int nhoff);
struct sk_buff *inet_gso_segment(struct sk_buff *skb,
				 netdev_features_t features);

static inline void inet_ctl_sock_destroy(struct sock *sk)
{
	if (sk)
+7 −5
Original line number Diff line number Diff line
@@ -1192,7 +1192,7 @@ int inet_sk_rebuild_header(struct sock *sk)
}
EXPORT_SYMBOL(inet_sk_rebuild_header);

static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
struct sk_buff *inet_gso_segment(struct sk_buff *skb,
				 netdev_features_t features)
{
	bool udpfrag = false, fixedid = false, encap;
@@ -1280,9 +1280,9 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
out:
	return segs;
}
EXPORT_SYMBOL(inet_gso_segment);

static struct sk_buff **inet_gro_receive(struct sk_buff **head,
					 struct sk_buff *skb)
struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb)
{
	const struct net_offload *ops;
	struct sk_buff **pp = NULL;
@@ -1398,6 +1398,7 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,

	return pp;
}
EXPORT_SYMBOL(inet_gro_receive);

static struct sk_buff **ipip_gro_receive(struct sk_buff **head,
					 struct sk_buff *skb)
@@ -1449,7 +1450,7 @@ int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
	return -EINVAL;
}

static int inet_gro_complete(struct sk_buff *skb, int nhoff)
int inet_gro_complete(struct sk_buff *skb, int nhoff)
{
	__be16 newlen = htons(skb->len - nhoff);
	struct iphdr *iph = (struct iphdr *)(skb->data + nhoff);
@@ -1479,6 +1480,7 @@ static int inet_gro_complete(struct sk_buff *skb, int nhoff)

	return err;
}
EXPORT_SYMBOL(inet_gro_complete);

static int ipip_gro_complete(struct sk_buff *skb, int nhoff)
{
+32 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include <net/protocol.h>
#include <net/ipv6.h>
#include <net/inet_common.h>

#include "ip6_offload.h"

@@ -268,6 +269,21 @@ static struct sk_buff **sit_ip6ip6_gro_receive(struct sk_buff **head,
	return ipv6_gro_receive(head, skb);
}

static struct sk_buff **ip4ip6_gro_receive(struct sk_buff **head,
					   struct sk_buff *skb)
{
	/* Common GRO receive for SIT and IP6IP6 */

	if (NAPI_GRO_CB(skb)->encap_mark) {
		NAPI_GRO_CB(skb)->flush = 1;
		return NULL;
	}

	NAPI_GRO_CB(skb)->encap_mark = 1;

	return inet_gro_receive(head, skb);
}

static int ipv6_gro_complete(struct sk_buff *skb, int nhoff)
{
	const struct net_offload *ops;
@@ -307,6 +323,13 @@ static int ip6ip6_gro_complete(struct sk_buff *skb, int nhoff)
	return ipv6_gro_complete(skb, nhoff);
}

static int ip4ip6_gro_complete(struct sk_buff *skb, int nhoff)
{
	skb->encapsulation = 1;
	skb_shinfo(skb)->gso_type |= SKB_GSO_IPXIP6;
	return inet_gro_complete(skb, nhoff);
}

static struct packet_offload ipv6_packet_offload __read_mostly = {
	.type = cpu_to_be16(ETH_P_IPV6),
	.callbacks = {
@@ -324,6 +347,14 @@ static const struct net_offload sit_offload = {
	},
};

static const struct net_offload ip4ip6_offload = {
	.callbacks = {
		.gso_segment	= inet_gso_segment,
		.gro_receive    = ip4ip6_gro_receive,
		.gro_complete   = ip4ip6_gro_complete,
	},
};

static const struct net_offload ip6ip6_offload = {
	.callbacks = {
		.gso_segment	= ipv6_gso_segment,
@@ -331,7 +362,6 @@ static const struct net_offload ip6ip6_offload = {
		.gro_complete   = ip6ip6_gro_complete,
	},
};

static int __init ipv6_offload_init(void)
{

@@ -344,6 +374,7 @@ static int __init ipv6_offload_init(void)

	inet_add_offload(&sit_offload, IPPROTO_IPV6);
	inet6_add_offload(&ip6ip6_offload, IPPROTO_IPV6);
	inet6_add_offload(&ip4ip6_offload, IPPROTO_IPIP);

	return 0;
}
+5 −0
Original line number Diff line number Diff line
@@ -1188,6 +1188,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
	if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
		fl6.flowi6_mark = skb->mark;

	if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
		return -1;

	skb_set_inner_ipproto(skb, IPPROTO_IPIP);

	err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
			   IPPROTO_IPIP);
	if (err != 0) {