/*
 * Copyright(c) 2016 Hauke Mehrtens <hauke@hauke-m.de>
 *
 * Backport functionality introduced in Linux 4.7.
 *
 * 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/export.h>
#include <linux/list.h>
#include <linux/rcupdate.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <net/netlink.h>

/**
 * __nla_reserve_64bit - reserve room for attribute on the skb and align it
 * @skb: socket buffer to reserve room on
 * @attrtype: attribute type
 * @attrlen: length of attribute payload
 *
 * Adds a netlink attribute header to a socket buffer and reserves
 * room for the payload but does not copy it. It also ensure that this
 * attribute will be 64-bit aign.
 *
 * The caller is responsible to ensure that the skb provides enough
 * tailroom for the attribute header and payload.
 */
struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype,
                                  int attrlen, int padattr)
{
       if (nla_need_padding_for_64bit(skb))
               nla_align_64bit(skb, padattr);

       return __nla_reserve(skb, attrtype, attrlen);
}
EXPORT_SYMBOL_GPL(__nla_reserve_64bit);

/**
 * nla_reserve_64bit - reserve room for attribute on the skb and align it
 * @skb: socket buffer to reserve room on
 * @attrtype: attribute type
 * @attrlen: length of attribute payload
 *
 * Adds a netlink attribute header to a socket buffer and reserves
 * room for the payload but does not copy it. It also ensure that this
 * attribute will be 64-bit aign.
 *
 * Returns NULL if the tailroom of the skb is insufficient to store
 * the attribute header and payload.
 */
struct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype, int attrlen,
				 int padattr)
{
       size_t len;

       if (nla_need_padding_for_64bit(skb))
               len = nla_total_size_64bit(attrlen);
       else
               len = nla_total_size(attrlen);
       if (unlikely(skb_tailroom(skb) < len))
               return NULL;

       return __nla_reserve_64bit(skb, attrtype, attrlen, padattr);
}
EXPORT_SYMBOL_GPL(nla_reserve_64bit);

/**
 * __nla_put_64bit - Add a netlink attribute to a socket buffer and align it
 * @skb: socket buffer to add attribute to
 * @attrtype: attribute type
 * @attrlen: length of attribute payload
 * @data: head of attribute payload
 *
 * The caller is responsible to ensure that the skb provides enough
 * tailroom for the attribute header and payload.
 */
void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
                    const void *data, int padattr)
{
       struct nlattr *nla;

       nla = __nla_reserve_64bit(skb, attrtype, attrlen, padattr);
       memcpy(nla_data(nla), data, attrlen);
}
EXPORT_SYMBOL_GPL(__nla_put_64bit);

/**
 * nla_put_64bit - Add a netlink attribute to a socket buffer and align it
 * @skb: socket buffer to add attribute to
 * @attrtype: attribute type
 * @attrtype: attribute type
 * @attrlen: length of attribute payload
 * @data: head of attribute payload
 *
 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
 * the attribute header and payload.
 */
int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
                 const void *data, int padattr)
{
       size_t len;

       if (nla_need_padding_for_64bit(skb))
               len = nla_total_size_64bit(attrlen);
       else
               len = nla_total_size(attrlen);
       if (unlikely(skb_tailroom(skb) < len))
               return -EMSGSIZE;

       __nla_put_64bit(skb, attrtype, attrlen, data, padattr);
       return 0;
}
EXPORT_SYMBOL_GPL(nla_put_64bit);

/*
 * Below 3.18 or if the kernel has devcoredump disabled, we copied the
 * entire devcoredump, so no need to define these functions.
 */
#if LINUX_VERSION_IS_GEQ(3,18,0) && \
	!defined(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP)
#include <linux/devcoredump.h>
#include <linux/scatterlist.h>

static void devcd_free_sgtable(void *data)
{
	struct scatterlist *table = data;
	int i;
	struct page *page;
	struct scatterlist *iter;
	struct scatterlist *delete_iter;

	/* free pages */
	iter = table;
	for_each_sg(table, iter, sg_nents(table), i) {
		page = sg_page(iter);
		if (page)
			__free_page(page);
	}

	/* then free all chained tables */
	iter = table;
	delete_iter = table;	/* always points on a head of a table */
	while (!sg_is_last(iter)) {
		iter++;
		if (sg_is_chain(iter)) {
			iter = sg_chain_ptr(iter);
			kfree(delete_iter);
			delete_iter = iter;
		}
	}

	/* free the last table */
	kfree(delete_iter);
}

static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset,
				       size_t buf_len, void *data,
				       size_t data_len)
{
	struct scatterlist *table = data;

	if (offset > data_len)
		return -EINVAL;

	if (offset + buf_len > data_len)
		buf_len = data_len - offset;
	return sg_pcopy_to_buffer(table, sg_nents(table), buffer, buf_len,
				  offset);
}

void dev_coredumpsg(struct device *dev, struct scatterlist *table,
		    size_t datalen, gfp_t gfp)
{
	dev_coredumpm(dev, THIS_MODULE, table, datalen, gfp,
		      devcd_read_from_sgtable, devcd_free_sgtable);
}
EXPORT_SYMBOL_GPL(dev_coredumpsg);
#endif /* >= 3.18.0 */
