#include <cnat/cnat_translation.h>
#include <cnat/cnat_inline.h>
#include <cnat/cnat_src_policy.h>
-#include <cnat/cnat_snat.h>
+#include <cnat/cnat_snat_policy.h>
#include <vnet/dpo/load_balance.h>
#include <vnet/dpo/load_balance_map.h>
session->value.cs_port[VLIB_TX] =
clib_host_to_net_u16 (trk0->ct_ep[VLIB_TX].ce_port);
session->value.cs_port[VLIB_RX] = udp0->src_port;
+ session->value.flags = 0;
- const dpo_id_t *dpo0;
- const load_balance_t *lb1;
- fib_entry_t *fib_entry;
- fib_entry = fib_entry_get (trk0->ct_fei);
-
- lb1 = load_balance_get (fib_entry->fe_lb /*[fct] */.dpoi_index);
- dpo0 = load_balance_get_bucket_i (lb1, 0);
+ if (trk0->ct_flags & CNAT_TRK_FLAG_NO_NAT)
+ {
+ const dpo_id_t *dpo0;
+ const load_balance_t *lb1;
- session->value.dpoi_next_node = dpo0->dpoi_next_node;
- session->value.cs_lbi = dpo0->dpoi_index;
+ lb1 = load_balance_get (trk0->ct_dpo.dpoi_index);
+ /* Assume backend has exactly one item in LB */
+ dpo0 = load_balance_get_bucket_i (lb1, 0);
- if (trk0->ct_flags & CNAT_TRK_FLAG_NO_NAT)
- session->value.flags |= CNAT_SESSION_FLAG_NO_NAT;
+ session->value.dpoi_next_node = dpo0->dpoi_next_node;
+ session->value.cs_lbi = dpo0->dpoi_index;
+ session->value.flags = CNAT_SESSION_FLAG_NO_NAT;
+ }
/* refcnt session in current client */
cnat_client_cnt_session (cc);
- cnat_session_create (session, ctx, CNAT_LOCATION_OUTPUT, rsession_flags);
+ cnat_session_create (session, ctx);
+ if (!(ct->flags & CNAT_TR_FLAG_NO_RETURN_SESSION))
+ cnat_rsession_create (session, ctx, CNAT_LOCATION_OUTPUT,
+ rsession_flags);
trace_flags |= CNAT_TRACE_SESSION_CREATED;
}
- next0 = session->value.dpoi_next_node;
- vnet_buffer (b)->ip.adj_index[VLIB_TX] = session->value.cs_lbi;
-
if (session->value.flags & CNAT_SESSION_FLAG_NO_NAT)
- goto trace;
+ {
+ /* If we don't translate, directly do the lookup & bypass arc */
+ next0 = session->value.dpoi_next_node;
+ vnet_buffer (b)->ip.adj_index[VLIB_TX] = session->value.cs_lbi;
+ goto trace;
+ }
if (AF_IP4 == ctx->af)
- cnat_translation_ip4 (session, ip4, udp0);
+ cnat_translation_ip4 (session, ip4, udp0, vnet_buffer (b)->oflags);
else
- cnat_translation_ip6 (session, ip6, udp0);
+ cnat_translation_ip6 (session, ip6, udp0, vnet_buffer (b)->oflags);
if (NULL != ct)
{
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = CNAT_N_ERROR,
.error_strings = cnat_error_strings,
- .n_next_nodes = IP_LOOKUP_N_NEXT,
- .next_nodes = IP4_LOOKUP_NEXT_NODES,
+ .sibling_of = "ip4-lookup",
};
VNET_FEATURE_INIT (cnat_in_ip4_feature, static) = {
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = CNAT_N_ERROR,
.error_strings = cnat_error_strings,
- .n_next_nodes = CNAT_FEATURE_N_NEXT,
- .next_nodes = {
- [CNAT_FEATURE_NEXT_DROP] = "error-drop",
- },
+ .sibling_of = "ip6-lookup",
};
VNET_FEATURE_INIT (cnat_in_ip6_feature, static) = {
vlib_buffer_t *b, cnat_node_ctx_t *ctx,
int session_not_found, cnat_session_t *session)
{
- cnat_main_t *cm = &cnat_main;
- cnat_snat_policy_main_t *cms = &cnat_snat_policy_main;
+ cnat_snat_policy_main_t *cpm = &cnat_snat_policy_main;
ip4_header_t *ip4 = NULL;
ip_protocol_t iproto;
ip6_header_t *ip6 = NULL;
/* session table hit */
cnat_timestamp_update (session->value.cs_ts_index, ctx->now);
}
- else if (!cms->snat_policy)
+ else if (!cpm->snat_policy)
goto trace;
else
{
- /* TODO: handle errors? */
- cms->snat_policy (vm, b, session, ctx, &do_snat);
+ do_snat = cpm->snat_policy (b, session);
if (do_snat != 1)
goto trace;
if (AF_IP4 == ctx->af)
{
- if (ip_address_is_zero (&cm->snat_ip4.ce_ip))
+ if (ip_address_is_zero (&cpm->snat_ip4.ce_ip))
goto trace;
ip46_address_set_ip4 (&session->value.cs_ip[VLIB_RX],
- &ip_addr_v4 (&cm->snat_ip4.ce_ip));
+ &ip_addr_v4 (&cpm->snat_ip4.ce_ip));
ip46_address_set_ip4 (&session->value.cs_ip[VLIB_TX],
&ip4->dst_address);
}
else
{
- if (ip_address_is_zero (&cm->snat_ip6.ce_ip))
+ if (ip_address_is_zero (&cpm->snat_ip6.ce_ip))
goto trace;
ip46_address_set_ip6 (&session->value.cs_ip[VLIB_RX],
- &ip_addr_v6 (&cm->snat_ip6.ce_ip));
+ &ip_addr_v6 (&cpm->snat_ip6.ce_ip));
ip46_address_set_ip6 (&session->value.cs_ip[VLIB_TX],
&ip6->dst_address);
}
CNAT_SESSION_FLAG_NO_CLIENT | CNAT_SESSION_FLAG_ALLOC_PORT;
trace_flags |= CNAT_TRACE_SESSION_CREATED;
- cnat_session_create (session, ctx, CNAT_LOCATION_INPUT,
- CNAT_SESSION_FLAG_NO_CLIENT);
+
+ cnat_session_create (session, ctx);
+ cnat_rsession_create (session, ctx, CNAT_LOCATION_INPUT,
+ CNAT_SESSION_FLAG_NO_CLIENT |
+ CNAT_SESSION_RETRY_SNAT);
}
if (AF_IP4 == ctx->af)
- cnat_translation_ip4 (session, ip4, udp0);
+ cnat_translation_ip4 (session, ip4, udp0, vnet_buffer (b)->oflags);
else
- cnat_translation_ip6 (session, ip6, udp0);
+ cnat_translation_ip6 (session, ip6, udp0, vnet_buffer (b)->oflags);
trace:
if (PREDICT_FALSE (ctx->do_trace))