1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #ifndef _NET_BOND_ALB_H 7*4882a593Smuzhiyun #define _NET_BOND_ALB_H 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <linux/if_ether.h> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun struct bonding; 12*4882a593Smuzhiyun struct slave; 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #define BOND_ALB_INFO(bond) ((bond)->alb_info) 15*4882a593Smuzhiyun #define SLAVE_TLB_INFO(slave) ((slave)->tlb_info) 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */ 18*4882a593Smuzhiyun #define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing. 19*4882a593Smuzhiyun * Used for division - never set 20*4882a593Smuzhiyun * to zero !!! 21*4882a593Smuzhiyun */ 22*4882a593Smuzhiyun #define BOND_ALB_DEFAULT_LP_INTERVAL 1 23*4882a593Smuzhiyun #define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval) /* In seconds, periodic send of 24*4882a593Smuzhiyun * learning packets to the switch 25*4882a593Smuzhiyun */ 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun #define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \ 28*4882a593Smuzhiyun * ALB_TIMER_TICKS_PER_SEC) 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun #define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \ 31*4882a593Smuzhiyun * ALB_TIMER_TICKS_PER_SEC) 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table. 34*4882a593Smuzhiyun * Note that this value MUST NOT be smaller 35*4882a593Smuzhiyun * because the key hash table is BYTE wide ! 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun #define TLB_NULL_INDEX 0xffffffff 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* rlb defs */ 42*4882a593Smuzhiyun #define RLB_HASH_TABLE_SIZE 256 43*4882a593Smuzhiyun #define RLB_NULL_INDEX 0xffffffff 44*4882a593Smuzhiyun #define RLB_UPDATE_DELAY (2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */ 45*4882a593Smuzhiyun #define RLB_ARP_BURST_SIZE 2 46*4882a593Smuzhiyun #define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb 47*4882a593Smuzhiyun * rebalance interval (5 min). 48*4882a593Smuzhiyun */ 49*4882a593Smuzhiyun /* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is 50*4882a593Smuzhiyun * promiscuous after failover 51*4882a593Smuzhiyun */ 52*4882a593Smuzhiyun #define RLB_PROMISC_TIMEOUT (10*ALB_TIMER_TICKS_PER_SEC) 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun struct tlb_client_info { 56*4882a593Smuzhiyun struct slave *tx_slave; /* A pointer to slave used for transmiting 57*4882a593Smuzhiyun * packets to a Client that the Hash function 58*4882a593Smuzhiyun * gave this entry index. 59*4882a593Smuzhiyun */ 60*4882a593Smuzhiyun u32 tx_bytes; /* Each Client accumulates the BytesTx that 61*4882a593Smuzhiyun * were transmitted to it, and after each 62*4882a593Smuzhiyun * CallBack the LoadHistory is divided 63*4882a593Smuzhiyun * by the balance interval 64*4882a593Smuzhiyun */ 65*4882a593Smuzhiyun u32 load_history; /* This field contains the amount of Bytes 66*4882a593Smuzhiyun * that were transmitted to this client by 67*4882a593Smuzhiyun * the server on the previous balance 68*4882a593Smuzhiyun * interval in Bps. 69*4882a593Smuzhiyun */ 70*4882a593Smuzhiyun u32 next; /* The next Hash table entry index, assigned 71*4882a593Smuzhiyun * to use the same adapter for transmit. 72*4882a593Smuzhiyun */ 73*4882a593Smuzhiyun u32 prev; /* The previous Hash table entry index, 74*4882a593Smuzhiyun * assigned to use the same 75*4882a593Smuzhiyun */ 76*4882a593Smuzhiyun }; 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun /* ------------------------------------------------------------------------- 79*4882a593Smuzhiyun * struct rlb_client_info contains all info related to a specific rx client 80*4882a593Smuzhiyun * connection. This is the Clients Hash Table entry struct. 81*4882a593Smuzhiyun * Note that this is not a proper hash table; if a new client's IP address 82*4882a593Smuzhiyun * hash collides with an existing client entry, the old entry is replaced. 83*4882a593Smuzhiyun * 84*4882a593Smuzhiyun * There is a linked list (linked by the used_next and used_prev members) 85*4882a593Smuzhiyun * linking all the used entries of the hash table. This allows updating 86*4882a593Smuzhiyun * all the clients without walking over all the unused elements of the table. 87*4882a593Smuzhiyun * 88*4882a593Smuzhiyun * There are also linked lists of entries with identical hash(ip_src). These 89*4882a593Smuzhiyun * allow cleaning up the table from ip_src<->mac_src associations that have 90*4882a593Smuzhiyun * become outdated and would cause sending out invalid ARP updates to the 91*4882a593Smuzhiyun * network. These are linked by the (src_next and src_prev members). 92*4882a593Smuzhiyun * ------------------------------------------------------------------------- 93*4882a593Smuzhiyun */ 94*4882a593Smuzhiyun struct rlb_client_info { 95*4882a593Smuzhiyun __be32 ip_src; /* the server IP address */ 96*4882a593Smuzhiyun __be32 ip_dst; /* the client IP address */ 97*4882a593Smuzhiyun u8 mac_src[ETH_ALEN]; /* the server MAC address */ 98*4882a593Smuzhiyun u8 mac_dst[ETH_ALEN]; /* the client MAC address */ 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun /* list of used hash table entries, starting at rx_hashtbl_used_head */ 101*4882a593Smuzhiyun u32 used_next; 102*4882a593Smuzhiyun u32 used_prev; 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun /* ip_src based hashing */ 105*4882a593Smuzhiyun u32 src_next; /* next entry with same hash(ip_src) */ 106*4882a593Smuzhiyun u32 src_prev; /* prev entry with same hash(ip_src) */ 107*4882a593Smuzhiyun u32 src_first; /* first entry with hash(ip_src) == this entry's index */ 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun u8 assigned; /* checking whether this entry is assigned */ 110*4882a593Smuzhiyun u8 ntt; /* flag - need to transmit client info */ 111*4882a593Smuzhiyun struct slave *slave; /* the slave assigned to this client */ 112*4882a593Smuzhiyun unsigned short vlan_id; /* VLAN tag associated with IP address */ 113*4882a593Smuzhiyun }; 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun struct tlb_slave_info { 116*4882a593Smuzhiyun u32 head; /* Index to the head of the bi-directional clients 117*4882a593Smuzhiyun * hash table entries list. The entries in the list 118*4882a593Smuzhiyun * are the entries that were assigned to use this 119*4882a593Smuzhiyun * slave for transmit. 120*4882a593Smuzhiyun */ 121*4882a593Smuzhiyun u32 load; /* Each slave sums the loadHistory of all clients 122*4882a593Smuzhiyun * assigned to it 123*4882a593Smuzhiyun */ 124*4882a593Smuzhiyun }; 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun struct alb_bond_info { 127*4882a593Smuzhiyun struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */ 128*4882a593Smuzhiyun u32 unbalanced_load; 129*4882a593Smuzhiyun atomic_t tx_rebalance_counter; 130*4882a593Smuzhiyun int lp_counter; 131*4882a593Smuzhiyun /* -------- rlb parameters -------- */ 132*4882a593Smuzhiyun int rlb_enabled; 133*4882a593Smuzhiyun struct rlb_client_info *rx_hashtbl; /* Receive hash table */ 134*4882a593Smuzhiyun u32 rx_hashtbl_used_head; 135*4882a593Smuzhiyun u8 rx_ntt; /* flag - need to transmit 136*4882a593Smuzhiyun * to all rx clients 137*4882a593Smuzhiyun */ 138*4882a593Smuzhiyun struct slave *rx_slave;/* last slave to xmit from */ 139*4882a593Smuzhiyun u8 primary_is_promisc; /* boolean */ 140*4882a593Smuzhiyun u32 rlb_promisc_timeout_counter;/* counts primary 141*4882a593Smuzhiyun * promiscuity time 142*4882a593Smuzhiyun */ 143*4882a593Smuzhiyun u32 rlb_update_delay_counter; 144*4882a593Smuzhiyun u32 rlb_update_retry_counter;/* counter of retries 145*4882a593Smuzhiyun * of client update 146*4882a593Smuzhiyun */ 147*4882a593Smuzhiyun u8 rlb_rebalance; /* flag - indicates that the 148*4882a593Smuzhiyun * rx traffic should be 149*4882a593Smuzhiyun * rebalanced 150*4882a593Smuzhiyun */ 151*4882a593Smuzhiyun }; 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun int bond_alb_initialize(struct bonding *bond, int rlb_enabled); 154*4882a593Smuzhiyun void bond_alb_deinitialize(struct bonding *bond); 155*4882a593Smuzhiyun int bond_alb_init_slave(struct bonding *bond, struct slave *slave); 156*4882a593Smuzhiyun void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave); 157*4882a593Smuzhiyun void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link); 158*4882a593Smuzhiyun void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave); 159*4882a593Smuzhiyun int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev); 160*4882a593Smuzhiyun int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev); 161*4882a593Smuzhiyun struct slave *bond_xmit_alb_slave_get(struct bonding *bond, 162*4882a593Smuzhiyun struct sk_buff *skb); 163*4882a593Smuzhiyun struct slave *bond_xmit_tlb_slave_get(struct bonding *bond, 164*4882a593Smuzhiyun struct sk_buff *skb); 165*4882a593Smuzhiyun void bond_alb_monitor(struct work_struct *); 166*4882a593Smuzhiyun int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr); 167*4882a593Smuzhiyun void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id); 168*4882a593Smuzhiyun #endif /* _NET_BOND_ALB_H */ 169*4882a593Smuzhiyun 170