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 <[email protected]> --- lib/conntrack-private.h | 3 ++- lib/conntrack.c | 32 +++++++++++++++----------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/lib/conntrack-private.h b/lib/conntrack-private.h index a344801d8..bf1d0773b 100644 --- a/lib/conntrack-private.h +++ b/lib/conntrack-private.h @@ -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; diff --git a/lib/conntrack.c b/lib/conntrack.c index a3cff1575..5c91f374b 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -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); -- 2.14.3 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
