diff options
Diffstat (limited to 'src/plugins/nat/nat.c')
-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); } |