#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vlibsocket/api.h>
+#include <vpp/app/version.h>
snat_main_t snat_main;
.runs_before = VNET_FEATURES ("ip4-lookup"),
};
-
-/*
- * This routine exists to convince the vlib plugin framework that
- * we haven't accidentally copied a random .dll into the plugin directory.
- *
- * Also collects global variable pointers passed from the vpp engine
- */
-
-clib_error_t *
-vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
- int from_early_init)
-{
- snat_main_t * sm = &snat_main;
- clib_error_t * error = 0;
-
- sm->vlib_main = vm;
- sm->vnet_main = h->vnet_main;
- sm->ethernet_main = h->ethernet_main;
-
- return error;
-}
+/* *INDENT-OFF* */
+VLIB_PLUGIN_REGISTER () = {
+ .version = VPP_BUILD_VER,
+};
+/* *INDENT-ON* */
/*$$$$$ move to an installed header file */
#if (1 || CLIB_DEBUG > 0) /* "trust, but verify" */
snat_interface_t *interface;
int i;
- /* If outside FIB index is not resolved yet */
- if (sm->outside_fib_index == ~0)
- {
- p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->outside_vrf_id);
- if (!p)
- return VNET_API_ERROR_NO_SUCH_FIB;
- sm->outside_fib_index = p[0];
- }
-
/* If the external address is a specific interface address */
if (sw_if_index != ~0)
{
/* If not specified use inside VRF id from SNAT plugin startup config */
else
{
- if (sm->inside_fib_index == ~0)
- {
- p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->inside_vrf_id);
- if (!p)
- return VNET_API_ERROR_NO_SUCH_FIB;
- fib_index = p[0];
- sm->inside_fib_index = fib_index;
- }
- else
- fib_index = sm->inside_fib_index;
-
+ fib_index = sm->inside_fib_index;
vrf_id = sm->inside_vrf_id;
}
clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
rmp->local_port = htons (m->local_port);
rmp->external_port = htons (m->external_port);
+ rmp->external_sw_if_index = ~0;
+ rmp->vrf_id = htonl (m->vrf_id);
+ rmp->protocol = snat_proto_to_ip_proto (m->proto);
+ rmp->context = context;
+
+ vl_msg_api_send_shmem (q, (u8 *) & rmp);
+}
+
+static void
+send_snat_static_map_resolve_details
+(snat_static_map_resolve_t * m, unix_shared_memory_queue_t * q, u32 context)
+{
+ vl_api_snat_static_mapping_details_t *rmp;
+ snat_main_t * sm = &snat_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_SNAT_STATIC_MAPPING_DETAILS+sm->msg_id_base);
+ rmp->is_ip4 = 1;
+ rmp->addr_only = m->addr_only;
+ clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
+ rmp->local_port = htons (m->l_port);
+ rmp->external_port = htons (m->e_port);
+ rmp->external_sw_if_index = htonl (m->sw_if_index);
rmp->vrf_id = htonl (m->vrf_id);
rmp->protocol = snat_proto_to_ip_proto (m->proto);
rmp->context = context;
unix_shared_memory_queue_t *q;
snat_main_t * sm = &snat_main;
snat_static_mapping_t * m;
+ snat_static_map_resolve_t *rp;
+ int j;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (q == 0)
({
send_snat_static_mapping_details (m, q, mp->context);
}));
+
+ for (j = 0; j < vec_len (sm->to_resolve); j++)
+ {
+ rp = sm->to_resolve + j;
+ send_snat_static_map_resolve_details (rp, q, mp->context);
+ }
}
static void *vl_api_snat_static_mapping_dump_t_print
vnet_main_t * vnm = vnet_get_main();
int rv;
snat_protocol_t proto;
+ u8 proto_set = 0;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
else if (unformat (line_input, "vrf %u", &vrf_id))
;
else if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
- ;
+ proto_set = 1;
else if (unformat (line_input, "del"))
is_add = 0;
else
}
unformat_free (line_input);
+ if (!addr_only && !proto_set)
+ return clib_error_return (0, "missing protocol");
+
rv = snat_add_static_mapping(l_addr, e_addr, (u16) l_port, (u16) e_port,
vrf_id, addr_only, sw_if_index, proto, is_add);
* Static mapping allows hosts on the external network to initiate connection
* to to the local network host.
* To create static mapping between local host address 10.0.0.3 port 6303 and
- * external address 4.4.4.4 port 3606 use:
- * vpp# snat add static mapping local 10.0.0.3 6303 external 4.4.4.4 3606
+ * external address 4.4.4.4 port 3606 for TCP protocol use:
+ * vpp# snat add static mapping local tcp 10.0.0.3 6303 external 4.4.4.4 3606
* If not runnig "static mapping only" S-NAT plugin mode use before:
* vpp# snat add address 4.4.4.4
* To create static mapping between local and external address use:
.path = "snat add static mapping",
.function = add_static_mapping_command_fn,
.short_help =
- "snat add static mapping local <addr> [<port>] external <addr> [<port>] [vrf <table-id>] [del]",
+ "snat add static mapping local tcp|udp|icmp <addr> [<port>] external <addr> [<port>] [vrf <table-id>] [del]",
};
static clib_error_t *
sm->user_memory_size = user_memory_size;
sm->max_translations_per_user = max_translations_per_user;
sm->outside_vrf_id = outside_vrf_id;
- sm->outside_fib_index = ~0;
+ sm->outside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
+ outside_vrf_id);
sm->inside_vrf_id = inside_vrf_id;
- sm->inside_fib_index = ~0;
+ sm->inside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
+ inside_vrf_id);
sm->static_mapping_only = static_mapping_only;
sm->static_mapping_connection_tracking = static_mapping_connection_tracking;
return s;
}
+u8 * format_snat_static_map_to_resolve (u8 * s, va_list * args)
+{
+ snat_static_map_resolve_t *m = va_arg (*args, snat_static_map_resolve_t *);
+ vnet_main_t *vnm = vnet_get_main();
+
+ if (m->addr_only)
+ s = format (s, "local %U external %U vrf %d",
+ format_ip4_address, &m->l_addr,
+ format_vnet_sw_interface_name, vnm,
+ vnet_get_sw_interface (vnm, m->sw_if_index),
+ m->vrf_id);
+ else
+ s = format (s, "%U local %U:%d external %U:%d vrf %d",
+ format_snat_protocol, m->proto,
+ format_ip4_address, &m->l_addr, m->l_port,
+ format_vnet_sw_interface_name, vnm,
+ vnet_get_sw_interface (vnm, m->sw_if_index), m->e_port,
+ m->vrf_id);
+
+ return s;
+}
+
static clib_error_t *
show_snat_command_fn (vlib_main_t * vm,
unformat_input_t * input,
snat_main_per_thread_data_t *tsm;
u32 users_num = 0, sessions_num = 0, *worker, *sw_if_index;
uword j = 0;
+ snat_static_map_resolve_t *rp;
if (unformat (input, "detail"))
verbose = 1;
}));
}
- if (pool_elts (sm->static_mappings))
+ if (pool_elts (sm->static_mappings) || vec_len (sm->to_resolve))
{
vlib_cli_output (vm, "static mappings:");
pool_foreach (m, sm->static_mappings,
({
vlib_cli_output (vm, "%U", format_snat_static_mapping, m);
}));
+ for (j = 0; j < vec_len (sm->to_resolve); j++)
+ {
+ rp = sm->to_resolve + j;
+ vlib_cli_output (vm, "%U", format_snat_static_map_to_resolve,
+ rp);
+ }
}
}
}