/*
 * drivers/net/team/team_mode_random.c - Random mode for team
 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/reciprocal_div.h>
#include <linux/if_team.h>

static u32 random_N(unsigned int N)
{
	return reciprocal_divide(prandom_u32(), N);
}

static bool rnd_transmit(struct team *team, struct sk_buff *skb)
{
	struct team_port *port;
	int port_index;

	port_index = random_N(team->en_port_count);
	port = team_get_port_by_index_rcu(team, port_index);
	if (unlikely(!port))
		goto drop;
	port = team_get_first_port_txable_rcu(team, port);
	if (unlikely(!port))
		goto drop;
	if (team_dev_queue_xmit(team, port, skb))
		return false;
	return true;

drop:
	dev_kfree_skb_any(skb);
	return false;
}

static const struct team_mode_ops rnd_mode_ops = {
	.transmit		= rnd_transmit,
	.port_enter		= team_modeop_port_enter,
	.port_change_dev_addr	= team_modeop_port_change_dev_addr,
};

static const struct team_mode rnd_mode = {
	.kind		= "random",
	.owner		= THIS_MODULE,
	.ops		= &rnd_mode_ops,
};

static int __init rnd_init_module(void)
{
	return team_mode_register(&rnd_mode);
}

static void __exit rnd_cleanup_module(void)
{
	team_mode_unregister(&rnd_mode);
}

module_init(rnd_init_module);
module_exit(rnd_cleanup_module);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Jiri Pirko <jiri@resnulli.us>");
MODULE_DESCRIPTION("Random mode for team");
MODULE_ALIAS("team-mode-random");
