16 #ifndef __HICN_PCS_H__
17 #define __HICN_PCS_H__
38 #define HICN_PIT_NULL_TYPE 0
39 #define HICN_PIT_TYPE 1
40 #define HICN_CS_TYPE 2
47 #define HICN_INFRA_FAST_TIMER_SECS 1
48 #define HICN_INFRA_FAST_TIMER_MSECS (HICN_INFRA_FAST_TIMER_SECS * SEC_MS)
49 #define HICN_INFRA_SLOW_TIMER_SECS 60
50 #define HICN_INFRA_SLOW_TIMER_MSECS (HICN_INFRA_SLOW_TIMER_SECS * SEC_MS)
56 typedef struct __attribute__ ((packed)) hicn_pcs_shared_s
72 #define HICN_PCS_ENTRY_CS_FLAG 0x01
77 typedef struct __attribute__ ((packed)) hicn_pit_entry_s
94 #define HICN_CS_ENTRY_OPAQUE_SIZE HICN_HASH_NODE_APP_DATA_SIZE - 36
99 typedef struct __attribute__ ((packed)) hicn_cs_entry_s
110 hicn_face_id_t cs_rxface;
119 u8 opaque[HICN_CS_ENTRY_OPAQUE_SIZE];
131 hicn_pcs_shared_t shared;
135 hicn_pit_entry_t
pit;
165 always_inline
void hicn_pit_to_cs (vlib_main_t *vm,
hicn_pit_cs_t *pitcs,
167 hicn_hash_entry_t *hash_entry,
168 hicn_hash_node_t *node,
170 dpo_id_t *hicn_dpo_id,
171 hicn_face_id_t inface_id, u8 is_appface);
173 always_inline
void hicn_pcs_cs_update (vlib_main_t *vm,
hicn_pit_cs_t *pitcs,
176 hicn_hash_node_t *node);
178 always_inline
void hicn_pcs_cs_delete (vlib_main_t *vm,
hicn_pit_cs_t *pitcs,
180 hicn_hash_node_t **node,
181 hicn_hash_entry_t *hash_entry,
183 dpo_id_t *hicn_dpo_id);
188 hicn_hash_entry_t **hash_entry, u64 hashval, u32 *node_id,
189 index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs,
190 u8 *hash_entry_id, u32 *bucket_id, u8 *bucket_is_overflow);
192 always_inline
int hicn_pcs_cs_insert_update (
194 hicn_hash_node_t *node, hicn_hash_entry_t **hash_entry, u64 hashval,
195 u32 *node_id, index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs, u8 *hash_entry_id,
196 u32 *bucket_id, u8 *bucket_is_overflow, hicn_face_id_t inface);
200 hicn_hash_node_t *node, hicn_hash_entry_t **hash_entry,
201 u64 hashval, u32 *node_id, index_t *dpo_ctx_id,
202 u8 *vft_id, u8 *is_cs, u8 *hash_entry_id, u32 *bucket_id,
203 u8 *bucket_is_overflow);
207 hicn_hash_node_t **node, vlib_main_t *vm,
208 hicn_hash_entry_t *hash_entry,
211 always_inline
int hicn_pcs_insert (vlib_main_t *vm,
hicn_pit_cs_t *pitcs,
213 hicn_hash_node_t *node,
214 hicn_hash_entry_t **hash_entry, u64 hashval,
215 u32 *node_id, index_t *dpo_ctx_id,
216 u8 *vft_id, u8 *is_cs, u8 *hash_entry_id,
217 u32 *bucket_id, u8 *bucket_is_overflow);
221 hicn_hash_node_t **node, vlib_main_t *vm,
222 hicn_hash_entry_t *hash_entry,
224 dpo_id_t *hicn_dpo_id);
228 hicn_hash_node_t **node, vlib_main_t *vm,
229 hicn_hash_entry_t *hash_entry,
232 always_inline
void hicn_cs_delete_trimmed (
hicn_pit_cs_t *pitcs,
234 hicn_hash_entry_t *hash_entry,
235 hicn_hash_node_t **node,
241 hicn_pit_get_data (hicn_hash_node_t *node)
250 p->shared.entry_flags = 0;
251 p->u.pit.faces.n_faces = 0;
252 p->u.pit.faces.is_overflow = 0;
254 pool_get (hicn_face_bucket_pool, face_bkt);
256 p->u.pit.faces.next_bucket = face_bkt - hicn_face_bucket_pool;
263 p->shared.entry_flags = 0;
264 p->u.pit.faces.n_faces = 0;
265 p->u.pit.faces.is_overflow = 0;
269 hicn_pcs_get_exp_time (f64 cur_time_sec, u64 lifetime_msec)
271 return (cur_time_sec + ((f64) lifetime_msec) / SEC_MS);
281 p->policy_state.max = limit;
290 return (pitcs->pcs_pit_count);
299 return (pitcs->pcs_cs_count);
305 return (pitcs->policy_state.count);
311 return (pitcs->pcs_table->ht_overflow_buckets_used);
317 switch (HICN_FEATURE_CS)
323 return (
pit->policy_state.max > 0);
335 hicn_hash_entry_t *hash_entry,
336 hicn_hash_node_t **node, vlib_main_t *vm,
341 ASSERT (pcs == hicn_hashtb_node_data (*node));
343 if (hash_entry->he_flags & HICN_HASH_ENTRY_FLAG_CS_ENTRY)
345 pitcs->pcs_cs_dealloc++;
347 vlib_buffer_free_one (vm, pcs->u.cs.cs_pkt_buf);
348 pcs->u.cs.cs_pkt_buf = ~0;
349 ASSERT ((pcs->u.cs.cs_lru_prev == 0) &&
350 (pcs->u.cs.cs_lru_prev == pcs->u.cs.cs_lru_next));
354 pitcs->pcs_pit_dealloc++;
358 hicn_faces_flush (&(pcs->u.pit.faces));
361 hicn_hashtb_delete (pitcs->pcs_table, node, hash_entry->he_msb64);
373 dpo_id_t *hicn_dpo_id, hicn_face_id_t inface_id, u8 is_appface)
380 pitcs->pcs_pit_count--;
383 hicn_faces_flush (&(pcs_entry->u.pit.faces));
385 hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_CS_ENTRY;
386 node->hn_flags |= HICN_HASH_NODE_CS_FLAGS;
387 pcs_entry->shared.entry_flags |= HICN_PCS_ENTRY_CS_FLAG;
389 pcs_entry->u.cs.cs_rxface = inface_id;
395 policy_state = &pitcs->policy_state;
396 policy_vft = &pitcs->policy_vft;
398 policy_vft->hicn_cs_insert (pitcs, node, pcs_entry, policy_state);
399 pitcs->pcs_cs_count++;
401 if (policy_state->count > policy_state->max)
403 hicn_hash_node_t *node;
405 hicn_hash_entry_t *hash_entry;
406 policy_vft->hicn_cs_delete_get (pitcs, policy_state, &node, &pcs_entry,
413 policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state);
415 hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm);
418 pitcs->pcs_cs_count--;
427 hicn_hash_node_t *node)
432 policy_state = &pitcs->policy_state;
433 policy_vft = &pitcs->policy_vft;
435 if (entry->u.cs.cs_rxface != old_entry->u.cs.cs_rxface)
438 policy_vft->hicn_cs_dequeue (pitcs, node, old_entry, policy_state);
440 old_entry->u.cs.cs_rxface = entry->u.cs.cs_rxface;
441 policy_state = &pitcs->policy_state;
442 policy_vft = &pitcs->policy_vft;
444 policy_vft->hicn_cs_insert (pitcs, node, old_entry, policy_state);
446 if (policy_state->count > policy_state->max)
448 hicn_hash_node_t *node;
450 hicn_hash_entry_t *hash_entry;
451 policy_vft->hicn_cs_delete_get (pitcs, policy_state, &node,
452 &pcs_entry, &hash_entry);
458 policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state);
460 hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm);
463 pitcs->pcs_cs_count--;
468 policy_vft->hicn_cs_update (pitcs, node, old_entry, policy_state);
474 hicn_hash_entry_t *hash_entry,
477 if (!(hash_entry->he_flags & HICN_HASH_ENTRY_FLAG_DELETED))
482 policy_state = &pitcs->policy_state;
483 policy_vft = &pitcs->policy_vft;
485 policy_vft->hicn_cs_dequeue (pitcs, (*nodep), (*pcs_entryp),
489 pitcs->pcs_cs_count--;
495 if (hash_entry->locks == 0)
497 hicn_pcs_delete_internal (pitcs, pcs_entryp, hash_entry, nodep, vm,
498 dpo_vft, hicn_dpo_id);
502 hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_DELETED;
509 hicn_hash_entry_t **hash_entry, u64 hashval, u32 *node_id,
510 index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs,
511 u8 *hash_entry_id, u32 *bucket_id, u8 *bucket_is_overflow)
513 ASSERT (entry == hicn_hashtb_node_data (node));
515 int ret = hicn_hashtb_insert (pitcs->pcs_table, node, hash_entry, hashval,
516 node_id, dpo_ctx_id, vft_id, is_cs,
517 hash_entry_id, bucket_id, bucket_is_overflow);
519 if (PREDICT_TRUE (ret == HICN_ERROR_NONE))
522 node->hn_flags |= HICN_HASH_NODE_CS_FLAGS;
523 entry->shared.entry_flags |= HICN_PCS_ENTRY_CS_FLAG;
524 (*hash_entry)->he_flags |= HICN_HASH_ENTRY_FLAG_CS_ENTRY;
529 policy_state = &pitcs->policy_state;
530 policy_vft = &pitcs->policy_vft;
532 policy_vft->hicn_cs_insert (pitcs, node, entry, policy_state);
533 pitcs->pcs_cs_count++;
535 if (policy_state->count > policy_state->max)
537 hicn_hash_node_t *node;
539 hicn_hash_entry_t *hash_entry;
540 policy_vft->hicn_cs_delete_get (pitcs, policy_state, &node,
541 &pcs_entry, &hash_entry);
547 policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state);
549 hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm);
552 pitcs->pcs_cs_count--;
563 hicn_pcs_cs_insert_update (vlib_main_t *vm,
hicn_pit_cs_t *pitcs,
565 hicn_hash_entry_t **hash_entry, u64 hashval,
566 u32 *node_id, index_t *dpo_ctx_id, u8 *vft_id,
567 u8 *is_cs, u8 *hash_entry_id, u32 *bucket_id,
568 u8 *bucket_is_overflow, hicn_face_id_t inface)
572 ASSERT (entry == hicn_hashtb_node_data (node));
574 entry->u.cs.cs_rxface = inface;
575 ret = hicn_pcs_cs_insert (vm, pitcs, entry, node, hash_entry, hashval,
576 node_id, dpo_ctx_id, vft_id, is_cs, hash_entry_id,
577 bucket_id, bucket_is_overflow);
580 if (ret == HICN_ERROR_HASHTB_EXIST && *is_cs)
583 hicn_hash_node_t *existing_node =
584 hicn_hashtb_node_from_idx (pitcs->pcs_table, *node_id);
588 pitcs->pcs_cs_dealloc++;
589 vlib_buffer_free_one (vm, pitp->u.cs.cs_pkt_buf);
591 pitp->shared.create_time = entry->shared.create_time;
592 pitp->shared.expire_time = entry->shared.expire_time;
593 pitp->u.cs.cs_pkt_buf = entry->u.cs.cs_pkt_buf;
595 hicn_pcs_cs_update (vm, pitcs, pitp, entry, existing_node);
607 hicn_hash_node_t *node, hicn_hash_entry_t **hash_entry,
608 u64 hashval, u32 *node_id, index_t *dpo_ctx_id,
609 u8 *vft_id, u8 *is_cs, u8 *hash_entry_id, u32 *bucket_id,
610 u8 *bucket_is_overflow)
612 ASSERT (entry == hicn_hashtb_node_data (node));
614 int ret = hicn_hashtb_insert (pitcs->pcs_table, node, hash_entry, hashval,
615 node_id, dpo_ctx_id, vft_id, is_cs,
616 hash_entry_id, bucket_id, bucket_is_overflow);
618 if (PREDICT_TRUE (ret == HICN_ERROR_NONE))
619 pitcs->pcs_pit_count++;
626 hicn_hash_node_t **node, vlib_main_t *vm,
627 hicn_hash_entry_t *hash_entry,
631 if (hash_entry->locks == 0)
633 pitcs->pcs_pit_count--;
634 hicn_pcs_delete_internal (pitcs, pcs_entryp, hash_entry, node, vm,
635 dpo_vft, hicn_dpo_id);
639 hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_DELETED;
652 hicn_hash_entry_t **hash_entry, u64 hashval, u32 *node_id,
653 index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs, u8 *hash_entry_id,
654 u32 *bucket_id, u8 *bucket_is_overflow)
658 if ((*hash_entry)->he_flags & HICN_HASH_ENTRY_FLAG_CS_ENTRY)
660 ret = hicn_pcs_cs_insert (vm, pitcs, entry, node, hash_entry, hashval,
661 node_id, dpo_ctx_id, vft_id, is_cs,
662 hash_entry_id, bucket_id, bucket_is_overflow);
666 ret = hicn_pcs_pit_insert (pitcs, entry, node, hash_entry, hashval,
667 node_id, dpo_ctx_id, vft_id, is_cs,
668 hash_entry_id, bucket_id, bucket_is_overflow);
680 hicn_hash_node_t **nodep, vlib_main_t *vm,
682 dpo_id_t *hicn_dpo_id)
688 if (hash_entry->he_flags & HICN_HASH_ENTRY_FLAG_CS_ENTRY)
690 hicn_pcs_cs_delete (vm, pitcs, pcs_entryp, nodep, hash_entry, dpo_vft,
695 hicn_pcs_pit_delete (pitcs, pcs_entryp, nodep, vm, hash_entry, dpo_vft,
706 hicn_hash_node_t **node, vlib_main_t *vm,
707 hicn_hash_entry_t *hash_entry,
711 if (hash_entry->locks == 0 &&
712 (hash_entry->he_flags & HICN_HASH_ENTRY_FLAG_DELETED))
714 hicn_pcs_delete_internal (pitcs, pcs_entryp, hash_entry, node, vm,
715 dpo_vft, hicn_dpo_id);
724 hicn_hash_entry_t *hash_entry, hicn_hash_node_t **node,
728 if (hash_entry->locks == 0)
734 .dpoi_index = hash_entry->dpo_ctx_id };
736 hicn_pcs_delete_internal (pitcs, pcs_entryp, hash_entry, node, vm,
737 dpo_vft, &hicn_dpo_id);
741 hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_DELETED;
749 hicn_infra_seq16_sum (u16 addend1, u16 addend2)
751 return (addend1 + addend2);
758 hicn_infra_seq16_cmp (u16 a, u16 b)
760 return ((int16_t) (a - b));
767 hicn_infra_seq16_lt (u16 a, u16 b)
769 return (hicn_infra_seq16_cmp (a, b) < 0);
773 hicn_infra_seq16_le (u16 a, u16 b)
775 return (hicn_infra_seq16_cmp (a, b) <= 0);
779 hicn_infra_seq16_gt (u16 a, u16 b)
781 return (hicn_infra_seq16_cmp (a, b) > 0);
785 hicn_infra_seq16_ge (u16 a, u16 b)
787 return (hicn_infra_seq16_cmp (a, b) >= 0);
790 extern u16 hicn_infra_fast_timer;
791 extern u16 hicn_infra_slow_timer;
800 hicn_infra_ms2clicks (u64 time_ms, u64 ms_per_click)
803 ((f64) (time_ms + ms_per_click - 1)) / ((f64) ms_per_click);
804 return ((u16) time_clicks);
808 hicn_infra_get_fast_exp_time (u64 lifetime_ms)
810 u16 lifetime_clicks =
811 hicn_infra_ms2clicks (lifetime_ms, HICN_INFRA_FAST_TIMER_MSECS);
812 return (hicn_infra_seq16_sum (hicn_infra_fast_timer, lifetime_clicks));
816 hicn_infra_get_slow_exp_time (u64 lifetime_ms)
818 u16 lifetime_clicks =
819 hicn_infra_ms2clicks (lifetime_ms, HICN_INFRA_SLOW_TIMER_MSECS);
820 return (hicn_infra_seq16_sum (hicn_infra_slow_timer, lifetime_clicks));