2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 07:15:17 +00:00

conntrack: Hash entire NAT data structure in nat_range_hash().

Part of the hash input for nat_range_hash() was accidentally
omitted, so this fixes the problem.  Also, add a missing call to
hash_finish().

Fixes: 286de27299 ("dpdk: Userspace Datapath: Introduce NAT Support.")
Co-authored-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: Darrell Ball <dlu998@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Darrell Ball
2017-06-09 15:30:43 -07:00
committed by Ben Pfaff
parent 67702b79d8
commit 92edd073ce
2 changed files with 30 additions and 21 deletions

View File

@@ -42,6 +42,10 @@ struct ct_endpoint {
}; };
}; };
/* Verify that there is no padding in struct ct_endpoint, to facilitate
* hashing in ct_endpoint_hash_add(). */
BUILD_ASSERT_DECL(sizeof(struct ct_endpoint) == sizeof(struct ct_addr) + 4);
/* Changes to this structure need to be reflected in conn_key_hash() */ /* Changes to this structure need to be reflected in conn_key_hash() */
struct conn_key { struct conn_key {
struct ct_endpoint src; struct ct_endpoint src;

View File

@@ -1509,6 +1509,20 @@ conn_key_extract(struct conntrack *ct, struct dp_packet *pkt, ovs_be16 dl_type,
return false; return false;
} }
static uint32_t
ct_addr_hash_add(uint32_t hash, const struct ct_addr *addr)
{
BUILD_ASSERT_DECL(sizeof *addr % 4 == 0);
return hash_add_bytes32(hash, (const uint32_t *) addr, sizeof *addr);
}
static uint32_t
ct_endpoint_hash_add(uint32_t hash, const struct ct_endpoint *ep)
{
BUILD_ASSERT_DECL(sizeof *ep % 4 == 0);
return hash_add_bytes32(hash, (const uint32_t *) ep, sizeof *ep);
}
/* Symmetric */ /* Symmetric */
static uint32_t static uint32_t
@@ -1616,33 +1630,24 @@ static uint32_t
nat_range_hash(const struct conn *conn, uint32_t basis) nat_range_hash(const struct conn *conn, uint32_t basis)
{ {
uint32_t hash = basis; uint32_t hash = basis;
int i;
uint16_t port;
for (i = 0; hash = ct_addr_hash_add(hash, &conn->nat_info->min_addr);
i < sizeof(conn->nat_info->min_addr) / sizeof(uint32_t); hash = ct_addr_hash_add(hash, &conn->nat_info->max_addr);
i++) { hash = hash_add(hash,
hash = hash_add(hash, ((uint32_t *) &conn->nat_info->min_addr)[i]); (conn->nat_info->max_port << 16)
hash = hash_add(hash, ((uint32_t *) &conn->nat_info->max_addr)[i]); | conn->nat_info->min_port);
}
memcpy(&port, &conn->nat_info->min_port, sizeof port); hash = ct_endpoint_hash_add(hash, &conn->key.src);
hash = hash_add(hash, port); hash = ct_endpoint_hash_add(hash, &conn->key.dst);
for (i = 0; i < sizeof(conn->key.src.addr) / sizeof(uint32_t); i++) {
hash = hash_add(hash, ((uint32_t *) &conn->key.src)[i]);
hash = hash_add(hash, ((uint32_t *) &conn->key.dst)[i]);
}
memcpy(&port, &conn->key.src.port, sizeof port);
hash = hash_add(hash, port);
memcpy(&port, &conn->key.dst.port, sizeof port);
hash = hash_add(hash, port);
hash = hash_add(hash, (OVS_FORCE uint32_t) conn->key.dl_type); hash = hash_add(hash, (OVS_FORCE uint32_t) conn->key.dl_type);
hash = hash_add(hash, conn->key.nw_proto); hash = hash_add(hash, conn->key.nw_proto);
hash = hash_add(hash, conn->key.zone); hash = hash_add(hash, conn->key.zone);
return hash;
/* The purpose of the second parameter is to distinguish hashes of data of
* different length; our data always has the same length so there is no
* value in counting. */
return hash_finish(hash, 0);
} }
static bool static bool