X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat44%2Fed_inlines.h;h=1b4df4d02fd56492ad79b58e5ec6c29db84ed792;hb=00dd39044e64b4a7a33d204ef7d19aac819d71f5;hp=37212f36bf52f90e6dcfc979a5d0c0f65e28f182;hpb=17ec577f7b3b092e09d95451317957415f4baf4f;p=vpp.git diff --git a/src/plugins/nat/nat44/ed_inlines.h b/src/plugins/nat/nat44/ed_inlines.h index 37212f36bf5..1b4df4d02fd 100644 --- a/src/plugins/nat/nat44/ed_inlines.h +++ b/src/plugins/nat/nat44/ed_inlines.h @@ -141,4 +141,115 @@ nat_ed_session_alloc (snat_main_t * sm, u32 thread_index, f64 now, u8 proto) return s; } +// slow path +static_always_inline void +per_vrf_sessions_cleanup (u32 thread_index) +{ + snat_main_t *sm = &snat_main; + snat_main_per_thread_data_t *tsm = + vec_elt_at_index (sm->per_thread_data, thread_index); + per_vrf_sessions_t *per_vrf_sessions; + u32 *to_free = 0, *i; + + vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec) + { + if (per_vrf_sessions->expired) + { + if (per_vrf_sessions->ses_count == 0) + { + vec_add1 (to_free, per_vrf_sessions - tsm->per_vrf_sessions_vec); + } + } + } + + if (vec_len (to_free)) + { + vec_foreach (i, to_free) + { + vec_del1 (tsm->per_vrf_sessions_vec, *i); + } + } + + vec_free (to_free); +} + +// slow path +static_always_inline void +per_vrf_sessions_register_session (snat_session_t * s, u32 thread_index) +{ + snat_main_t *sm = &snat_main; + snat_main_per_thread_data_t *tsm = + vec_elt_at_index (sm->per_thread_data, thread_index); + per_vrf_sessions_t *per_vrf_sessions; + + per_vrf_sessions_cleanup (thread_index); + + // s->per_vrf_sessions_index == ~0 ... reuse of old session + + vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec) + { + // ignore already expired registrations + if (per_vrf_sessions->expired) + continue; + + if ((s->in2out.fib_index == per_vrf_sessions->rx_fib_index) && + (s->out2in.fib_index == per_vrf_sessions->tx_fib_index)) + { + goto done; + } + if ((s->in2out.fib_index == per_vrf_sessions->tx_fib_index) && + (s->out2in.fib_index == per_vrf_sessions->rx_fib_index)) + { + goto done; + } + } + + // create a new registration + vec_add2 (tsm->per_vrf_sessions_vec, per_vrf_sessions, 1); + clib_memset (per_vrf_sessions, 0, sizeof (*per_vrf_sessions)); + + per_vrf_sessions->rx_fib_index = s->in2out.fib_index; + per_vrf_sessions->tx_fib_index = s->out2in.fib_index; + +done: + s->per_vrf_sessions_index = per_vrf_sessions - tsm->per_vrf_sessions_vec; + per_vrf_sessions->ses_count++; +} + +// fast path +static_always_inline void +per_vrf_sessions_unregister_session (snat_session_t * s, u32 thread_index) +{ + snat_main_t *sm = &snat_main; + snat_main_per_thread_data_t *tsm; + per_vrf_sessions_t *per_vrf_sessions; + + ASSERT (s->per_vrf_sessions_index != ~0); + + tsm = vec_elt_at_index (sm->per_thread_data, thread_index); + per_vrf_sessions = vec_elt_at_index (tsm->per_vrf_sessions_vec, + s->per_vrf_sessions_index); + + ASSERT (per_vrf_sessions->ses_count != 0); + + per_vrf_sessions->ses_count--; + s->per_vrf_sessions_index = ~0; +} + +// fast path +static_always_inline u8 +per_vrf_sessions_is_expired (snat_session_t * s, u32 thread_index) +{ + snat_main_t *sm = &snat_main; + snat_main_per_thread_data_t *tsm; + per_vrf_sessions_t *per_vrf_sessions; + + ASSERT (s->per_vrf_sessions_index != ~0); + + tsm = vec_elt_at_index (sm->per_thread_data, thread_index); + per_vrf_sessions = vec_elt_at_index (tsm->per_vrf_sessions_vec, + s->per_vrf_sessions_index); + return per_vrf_sessions->expired; +} + #endif