From dbdc8a21759959af2c4a702cacbb94f9b1864e73 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Fri, 11 May 2018 02:53:10 -0700 Subject: bonding: replace the return value type The method ndo_start_xmit is defined as returning a netdev_tx_t, which is a typedef for an enum type, but the implementation in this driver returns an int. Signed-off-by: Tonghao Zhang Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 8 ++++---- drivers/net/bonding/bond_main.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 1ed9529e7bd1..601f67872e58 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -1316,8 +1316,8 @@ void bond_alb_deinitialize(struct bonding *bond) rlb_deinitialize(bond); } -static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond, - struct slave *tx_slave) +static netdev_tx_t bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond, + struct slave *tx_slave) { struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); struct ethhdr *eth_data = eth_hdr(skb); @@ -1351,7 +1351,7 @@ out: return NETDEV_TX_OK; } -int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) +netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); struct ethhdr *eth_data; @@ -1389,7 +1389,7 @@ int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) return bond_do_alb_xmit(skb, bond, tx_slave); } -int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) +netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); struct ethhdr *eth_data; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 718e4914e3a0..01bca863e7d8 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3805,7 +3805,8 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond) return slave_id; } -static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev) +static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb, + struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); struct iphdr *iph = ip_hdr(skb); @@ -3841,7 +3842,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev /* In active-backup mode, we know that bond->curr_active_slave is always valid if * the bond has a usable interface. */ -static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_dev) +static netdev_tx_t bond_xmit_activebackup(struct sk_buff *skb, + struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); struct slave *slave; @@ -3979,7 +3981,8 @@ out: * usable slave array is formed in the control path. The xmit function * just calculates hash and sends the packet out. */ -static int bond_3ad_xor_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb, + struct net_device *dev) { struct bonding *bond = netdev_priv(dev); struct slave *slave; @@ -3999,7 +4002,8 @@ static int bond_3ad_xor_xmit(struct sk_buff *skb, struct net_device *dev) } /* in broadcast mode, we send everything to all usable interfaces. */ -static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) +static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb, + struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); struct slave *slave = NULL; -- cgit v1.2.3 From ae35c6f7a5e78c3bcf1b468a3d352fa0021a22bb Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Fri, 11 May 2018 02:53:11 -0700 Subject: bonding: use the skb_get/set_queue_mapping Use the skb_get_queue_mapping, skb_set_queue_mapping and skb_rx_queue_recorded for skb queue_mapping in bonding driver, but not use it directly. Signed-off-by: Tonghao Zhang Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 01bca863e7d8..966d09183744 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -247,7 +247,7 @@ void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, BUILD_BUG_ON(sizeof(skb->queue_mapping) != sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); - skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping; + skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping); if (unlikely(netpoll_tx_running(bond->dev))) bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); @@ -4040,12 +4040,12 @@ static inline int bond_slave_override(struct bonding *bond, struct slave *slave = NULL; struct list_head *iter; - if (!skb->queue_mapping) + if (!skb_rx_queue_recorded(skb)) return 1; /* Find out if any slaves have the same mapping as this skb. */ bond_for_each_slave_rcu(bond, slave, iter) { - if (slave->queue_id == skb->queue_mapping) { + if (slave->queue_id == skb_get_queue_mapping(skb)) { if (bond_slave_is_up(slave) && slave->link == BOND_LINK_UP) { bond_dev_queue_xmit(bond, skb, slave->dev); @@ -4071,7 +4071,7 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; /* Save the original txq to restore before passing to the driver */ - qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping; + qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb_get_queue_mapping(skb); if (unlikely(txq >= dev->real_num_tx_queues)) { do { -- cgit v1.2.3 From 2578041011c43c38f3742e161cdb99b710d5a9f8 Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Mon, 14 May 2018 14:48:07 -0400 Subject: bonding: don't queue up extraneous rlb updates arps for incomplete entries can't be sent anyway. Signed-off-by: Debabrata Banerjee Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index a8f60982d483..9f7031ec56d5 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -421,7 +421,8 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) if (assigned_slave) { rx_hash_table[index].slave = assigned_slave; if (!ether_addr_equal_64bits(rx_hash_table[index].mac_dst, - mac_bcast)) { + mac_bcast) && + !is_zero_ether_addr(rx_hash_table[index].mac_dst)) { bond_info->rx_hashtbl[index].ntt = 1; bond_info->rx_ntt = 1; /* A slave has been removed from the @@ -524,7 +525,8 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla client_info = &(bond_info->rx_hashtbl[hash_index]); if ((client_info->slave == slave) && - !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { + !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast) && + !is_zero_ether_addr(client_info->mac_dst)) { client_info->ntt = 1; ntt = 1; } @@ -565,7 +567,8 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) if ((client_info->ip_src == src_ip) && !ether_addr_equal_64bits(client_info->slave->dev->dev_addr, bond->dev->dev_addr) && - !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { + !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast) && + !is_zero_ether_addr(client_info->mac_dst)) { client_info->ntt = 1; bond_info->rx_ntt = 1; } @@ -641,7 +644,8 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon ether_addr_copy(client_info->mac_src, arp->mac_src); client_info->slave = assigned_slave; - if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) { + if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast) && + !is_zero_ether_addr(client_info->mac_dst)) { client_info->ntt = 1; bond->alb_info.rx_ntt = 1; } else { @@ -733,8 +737,10 @@ static void rlb_rebalance(struct bonding *bond) assigned_slave = __rlb_next_rx_slave(bond); if (assigned_slave && (client_info->slave != assigned_slave)) { client_info->slave = assigned_slave; - client_info->ntt = 1; - ntt = 1; + if (!is_zero_ether_addr(client_info->mac_dst)) { + client_info->ntt = 1; + ntt = 1; + } } } -- cgit v1.2.3 From cbeeea70de457ce4de89197d72943ab455b4172c Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Mon, 14 May 2018 14:48:08 -0400 Subject: bonding: use common mac addr checks Replace homegrown mac addr checks with faster defs from etherdevice.h Note that this will also prevent any rlb arp updates for multicast addresses, however this should have been forbidden anyway. Signed-off-by: Debabrata Banerjee Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 9f7031ec56d5..67fd1af1d1de 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -40,11 +40,6 @@ #include #include - - -static const u8 mac_bcast[ETH_ALEN + 2] __long_aligned = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; static const u8 mac_v6_allmcast[ETH_ALEN + 2] __long_aligned = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x01 }; @@ -420,9 +415,7 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) if (assigned_slave) { rx_hash_table[index].slave = assigned_slave; - if (!ether_addr_equal_64bits(rx_hash_table[index].mac_dst, - mac_bcast) && - !is_zero_ether_addr(rx_hash_table[index].mac_dst)) { + if (is_valid_ether_addr(rx_hash_table[index].mac_dst)) { bond_info->rx_hashtbl[index].ntt = 1; bond_info->rx_ntt = 1; /* A slave has been removed from the @@ -525,8 +518,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla client_info = &(bond_info->rx_hashtbl[hash_index]); if ((client_info->slave == slave) && - !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast) && - !is_zero_ether_addr(client_info->mac_dst)) { + is_valid_ether_addr(client_info->mac_dst)) { client_info->ntt = 1; ntt = 1; } @@ -567,8 +559,7 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) if ((client_info->ip_src == src_ip) && !ether_addr_equal_64bits(client_info->slave->dev->dev_addr, bond->dev->dev_addr) && - !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast) && - !is_zero_ether_addr(client_info->mac_dst)) { + is_valid_ether_addr(client_info->mac_dst)) { client_info->ntt = 1; bond_info->rx_ntt = 1; } @@ -596,7 +587,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon if ((client_info->ip_src == arp->ip_src) && (client_info->ip_dst == arp->ip_dst)) { /* the entry is already assigned to this client */ - if (!ether_addr_equal_64bits(arp->mac_dst, mac_bcast)) { + if (!is_broadcast_ether_addr(arp->mac_dst)) { /* update mac address from arp */ ether_addr_copy(client_info->mac_dst, arp->mac_dst); } @@ -644,8 +635,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon ether_addr_copy(client_info->mac_src, arp->mac_src); client_info->slave = assigned_slave; - if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast) && - !is_zero_ether_addr(client_info->mac_dst)) { + if (is_valid_ether_addr(client_info->mac_dst)) { client_info->ntt = 1; bond->alb_info.rx_ntt = 1; } else { @@ -1418,9 +1408,9 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) case ETH_P_IP: { const struct iphdr *iph = ip_hdr(skb); - if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) || - (iph->daddr == ip_bcast) || - (iph->protocol == IPPROTO_IGMP)) { + if (is_broadcast_ether_addr(eth_data->h_dest) || + iph->daddr == ip_bcast || + iph->protocol == IPPROTO_IGMP) { do_tx_balance = false; break; } @@ -1432,7 +1422,7 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) /* IPv6 doesn't really use broadcast mac address, but leave * that here just in case. */ - if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast)) { + if (is_broadcast_ether_addr(eth_data->h_dest)) { do_tx_balance = false; break; } -- cgit v1.2.3 From e79c1055749e3183a2beee04a24da378623329c5 Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Mon, 14 May 2018 14:48:09 -0400 Subject: bonding: allow use of tx hashing in balance-alb The rx load balancing provided by balance-alb is not mutually exclusive with using hashing for tx selection, and should provide a decent speed increase because this eliminates spinlocks and cache contention. Signed-off-by: Debabrata Banerjee Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 20 ++++++++++++++++++-- drivers/net/bonding/bond_main.c | 25 +++++++++++++++---------- drivers/net/bonding/bond_options.c | 2 +- include/net/bonding.h | 11 +++++++++-- 4 files changed, 43 insertions(+), 15 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 67fd1af1d1de..e82108c917a6 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -1478,8 +1478,24 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) } if (do_tx_balance) { - hash_index = _simple_hash(hash_start, hash_size); - tx_slave = tlb_choose_channel(bond, hash_index, skb->len); + if (bond->params.tlb_dynamic_lb) { + hash_index = _simple_hash(hash_start, hash_size); + tx_slave = tlb_choose_channel(bond, hash_index, skb->len); + } else { + /* + * do_tx_balance means we are free to select the tx_slave + * So we do exactly what tlb would do for hash selection + */ + + struct bond_up_slave *slaves; + unsigned int count; + + slaves = rcu_dereference(bond->slave_arr); + count = slaves ? READ_ONCE(slaves->count) : 0; + if (likely(count)) + tx_slave = slaves->arr[bond_xmit_hash(bond, skb) % + count]; + } } return bond_do_alb_xmit(skb, bond, tx_slave); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4176e1d95f47..a4cd7f6bfd4d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -159,7 +159,7 @@ module_param(min_links, int, 0); MODULE_PARM_DESC(min_links, "Minimum number of available links before turning on carrier"); module_param(xmit_hash_policy, charp, 0); -MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; " +MODULE_PARM_DESC(xmit_hash_policy, "balance-alb, balance-tlb, balance-xor, 802.3ad hashing method; " "0 for layer 2 (default), 1 for layer 3+4, " "2 for layer 2+3, 3 for encap layer 2+3, " "4 for encap layer 3+4"); @@ -1735,7 +1735,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, unblock_netpoll_tx(); } - if (bond_mode_uses_xmit_hash(bond)) + if (bond_mode_can_use_xmit_hash(bond)) bond_update_slave_arr(bond, NULL); bond->nest_level = dev_get_nest_level(bond_dev); @@ -1870,7 +1870,7 @@ static int __bond_release_one(struct net_device *bond_dev, if (BOND_MODE(bond) == BOND_MODE_8023AD) bond_3ad_unbind_slave(slave); - if (bond_mode_uses_xmit_hash(bond)) + if (bond_mode_can_use_xmit_hash(bond)) bond_update_slave_arr(bond, slave); netdev_info(bond_dev, "Releasing %s interface %s\n", @@ -3102,7 +3102,7 @@ static int bond_slave_netdev_event(unsigned long event, * events. If these (miimon/arpmon) parameters are configured * then array gets refreshed twice and that should be fine! */ - if (bond_mode_uses_xmit_hash(bond)) + if (bond_mode_can_use_xmit_hash(bond)) bond_update_slave_arr(bond, NULL); break; case NETDEV_CHANGEMTU: @@ -3322,7 +3322,7 @@ static int bond_open(struct net_device *bond_dev) */ if (bond_alb_initialize(bond, (BOND_MODE(bond) == BOND_MODE_ALB))) return -ENOMEM; - if (bond->params.tlb_dynamic_lb) + if (bond->params.tlb_dynamic_lb || BOND_MODE(bond) == BOND_MODE_ALB) queue_delayed_work(bond->wq, &bond->alb_work, 0); } @@ -3341,7 +3341,7 @@ static int bond_open(struct net_device *bond_dev) bond_3ad_initiate_agg_selection(bond, 1); } - if (bond_mode_uses_xmit_hash(bond)) + if (bond_mode_can_use_xmit_hash(bond)) bond_update_slave_arr(bond, NULL); return 0; @@ -3894,7 +3894,7 @@ err: * to determine the slave interface - * (a) BOND_MODE_8023AD * (b) BOND_MODE_XOR - * (c) BOND_MODE_TLB && tlb_dynamic_lb == 0 + * (c) (BOND_MODE_TLB || BOND_MODE_ALB) && tlb_dynamic_lb == 0 * * The caller is expected to hold RTNL only and NO other lock! */ @@ -3947,6 +3947,11 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave) continue; if (skipslave == slave) continue; + + netdev_dbg(bond->dev, + "Adding slave dev %s to tx hash array[%d]\n", + slave->dev->name, new_arr->count); + new_arr->arr[new_arr->count++] = slave; } @@ -4324,9 +4329,9 @@ static int bond_check_params(struct bond_params *params) } if (xmit_hash_policy) { - if ((bond_mode != BOND_MODE_XOR) && - (bond_mode != BOND_MODE_8023AD) && - (bond_mode != BOND_MODE_TLB)) { + if (bond_mode == BOND_MODE_ROUNDROBIN || + bond_mode == BOND_MODE_ACTIVEBACKUP || + bond_mode == BOND_MODE_BROADCAST) { pr_info("xmit_hash_policy param is irrelevant in mode %s\n", bond_mode_name(bond_mode)); } else { diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 58c705f24f96..8a945c9341d6 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -395,7 +395,7 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { .id = BOND_OPT_TLB_DYNAMIC_LB, .name = "tlb_dynamic_lb", .desc = "Enable dynamic flow shuffling", - .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_TLB)), + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_TLB) | BIT(BOND_MODE_ALB)), .values = bond_tlb_dynamic_lb_tbl, .flags = BOND_OPTFLAG_IFDOWN, .set = bond_option_tlb_dynamic_lb_set, diff --git a/include/net/bonding.h b/include/net/bonding.h index b52235158836..808f1d167349 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -285,8 +285,15 @@ static inline bool bond_needs_speed_duplex(const struct bonding *bond) static inline bool bond_is_nondyn_tlb(const struct bonding *bond) { - return (BOND_MODE(bond) == BOND_MODE_TLB) && - (bond->params.tlb_dynamic_lb == 0); + return (bond_is_lb(bond) && bond->params.tlb_dynamic_lb == 0); +} + +static inline bool bond_mode_can_use_xmit_hash(const struct bonding *bond) +{ + return (BOND_MODE(bond) == BOND_MODE_8023AD || + BOND_MODE(bond) == BOND_MODE_XOR || + BOND_MODE(bond) == BOND_MODE_TLB || + BOND_MODE(bond) == BOND_MODE_ALB); } static inline bool bond_mode_uses_xmit_hash(const struct bonding *bond) -- cgit v1.2.3 From 1386c36b30388f46a95100924bfcae75160db715 Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Mon, 14 May 2018 14:48:10 -0400 Subject: bonding: allow carrier and link status to determine link state In a mixed environment it may be difficult to tell if your hardware support carrier, if it does not it can always report true. With a new use_carrier option of 2, we can check both carrier and link status sequentially, instead of one or the other Signed-off-by: Debabrata Banerjee Signed-off-by: David S. Miller --- Documentation/networking/bonding.txt | 4 ++-- drivers/net/bonding/bond_main.c | 12 ++++++++---- drivers/net/bonding/bond_options.c | 7 ++++--- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers/net/bonding') diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index c13214d073a4..86d07fbb592d 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -828,8 +828,8 @@ use_carrier MII / ETHTOOL ioctl method to determine the link state. A value of 1 enables the use of netif_carrier_ok(), a value of - 0 will use the deprecated MII / ETHTOOL ioctls. The default - value is 1. + 0 will use the deprecated MII / ETHTOOL ioctls. A value of 2 + will check both. The default value is 1. xmit_hash_policy diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a4cd7f6bfd4d..e4c253dc7dfb 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -132,7 +132,7 @@ MODULE_PARM_DESC(downdelay, "Delay before considering link down, " "in milliseconds"); module_param(use_carrier, int, 0); MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; " - "0 for off, 1 for on (default)"); + "0 for off, 1 for on (default), 2 for carrier then legacy checks"); module_param(mode, charp, 0); MODULE_PARM_DESC(mode, "Mode of operation; 0 for balance-rr, " "1 for active-backup, 2 for balance-xor, " @@ -434,12 +434,16 @@ static int bond_check_dev_link(struct bonding *bond, int (*ioctl)(struct net_device *, struct ifreq *, int); struct ifreq ifr; struct mii_ioctl_data *mii; + bool carrier = true; if (!reporting && !netif_running(slave_dev)) return 0; if (bond->params.use_carrier) - return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; + carrier = netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; + + if (!carrier) + return carrier; /* Try to get link status using Ethtool first. */ if (slave_dev->ethtool_ops->get_link) @@ -4403,8 +4407,8 @@ static int bond_check_params(struct bond_params *params) downdelay = 0; } - if ((use_carrier != 0) && (use_carrier != 1)) { - pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n", + if (use_carrier < 0 || use_carrier > 2) { + pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0-2), so it was set to 1\n", use_carrier); use_carrier = 1; } diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 8a945c9341d6..dba6cef05134 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -164,9 +164,10 @@ static const struct bond_opt_value bond_primary_reselect_tbl[] = { }; static const struct bond_opt_value bond_use_carrier_tbl[] = { - { "off", 0, 0}, - { "on", 1, BOND_VALFLAG_DEFAULT}, - { NULL, -1, 0} + { "off", 0, 0}, + { "on", 1, BOND_VALFLAG_DEFAULT}, + { "both", 2, 0}, + { NULL, -1, 0} }; static const struct bond_opt_value bond_all_slaves_active_tbl[] = { -- cgit v1.2.3 From b3c898e20b1881b0876c3e811c58b039b37dd5fd Mon Sep 17 00:00:00 2001 From: Debabrata Banerjee Date: Wed, 16 May 2018 14:02:13 -0400 Subject: Revert "bonding: allow carrier and link status to determine link state" This reverts commit 1386c36b30388f46a95100924bfcae75160db715. We don't want to encourage drivers to not report carrier status correctly, therefore remove this commit. Signed-off-by: Debabrata Banerjee Signed-off-by: David S. Miller --- Documentation/networking/bonding.txt | 4 ++-- drivers/net/bonding/bond_main.c | 12 ++++-------- drivers/net/bonding/bond_options.c | 7 +++---- 3 files changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers/net/bonding') diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 86d07fbb592d..c13214d073a4 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -828,8 +828,8 @@ use_carrier MII / ETHTOOL ioctl method to determine the link state. A value of 1 enables the use of netif_carrier_ok(), a value of - 0 will use the deprecated MII / ETHTOOL ioctls. A value of 2 - will check both. The default value is 1. + 0 will use the deprecated MII / ETHTOOL ioctls. The default + value is 1. xmit_hash_policy diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e4c253dc7dfb..a4cd7f6bfd4d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -132,7 +132,7 @@ MODULE_PARM_DESC(downdelay, "Delay before considering link down, " "in milliseconds"); module_param(use_carrier, int, 0); MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; " - "0 for off, 1 for on (default), 2 for carrier then legacy checks"); + "0 for off, 1 for on (default)"); module_param(mode, charp, 0); MODULE_PARM_DESC(mode, "Mode of operation; 0 for balance-rr, " "1 for active-backup, 2 for balance-xor, " @@ -434,16 +434,12 @@ static int bond_check_dev_link(struct bonding *bond, int (*ioctl)(struct net_device *, struct ifreq *, int); struct ifreq ifr; struct mii_ioctl_data *mii; - bool carrier = true; if (!reporting && !netif_running(slave_dev)) return 0; if (bond->params.use_carrier) - carrier = netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; - - if (!carrier) - return carrier; + return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; /* Try to get link status using Ethtool first. */ if (slave_dev->ethtool_ops->get_link) @@ -4407,8 +4403,8 @@ static int bond_check_params(struct bond_params *params) downdelay = 0; } - if (use_carrier < 0 || use_carrier > 2) { - pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0-2), so it was set to 1\n", + if ((use_carrier != 0) && (use_carrier != 1)) { + pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n", use_carrier); use_carrier = 1; } diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index dba6cef05134..8a945c9341d6 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -164,10 +164,9 @@ static const struct bond_opt_value bond_primary_reselect_tbl[] = { }; static const struct bond_opt_value bond_use_carrier_tbl[] = { - { "off", 0, 0}, - { "on", 1, BOND_VALFLAG_DEFAULT}, - { "both", 2, 0}, - { NULL, -1, 0} + { "off", 0, 0}, + { "on", 1, BOND_VALFLAG_DEFAULT}, + { NULL, -1, 0} }; static const struct bond_opt_value bond_all_slaves_active_tbl[] = { -- cgit v1.2.3 From 7e878b605f05bf0c09aa0d81e05fb7878bf8c7d4 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Wed, 16 May 2018 19:09:23 -0700 Subject: bonding: introduce link change helper Introduce an new common helper to avoid redundancy. Signed-off-by: Tonghao Zhang Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a4cd7f6bfd4d..06efdf6a762b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2137,6 +2137,24 @@ static int bond_miimon_inspect(struct bonding *bond) return commit; } +static void bond_miimon_link_change(struct bonding *bond, + struct slave *slave, + char link) +{ + switch (BOND_MODE(bond)) { + case BOND_MODE_8023AD: + bond_3ad_handle_link_change(slave, link); + break; + case BOND_MODE_TLB: + case BOND_MODE_ALB: + bond_alb_handle_link_change(bond, slave, link); + break; + case BOND_MODE_XOR: + bond_update_slave_arr(bond, NULL); + break; + } +} + static void bond_miimon_commit(struct bonding *bond) { struct list_head *iter; @@ -2178,16 +2196,7 @@ static void bond_miimon_commit(struct bonding *bond) slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, slave->duplex ? "full" : "half"); - /* notify ad that the link status has changed */ - if (BOND_MODE(bond) == BOND_MODE_8023AD) - bond_3ad_handle_link_change(slave, BOND_LINK_UP); - - if (bond_is_lb(bond)) - bond_alb_handle_link_change(bond, slave, - BOND_LINK_UP); - - if (BOND_MODE(bond) == BOND_MODE_XOR) - bond_update_slave_arr(bond, NULL); + bond_miimon_link_change(bond, slave, BOND_LINK_UP); if (!bond->curr_active_slave || slave == primary) goto do_failover; @@ -2209,16 +2218,7 @@ static void bond_miimon_commit(struct bonding *bond) netdev_info(bond->dev, "link status definitely down for interface %s, disabling it\n", slave->dev->name); - if (BOND_MODE(bond) == BOND_MODE_8023AD) - bond_3ad_handle_link_change(slave, - BOND_LINK_DOWN); - - if (bond_is_lb(bond)) - bond_alb_handle_link_change(bond, slave, - BOND_LINK_DOWN); - - if (BOND_MODE(bond) == BOND_MODE_XOR) - bond_update_slave_arr(bond, NULL); + bond_miimon_link_change(bond, slave, BOND_LINK_DOWN); if (slave == rcu_access_pointer(bond->curr_active_slave)) goto do_failover; -- cgit v1.2.3 From 8eea1ca82be90a7e7a4624ab9cb323574a5f71df Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Tue, 22 May 2018 11:34:40 -0400 Subject: gso: limit udp gso to egress-only virtual devices Until the udp receive stack supports large packets (UDP GRO), GSO packets must not loop from the egress to the ingress path. Revert the change that added NETIF_F_GSO_UDP_L4 to various virtual devices through NETIF_F_GSO_ENCAP_ALL as this included devices that may loop packets, such as veth and macvlan. Instead add it to specific devices that forward to another device's egress path, bonding and team. Fixes: 83aa025f535f ("udp: add gso support to virtual devices") CC: Alexander Duyck Signed-off-by: Willem de Bruijn Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 5 +++-- drivers/net/team/team.c | 5 +++-- include/linux/netdev_features.h | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 06efdf6a762b..fea17b92b1ae 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1107,7 +1107,8 @@ static void bond_compute_features(struct bonding *bond) done: bond_dev->vlan_features = vlan_features; - bond_dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL; + bond_dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL | + NETIF_F_GSO_UDP_L4; bond_dev->gso_max_segs = gso_max_segs; netif_set_gso_max_size(bond_dev, gso_max_size); @@ -4268,7 +4269,7 @@ void bond_setup(struct net_device *bond_dev) NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; - bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL; + bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; bond_dev->features |= bond_dev->hw_features; } diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 9dbd390ace34..d6ff881165d0 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1026,7 +1026,8 @@ static void __team_compute_features(struct team *team) } team->dev->vlan_features = vlan_features; - team->dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL; + team->dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL | + NETIF_F_GSO_UDP_L4; team->dev->hard_header_len = max_hard_header_len; team->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; @@ -2117,7 +2118,7 @@ static void team_setup(struct net_device *dev) NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; - dev->hw_features |= NETIF_F_GSO_ENCAP_ALL; + dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; dev->features |= dev->hw_features; } diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index c87c3a3453c1..623bb8ced060 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -220,7 +220,6 @@ enum { NETIF_F_GSO_GRE_CSUM | \ NETIF_F_GSO_IPXIP4 | \ NETIF_F_GSO_IPXIP6 | \ - NETIF_F_GSO_UDP_L4 | \ NETIF_F_GSO_UDP_TUNNEL | \ NETIF_F_GSO_UDP_TUNNEL_CSUM) -- cgit v1.2.3 From f44aa9ef7950a56daa3a5b41f069761f945f1a1f Mon Sep 17 00:00:00 2001 From: John Hurley Date: Wed, 23 May 2018 19:22:52 -0700 Subject: net: include hash policy in LAG changeupper info LAG upper event notifiers contain the tx type used by the LAG device. Extend this to also include the hash policy used for tx types that utilize hashing. Signed-off-by: John Hurley Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 27 ++++++++++++++++++++++++++- drivers/net/team/team.c | 1 + include/linux/netdevice.h | 11 +++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/net/bonding') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index fea17b92b1ae..bd53a71f6b00 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1218,12 +1218,37 @@ static enum netdev_lag_tx_type bond_lag_tx_type(struct bonding *bond) } } +static enum netdev_lag_hash bond_lag_hash_type(struct bonding *bond, + enum netdev_lag_tx_type type) +{ + if (type != NETDEV_LAG_TX_TYPE_HASH) + return NETDEV_LAG_HASH_NONE; + + switch (bond->params.xmit_policy) { + case BOND_XMIT_POLICY_LAYER2: + return NETDEV_LAG_HASH_L2; + case BOND_XMIT_POLICY_LAYER34: + return NETDEV_LAG_HASH_L34; + case BOND_XMIT_POLICY_LAYER23: + return NETDEV_LAG_HASH_L23; + case BOND_XMIT_POLICY_ENCAP23: + return NETDEV_LAG_HASH_E23; + case BOND_XMIT_POLICY_ENCAP34: + return NETDEV_LAG_HASH_E34; + default: + return NETDEV_LAG_HASH_UNKNOWN; + } +} + static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave, struct netlink_ext_ack *extack) { struct netdev_lag_upper_info lag_upper_info; + enum netdev_lag_tx_type type; - lag_upper_info.tx_type = bond_lag_tx_type(bond); + type = bond_lag_tx_type(bond); + lag_upper_info.tx_type = type; + lag_upper_info.hash_type = bond_lag_hash_type(bond, type); return netdev_master_upper_dev_link(slave->dev, bond->dev, slave, &lag_upper_info, extack); diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index d6ff881165d0..e6730a01d130 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1129,6 +1129,7 @@ static int team_upper_dev_link(struct team *team, struct team_port *port, int err; lag_upper_info.tx_type = team->mode->lag_tx_type; + lag_upper_info.hash_type = NETDEV_LAG_HASH_UNKNOWN; err = netdev_master_upper_dev_link(port->dev, team->dev, NULL, &lag_upper_info, extack); if (err) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index debdb6286170..8452f72087ef 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2332,8 +2332,19 @@ enum netdev_lag_tx_type { NETDEV_LAG_TX_TYPE_HASH, }; +enum netdev_lag_hash { + NETDEV_LAG_HASH_NONE, + NETDEV_LAG_HASH_L2, + NETDEV_LAG_HASH_L34, + NETDEV_LAG_HASH_L23, + NETDEV_LAG_HASH_E23, + NETDEV_LAG_HASH_E34, + NETDEV_LAG_HASH_UNKNOWN, +}; + struct netdev_lag_upper_info { enum netdev_lag_tx_type tx_type; + enum netdev_lag_hash hash_type; }; struct netdev_lag_lower_state_info { -- cgit v1.2.3