aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat.c
diff options
context:
space:
mode:
authorDmitry Vakhrushev <dmitry@netgate.com>2019-01-22 05:28:53 -0500
committerFlorin Coras <florin.coras@gmail.com>2019-01-28 15:23:03 +0000
commitee3fb62bc8dee44aef23d4cf82cf5f70011fbf94 (patch)
treefecd8a25b74c2b650ce78428c0a39f019df5a172 /src/plugins/nat/nat.c
parent31dd6090e882158a57dc02dead99c4577d59cd20 (diff)
Fix issues with order of NAT commands before set VRF table on an interface
Outside FIB index doesn't change in this case. We register callback for changing of outside FIB if table binding is changed on an interface. Change-Id: I1ebbd7c3c547fc999089db07abd2019734395a6e Signed-off-by: Dmitry Vakhrushev <dmitry@netgate.com>
Diffstat (limited to 'src/plugins/nat/nat.c')
-rwxr-xr-xsrc/plugins/nat/nat.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c
index 8d02e5607c3..dabb8122adf 100755
--- a/src/plugins/nat/nat.c
+++ b/src/plugins/nat/nat.c
@@ -1769,7 +1769,7 @@ snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del)
{
if (is_del)
{
- outside_fib->refcount--;
+ outside_fib->refcount--;
if (!outside_fib->refcount)
vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
}
@@ -1995,7 +1995,7 @@ snat_interface_add_del_output_feature (u32 sw_if_index,
{
if (is_del)
{
- outside_fib->refcount--;
+ outside_fib->refcount--;
if (!outside_fib->refcount)
vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
}
@@ -2144,6 +2144,65 @@ snat_set_workers (uword * bitmap)
return 0;
}
+static void
+snat_update_outside_fib (u32 sw_if_index, u32 new_fib_index,
+ u32 old_fib_index)
+{
+ snat_main_t *sm = &snat_main;
+ nat_outside_fib_t *outside_fib;
+ snat_interface_t *i;
+ u8 is_add = 1;
+
+ if (new_fib_index == old_fib_index)
+ return;
+
+ if (!vec_len (sm->outside_fibs))
+ return;
+
+ pool_foreach (i, sm->interfaces, (
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ if (!(nat_interface_is_outside (i)))
+ return;}
+ }
+ ));
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ if (outside_fib->fib_index == old_fib_index)
+ {
+ outside_fib->refcount--;
+ if (!outside_fib->refcount)
+ vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
+ break;
+ }
+ }
+
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ if (outside_fib->fib_index == new_fib_index)
+ {
+ outside_fib->refcount++;
+ is_add = 0;
+ break;
+ }
+ }
+
+ if (is_add)
+ {
+ vec_add2 (sm->outside_fibs, outside_fib, 1);
+ outside_fib->refcount = 1;
+ outside_fib->fib_index = new_fib_index;
+ }
+}
+
+static void
+snat_ip4_table_bind (ip4_main_t * im,
+ uword opaque,
+ u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
+{
+ snat_update_outside_fib (sw_if_index, new_fib_index, old_fib_index);
+}
static void
snat_ip4_add_del_interface_address_cb (ip4_main_t * im,
@@ -2272,6 +2331,11 @@ snat_init (vlib_main_t * vm)
nat66_init ();
+ ip4_table_bind_callback_t cbt4 = {
+ .function = snat_ip4_table_bind,
+ };
+ vec_add1 (ip4_main.table_bind_callbacks, cbt4);
+
/* Init virtual fragmenentation reassembly */
return nat_reass_init (vm);
}