/*
 * Copyright (c) 2017 Nicira, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/if.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/openvswitch.h>
#include <linux/netlink.h>
#include <linux/rculist.h>

#include <net/netlink.h>
#include <net/genetlink.h>

#include "datapath.h"
#include "meter.h"

#define METER_HASH_BUCKETS 1024

static const struct nla_policy meter_policy[OVS_METER_ATTR_MAX + 1] = {
	[OVS_METER_ATTR_ID] = { .type = NLA_U32, },
	[OVS_METER_ATTR_KBPS] = { .type = NLA_FLAG },
	[OVS_METER_ATTR_STATS] = { .len = sizeof(struct ovs_flow_stats) },
	[OVS_METER_ATTR_BANDS] = { .type = NLA_NESTED },
	[OVS_METER_ATTR_USED] = { .type = NLA_U64 },
	[OVS_METER_ATTR_CLEAR] = { .type = NLA_FLAG },
	[OVS_METER_ATTR_MAX_METERS] = { .type = NLA_U32 },
	[OVS_METER_ATTR_MAX_BANDS] = { .type = NLA_U32 },
};

static const struct nla_policy band_policy[OVS_BAND_ATTR_MAX + 1] = {
	[OVS_BAND_ATTR_TYPE] = { .type = NLA_U32, },
	[OVS_BAND_ATTR_RATE] = { .type = NLA_U32, },
	[OVS_BAND_ATTR_BURST] = { .type = NLA_U32, },
	[OVS_BAND_ATTR_STATS] = { .len = sizeof(struct ovs_flow_stats) },
};

static void ovs_meter_free(struct dp_meter *meter)
{
	if (!meter)
		return;

	kfree_rcu(meter, rcu);
}

static struct hlist_head *meter_hash_bucket(const struct datapath *dp,
					    u32 meter_id)
{
	return &dp->meters[meter_id & (METER_HASH_BUCKETS - 1)];
}

/* Call with ovs_mutex or RCU read lock. */
static struct dp_meter *lookup_meter(const struct datapath *dp,
				     u32 meter_id)
{
	struct dp_meter *meter;
	struct hlist_head *head;

	head = meter_hash_bucket(dp, meter_id);
	hlist_for_each_entry_rcu(meter, head, dp_hash_node) {
		if (meter->id == meter_id)
			return meter;
	}
	return NULL;
}

static void attach_meter(struct datapath *dp, struct dp_meter *meter)
{
	struct hlist_head *head = meter_hash_bucket(dp, meter->id);

	hlist_add_head_rcu(&meter->dp_hash_node, head);
}

static void detach_meter(struct dp_meter *meter)
{
	ASSERT_OVSL();
	if (meter)
		hlist_del_rcu(&meter->dp_hash_node);
}

static struct sk_buff *
ovs_meter_cmd_reply_start(struct genl_info *info, u8 cmd,
			  struct ovs_header **ovs_reply_header)
{
	struct sk_buff *skb;
	struct ovs_header *ovs_header = info->userhdr;

	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
	if (!skb)
		return ERR_PTR(-ENOMEM);

	*ovs_reply_header = genlmsg_put(skb, info->snd_portid,
					info->snd_seq,
					&dp_meter_genl_family, 0, cmd);
	if (!*ovs_reply_header) {
		nlmsg_free(skb);
		return ERR_PTR(-EMSGSIZE);
	}
	(*ovs_reply_header)->dp_ifindex = ovs_header->dp_ifindex;

	return skb;
}

static int ovs_meter_cmd_reply_stats(struct sk_buff *reply, u32 meter_id,
				     struct dp_meter *meter)
{
	struct nlattr *nla;
	struct dp_meter_band *band;
	u16 i;

	if (nla_put_u32(reply, OVS_METER_ATTR_ID, meter_id))
		goto error;

	if (!meter)
		return 0;

	if (nla_put(reply, OVS_METER_ATTR_STATS,
		    sizeof(struct ovs_flow_stats), &meter->stats) ||
	    nla_put_u64_64bit(reply, OVS_METER_ATTR_USED, meter->used,
			      OVS_METER_ATTR_PAD))
		goto error;

	nla = nla_nest_start(reply, OVS_METER_ATTR_BANDS);
	if (!nla)
		goto error;

	band = meter->bands;

	for (i = 0; i < meter->n_bands; ++i, ++band) {
		struct nlattr *band_nla;

		band_nla = nla_nest_start(reply, OVS_BAND_ATTR_UNSPEC);
		if (!band_nla || nla_put(reply, OVS_BAND_ATTR_STATS,
					 sizeof(struct ovs_flow_stats),
					 &band->stats))
			goto error;
		nla_nest_end(reply, band_nla);
	}
	nla_nest_end(reply, nla);

	return 0;
error:
	return -EMSGSIZE;
}

static int ovs_meter_cmd_features(struct sk_buff *skb, struct genl_info *info)
{
	struct sk_buff *reply;
	struct ovs_header *ovs_reply_header;
	struct nlattr *nla, *band_nla;
	int err;

	reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_FEATURES,
					  &ovs_reply_header);
	if (IS_ERR(reply))
		return PTR_ERR(reply);

	if (nla_put_u32(reply, OVS_METER_ATTR_MAX_METERS, U32_MAX) ||
	    nla_put_u32(reply, OVS_METER_ATTR_MAX_BANDS, DP_MAX_BANDS))
		goto nla_put_failure;

	nla = nla_nest_start(reply, OVS_METER_ATTR_BANDS);
	if (!nla)
		goto nla_put_failure;

	band_nla = nla_nest_start(reply, OVS_BAND_ATTR_UNSPEC);
	if (!band_nla)
		goto nla_put_failure;
	/* Currently only DROP band type is supported. */
	if (nla_put_u32(reply, OVS_BAND_ATTR_TYPE, OVS_METER_BAND_TYPE_DROP))
		goto nla_put_failure;
	nla_nest_end(reply, band_nla);
	nla_nest_end(reply, nla);

	genlmsg_end(reply, ovs_reply_header);
	return genlmsg_reply(reply, info);

nla_put_failure:
	nlmsg_free(reply);
	err = -EMSGSIZE;
	return err;
}

static struct dp_meter *dp_meter_create(struct nlattr **a)
{
	struct nlattr *nla;
	int rem;
	u16 n_bands = 0;
	struct dp_meter *meter;
	struct dp_meter_band *band;
	int err;

	/* Validate attributes, count the bands. */
	if (!a[OVS_METER_ATTR_BANDS])
		return ERR_PTR(-EINVAL);

	nla_for_each_nested(nla, a[OVS_METER_ATTR_BANDS], rem)
		if (++n_bands > DP_MAX_BANDS)
			return ERR_PTR(-EINVAL);

	/* Allocate and set up the meter before locking anything. */
	meter = kzalloc(struct_size(meter, bands, n_bands), GFP_KERNEL);
	if (!meter)
		return ERR_PTR(-ENOMEM);

	meter->id = nla_get_u32(a[OVS_METER_ATTR_ID]);
	meter->used = div_u64(ktime_get_ns(), 1000 * 1000);
	meter->kbps = a[OVS_METER_ATTR_KBPS] ? 1 : 0;
	meter->keep_stats = !a[OVS_METER_ATTR_CLEAR];
	spin_lock_init(&meter->lock);
	if (meter->keep_stats && a[OVS_METER_ATTR_STATS]) {
		meter->stats = *(struct ovs_flow_stats *)
			nla_data(a[OVS_METER_ATTR_STATS]);
	}
	meter->n_bands = n_bands;

	/* Set up meter bands. */
	band = meter->bands;
	nla_for_each_nested(nla, a[OVS_METER_ATTR_BANDS], rem) {
		struct nlattr *attr[OVS_BAND_ATTR_MAX + 1];
		u32 band_max_delta_t;

		err = nla_parse((struct nlattr **)&attr, OVS_BAND_ATTR_MAX,
				nla_data(nla), nla_len(nla), band_policy,
				NULL);
		if (err)
			goto exit_free_meter;

		if (!attr[OVS_BAND_ATTR_TYPE] ||
		    !attr[OVS_BAND_ATTR_RATE] ||
		    !attr[OVS_BAND_ATTR_BURST]) {
			err = -EINVAL;
			goto exit_free_meter;
		}

		band->type = nla_get_u32(attr[OVS_BAND_ATTR_TYPE]);
		band->rate = nla_get_u32(attr[OVS_BAND_ATTR_RATE]);
		if (band->rate == 0) {
			err = -EINVAL;
			goto exit_free_meter;
		}

		band->burst_size = nla_get_u32(attr[OVS_BAND_ATTR_BURST]);
		/* Figure out max delta_t that is enough to fill any bucket.
		 * Keep max_delta_t size to the bucket units:
		 * pkts => 1/1000 packets, kilobits => bits.
		 *
		 * Start with a full bucket.
		 */
		band->bucket = (band->burst_size + band->rate) * 1000;
		band_max_delta_t = band->bucket / band->rate;
		if (band_max_delta_t > meter->max_delta_t)
			meter->max_delta_t = band_max_delta_t;
		band++;
	}

	return meter;

exit_free_meter:
	kfree(meter);
	return ERR_PTR(err);
}

static int ovs_meter_cmd_set(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr **a = info->attrs;
	struct dp_meter *meter, *old_meter;
	struct sk_buff *reply;
	struct ovs_header *ovs_reply_header;
	struct ovs_header *ovs_header = info->userhdr;
	struct datapath *dp;
	int err;
	u32 meter_id;
	bool failed;

	if (!a[OVS_METER_ATTR_ID]) {
		return -ENODEV;
	}

	meter = dp_meter_create(a);
	if (IS_ERR_OR_NULL(meter))
		return PTR_ERR(meter);

	reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_SET,
					  &ovs_reply_header);
	if (IS_ERR(reply)) {
		err = PTR_ERR(reply);
		goto exit_free_meter;
	}

	ovs_lock();
	dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
	if (!dp) {
		err = -ENODEV;
		goto exit_unlock;
	}

	meter_id = nla_get_u32(a[OVS_METER_ATTR_ID]);

	/* Cannot fail after this. */
	old_meter = lookup_meter(dp, meter_id);
	detach_meter(old_meter);
	attach_meter(dp, meter);
	ovs_unlock();

	/* Build response with the meter_id and stats from
	 * the old meter, if any.
	 */
	failed = nla_put_u32(reply, OVS_METER_ATTR_ID, meter_id);
	WARN_ON(failed);
	if (old_meter) {
		spin_lock_bh(&old_meter->lock);
		if (old_meter->keep_stats) {
			err = ovs_meter_cmd_reply_stats(reply, meter_id,
							old_meter);
			WARN_ON(err);
		}
		spin_unlock_bh(&old_meter->lock);
		ovs_meter_free(old_meter);
	}

	genlmsg_end(reply, ovs_reply_header);
	return genlmsg_reply(reply, info);

exit_unlock:
	ovs_unlock();
	nlmsg_free(reply);
exit_free_meter:
	kfree(meter);
	return err;
}

static int ovs_meter_cmd_get(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr **a = info->attrs;
	u32 meter_id;
	struct ovs_header *ovs_header = info->userhdr;
	struct ovs_header *ovs_reply_header;
	struct datapath *dp;
	int err;
	struct sk_buff *reply;
	struct dp_meter *meter;

	if (!a[OVS_METER_ATTR_ID])
		return -EINVAL;

	meter_id = nla_get_u32(a[OVS_METER_ATTR_ID]);

	reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_GET,
					  &ovs_reply_header);
	if (IS_ERR(reply))
		return PTR_ERR(reply);

	ovs_lock();

	dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
	if (!dp) {
		err = -ENODEV;
		goto exit_unlock;
	}

	/* Locate meter, copy stats. */
	meter = lookup_meter(dp, meter_id);
	if (!meter) {
		err = -ENOENT;
		goto exit_unlock;
	}

	spin_lock_bh(&meter->lock);
	err = ovs_meter_cmd_reply_stats(reply, meter_id, meter);
	spin_unlock_bh(&meter->lock);
	if (err)
		goto exit_unlock;

	ovs_unlock();

	genlmsg_end(reply, ovs_reply_header);
	return genlmsg_reply(reply, info);

exit_unlock:
	ovs_unlock();
	nlmsg_free(reply);
	return err;
}

static int ovs_meter_cmd_del(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr **a = info->attrs;
	u32 meter_id;
	struct ovs_header *ovs_header = info->userhdr;
	struct ovs_header *ovs_reply_header;
	struct datapath *dp;
	int err;
	struct sk_buff *reply;
	struct dp_meter *old_meter;

	if (!a[OVS_METER_ATTR_ID])
		return -EINVAL;
	meter_id = nla_get_u32(a[OVS_METER_ATTR_ID]);

	reply = ovs_meter_cmd_reply_start(info, OVS_METER_CMD_DEL,
					  &ovs_reply_header);
	if (IS_ERR(reply))
		return PTR_ERR(reply);

	ovs_lock();

	dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
	if (!dp) {
		err = -ENODEV;
		goto exit_unlock;
	}

	old_meter = lookup_meter(dp, meter_id);
	if (old_meter) {
		spin_lock_bh(&old_meter->lock);
		err = ovs_meter_cmd_reply_stats(reply, meter_id, old_meter);
		WARN_ON(err);
		spin_unlock_bh(&old_meter->lock);
		detach_meter(old_meter);
	}
	ovs_unlock();
	ovs_meter_free(old_meter);
	genlmsg_end(reply, ovs_reply_header);
	return genlmsg_reply(reply, info);

exit_unlock:
	ovs_unlock();
	nlmsg_free(reply);
	return err;
}

/* Meter action execution.
 *
 * Return true 'meter_id' drop band is triggered. The 'skb' should be
 * dropped by the caller'.
 */
bool ovs_meter_execute(struct datapath *dp, struct sk_buff *skb,
		       struct sw_flow_key *key, u32 meter_id)
{
	struct dp_meter *meter;
	struct dp_meter_band *band;
	long long int now_ms = div_u64(ktime_get_ns(), 1000 * 1000);
	long long int long_delta_ms;
	u32 delta_ms;
	u32 cost;
	int i, band_exceeded_max = -1;
	u32 band_exceeded_rate = 0;

	meter = lookup_meter(dp, meter_id);
	/* Do not drop the packet when there is no meter. */
	if (!meter)
		return false;

	/* Lock the meter while using it. */
	spin_lock(&meter->lock);

	long_delta_ms = (now_ms - meter->used); /* ms */

	/* Make sure delta_ms will not be too large, so that bucket will not
	 * wrap around below.
	 */
	delta_ms = (long_delta_ms > (long long int)meter->max_delta_t)
		   ? meter->max_delta_t : (u32)long_delta_ms;

	/* Update meter statistics.
	 */
	meter->used = now_ms;
	meter->stats.n_packets += 1;
	meter->stats.n_bytes += skb->len;

	/* Bucket rate is either in kilobits per second, or in packets per
	 * second.  We maintain the bucket in the units of either bits or
	 * 1/1000th of a packet, correspondingly.
	 * Then, when rate is multiplied with milliseconds, we get the
	 * bucket units:
	 * msec * kbps = bits, and
	 * msec * packets/sec = 1/1000 packets.
	 *
	 * 'cost' is the number of bucket units in this packet.
	 */
	cost = (meter->kbps) ? skb->len * 8 : 1000;

	/* Update all bands and find the one hit with the highest rate. */
	for (i = 0; i < meter->n_bands; ++i) {
		long long int max_bucket_size;

		band = &meter->bands[i];
		max_bucket_size = (band->burst_size + band->rate) * 1000LL;

		band->bucket += delta_ms * band->rate;
		if (band->bucket > max_bucket_size)
			band->bucket = max_bucket_size;

		if (band->bucket >= cost) {
			band->bucket -= cost;
		} else if (band->rate > band_exceeded_rate) {
			band_exceeded_rate = band->rate;
			band_exceeded_max = i;
		}
	}

	if (band_exceeded_max >= 0) {
		/* Update band statistics. */
		band = &meter->bands[band_exceeded_max];
		band->stats.n_packets += 1;
		band->stats.n_bytes += skb->len;

		/* Drop band triggered, let the caller drop the 'skb'.  */
		if (band->type == OVS_METER_BAND_TYPE_DROP) {
			spin_unlock(&meter->lock);
			return true;
		}
	}

	spin_unlock(&meter->lock);
	return false;
}

static struct genl_ops dp_meter_genl_ops[] = {
	{ .cmd = OVS_METER_CMD_FEATURES,
		.flags = 0,		  /* OK for unprivileged users. */
		.policy = meter_policy,
		.doit = ovs_meter_cmd_features
	},
	{ .cmd = OVS_METER_CMD_SET,
		.flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN
					   *  privilege.
					   */
		.policy = meter_policy,
		.doit = ovs_meter_cmd_set,
	},
	{ .cmd = OVS_METER_CMD_GET,
		.flags = 0,		  /* OK for unprivileged users. */
		.policy = meter_policy,
		.doit = ovs_meter_cmd_get,
	},
	{ .cmd = OVS_METER_CMD_DEL,
		.flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN
					   *  privilege.
					   */
		.policy = meter_policy,
		.doit = ovs_meter_cmd_del
	},
};

static const struct genl_multicast_group ovs_meter_multicast_group = {
	.name = OVS_METER_MCGROUP,
};

struct genl_family dp_meter_genl_family __ro_after_init = {
	.hdrsize = sizeof(struct ovs_header),
	.name = OVS_METER_FAMILY,
	.version = OVS_METER_VERSION,
	.maxattr = OVS_METER_ATTR_MAX,
	.netnsok = true,
	.parallel_ops = true,
	.ops = dp_meter_genl_ops,
	.n_ops = ARRAY_SIZE(dp_meter_genl_ops),
	.mcgrps = &ovs_meter_multicast_group,
	.n_mcgrps = 1,
	.module = THIS_MODULE,
};

int ovs_meters_init(struct datapath *dp)
{
	int i;

	dp->meters = kmalloc_array(METER_HASH_BUCKETS,
				   sizeof(struct hlist_head), GFP_KERNEL);

	if (!dp->meters)
		return -ENOMEM;

	for (i = 0; i < METER_HASH_BUCKETS; i++)
		INIT_HLIST_HEAD(&dp->meters[i]);

	return 0;
}

void ovs_meters_exit(struct datapath *dp)
{
	int i;

	for (i = 0; i < METER_HASH_BUCKETS; i++) {
		struct hlist_head *head = &dp->meters[i];
		struct dp_meter *meter;
		struct hlist_node *n;

		hlist_for_each_entry_safe(meter, n, head, dp_hash_node)
			kfree(meter);
	}

	kfree(dp->meters);
}
