openvswitch: Use tun_key only for egress tunnel path.
[firefly-linux-kernel-4.4.55.git] / net / openvswitch / vport.c
index 6d8f2ec481d9d33927795cfd3f4a59bb7258f128..5df8377fcfb1d59a721fbecbed70f2313cafe8cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2012 Nicira, Inc.
+ * Copyright (c) 2007-2014 Nicira, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -148,8 +148,6 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
                return ERR_PTR(-ENOMEM);
        }
 
-       spin_lock_init(&vport->stats_lock);
-
        return vport;
 }
 
@@ -268,14 +266,10 @@ void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
         * netdev-stats can be directly read over netlink-ioctl.
         */
 
-       spin_lock_bh(&vport->stats_lock);
-
-       stats->rx_errors        = vport->err_stats.rx_errors;
-       stats->tx_errors        = vport->err_stats.tx_errors;
-       stats->tx_dropped       = vport->err_stats.tx_dropped;
-       stats->rx_dropped       = vport->err_stats.rx_dropped;
-
-       spin_unlock_bh(&vport->stats_lock);
+       stats->rx_errors  = atomic_long_read(&vport->err_stats.rx_errors);
+       stats->tx_errors  = atomic_long_read(&vport->err_stats.tx_errors);
+       stats->tx_dropped = atomic_long_read(&vport->err_stats.tx_dropped);
+       stats->rx_dropped = atomic_long_read(&vport->err_stats.rx_dropped);
 
        for_each_possible_cpu(i) {
                const struct pcpu_sw_netstats *percpu_stats;
@@ -441,6 +435,8 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
                       struct ovs_key_ipv4_tunnel *tun_key)
 {
        struct pcpu_sw_netstats *stats;
+       struct sw_flow_key key;
+       int error;
 
        stats = this_cpu_ptr(vport->percpu_stats);
        u64_stats_update_begin(&stats->syncp);
@@ -448,8 +444,15 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
        stats->rx_bytes += skb->len;
        u64_stats_update_end(&stats->syncp);
 
-       OVS_CB(skb)->tun_key = tun_key;
-       ovs_dp_process_received_packet(vport, skb);
+       OVS_CB(skb)->input_vport = vport;
+       OVS_CB(skb)->egress_tun_key = NULL;
+       /* Extract flow from 'skb' into 'key'. */
+       error = ovs_flow_key_extract(tun_key, skb, &key);
+       if (unlikely(error)) {
+               kfree_skb(skb);
+               return;
+       }
+       ovs_dp_process_packet(skb, &key);
 }
 
 /**
@@ -495,27 +498,24 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb)
 static void ovs_vport_record_error(struct vport *vport,
                                   enum vport_err_type err_type)
 {
-       spin_lock(&vport->stats_lock);
-
        switch (err_type) {
        case VPORT_E_RX_DROPPED:
-               vport->err_stats.rx_dropped++;
+               atomic_long_inc(&vport->err_stats.rx_dropped);
                break;
 
        case VPORT_E_RX_ERROR:
-               vport->err_stats.rx_errors++;
+               atomic_long_inc(&vport->err_stats.rx_errors);
                break;
 
        case VPORT_E_TX_DROPPED:
-               vport->err_stats.tx_dropped++;
+               atomic_long_inc(&vport->err_stats.tx_dropped);
                break;
 
        case VPORT_E_TX_ERROR:
-               vport->err_stats.tx_errors++;
+               atomic_long_inc(&vport->err_stats.tx_errors);
                break;
        }
 
-       spin_unlock(&vport->stats_lock);
 }
 
 static void free_vport_rcu(struct rcu_head *rcu)