aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2017-01-11 13:01:14 -0500
committerDave Barach <dave@barachs.net>2017-01-11 13:01:44 -0500
commitcab65ec86b6c04d7a4674312989b5be0c0e394a4 (patch)
tree2ca01a090eba296d8dbb48ee067cda7565b83e0a
parentea4fa7526f51f78fa8ec712c002ba55983187ad3 (diff)
Acquire SNAT pool addresses from specific interfaces
Pick up addresses added by DHCP client, or by static configuration Needs to have binary API support added Change-Id: I962ef89e6e5f36cdc5457b92e165c498b08b25a9 Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/plugins/snat/snat.c124
-rw-r--r--src/plugins/snat/snat.h3
-rw-r--r--src/vnet/ip/ip4.h1
3 files changed, 127 insertions, 1 deletions
diff --git a/src/plugins/snat/snat.c b/src/plugins/snat/snat.c
index bc995684..94e05078 100644
--- a/src/plugins/snat/snat.c
+++ b/src/plugins/snat/snat.c
@@ -16,6 +16,8 @@
*/
#include <vnet/vnet.h>
+#include <vnet/ip/ip.h>
+#include <vnet/ip/ip4.h>
#include <vnet/plugin/plugin.h>
#include <vlibapi/api.h>
#include <snat/snat.h>
@@ -1146,6 +1148,15 @@ static void plugin_custom_dump_configure (snat_main_t * sm)
#undef _
}
+static void
+snat_ip4_add_del_interface_address_cb (ip4_main_t * im,
+ uword opaque,
+ u32 sw_if_index,
+ ip4_address_t * address,
+ u32 address_length,
+ u32 if_address_index,
+ u32 is_delete);
+
static clib_error_t * snat_init (vlib_main_t * vm)
{
snat_main_t * sm = &snat_main;
@@ -1158,6 +1169,7 @@ static clib_error_t * snat_init (vlib_main_t * vm)
vlib_thread_main_t *tm = vlib_get_thread_main ();
uword *bitmap = 0;
u32 i;
+ ip4_add_del_interface_address_callback_t cb4;
name = format (0, "snat_%08x%c", api_version, 0);
@@ -1205,6 +1217,12 @@ static clib_error_t * snat_init (vlib_main_t * vm)
plugin_custom_dump_configure (sm);
vec_free(name);
+ /* Set up the interface address add/del callback */
+ cb4.function = snat_ip4_add_del_interface_address_cb;
+ cb4.function_opaque = 0;
+
+ vec_add1 (im->add_del_interface_address_callbacks, cb4);
+
return error;
}
@@ -1955,3 +1973,109 @@ VLIB_CLI_COMMAND (show_snat_command, static) = {
.short_help = "show snat",
.function = show_snat_command_fn,
};
+
+
+static void
+snat_ip4_add_del_interface_address_cb (ip4_main_t * im,
+ uword opaque,
+ u32 sw_if_index,
+ ip4_address_t * address,
+ u32 address_length,
+ u32 if_address_index,
+ u32 is_delete)
+{
+ snat_main_t *sm = &snat_main;
+ int i, j;
+
+ for (i = 0; i < vec_len(sm->auto_add_sw_if_indices); i++)
+ {
+ if (sw_if_index == sm->auto_add_sw_if_indices[i])
+ {
+ if (!is_delete)
+ {
+ /* Don't trip over lease renewal, static config */
+ for (j = 0; j < vec_len(sm->addresses); j++)
+ if (sm->addresses[j].addr.as_u32 == address->as_u32)
+ return;
+
+ snat_add_address (sm, address);
+ return;
+ }
+ else
+ {
+ (void) snat_del_address(sm, address[0]);
+ return;
+ }
+ }
+ }
+}
+
+
+static int snat_add_interface_address (snat_main_t *sm, u32 sw_if_index)
+{
+ ip4_main_t * ip4_main = sm->ip4_main;
+ ip4_address_t * first_int_addr;
+ int i;
+
+ first_int_addr = ip4_interface_first_address (ip4_main, sw_if_index,
+ 0 /* just want the address*/);
+
+ for (i = 0; i < vec_len(sm->auto_add_sw_if_indices); i++)
+ {
+ if (sm->auto_add_sw_if_indices[i] == sw_if_index)
+ return 0;
+ }
+
+ /* add to the auto-address list */
+ vec_add1(sm->auto_add_sw_if_indices, sw_if_index);
+
+ /* If the address is already bound - or static - add it now */
+ if (first_int_addr)
+ snat_add_address (sm, first_int_addr);
+
+ return 0;
+}
+
+static clib_error_t *
+snat_add_interface_address_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ snat_main_t *sm = &snat_main;
+ unformat_input_t _line_input, *line_input = &_line_input;
+ u32 sw_if_index;
+ int rv;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U", unformat_vnet_sw_interface,
+ sm->vnet_main, &sw_if_index))
+ ;
+ else
+ return clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ }
+
+ rv = snat_add_interface_address (sm, sw_if_index);
+
+ switch (rv)
+ {
+ case 0:
+ break;
+
+ default:
+ return clib_error_return (0, "snat_add_interface_address returned %d",
+ rv);
+ }
+ return 0;
+}
+
+VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
+ .path = "snat add interface address",
+ .short_help = "snat add interface address <interface>",
+ .function = snat_add_interface_address_command_fn,
+};
diff --git a/src/plugins/snat/snat.h b/src/plugins/snat/snat.h
index cb31dc51..71f254fe 100644
--- a/src/plugins/snat/snat.h
+++ b/src/plugins/snat/snat.h
@@ -179,6 +179,9 @@ typedef struct {
/* Vector of outside addresses */
snat_address_t * addresses;
+ /* sw_if_indices whose intfc addresses should be auto-added */
+ u32 * auto_add_sw_if_indices;
+
/* Randomize port allocation order */
u32 random_seed;
diff --git a/src/vnet/ip/ip4.h b/src/vnet/ip/ip4.h
index 0331c445..cc33dff4 100644
--- a/src/vnet/ip/ip4.h
+++ b/src/vnet/ip/ip4.h
@@ -190,7 +190,6 @@ ip4_src_address_for_packet (ip_lookup_main_t * lm,
}
else
{
- ASSERT (0);
src->as_u32 = 0;
}
return (!0);