/* * ct6.h - skeleton vpp engine plug-in header file * * Copyright (c) <current-year> <your-organization> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __included_ct6_h__ #define __included_ct6_h__ #include <vnet/vnet.h> #include <vnet/ip/ip.h> #include <vnet/ethernet/ethernet.h> #include <vppinfra/bihash_48_8.h> #include <vppinfra/hash.h> #include <vppinfra/error.h> /* *INDENT-OFF* */ typedef CLIB_PACKED (struct { union { struct { /* out2in */ ip6_address_t src; ip6_address_t dst; u16 sport; u16 dport; u8 proto; /* byte 37 */ }; u64 as_u64[6]; }; }) ct6_session_key_t; /* *INDENT-ON* */ typedef struct { ct6_session_key_t key; u32 thread_index; u32 next_index; u32 prev_index; u32 hits; f64 expires; } ct6_session_t; typedef struct { /* API message ID base */ u16 msg_id_base; /* session lookup table */ clib_bihash_48_8_t session_hash; u8 feature_initialized; /* per_thread session pools */ ct6_session_t **sessions; u32 *first_index; u32 *last_index; /* Config parameters */ f64 session_timeout_interval; uword session_hash_memory; u32 session_hash_buckets; u32 max_sessions_per_worker; /* convenience */ vlib_main_t *vlib_main; vnet_main_t *vnet_main; ethernet_main_t *ethernet_main; } ct6_main_t; extern ct6_main_t ct6_main; extern vlib_node_registration_t ct6_out2in_node; extern vlib_node_registration_t ct6_in2out_node; format_function_t format_ct6_session; ct6_session_t *ct6_create_or_recycle_session (ct6_main_t * cmp, clib_bihash_kv_48_8_t * kvpp, f64 now, u32 my_thread_index, u32 * recyclep, u32 * createp); static inline void ct6_lru_remove (ct6_main_t * cmp, ct6_session_t * s0) { ct6_session_t *next_sess, *prev_sess; u32 thread_index; u32 s0_index; thread_index = s0->thread_index; s0_index = s0 - cmp->sessions[thread_index]; /* Deal with list heads */ if (s0_index == cmp->first_index[thread_index]) cmp->first_index[thread_index] = s0->next_index; if (s0_index == cmp->last_index[thread_index]) cmp->last_index[thread_index] = s0->prev_index; /* Fix next->prev */ if (s0->next_index != ~0) { next_sess = pool_elt_at_index (cmp->sessions[thread_index], s0->next_index); next_sess->prev_index = s0->prev_index; } /* Fix prev->next */ if (s0->prev_index != ~0) { prev_sess = pool_elt_at_index (cmp->sessions[thread_index], s0->prev_index); prev_sess->next_index = s0->next_index; } } static inline void ct6_lru_add (ct6_main_t * cmp, ct6_session_t * s0, f64 now) { ct6_session_t *next_sess; u32 thread_index; u32 s0_index; s0->hits++; s0->expires = now + cmp->session_timeout_interval; thread_index = s0->thread_index; s0_index = s0 - cmp->sessions[thread_index]; /* * Re-add at the head of the forward LRU list, * tail of the reverse LRU list */ if (cmp->first_index[thread_index] != ~0) { next_sess = pool_elt_at_index (cmp->sessions[thread_index], cmp->first_index[thread_index]); next_sess->prev_index = s0_index; } s0->prev_index = ~0; /* s0 now the new head of the LRU forward list */ s0->next_index = cmp->first_index[thread_index]; cmp->first_index[thread_index] = s0_index; /* single session case: also the tail of the reverse LRU list */ if (cmp->last_index[thread_index] == ~0) cmp->last_index[thread_index] = s0_index; } static inline void ct6_update_session_hit (ct6_main_t * cmp, ct6_session_t * s0, f64 now) { ct6_lru_remove (cmp, s0); ct6_lru_add (cmp, s0, now); } #endif /* __included_ct6_h__ */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */