From: Dmitry Vakhrushev Date: Tue, 22 Jan 2019 10:28:53 +0000 (-0500) Subject: Fix issues with order of NAT commands before set VRF table on an interface X-Git-Tag: v19.04-rc1~579 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=ee3fb62bc8dee44aef23d4cf82cf5f70011fbf94 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 --- 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); }