diff options
author | Dmitry Vakhrushev <dmitry@netgate.com> | 2019-01-22 05:28:53 -0500 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-01-28 15:23:03 +0000 |
commit | ee3fb62bc8dee44aef23d4cf82cf5f70011fbf94 (patch) | |
tree | fecd8a25b74c2b650ce78428c0a39f019df5a172 /src/plugins/nat | |
parent | 31dd6090e882158a57dc02dead99c4577d59cd20 (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')
-rwxr-xr-x | src/plugins/nat/nat.c | 68 |
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); } |