aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hicn-light/src/hicn/processor/fib.c2
-rw-r--r--hicn-light/src/hicn/processor/fibEntry.c13
-rw-r--r--hicn-light/src/hicn/processor/messageProcessor.c3
-rw-r--r--hicn-light/src/hicn/strategies/loadBalancer.c11
-rw-r--r--hicn-plugin/CMakeLists.txt4
-rw-r--r--hicn-plugin/src/data_fwd_node.c5
-rw-r--r--hicn-plugin/src/data_pcslookup_node.c35
-rw-r--r--hicn-plugin/src/faces/app/face_prod.c4
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.c106
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.h117
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.c341
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.h62
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_cli.c4
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_node.c3
-rw-r--r--hicn-plugin/src/hicn.h5
-rw-r--r--hicn-plugin/src/hicn_api.c2
-rw-r--r--hicn-plugin/src/mgmt.c4
-rw-r--r--hicn-plugin/src/pcs.h2
-rw-r--r--lib/src/compat.c4
-rw-r--r--lib/src/name.c3
-rw-r--r--libtransport/src/hicn/transport/core/forwarder_interface.h2
-rw-r--r--libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc105
-rw-r--r--libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h20
-rw-r--r--libtransport/src/hicn/transport/protocols/rtc.cc64
-rw-r--r--libtransport/src/hicn/transport/protocols/rtc.h11
-rw-r--r--utils/src/hiperf.cc22
26 files changed, 549 insertions, 405 deletions
diff --git a/hicn-light/src/hicn/processor/fib.c b/hicn-light/src/hicn/processor/fib.c
index 6489e59e2..6bb29c404 100644
--- a/hicn-light/src/hicn/processor/fib.c
+++ b/hicn-light/src/hicn/processor/fib.c
@@ -452,6 +452,8 @@ void fib_RemoveConnectionId(FIB *fib, unsigned connectionId) {
for (int i = 0; i < fibEntryList_Length(list); i++) {
_removeNode(fib, fibEntry_GetPrefix(fibEntryList_Get(list, i)));
}
+
+ fibEntryList_Destroy(&list);
}
size_t fib_Length(const FIB *fib) {
diff --git a/hicn-light/src/hicn/processor/fibEntry.c b/hicn-light/src/hicn/processor/fibEntry.c
index 04e453ab9..f12dd506b 100644
--- a/hicn-light/src/hicn/processor/fibEntry.c
+++ b/hicn-light/src/hicn/processor/fibEntry.c
@@ -201,6 +201,7 @@ NumberSet *
fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection) {
ConnectionTable * table = forwarder_GetConnectionTable(fibEntry->forwarder);
NumberSet * nexthops;
+ bool dealloc_nexthops = false;
policy_t policy = fibEntry_GetPolicy(fibEntry);
/* Reset available next hops and start filtering */
@@ -214,6 +215,7 @@ fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection)
if (in_connection == ~0) {
/* We might advertise among all available up connections */
nexthops = numberSet_Create();
+ dealloc_nexthops = true;
ConnectionList * list = connectionTable_GetEntries(table);
for (size_t i = 0; i < connectionList_Length(list); i++) {
@@ -226,7 +228,7 @@ fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection)
continue;
numberSet_Add(nexthops, connection_GetConnectionId(conn));
}
-
+ connectionList_Destroy(&list);
} else {
nexthops = (NumberSet*)fibEntry_GetNexthops(fibEntry);
for (size_t k = 0; k < numberSet_Length(nexthops); k++) {
@@ -247,8 +249,12 @@ fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection)
numberSet_Add(available_nexthops, conn_id);
}
- if (numberSet_Length(available_nexthops) > 0)
+ if (numberSet_Length(available_nexthops) > 0){
+ if(dealloc_nexthops){
+ numberSet_Release(&nexthops);
+ }
return available_nexthops;
+ }
}
for (size_t k = 0; k < numberSet_Length(nexthops); k++) {
@@ -297,6 +303,9 @@ fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection)
numberSet_Add(available_nexthops, conn_id);
}
+ if(dealloc_nexthops)
+ numberSet_Release(&nexthops);
+
if (numberSet_Length(available_nexthops) == 0)
return available_nexthops;
diff --git a/hicn-light/src/hicn/processor/messageProcessor.c b/hicn-light/src/hicn/processor/messageProcessor.c
index 456618269..3ca9264b8 100644
--- a/hicn-light/src/hicn/processor/messageProcessor.c
+++ b/hicn-light/src/hicn/processor/messageProcessor.c
@@ -298,7 +298,7 @@ bool messageProcessor_AddOrUpdateRoute(MessageProcessor *processor,
unsigned ifidx) {
Configuration *config = forwarder_GetConfiguration(processor->forwarder);
- const char *prefixStr = utils_PrefixLenToString(
+ char *prefixStr = (char *) utils_PrefixLenToString(
control->addressType, &control->address, &control->len);
strategy_type fwdStrategy =
configuration_GetForwardingStrategy(config, prefixStr);
@@ -323,6 +323,7 @@ bool messageProcessor_AddOrUpdateRoute(MessageProcessor *processor,
fib_Add(processor->fib, entry);
}
+ free(prefixStr);
name_Release(&prefix);
/* For policy implementation, we need access to the ConnectionTable in all
diff --git a/hicn-light/src/hicn/strategies/loadBalancer.c b/hicn-light/src/hicn/strategies/loadBalancer.c
index b66de217e..ca9d34289 100644
--- a/hicn-light/src/hicn/strategies/loadBalancer.c
+++ b/hicn-light/src/hicn/strategies/loadBalancer.c
@@ -201,6 +201,7 @@ static NumberSet *_strategyLoadBalancer_LookupNexthop(
PARCUnsigned *cid = parcUnsigned_Create(numberSet_GetItem(nexthops, i));
const StrategyNexthopState *elem =
parcHashMap_Get(lb->strategy_state, cid);
+ parcUnsigned_Release(&cid);
if (!elem)
continue;
sum += strategyNexthopState_GetWeight(elem);
@@ -213,12 +214,15 @@ static NumberSet *_strategyLoadBalancer_LookupNexthop(
PARCUnsigned *cid = parcUnsigned_Create(numberSet_GetItem(nexthops, i));
const StrategyNexthopState *state =
parcHashMap_Get(lb->strategy_state, cid);
- if (!state)
- continue;
+ if (!state){
+ parcUnsigned_Release(&cid);
+ continue;
+ }
distance -= strategyNexthopState_GetWeight(state);
if (distance < 0) {
numberSet_Add(outList, parcUnsigned_GetUnsigned(cid));
_update_Stats(lb, (StrategyNexthopState *)state, true);
+ parcUnsigned_Release(&cid);
break;
}
}
@@ -296,19 +300,20 @@ static void _strategyLoadBalancer_resetState(StrategyImpl *strategy) {
static void _strategyLoadBalancer_AddNexthop(StrategyImpl *strategy,
unsigned connectionId) {
- StrategyNexthopState *state = strategyNexthopState_Create();
PARCUnsigned *cid = parcUnsigned_Create(connectionId);
StrategyLoadBalancer *lb = (StrategyLoadBalancer *)strategy->context;
if (!parcHashMap_Contains(lb->strategy_state, cid)) {
+ StrategyNexthopState *state = strategyNexthopState_Create();
parcHashMap_Put(lb->strategy_state, cid, state);
#ifndef WITH_POLICY
numberSet_Add(lb->nexthops, connectionId);
#endif /* WITH_POLICY */
_strategyLoadBalancer_resetState(strategy);
}
+ parcUnsigned_Release(&cid);
}
static void _strategyLoadBalancer_RemoveNexthop(StrategyImpl *strategy,
diff --git a/hicn-plugin/CMakeLists.txt b/hicn-plugin/CMakeLists.txt
index 97279e540..8425a5cf3 100644
--- a/hicn-plugin/CMakeLists.txt
+++ b/hicn-plugin/CMakeLists.txt
@@ -307,6 +307,10 @@ install(FILES ${HICN_API_HEADER_FILES} ${HICN_API_GENERATED_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vpp_plugins/hicn
COMPONENT ${HICN_PLUGIN}-dev)
+install(FILES ${HICN_API_GENERATED_FILES}
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vpp_plugins/hicn
+ COMPONENT ${HICN_PLUGIN_DEV})
+
install(FILES ${HICN_VAPI_GENERATED_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vapi
COMPONENT ${HICN_PLUGIN}-dev)
diff --git a/hicn-plugin/src/data_fwd_node.c b/hicn-plugin/src/data_fwd_node.c
index 53308a49d..ca3baaa0d 100644
--- a/hicn-plugin/src/data_fwd_node.c
+++ b/hicn-plugin/src/data_fwd_node.c
@@ -176,6 +176,7 @@ hicn_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
hicn_pcs_delete (pitcs, &pitp, &node0, vm, hash_entry0,
dpo_vft0, &hicn_dpo_id0);
+#if HICN_FEATURE_CS
if (hicnb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP)
{
push_in_cache (vm, bi0, &n_left_to_next, &next0, &to_next,
@@ -186,6 +187,10 @@ hicn_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
drop_packet (vm, bi0, &n_left_to_next, &next0, &to_next,
&next_index, node);
}
+#else
+ drop_packet (vm, bi0, &n_left_to_next, &next0, &to_next,
+ &next_index, node);
+#endif
stats.pit_expired_count++;
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
diff --git a/hicn-plugin/src/data_pcslookup_node.c b/hicn-plugin/src/data_pcslookup_node.c
index aeb8c2276..fdf855e57 100644
--- a/hicn-plugin/src/data_pcslookup_node.c
+++ b/hicn-plugin/src/data_pcslookup_node.c
@@ -102,27 +102,17 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
b0 = vlib_get_buffer (vm, bi0);
hb0 = hicn_get_buffer (b0);
+ next0 = HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP;
/* Incr packet counter */
stats.pkts_processed += 1;
ret0 = hicn_data_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
-
- if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE))
- {
- next0 =
- isv6 ? HICN_DATA_PCSLOOKUP_NEXT_V6_LOOKUP :
- HICN_DATA_PCSLOOKUP_NEXT_V4_LOOKUP;
- }
nameptr = (u8 *) (&name);
- if (PREDICT_FALSE
- (ret0 != HICN_ERROR_NONE
- || hicn_hashtb_fullhash (nameptr, namelen,
- &name_hash) != HICN_ERROR_NONE))
- {
- next0 = HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP;
- }
- else
+
+ if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE &&
+ hicn_hashtb_fullhash (nameptr, namelen,
+ &name_hash) == HICN_ERROR_NONE))
{
int res =
hicn_hashtb_lookup_node (rt->pitcs->pcs_table, nameptr,
@@ -137,9 +127,10 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
stats.pkts_data_count += 1;
+#if HICN_FEATURE_CS
if ((res == HICN_ERROR_HASHTB_HASH_NOT_FOUND
|| (res == HICN_ERROR_NONE && is_cs0))
- && (hb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP))
+ && ((hb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP)))
{
next0 = HICN_DATA_PCSLOOKUP_NEXT_STORE_DATA;
}
@@ -153,6 +144,18 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
next0 = HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD + is_cs0;
}
}
+#else
+ if (res == HICN_ERROR_NONE)
+ {
+ /*
+ * In case the result of the lookup
+ * is a CS entry, the packet is
+ * dropped
+ */
+ next0 = HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD + is_cs0;
+ }
+ }
+#endif
hicn_store_internal_state (b0, name_hash, node_id0, dpo_ctx_id0,
vft_id0, hash_entry_id, bucket_id,
diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c
index 7e6117b84..bbcc7fa6e 100644
--- a/hicn-plugin/src/faces/app/face_prod.c
+++ b/hicn-plugin/src/faces/app/face_prod.c
@@ -218,7 +218,7 @@ hicn_face_prod_add (hicn_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
remote_app_ip = to_ip46 ( /* isv6 */ 0, remote_app_ip4.as_u8);
ret =
- hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid);
+ hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, HICN_FACE_FLAGS_APPFACE_PROD);
}
else
{
@@ -238,7 +238,7 @@ hicn_face_prod_add (hicn_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
remote_app_ip = to_ip46 ( /* isv6 */ 1, remote_app_ip6.as_u8);
ret =
- hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid);
+ hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, HICN_FACE_FLAGS_APPFACE_PROD);
}
face = hicn_dpoi_get_from_idx (*faceid);
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.c b/hicn-plugin/src/faces/ip/dpo_ip.c
index de71f1b01..d05fec1a0 100644
--- a/hicn-plugin/src/faces/ip/dpo_ip.c
+++ b/hicn-plugin/src/faces/ip/dpo_ip.c
@@ -19,6 +19,8 @@ mhash_t hicn_face_ip_local_hashtb;
mhash_t hicn_face_ip_remote_hashtb;
dpo_type_t hicn_face_ip_type;
+hicn_face_ip_vec_t * hicn_vec_pool;
+
const static char *const hicn_face_ip4dpoi_nodes[] = {
"hicn-face-ip4-input",
"hicn-face-ip4-output",
@@ -51,12 +53,14 @@ void
hicn_dpo_ip_module_init (void)
{
mhash_init (&hicn_face_ip_local_hashtb,
- sizeof (hicn_face_id_t) /* value */ ,
+ sizeof (hicn_face_ip_input_faces_t) /* value */ ,
sizeof (hicn_face_ip_key_t) /* key */ );
mhash_init (&hicn_face_ip_remote_hashtb,
sizeof (hicn_face_id_t) /* value */ ,
sizeof (hicn_face_ip_key_t) /* key */ );
+ pool_alloc(hicn_vec_pool, 100);
+
/*
* How much useful is the following registration?
* So far it seems that we need it only for setting the dpo_type.
@@ -65,106 +69,6 @@ hicn_dpo_ip_module_init (void)
dpo_register_new_type (&hicn_face_ip_vft, hicn_ip_nodes);
}
-
-int
-hicn_dpo_ip4_create (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- /* If local matches the dpoi is a face */
- hicn_face_t *face =
- hicn_face_ip4_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
- u8 hicnb_flags;
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face = hicn_face_ip4_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- if (face == NULL)
- {
- hicn_dpo_ip4_add_and_lock_from_remote (dpo, &hicnb_flags, local_addr,
- remote_addr, sw_if, node_index);
- *face_id = (hicn_face_id_t) dpo->dpoi_index;
- face = hicn_dpoi_get_from_idx (*face_id);
- }
- else
- {
- *face_id = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, *face_id);
- dpo->dpoi_next_node = node_index;
- }
-
-
- hicn_face_ip_key_t key;
- hicn_face_ip4_get_key (local_addr, sw_if, &key);
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) face_id, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- ip46_address_set_ip4 (&ip_face->local_addr, local_addr);
- ip46_address_set_ip4 (&ip_face->remote_addr, remote_addr);
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- return HICN_ERROR_NONE;
-}
-
-int
-hicn_dpo_ip6_create (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- /* If local matches the dpoi is a face */
- hicn_face_t *face =
- hicn_face_ip6_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
-
- u8 hicnb_flags;
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face = hicn_face_ip6_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- /* If remote matches the dpoi is a iface */
- if (face == NULL)
- {
- hicn_dpo_ip6_add_and_lock_from_remote (dpo, &hicnb_flags, local_addr,
- remote_addr, sw_if, node_index);
- *face_id = (hicn_face_id_t) dpo->dpoi_index;
- face = hicn_dpoi_get_from_idx (*face_id);
- }
- else
- {
- *face_id = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, *face_id);
- dpo->dpoi_next_node = node_index;
- }
-
- hicn_face_ip_key_t key;
- hicn_face_ip6_get_key (local_addr, sw_if, &key);
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) face_id, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr, sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
-
- return HICN_ERROR_NONE;
-}
-
void
hicn_dpo_ip_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
u16 dpoi_next_node)
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.h b/hicn-plugin/src/faces/ip/dpo_ip.h
index 164931a06..d6b4f5f7e 100644
--- a/hicn-plugin/src/faces/ip/dpo_ip.h
+++ b/hicn-plugin/src/faces/ip/dpo_ip.h
@@ -29,10 +29,9 @@ void hicn_dpo_ip_module_init (void);
/**
- * @brief Retrieve a face from the ip4 local address and returns its dpo. This
- * method adds a lock on the face state.
+ * @brief Retrieve a vector of faces from the ip4 local address and returns its index.
*
- * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
+ * @param vec: Result of the lookup. If no face exists for the local address vec = NULL
* @param hicnb_flags: Flags that indicate whether the face is an application
* face or not
* @param local_addr: Ip v4 local address of the face
@@ -42,22 +41,25 @@ void hicn_dpo_ip_module_init (void);
*/
always_inline int
hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo,
+ u32 * in_faces_vec_id,
u8 * hicnb_flags,
const ip4_address_t * local_addr, u32 sw_if)
{
- hicn_face_t *face =
- hicn_face_ip4_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
+ hicn_face_ip_input_faces_t * in_faces_vec =
+ hicn_face_ip4_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb);
- if (PREDICT_FALSE (face == NULL))
+ if (PREDICT_FALSE (in_faces_vec == NULL))
return HICN_ERROR_FACE_NOT_FOUND;
+ *in_faces_vec_id = in_faces_vec->vec_id;
+ hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
+
*hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
*hicnb_flags |=
(face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
HICN_FACE_FLAGS_APPFACE_PROD_BIT;
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index);
+ dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, in_faces_vec->face_id);
dpo->dpoi_next_node = ~0;
dpo_lock (dpo);
@@ -78,22 +80,25 @@ hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo,
*/
always_inline int
hicn_dpo_ip6_lock_from_local (dpo_id_t * dpo,
+ u32 * in_faces_vec_id,
u8 * hicnb_flags,
const ip6_address_t * local_addr, u32 sw_if)
{
- hicn_face_t *face =
- hicn_face_ip6_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
+ hicn_face_ip_input_faces_t * in_faces_vec =
+ hicn_face_ip6_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb);
- if (PREDICT_FALSE (face == NULL))
+ if (PREDICT_FALSE (in_faces_vec == NULL))
return HICN_ERROR_FACE_NOT_FOUND;
+ *in_faces_vec_id = in_faces_vec->vec_id;
+ hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
+
*hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
*hicnb_flags |=
(face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
HICN_FACE_FLAGS_APPFACE_PROD_BIT;
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, dpoi_index);
+ dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, in_faces_vec->face_id);
dpo->dpoi_next_node = ~0;
dpo_lock (dpo);
@@ -210,49 +215,49 @@ hicn_dpo_ip6_add_and_lock_from_remote (dpo_id_t * dpo,
}
-/**
- * @brief Create an ip face and its corresponding dpo. Meant to be used for the
- * control plane.
- *
- * @param dpo: Data plane object that point to the face created.
- * @param local_addr: Ip v4 local address of the face
- * @param remote_addr: Ip v4 remote address of the face
- * @param sw_if: software interface id of the face
- * @param adj: Ip adjacency corresponding to the remote address in the face
- * @param node_index: vlib edge index to use in the packet processing
- * @param flags: Flags of the face
- * @param face_id: Identifier for the face (dpoi_index)
- * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE
- */
-int hicn_dpo_ip4_create (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
-
-/**
- * @brief Create an ip face and its corresponding dpo. Meant to be used for the
- * control plane.
- *
- * @param dpo: Data plane object that point to the face created.
- * @param local_addr: Ip v6 local address of the face
- * @param remote_addr: Ip v6 remote address of the face
- * @param sw_if: software interface id of the face
- * @param adj: Ip adjacency corresponding to the remote address in the face
- * @param node_index: vlib edge index to use in the packet processing
- * @param flags: Flags of the face
- * @param face_id: Identifier for the face (dpoi_index)
- * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE
- */
-int hicn_dpo_ip6_create (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
+/* /\** */
+/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */
+/* * control plane. */
+/* * */
+/* * @param dpo: Data plane object that point to the face created. */
+/* * @param local_addr: Ip v4 local address of the face */
+/* * @param remote_addr: Ip v4 remote address of the face */
+/* * @param sw_if: software interface id of the face */
+/* * @param adj: Ip adjacency corresponding to the remote address in the face */
+/* * @param node_index: vlib edge index to use in the packet processing */
+/* * @param flags: Flags of the face */
+/* * @param face_id: Identifier for the face (dpoi_index) */
+/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */
+/* *\/ */
+/* int hicn_dpo_ip4_create (dpo_id_t * dpo, */
+/* const ip4_address_t * local_addr, */
+/* const ip4_address_t * remote_addr, */
+/* u32 sw_if, */
+/* adj_index_t adj, */
+/* u32 node_index, */
+/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */
+
+/* /\** */
+/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */
+/* * control plane. */
+/* * */
+/* * @param dpo: Data plane object that point to the face created. */
+/* * @param local_addr: Ip v6 local address of the face */
+/* * @param remote_addr: Ip v6 remote address of the face */
+/* * @param sw_if: software interface id of the face */
+/* * @param adj: Ip adjacency corresponding to the remote address in the face */
+/* * @param node_index: vlib edge index to use in the packet processing */
+/* * @param flags: Flags of the face */
+/* * @param face_id: Identifier for the face (dpoi_index) */
+/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */
+/* *\/ */
+/* int hicn_dpo_ip6_create (dpo_id_t * dpo, */
+/* const ip6_address_t * local_addr, */
+/* const ip6_address_t * remote_addr, */
+/* u32 sw_if, */
+/* adj_index_t adj, */
+/* u32 node_index, */
+/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */
/**
* @brief Create a dpo from an ip face
diff --git a/hicn-plugin/src/faces/ip/face_ip.c b/hicn-plugin/src/faces/ip/face_ip.c
index 6e279583c..23d3900ec 100644
--- a/hicn-plugin/src/faces/ip/face_ip.c
+++ b/hicn-plugin/src/faces/ip/face_ip.c
@@ -12,6 +12,8 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+#include <vnet/adj/adj_midchain.h>
+#include <vnet/adj/adj.h>
#include "face_ip.h"
#include "face_ip_node.h"
@@ -96,62 +98,165 @@ hicn_face_ip_del (hicn_face_id_t face_id)
hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
hicn_face_ip_key_t key;
hicn_face_ip_key_t old_key;
+ hicn_face_ip_key_t old_key2;
if (ip46_address_is_ip4 (&face_ip->local_addr))
{
hicn_face_ip4_get_key (&(face_ip->local_addr.ip4), face->shared.sw_if,
&key);
- mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
- hicn_face_ip4_get_key (&(face_ip->remote_addr.ip4), face->shared.sw_if,
- &key);
- mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key);
+ hicn_face_ip_input_faces_t * in_faces_vec = hicn_face_ip4_get_vec(&(face_ip->local_addr.ip4), face->shared.sw_if,
+ &hicn_face_ip_local_hashtb);
+ if (in_faces_vec != NULL)
+ {
+ hicn_face_ip_vec_t * vec = pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id);
+ u32 index_face = vec_search(*vec, face_id);
+ vec_del1(*vec, index_face);
+
+ if (vec_len(*vec) == 0)
+ {
+ pool_put_index(hicn_vec_pool, in_faces_vec->vec_id);
+ mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
+ vec_free(*vec);
+ }
+ else
+ {
+ /* Check if the face we are deleting is the preferred one. */
+ /* If so, repleace with another. */
+ if (in_faces_vec->face_id == face_id)
+ {
+ in_faces_vec->face_id = (*vec)[0];
+ }
+ }
+ hicn_face_ip4_get_key (&(face_ip->remote_addr.ip4), face->shared.sw_if,
+ &key);
+ mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key2);
+ }
}
else
{
hicn_face_ip6_get_key (&(face_ip->local_addr.ip6), face->shared.sw_if,
&key);
- mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
- hicn_face_ip6_get_key (&(face_ip->remote_addr.ip6), face->shared.sw_if,
- &key);
- mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key);
+
+ hicn_face_ip_input_faces_t * in_faces_vec = hicn_face_ip6_get_vec(&(face_ip->local_addr.ip6), face->shared.sw_if,
+ &hicn_face_ip_local_hashtb);
+ if (in_faces_vec != NULL)
+ {
+ hicn_face_ip_vec_t * vec = pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id);
+ u32 index_face = vec_search(*vec, face_id);
+ vec_del1(*vec, index_face);
+
+ if (vec_len(*vec) == 0)
+ {
+ pool_put(hicn_vec_pool, vec);
+ mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
+ vec_free(*vec);
+ }
+ else
+ {
+ /* Check if the face we are deleting is the preferred one. */
+ /* If so, repleace with another. */
+ if (in_faces_vec->face_id == face_id)
+ {
+ in_faces_vec->face_id = (*vec)[0];
+ }
+ }
+ hicn_face_ip6_get_key (&(face_ip->remote_addr.ip6), face->shared.sw_if,
+ &key);
+ mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key);
+ }
}
return hicn_face_del (face_id);
}
+/**
+ * @brief Helper for handling midchain adjacencies
+ */
+void face_midchain_fixup_t (vlib_main_t * vm,
+ struct ip_adjacency_t_ * adj,
+ vlib_buffer_t * b0,
+ const void *data) {
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0;
+};
-/*
- * Utility that adds a new face cache entry. For the moment we assume that
- * the ip_adjacency has already been set up.
+/**
+ * @brief Build a rewrite string for the face.
*/
-int
-hicn_face_ip_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr,
- int sw_if, hicn_face_id_t * pfaceid)
+static u8*
+face_build_rewrite_i (void)
{
- /* fib_protocol_t fib_type; */
- /* vnet_link_t link_type; */
- adj_index_t adj;
- dpo_proto_t dpo_proto;
+ /*
+ * passing the adj code a NULL rewrite means 'i don't have one cos
+ * t'other end is unresolved'. That's not the case here. For the mpls
+ * tunnel there are just no bytes of encap to apply in the adj. We'll impose
+ * the label stack once we choose a path. So return a zero length rewrite.
+ */
+ u8 *rewrite = NULL;
- /* Check if we found at least one ip address */
- if (ip46_address_is_zero (local_addr) || ip46_address_is_zero (remote_addr))
- return HICN_ERROR_FACE_NO_GLOBAL_IP;
+ vec_validate(rewrite, 0);
+ vec_reset_length(rewrite);
+ return (rewrite);
+}
+
+always_inline int
+hicn_face_ip_find_adj (const ip46_address_t * remote_addr,
+ int sw_if, adj_index_t * adj)
+{
fib_prefix_t fib_pfx;
fib_node_index_t fib_entry_index;
fib_prefix_from_ip46_addr (remote_addr, &fib_pfx);
fib_pfx.fp_len = ip46_address_is_ip4(remote_addr)? 32 : 128;
+ vnet_link_t link_type = ip46_address_is_ip4(&fib_pfx.fp_addr)? VNET_LINK_IP4 : VNET_LINK_IP6;
+ *adj = adj_nbr_find(fib_pfx.fp_proto, link_type, &fib_pfx.fp_addr, sw_if);
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PLUGIN_HI);
+ if (*adj == ADJ_INDEX_INVALID)
+ {
+ u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
+ HICN_FIB_TABLE,
+ FIB_SOURCE_PLUGIN_HI);
+
+ fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
+
+ if (fib_entry_index == (FIB_NODE_INDEX_INVALID))
+ return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
+
+ *adj = fib_entry_get_adj (fib_entry_index);
+ ip_adjacency_t * temp = NULL;
+ if (*adj != ~0)
+ temp = adj_get(*adj);
+
+ if (temp == NULL || temp->lookup_next_index <= IP_LOOKUP_NEXT_REWRITE)
+ {
+ if(sw_if != ~0)
+ *adj = adj_nbr_add_or_lock(fib_pfx.fp_proto, link_type, remote_addr, sw_if);
+ else
+ return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
+ }
+ else
+ {
+ adj_nbr_midchain_update_rewrite(*adj, &face_midchain_fixup_t, NULL, ADJ_FLAG_NONE, face_build_rewrite_i());
+ adj_midchain_delegate_stack(*adj, fib_index, &fib_pfx);
+ }
+ }
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
+ return HICN_ERROR_NONE;
+}
- adj = fib_entry_get_adj (fib_entry_index);
+/*
+ * Utility that adds a new face cache entry. For the moment we assume that
+ * the ip_adjacency has already been set up.
+ */
+int
+hicn_face_ip_add (const ip46_address_t * local_addr,
+ const ip46_address_t * remote_addr,
+ int sw_if, hicn_face_id_t * pfaceid,
+ u8 is_app_prod)
+{
+ dpo_proto_t dpo_proto;
- if (adj == ~0)
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
+ /* Check if we found at least one ip address */
+ if (ip46_address_is_zero (remote_addr))
+ return HICN_ERROR_FACE_NO_GLOBAL_IP;
hicn_face_flags_t flags = (hicn_face_flags_t) 0;
flags |= HICN_FACE_FLAGS_FACE;
@@ -160,17 +265,10 @@ hicn_face_ip_add (const ip46_address_t * local_addr,
if (ip46_address_is_ip4 (local_addr))
{
face =
- hicn_face_ip4_get (&(local_addr->ip4), sw_if,
- &hicn_face_ip_local_hashtb);
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face =
hicn_face_ip4_get (&(remote_addr->ip4), sw_if,
&hicn_face_ip_remote_hashtb);
- /* If remote matches the face is a iface */
+ /* If remote matches the face we need to check if it is an incomplete face */
if (face == NULL)
{
hicn_iface_ip_add (local_addr, remote_addr, sw_if, pfaceid);
@@ -181,31 +279,83 @@ hicn_face_ip_add (const ip46_address_t * local_addr,
*pfaceid = hicn_dpoi_get_index (face);
}
+ if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE))
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
hicn_face_ip_key_t key;
hicn_face_ip4_get_key (&(local_addr->ip4), sw_if, &key);
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) pfaceid, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip4_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP4;
+ hicn_face_ip_input_faces_t * in_faces =
+ hicn_face_ip4_get_vec (&(local_addr->ip4), sw_if,
+ &hicn_face_ip_local_hashtb);
+
+ if (in_faces == NULL)
+ {
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ hicn_face_ip_input_faces_t in_faces_temp;
+ hicn_face_ip_vec_t *vec;
+ pool_get(hicn_vec_pool, vec);
+ *vec = vec_new(hicn_face_ip_vec_t, 0);
+ u32 index = vec - hicn_vec_pool;
+ in_faces_temp.vec_id = index;
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip4_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP4;
+
+ in_faces_temp.face_id = *pfaceid;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) &in_faces_temp, 0);
+ }
+ else
+ {
+ hicn_face_ip_vec_t * vec = pool_elt_at_index(hicn_vec_pool, in_faces->vec_id);
+
+ /* */
+ if (vec_search(*vec, *pfaceid) != ~0)
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip4_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP4;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, 0);
+
+ /* If the face is an application producer face, we set it as the preferred incoming face. */
+ /* This is required to handle the CS separation, and the push api in a lightway*/
+ if (is_app_prod)
+ {
+ in_faces->face_id = *pfaceid;
+ }
+ }
}
else
{
face =
- hicn_face_ip6_get (&(local_addr->ip6), sw_if,
- &hicn_face_ip_local_hashtb);
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face =
hicn_face_ip6_get (&(remote_addr->ip6), sw_if,
&hicn_face_ip_remote_hashtb);
@@ -220,20 +370,79 @@ hicn_face_ip_add (const ip46_address_t * local_addr,
*pfaceid = hicn_dpoi_get_index (face);
}
+ if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE))
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
hicn_face_ip_key_t key;
hicn_face_ip6_get_key (&(local_addr->ip6), sw_if, &key);
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) pfaceid, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP6;
+ hicn_face_ip_input_faces_t * in_faces =
+ hicn_face_ip6_get_vec (&(local_addr->ip6), sw_if,
+ &hicn_face_ip_local_hashtb);
+
+ if (in_faces == NULL)
+ {
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ hicn_face_ip_input_faces_t in_faces_temp;
+ hicn_face_ip_vec_t *vec;
+ pool_get(hicn_vec_pool, vec);
+ vec_alloc(*vec, 1);
+ u32 index = vec - hicn_vec_pool;
+ in_faces_temp.vec_id = index;
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip6_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP6;
+
+ in_faces_temp.face_id = *pfaceid;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) &in_faces_temp, 0);
+ }
+ else
+ {
+ hicn_face_ip_vec_t *vec = pool_elt_at_index(hicn_vec_pool, in_faces->vec_id);
+
+ /* */
+ if (vec_search(*vec, *pfaceid) != ~0)
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip6_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP6;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, 0);
+
+ /* If the face is an application producer face, we set it as the preferred incoming face. */
+ /* This is required to handle the CS separation, and the push api in a lightway*/
+ if (is_app_prod)
+ {
+ in_faces->face_id = *pfaceid;
+ }
+ }
}
retx_t *retx = vlib_process_signal_event_data (vlib_get_main (),
diff --git a/hicn-plugin/src/faces/ip/face_ip.h b/hicn-plugin/src/faces/ip/face_ip.h
index 852106b70..0491af506 100644
--- a/hicn-plugin/src/faces/ip/face_ip.h
+++ b/hicn-plugin/src/faces/ip/face_ip.h
@@ -43,6 +43,24 @@ typedef struct hicn_ip_face_t_
} hicn_face_ip_t;
+/**
+ * @bried vector of faces used to collect faces having the same local address
+ *
+ */
+typedef hicn_face_id_t * hicn_face_ip_vec_t;
+
+typedef struct hicn_ip_input_faces_s_
+{
+ /* Vector of all possible input faces */
+ u32 vec_id;
+
+ /* Preferred face. If an prod_app face is in the vector it will be the preferred one. */
+ /* It's not possible to have multiple prod_app face in the same vector, they would have */
+ /* the same local address. Every prod_app face is a point-to-point face between the forwarder */
+ /* and the application. */
+ hicn_face_id_t face_id;
+
+} hicn_face_ip_input_faces_t;
/**
* Hash tables that indexes a face by local address. For fast lookup when an
@@ -57,6 +75,11 @@ extern mhash_t hicn_face_ip_local_hashtb;
extern mhash_t hicn_face_ip_remote_hashtb;
/**
+ * Pool containing the vector of possible incoming faces.
+ */
+extern hicn_face_ip_vec_t * hicn_vec_pool;
+
+/**
* Key definition for the mhash table. An ip face is uniquely identified by ip
* address and the interface id. The ip address can correspond to the remote ip
* address of the next hicn hop, or to the local address of the receiving
@@ -129,6 +152,42 @@ hicn_face_ip4_get (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb)
}
/**
+ * @brief Get the vector of faces from the ip v4 address. Does not add any lock.
+ *
+ * @param addr Ip v4 address used to create the key for the hash table.
+ * @param sw_if Software interface id used to create the key for the hash table.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
+ *
+ * @result Pointer to the face.
+ */
+always_inline hicn_face_ip_input_faces_t *
+hicn_face_ip4_get_vec (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb)
+{
+ hicn_face_ip_key_t key;
+
+ hicn_face_ip4_get_key (addr, sw_if, &key);
+ return (hicn_face_ip_input_faces_t *) mhash_get (hashtb,&key);
+}
+
+/**
+ * @brief Get the vector of faces from the ip v6 address. Does not add any lock.
+ *
+ * @param addr Ip v6 address used to create the key for the hash table.
+ * @param sw_if Software interface id used to create the key for the hash table.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
+ *
+ * @result Pointer to the face.
+ */
+always_inline hicn_face_ip_input_faces_t *
+hicn_face_ip6_get_vec (const ip6_address_t * addr, u32 sw_if, mhash_t * hashtb)
+{
+ hicn_face_ip_key_t key;
+
+ hicn_face_ip6_get_key (addr, sw_if, &key);
+ return (hicn_face_ip_input_faces_t *) mhash_get (hashtb,&key);
+}
+
+/**
* @brief Get the dpoi from the ip v6 address. Does not add any lock.
*
* @param addr Ip v6 address used to create the key for the hash table.
@@ -158,12 +217,13 @@ hicn_face_ip6_get (const ip6_address_t * addr, u32 sw_if, mhash_t * hashtb)
* @param sw_if interface associated to the face
* @param is_app_face Boolean to set the face as an application face
* @param pfaceid Pointer to return the face id
+ * @param is_app_prod if HICN_FACE_FLAGS_APPFACE_PROD the face is a local application face, all other values are ignored
* @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
* reachable ip address, otherwise HICN_ERROR_NONE
*/
int hicn_face_ip_add (const ip46_address_t * local_addr,
const ip46_address_t * remote_addr,
- int swif, hicn_face_id_t * pfaceid);
+ int swif, hicn_face_id_t * pfaceid, u8 is_app_prod);
/**
* @brief Create a new incomplete face ip. (Meant to be used by the data plane)
diff --git a/hicn-plugin/src/faces/ip/face_ip_cli.c b/hicn-plugin/src/faces/ip/face_ip_cli.c
index 760768be1..4c4986f97 100644
--- a/hicn-plugin/src/faces/ip/face_ip_cli.c
+++ b/hicn-plugin/src/faces/ip/face_ip_cli.c
@@ -158,7 +158,7 @@ hicn_face_ip_cli_set_command_fn (vlib_main_t * vm,
}
}
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &face_id);
+ rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &face_id, 0);
if (rv == HICN_ERROR_NONE)
{
@@ -194,7 +194,7 @@ hicn_face_ip_cli_set_command_fn (vlib_main_t * vm,
VLIB_CLI_COMMAND (hicn_face_ip_cli_set_command, static) =
{
.path = "hicn face ip",
- .short_help = "hicn face ip {add local <src_address> remote <dst_address> intfc <sw_if>} | {del id <face_id>}",
+ .short_help = "hicn face ip {add [local <src_address>] remote <dst_address> intfc <sw_if>} | {del id <face_id>}",
.function = hicn_face_ip_cli_set_command_fn,
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.c b/hicn-plugin/src/faces/ip/face_ip_node.c
index 6592dc065..3f1f6a0d0 100644
--- a/hicn-plugin/src/faces/ip/face_ip_node.c
+++ b/hicn-plugin/src/faces/ip/face_ip_node.c
@@ -144,6 +144,7 @@ typedef enum
\
ret = LOCK_FROM_LOCAL_IP##ipv \
(&(hicnb0->face_dpo_id), \
+ &(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
&(ip_hdr->dst_address), \
vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
@@ -232,12 +233,14 @@ typedef enum
\
ret0 = LOCK_FROM_LOCAL_IP##ipv \
(&(hicnb0->face_dpo_id), \
+ &(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
&(ip_hdr0->dst_address), \
vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
\
ret1 = LOCK_FROM_LOCAL_IP##ipv \
(&(hicnb1->face_dpo_id), \
+ &(hicnb1->in_faces_vec_id), \
&hicnb1->flags, \
&(ip_hdr1->dst_address), \
vnet_buffer (b1)->sw_if_index[VLIB_RX]); \
diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h
index 87628ba53..1b57ce9e2 100644
--- a/hicn-plugin/src/hicn.h
+++ b/hicn-plugin/src/hicn.h
@@ -64,8 +64,9 @@ typedef struct
u8 dpo_ctx_id; /* used for data path */
u8 vft_id; /* " */
- dpo_id_t face_dpo_id; /* ingress face ,sizeof(iface_dpo_id)
- * <= sizeof(u64) */
+ dpo_id_t face_dpo_id; /* ingress iface, sizeof(dpo_id_t)
+ * <= sizeof(u64) */
+ u32 in_faces_vec_id; /* vector of possible input face for a data packet */
hicn_type_t type;
} hicn_buffer_t;
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c
index 9bca748e6..f8933206d 100644
--- a/hicn-plugin/src/hicn_api.c
+++ b/hicn-plugin/src/hicn_api.c
@@ -249,7 +249,7 @@ vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp)
}
if (rv == HICN_ERROR_NONE)
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &faceid);
+ rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &faceid, 0);
else
faceid = HICN_FACE_NULL;
diff --git a/hicn-plugin/src/mgmt.c b/hicn-plugin/src/mgmt.c
index b992ba15c..cfeef6cb6 100644
--- a/hicn-plugin/src/mgmt.c
+++ b/hicn-plugin/src/mgmt.c
@@ -66,10 +66,6 @@ hicn_mgmt_node_stats_get (vl_api_hicn_api_node_stats_get_reply_t * rmp)
rmp->pkts_processed +=
clib_host_to_net_u64 (em->counters[node_cntr_base_idx +
HICNFWD_ERROR_PROCESSED]);
- n =
- vlib_get_node (this_vlib_main,
- hicn_data_pcslookup_node.index);
- node_cntr_base_idx = n->error_heap_index;
rmp->pkts_data_count +=
clib_host_to_net_u64 (em->counters[node_cntr_base_idx +
HICNFWD_ERROR_DATAS]);
diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h
index 28f9c3c37..c7e8a4b59 100644
--- a/hicn-plugin/src/pcs.h
+++ b/hicn-plugin/src/pcs.h
@@ -685,9 +685,9 @@ hicn_pcs_pit_delete (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t ** pcs_entryp,
const hicn_dpo_vft_t * dpo_vft, dpo_id_t * hicn_dpo_id)
{
hash_entry->locks--;
- pitcs->pcs_pit_count--;
if (hash_entry->locks == 0)
{
+ pitcs->pcs_pit_count--;
hicn_pcs_delete_internal
(pitcs, pcs_entryp, hash_entry, node, vm, dpo_vft, hicn_dpo_id);
}
diff --git a/lib/src/compat.c b/lib/src/compat.c
index d76e17a6d..68f761ac0 100644
--- a/lib/src/compat.c
+++ b/lib/src/compat.c
@@ -344,7 +344,7 @@ hicn_packet_get_locator (hicn_format_t format, const hicn_header_t * h,
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
}
- memcpy (prefix->address.buffer, locator, ip_prefix_len(prefix));
+ memcpy (prefix->address.buffer, locator, ip_address_len(&prefix->address, prefix->family));
return HICN_LIB_ERROR_NONE;
}
@@ -370,7 +370,7 @@ hicn_packet_set_locator (hicn_format_t format, hicn_header_t * h,
return HICN_LIB_ERROR_INVALID_PARAMETER;
}
- memcpy (locator, prefix->address.buffer, ip_prefix_len(prefix));
+ memcpy (locator, prefix->address.buffer, ip_address_len(&prefix->address, prefix->family));
return HICN_LIB_ERROR_NONE;
}
diff --git a/lib/src/name.c b/lib/src/name.c
index 1f1051522..a19971d49 100644
--- a/lib/src/name.c
+++ b/lib/src/name.c
@@ -95,7 +95,8 @@ hicn_name_create_from_prefix (const ip_prefix_t * prefix, u32 id,
return HICN_LIB_ERROR_NOT_IMPLEMENTED;
}
- memcpy (name->buffer, prefix->address.buffer, ip_prefix_len (prefix));
+ memcpy (name->buffer, prefix->address.buffer,
+ ip_address_len(&prefix->address, prefix->family));
*(u32 *) (name->buffer + name->len) = id;
return HICN_LIB_ERROR_NONE;
diff --git a/libtransport/src/hicn/transport/core/forwarder_interface.h b/libtransport/src/hicn/transport/core/forwarder_interface.h
index 6bcdaafc1..a89ed8a3c 100644
--- a/libtransport/src/hicn/transport/core/forwarder_interface.h
+++ b/libtransport/src/hicn/transport/core/forwarder_interface.h
@@ -50,7 +50,9 @@ class ForwarderInterface {
output_interface_(""),
content_store_reserved_(standard_cs_reserved) {
inet_address_.family = AF_INET;
+ inet_address_.len = IPV4_ADDR_LEN;
inet6_address_.family = AF_INET6;
+ inet6_address_.len = IPV6_ADDR_LEN;
}
public:
diff --git a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc
index 446b9ef8e..740f9f77c 100644
--- a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc
+++ b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.cc
@@ -32,8 +32,8 @@
#define HICN_MAX_DATA_SEQ 0xefffffff
//slow production rate param
-#define MIN_PRODUCTION_RATE 8000 // in bytes per sec. this value is computed
- // through experiments
+#define MIN_PRODUCTION_RATE 10 // in pacekts per sec. this value is computed
+ // through experiments
#define LIFETIME_FRACTION 0.5
// NACK HEADER
@@ -63,15 +63,14 @@ RTCProducerSocket::RTCProducerSocket(asio::io_service &io_service)
bytesProductionRate_(INIT_PACKET_PRODUCTION_RATE * 1400),
packetsProductionRate_(INIT_PACKET_PRODUCTION_RATE),
perSecondFactor_(MILLI_IN_A_SEC / STATS_INTERVAL_DURATION),
- timer_on_(false),
- active_(false) {
- lastStats_ = std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count();
+ timer_on_(false){
srand((unsigned int)time(NULL));
prodLabel_ = ((rand() % 255) << 24UL);
interests_cache_timer_ = std::make_unique<asio::steady_timer>(
this->getIoService());
+ round_timer_ = std::make_unique<asio::steady_timer>(
+ this->getIoService());
+ scheduleRoundTimer();
}
RTCProducerSocket::RTCProducerSocket()
@@ -82,14 +81,14 @@ RTCProducerSocket::RTCProducerSocket()
bytesProductionRate_(INIT_PACKET_PRODUCTION_RATE * 1400),
packetsProductionRate_(INIT_PACKET_PRODUCTION_RATE),
perSecondFactor_(MILLI_IN_A_SEC / STATS_INTERVAL_DURATION),
- active_(false) {
- lastStats_ = std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count();
+ timer_on_(false){
srand((unsigned int)time(NULL));
prodLabel_ = ((rand() % 255) << 24UL);
interests_cache_timer_ = std::make_unique<asio::steady_timer>(
this->getIoService());
+ round_timer_ = std::make_unique<asio::steady_timer>(
+ this->getIoService());
+ scheduleRoundTimer();
}
RTCProducerSocket::~RTCProducerSocket() {}
@@ -112,18 +111,22 @@ void RTCProducerSocket::registerPrefix(const Prefix &producer_namespace) {
}
}
-void RTCProducerSocket::updateStats(uint32_t packet_size, uint64_t now) {
- producedBytes_ += packet_size;
- producedPackets_++;
- uint64_t duration = now - lastStats_;
- if (duration >= STATS_INTERVAL_DURATION) {
- lastStats_ = now;
- bytesProductionRate_ = producedBytes_ * perSecondFactor_;
- packetsProductionRate_ = producedPackets_ * perSecondFactor_;
- if (packetsProductionRate_.load() == 0) packetsProductionRate_ = 1;
- producedBytes_ = 0;
- producedPackets_ = 0;
- }
+void RTCProducerSocket::scheduleRoundTimer(){
+ round_timer_->expires_from_now(
+ std::chrono::milliseconds(STATS_INTERVAL_DURATION));
+ round_timer_->async_wait([this](std::error_code ec) {
+ if (ec) return;
+ updateStats();
+ });
+}
+
+void RTCProducerSocket::updateStats() {
+ bytesProductionRate_ = producedBytes_.load() * perSecondFactor_;
+ packetsProductionRate_ = producedPackets_.load() * perSecondFactor_;
+ if (packetsProductionRate_.load() == 0) packetsProductionRate_ = 1;
+ producedBytes_ = 0;
+ producedPackets_ = 0;
+ scheduleRoundTimer();
}
void RTCProducerSocket::produce(std::unique_ptr<utils::MemBuf> &&buffer) {
@@ -142,13 +145,8 @@ void RTCProducerSocket::produce(std::unique_ptr<utils::MemBuf> &&buffer) {
std::chrono::steady_clock::now().time_since_epoch())
.count();
- {
- utils::SpinLock::Acquire locked(lock_);
- active_ = true;
- lastProduced_ = now;
- }
-
- updateStats((uint32_t)(buffer_size + headerSize_ + TIMESTAMP_LEN), now);
+ producedBytes_ += (uint32_t)(buffer_size + headerSize_ + TIMESTAMP_LEN);
+ producedPackets_++;
ContentObject content_object(flowName_.setSuffix(currentSeg_));
@@ -183,6 +181,7 @@ void RTCProducerSocket::produce(std::unique_ptr<utils::MemBuf> &&buffer) {
break;
}
}
+ seqs_map_.erase(it_seqs);
}
}
@@ -201,22 +200,14 @@ void RTCProducerSocket::onInterest(Interest::Ptr &&interest) {
std::chrono::steady_clock::now().time_since_epoch())
.count();
- bool isActive;
- {
- utils::SpinLock::Acquire locked(lock_);
- isActive = active_;
- if (isActive) {
- if ((now - lastProduced_) > INACTIVE_TIME) {
- // socket is inactive
- active_ = false;
- isActive = false;
- }
- }
+ if(interestSeg > HICN_MAX_DATA_SEQ){
+ sendNack(interestSeg);
+ return;
}
// if the production rate is less than MIN_PRODUCTION_RATE we put the
// interest in a queue, otherwise we handle it in the usual way
- if(bytesProductionRate_ < MIN_PRODUCTION_RATE){
+ if(packetsProductionRate_.load() < MIN_PRODUCTION_RATE && interestSeg >= currentSeg_){
utils::SpinLock::Acquire locked(interests_cache_lock_);
@@ -258,39 +249,29 @@ void RTCProducerSocket::onInterest(Interest::Ptr &&interest) {
if(!timer_on_){
//set timeout
timer_on_ = true;
- scheduleTimer(timers_map_.begin()->first - now);
+ scheduleCacheTimer(timers_map_.begin()->first - now);
} else {
//re-schedule the timer because a new interest will expires sooner
if(next_timer > timers_map_.begin()->first){
interests_cache_timer_->cancel();
- scheduleTimer(timers_map_.begin()->first - now);
+ scheduleCacheTimer(timers_map_.begin()->first - now);
}
}
return;
}
- if(interestSeg > HICN_MAX_DATA_SEQ){
- sendNack(interestSeg, isActive);
- return;
- }
-
- if (TRANSPORT_EXPECT_FALSE(!isActive)) {
- sendNack(interestSeg, false);
- return;
- }
-
uint32_t max_gap = (uint32_t)floor(
(double)((double)((double)lifetime * INTEREST_LIFETIME_REDUCTION_FACTOR /
1000.0) *
(double)packetsProductionRate_.load()));
if (interestSeg < currentSeg_ || interestSeg > (max_gap + currentSeg_)) {
- sendNack(interestSeg, true);
+ sendNack(interestSeg);
}
// else drop packet
}
-void RTCProducerSocket::scheduleTimer(uint64_t wait){
+void RTCProducerSocket::scheduleCacheTimer(uint64_t wait){
interests_cache_timer_->expires_from_now(
std::chrono::milliseconds(wait));
interests_cache_timer_->async_wait([this](std::error_code ec) {
@@ -310,7 +291,7 @@ void RTCProducerSocket::interestCacheTimer(){
uint64_t expire = it_timers->first;
if(expire <= now){
uint32_t seq = it_timers->second;
- sendNack(seq, active_);
+ sendNack(seq);
//remove the interest from the other map
seqs_map_.erase(seq);
it_timers = timers_map_.erase(it_timers);
@@ -323,11 +304,11 @@ void RTCProducerSocket::interestCacheTimer(){
timer_on_ = false;
}else{
timer_on_ = true;
- scheduleTimer(timers_map_.begin()->first - now);
+ scheduleCacheTimer(timers_map_.begin()->first - now);
}
}
-void RTCProducerSocket::sendNack(uint32_t sequence, bool isActive) {
+void RTCProducerSocket::sendNack(uint32_t sequence) {
auto nack_payload = utils::MemBuf::create(NACK_HEADER_SIZE);
nack_payload->append(NACK_HEADER_SIZE);
ContentObject nack;
@@ -338,11 +319,7 @@ void RTCProducerSocket::sendNack(uint32_t sequence, bool isActive) {
uint32_t *payload_ptr = (uint32_t *)nack.getPayload()->data();
*payload_ptr = currentSeg_;
- if (isActive) {
- *(++payload_ptr) = bytesProductionRate_;
- } else {
- *(++payload_ptr) = 0;
- }
+ *(++payload_ptr) = bytesProductionRate_.load();
nack.setLifetime(0);
nack.setPathLabel(prodLabel_);
diff --git a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h
index aa67f1a29..a2540ceef 100644
--- a/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h
+++ b/libtransport/src/hicn/transport/interfaces/rtc_socket_producer.h
@@ -41,21 +41,23 @@ class RTCProducerSocket : public ProducerSocket {
void onInterest(Interest::Ptr &&interest) override;
private:
- void sendNack(uint32_t sequence, bool isActive);
- void updateStats(uint32_t packet_size, uint64_t now);
- void scheduleTimer(uint64_t wait);
+ void sendNack(uint32_t sequence);
+ void updateStats();
+ void scheduleCacheTimer(uint64_t wait);
+ void scheduleRoundTimer();
void interestCacheTimer();
uint32_t currentSeg_;
uint32_t prodLabel_;
uint16_t headerSize_;
Name flowName_;
- uint32_t producedBytes_;
- uint32_t producedPackets_;
- uint32_t bytesProductionRate_;
+ std::atomic<uint32_t> producedBytes_;
+ std::atomic<uint32_t> producedPackets_;
+ std::atomic<uint32_t> bytesProductionRate_;
std::atomic<uint32_t> packetsProductionRate_;
uint32_t perSecondFactor_;
- uint64_t lastStats_;
+
+ std::unique_ptr<asio::steady_timer> round_timer_;
// cache for the received interests
// this map maps the expiration time of an interest to
@@ -70,10 +72,6 @@ class RTCProducerSocket : public ProducerSocket {
bool timer_on_;
std::unique_ptr<asio::steady_timer> interests_cache_timer_;
utils::SpinLock interests_cache_lock_;
-
- uint64_t lastProduced_;
- bool active_;
- utils::SpinLock lock_;
};
} // namespace interface
diff --git a/libtransport/src/hicn/transport/protocols/rtc.cc b/libtransport/src/hicn/transport/protocols/rtc.cc
index 4104d8883..accd98495 100644
--- a/libtransport/src/hicn/transport/protocols/rtc.cc
+++ b/libtransport/src/hicn/transport/protocols/rtc.cc
@@ -31,10 +31,8 @@ RTCTransportProtocol::RTCTransportProtocol(
inflightInterests_(1 << default_values::log_2_default_buffer_size),
modMask_((1 << default_values::log_2_default_buffer_size) - 1) {
icnet_socket->getSocketOption(PORTAL, portal_);
- nack_timer_ = std::make_unique<asio::steady_timer>(portal_->getIoService());
rtx_timer_ = std::make_unique<asio::steady_timer>(portal_->getIoService());
probe_timer_ = std::make_unique<asio::steady_timer>(portal_->getIoService());
- nack_timer_used_ = false;
reset();
}
@@ -92,7 +90,6 @@ void RTCTransportProtocol::reset() {
highestReceived_ = 0;
firstSequenceInRound_ = 0;
- nack_timer_used_ = false;
rtx_timer_used_ = false;
for(int i = 0; i < (1 << default_values::log_2_default_buffer_size); i++){
inflightInterests_[i] = {0};
@@ -673,36 +670,6 @@ void RTCTransportProtocol::onTimeout(Interest::Ptr &&interest) {
scheduleNextInterests();
}
-bool RTCTransportProtocol::checkIfProducerIsActive(
- const ContentObject &content_object) {
- uint32_t *payload = (uint32_t *)content_object.getPayload()->data();
- uint32_t productionSeg = *payload;
- uint32_t productionRate = *(++payload);
-
- if (productionRate == 0) {
- // the producer socket is not active
- // in this case we consider only the first nack
- if (nack_timer_used_) {
- return false;
- }
-
- nack_timer_used_ = true;
- // actualSegment_ should be the one in the nack, which will be the next in
- // production
- actualSegment_ = productionSeg;
- // all the rest (win size should not change)
- // we wait a bit before pull the socket again
- nack_timer_->expires_from_now(std::chrono::milliseconds(500));
- nack_timer_->async_wait([this](std::error_code ec) {
- if (ec) return;
- nack_timer_used_ = false;
- scheduleNextInterests();
- });
- return false;
- }
- return true;
-}
-
bool RTCTransportProtocol::onNack(const ContentObject &content_object, bool rtx) {
uint32_t *payload = (uint32_t *)content_object.getPayload()->data();
uint32_t productionSeg = *payload;
@@ -719,7 +686,7 @@ bool RTCTransportProtocol::onNack(const ContentObject &content_object, bool rtx)
if (productionSeg > nackSegment) {
// we are asking for stuff produced in the past
- actualSegment_ = max(productionSeg + 1, actualSegment_) % HICN_MIN_PROBE_SEQ;
+ actualSegment_ = max(productionSeg, actualSegment_) % HICN_MIN_PROBE_SEQ;
if(!rtx) {
if (currentState_ == HICN_RTC_NORMAL_STATE) {
@@ -756,7 +723,11 @@ bool RTCTransportProtocol::onNack(const ContentObject &content_object, bool rtx)
currentState_ = HICN_RTC_NORMAL_STATE;
}
}
- } // equal should not happen
+ } else {
+ //we are asking the right thing, but the producer is slow
+ //keep doing the same until the packet is produced
+ actualSegment_ = productionSeg % HICN_MIN_PROBE_SEQ;
+ }
return old_nack;
}
@@ -771,7 +742,6 @@ void RTCTransportProtocol::onContentObject(
uint32_t payload_size = (uint32_t)payload->length();
uint32_t segmentNumber = content_object->getName().getSuffix();
uint32_t pkt = segmentNumber & modMask_;
- bool schedule_next_interest = true;
ConsumerContentObjectCallback *callback_content_object = nullptr;
socket_->getSocketOption(ConsumerCallbacksOptions::CONTENT_OBJECT_INPUT,
@@ -802,25 +772,19 @@ void RTCTransportProtocol::onContentObject(
}
if (payload_size == HICN_NACK_HEADER_SIZE) {
- schedule_next_interest = checkIfProducerIsActive(*content_object);
-
if (inflightInterests_[pkt].state == sent_) {
inflightInterestsCount_--;
}
- // if checkIfProducerIsActive returns false, we did all we need to do
- // inside that function, no need to call onNack
bool old_nack = false;
- if (schedule_next_interest){
- if (interestRetransmissions_.find(segmentNumber) ==
+ if (interestRetransmissions_.find(segmentNumber) ==
interestRetransmissions_.end()){
- //this is not a retransmitted packet
- old_nack = onNack(*content_object, false);
- updateDelayStats(*content_object);
- } else {
- old_nack = onNack(*content_object, true);
- }
+ //this is not a retransmitted packet
+ old_nack = onNack(*content_object, false);
+ updateDelayStats(*content_object);
+ } else {
+ old_nack = onNack(*content_object, true);
}
//the nacked_ state is used only to avoid to decrease inflightInterestsCount_
@@ -870,9 +834,7 @@ void RTCTransportProtocol::onContentObject(
interestRetransmissions_.erase(segmentNumber);
- if (schedule_next_interest) {
- scheduleNextInterests();
- }
+ scheduleNextInterests();
}
void RTCTransportProtocol::returnContentToApplication(
diff --git a/libtransport/src/hicn/transport/protocols/rtc.h b/libtransport/src/hicn/transport/protocols/rtc.h
index 4ebae2b90..509f11361 100644
--- a/libtransport/src/hicn/transport/protocols/rtc.h
+++ b/libtransport/src/hicn/transport/protocols/rtc.h
@@ -128,10 +128,6 @@ class RTCTransportProtocol : public TransportProtocol, public Reassembly {
void checkRtx();
void probeRtt();
void onTimeout(Interest::Ptr &&interest) override;
- // checkIfProducerIsActive: return true if we need to schedule an interest
- // immediatly after, false otherwise (this happens when the producer socket
- // is not active)
- bool checkIfProducerIsActive(const ContentObject &content_object);
bool onNack(const ContentObject &content_object, bool rtx);
void onContentObject(Interest::Ptr &&interest,
ContentObject::Ptr &&content_object) override;
@@ -155,6 +151,7 @@ class RTCTransportProtocol : public TransportProtocol, public Reassembly {
uint32_t inflightInterestsCount_;
//map seq to rtx
std::map<uint32_t, uint8_t> interestRetransmissions_;
+ bool rtx_timer_used_;
std::unique_ptr<asio::steady_timer> rtx_timer_;
std::vector<sentInterest> inflightInterests_;
uint32_t lastSegNacked_; //indicates the segment id in the last received
@@ -163,12 +160,6 @@ class RTCTransportProtocol : public TransportProtocol, public Reassembly {
uint32_t lastReceived_; //segment of the last content object received
//indicates the base of the window on the client
- bool nack_timer_used_;
- bool rtx_timer_used_;
- std::unique_ptr<asio::steady_timer> nack_timer_; // timer used to schedule
- // a nack retransmission in case
- // of inactive prod socket
-
//rtt probes
//the RTC transport tends to overestimate the RTT
//du to the production time on the server side
diff --git a/utils/src/hiperf.cc b/utils/src/hiperf.cc
index 3e39990a4..ccb22779b 100644
--- a/utils/src/hiperf.cc
+++ b/utils/src/hiperf.cc
@@ -67,7 +67,8 @@ struct ClientConfiguration {
download_size(0),
report_interval_milliseconds_(1000),
rtc_(false),
- test_mode_(false) {}
+ test_mode_(false),
+ interest_lifetime_(1000) {}
Name name;
bool verify;
@@ -82,6 +83,7 @@ struct ClientConfiguration {
TransportProtocolAlgorithms transport_protocol_;
bool rtc_;
bool test_mode_;
+ uint32_t interest_lifetime_;
};
/**
@@ -325,6 +327,7 @@ class HIperfClient {
}
consumer_socket_ = std::make_unique<ConsumerSocket>(transport_protocol);
+ consumer_socket_->setSocketOption(GeneralTransportOptions::INTEREST_LIFETIME, configuration_.interest_lifetime_);
#if defined(DEBUG) && defined(__linux__)
std::shared_ptr<transport::BasePortal> portal;
@@ -509,11 +512,7 @@ class HIperfClient {
void readBufferAvailable(
std::unique_ptr<utils::MemBuf> &&buffer) noexcept override {
- if (client_.configuration_.receive_buffer) {
- client_.configuration_.receive_buffer->prependChain(std::move(buffer));
- } else {
- client_.configuration_.receive_buffer = std::move(buffer);
- }
+ return;
}
size_t maxBufferSize() const override { return read_size; }
@@ -898,6 +897,8 @@ void usage() {
<< std::endl;
std::cerr << "-d <drop_factor_parameter> = RAAQM drop factor parameter"
<< std::endl;
+ std::cerr << "-L\t<interest lifetime>\t\t"
+ << "Set interest lifetime." << std::endl;
std::cerr << "-M = store the content downloaded"
"(default false)"
<< std::endl;
@@ -943,7 +944,7 @@ int main(int argc, char *argv[]) {
int opt;
#ifndef _WIN32
- while ((opt = getopt(argc, argv, "DSCf:b:d:W:RMc:vA:s:rmlk:y:p:hi:xB:It")) !=
+ while ((opt = getopt(argc, argv, "DSCf:b:d:W:RMc:vA:s:rmlk:y:p:hi:xB:ItL:")) !=
-1) {
switch (opt) {
// Common
@@ -956,7 +957,7 @@ int main(int argc, char *argv[]) {
break;
}
#else
- while ((opt = getopt(argc, argv, "SCf:b:d:W:RMc:vA:s:rmlk:y:p:hi:xB:t")) !=
+ while ((opt = getopt(argc, argv, "SCf:b:d:W:RMc:vA:s:rmlk:y:p:hi:xB:tL:")) !=
-1) {
switch (opt) {
#endif
@@ -1021,6 +1022,11 @@ int main(int argc, char *argv[]) {
options = 1;
break;
}
+ case 'L': {
+ client_configuration.interest_lifetime_ = std::stoul(optarg);
+ options = 1;
+ break;
+ }
// Server specific
case 'A': {
server_configuration.download_size = std::stoul(optarg);