/*
 * Network Service Header
 *
 * Copyright (c) 2017 Red Hat, Inc. -- Jiri Benc <jbenc@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/nsh.h>
#include <net/tun_proto.h>

static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
				       netdev_features_t features)
{
	unsigned int outer_hlen, mac_len, nsh_len;
	struct sk_buff *segs = ERR_PTR(-EINVAL);
	u16 mac_offset = skb->mac_header;
	__be16 outer_proto, proto;

	skb_reset_network_header(skb);

	outer_proto = skb->protocol;
	outer_hlen = skb_mac_header_len(skb);
	mac_len = skb->mac_len;

	if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN)))
		goto out;
	nsh_len = nsh_hdr_len(nsh_hdr(skb));
	if (nsh_len < NSH_BASE_HDR_LEN)
		goto out;
	if (unlikely(!pskb_may_pull(skb, nsh_len)))
		goto out;

	proto = tun_p_to_eth_p(nsh_hdr(skb)->np);
	if (!proto)
		goto out;

	__skb_pull(skb, nsh_len);

	skb_reset_mac_header(skb);
	skb->mac_len = proto == htons(ETH_P_TEB) ? ETH_HLEN : 0;
	skb->protocol = proto;

	features &= NETIF_F_SG;
	segs = skb_mac_gso_segment(skb, features);
	if (IS_ERR_OR_NULL(segs)) {
		skb_gso_error_unwind(skb, htons(ETH_P_NSH), nsh_len,
				     mac_offset, mac_len);
		goto out;
	}

	for (skb = segs; skb; skb = skb->next) {
		skb->protocol = outer_proto;
		__skb_push(skb, nsh_len + outer_hlen);
		skb_reset_mac_header(skb);
		skb_set_network_header(skb, outer_hlen);
		skb->mac_len = mac_len;
	}

out:
	return segs;
}

static struct packet_offload nsh_packet_offload __read_mostly = {
	.type = htons(ETH_P_NSH),
	.priority = 15,
	.callbacks = {
		.gso_segment = nsh_gso_segment,
	},
};

static int __init nsh_init_module(void)
{
	dev_add_offload(&nsh_packet_offload);
	return 0;
}

static void __exit nsh_cleanup_module(void)
{
	dev_remove_offload(&nsh_packet_offload);
}

module_init(nsh_init_module);
module_exit(nsh_cleanup_module);

MODULE_AUTHOR("Jiri Benc <jbenc@redhat.com>");
MODULE_DESCRIPTION("NSH protocol");
MODULE_LICENSE("GPL v2");
