summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/cnat/cnat.api2
-rw-r--r--src/plugins/cnat/cnat_api.c13
-rw-r--r--src/plugins/cnat/cnat_translation.c13
-rw-r--r--src/plugins/cnat/cnat_translation.h5
4 files changed, 25 insertions, 8 deletions
diff --git a/src/plugins/cnat/cnat.api b/src/plugins/cnat/cnat.api
index a9507c90b4d..7bf6be8b349 100644
--- a/src/plugins/cnat/cnat.api
+++ b/src/plugins/cnat/cnat.api
@@ -53,7 +53,7 @@ typedef cnat_translation
vl_api_ip_proto_t ip_proto;
u8 is_real_ip;
u8 flags;
- u8 n_paths;
+ u32 n_paths;
vl_api_cnat_endpoint_tuple_t paths[n_paths];
};
diff --git a/src/plugins/cnat/cnat_api.c b/src/plugins/cnat/cnat_api.c
index f692451c14b..338cb5926a8 100644
--- a/src/plugins/cnat/cnat_api.c
+++ b/src/plugins/cnat/cnat_api.c
@@ -88,16 +88,17 @@ vl_api_cnat_translation_update_t_handler (vl_api_cnat_translation_update_t
u32 id = ~0;
u8 flags;
int rv = 0;
- u8 pi;
+ u32 pi, n_paths;
rv = ip_proto_decode (mp->translation.ip_proto, &ip_proto);
if (rv)
goto done;
- vec_validate (paths, mp->translation.n_paths - 1);
+ n_paths = clib_net_to_host_u32 (mp->translation.n_paths);
+ vec_validate (paths, n_paths - 1);
- for (pi = 0; pi < mp->translation.n_paths; pi++)
+ for (pi = 0; pi < n_paths; pi++)
{
path = &paths[pi];
cnat_endpoint_tuple_decode (&mp->translation.paths[pi], path);
@@ -146,7 +147,7 @@ cnat_translation_send_details (u32 cti, void *args)
vl_api_cnat_endpoint_tuple_t *path;
size_t msg_size;
cnat_translation_t *ct;
- u8 n_paths;
+ u32 n_paths;
ctx = args;
ct = cnat_translation_get (cti);
@@ -158,8 +159,8 @@ cnat_translation_send_details (u32 cti, void *args)
/* fill in the message */
mp->context = ctx->context;
- mp->translation.n_paths = n_paths;
- mp->translation.id = htonl (cti);
+ mp->translation.n_paths = clib_host_to_net_u32 (n_paths);
+ mp->translation.id = clib_host_to_net_u32 (cti);
cnat_endpoint_encode (&ct->ct_vip, &mp->translation.vip);
mp->translation.ip_proto = ip_proto_encode (ct->ct_proto);
diff --git a/src/plugins/cnat/cnat_translation.c b/src/plugins/cnat/cnat_translation.c
index 4833df9fc37..263ec05e973 100644
--- a/src/plugins/cnat/cnat_translation.c
+++ b/src/plugins/cnat/cnat_translation.c
@@ -180,7 +180,7 @@ cnat_translation_stack (cnat_translation_t * ct)
fib_protocol_t fproto;
cnat_ep_trk_t *trk;
dpo_proto_t dproto;
- u8 ep_idx = 0;
+ u32 ep_idx = 0;
index_t lbi;
fproto = ip_address_family_to_fib_proto (ct->ct_vip.ce_ip.version);
@@ -198,6 +198,7 @@ cnat_translation_stack (cnat_translation_t * ct)
dpo_set (&ct->ct_lb, DPO_LOAD_BALANCE, dproto, lbi);
dpo_stack (cnat_client_dpo, dproto, &ct->ct_lb, &ct->ct_lb);
+ ct->flags |= CNAT_TRANSLATION_STACKED;
}
int
@@ -277,6 +278,7 @@ cnat_translation_update (cnat_endpoint_t * vip,
}
vec_reset_length (ct->ct_paths);
+ ct->flags &= ~CNAT_TRANSLATION_STACKED;
u64 path_idx = 0;
vec_foreach (path, paths)
@@ -457,6 +459,12 @@ cnat_translation_back_walk_notify (fib_node_t * node,
*/
cnat_translation_t *ct = cnat_translation_get_from_node (node);
+ /* If we have more than FIB_PATH_LIST_POPULAR paths
+ * we might get called during path tracking
+ * (cnat_tracker_track) */
+ if (!(ct->flags & CNAT_TRANSLATION_STACKED))
+ return (FIB_NODE_BACK_WALK_CONTINUE);
+
cnat_translation_stack (ct);
return (FIB_NODE_BACK_WALK_CONTINUE);
@@ -601,9 +609,12 @@ cnat_if_addr_add_del_backend_cb (addr_resolution_t * ar,
ip_address_copy (&ep->ce_ip, address);
ep->ce_flags |= CNAT_EP_FLAG_RESOLVED;
}
+
+ ct->flags &= ~CNAT_TRANSLATION_STACKED;
cnat_tracker_track (ar->cti, trk);
cnat_translation_stack (ct);
+ ct->flags |= CNAT_TRANSLATION_STACKED;
}
static void
diff --git a/src/plugins/cnat/cnat_translation.h b/src/plugins/cnat/cnat_translation.h
index cfcbf5bc13b..a4ae1ece718 100644
--- a/src/plugins/cnat/cnat_translation.h
+++ b/src/plugins/cnat/cnat_translation.h
@@ -58,7 +58,12 @@ typedef struct cnat_ep_trk_t_
typedef enum cnat_translation_flag_t_
{
+ /* Do allocate a source port */
CNAT_TRANSLATION_FLAG_ALLOCATE_PORT = (1 << 0),
+ /* Has this translation been satcked ?
+ * this allow not being called twice when
+ * with more then FIB_PATH_LIST_POPULAR backends */
+ CNAT_TRANSLATION_STACKED = (1 << 1),
} cnat_translation_flag_t;
typedef enum