2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-01 14:55:18 +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() */
struct conn_key {
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;
}
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 */
static uint32_t
@@ -1616,33 +1630,24 @@ static uint32_t
nat_range_hash(const struct conn *conn, uint32_t basis)
{
uint32_t hash = basis;
int i;
uint16_t port;
for (i = 0;
i < sizeof(conn->nat_info->min_addr) / sizeof(uint32_t);
i++) {
hash = hash_add(hash, ((uint32_t *) &conn->nat_info->min_addr)[i]);
hash = hash_add(hash, ((uint32_t *) &conn->nat_info->max_addr)[i]);
}
hash = ct_addr_hash_add(hash, &conn->nat_info->min_addr);
hash = ct_addr_hash_add(hash, &conn->nat_info->max_addr);
hash = hash_add(hash,
(conn->nat_info->max_port << 16)
| conn->nat_info->min_port);
memcpy(&port, &conn->nat_info->min_port, sizeof port);
hash = hash_add(hash, port);
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 = ct_endpoint_hash_add(hash, &conn->key.src);
hash = ct_endpoint_hash_add(hash, &conn->key.dst);
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.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