18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * drivers/net/team/team_mode_random.c - Random mode for team 48c2ecf20Sopenharmony_ci * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <linux/types.h> 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci#include <linux/init.h> 118c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 128c2ecf20Sopenharmony_ci#include <linux/if_team.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic bool rnd_transmit(struct team *team, struct sk_buff *skb) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci struct team_port *port; 178c2ecf20Sopenharmony_ci int port_index; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci port_index = prandom_u32_max(team->en_port_count); 208c2ecf20Sopenharmony_ci port = team_get_port_by_index_rcu(team, port_index); 218c2ecf20Sopenharmony_ci if (unlikely(!port)) 228c2ecf20Sopenharmony_ci goto drop; 238c2ecf20Sopenharmony_ci port = team_get_first_port_txable_rcu(team, port); 248c2ecf20Sopenharmony_ci if (unlikely(!port)) 258c2ecf20Sopenharmony_ci goto drop; 268c2ecf20Sopenharmony_ci if (team_dev_queue_xmit(team, port, skb)) 278c2ecf20Sopenharmony_ci return false; 288c2ecf20Sopenharmony_ci return true; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cidrop: 318c2ecf20Sopenharmony_ci dev_kfree_skb_any(skb); 328c2ecf20Sopenharmony_ci return false; 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic const struct team_mode_ops rnd_mode_ops = { 368c2ecf20Sopenharmony_ci .transmit = rnd_transmit, 378c2ecf20Sopenharmony_ci .port_enter = team_modeop_port_enter, 388c2ecf20Sopenharmony_ci .port_change_dev_addr = team_modeop_port_change_dev_addr, 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic const struct team_mode rnd_mode = { 428c2ecf20Sopenharmony_ci .kind = "random", 438c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 448c2ecf20Sopenharmony_ci .ops = &rnd_mode_ops, 458c2ecf20Sopenharmony_ci .lag_tx_type = NETDEV_LAG_TX_TYPE_RANDOM, 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic int __init rnd_init_module(void) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci return team_mode_register(&rnd_mode); 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic void __exit rnd_cleanup_module(void) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci team_mode_unregister(&rnd_mode); 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cimodule_init(rnd_init_module); 598c2ecf20Sopenharmony_cimodule_exit(rnd_cleanup_module); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 628c2ecf20Sopenharmony_ciMODULE_AUTHOR("Jiri Pirko <jiri@resnulli.us>"); 638c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Random mode for team"); 648c2ecf20Sopenharmony_ciMODULE_ALIAS_TEAM_MODE("random"); 65