diff options
Diffstat (limited to 'drivers/net/bonding/bonding.h')
-rw-r--r-- | drivers/net/bonding/bonding.h | 96 |
1 files changed, 54 insertions, 42 deletions
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 42d1c6599cb..f7ab16185f6 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -71,6 +71,28 @@ set_fs(fs); \ res; }) +/* slave list primitives */ +#define bond_to_slave(ptr) list_entry(ptr, struct slave, list) + +/* IMPORTANT: bond_first/last_slave can return NULL in case of an empty list */ +#define bond_first_slave(bond) \ + list_first_entry_or_null(&(bond)->slave_list, struct slave, list) +#define bond_last_slave(bond) \ + (list_empty(&(bond)->slave_list) ? NULL : \ + bond_to_slave((bond)->slave_list.prev)) + +#define bond_is_first_slave(bond, pos) ((pos)->list.prev == &(bond)->slave_list) +#define bond_is_last_slave(bond, pos) ((pos)->list.next == &(bond)->slave_list) + +/* Since bond_first/last_slave can return NULL, these can return NULL too */ +#define bond_next_slave(bond, pos) \ + (bond_is_last_slave(bond, pos) ? bond_first_slave(bond) : \ + bond_to_slave((pos)->list.next)) + +#define bond_prev_slave(bond, pos) \ + (bond_is_first_slave(bond, pos) ? bond_last_slave(bond) : \ + bond_to_slave((pos)->list.prev)) + /** * bond_for_each_slave_from - iterate the slaves list from a starting point * @bond: the bond holding this list. @@ -80,37 +102,33 @@ * * Caller must hold bond->lock */ -#define bond_for_each_slave_from(bond, pos, cnt, start) \ - for (cnt = 0, pos = start; \ - cnt < (bond)->slave_cnt; \ - cnt++, pos = (pos)->next) +#define bond_for_each_slave_from(bond, pos, cnt, start) \ + for (cnt = 0, pos = start; pos && cnt < (bond)->slave_cnt; \ + cnt++, pos = bond_next_slave(bond, pos)) /** - * bond_for_each_slave_from_to - iterate the slaves list from start point to stop point - * @bond: the bond holding this list. - * @pos: current slave. - * @cnt: counter for number max of moves - * @start: start point. - * @stop: stop point. + * bond_for_each_slave - iterate over all slaves + * @bond: the bond holding this list + * @pos: current slave * * Caller must hold bond->lock */ -#define bond_for_each_slave_from_to(bond, pos, cnt, start, stop) \ - for (cnt = 0, pos = start; \ - ((cnt < (bond)->slave_cnt) && (pos != (stop)->next)); \ - cnt++, pos = (pos)->next) +#define bond_for_each_slave(bond, pos) \ + list_for_each_entry(pos, &(bond)->slave_list, list) + +/* Caller must have rcu_read_lock */ +#define bond_for_each_slave_rcu(bond, pos) \ + list_for_each_entry_rcu(pos, &(bond)->slave_list, list) /** - * bond_for_each_slave - iterate the slaves list from head - * @bond: the bond holding this list. - * @pos: current slave. - * @cnt: counter for max number of moves + * bond_for_each_slave_reverse - iterate in reverse from a given position + * @bond: the bond holding this list + * @pos: slave to continue from * * Caller must hold bond->lock */ -#define bond_for_each_slave(bond, pos, cnt) \ - bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave) - +#define bond_for_each_slave_continue_reverse(bond, pos) \ + list_for_each_entry_continue_reverse(pos, &(bond)->slave_list, list) #ifdef CONFIG_NET_POLL_CONTROLLER extern atomic_t netpoll_block_tx; @@ -167,15 +185,9 @@ struct bond_parm_tbl { #define BOND_MAX_MODENAME_LEN 20 -struct vlan_entry { - struct list_head vlan_list; - unsigned short vlan_id; -}; - struct slave { struct net_device *dev; /* first - useful for panic debug */ - struct slave *next; - struct slave *prev; + struct list_head list; struct bonding *bond; /* our master */ int delay; unsigned long jiffies; @@ -215,7 +227,7 @@ struct slave { */ struct bonding { struct net_device *dev; /* first - useful for panic debug */ - struct slave *first_slave; + struct list_head slave_list; struct slave *curr_active_slave; struct slave *current_arp_slave; struct slave *primary_slave; @@ -237,7 +249,6 @@ struct bonding { struct ad_bond_info ad_info; struct alb_bond_info alb_info; struct bond_params params; - struct list_head vlan_list; struct workqueue_struct *wq; struct delayed_work mii_work; struct delayed_work arp_work; @@ -250,11 +261,6 @@ struct bonding { #endif /* CONFIG_DEBUG_FS */ }; -static inline bool bond_vlan_used(struct bonding *bond) -{ - return !list_empty(&bond->vlan_list); -} - #define bond_slave_get_rcu(dev) \ ((struct slave *) rcu_dereference(dev->rx_handler_data)) @@ -270,13 +276,10 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev) { struct slave *slave = NULL; - int i; - bond_for_each_slave(bond, slave, i) { - if (slave->dev == slave_dev) { + bond_for_each_slave(bond, slave) + if (slave->dev == slave_dev) return slave; - } - } return NULL; } @@ -416,10 +419,20 @@ static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be3 return addr; } +static inline bool slave_can_tx(struct slave *slave) +{ + if (IS_UP(slave->dev) && slave->link == BOND_LINK_UP && + bond_is_active_slave(slave)) + return true; + else + return false; +} + struct bond_net; struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); +void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id); int bond_create(struct net *net, const char *name); int bond_create_sysfs(struct bond_net *net); void bond_destroy_sysfs(struct bond_net *net); @@ -477,10 +490,9 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn) static inline struct slave *bond_slave_has_mac(struct bonding *bond, const u8 *mac) { - int i = 0; struct slave *tmp; - bond_for_each_slave(bond, tmp, i) + bond_for_each_slave(bond, tmp) if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr)) return tmp; |