X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fnet%2Fbonding%2Fbond_main.c;h=27c413aa15da06c24b711c8d493682c8d056c80e;hb=8a4eb5734e8d1dc60a8c28576bbbdfdcc643626d;hp=a93d9417dc150f5d72a789d1ae1a3d8a58d0b554;hpb=fd0e435b0fe85622f167b84432552885a4856ac8;p=platform%2Fadaptation%2Frenesas_rcar%2Frenesas_kernel.git diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a93d941..27c413a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1458,20 +1458,20 @@ static void bond_setup_by_slave(struct net_device *bond_dev, * ARP on active-backup slaves with arp_validate enabled. */ static bool bond_should_deliver_exact_match(struct sk_buff *skb, - struct net_device *slave_dev, - struct net_device *bond_dev) + struct slave *slave, + struct bonding *bond) { - if (slave_dev->priv_flags & IFF_SLAVE_INACTIVE) { - if (slave_dev->priv_flags & IFF_SLAVE_NEEDARP && + if (bond_is_slave_inactive(slave)) { + if (slave_do_arp_validate(bond, slave) && skb->protocol == __cpu_to_be16(ETH_P_ARP)) return false; - if (bond_dev->priv_flags & IFF_MASTER_ALB && + if (bond->params.mode == BOND_MODE_ALB && skb->pkt_type != PACKET_BROADCAST && skb->pkt_type != PACKET_MULTICAST) return false; - if (bond_dev->priv_flags & IFF_MASTER_8023AD && + if (bond->params.mode == BOND_MODE_8023AD && skb->protocol == __cpu_to_be16(ETH_P_SLOW)) return false; @@ -1480,42 +1480,48 @@ static bool bond_should_deliver_exact_match(struct sk_buff *skb, return false; } -static struct sk_buff *bond_handle_frame(struct sk_buff *skb) +static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) { - struct net_device *slave_dev; + struct sk_buff *skb = *pskb; + struct slave *slave; struct net_device *bond_dev; + struct bonding *bond; + + slave = bond_slave_get_rcu(skb->dev); + bond_dev = ACCESS_ONCE(slave->dev->master); + if (unlikely(!bond_dev)) + return RX_HANDLER_PASS; skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) - return NULL; - slave_dev = skb->dev; - bond_dev = ACCESS_ONCE(slave_dev->master); - if (unlikely(!bond_dev)) - return skb; + return RX_HANDLER_CONSUMED; + + *pskb = skb; + + bond = netdev_priv(bond_dev); - if (bond_dev->priv_flags & IFF_MASTER_ARPMON) - slave_dev->last_rx = jiffies; + if (bond->params.arp_interval) + slave->dev->last_rx = jiffies; - if (bond_should_deliver_exact_match(skb, slave_dev, bond_dev)) { - skb->deliver_no_wcard = 1; - return skb; + if (bond_should_deliver_exact_match(skb, slave, bond)) { + return RX_HANDLER_EXACT; } skb->dev = bond_dev; - if (bond_dev->priv_flags & IFF_MASTER_ALB && + if (bond->params.mode == BOND_MODE_ALB && bond_dev->priv_flags & IFF_BRIDGE_PORT && skb->pkt_type == PACKET_HOST) { if (unlikely(skb_cow_head(skb, skb->data - skb_mac_header(skb)))) { kfree_skb(skb); - return NULL; + return RX_HANDLER_CONSUMED; } memcpy(eth_hdr(skb)->h_dest, bond_dev->dev_addr, ETH_ALEN); } - return skb; + return RX_HANDLER_ANOTHER; } /* enslave device to bond device */ @@ -1694,7 +1700,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) pr_debug("Error %d calling netdev_set_bond_master\n", res); goto err_restore_mac; } - res = netdev_rx_handler_register(slave_dev, bond_handle_frame, NULL); + res = netdev_rx_handler_register(slave_dev, bond_handle_frame, + new_slave); if (res) { pr_debug("Error %d calling netdev_rx_handler_register\n", res); goto err_unset_master; @@ -1858,7 +1865,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) break; case BOND_MODE_TLB: case BOND_MODE_ALB: - new_slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(new_slave); bond_set_slave_inactive_flags(new_slave); bond_select_active_slave(bond); break; @@ -1866,7 +1873,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) pr_debug("This slave is always active in trunk mode\n"); /* always active in trunk mode */ - new_slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(new_slave); /* In trunking mode there is little meaning to curr_active_slave * anyway (it holds no special properties of the bond device), @@ -1904,7 +1911,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) pr_info("%s: enslaving %s as a%s interface with a%s link.\n", bond_dev->name, slave_dev->name, - new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup", + bond_is_active_slave(new_slave) ? "n active" : " backup", new_slave->link != BOND_LINK_DOWN ? "n up" : " down"); /* enslave is successful */ @@ -1916,6 +1923,7 @@ err_close: err_unreg_rxhandler: netdev_rx_handler_unregister(slave_dev); + synchronize_net(); err_unset_master: netdev_set_bond_master(slave_dev, NULL); @@ -2001,7 +2009,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) pr_info("%s: releasing %s interface %s\n", bond_dev->name, - (slave->state == BOND_STATE_ACTIVE) ? "active" : "backup", + bond_is_active_slave(slave) ? "active" : "backup", slave_dev->name); oldcurrent = bond->curr_active_slave; @@ -2099,6 +2107,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } netdev_rx_handler_unregister(slave_dev); + synchronize_net(); netdev_set_bond_master(slave_dev, NULL); slave_disable_netpoll(slave); @@ -2115,9 +2124,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) dev_set_mtu(slave_dev, slave->original_mtu); - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE | IFF_BONDING | - IFF_SLAVE_NEEDARP); + slave_dev->priv_flags &= ~IFF_BONDING; kfree(slave); @@ -2213,6 +2220,7 @@ static int bond_release_all(struct net_device *bond_dev) } netdev_rx_handler_unregister(slave_dev); + synchronize_net(); netdev_set_bond_master(slave_dev, NULL); slave_disable_netpoll(slave); @@ -2227,9 +2235,6 @@ static int bond_release_all(struct net_device *bond_dev) dev_set_mac_address(slave_dev, &addr); } - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE); - kfree(slave); /* re-acquire the lock before getting the next slave */ @@ -2343,7 +2348,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in res = 0; strcpy(info->slave_name, slave->dev->name); info->link = slave->link; - info->state = slave->state; + info->state = bond_slave_state(slave); info->link_failure_count = slave->link_failure_count; break; } @@ -2382,7 +2387,7 @@ static int bond_miimon_inspect(struct bonding *bond) bond->dev->name, (bond->params.mode == BOND_MODE_ACTIVEBACKUP) ? - ((slave->state == BOND_STATE_ACTIVE) ? + (bond_is_active_slave(slave) ? "active " : "backup ") : "", slave->dev->name, bond->params.downdelay * bond->params.miimon); @@ -2473,13 +2478,13 @@ static void bond_miimon_commit(struct bonding *bond) if (bond->params.mode == BOND_MODE_8023AD) { /* prevent it from being the active one */ - slave->state = BOND_STATE_BACKUP; + bond_set_backup_slave(slave); } else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) { /* make it immediately active */ - slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(slave); } else if (slave != bond->primary_slave) { /* prevent it from being the active one */ - slave->state = BOND_STATE_BACKUP; + bond_set_backup_slave(slave); } bond_update_speed_duplex(slave); @@ -2853,7 +2858,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack memcpy(&tip, arp_ptr, 4); pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n", - bond->dev->name, slave->dev->name, slave->state, + bond->dev->name, slave->dev->name, bond_slave_state(slave), bond->params.arp_validate, slave_do_arp_validate(bond, slave), &sip, &tip); @@ -2865,7 +2870,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack * the active, through one switch, the router, then the other * switch before reaching the backup. */ - if (slave->state == BOND_STATE_ACTIVE) + if (bond_is_active_slave(slave)) bond_validate_arp(bond, slave, sip, tip); else bond_validate_arp(bond, slave, tip, sip); @@ -2927,7 +2932,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work) slave->dev->last_rx + delta_in_ticks)) { slave->link = BOND_LINK_UP; - slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(slave); /* primary_slave has no meaning in round-robin * mode. the window of a slave being up and @@ -2960,7 +2965,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work) slave->dev->last_rx + 2 * delta_in_ticks)) { slave->link = BOND_LINK_DOWN; - slave->state = BOND_STATE_BACKUP; + bond_set_backup_slave(slave); if (slave->link_failure_count < UINT_MAX) slave->link_failure_count++; @@ -3054,7 +3059,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) * gives each slave a chance to tx/rx traffic * before being taken out */ - if (slave->state == BOND_STATE_BACKUP && + if (!bond_is_active_slave(slave) && !bond->current_arp_slave && !time_in_range(jiffies, slave_last_rx(bond, slave) - delta_in_ticks, @@ -3071,7 +3076,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) * the bond has an IP address) */ trans_start = dev_trans_start(slave->dev); - if ((slave->state == BOND_STATE_ACTIVE) && + if (bond_is_active_slave(slave) && (!time_in_range(jiffies, trans_start - delta_in_ticks, trans_start + 2 * delta_in_ticks) || @@ -4135,7 +4140,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev bond_for_each_slave_from(bond, slave, i, start_at) { if (IS_UP(slave->dev) && (slave->link == BOND_LINK_UP) && - (slave->state == BOND_STATE_ACTIVE)) { + bond_is_active_slave(slave)) { res = bond_dev_queue_xmit(bond, skb, slave->dev); break; } @@ -4212,7 +4217,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) bond_for_each_slave_from(bond, slave, i, start_at) { if (IS_UP(slave->dev) && (slave->link == BOND_LINK_UP) && - (slave->state == BOND_STATE_ACTIVE)) { + bond_is_active_slave(slave)) { res = bond_dev_queue_xmit(bond, skb, slave->dev); break; } @@ -4253,7 +4258,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) bond_for_each_slave_from(bond, slave, i, start_at) { if (IS_UP(slave->dev) && (slave->link == BOND_LINK_UP) && - (slave->state == BOND_STATE_ACTIVE)) { + bond_is_active_slave(slave)) { if (tx_dev) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (!skb2) { @@ -4414,11 +4419,9 @@ void bond_set_mode_ops(struct bonding *bond, int mode) case BOND_MODE_BROADCAST: break; case BOND_MODE_8023AD: - bond_set_master_3ad_flags(bond); bond_set_xmit_hash_policy(bond); break; case BOND_MODE_ALB: - bond_set_master_alb_flags(bond); /* FALLTHRU */ case BOND_MODE_TLB: break; @@ -4509,9 +4512,6 @@ static void bond_setup(struct net_device *bond_dev) bond_dev->priv_flags |= IFF_BONDING; bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; - if (bond->params.arp_interval) - bond_dev->priv_flags |= IFF_MASTER_ARPMON; - /* At first, we block adding VLANs. That's the only way to * prevent problems that occur when adding VLANs over an * empty bond. The block will be removed once non-challenged @@ -4980,8 +4980,6 @@ static int bond_init(struct net_device *bond_dev) bond_set_lockdep_class(bond_dev); - netif_carrier_off(bond_dev); - bond_create_proc_entry(bond); list_add_tail(&bond->bond_list, &bn->dev_list); @@ -5051,6 +5049,8 @@ int bond_create(struct net *net, const char *name) res = register_netdevice(bond_dev); + netif_carrier_off(bond_dev); + out: rtnl_unlock(); if (res < 0)