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 <tiago...@gmail.com>
---
 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
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to