diff options
-rw-r--r-- | vnet/vnet/lisp-cp/control.c | 60 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/control.h | 3 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_types.h | 1 |
3 files changed, 63 insertions, 1 deletions
diff --git a/vnet/vnet/lisp-cp/control.c b/vnet/vnet/lisp-cp/control.c index 40ce6b0c..a2172bf3 100644 --- a/vnet/vnet/lisp-cp/control.c +++ b/vnet/vnet/lisp-cp/control.c @@ -1155,6 +1155,12 @@ remove_overlapping_sub_prefixes (lisp_cp_main_t * lcm, gid_address_t * eid, vec_free (a.eids_to_be_deleted); } +static void +mapping_delete_timer (lisp_cp_main_t * lcm, u32 mi) +{ + timing_wheel_delete (&lcm->wheel, mi); +} + /** * Adds/removes/updates mapping. Does not program forwarding. * @@ -1247,6 +1253,7 @@ vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action, m_args->action = action; m_args->locator_set_index = ls_index; m_args->is_static = is_static; + m_args->ttl = ttl; vnet_lisp_map_cache_add_del (m_args, &dst_map_index); if (res_map_index) @@ -1274,6 +1281,10 @@ vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action, /* delete locator set */ vnet_lisp_add_del_locator_set (ls_args, 0); + /* delete timer associated to the mapping if any */ + if (old_map->timer_set) + mapping_delete_timer (lcm, mi); + /* return old mapping index */ if (res_map_index) res_map_index[0] = mi; @@ -4067,6 +4078,33 @@ format_lisp_cp_input_trace (u8 * s, va_list * args) return s; } +static void +remove_expired_mapping (lisp_cp_main_t * lcm, u32 mi) +{ + mapping_t *m; + + m = pool_elt_at_index (lcm->mapping_pool, mi); + lisp_add_del_adjacency (lcm, 0, &m->eid, 0 /* is_add */ ); + vnet_lisp_add_del_mapping (&m->eid, 0, 0, 0, ~0, 0 /* is_add */ , + 0 /* is_static */ , 0); + mapping_delete_timer (lcm, mi); +} + +static void +mapping_start_expiration_timer (lisp_cp_main_t * lcm, u32 mi, + f64 expiration_time) +{ + mapping_t *m; + u64 now = clib_cpu_time_now (); + u64 cpu_cps = lcm->vlib_main->clib_time.clocks_per_second; + u64 exp_clock_time = now + expiration_time * cpu_cps; + + m = pool_elt_at_index (lcm->mapping_pool, mi); + + m->timer_set = 1; + timing_wheel_insert (&lcm->wheel, exp_clock_time, mi); +} + void * process_map_reply (void *arg) { @@ -4124,7 +4162,11 @@ process_map_reply (void *arg) /* try to program forwarding only if mapping saved or updated */ if ((u32) ~ 0 != dst_map_index) - lisp_add_del_adjacency (lcm, &pmr->src, &deid, 1); + { + lisp_add_del_adjacency (lcm, &pmr->src, &deid, 1); + if ((u32) ~ 0 != ttl) + mapping_start_expiration_timer (lcm, dst_map_index, ttl * 60); + } vec_free (locators); } @@ -4568,6 +4610,8 @@ lisp_cp_init (vlib_main_t * vm) udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp6, lisp_cp_input_node.index, 0 /* is_ip4 */ ); + u64 now = clib_cpu_time_now (); + timing_wheel_init (&lcm->wheel, now, vm->clib_time.clocks_per_second); return 0; } @@ -4734,6 +4778,7 @@ static uword send_map_resolver_service (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) { + u32 *expired = 0; f64 period = 2.0; pending_map_request_t *pmr; lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); @@ -4760,6 +4805,19 @@ send_map_resolver_service (vlib_main_t * vm, update_map_register (lcm, period); update_rloc_probing (lcm, period); + + u64 now = clib_cpu_time_now (); + + expired = timing_wheel_advance (&lcm->wheel, now, expired, 0); + if (vec_len (expired) > 0) + { + u32 *mi = 0; + vec_foreach (mi, expired) + { + remove_expired_mapping (lcm, mi[0]); + } + _vec_len (expired) = 0; + } } /* unreachable */ diff --git a/vnet/vnet/lisp-cp/control.h b/vnet/vnet/lisp-cp/control.h index 14b54606..71bb39af 100644 --- a/vnet/vnet/lisp-cp/control.h +++ b/vnet/vnet/lisp-cp/control.h @@ -184,6 +184,9 @@ typedef struct /* enable/disable rloc-probing */ u8 rloc_probing; + /* timing wheel for mappping timeouts */ + timing_wheel_t wheel; + /* commodity */ ip4_main_t *im4; ip6_main_t *im6; diff --git a/vnet/vnet/lisp-cp/lisp_types.h b/vnet/vnet/lisp-cp/lisp_types.h index 7df0e653..1a3cfdef 100644 --- a/vnet/vnet/lisp-cp/lisp_types.h +++ b/vnet/vnet/lisp-cp/lisp_types.h @@ -321,6 +321,7 @@ typedef struct u8 is_static; u8 *key; lisp_key_type_t key_id; + u8 timer_set; } mapping_t; uword |