net: introduce rx_handler results and logic around that
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / net / bonding / bond_main.c
index a93d941..27c413a 100644 (file)
@@ -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 <slave> to bond device <master> */
@@ -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)