#include <linux/proc_fs.h>
#include <linux/export.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include "bonding.h"


static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
	__acquires(RCU)
	__acquires(&bond->lock)
{
	struct bonding *bond = seq->private;
	struct list_head *iter;
	struct slave *slave;
	loff_t off = 0;

	/* make sure the bond won't be taken away */
	rcu_read_lock();
	read_lock(&bond->lock);

	if (*pos == 0)
		return SEQ_START_TOKEN;

	bond_for_each_slave(bond, slave, iter)
		if (++off == *pos)
			return slave;

	return NULL;
}

static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct bonding *bond = seq->private;
	struct list_head *iter;
	struct slave *slave;
	bool found = false;

	++*pos;
	if (v == SEQ_START_TOKEN)
		return bond_first_slave(bond);

	if (bond_is_last_slave(bond, v))
		return NULL;

	bond_for_each_slave(bond, slave, iter) {
		if (found)
			return slave;
		if (slave == v)
			found = true;
	}

	return NULL;
}

static void bond_info_seq_stop(struct seq_file *seq, void *v)
	__releases(&bond->lock)
	__releases(RCU)
{
	struct bonding *bond = seq->private;

	read_unlock(&bond->lock);
	rcu_read_unlock();
}

static void bond_info_show_master(struct seq_file *seq)
{
	struct bonding *bond = seq->private;
	const struct bond_opt_value *optval;
	struct slave *curr;
	int i;

	curr = rcu_dereference(bond->curr_active_slave);

	seq_printf(seq, "Bonding Mode: %s",
		   bond_mode_name(BOND_MODE(bond)));

	if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
	    bond->params.fail_over_mac) {
		optval = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC,
					  bond->params.fail_over_mac);
		seq_printf(seq, " (fail_over_mac %s)", optval->string);
	}

	seq_printf(seq, "\n");

	if (BOND_MODE(bond) == BOND_MODE_XOR ||
		BOND_MODE(bond) == BOND_MODE_8023AD) {
		optval = bond_opt_get_val(BOND_OPT_XMIT_HASH,
					  bond->params.xmit_policy);
		seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
			   optval->string, bond->params.xmit_policy);
	}

	if (bond_uses_primary(bond)) {
		seq_printf(seq, "Primary Slave: %s",
			   (bond->primary_slave) ?
			   bond->primary_slave->dev->name : "None");
		if (bond->primary_slave) {
			optval = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
						  bond->params.primary_reselect);
			seq_printf(seq, " (primary_reselect %s)",
				   optval->string);
		}

		seq_printf(seq, "\nCurrently Active Slave: %s\n",
			   (curr) ? curr->dev->name : "None");
	}

	seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
		   "up" : "down");
	seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
	seq_printf(seq, "Up Delay (ms): %d\n",
		   bond->params.updelay * bond->params.miimon);
	seq_printf(seq, "Down Delay (ms): %d\n",
		   bond->params.downdelay * bond->params.miimon);


	/* ARP information */
	if (bond->params.arp_interval > 0) {
		int printed = 0;
		seq_printf(seq, "ARP Polling Interval (ms): %d\n",
				bond->params.arp_interval);

		seq_printf(seq, "ARP IP target/s (n.n.n.n form):");

		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
			if (!bond->params.arp_targets[i])
				break;
			if (printed)
				seq_printf(seq, ",");
			seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
			printed = 1;
		}
		seq_printf(seq, "\n");
	}

	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
		struct ad_info ad_info;

		seq_puts(seq, "\n802.3ad info\n");
		seq_printf(seq, "LACP rate: %s\n",
			   (bond->params.lacp_fast) ? "fast" : "slow");
		seq_printf(seq, "Min links: %d\n", bond->params.min_links);
		optval = bond_opt_get_val(BOND_OPT_AD_SELECT,
					  bond->params.ad_select);
		seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
			   optval->string);

		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
			seq_printf(seq, "bond %s has no active aggregator\n",
				   bond->dev->name);
		} else {
			seq_printf(seq, "Active Aggregator Info:\n");

			seq_printf(seq, "\tAggregator ID: %d\n",
				   ad_info.aggregator_id);
			seq_printf(seq, "\tNumber of ports: %d\n",
				   ad_info.ports);
			seq_printf(seq, "\tActor Key: %d\n",
				   ad_info.actor_key);
			seq_printf(seq, "\tPartner Key: %d\n",
				   ad_info.partner_key);
			seq_printf(seq, "\tPartner Mac Address: %pM\n",
				   ad_info.partner_system);
		}
	}
}

static void bond_info_show_slave(struct seq_file *seq,
				 const struct slave *slave)
{
	struct bonding *bond = seq->private;

	seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
	seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link));
	if (slave->speed == SPEED_UNKNOWN)
		seq_printf(seq, "Speed: %s\n", "Unknown");
	else
		seq_printf(seq, "Speed: %d Mbps\n", slave->speed);

	if (slave->duplex == DUPLEX_UNKNOWN)
		seq_printf(seq, "Duplex: %s\n", "Unknown");
	else
		seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");

	seq_printf(seq, "Link Failure Count: %u\n",
		   slave->link_failure_count);

	seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);

	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
		const struct aggregator *agg
			= SLAVE_AD_INFO(slave)->port.aggregator;

		if (agg)
			seq_printf(seq, "Aggregator ID: %d\n",
				   agg->aggregator_identifier);
		else
			seq_puts(seq, "Aggregator ID: N/A\n");
	}
	seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
}

static int bond_info_seq_show(struct seq_file *seq, void *v)
{
	if (v == SEQ_START_TOKEN) {
		seq_printf(seq, "%s\n", bond_version);
		bond_info_show_master(seq);
	} else
		bond_info_show_slave(seq, v);

	return 0;
}

static const struct seq_operations bond_info_seq_ops = {
	.start = bond_info_seq_start,
	.next  = bond_info_seq_next,
	.stop  = bond_info_seq_stop,
	.show  = bond_info_seq_show,
};

static int bond_info_open(struct inode *inode, struct file *file)
{
	struct seq_file *seq;
	int res;

	res = seq_open(file, &bond_info_seq_ops);
	if (!res) {
		/* recover the pointer buried in proc_dir_entry data */
		seq = file->private_data;
		seq->private = PDE_DATA(inode);
	}

	return res;
}

static const struct file_operations bond_info_fops = {
	.owner   = THIS_MODULE,
	.open    = bond_info_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release,
};

void bond_create_proc_entry(struct bonding *bond)
{
	struct net_device *bond_dev = bond->dev;
	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);

	if (bn->proc_dir) {
		bond->proc_entry = proc_create_data(bond_dev->name,
						    S_IRUGO, bn->proc_dir,
						    &bond_info_fops, bond);
		if (bond->proc_entry == NULL)
			pr_warn("Warning: Cannot create /proc/net/%s/%s\n",
				DRV_NAME, bond_dev->name);
		else
			memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
	}
}

void bond_remove_proc_entry(struct bonding *bond)
{
	struct net_device *bond_dev = bond->dev;
	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);

	if (bn->proc_dir && bond->proc_entry) {
		remove_proc_entry(bond->proc_file_name, bn->proc_dir);
		memset(bond->proc_file_name, 0, IFNAMSIZ);
		bond->proc_entry = NULL;
	}
}

/* Create the bonding directory under /proc/net, if doesn't exist yet.
 * Caller must hold rtnl_lock.
 */
void __net_init bond_create_proc_dir(struct bond_net *bn)
{
	if (!bn->proc_dir) {
		bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
		if (!bn->proc_dir)
			pr_warn("Warning: Cannot create /proc/net/%s\n",
				DRV_NAME);
	}
}

/* Destroy the bonding directory under /proc/net, if empty.
 * Caller must hold rtnl_lock.
 */
void __net_exit bond_destroy_proc_dir(struct bond_net *bn)
{
	if (bn->proc_dir) {
		remove_proc_entry(DRV_NAME, bn->net->proc_net);
		bn->proc_dir = NULL;
	}
}
