xref: /openbmc/linux/drivers/net/team/team_mode_random.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2753f9939SJiri Pirko /*
3753f9939SJiri Pirko  * drivers/net/team/team_mode_random.c - Random mode for team
4753f9939SJiri Pirko  * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
5753f9939SJiri Pirko  */
6753f9939SJiri Pirko 
7753f9939SJiri Pirko #include <linux/kernel.h>
8753f9939SJiri Pirko #include <linux/types.h>
9753f9939SJiri Pirko #include <linux/module.h>
10753f9939SJiri Pirko #include <linux/init.h>
11753f9939SJiri Pirko #include <linux/skbuff.h>
12753f9939SJiri Pirko #include <linux/if_team.h>
13753f9939SJiri Pirko 
rnd_transmit(struct team * team,struct sk_buff * skb)14753f9939SJiri Pirko static bool rnd_transmit(struct team *team, struct sk_buff *skb)
15753f9939SJiri Pirko {
16753f9939SJiri Pirko 	struct team_port *port;
17753f9939SJiri Pirko 	int port_index;
18753f9939SJiri Pirko 
19*8032bf12SJason A. Donenfeld 	port_index = get_random_u32_below(team->en_port_count);
20753f9939SJiri Pirko 	port = team_get_port_by_index_rcu(team, port_index);
2176c455deSJiri Pirko 	if (unlikely(!port))
2276c455deSJiri Pirko 		goto drop;
23753f9939SJiri Pirko 	port = team_get_first_port_txable_rcu(team, port);
24753f9939SJiri Pirko 	if (unlikely(!port))
25753f9939SJiri Pirko 		goto drop;
26753f9939SJiri Pirko 	if (team_dev_queue_xmit(team, port, skb))
27753f9939SJiri Pirko 		return false;
28753f9939SJiri Pirko 	return true;
29753f9939SJiri Pirko 
30753f9939SJiri Pirko drop:
31753f9939SJiri Pirko 	dev_kfree_skb_any(skb);
32753f9939SJiri Pirko 	return false;
33753f9939SJiri Pirko }
34753f9939SJiri Pirko 
35753f9939SJiri Pirko static const struct team_mode_ops rnd_mode_ops = {
36753f9939SJiri Pirko 	.transmit		= rnd_transmit,
37753f9939SJiri Pirko 	.port_enter		= team_modeop_port_enter,
38753f9939SJiri Pirko 	.port_change_dev_addr	= team_modeop_port_change_dev_addr,
39753f9939SJiri Pirko };
40753f9939SJiri Pirko 
41753f9939SJiri Pirko static const struct team_mode rnd_mode = {
42753f9939SJiri Pirko 	.kind		= "random",
43753f9939SJiri Pirko 	.owner		= THIS_MODULE,
44753f9939SJiri Pirko 	.ops		= &rnd_mode_ops,
458fd72856SJiri Pirko 	.lag_tx_type	= NETDEV_LAG_TX_TYPE_RANDOM,
46753f9939SJiri Pirko };
47753f9939SJiri Pirko 
rnd_init_module(void)48753f9939SJiri Pirko static int __init rnd_init_module(void)
49753f9939SJiri Pirko {
50753f9939SJiri Pirko 	return team_mode_register(&rnd_mode);
51753f9939SJiri Pirko }
52753f9939SJiri Pirko 
rnd_cleanup_module(void)53753f9939SJiri Pirko static void __exit rnd_cleanup_module(void)
54753f9939SJiri Pirko {
55753f9939SJiri Pirko 	team_mode_unregister(&rnd_mode);
56753f9939SJiri Pirko }
57753f9939SJiri Pirko 
58753f9939SJiri Pirko module_init(rnd_init_module);
59753f9939SJiri Pirko module_exit(rnd_cleanup_module);
60753f9939SJiri Pirko 
61753f9939SJiri Pirko MODULE_LICENSE("GPL v2");
62753f9939SJiri Pirko MODULE_AUTHOR("Jiri Pirko <jiri@resnulli.us>");
63753f9939SJiri Pirko MODULE_DESCRIPTION("Random mode for team");
643a5f8997SZhang Shengju MODULE_ALIAS_TEAM_MODE("random");
65