vlan: Fix the ingress VLAN_FLAG_REORDER_HDR check
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / core / dev.c
index b624fe4d9bd7ce408ab93d324ad7cc8413d8f4b8..9c58c1ec41a9dba24cca0318f723b01208c7b880 100644 (file)
@@ -948,7 +948,7 @@ int dev_alloc_name(struct net_device *dev, const char *name)
 }
 EXPORT_SYMBOL(dev_alloc_name);
 
-static int dev_get_valid_name(struct net_device *dev, const char *name, bool fmt)
+static int dev_get_valid_name(struct net_device *dev, const char *name)
 {
        struct net *net;
 
@@ -958,7 +958,7 @@ static int dev_get_valid_name(struct net_device *dev, const char *name, bool fmt
        if (!dev_valid_name(name))
                return -EINVAL;
 
-       if (fmt && strchr(name, '%'))
+       if (strchr(name, '%'))
                return dev_alloc_name(dev, name);
        else if (__dev_get_by_name(net, name))
                return -EEXIST;
@@ -995,7 +995,7 @@ int dev_change_name(struct net_device *dev, const char *newname)
 
        memcpy(oldname, dev->name, IFNAMSIZ);
 
-       err = dev_get_valid_name(dev, newname, 1);
+       err = dev_get_valid_name(dev, newname);
        if (err < 0)
                return err;
 
@@ -1007,7 +1007,7 @@ rollback:
        }
 
        write_lock_bh(&dev_base_lock);
-       hlist_del(&dev->name_hlist);
+       hlist_del_rcu(&dev->name_hlist);
        write_unlock_bh(&dev_base_lock);
 
        synchronize_rcu();
@@ -1308,6 +1308,13 @@ void dev_disable_lro(struct net_device *dev)
 {
        u32 flags;
 
+       /*
+        * If we're trying to disable lro on a vlan device
+        * use the underlying physical device instead
+        */
+       if (is_vlan_dev(dev))
+               dev = vlan_dev_real_dev(dev);
+
        if (dev->ethtool_ops && dev->ethtool_ops->get_flags)
                flags = dev->ethtool_ops->get_flags(dev);
        else
@@ -1317,7 +1324,8 @@ void dev_disable_lro(struct net_device *dev)
                return;
 
        __ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO);
-       WARN_ON(dev->features & NETIF_F_LRO);
+       if (unlikely(dev->features & NETIF_F_LRO))
+               netdev_WARN(dev, "failed to disable LRO!\n");
 }
 EXPORT_SYMBOL(dev_disable_lro);
 
@@ -2088,6 +2096,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 {
        const struct net_device_ops *ops = dev->netdev_ops;
        int rc = NETDEV_TX_OK;
+       unsigned int skb_len;
 
        if (likely(!skb->next)) {
                u32 features;
@@ -2138,8 +2147,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                        }
                }
 
+               skb_len = skb->len;
                rc = ops->ndo_start_xmit(skb, dev);
-               trace_net_dev_xmit(skb, rc);
+               trace_net_dev_xmit(skb, rc, dev, skb_len);
                if (rc == NETDEV_TX_OK)
                        txq_trans_update(txq);
                return rc;
@@ -2159,8 +2169,9 @@ gso:
                if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
                        skb_dst_drop(nskb);
 
+               skb_len = nskb->len;
                rc = ops->ndo_start_xmit(nskb, dev);
-               trace_net_dev_xmit(nskb, rc);
+               trace_net_dev_xmit(nskb, rc, dev, skb_len);
                if (unlikely(rc != NETDEV_TX_OK)) {
                        if (rc & ~NETDEV_TX_MASK)
                                goto out_kfree_gso_skb;
@@ -2504,8 +2515,8 @@ static inline void ____napi_schedule(struct softnet_data *sd,
 __u32 __skb_get_rxhash(struct sk_buff *skb)
 {
        int nhoff, hash = 0, poff;
-       struct ipv6hdr *ip6;
-       struct iphdr *ip;
+       const struct ipv6hdr *ip6;
+       const struct iphdr *ip;
        u8 ip_proto;
        u32 addr1, addr2, ihl;
        union {
@@ -2520,7 +2531,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
                if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
                        goto done;
 
-               ip = (struct iphdr *) (skb->data + nhoff);
+               ip = (const struct iphdr *) (skb->data + nhoff);
                if (ip->frag_off & htons(IP_MF | IP_OFFSET))
                        ip_proto = 0;
                else
@@ -2533,7 +2544,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb)
                if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
                        goto done;
 
-               ip6 = (struct ipv6hdr *) (skb->data + nhoff);
+               ip6 = (const struct ipv6hdr *) (skb->data + nhoff);
                ip_proto = ip6->nexthdr;
                addr1 = (__force u32) ip6->saddr.s6_addr32[3];
                addr2 = (__force u32) ip6->daddr.s6_addr32[3];
@@ -3078,25 +3089,6 @@ void netdev_rx_handler_unregister(struct net_device *dev)
 }
 EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
 
-static void vlan_on_bond_hook(struct sk_buff *skb)
-{
-       /*
-        * Make sure ARP frames received on VLAN interfaces stacked on
-        * bonding interfaces still make their way to any base bonding
-        * device that may have registered for a specific ptype.
-        */
-       if (skb->dev->priv_flags & IFF_802_1Q_VLAN &&
-           vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING &&
-           skb->protocol == htons(ETH_P_ARP)) {
-               struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
-
-               if (!skb2)
-                       return;
-               skb2->dev = vlan_dev_real_dev(skb->dev);
-               netif_rx(skb2);
-       }
-}
-
 static int __netif_receive_skb(struct sk_buff *skb)
 {
        struct packet_type *ptype, *pt_prev;
@@ -3122,7 +3114,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
 
        skb_reset_network_header(skb);
        skb_reset_transport_header(skb);
-       skb->mac_len = skb->network_header - skb->mac_header;
+       skb_reset_mac_len(skb);
 
        pt_prev = NULL;
 
@@ -3132,6 +3124,12 @@ another_round:
 
        __this_cpu_inc(softnet_data.processed);
 
+       if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+               skb = vlan_untag(skb);
+               if (unlikely(!skb))
+                       goto out;
+       }
+
 #ifdef CONFIG_NET_CLS_ACT
        if (skb->tc_verd & TC_NCLS) {
                skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@ -3179,15 +3177,13 @@ ncls:
                        ret = deliver_skb(skb, pt_prev, orig_dev);
                        pt_prev = NULL;
                }
-               if (vlan_hwaccel_do_receive(&skb)) {
+               if (vlan_do_receive(&skb)) {
                        ret = __netif_receive_skb(skb);
                        goto out;
                } else if (unlikely(!skb))
                        goto out;
        }
 
-       vlan_on_bond_hook(skb);
-
        /* deliver only exact match when indicated */
        null_or_dev = deliver_exact ? skb->dev : NULL;
 
@@ -4308,10 +4304,8 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
 
        slave->master = master;
 
-       if (old) {
-               synchronize_net();
+       if (old)
                dev_put(old);
-       }
        return 0;
 }
 EXPORT_SYMBOL(netdev_set_master);
@@ -4511,6 +4505,30 @@ void dev_set_rx_mode(struct net_device *dev)
        netif_addr_unlock_bh(dev);
 }
 
+/**
+ *     dev_ethtool_get_settings - call device's ethtool_ops::get_settings()
+ *     @dev: device
+ *     @cmd: memory area for ethtool_ops::get_settings() result
+ *
+ *      The cmd arg is initialized properly (cleared and
+ *      ethtool_cmd::cmd field set to ETHTOOL_GSET).
+ *
+ *     Return device's ethtool_ops::get_settings() result value or
+ *     -EOPNOTSUPP when device doesn't expose
+ *     ethtool_ops::get_settings() operation.
+ */
+int dev_ethtool_get_settings(struct net_device *dev,
+                            struct ethtool_cmd *cmd)
+{
+       if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
+               return -EOPNOTSUPP;
+
+       memset(cmd, 0, sizeof(struct ethtool_cmd));
+       cmd->cmd = ETHTOOL_GSET;
+       return dev->ethtool_ops->get_settings(dev, cmd);
+}
+EXPORT_SYMBOL(dev_ethtool_get_settings);
+
 /**
  *     dev_get_flags - get flags reported to userspace
  *     @dev: device
@@ -5116,7 +5134,7 @@ static void rollback_registered_many(struct list_head *head)
                        list_del(&dev->unreg_list);
                        continue;
                }
-
+               dev->dismantle = true;
                BUG_ON(dev->reg_state != NETREG_REGISTERED);
        }
 
@@ -5242,11 +5260,13 @@ u32 netdev_fix_features(struct net_device *dev, u32 features)
 }
 EXPORT_SYMBOL(netdev_fix_features);
 
-void netdev_update_features(struct net_device *dev)
+int __netdev_update_features(struct net_device *dev)
 {
        u32 features;
        int err = 0;
 
+       ASSERT_RTNL();
+
        features = netdev_get_wanted_features(dev);
 
        if (dev->netdev_ops->ndo_fix_features)
@@ -5256,23 +5276,59 @@ void netdev_update_features(struct net_device *dev)
        features = netdev_fix_features(dev, features);
 
        if (dev->features == features)
-               return;
+               return 0;
 
-       netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n",
+       netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n",
                dev->features, features);
 
        if (dev->netdev_ops->ndo_set_features)
                err = dev->netdev_ops->ndo_set_features(dev, features);
 
-       if (!err)
-               dev->features = features;
-       else if (err < 0)
+       if (unlikely(err < 0)) {
                netdev_err(dev,
                        "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
                        err, features, dev->features);
+               return -1;
+       }
+
+       if (!err)
+               dev->features = features;
+
+       return 1;
+}
+
+/**
+ *     netdev_update_features - recalculate device features
+ *     @dev: the device to check
+ *
+ *     Recalculate dev->features set and send notifications if it
+ *     has changed. Should be called after driver or hardware dependent
+ *     conditions might have changed that influence the features.
+ */
+void netdev_update_features(struct net_device *dev)
+{
+       if (__netdev_update_features(dev))
+               netdev_features_change(dev);
 }
 EXPORT_SYMBOL(netdev_update_features);
 
+/**
+ *     netdev_change_features - recalculate device features
+ *     @dev: the device to check
+ *
+ *     Recalculate dev->features set and send notifications even
+ *     if they have not changed. Should be called instead of
+ *     netdev_update_features() if also dev->vlan_features might
+ *     have changed to allow the changes to be propagated to stacked
+ *     VLAN devices.
+ */
+void netdev_change_features(struct net_device *dev)
+{
+       __netdev_update_features(dev);
+       netdev_features_change(dev);
+}
+EXPORT_SYMBOL(netdev_change_features);
+
 /**
  *     netif_stacked_transfer_operstate -      transfer operstate
  *     @rootdev: the root or lower level device to transfer state from
@@ -5389,6 +5445,10 @@ int register_netdevice(struct net_device *dev)
 
        dev->iflink = -1;
 
+       ret = dev_get_valid_name(dev, dev->name);
+       if (ret < 0)
+               goto out;
+
        /* Init, if this function is available */
        if (dev->netdev_ops->ndo_init) {
                ret = dev->netdev_ops->ndo_init(dev);
@@ -5399,10 +5459,6 @@ int register_netdevice(struct net_device *dev)
                }
        }
 
-       ret = dev_get_valid_name(dev, dev->name, 0);
-       if (ret)
-               goto err_uninit;
-
        dev->ifindex = dev_new_index(net);
        if (dev->iflink == -1)
                dev->iflink = dev->ifindex;
@@ -5414,6 +5470,14 @@ int register_netdevice(struct net_device *dev)
        dev->features |= NETIF_F_SOFT_FEATURES;
        dev->wanted_features = dev->features & dev->hw_features;
 
+       /* Turn on no cache copy if HW is doing checksum */
+       dev->hw_features |= NETIF_F_NOCACHE_COPY;
+       if ((dev->features & NETIF_F_ALL_CSUM) &&
+           !(dev->features & NETIF_F_NO_CSUM)) {
+               dev->wanted_features |= NETIF_F_NOCACHE_COPY;
+               dev->features |= NETIF_F_NOCACHE_COPY;
+       }
+
        /* Enable GRO and NETIF_F_HIGHDMA for vlans by default,
         * vlan_dev_init() will do the dev->features check, so these features
         * are enabled only if supported by underlying device.
@@ -5430,7 +5494,7 @@ int register_netdevice(struct net_device *dev)
                goto err_uninit;
        dev->reg_state = NETREG_REGISTERED;
 
-       netdev_update_features(dev);
+       __netdev_update_features(dev);
 
        /*
         *      Default initial state at registry is that the
@@ -5527,19 +5591,7 @@ int register_netdev(struct net_device *dev)
        int err;
 
        rtnl_lock();
-
-       /*
-        * If the name is a format string the caller wants us to do a
-        * name allocation.
-        */
-       if (strchr(dev->name, '%')) {
-               err = dev_alloc_name(dev, dev->name);
-               if (err < 0)
-                       goto out;
-       }
-
        err = register_netdevice(dev);
-out:
        rtnl_unlock();
        return err;
 }
@@ -5912,7 +5964,10 @@ EXPORT_SYMBOL(free_netdev);
 void synchronize_net(void)
 {
        might_sleep();
-       synchronize_rcu();
+       if (rtnl_is_locked())
+               synchronize_rcu_expedited();
+       else
+               synchronize_rcu();
 }
 EXPORT_SYMBOL(synchronize_net);
 
@@ -6021,7 +6076,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
                /* We get here if we can't use the current device name */
                if (!pat)
                        goto out;
-               if (dev_get_valid_name(dev, pat, 1))
+               if (dev_get_valid_name(dev, pat) < 0)
                        goto out;
        }
 
@@ -6123,6 +6178,11 @@ static int dev_cpu_callback(struct notifier_block *nfb,
                oldsd->output_queue = NULL;
                oldsd->output_queue_tailp = &oldsd->output_queue;
        }
+       /* Append NAPI poll list from offline CPU. */
+       if (!list_empty(&oldsd->poll_list)) {
+               list_splice_init(&oldsd->poll_list, &sd->poll_list);
+               raise_softirq_irqoff(NET_RX_SOFTIRQ);
+       }
 
        raise_softirq_irqoff(NET_TX_SOFTIRQ);
        local_irq_enable();
@@ -6153,29 +6213,20 @@ static int dev_cpu_callback(struct notifier_block *nfb,
  */
 u32 netdev_increment_features(u32 all, u32 one, u32 mask)
 {
-       /* If device needs checksumming, downgrade to it. */
-       if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
-               all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM);
-       else if (mask & NETIF_F_ALL_CSUM) {
-               /* If one device supports v4/v6 checksumming, set for all. */
-               if (one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) &&
-                   !(all & NETIF_F_GEN_CSUM)) {
-                       all &= ~NETIF_F_ALL_CSUM;
-                       all |= one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-               }
+       if (mask & NETIF_F_GEN_CSUM)
+               mask |= NETIF_F_ALL_CSUM;
+       mask |= NETIF_F_VLAN_CHALLENGED;
 
-               /* If one device supports hw checksumming, set for all. */
-               if (one & NETIF_F_GEN_CSUM && !(all & NETIF_F_GEN_CSUM)) {
-                       all &= ~NETIF_F_ALL_CSUM;
-                       all |= NETIF_F_HW_CSUM;
-               }
-       }
+       all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask;
+       all &= one | ~NETIF_F_ALL_FOR_ALL;
 
-       one |= NETIF_F_ALL_CSUM;
+       /* If device needs checksumming, downgrade to it. */
+       if (all & (NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM))
+               all &= ~NETIF_F_NO_CSUM;
 
-       one |= all & NETIF_F_ONE_FOR_ALL;
-       all &= one | NETIF_F_LLTX | NETIF_F_GSO | NETIF_F_UFO;
-       all |= one & mask & NETIF_F_ONE_FOR_ALL;
+       /* If one device supports hw checksumming, set for all. */
+       if (all & NETIF_F_GEN_CSUM)
+               all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
 
        return all;
 }
@@ -6218,29 +6269,23 @@ err_name:
 /**
  *     netdev_drivername - network driver for the device
  *     @dev: network device
- *     @buffer: buffer for resulting name
- *     @len: size of buffer
  *
  *     Determine network driver for device.
  */
-char *netdev_drivername(const struct net_device *dev, char *buffer, int len)
+const char *netdev_drivername(const struct net_device *dev)
 {
        const struct device_driver *driver;
        const struct device *parent;
-
-       if (len <= 0 || !buffer)
-               return buffer;
-       buffer[0] = 0;
+       const char *empty = "";
 
        parent = dev->dev.parent;
-
        if (!parent)
-               return buffer;
+               return empty;
 
        driver = parent->driver;
        if (driver && driver->name)
-               strlcpy(buffer, driver->name, len);
-       return buffer;
+               return driver->name;
+       return empty;
 }
 
 static int __netdev_printk(const char *level, const struct net_device *dev,