diff options
-rw-r--r-- | src/plugins/cnat/cnat.api | 2 | ||||
-rw-r--r-- | src/plugins/cnat/cnat_api.c | 13 | ||||
-rw-r--r-- | src/plugins/cnat/cnat_translation.c | 13 | ||||
-rw-r--r-- | src/plugins/cnat/cnat_translation.h | 5 |
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 |