blob: 534534f5c99663e38746253994a713aecdb2a957 [file] [log] [blame]
/*
* 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:
*/