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