Expand tunnel IDs from 32 to 64 bits.
[sliver-openvswitch.git] / datapath / tunnel.c
index 271651b..3534909 100644 (file)
@@ -166,11 +166,11 @@ static unsigned int *find_port_pool(const struct tnl_mutable_config *mutable)
 }
 
 struct port_lookup_key {
+       const struct tnl_mutable_config *mutable;
+       __be64 key;
        u32 tunnel_type;
        __be32 saddr;
        __be32 daddr;
-       __be32 key;
-       const struct tnl_mutable_config *mutable;
 };
 
 /*
@@ -192,7 +192,8 @@ static int port_cmp(const struct tbl_node *node, void *target)
 
 static u32 port_hash(struct port_lookup_key *k)
 {
-       return jhash_3words(k->key, k->saddr, k->daddr, k->tunnel_type);
+       u32 x = jhash_3words(k->saddr, k->daddr, k->tunnel_type, 0);
+       return jhash_2words(k->key >> 32, k->key, x);
 }
 
 static u32 mutable_hash(const struct tnl_mutable_config *mutable)
@@ -247,7 +248,6 @@ static int add_port(struct vport *vport)
 
        err = tbl_insert(port_table, &tnl_vport->tbl_node, mutable_hash(tnl_vport->mutable));
        if (err) {
-               (*find_port_pool(tnl_vport->mutable))--;
                check_table_empty();
                return err;
        }
@@ -278,6 +278,7 @@ static int move_port(struct vport *vport, struct tnl_mutable_config *new_mutable
 
        err = tbl_insert(port_table, &tnl_vport->tbl_node, hash);
        if (err) {
+               (*find_port_pool(tnl_vport->mutable))--;
                check_table_empty();
                return err;
        }
@@ -305,7 +306,7 @@ static int del_port(struct vport *vport)
        return 0;
 }
 
-struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be32 key,
+struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be64 key,
                            int tunnel_type,
                            const struct tnl_mutable_config **mutable)
 {
@@ -598,7 +599,7 @@ static void ipv6_build_icmp(struct sk_buff *skb, struct sk_buff *nskb,
 #endif /* IPv6 */
 
 bool tnl_frag_needed(struct vport *vport, const struct tnl_mutable_config *mutable,
-                    struct sk_buff *skb, unsigned int mtu, __be32 flow_key)
+                    struct sk_buff *skb, unsigned int mtu, __be64 flow_key)
 {
        unsigned int eth_hdr_len = ETH_HLEN;
        unsigned int total_length = 0, header_length = 0, payload_length;
@@ -818,7 +819,7 @@ static void cache_cleaner(struct work_struct *work)
        schedule_cache_cleaner();
 
        rcu_read_lock();
-       tbl_foreach(port_table, cache_cleaner_cb, NULL);
+       tbl_foreach(rcu_dereference(port_table), cache_cleaner_cb, NULL);
        rcu_read_unlock();
 }