Merge tag 'v3.10.70' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / core / dev.c
index b24ab0e98eb4d8dd8cef2a20ef2a39b97d9ece92..a2b10bf466be4c88ca7c51491ff39b8a4188cd9a 100644 (file)
 #include <linux/inetdevice.h>
 #include <linux/cpu_rmap.h>
 #include <linux/static_key.h>
-
+#include <net/udp.h>
 #include "net-sysfs.h"
 
+#ifdef UDP_SKT_WIFI
+#include <linux/ftrace_event.h>
+#endif
+
 /* Instead of increasing this, you should create a hash table. */
 #define MAX_GRO_SKBS 8
 
@@ -200,7 +204,7 @@ static inline void rps_unlock(struct softnet_data *sd)
 }
 
 /* Device list insertion */
-static int list_netdevice(struct net_device *dev)
+static void list_netdevice(struct net_device *dev)
 {
        struct net *net = dev_net(dev);
 
@@ -214,8 +218,6 @@ static int list_netdevice(struct net_device *dev)
        write_unlock_bh(&dev_base_lock);
 
        dev_base_seq_inc(net);
-
-       return 0;
 }
 
 /* Device list removal
@@ -793,6 +795,40 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex)
 }
 EXPORT_SYMBOL(dev_get_by_index);
 
+/**
+ *     netdev_get_name - get a netdevice name, knowing its ifindex.
+ *     @net: network namespace
+ *     @name: a pointer to the buffer where the name will be stored.
+ *     @ifindex: the ifindex of the interface to get the name from.
+ *
+ *     The use of raw_seqcount_begin() and cond_resched() before
+ *     retrying is required as we want to give the writers a chance
+ *     to complete when CONFIG_PREEMPT is not set.
+ */
+int netdev_get_name(struct net *net, char *name, int ifindex)
+{
+       struct net_device *dev;
+       unsigned int seq;
+
+retry:
+       seq = raw_seqcount_begin(&devnet_rename_seq);
+       rcu_read_lock();
+       dev = dev_get_by_index_rcu(net, ifindex);
+       if (!dev) {
+               rcu_read_unlock();
+               return -ENODEV;
+       }
+
+       strcpy(name, dev->name);
+       rcu_read_unlock();
+       if (read_seqcount_retry(&devnet_rename_seq, seq)) {
+               cond_resched();
+               goto retry;
+       }
+
+       return 0;
+}
+
 /**
  *     dev_getbyhwaddr_rcu - find a device by its hardware address
  *     @net: the applicable net namespace
@@ -2210,30 +2246,51 @@ out:
 }
 EXPORT_SYMBOL(skb_checksum_help);
 
-/**
- *     skb_mac_gso_segment - mac layer segmentation handler.
- *     @skb: buffer to segment
- *     @features: features for the output path (see dev->features)
- */
-struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
-                                   netdev_features_t features)
+__be16 skb_network_protocol(struct sk_buff *skb)
 {
-       struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
-       struct packet_offload *ptype;
        __be16 type = skb->protocol;
        int vlan_depth = ETH_HLEN;
 
-       while (type == htons(ETH_P_8021Q)) {
+       /* Tunnel gso handlers can set protocol to ethernet. */
+       if (type == htons(ETH_P_TEB)) {
+               struct ethhdr *eth;
+
+               if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr))))
+                       return 0;
+
+               eth = (struct ethhdr *)skb_mac_header(skb);
+               type = eth->h_proto;
+       }
+
+       while (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) {
                struct vlan_hdr *vh;
 
                if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
-                       return ERR_PTR(-EINVAL);
+                       return 0;
 
                vh = (struct vlan_hdr *)(skb->data + vlan_depth);
                type = vh->h_vlan_encapsulated_proto;
                vlan_depth += VLAN_HLEN;
        }
 
+       return type;
+}
+
+/**
+ *     skb_mac_gso_segment - mac layer segmentation handler.
+ *     @skb: buffer to segment
+ *     @features: features for the output path (see dev->features)
+ */
+struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb,
+                                   netdev_features_t features)
+{
+       struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
+       struct packet_offload *ptype;
+       __be16 type = skb_network_protocol(skb);
+
+       if (unlikely(!type))
+               return ERR_PTR(-EINVAL);
+
        __skb_pull(skb, skb->mac_len);
 
        rcu_read_lock();
@@ -2321,7 +2378,7 @@ EXPORT_SYMBOL(netdev_rx_csum_fault);
  * 2. No high memory really exists on this machine.
  */
 
-static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
+static int illegal_highdma(const struct net_device *dev, struct sk_buff *skb)
 {
 #ifdef CONFIG_HIGHMEM
        int i;
@@ -2400,57 +2457,52 @@ static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features)
        return 0;
 }
 
-static bool can_checksum_protocol(netdev_features_t features, __be16 protocol)
-{
-       return ((features & NETIF_F_GEN_CSUM) ||
-               ((features & NETIF_F_V4_CSUM) &&
-                protocol == htons(ETH_P_IP)) ||
-               ((features & NETIF_F_V6_CSUM) &&
-                protocol == htons(ETH_P_IPV6)) ||
-               ((features & NETIF_F_FCOE_CRC) &&
-                protocol == htons(ETH_P_FCOE)));
-}
-
 static netdev_features_t harmonize_features(struct sk_buff *skb,
-       __be16 protocol, netdev_features_t features)
+                                           __be16 protocol,
+                                           const struct net_device *dev,
+                                           netdev_features_t features)
 {
        if (skb->ip_summed != CHECKSUM_NONE &&
            !can_checksum_protocol(features, protocol)) {
                features &= ~NETIF_F_ALL_CSUM;
-               features &= ~NETIF_F_SG;
-       } else if (illegal_highdma(skb->dev, skb)) {
+       } else if (illegal_highdma(dev, skb)) {
                features &= ~NETIF_F_SG;
        }
 
        return features;
 }
 
-netdev_features_t netif_skb_features(struct sk_buff *skb)
+netdev_features_t netif_skb_dev_features(struct sk_buff *skb,
+                                        const struct net_device *dev)
 {
        __be16 protocol = skb->protocol;
-       netdev_features_t features = skb->dev->features;
+       netdev_features_t features = dev->features;
 
-       if (skb_shinfo(skb)->gso_segs > skb->dev->gso_max_segs)
+       if (skb_shinfo(skb)->gso_segs > dev->gso_max_segs)
                features &= ~NETIF_F_GSO_MASK;
 
-       if (protocol == htons(ETH_P_8021Q)) {
+       if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) {
                struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
                protocol = veh->h_vlan_encapsulated_proto;
        } else if (!vlan_tx_tag_present(skb)) {
-               return harmonize_features(skb, protocol, features);
+               return harmonize_features(skb, protocol, dev, features);
        }
 
-       features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_TX);
+       features &= (dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX |
+                                              NETIF_F_HW_VLAN_STAG_TX);
 
-       if (protocol != htons(ETH_P_8021Q)) {
-               return harmonize_features(skb, protocol, features);
+       if (protocol != htons(ETH_P_8021Q) && protocol != htons(ETH_P_8021AD)) {
+               return harmonize_features(skb, protocol, dev, features);
        } else {
                features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
-                               NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_TX;
-               return harmonize_features(skb, protocol, features);
+                               NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
+                               NETIF_F_HW_VLAN_STAG_TX;
+               return harmonize_features(skb, protocol, dev, features);
        }
+
+       return harmonize_features(skb, protocol, dev, features);
 }
-EXPORT_SYMBOL(netif_skb_features);
+EXPORT_SYMBOL(netif_skb_dev_features);
 
 /*
  * Returns true if either:
@@ -2458,7 +2510,7 @@ EXPORT_SYMBOL(netif_skb_features);
  *     2. skb is fragmented and the device does not support SG.
  */
 static inline int skb_needs_linearize(struct sk_buff *skb,
-                                     int features)
+                                     netdev_features_t features)
 {
        return skb_is_nonlinear(skb) &&
                        ((skb_has_frag_list(skb) &&
@@ -2487,8 +2539,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                features = netif_skb_features(skb);
 
                if (vlan_tx_tag_present(skb) &&
-                   !(features & NETIF_F_HW_VLAN_TX)) {
-                       skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
+                   !vlan_hw_offload_capable(features, skb->vlan_proto)) {
+                       skb = __vlan_put_tag(skb, skb->vlan_proto,
+                                            vlan_tx_tag_get(skb));
                        if (unlikely(!skb))
                                goto out;
 
@@ -2547,13 +2600,6 @@ gso:
                skb->next = nskb->next;
                nskb->next = NULL;
 
-               /*
-                * If device doesn't need nskb->dst, release it right now while
-                * its hot in this cpu cache
-                */
-               if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
-                       skb_dst_drop(nskb);
-
                if (!list_empty(&ptype_all))
                        dev_queue_xmit_nit(nskb, dev);
 
@@ -2573,8 +2619,11 @@ gso:
        } while (skb->next);
 
 out_kfree_gso_skb:
-       if (likely(skb->next == NULL))
+       if (likely(skb->next == NULL)) {
                skb->destructor = DEV_GSO_CB(skb)->destructor;
+               consume_skb(skb);
+               return rc;
+       }
 out_kfree_skb:
        kfree_skb(skb);
 out:
@@ -2592,6 +2641,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb)
         */
        if (shinfo->gso_size)  {
                unsigned int hdr_len;
+               u16 gso_segs = shinfo->gso_segs;
 
                /* mac layer + network layer */
                hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
@@ -2601,7 +2651,12 @@ static void qdisc_pkt_len_init(struct sk_buff *skb)
                        hdr_len += tcp_hdrlen(skb);
                else
                        hdr_len += sizeof(struct udphdr);
-               qdisc_skb_cb(skb)->pkt_len += (shinfo->gso_segs - 1) * hdr_len;
+
+               if (shinfo->gso_type & SKB_GSO_DODGY)
+                       gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
+                                               shinfo->gso_size);
+
+               qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len;
        }
 }
 
@@ -2627,6 +2682,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
 
        spin_lock(root_lock);
        if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
+               printk(KERN_WARNING "[mtk_net]__dev_xmit_skb drop skb_len = %d \n", skb->len);
                kfree_skb(skb);
                rc = NET_XMIT_DROP;
        } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
@@ -2738,6 +2794,22 @@ int dev_queue_xmit(struct sk_buff *skb)
 
        skb_reset_mac_header(skb);
 
+#ifdef UDP_SKT_WIFI
+       
+       if (unlikely((sysctl_met_is_enable == 1) && (sysctl_udp_met_port > 0)
+                && (ip_hdr(skb)->protocol == IPPROTO_UDP) && skb->sk)) {
+               
+           if (sysctl_udp_met_port == ntohs((inet_sk(skb->sk))->inet_sport)) {
+               struct udphdr * udp_iphdr = udp_hdr(skb);
+               if (udp_iphdr && (ntohs(udp_iphdr->len) >= 12)) {
+                __u16 * seq_id = (__u16 *)((char *)udp_iphdr + 10);
+                   udp_event_trace_printk("F|%d|%s|%d\n", current->pid, *seq_id);
+                   
+               }
+           }
+       }
+#endif
+
        /* Disable soft irqs for various locks below. Also
         * stops preemption for RCU.
         */
@@ -3329,7 +3401,7 @@ EXPORT_SYMBOL_GPL(netdev_rx_handler_register);
  *     netdev_rx_handler_unregister - unregister receive handler
  *     @dev: device to unregister a handler from
  *
- *     Unregister a receive hander from a device.
+ *     Unregister a receive handler from a device.
  *
  *     The caller must hold the rtnl_mutex.
  */
@@ -3358,6 +3430,7 @@ static bool skb_pfmemalloc_protocol(struct sk_buff *skb)
        case __constant_htons(ETH_P_IP):
        case __constant_htons(ETH_P_IPV6):
        case __constant_htons(ETH_P_8021Q):
+       case __constant_htons(ETH_P_8021AD):
                return true;
        default:
                return false;
@@ -3398,7 +3471,8 @@ another_round:
 
        __this_cpu_inc(softnet_data.processed);
 
-       if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+       if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
+           skb->protocol == cpu_to_be16(ETH_P_8021AD)) {
                skb = vlan_untag(skb);
                if (unlikely(!skb))
                        goto unlock;
@@ -3465,8 +3539,15 @@ ncls:
                }
        }
 
-       if (vlan_tx_nonzero_tag_present(skb))
-               skb->pkt_type = PACKET_OTHERHOST;
+       if (unlikely(vlan_tx_tag_present(skb))) {
+               if (vlan_tx_tag_get_id(skb))
+                       skb->pkt_type = PACKET_OTHERHOST;
+               /* Note: we might in the future use prio bits
+                * and set skb->priority like in vlan_do_receive()
+                * For the time being, just ignore Priority Code Point
+                */
+               skb->vlan_tci = 0;
+       }
 
        /* deliver only exact match when indicated */
        null_or_dev = deliver_exact ? skb->dev : NULL;
@@ -3838,6 +3919,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
        skb->vlan_tci = 0;
        skb->dev = napi->dev;
        skb->skb_iif = 0;
+       skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
 
        napi->skb = skb;
 }
@@ -4066,6 +4148,9 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
        napi->gro_list = NULL;
        napi->skb = NULL;
        napi->poll = poll;
+       if (weight > NAPI_POLL_WEIGHT)
+               pr_err_once("netif_napi_add() called with weight %d on device %s\n",
+                           weight, dev->name);
        napi->weight = weight;
        list_add(&napi->dev_list, &dev->napi_list);
        napi->dev = dev;
@@ -4420,7 +4505,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags)
 {
        const struct net_device_ops *ops = dev->netdev_ops;
 
-       if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
+       if (ops->ndo_change_rx_flags)
                ops->ndo_change_rx_flags(dev, flags);
 }
 
@@ -4571,6 +4656,7 @@ void __dev_set_rx_mode(struct net_device *dev)
        if (ops->ndo_set_rx_mode)
                ops->ndo_set_rx_mode(dev);
 }
+EXPORT_SYMBOL(__dev_set_rx_mode);
 
 void dev_set_rx_mode(struct net_device *dev)
 {
@@ -4927,20 +5013,25 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
                features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
        }
 
-       /* Fix illegal SG+CSUM combinations. */
-       if ((features & NETIF_F_SG) &&
-           !(features & NETIF_F_ALL_CSUM)) {
-               netdev_dbg(dev,
-                       "Dropping NETIF_F_SG since no checksum feature.\n");
-               features &= ~NETIF_F_SG;
-       }
-
        /* TSO requires that SG is present as well. */
        if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) {
                netdev_dbg(dev, "Dropping TSO features since no SG feature.\n");
                features &= ~NETIF_F_ALL_TSO;
        }
 
+       if ((features & NETIF_F_TSO) && !(features & NETIF_F_HW_CSUM) &&
+                                       !(features & NETIF_F_IP_CSUM)) {
+               netdev_dbg(dev, "Dropping TSO features since no CSUM feature.\n");
+               features &= ~NETIF_F_TSO;
+               features &= ~NETIF_F_TSO_ECN;
+       }
+
+       if ((features & NETIF_F_TSO6) && !(features & NETIF_F_HW_CSUM) &&
+                                        !(features & NETIF_F_IPV6_CSUM)) {
+               netdev_dbg(dev, "Dropping TSO6 features since no CSUM feature.\n");
+               features &= ~NETIF_F_TSO6;
+       }
+
        /* TSO ECN requires that TSO is present as well. */
        if ((features & NETIF_F_ALL_TSO) == NETIF_F_TSO_ECN)
                features &= ~NETIF_F_TSO_ECN;
@@ -5171,7 +5262,8 @@ int register_netdevice(struct net_device *dev)
                }
        }
 
-       if (((dev->hw_features | dev->features) & NETIF_F_HW_VLAN_FILTER) &&
+       if (((dev->hw_features | dev->features) &
+            NETIF_F_HW_VLAN_CTAG_FILTER) &&
            (!dev->netdev_ops->ndo_vlan_rx_add_vid ||
             !dev->netdev_ops->ndo_vlan_rx_kill_vid)) {
                netdev_WARN(dev, "Buggy VLAN acceleration in driver!\n");
@@ -5208,6 +5300,10 @@ int register_netdevice(struct net_device *dev)
         */
        dev->vlan_features |= NETIF_F_HIGHDMA;
 
+       /* Make NETIF_F_SG inheritable to tunnel devices.
+        */
+       dev->hw_enc_features |= NETIF_F_SG;
+
        ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
        ret = notifier_to_errno(ret);
        if (ret)
@@ -5752,6 +5848,9 @@ EXPORT_SYMBOL(unregister_netdevice_queue);
 /**
  *     unregister_netdevice_many - unregister many devices
  *     @head: list of devices
+ *
+ *  Note: As most callers use a stack allocated list_head,
+ *  we force a list_del() to make sure stack wont be corrupted later.
  */
 void unregister_netdevice_many(struct list_head *head)
 {
@@ -5761,6 +5860,7 @@ void unregister_netdevice_many(struct list_head *head)
                rollback_registered_many(head);
                list_for_each_entry(dev, head, unreg_list)
                        net_set_todo(dev);
+               list_del(head);
        }
 }
 EXPORT_SYMBOL(unregister_netdevice_many);
@@ -5936,10 +6036,20 @@ 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);
+       /* Append NAPI poll list from offline CPU, with one exception :
+        * process_backlog() must be called by cpu owning percpu backlog.
+        * We properly handle process_queue & input_pkt_queue later.
+        */
+       while (!list_empty(&oldsd->poll_list)) {
+               struct napi_struct *napi = list_first_entry(&oldsd->poll_list,
+                                                           struct napi_struct,
+                                                           poll_list);
+
+               list_del_init(&napi->poll_list);
+               if (napi->poll == process_backlog)
+                       napi->state = 0;
+               else
+                       ____napi_schedule(sd, napi);
        }
 
        raise_softirq_irqoff(NET_TX_SOFTIRQ);
@@ -5950,7 +6060,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
                netif_rx(skb);
                input_queue_head_incr(oldsd);
        }
-       while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) {
+       while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
                netif_rx(skb);
                input_queue_head_incr(oldsd);
        }
@@ -6177,7 +6287,6 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
                }
        }
        unregister_netdevice_many(&dev_kill_list);
-       list_del(&dev_kill_list);
        rtnl_unlock();
 }