summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2019-05-07 12:06:04 +0200
committerAlberto Compagno <acompagn+fdio@cisco.com>2019-05-07 12:06:04 +0200
commitcd48bbd9685f042a2f1f90678f8fa98a5175ea4d (patch)
tree8412a4f3d56c451250ccb4ea1b687d51ccbb214b
parent113e0af25e5a802eccac1fc4521f096a2e1bd199 (diff)
[HICN-189] In case the adj is not complete, we look if a better one exists and we follow the new adjacency. The adj in the face is updated accordingly.
Change-Id: Ieb5c02ee66146475d54ee99a77fc795c9bdf3130 Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com>
-rw-r--r--hicn-plugin/src/data_fwd.h16
-rw-r--r--hicn-plugin/src/data_fwd_node.c2
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_node.c37
-rw-r--r--hicn-plugin/src/faces/udp/dpo_udp.h61
-rw-r--r--hicn-plugin/src/faces/udp/face_udp.h104
-rw-r--r--hicn-plugin/src/faces/udp/face_udp_node.c49
6 files changed, 195 insertions, 74 deletions
diff --git a/hicn-plugin/src/data_fwd.h b/hicn-plugin/src/data_fwd.h
index 742bb2882..c001e5af5 100644
--- a/hicn-plugin/src/data_fwd.h
+++ b/hicn-plugin/src/data_fwd.h
@@ -95,18 +95,18 @@ vlib_buffer_clone_256_2 (vlib_main_t * vm, u32 src_buffer, u32 * buffers,
d->flags = s->flags | VLIB_BUFFER_NEXT_PRESENT;
d->flags &= ~VLIB_BUFFER_EXT_HDR_VALID;
d->trace_index = s->trace_index;
- clib_memcpy (d->opaque, s->opaque, sizeof (s->opaque));
- clib_memcpy (d->opaque2, s->opaque2, sizeof (s->opaque2));
- clib_memcpy (vlib_buffer_get_current (d), vlib_buffer_get_current (s),
- head_end_offset);
+ clib_memcpy_fast (d->opaque, s->opaque, sizeof (s->opaque));
+ clib_memcpy_fast (d->opaque2, s->opaque2, sizeof (s->opaque2));
+ clib_memcpy_fast (vlib_buffer_get_current (d),
+ vlib_buffer_get_current (s), head_end_offset);
d->next_buffer = src_buffer;
}
vlib_buffer_advance (s, head_end_offset);
- s->ref_count = n_buffers - 1;
+ s->ref_count = n_buffers;
while (s->flags & VLIB_BUFFER_NEXT_PRESENT)
{
s = vlib_get_buffer (vm, s->next_buffer);
- s->ref_count = n_buffers - 1;
+ s->ref_count = n_buffers;
}
return n_buffers;
@@ -166,7 +166,7 @@ vlib_buffer_clone2 (vlib_main_t * vm, u32 src_buffer, u32 * buffers,
*/
u8 tmp_ref_count = s->ref_count;
- s->ref_count = 0;
+ s->ref_count = 1;
/*
* The regular vlib_buffer_clone_256 does copy if we need to clone
* only one packet. While this is not a problem per se, it adds
@@ -178,7 +178,7 @@ vlib_buffer_clone2 (vlib_main_t * vm, u32 src_buffer, u32 * buffers,
(buffers + n_cloned),
n_buffers, head_end_offset);
- s->ref_count += tmp_ref_count;
+ s->ref_count += (tmp_ref_count - 1);
return n_cloned;
}
diff --git a/hicn-plugin/src/data_fwd_node.c b/hicn-plugin/src/data_fwd_node.c
index 0b8685ff2..fe4155958 100644
--- a/hicn-plugin/src/data_fwd_node.c
+++ b/hicn-plugin/src/data_fwd_node.c
@@ -389,6 +389,7 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
hicn_buffer_t *hicnb = hicn_get_buffer (b0);
+
/*
* Mark the buffer as smaller than TWO_CL. It will be stored as is in the CS, without excluding
* the hicn_header. Cloning is not possible, it will be copied.
@@ -546,7 +547,6 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
}
}
-
vec_free (header);
if (PREDICT_FALSE (!found))
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.c b/hicn-plugin/src/faces/ip/face_ip_node.c
index 8d0820604..109750de8 100644
--- a/hicn-plugin/src/faces/ip/face_ip_node.c
+++ b/hicn-plugin/src/faces/ip/face_ip_node.c
@@ -463,12 +463,10 @@ VLIB_REGISTER_NODE(hicn_face_ip6_input_node) =
static inline void
hicn_face_rewrite_interest (vlib_main_t * vm, vlib_buffer_t * b0,
- const hicn_face_t * face, u32 * next)
+ hicn_face_t * face, u32 * next)
{
ip_adjacency_t *adj = adj_get (face->shared.adj);
- /* We assume the ip adjacency has already the MAC/link layer address */
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
hicn_header_t *hicn = vlib_buffer_get_current (b0);
hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
@@ -479,14 +477,33 @@ hicn_face_rewrite_interest (vlib_main_t * vm, vlib_buffer_t * b0,
hicn_ops_vft[type.l1]->rewrite_interest (type, &hicn->protocol,
&ip_face->local_addr, &temp_addr);
- /* We rewrite the dst address to send an arp/neighbour discovert request */
- if (PREDICT_FALSE
- (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
- || adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN))
- hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
- &ip_face->remote_addr, &temp_addr,
- 0);
+ /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
+ * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
+ * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
+ */
+ if (PREDICT_FALSE (adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
+ {
+ fib_prefix_t fib_pfx;
+ fib_node_index_t fib_entry_index;
+ fib_prefix_from_ip46_addr (&ip_face->remote_addr, &fib_pfx);
+ fib_pfx.fp_len = 128;
+
+ 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);
+
+ face->shared.adj = fib_entry_get_adj (fib_entry_index);
+ adj = adj_get (face->shared.adj);
+
+ hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
+ &ip_face->remote_addr, &temp_addr,
+ 0);
+ }
+
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
*next = adj->lookup_next_index;
}
diff --git a/hicn-plugin/src/faces/udp/dpo_udp.h b/hicn-plugin/src/faces/udp/dpo_udp.h
index 3d74a1884..42b9864df 100644
--- a/hicn-plugin/src/faces/udp/dpo_udp.h
+++ b/hicn-plugin/src/faces/udp/dpo_udp.h
@@ -127,33 +127,10 @@ hicn_dpo_udp4_add_and_lock (dpo_id_t * dpo,
if (face == NULL)
{
- pool_get (hicn_dpoi_face_pool, face);
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip4.ip), &ip4_header_skl,
- sizeof (ip4_header_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.src_address), local_addr,
- sizeof (ip4_address_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.dst_address), remote_addr,
- sizeof (ip4_address_t));
-
- udp_face->hdrs.ip4.udp.src_port = local_port;
- udp_face->hdrs.ip4.udp.dst_port = remote_port;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 0;
- face->shared.sw_if = sw_if;
-
- hicn_face_udp_key_t key;
- hicn_face_udp4_get_key (local_addr, remote_addr, local_port,
- remote_port, &key);
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
+ hicn_face_id_t dpoi_index;
+ hicn_iface_udp4_add (local_addr, remote_addr, local_port, remote_port,
+ sw_if, &dpoi_index);
*hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
@@ -230,7 +207,7 @@ hicn_dpo_udp6_lock (dpo_id_t * dpo,
return HICN_ERROR_FACE_NOT_FOUND;
hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
+ dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
dpo->dpoi_next_node = ~0;
dpo_lock (dpo);
*hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
@@ -269,33 +246,9 @@ hicn_dpo_udp6_add_and_lock (dpo_id_t * dpo,
if (face == NULL)
{
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip6.ip), &ip6_header_skl,
- sizeof (ip6_header_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.src_address), local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.dst_address), remote_addr,
- sizeof (ip6_address_t));
-
- udp_face->hdrs.ip6.udp.src_port = local_port;
- udp_face->hdrs.ip6.udp.dst_port = remote_port;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 0;
- face->shared.sw_if = sw_if;
-
- hicn_face_udp_key_t key;
- hicn_face_udp6_get_key (local_addr, remote_addr, local_port,
- remote_port, &key);
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
+ hicn_face_id_t dpoi_index;
+ hicn_iface_udp6_add (local_addr, remote_addr, local_port, remote_port,
+ sw_if, &dpoi_index);
*hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
diff --git a/hicn-plugin/src/faces/udp/face_udp.h b/hicn-plugin/src/faces/udp/face_udp.h
index 8694bad5c..2bd420b55 100644
--- a/hicn-plugin/src/faces/udp/face_udp.h
+++ b/hicn-plugin/src/faces/udp/face_udp.h
@@ -207,6 +207,110 @@ int hicn_face_udp_add (const ip46_address_t * local_addr,
u16 remote_port, u32 swif, hicn_face_id_t * pfaceid);
/**
+ * @brief Create a new incomplete face udp. (Meant to be used by the data plane)
+ *
+ * @param local_addr Local ip v6 address of the face
+ * @param remote_addr Remote ip v6 address of the face
+ * @param sw_if interface associated to the face
+ * @param pfaceid Pointer to return the face id
+ * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
+ * reachable ip address, otherwise HICN_ERROR_NONE
+ */
+always_inline void
+hicn_iface_udp6_add (const ip6_address_t * local_addr,
+ const ip6_address_t * remote_addr, u16 local_port,
+ u16 remote_port, int sw_if, hicn_face_id_t * pfaceid)
+{
+ hicn_face_t *face;
+ pool_get (hicn_dpoi_face_pool, face);
+
+ hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
+
+ clib_memcpy (&(udp_face->hdrs.ip6.ip), &ip6_header_skl,
+ sizeof (ip6_header_t));
+ clib_memcpy (&(udp_face->hdrs.ip6.ip.src_address), local_addr,
+ sizeof (ip6_address_t));
+ clib_memcpy (&(udp_face->hdrs.ip6.ip.dst_address), remote_addr,
+ sizeof (ip6_address_t));
+
+ udp_face->hdrs.ip6.udp.src_port = local_port;
+ udp_face->hdrs.ip6.udp.dst_port = remote_port;
+
+ face->shared.adj = ADJ_INDEX_INVALID;
+ face->shared.pl_id = (u16) 0;
+ face->shared.face_type = hicn_face_udp_type;
+ face->shared.flags = HICN_FACE_FLAGS_IFACE;
+ face->shared.locks = 0;
+ face->shared.sw_if = sw_if;
+
+ hicn_face_udp_key_t key;
+ hicn_face_udp6_get_key (local_addr, remote_addr, local_port,
+ remote_port, &key);
+ *pfaceid = hicn_dpoi_get_index (face);
+
+ mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & pfaceid, 0);
+
+ for (int i = 0; i < HICN_N_COUNTER; i++)
+ {
+ vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
+ i);
+ vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
+ }
+}
+
+/**
+ * @brief Create a new incomplete face udp. (Meant to be used by the data plane)
+ *
+ * @param local_addr Local ip v4 address of the face
+ * @param remote_addr Remote ip v4 address of the face
+ * @param sw_if interface associated to the face
+ * @param pfaceid Pointer to return the face id
+ * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
+ * reachable ip address, otherwise HICN_ERROR_NONE
+ */
+always_inline void
+hicn_iface_udp4_add (const ip4_address_t * local_addr,
+ const ip4_address_t * remote_addr, u16 local_port,
+ u16 remote_port, int sw_if, hicn_face_id_t * pfaceid)
+{
+ hicn_face_t *face;
+ pool_get (hicn_dpoi_face_pool, face);
+
+ hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
+
+ clib_memcpy (&(udp_face->hdrs.ip4.ip), &ip4_header_skl,
+ sizeof (ip4_header_t));
+ clib_memcpy (&(udp_face->hdrs.ip4.ip.src_address), local_addr,
+ sizeof (ip4_address_t));
+ clib_memcpy (&(udp_face->hdrs.ip4.ip.dst_address), remote_addr,
+ sizeof (ip4_address_t));
+
+ udp_face->hdrs.ip4.udp.src_port = local_port;
+ udp_face->hdrs.ip4.udp.dst_port = remote_port;
+
+ face->shared.adj = ADJ_INDEX_INVALID;
+ face->shared.pl_id = (u16) 0;
+ face->shared.face_type = hicn_face_udp_type;
+ face->shared.flags = HICN_FACE_FLAGS_IFACE;
+ face->shared.locks = 0;
+ face->shared.sw_if = sw_if;
+
+ hicn_face_udp_key_t key;
+ hicn_face_udp4_get_key (local_addr, remote_addr, local_port,
+ remote_port, &key);
+ *pfaceid = hicn_dpoi_get_index (face);
+
+ mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & pfaceid, 0);
+
+ for (int i = 0; i < HICN_N_COUNTER; i++)
+ {
+ vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
+ i);
+ vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
+ }
+}
+
+/**
* @brief Delete an ip face
*
* @param face_id Id of the face to delete
diff --git a/hicn-plugin/src/faces/udp/face_udp_node.c b/hicn-plugin/src/faces/udp/face_udp_node.c
index df24c477f..184fea679 100644
--- a/hicn-plugin/src/faces/udp/face_udp_node.c
+++ b/hicn-plugin/src/faces/udp/face_udp_node.c
@@ -535,8 +535,31 @@ hicn_face_udp4_encap (vlib_main_t * vm,
length /* changed member */ );
ip0->checksum = sum0;
- vnet_buffer (outer_b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
+ /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
+ * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
+ * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
+ */
+ if (PREDICT_FALSE (adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
+ {
+ fib_prefix_t fib_pfx;
+ fib_node_index_t fib_entry_index;
+ ip46_address_t ip46 =
+ to_ip46 (0, (u8 *) & (face_udp->hdrs.ip4.ip.dst_address));
+ fib_prefix_from_ip46_addr (&ip46, &fib_pfx);
+ fib_pfx.fp_len = 32;
+
+ 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);
+ face->shared.adj = fib_entry_get_adj (fib_entry_index);
+
+ adj = adj_get (face->shared.adj);
+ }
+
+ vnet_buffer (outer_b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
*next = adj->lookup_next_index;
}
@@ -572,6 +595,30 @@ hicn_face_udp6_encap (vlib_main_t * vm,
if (udp0->checksum == 0)
udp0->checksum = 0xffff;
+ /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
+ * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
+ * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
+ */
+ if (PREDICT_FALSE (adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
+ {
+ fib_prefix_t fib_pfx;
+ fib_node_index_t fib_entry_index;
+ ip46_address_t ip46 =
+ to_ip46 (1, (u8 *) & (face_udp->hdrs.ip6.ip.dst_address));
+ fib_prefix_from_ip46_addr (&ip46, &fib_pfx);
+ fib_pfx.fp_len = 128;
+
+ 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);
+
+ face->shared.adj = fib_entry_get_adj (fib_entry_index);
+
+ adj = adj_get (face->shared.adj);
+ }
+
vnet_buffer (outer_b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
*next = adj->lookup_next_index;