/* net/tipc/udp_media.c: IP bearer support for TIPC
 *
 * Copyright (c) 2015, Ericsson AB
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the names of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/inet.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <linux/list.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/udp_tunnel.h>
#include <net/addrconf.h>
#include <linux/tipc_netlink.h>
#include "core.h"
#include "bearer.h"
#include "netlink.h"

/* IANA assigned UDP port */
#define UDP_PORT_DEFAULT	6118

#define UDP_MIN_HEADROOM        48

/**
 * struct udp_media_addr - IP/UDP addressing information
 *
 * This is the bearer level originating address used in neighbor discovery
 * messages, and all fields should be in network byte order
 */
struct udp_media_addr {
	__be16	proto;
	__be16	port;
	union {
		struct in_addr ipv4;
		struct in6_addr ipv6;
	};
};

/**
 * struct udp_bearer - ip/udp bearer data structure
 * @bearer:	associated generic tipc bearer
 * @ubsock:	bearer associated socket
 * @ifindex:	local address scope
 * @work:	used to schedule deferred work on a bearer
 */
struct udp_bearer {
	struct tipc_bearer __rcu *bearer;
	struct socket *ubsock;
	u32 ifindex;
	struct work_struct work;
};

/* udp_media_addr_set - convert a ip/udp address to a TIPC media address */
static void tipc_udp_media_addr_set(struct tipc_media_addr *addr,
				    struct udp_media_addr *ua)
{
	memset(addr, 0, sizeof(struct tipc_media_addr));
	addr->media_id = TIPC_MEDIA_TYPE_UDP;
	memcpy(addr->value, ua, sizeof(struct udp_media_addr));
	if (ntohs(ua->proto) == ETH_P_IP) {
		if (ipv4_is_multicast(ua->ipv4.s_addr))
			addr->broadcast = 1;
	} else if (ntohs(ua->proto) == ETH_P_IPV6) {
		if (ipv6_addr_type(&ua->ipv6) & IPV6_ADDR_MULTICAST)
			addr->broadcast = 1;
	} else {
		pr_err("Invalid UDP media address\n");
	}
}

/* tipc_udp_addr2str - convert ip/udp address to string */
static int tipc_udp_addr2str(struct tipc_media_addr *a, char *buf, int size)
{
	struct udp_media_addr *ua = (struct udp_media_addr *)&a->value;

	if (ntohs(ua->proto) == ETH_P_IP)
		snprintf(buf, size, "%pI4:%u", &ua->ipv4, ntohs(ua->port));
	else if (ntohs(ua->proto) == ETH_P_IPV6)
		snprintf(buf, size, "%pI6:%u", &ua->ipv6, ntohs(ua->port));
	else
		pr_err("Invalid UDP media address\n");
	return 0;
}

/* tipc_udp_msg2addr - extract an ip/udp address from a TIPC ndisc message */
static int tipc_udp_msg2addr(struct tipc_bearer *b, struct tipc_media_addr *a,
			     char *msg)
{
	struct udp_media_addr *ua;

	ua = (struct udp_media_addr *) (msg + TIPC_MEDIA_ADDR_OFFSET);
	if (msg[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_UDP)
		return -EINVAL;
	tipc_udp_media_addr_set(a, ua);
	return 0;
}

/* tipc_udp_addr2msg - write an ip/udp address to a TIPC ndisc message */
static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a)
{
	memset(msg, 0, TIPC_MEDIA_INFO_SIZE);
	msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_UDP;
	memcpy(msg + TIPC_MEDIA_ADDR_OFFSET, a->value,
	       sizeof(struct udp_media_addr));
	return 0;
}

/* tipc_send_msg - enqueue a send request */
static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
			     struct tipc_bearer *b,
			     struct tipc_media_addr *dest)
{
	int ttl, err = 0;
	struct udp_bearer *ub;
	struct udp_media_addr *dst = (struct udp_media_addr *)&dest->value;
	struct udp_media_addr *src = (struct udp_media_addr *)&b->addr.value;
	struct rtable *rt;

	if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
		err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
		if (err)
			goto tx_error;
	}

	skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
	ub = rcu_dereference_rtnl(b->media_ptr);
	if (!ub) {
		err = -ENODEV;
		goto tx_error;
	}
	if (dst->proto == htons(ETH_P_IP)) {
		struct flowi4 fl = {
			.daddr = dst->ipv4.s_addr,
			.saddr = src->ipv4.s_addr,
			.flowi4_mark = skb->mark,
			.flowi4_proto = IPPROTO_UDP
		};
		rt = ip_route_output_key(net, &fl);
		if (IS_ERR(rt)) {
			err = PTR_ERR(rt);
			goto tx_error;
		}

		skb->dev = rt->dst.dev;
		ttl = ip4_dst_hoplimit(&rt->dst);
		udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
				    dst->ipv4.s_addr, 0, ttl, 0, src->port,
				    dst->port, false, true);
#if IS_ENABLED(CONFIG_IPV6)
	} else {
		struct dst_entry *ndst;
		struct flowi6 fl6 = {
			.flowi6_oif = ub->ifindex,
			.daddr = dst->ipv6,
			.saddr = src->ipv6,
			.flowi6_proto = IPPROTO_UDP
		};
		err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk, &ndst,
						 &fl6);
		if (err)
			goto tx_error;
		ttl = ip6_dst_hoplimit(ndst);
		err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
					   ndst->dev, &src->ipv6,
					   &dst->ipv6, 0, ttl, 0, src->port,
					   dst->port, false);
#endif
	}
	return err;

tx_error:
	kfree_skb(skb);
	return err;
}

/* tipc_udp_recv - read data from bearer socket */
static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
{
	struct udp_bearer *ub;
	struct tipc_bearer *b;

	ub = rcu_dereference_sk_user_data(sk);
	if (!ub) {
		pr_err_ratelimited("Failed to get UDP bearer reference");
		kfree_skb(skb);
		return 0;
	}

	skb_pull(skb, sizeof(struct udphdr));
	rcu_read_lock();
	b = rcu_dereference_rtnl(ub->bearer);

	if (b) {
		tipc_rcv(sock_net(sk), skb, b);
		rcu_read_unlock();
		return 0;
	}
	rcu_read_unlock();
	kfree_skb(skb);
	return 0;
}

static int enable_mcast(struct udp_bearer *ub, struct udp_media_addr *remote)
{
	int err = 0;
	struct ip_mreqn mreqn;
	struct sock *sk = ub->ubsock->sk;

	if (ntohs(remote->proto) == ETH_P_IP) {
		if (!ipv4_is_multicast(remote->ipv4.s_addr))
			return 0;
		mreqn.imr_multiaddr = remote->ipv4;
		mreqn.imr_ifindex = ub->ifindex;
		err = ip_mc_join_group(sk, &mreqn);
#if IS_ENABLED(CONFIG_IPV6)
	} else {
		if (!ipv6_addr_is_multicast(&remote->ipv6))
			return 0;
		err = ipv6_stub->ipv6_sock_mc_join(sk, ub->ifindex,
						   &remote->ipv6);
#endif
	}
	return err;
}

/**
 * parse_options - build local/remote addresses from configuration
 * @attrs:	netlink config data
 * @ub:		UDP bearer instance
 * @local:	local bearer IP address/port
 * @remote:	peer or multicast IP/port
 */
static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub,
			 struct udp_media_addr *local,
			 struct udp_media_addr *remote)
{
	struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
	struct sockaddr_storage sa_local, sa_remote;

	if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
		goto err;
	if (nla_parse_nested(opts, TIPC_NLA_UDP_MAX,
			     attrs[TIPC_NLA_BEARER_UDP_OPTS],
			     tipc_nl_udp_policy))
		goto err;
	if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) {
		nla_memcpy(&sa_local, opts[TIPC_NLA_UDP_LOCAL],
			   sizeof(sa_local));
		nla_memcpy(&sa_remote, opts[TIPC_NLA_UDP_REMOTE],
			   sizeof(sa_remote));
	} else {
err:
		pr_err("Invalid UDP bearer configuration");
		return -EINVAL;
	}
	if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET) {
		struct sockaddr_in *ip4;

		ip4 = (struct sockaddr_in *)&sa_local;
		local->proto = htons(ETH_P_IP);
		local->port = ip4->sin_port;
		local->ipv4.s_addr = ip4->sin_addr.s_addr;

		ip4 = (struct sockaddr_in *)&sa_remote;
		remote->proto = htons(ETH_P_IP);
		remote->port = ip4->sin_port;
		remote->ipv4.s_addr = ip4->sin_addr.s_addr;
		return 0;

#if IS_ENABLED(CONFIG_IPV6)
	} else if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET6) {
		int atype;
		struct sockaddr_in6 *ip6;

		ip6 = (struct sockaddr_in6 *)&sa_local;
		atype = ipv6_addr_type(&ip6->sin6_addr);
		if (__ipv6_addr_needs_scope_id(atype) && !ip6->sin6_scope_id)
			return -EINVAL;

		local->proto = htons(ETH_P_IPV6);
		local->port = ip6->sin6_port;
		memcpy(&local->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
		ub->ifindex = ip6->sin6_scope_id;

		ip6 = (struct sockaddr_in6 *)&sa_remote;
		remote->proto = htons(ETH_P_IPV6);
		remote->port = ip6->sin6_port;
		memcpy(&remote->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
		return 0;
#endif
	}
	return -EADDRNOTAVAIL;
}

/**
 * tipc_udp_enable - callback to create a new udp bearer instance
 * @net:	network namespace
 * @b:		pointer to generic tipc_bearer
 * @attrs:	netlink bearer configuration
 *
 * validate the bearer parameters and initialize the udp bearer
 * rtnl_lock should be held
 */
static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
			   struct nlattr *attrs[])
{
	int err = -EINVAL;
	struct udp_bearer *ub;
	struct udp_media_addr *remote;
	struct udp_media_addr local = {0};
	struct udp_port_cfg udp_conf = {0};
	struct udp_tunnel_sock_cfg tuncfg = {NULL};

	ub = kzalloc(sizeof(*ub), GFP_ATOMIC);
	if (!ub)
		return -ENOMEM;

	remote = (struct udp_media_addr *)&b->bcast_addr.value;
	memset(remote, 0, sizeof(struct udp_media_addr));
	err = parse_options(attrs, ub, &local, remote);
	if (err)
		goto err;

	b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP;
	b->bcast_addr.broadcast = 1;
	rcu_assign_pointer(b->media_ptr, ub);
	rcu_assign_pointer(ub->bearer, b);
	tipc_udp_media_addr_set(&b->addr, &local);
	if (local.proto == htons(ETH_P_IP)) {
		struct net_device *dev;

		dev = __ip_dev_find(net, local.ipv4.s_addr, false);
		if (!dev) {
			err = -ENODEV;
			goto err;
		}
		udp_conf.family = AF_INET;
		udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
		udp_conf.use_udp_checksums = false;
		ub->ifindex = dev->ifindex;
		b->mtu = dev->mtu - sizeof(struct iphdr)
			- sizeof(struct udphdr);
#if IS_ENABLED(CONFIG_IPV6)
	} else if (local.proto == htons(ETH_P_IPV6)) {
		udp_conf.family = AF_INET6;
		udp_conf.use_udp6_tx_checksums = true;
		udp_conf.use_udp6_rx_checksums = true;
		udp_conf.local_ip6 = in6addr_any;
		b->mtu = 1280;
#endif
	} else {
		err = -EAFNOSUPPORT;
		goto err;
	}
	udp_conf.local_udp_port = local.port;
	err = udp_sock_create(net, &udp_conf, &ub->ubsock);
	if (err)
		goto err;
	tuncfg.sk_user_data = ub;
	tuncfg.encap_type = 1;
	tuncfg.encap_rcv = tipc_udp_recv;
	tuncfg.encap_destroy = NULL;
	setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);

	err = enable_mcast(ub, remote);
	if (err)
		goto err;
	return 0;
err:
	if (ub->ubsock)
		udp_tunnel_sock_release(ub->ubsock);
	kfree(ub);
	return err;
}

/* cleanup_bearer - break the socket/bearer association */
static void cleanup_bearer(struct work_struct *work)
{
	struct udp_bearer *ub = container_of(work, struct udp_bearer, work);

	if (ub->ubsock)
		udp_tunnel_sock_release(ub->ubsock);
	synchronize_net();
	kfree(ub);
}

/* tipc_udp_disable - detach bearer from socket */
static void tipc_udp_disable(struct tipc_bearer *b)
{
	struct udp_bearer *ub;

	ub = rcu_dereference_rtnl(b->media_ptr);
	if (!ub) {
		pr_err("UDP bearer instance not found\n");
		return;
	}
	if (ub->ubsock)
		sock_set_flag(ub->ubsock->sk, SOCK_DEAD);
	RCU_INIT_POINTER(ub->bearer, NULL);

	/* sock_release need to be done outside of rtnl lock */
	INIT_WORK(&ub->work, cleanup_bearer);
	schedule_work(&ub->work);
}

struct tipc_media udp_media_info = {
	.send_msg	= tipc_udp_send_msg,
	.enable_media	= tipc_udp_enable,
	.disable_media	= tipc_udp_disable,
	.addr2str	= tipc_udp_addr2str,
	.addr2msg	= tipc_udp_addr2msg,
	.msg2addr	= tipc_udp_msg2addr,
	.priority	= TIPC_DEF_LINK_PRI,
	.tolerance	= TIPC_DEF_LINK_TOL,
	.window		= TIPC_DEF_LINK_WIN,
	.type_id	= TIPC_MEDIA_TYPE_UDP,
	.hwaddr_len	= 0,
	.name		= "udp"
};
