@@ -79,9 +79,10 @@ struct alg_exp_node {
/* The NAT replacement address to be used by the data connection. */
struct ct_addr alg_nat_repl_addr;
/* The data connection inherits the master control
- * connection label and mark. */
+ * connection label, mark and alg. */
ovs_u128 master_label;
uint32_t master_mark;
+ char *master_alg;
/* True if for NAT application, the alg replaces the dest address;
* otherwise, the source address is replaced. */
bool nat_rpl_dst;
@@ -131,8 +131,7 @@ extract_l3_ipv6(struct conn_key *key, const void *data, size_t size,
const char **new_data);
static struct alg_exp_node *
-expectation_lookup(struct hmap *alg_expectations, const struct conn_key *key,
- uint32_t basis, bool src_ip_wc);
+expectation_lookup(struct hmap *alg_expectations, const struct conn_key *key);
static int
repl_ftp_v4_addr(struct dp_packet *pkt, ovs_be32 v4_addr_rep,
@@ -505,9 +504,9 @@ get_alg_ctl_type(const struct dp_packet *pkt, ovs_be16 tp_src, ovs_be16 tp_dst,
}
static bool
-alg_src_ip_wc(enum ct_alg_ctl_type alg_ctl_type)
+alg_src_ip_wc(const char *alg)
{
- if (alg_ctl_type == CT_ALG_CTL_SIP) {
+ if (!strncmp(alg, "sip", strlen("sip"))) {
return true;
}
return false;
@@ -1252,9 +1251,7 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
struct alg_exp_node alg_exp_entry;
ct_rwlock_rdlock(&ct->resources_lock);
- alg_exp = expectation_lookup(&ct->alg_expectations, &ctx->key,
- ct->hash_basis,
- alg_src_ip_wc(ct_alg_ctl));
+ alg_exp = expectation_lookup(&ct->alg_expectations, &ctx->key);
if (alg_exp) {
alg_exp_entry = *alg_exp;
alg_exp = &alg_exp_entry;
@@ -2539,21 +2536,21 @@ conntrack_get_nconns(struct conntrack *ct, uint32_t *nconns)
/* This function must be called with the ct->resources read lock taken. */
static struct alg_exp_node *
-expectation_lookup(struct hmap *alg_expectations, const struct conn_key *key,
- uint32_t basis, bool src_ip_wc)
+expectation_lookup(struct hmap *alg_expectations, const struct conn_key *key)
{
struct conn_key check_key = *key;
check_key.src.port = ALG_WC_SRC_PORT;
- if (src_ip_wc) {
- memset(&check_key.src.addr, 0, sizeof check_key.src.addr);
- }
-
struct alg_exp_node *alg_exp_node;
+ struct alg_exp_node *next;
+
+ HMAP_FOR_EACH_SAFE (alg_exp_node, next, node, alg_expectations) {
+ bool is_wc = alg_src_ip_wc(alg_exp_node->master_alg);
+
+ if (is_wc) {
+ memset(&check_key.src.addr, 0, sizeof check_key.src.addr);
+ }
- HMAP_FOR_EACH_WITH_HASH (alg_exp_node, node,
- conn_key_hash(&check_key, basis),
- alg_expectations) {
if (!conn_key_cmp(&alg_exp_node->key, &check_key)) {
return alg_exp_node;
}
@@ -2666,12 +2663,13 @@ expectation_create_outband(struct conntrack *ct, struct ct_addr src_addr,
alg_exp_node->master_mark = master_conn->mark;
alg_exp_node->master_label = master_conn->label;
alg_exp_node->master_key = master_conn->key;
+ alg_exp_node->master_alg = nullable_xstrdup(master_conn->alg);
/* Take the write lock here because it is almost 100%
* likely that the lookup will fail and
* expectation_create() will be called below. */
ct_rwlock_wrlock(&ct->resources_lock);
struct alg_exp_node *alg_exp = expectation_lookup(
- &ct->alg_expectations, &alg_exp_node->key, ct->hash_basis, src_ip_wc);
+ &ct->alg_expectations, &alg_exp_node->key);
if (alg_exp) {
free(alg_exp_node);
ct_rwlock_unlock(&ct->resources_lock);
In certain protocols, such as SIP, infering if the data connection belongs to a specific protocol might not be feasible, from the used addresses and ports alone. The data connection may have a different network transport protocol, src/dst addresses and/or src/dst ports than the control connection. Instead, this commit adds an extra piece of information to the alg_exp_node struct, duplicated from the control connection, that identifies the Alg under use. It then makes use of that in expectation_lookup, to check if the given src address should be whitelisted or not, before proceeding with the comparison with each expectation in the list of expectations. Signed-off-by: Tiago Lam <tiagolam@gmail.com> --- lib/conntrack-private.h | 3 ++- lib/conntrack.c | 32 +++++++++++++++----------------- 2 files changed, 17 insertions(+), 18 deletions(-)