1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * drivers/net/team/team_mode_random.c - Random mode for team 4 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us> 5 */ 6 7 #include <linux/kernel.h> 8 #include <linux/types.h> 9 #include <linux/module.h> 10 #include <linux/init.h> 11 #include <linux/skbuff.h> 12 #include <linux/if_team.h> 13 14 static bool rnd_transmit(struct team *team, struct sk_buff *skb) 15 { 16 struct team_port *port; 17 int port_index; 18 19 port_index = prandom_u32_max(team->en_port_count); 20 port = team_get_port_by_index_rcu(team, port_index); 21 if (unlikely(!port)) 22 goto drop; 23 port = team_get_first_port_txable_rcu(team, port); 24 if (unlikely(!port)) 25 goto drop; 26 if (team_dev_queue_xmit(team, port, skb)) 27 return false; 28 return true; 29 30 drop: 31 dev_kfree_skb_any(skb); 32 return false; 33 } 34 35 static const struct team_mode_ops rnd_mode_ops = { 36 .transmit = rnd_transmit, 37 .port_enter = team_modeop_port_enter, 38 .port_change_dev_addr = team_modeop_port_change_dev_addr, 39 }; 40 41 static const struct team_mode rnd_mode = { 42 .kind = "random", 43 .owner = THIS_MODULE, 44 .ops = &rnd_mode_ops, 45 .lag_tx_type = NETDEV_LAG_TX_TYPE_RANDOM, 46 }; 47 48 static int __init rnd_init_module(void) 49 { 50 return team_mode_register(&rnd_mode); 51 } 52 53 static void __exit rnd_cleanup_module(void) 54 { 55 team_mode_unregister(&rnd_mode); 56 } 57 58 module_init(rnd_init_module); 59 module_exit(rnd_cleanup_module); 60 61 MODULE_LICENSE("GPL v2"); 62 MODULE_AUTHOR("Jiri Pirko <jiri@resnulli.us>"); 63 MODULE_DESCRIPTION("Random mode for team"); 64 MODULE_ALIAS_TEAM_MODE("random"); 65