// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  SR-IPv6 implementation
 *
 *  Author:
 *  David Lebrun <david.lebrun@uclouvain.be>
 */

#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/net.h>
#include <linux/module.h>
#include <net/ip.h>
#include <net/ip_tunnels.h>
#include <net/lwtunnel.h>
#include <net/netevent.h>
#include <net/netns/generic.h>
#include <net/ip6_fib.h>
#include <net/route.h>
#include <net/seg6.h>
#include <linux/seg6.h>
#include <linux/seg6_iptunnel.h>
#include <net/addrconf.h>
#include <net/ip6_route.h>
#include <net/dst_cache.h>
#ifdef CONFIG_IPV6_SEG6_HMAC
#include <net/seg6_hmac.h>
#endif
#include <linux/netfilter.h>

static size_t seg6_lwt_headroom(struct seg6_iptunnel_encap *tuninfo)
{
	int head = 0;

	switch (tuninfo->mode) {
	case SEG6_IPTUN_MODE_INLINE:
		break;
	case SEG6_IPTUN_MODE_ENCAP:
	case SEG6_IPTUN_MODE_ENCAP_RED:
		head = sizeof(struct ipv6hdr);
		break;
	case SEG6_IPTUN_MODE_L2ENCAP:
	case SEG6_IPTUN_MODE_L2ENCAP_RED:
		return 0;
	}

	return ((tuninfo->srh->hdrlen + 1) << 3) + head;
}

struct seg6_lwt {
	struct dst_cache cache_input;
	struct dst_cache cache_output;
	struct in6_addr tunsrc;
	struct seg6_iptunnel_encap tuninfo[];
};

static inline struct seg6_lwt *seg6_lwt_lwtunnel(struct lwtunnel_state *lwt)
{
	return (struct seg6_lwt *)lwt->data;
}

static inline struct seg6_iptunnel_encap *
seg6_encap_lwtunnel(struct lwtunnel_state *lwt)
{
	return seg6_lwt_lwtunnel(lwt)->tuninfo;
}

static const struct nla_policy seg6_iptunnel_policy[SEG6_IPTUNNEL_MAX + 1] = {
	[SEG6_IPTUNNEL_SRH]	= { .type = NLA_BINARY },
	[SEG6_IPTUNNEL_SRC]	= NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
};

static int nla_put_srh(struct sk_buff *skb, int attrtype,
		       struct seg6_iptunnel_encap *tuninfo)
{
	struct seg6_iptunnel_encap *data;
	struct nlattr *nla;
	int len;

	len = SEG6_IPTUN_ENCAP_SIZE(tuninfo);

	nla = nla_reserve(skb, attrtype, len);
	if (!nla)
		return -EMSGSIZE;

	data = nla_data(nla);
	memcpy(data, tuninfo, len);

	return 0;
}

static void set_tun_src(struct net *net, struct net_device *dev,
			struct in6_addr *daddr, struct in6_addr *saddr,
			struct in6_addr *route_tunsrc)
{
	struct seg6_pernet_data *sdata = seg6_pernet(net);
	struct in6_addr *tun_src;

	/* Priority order to select tunnel source address:
	 *  1. per route source address (if configured)
	 *  2. per network namespace source address (if configured)
	 *  3. dynamic resolution
	 */
	if (route_tunsrc && !ipv6_addr_any(route_tunsrc)) {
		memcpy(saddr, route_tunsrc, sizeof(struct in6_addr));
	} else {
		rcu_read_lock();
		tun_src = rcu_dereference(sdata->tun_src);

		if (!ipv6_addr_any(tun_src)) {
			memcpy(saddr, tun_src, sizeof(struct in6_addr));
		} else {
			ipv6_dev_get_saddr(net, dev, daddr,
					   IPV6_PREFER_SRC_PUBLIC, saddr);
		}

		rcu_read_unlock();
	}
}

/* Compute flowlabel for outer IPv6 header */
static __be32 seg6_make_flowlabel(struct net *net, struct sk_buff *skb,
				  struct ipv6hdr *inner_hdr)
{
	int do_flowlabel = net->ipv6.sysctl.seg6_flowlabel;
	__be32 flowlabel = 0;
	u32 hash;

	if (do_flowlabel > 0) {
		hash = skb_get_hash(skb);
		hash = rol32(hash, 16);
		flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;
	} else if (!do_flowlabel && skb->protocol == htons(ETH_P_IPV6)) {
		flowlabel = ip6_flowlabel(inner_hdr);
	}
	return flowlabel;
}

static int __seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh,
			       int proto, struct dst_entry *cache_dst,
			       struct in6_addr *route_tunsrc)
{
	struct dst_entry *dst = skb_dst(skb);
	struct net_device *dev = dst_dev(dst);
	struct net *net = dev_net(dev);
	struct ipv6hdr *hdr, *inner_hdr;
	struct ipv6_sr_hdr *isrh;
	int hdrlen, tot_len, err;
	__be32 flowlabel;

	hdrlen = (osrh->hdrlen + 1) << 3;
	tot_len = hdrlen + sizeof(*hdr);

	err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb));
	if (unlikely(err))
		return err;

	inner_hdr = ipv6_hdr(skb);
	flowlabel = seg6_make_flowlabel(net, skb, inner_hdr);

	skb_push(skb, tot_len);
	skb_reset_network_header(skb);
	skb_mac_header_rebuild(skb);
	hdr = ipv6_hdr(skb);

	/* inherit tc, flowlabel and hlim
	 * hlim will be decremented in ip6_forward() afterwards and
	 * decapsulation will overwrite inner hlim with outer hlim
	 */

	if (skb->protocol == htons(ETH_P_IPV6)) {
		ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)),
			     flowlabel);
		hdr->hop_limit = inner_hdr->hop_limit;
	} else {
		ip6_flow_hdr(hdr, 0, flowlabel);
		hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb));

		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));

		/* the control block has been erased, so we have to set the
		 * iif once again.
		 * We read the receiving interface index directly from the
		 * skb->skb_iif as it is done in the IPv4 receiving path (i.e.:
		 * ip_rcv_core(...)).
		 */
		IP6CB(skb)->iif = skb->skb_iif;
	}

	hdr->nexthdr = NEXTHDR_ROUTING;

	isrh = (void *)hdr + sizeof(*hdr);
	memcpy(isrh, osrh, hdrlen);

	isrh->nexthdr = proto;

	hdr->daddr = isrh->segments[isrh->first_segment];
	set_tun_src(net, dev, &hdr->daddr, &hdr->saddr, route_tunsrc);

#ifdef CONFIG_IPV6_SEG6_HMAC
	if (sr_has_hmac(isrh)) {
		err = seg6_push_hmac(net, &hdr->saddr, isrh);
		if (unlikely(err))
			return err;
	}
#endif

	hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));

	skb_postpush_rcsum(skb, hdr, tot_len);

	return 0;
}

/* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */
int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
{
	return __seg6_do_srh_encap(skb, osrh, proto, NULL, NULL);
}
EXPORT_SYMBOL_GPL(seg6_do_srh_encap);

/* encapsulate an IPv6 packet within an outer IPv6 header with reduced SRH */
static int seg6_do_srh_encap_red(struct sk_buff *skb,
				 struct ipv6_sr_hdr *osrh, int proto,
				 struct dst_entry *cache_dst,
				 struct in6_addr *route_tunsrc)
{
	__u8 first_seg = osrh->first_segment;
	struct dst_entry *dst = skb_dst(skb);
	struct net_device *dev = dst_dev(dst);
	struct net *net = dev_net(dev);
	struct ipv6hdr *hdr, *inner_hdr;
	int hdrlen = ipv6_optlen(osrh);
	int red_tlv_offset, tlv_offset;
	struct ipv6_sr_hdr *isrh;
	bool skip_srh = false;
	__be32 flowlabel;
	int tot_len, err;
	int red_hdrlen;
	int tlvs_len;

	if (first_seg > 0) {
		red_hdrlen = hdrlen - sizeof(struct in6_addr);
	} else {
		/* NOTE: if tag/flags and/or other TLVs are introduced in the
		 * seg6_iptunnel infrastructure, they should be considered when
		 * deciding to skip the SRH.
		 */
		skip_srh = !sr_has_hmac(osrh);

		red_hdrlen = skip_srh ? 0 : hdrlen;
	}

	tot_len = red_hdrlen + sizeof(struct ipv6hdr);

	err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb));
	if (unlikely(err))
		return err;

	inner_hdr = ipv6_hdr(skb);
	flowlabel = seg6_make_flowlabel(net, skb, inner_hdr);

	skb_push(skb, tot_len);
	skb_reset_network_header(skb);
	skb_mac_header_rebuild(skb);
	hdr = ipv6_hdr(skb);

	/* based on seg6_do_srh_encap() */
	if (skb->protocol == htons(ETH_P_IPV6)) {
		ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)),
			     flowlabel);
		hdr->hop_limit = inner_hdr->hop_limit;
	} else {
		ip6_flow_hdr(hdr, 0, flowlabel);
		hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb));

		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
		IP6CB(skb)->iif = skb->skb_iif;
	}

	/* no matter if we have to skip the SRH or not, the first segment
	 * always comes in the pushed IPv6 header.
	 */
	hdr->daddr = osrh->segments[first_seg];

	if (skip_srh) {
		hdr->nexthdr = proto;

		set_tun_src(net, dev, &hdr->daddr, &hdr->saddr, route_tunsrc);
		goto out;
	}

	/* we cannot skip the SRH, slow path */

	hdr->nexthdr = NEXTHDR_ROUTING;
	isrh = (void *)hdr + sizeof(struct ipv6hdr);

	if (unlikely(!first_seg)) {
		/* this is a very rare case; we have only one SID but
		 * we cannot skip the SRH since we are carrying some
		 * other info.
		 */
		memcpy(isrh, osrh, hdrlen);
		goto srcaddr;
	}

	tlv_offset = sizeof(*osrh) + (first_seg + 1) * sizeof(struct in6_addr);
	red_tlv_offset = tlv_offset - sizeof(struct in6_addr);

	memcpy(isrh, osrh, red_tlv_offset);

	tlvs_len = hdrlen - tlv_offset;
	if (unlikely(tlvs_len > 0)) {
		const void *s = (const void *)osrh + tlv_offset;
		void *d = (void *)isrh + red_tlv_offset;

		memcpy(d, s, tlvs_len);
	}

	--isrh->first_segment;
	isrh->hdrlen -= 2;

srcaddr:
	isrh->nexthdr = proto;
	set_tun_src(net, dev, &hdr->daddr, &hdr->saddr, route_tunsrc);

#ifdef CONFIG_IPV6_SEG6_HMAC
	if (unlikely(!skip_srh && sr_has_hmac(isrh))) {
		err = seg6_push_hmac(net, &hdr->saddr, isrh);
		if (unlikely(err))
			return err;
	}
#endif

out:
	hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));

	skb_postpush_rcsum(skb, hdr, tot_len);

	return 0;
}

static int __seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh,
				struct dst_entry *cache_dst)
{
	struct ipv6hdr *hdr, *oldhdr;
	struct ipv6_sr_hdr *isrh;
	int hdrlen, err;

	hdrlen = (osrh->hdrlen + 1) << 3;

	err = skb_cow_head(skb, hdrlen + dst_dev_overhead(cache_dst, skb));
	if (unlikely(err))
		return err;

	oldhdr = ipv6_hdr(skb);

	skb_pull(skb, sizeof(struct ipv6hdr));
	skb_postpull_rcsum(skb, skb_network_header(skb),
			   sizeof(struct ipv6hdr));

	skb_push(skb, sizeof(struct ipv6hdr) + hdrlen);
	skb_reset_network_header(skb);
	skb_mac_header_rebuild(skb);

	hdr = ipv6_hdr(skb);

	memmove(hdr, oldhdr, sizeof(*hdr));

	isrh = (void *)hdr + sizeof(*hdr);
	memcpy(isrh, osrh, hdrlen);

	isrh->nexthdr = hdr->nexthdr;
	hdr->nexthdr = NEXTHDR_ROUTING;

	isrh->segments[0] = hdr->daddr;
	hdr->daddr = isrh->segments[isrh->first_segment];

#ifdef CONFIG_IPV6_SEG6_HMAC
	if (sr_has_hmac(isrh)) {
		struct net *net = skb_dst_dev_net(skb);

		err = seg6_push_hmac(net, &hdr->saddr, isrh);
		if (unlikely(err))
			return err;
	}
#endif

	hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));

	skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);

	return 0;
}

static int seg6_do_srh(struct sk_buff *skb, struct dst_entry *cache_dst)
{
	struct dst_entry *dst = skb_dst(skb);
	struct seg6_iptunnel_encap *tinfo;
	struct seg6_lwt *slwt;
	int proto, err = 0;

	slwt = seg6_lwt_lwtunnel(dst->lwtstate);
	tinfo = slwt->tuninfo;

	switch (tinfo->mode) {
	case SEG6_IPTUN_MODE_INLINE:
		if (skb->protocol != htons(ETH_P_IPV6))
			return -EINVAL;

		err = __seg6_do_srh_inline(skb, tinfo->srh, cache_dst);
		if (err)
			return err;
		break;
	case SEG6_IPTUN_MODE_ENCAP:
	case SEG6_IPTUN_MODE_ENCAP_RED:
		err = iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6);
		if (err)
			return err;

		if (skb->protocol == htons(ETH_P_IPV6))
			proto = IPPROTO_IPV6;
		else if (skb->protocol == htons(ETH_P_IP))
			proto = IPPROTO_IPIP;
		else
			return -EINVAL;

		if (tinfo->mode == SEG6_IPTUN_MODE_ENCAP)
			err = __seg6_do_srh_encap(skb, tinfo->srh, proto,
						  cache_dst, &slwt->tunsrc);
		else
			err = seg6_do_srh_encap_red(skb, tinfo->srh, proto,
						    cache_dst, &slwt->tunsrc);

		if (err)
			return err;

		skb_set_inner_transport_header(skb, skb_transport_offset(skb));
		skb_set_inner_protocol(skb, skb->protocol);
		skb->protocol = htons(ETH_P_IPV6);
		break;
	case SEG6_IPTUN_MODE_L2ENCAP:
	case SEG6_IPTUN_MODE_L2ENCAP_RED:
		if (!skb_mac_header_was_set(skb))
			return -EINVAL;

		if (pskb_expand_head(skb, skb->mac_len, 0, GFP_ATOMIC) < 0)
			return -ENOMEM;

		skb_mac_header_rebuild(skb);
		skb_push(skb, skb->mac_len);

		if (tinfo->mode == SEG6_IPTUN_MODE_L2ENCAP)
			err = __seg6_do_srh_encap(skb, tinfo->srh,
						  IPPROTO_ETHERNET, cache_dst,
						  &slwt->tunsrc);
		else
			err = seg6_do_srh_encap_red(skb, tinfo->srh,
						    IPPROTO_ETHERNET, cache_dst,
						    &slwt->tunsrc);

		if (err)
			return err;

		skb->protocol = htons(ETH_P_IPV6);
		break;
	}

	skb_set_transport_header(skb, sizeof(struct ipv6hdr));
	nf_reset_ct(skb);

	return 0;
}

/* insert an SRH within an IPv6 packet, just after the IPv6 header */
int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
{
	return __seg6_do_srh_inline(skb, osrh, NULL);
}
EXPORT_SYMBOL_GPL(seg6_do_srh_inline);

static int seg6_input_finish(struct net *net, struct sock *sk,
			     struct sk_buff *skb)
{
	return dst_input(skb);
}

static int seg6_input_core(struct net *net, struct sock *sk,
			   struct sk_buff *skb)
{
	struct dst_entry *orig_dst = skb_dst(skb);
	struct dst_entry *dst = NULL;
	struct lwtunnel_state *lwtst;
	struct seg6_lwt *slwt;
	int err;

	/* We cannot dereference "orig_dst" once ip6_route_input() or
	 * skb_dst_drop() is called. However, in order to detect a dst loop, we
	 * need the address of its lwtstate. So, save the address of lwtstate
	 * now and use it later as a comparison.
	 */
	lwtst = orig_dst->lwtstate;

	slwt = seg6_lwt_lwtunnel(lwtst);

	local_bh_disable();
	dst = dst_cache_get(&slwt->cache_input);
	local_bh_enable();

	err = seg6_do_srh(skb, dst);
	if (unlikely(err)) {
		dst_release(dst);
		goto drop;
	}

	if (!dst) {
		ip6_route_input(skb);

		/* ip6_route_input() sets a NOREF dst; force a refcount on it
		 * before caching or further use.
		 */
		skb_dst_force(skb);
		dst = skb_dst(skb);
		if (unlikely(!dst)) {
			err = -ENETUNREACH;
			goto drop;
		}

		/* cache only if we don't create a dst reference loop */
		if (!dst->error && lwtst != dst->lwtstate) {
			local_bh_disable();
			dst_cache_set_ip6(&slwt->cache_input, dst,
					  &ipv6_hdr(skb)->saddr);
			local_bh_enable();
		}

		err = skb_cow_head(skb, LL_RESERVED_SPACE(dst_dev(dst)));
		if (unlikely(err))
			goto drop;
	} else {
		skb_dst_drop(skb);
		skb_dst_set(skb, dst);
	}

	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
		return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
			       dev_net(skb->dev), NULL, skb, NULL,
			       skb_dst_dev(skb), seg6_input_finish);

	return seg6_input_finish(dev_net(skb->dev), NULL, skb);
drop:
	kfree_skb(skb);
	return err;
}

static int seg6_input_nf(struct sk_buff *skb)
{
	struct net_device *dev = skb_dst_dev(skb);
	struct net *net = dev_net(skb->dev);

	switch (skb->protocol) {
	case htons(ETH_P_IP):
		return NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, NULL,
			       skb, NULL, dev, seg6_input_core);
	case htons(ETH_P_IPV6):
		return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, NULL,
			       skb, NULL, dev, seg6_input_core);
	}

	return -EINVAL;
}

static int seg6_input(struct sk_buff *skb)
{
	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
		return seg6_input_nf(skb);

	return seg6_input_core(dev_net(skb->dev), NULL, skb);
}

static int seg6_output_core(struct net *net, struct sock *sk,
			    struct sk_buff *skb)
{
	struct dst_entry *orig_dst = skb_dst(skb);
	struct dst_entry *dst = NULL;
	struct seg6_lwt *slwt;
	int err;

	slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);

	local_bh_disable();
	dst = dst_cache_get(&slwt->cache_output);
	local_bh_enable();

	err = seg6_do_srh(skb, dst);
	if (unlikely(err))
		goto drop;

	if (unlikely(!dst)) {
		struct ipv6hdr *hdr = ipv6_hdr(skb);
		struct flowi6 fl6;

		memset(&fl6, 0, sizeof(fl6));
		fl6.daddr = hdr->daddr;
		fl6.saddr = hdr->saddr;
		fl6.flowlabel = ip6_flowinfo(hdr);
		fl6.flowi6_mark = skb->mark;
		fl6.flowi6_proto = hdr->nexthdr;

		dst = ip6_route_output(net, NULL, &fl6);
		if (dst->error) {
			err = dst->error;
			goto drop;
		}

		/* cache only if we don't create a dst reference loop */
		if (orig_dst->lwtstate != dst->lwtstate) {
			local_bh_disable();
			dst_cache_set_ip6(&slwt->cache_output, dst, &fl6.saddr);
			local_bh_enable();
		}

		err = skb_cow_head(skb, LL_RESERVED_SPACE(dst_dev(dst)));
		if (unlikely(err))
			goto drop;
	}

	skb_dst_drop(skb);
	skb_dst_set(skb, dst);

	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
		return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb,
			       NULL, dst_dev(dst), dst_output);

	return dst_output(net, sk, skb);
drop:
	dst_release(dst);
	kfree_skb(skb);
	return err;
}

static int seg6_output_nf(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	struct net_device *dev = skb_dst_dev(skb);

	switch (skb->protocol) {
	case htons(ETH_P_IP):
		return NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, sk, skb,
			       NULL, dev, seg6_output_core);
	case htons(ETH_P_IPV6):
		return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, sk, skb,
			       NULL, dev, seg6_output_core);
	}

	return -EINVAL;
}

static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
		return seg6_output_nf(net, sk, skb);

	return seg6_output_core(net, sk, skb);
}

static int seg6_build_state(struct net *net, struct nlattr *nla,
			    unsigned int family, const void *cfg,
			    struct lwtunnel_state **ts,
			    struct netlink_ext_ack *extack)
{
	struct nlattr *tb[SEG6_IPTUNNEL_MAX + 1];
	struct seg6_iptunnel_encap *tuninfo;
	struct lwtunnel_state *newts;
	int tuninfo_len, min_size;
	struct seg6_lwt *slwt;
	int err;

	if (family != AF_INET && family != AF_INET6)
		return -EINVAL;

	err = nla_parse_nested_deprecated(tb, SEG6_IPTUNNEL_MAX, nla,
					  seg6_iptunnel_policy, extack);

	if (err < 0)
		return err;

	if (!tb[SEG6_IPTUNNEL_SRH])
		return -EINVAL;

	tuninfo = nla_data(tb[SEG6_IPTUNNEL_SRH]);
	tuninfo_len = nla_len(tb[SEG6_IPTUNNEL_SRH]);

	/* tuninfo must contain at least the iptunnel encap structure,
	 * the SRH and one segment
	 */
	min_size = sizeof(*tuninfo) + sizeof(struct ipv6_sr_hdr) +
		   sizeof(struct in6_addr);
	if (tuninfo_len < min_size)
		return -EINVAL;

	switch (tuninfo->mode) {
	case SEG6_IPTUN_MODE_INLINE:
		if (family != AF_INET6)
			return -EINVAL;

		if (tb[SEG6_IPTUNNEL_SRC]) {
			NL_SET_ERR_MSG(extack, "incompatible mode for tunsrc");
			return -EINVAL;
		}
		break;
	case SEG6_IPTUN_MODE_ENCAP:
		break;
	case SEG6_IPTUN_MODE_L2ENCAP:
		break;
	case SEG6_IPTUN_MODE_ENCAP_RED:
		break;
	case SEG6_IPTUN_MODE_L2ENCAP_RED:
		break;
	default:
		return -EINVAL;
	}

	/* verify that SRH is consistent */
	if (!seg6_validate_srh(tuninfo->srh, tuninfo_len - sizeof(*tuninfo), false))
		return -EINVAL;

	newts = lwtunnel_state_alloc(tuninfo_len + sizeof(*slwt));
	if (!newts)
		return -ENOMEM;

	slwt = seg6_lwt_lwtunnel(newts);

	err = dst_cache_init(&slwt->cache_input, GFP_ATOMIC);
	if (err)
		goto err_free_newts;

	err = dst_cache_init(&slwt->cache_output, GFP_ATOMIC);
	if (err)
		goto err_destroy_input;

	memcpy(&slwt->tuninfo, tuninfo, tuninfo_len);

	if (tb[SEG6_IPTUNNEL_SRC]) {
		slwt->tunsrc = nla_get_in6_addr(tb[SEG6_IPTUNNEL_SRC]);

		if (ipv6_addr_any(&slwt->tunsrc) ||
		    ipv6_addr_is_multicast(&slwt->tunsrc) ||
		    ipv6_addr_loopback(&slwt->tunsrc)) {
			NL_SET_ERR_MSG(extack, "invalid tunsrc address");
			err = -EINVAL;
			goto err_destroy_output;
		}
	}

	newts->type = LWTUNNEL_ENCAP_SEG6;
	newts->flags |= LWTUNNEL_STATE_INPUT_REDIRECT;

	if (tuninfo->mode != SEG6_IPTUN_MODE_L2ENCAP &&
	    tuninfo->mode != SEG6_IPTUN_MODE_L2ENCAP_RED)
		newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT;

	newts->headroom = seg6_lwt_headroom(tuninfo);

	*ts = newts;

	return 0;

err_destroy_output:
	dst_cache_destroy(&slwt->cache_output);
err_destroy_input:
	dst_cache_destroy(&slwt->cache_input);
err_free_newts:
	kfree(newts);
	return err;
}

static void seg6_destroy_state(struct lwtunnel_state *lwt)
{
	struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwt);

	dst_cache_destroy(&slwt->cache_input);
	dst_cache_destroy(&slwt->cache_output);
}

static int seg6_fill_encap_info(struct sk_buff *skb,
				struct lwtunnel_state *lwtstate)
{
	struct seg6_iptunnel_encap *tuninfo = seg6_encap_lwtunnel(lwtstate);
	struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwtstate);

	if (nla_put_srh(skb, SEG6_IPTUNNEL_SRH, tuninfo))
		return -EMSGSIZE;

	if (!ipv6_addr_any(&slwt->tunsrc) &&
	    nla_put_in6_addr(skb, SEG6_IPTUNNEL_SRC, &slwt->tunsrc))
		return -EMSGSIZE;

	return 0;
}

static int seg6_encap_nlsize(struct lwtunnel_state *lwtstate)
{
	struct seg6_iptunnel_encap *tuninfo = seg6_encap_lwtunnel(lwtstate);
	struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwtstate);
	int nlsize;

	nlsize = nla_total_size(SEG6_IPTUN_ENCAP_SIZE(tuninfo));

	if (!ipv6_addr_any(&slwt->tunsrc))
		nlsize += nla_total_size(sizeof(slwt->tunsrc));

	return nlsize;
}

static int seg6_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
{
	struct seg6_iptunnel_encap *a_hdr = seg6_encap_lwtunnel(a);
	struct seg6_iptunnel_encap *b_hdr = seg6_encap_lwtunnel(b);
	struct seg6_lwt *a_slwt = seg6_lwt_lwtunnel(a);
	struct seg6_lwt *b_slwt = seg6_lwt_lwtunnel(b);
	int len = SEG6_IPTUN_ENCAP_SIZE(a_hdr);

	if (len != SEG6_IPTUN_ENCAP_SIZE(b_hdr))
		return 1;

	if (!ipv6_addr_equal(&a_slwt->tunsrc, &b_slwt->tunsrc))
		return 1;

	return memcmp(a_hdr, b_hdr, len);
}

static const struct lwtunnel_encap_ops seg6_iptun_ops = {
	.build_state = seg6_build_state,
	.destroy_state = seg6_destroy_state,
	.output = seg6_output,
	.input = seg6_input,
	.fill_encap = seg6_fill_encap_info,
	.get_encap_size = seg6_encap_nlsize,
	.cmp_encap = seg6_encap_cmp,
	.owner = THIS_MODULE,
};

int __init seg6_iptunnel_init(void)
{
	return lwtunnel_encap_add_ops(&seg6_iptun_ops, LWTUNNEL_ENCAP_SEG6);
}

void seg6_iptunnel_exit(void)
{
	lwtunnel_encap_del_ops(&seg6_iptun_ops, LWTUNNEL_ENCAP_SEG6);
}
