aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin/src')
-rw-r--r--hicn-plugin/src/CMakeLists.txt3
-rw-r--r--hicn-plugin/src/cli.c90
-rw-r--r--hicn-plugin/src/data_fwd_node.c17
-rw-r--r--hicn-plugin/src/data_input_node.c8
-rw-r--r--hicn-plugin/src/data_pcslookup_node.c14
-rw-r--r--hicn-plugin/src/faces/app/face_prod_node.c150
-rw-r--r--hicn-plugin/src/faces/face.c6
-rw-r--r--hicn-plugin/src/faces/face.h69
-rw-r--r--hicn-plugin/src/faces/face_flags.h39
-rw-r--r--hicn-plugin/src/faces/face_node.c290
-rw-r--r--hicn-plugin/src/faces/iface_node.c316
-rw-r--r--hicn-plugin/src/hicn.c14
-rw-r--r--hicn-plugin/src/hicn.h58
-rw-r--r--hicn-plugin/src/hicn_buffer_flags.h35
-rw-r--r--hicn-plugin/src/interest_hitcs_node.c14
-rw-r--r--hicn-plugin/src/interest_hitpit.h4
-rw-r--r--hicn-plugin/src/interest_hitpit_node.c17
-rw-r--r--hicn-plugin/src/interest_pcslookup_node.c20
-rw-r--r--hicn-plugin/src/parser.h186
-rw-r--r--hicn-plugin/src/pg.c1340
-rw-r--r--hicn-plugin/src/pg.h142
-rw-r--r--hicn-plugin/src/pg_node.c1132
-rw-r--r--hicn-plugin/src/route.c10
-rw-r--r--hicn-plugin/src/strategy_node.c27
24 files changed, 2250 insertions, 1751 deletions
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt
index 2141ec596..e071b3b9d 100644
--- a/hicn-plugin/src/CMakeLists.txt
+++ b/hicn-plugin/src/CMakeLists.txt
@@ -59,6 +59,7 @@ set(HICN_PLUGIN_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod_node.c
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_app_cli.c
${CMAKE_CURRENT_SOURCE_DIR}/pg.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/pg_node.c
${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_mw.c
${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw.c
${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw_cli.c
@@ -83,6 +84,7 @@ set(HICN_PLUGIN_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/pcs.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn_api.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn_buffer_flags.h
${CMAKE_CURRENT_SOURCE_DIR}/state.h
${CMAKE_CURRENT_SOURCE_DIR}/infra.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn_msg_enum.h
@@ -99,6 +101,7 @@ set(HICN_PLUGIN_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/error.h
${CMAKE_CURRENT_SOURCE_DIR}/face_db.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/face.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_flags.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/inlines.h
diff --git a/hicn-plugin/src/cli.c b/hicn-plugin/src/cli.c
index cd45607ca..f743f6362 100644
--- a/hicn-plugin/src/cli.c
+++ b/hicn-plugin/src/cli.c
@@ -585,13 +585,15 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t *vm,
unformat_input_t *main_input,
vlib_cli_command_t *cmd)
{
- clib_error_t *cl_err;
- int rv = HICN_ERROR_NONE;
- hicnpg_server_main_t *pg_main = &hicnpg_server_main;
int payload_size = 1440;
u32 sw_if_index = ~0;
vnet_main_t *vnm = vnet_get_main ();
- fib_prefix_t *prefix = calloc (1, sizeof (fib_prefix_t));
+ fib_prefix_t prefix;
+ u32 hicnpg_server_index;
+ ip46_address_t locator;
+
+ locator.as_u64[0] = 0;
+ locator.as_u64[1] = 0;
/* Get a line of input. */
unformat_input_t _line_input, *line_input = &_line_input;
@@ -601,7 +603,7 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t *vm,
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (line_input, "name %U/%d", unformat_ip46_address,
- &prefix->fp_addr, IP46_TYPE_ANY, &prefix->fp_len))
+ &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
{
;
}
@@ -618,6 +620,11 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t *vm,
{
;
}
+ else if (unformat (line_input, "dst %U", unformat_ip46_address,
+ &locator, IP46_TYPE_ANY))
+ {
+ ;
+ }
else
{
return (clib_error_return (0, "Unknown input '%U'",
@@ -628,70 +635,45 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t *vm,
}
/* Attach our packet-gen node for ip4 udp local traffic */
- if ((prefix->fp_addr.ip6.as_u64[0] == (u64) 0 &&
- prefix->fp_addr.ip6.as_u64[1] == 0) ||
- payload_size == 0 || sw_if_index == ~0)
+ if ((prefix.fp_addr.ip6.as_u64[0] == (u64) 0 &&
+ prefix.fp_addr.ip6.as_u64[1] == 0) ||
+ payload_size == 0 || sw_if_index == ~0 ||
+ ip46_address_is_zero (&locator))
{
- return clib_error_return (0, "Error: must supply local port, payload "
+ return clib_error_return (0, "Error: must supply locator, payload "
"size and incoming hICN prefix");
}
// Remove bits that are out of the subnet
- if (ip46_address_is_ip4 (&prefix->fp_addr))
+ if (ip46_address_is_ip4 (&prefix.fp_addr))
{
ip4_address_t mask;
- ip4_preflen_to_mask (prefix->fp_len, &mask);
- prefix->fp_addr.ip4.as_u32 = prefix->fp_addr.ip4.as_u32 & mask.as_u32;
- prefix->fp_proto = FIB_PROTOCOL_IP4;
+ ip4_preflen_to_mask (prefix.fp_len, &mask);
+ prefix.fp_addr.ip4.as_u32 = prefix.fp_addr.ip4.as_u32 & mask.as_u32;
+ prefix.fp_proto = FIB_PROTOCOL_IP4;
}
else
{
ip6_address_t mask;
- ip6_preflen_to_mask (prefix->fp_len, &mask);
- prefix->fp_addr.ip6.as_u64[0] =
- prefix->fp_addr.ip6.as_u64[0] & mask.as_u64[0];
- prefix->fp_addr.ip6.as_u64[1] =
- prefix->fp_addr.ip6.as_u64[1] & mask.as_u64[1];
- prefix->fp_proto = FIB_PROTOCOL_IP6;
+ ip6_preflen_to_mask (prefix.fp_len, &mask);
+ prefix.fp_addr.ip6.as_u64[0] =
+ prefix.fp_addr.ip6.as_u64[0] & mask.as_u64[0];
+ prefix.fp_addr.ip6.as_u64[1] =
+ prefix.fp_addr.ip6.as_u64[1] & mask.as_u64[1];
+ prefix.fp_proto = FIB_PROTOCOL_IP6;
}
- /* Allocate the buffer with the actual content payload TLV */
- int n_buf = vlib_buffer_alloc (vm, &pg_main->pgen_svr_buffer_idx, 1);
-
- if (n_buf == 0)
+ fib_protocol_t dest_proto =
+ ip46_address_is_ip4 (&locator) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+ if (prefix.fp_proto != dest_proto)
{
- return (clib_error_return (0, "Impossible to allocate paylod buffer."));
+ return clib_error_return (0, "Error: prefix and locator must be of the "
+ "same protocol");
}
- vlib_buffer_t *rb = NULL;
- rb = vlib_get_buffer (vm, pg_main->pgen_svr_buffer_idx);
-
- pg_main->pgen_srv_hicn_name = prefix;
-
- /* Initialize the buffer data with zeros */
- memset (rb->data, 0, payload_size);
- rb->current_length = payload_size;
-
- vnet_feature_enable_disable ("ip4-unicast", "hicnpg-server", sw_if_index, 1,
- 0, 0);
- vnet_feature_enable_disable ("ip6-unicast", "hicnpg-server", sw_if_index, 1,
- 0, 0);
-
- switch (rv)
- {
- case 0:
- cl_err = 0;
- break;
-
- case VNET_API_ERROR_UNIMPLEMENTED:
- cl_err = clib_error_return (0, "Unimplemented, NYI");
- break;
-
- default:
- cl_err = clib_error_return (0, "hicn pgen server returned %d", rv);
- }
-
- return cl_err;
+ // Create hicnpg_server
+ return hicnpg_server_add_and_lock (&prefix, &hicnpg_server_index, &locator,
+ payload_size);
}
static clib_error_t *
@@ -855,7 +837,7 @@ VLIB_CLI_COMMAND (hicn_cli_pgen_client_set_command, static) = {
VLIB_CLI_COMMAND (hicn_cli_pgen_server_set_command, static) = {
.path = "hicn pgen server",
.short_help = "hicn pgen server name <prefix> intfc <interest in-interface> "
- "size <payload_size>",
+ "dst <ip_address> size <payload_size>",
.long_help = "Run hicn in packet-gen server mode\n",
.function = hicn_cli_pgen_server_set_command_fn,
};
diff --git a/hicn-plugin/src/data_fwd_node.c b/hicn-plugin/src/data_fwd_node.c
index 6acb5915b..a3f1a592f 100644
--- a/hicn-plugin/src/data_fwd_node.c
+++ b/hicn-plugin/src/data_fwd_node.c
@@ -91,7 +91,6 @@ hicn_data_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
u16 namelen;
u32 bi0;
u32 next0 = HICN_DATA_FWD_NEXT_ERROR_DROP;
- hicn_name_t name;
hicn_header_t *hicn0;
hicn_buffer_t *hicnb0;
hicn_hash_node_t *node0;
@@ -124,15 +123,15 @@ hicn_data_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
/* Get hicn buffer and state */
hicnb0 = hicn_get_buffer (b0);
+ hicn0 = (hicn_header_t *) (vlib_buffer_get_current (b0));
hicn_get_internal_state (hicnb0, pitcs, &node0, &strategy_vft0,
&dpo_vft0, &dpo_ctx_id0, &hash_entry0);
- ret = hicn_data_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
+ hicn_buffer_get_name_and_namelen (b0, &nameptr, &namelen);
+ isv6 = hicn_buffer_is_v6 (b0);
pitp = hicn_pit_get_data (node0);
- nameptr = (u8 *) (&name);
if (PREDICT_FALSE (
- ret != HICN_ERROR_NONE ||
!hicn_node_compare (nameptr, namelen, node0) ||
(hash_entry0->he_flags & HICN_HASH_ENTRY_FLAG_CS_ENTRY)))
{
@@ -182,7 +181,7 @@ hicn_data_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
{
hicn_data_fwd_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
+ t->pkt_type = HICN_PACKET_TYPE_DATA;
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
t->next_index = next0;
clib_memcpy (t->packet_data, vlib_buffer_get_current (b0),
@@ -442,7 +441,7 @@ hicn_satisfy_faces (vlib_main_t *vm, u32 bi0, hicn_pcs_entry_t *pitp,
{
hicn_data_fwd_trace_t *t =
vlib_add_trace (vm, node, h0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
+ t->pkt_type = HICN_PACKET_TYPE_DATA;
t->sw_if_index = vnet_buffer (h0)->sw_if_index[VLIB_RX];
t->next_index = next0;
clib_memcpy (t->packet_data, vlib_buffer_get_current (h0),
@@ -453,7 +452,7 @@ hicn_satisfy_faces (vlib_main_t *vm, u32 bi0, hicn_pcs_entry_t *pitp,
{
hicn_data_fwd_trace_t *t =
vlib_add_trace (vm, node, h1, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
+ t->pkt_type = HICN_PACKET_TYPE_DATA;
t->sw_if_index = vnet_buffer (h1)->sw_if_index[VLIB_RX];
t->next_index = next1;
clib_memcpy (t->packet_data, vlib_buffer_get_current (h1),
@@ -491,7 +490,7 @@ hicn_satisfy_faces (vlib_main_t *vm, u32 bi0, hicn_pcs_entry_t *pitp,
{
hicn_data_fwd_trace_t *t =
vlib_add_trace (vm, node, h0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
+ t->pkt_type = HICN_PACKET_TYPE_DATA;
t->sw_if_index = vnet_buffer (h0)->sw_if_index[VLIB_RX];
t->next_index = next0;
clib_memcpy (t->packet_data, vlib_buffer_get_current (h0),
@@ -607,4 +606,4 @@ VLIB_REGISTER_NODE(hicn_data_fwd_node) =
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/data_input_node.c b/hicn-plugin/src/data_input_node.c
index 46fda1080..65bba7b1b 100644
--- a/hicn-plugin/src/data_input_node.c
+++ b/hicn-plugin/src/data_input_node.c
@@ -80,6 +80,7 @@ hicn_data_input_set_adj_index (vlib_buffer_t *b,
const ip46_address_t *dst_addr,
const hicn_dpo_ctx_t *dpo_ctx)
{
+ CLIB_UNUSED (u8 set) = 0;
for (u8 pos = 0; pos < dpo_ctx->entry_count; pos++)
{
hicn_face_t *face = hicn_dpoi_get_from_idx (dpo_ctx->next_hops[pos]);
@@ -87,9 +88,12 @@ hicn_data_input_set_adj_index (vlib_buffer_t *b,
if (ip46_address_cmp (&(face->nat_addr), dst_addr) == 0)
{
vnet_buffer (b)->ip.adj_index[VLIB_RX] = face->dpo.dpoi_index;
+ set = 1;
break;
}
}
+
+ ASSERT (set == 1);
}
static uword
@@ -147,7 +151,7 @@ hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
src_addr1 = &ip1->src_address;
ip46_address_set_ip6 (&dst_addr0, &ip0->dst_address);
- ip46_address_set_ip6 (&dst_addr0, &ip1->dst_address);
+ ip46_address_set_ip6 (&dst_addr1, &ip1->dst_address);
ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0);
ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p1);
@@ -701,4 +705,4 @@ VNET_FEATURE_INIT (hicn_data_input_ip4_arc, static) = {
.arc_name = "ip4-local",
.node_name = "hicn-data-input-ip4",
.runs_before = VNET_FEATURES ("ip4-local-end-of-arc"),
-};
+}; \ No newline at end of file
diff --git a/hicn-plugin/src/data_pcslookup_node.c b/hicn-plugin/src/data_pcslookup_node.c
index 69278c306..95db66f54 100644
--- a/hicn-plugin/src/data_pcslookup_node.c
+++ b/hicn-plugin/src/data_pcslookup_node.c
@@ -63,17 +63,13 @@ hicn_data_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
while (n_left_from > 0 && n_left_to_next > 0)
{
vlib_buffer_t *b0;
- u8 isv6;
u8 *nameptr;
u16 namelen;
u32 bi0;
u32 next0 = HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP;
u64 name_hash = 0;
- hicn_name_t name;
- hicn_header_t *hicn0 = NULL;
u32 node_id0 = 0;
index_t dpo_ctx_id0 = 0;
- int ret0;
u8 vft_id0 = 0;
u8 is_cs0;
u8 hash_entry_id = 0;
@@ -104,13 +100,11 @@ hicn_data_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
/* Incr packet counter */
stats.pkts_processed += 1;
- ret0 = hicn_data_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
- nameptr = (u8 *) (&name);
+ hicn_buffer_get_name_and_namelen (b0, &nameptr, &namelen);
if (PREDICT_TRUE (
- ret0 == HICN_ERROR_NONE &&
hicn_hashtb_fullhash (nameptr, namelen, &name_hash) ==
- HICN_ERROR_NONE))
+ HICN_ERROR_NONE))
{
int res = hicn_hashtb_lookup_node (
rt->pitcs->pcs_table, nameptr, namelen, name_hash,
@@ -154,7 +148,7 @@ hicn_data_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
{
hicn_data_pcslookup_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
+ t->pkt_type = HICN_PACKET_TYPE_DATA;
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
t->next_index = next0;
}
@@ -216,4 +210,4 @@ VLIB_REGISTER_NODE(hicn_data_pcslookup_node) =
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/faces/app/face_prod_node.c b/hicn-plugin/src/faces/app/face_prod_node.c
index 5d2b54040..e3241e477 100644
--- a/hicn-plugin/src/faces/app/face_prod_node.c
+++ b/hicn-plugin/src/faces/app/face_prod_node.c
@@ -42,12 +42,12 @@ typedef struct
{
u32 next_index;
u32 sw_if_index;
+ hicn_error_t error;
} hicn_face_prod_input_trace_t;
typedef enum
{
- HICN_FACE_PROD_NEXT_DATA_IP4,
- HICN_FACE_PROD_NEXT_DATA_IP6,
+ HICN_FACE_PROD_NEXT_PCS,
HICN_FACE_PROD_NEXT_ERROR_DROP,
HICN_FACE_PROD_N_NEXT,
} hicn_face_prod_next_t;
@@ -65,11 +65,14 @@ format_face_prod_input_trace (u8 *s, va_list *args)
s = format (s, "prod-face: sw_if_index %d next-index %d", t->sw_if_index,
t->next_index);
+
+ if (t->error != HICN_ERROR_NONE)
+ s = format (s, " error %s", get_error_string (t->error));
return s;
}
static_always_inline int
-match_ip4_name (u32 *name, fib_prefix_t *prefix)
+match_ip4_name (u32 *name, const fib_prefix_t *prefix)
{
u32 xor = 0;
@@ -79,7 +82,7 @@ match_ip4_name (u32 *name, fib_prefix_t *prefix)
}
static_always_inline int
-match_ip6_name (u8 *name, fib_prefix_t *prefix)
+match_ip6_name (u8 *name, const fib_prefix_t *prefix)
{
union
{
@@ -96,24 +99,42 @@ match_ip6_name (u8 *name, fib_prefix_t *prefix)
}
static_always_inline u32
-hicn_face_prod_next_from_data_hdr (vlib_node_runtime_t *node, vlib_buffer_t *b,
- fib_prefix_t *prefix)
+hicn_face_prod_next_from_data_hdr (vlib_buffer_t *b)
{
- u8 *ptr = vlib_buffer_get_current (b);
- u8 v = *ptr & 0xf0;
+ u8 is_v6;
int match_res = 1;
+ int ret = 0;
+ hicn_name_t *name;
+ hicn_face_prod_state_t *prod_face = NULL;
+
+ // 1 - ensure the packet is hicn and its format is correct
+ ret = hicn_data_parse_pkt (b);
+ if (PREDICT_FALSE (ret))
+ {
+ return HICN_FACE_PROD_NEXT_ERROR_DROP;
+ }
- if (PREDICT_TRUE (v == 0x40 && ip46_address_is_ip4 (&prefix->fp_addr)))
+ // 2 - make sure the packet refers to a valid producer app state and
+ // retrieve app state information
+ prod_face = &face_state_vec[vnet_buffer (b)->sw_if_index[VLIB_RX]];
+ vnet_buffer (b)->ip.adj_index[VLIB_RX] = prod_face->adj_index;
+
+ // 3 - make sure the address in the packet belongs to the producer prefix
+ // of this face
+ const fib_prefix_t *prefix = &prod_face->prefix;
+ is_v6 = hicn_buffer_is_v6 (b);
+ name = &hicn_get_buffer (b)->name;
+ if (PREDICT_TRUE (!is_v6 && ip46_address_is_ip4 (&prefix->fp_addr)))
{
- match_res = match_ip4_name ((u32 *) &(ptr[12]), prefix);
+ match_res = match_ip4_name (&name->prefix.ip4.as_u32, prefix);
}
- else if (PREDICT_TRUE (v == 0x60 && !ip46_address_is_ip4 (&prefix->fp_addr)))
+ else if (PREDICT_TRUE (is_v6 && !ip46_address_is_ip4 (&prefix->fp_addr)))
{
- match_res = match_ip6_name (&(ptr[8]), prefix);
+ match_res = match_ip6_name (name->prefix.ip6.as_u8, prefix);
}
- return match_res ? HICN_FACE_PROD_NEXT_DATA_IP4 + (v == 0x60) :
- HICN_FACE_PROD_NEXT_ERROR_DROP;
+ // 4 - if match found, forward data to next hicn node
+ return match_res ? HICN_FACE_PROD_NEXT_PCS : HICN_FACE_PROD_NEXT_ERROR_DROP;
}
static_always_inline void
@@ -137,6 +158,7 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
u32 n_left_from, *from, *to_next;
hicn_face_prod_next_t next_index;
vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
+ u32 thread_index = vm->thread_index;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -152,22 +174,28 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
vlib_buffer_t *b0, *b1, *b2, *b3;
hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3;
u32 bi0, bi1, bi2, bi3;
- hicn_face_prod_state_t *prod_face0 = NULL;
- hicn_face_prod_state_t *prod_face1 = NULL;
- hicn_face_prod_state_t *prod_face2 = NULL;
- hicn_face_prod_state_t *prod_face3 = NULL;
u32 next0, next1, next2, next3;
+ // Prefetch next iteration
{
vlib_buffer_t *b4, *b5, *b6, *b7;
b4 = vlib_get_buffer (vm, from[4]);
b5 = vlib_get_buffer (vm, from[5]);
b6 = vlib_get_buffer (vm, from[6]);
b7 = vlib_get_buffer (vm, from[7]);
- CLIB_PREFETCH (b4, CLIB_CACHE_LINE_BYTES, STORE);
- CLIB_PREFETCH (b5, CLIB_CACHE_LINE_BYTES, STORE);
- CLIB_PREFETCH (b6, CLIB_CACHE_LINE_BYTES, STORE);
- CLIB_PREFETCH (b7, CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (b4, 2 * CLIB_CACHE_LINE_BYTES, WRITE);
+ CLIB_PREFETCH (b5, 2 * CLIB_CACHE_LINE_BYTES, WRITE);
+ CLIB_PREFETCH (b6, 2 * CLIB_CACHE_LINE_BYTES, WRITE);
+ CLIB_PREFETCH (b7, 2 * CLIB_CACHE_LINE_BYTES, WRITE);
+
+ CLIB_PREFETCH (vlib_buffer_get_current (b4),
+ 2 * CLIB_CACHE_LINE_BYTES, WRITE);
+ CLIB_PREFETCH (vlib_buffer_get_current (b5),
+ 2 * CLIB_CACHE_LINE_BYTES, WRITE);
+ CLIB_PREFETCH (vlib_buffer_get_current (b6),
+ 2 * CLIB_CACHE_LINE_BYTES, WRITE);
+ CLIB_PREFETCH (vlib_buffer_get_current (b7),
+ 2 * CLIB_CACHE_LINE_BYTES, WRITE);
}
bi0 = from[0];
@@ -200,31 +228,39 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
hicnb2->flags = HICN_FACE_FLAGS_DEFAULT;
hicnb3->flags = HICN_FACE_FLAGS_DEFAULT;
- prod_face0 = &face_state_vec[vnet_buffer (b0)->sw_if_index[VLIB_RX]];
- prod_face1 = &face_state_vec[vnet_buffer (b1)->sw_if_index[VLIB_RX]];
- prod_face2 = &face_state_vec[vnet_buffer (b2)->sw_if_index[VLIB_RX]];
- prod_face3 = &face_state_vec[vnet_buffer (b3)->sw_if_index[VLIB_RX]];
-
- vnet_buffer (b0)->ip.adj_index[VLIB_RX] =
- face_state_vec[vnet_buffer (b0)->sw_if_index[VLIB_RX]].adj_index;
- vnet_buffer (b1)->ip.adj_index[VLIB_RX] =
- face_state_vec[vnet_buffer (b1)->sw_if_index[VLIB_RX]].adj_index;
- vnet_buffer (b2)->ip.adj_index[VLIB_RX] =
- face_state_vec[vnet_buffer (b2)->sw_if_index[VLIB_RX]].adj_index;
- vnet_buffer (b3)->ip.adj_index[VLIB_RX] =
- face_state_vec[vnet_buffer (b3)->sw_if_index[VLIB_RX]].adj_index;
-
- next0 =
- hicn_face_prod_next_from_data_hdr (node, b0, &prod_face0->prefix);
- next1 =
- hicn_face_prod_next_from_data_hdr (node, b1, &prod_face1->prefix);
- next2 =
- hicn_face_prod_next_from_data_hdr (node, b2, &prod_face2->prefix);
- next3 =
- hicn_face_prod_next_from_data_hdr (node, b3, &prod_face3->prefix);
+ // parse packets and get next node
+ next0 = hicn_face_prod_next_from_data_hdr (b0);
+ next1 = hicn_face_prod_next_from_data_hdr (b1);
+ next2 = hicn_face_prod_next_from_data_hdr (b2);
+ next3 = hicn_face_prod_next_from_data_hdr (b3);
stats.pkts_data_count += 4;
- /* trace */
+ // counters
+ vlib_increment_combined_counter (
+ &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index,
+ HICN_FACE_COUNTERS_DATA_RX, 1,
+ vlib_buffer_length_in_chain (vm, b0));
+ stats.pkts_data_count += 1;
+
+ vlib_increment_combined_counter (
+ &counters[hicnb1->face_id * HICN_N_COUNTER], thread_index,
+ HICN_FACE_COUNTERS_DATA_RX, 1,
+ vlib_buffer_length_in_chain (vm, b0));
+ stats.pkts_data_count += 1;
+
+ vlib_increment_combined_counter (
+ &counters[hicnb2->face_id * HICN_N_COUNTER], thread_index,
+ HICN_FACE_COUNTERS_DATA_RX, 1,
+ vlib_buffer_length_in_chain (vm, b0));
+ stats.pkts_data_count += 1;
+
+ vlib_increment_combined_counter (
+ &counters[hicnb3->face_id * HICN_N_COUNTER], thread_index,
+ HICN_FACE_COUNTERS_DATA_RX, 1,
+ vlib_buffer_length_in_chain (vm, b0));
+ stats.pkts_data_count += 1;
+
+ // trace
hicn_face_prod_trace_buffer (
vm, node, vnet_buffer (b0)->sw_if_index[VLIB_RX], b0, next0);
hicn_face_prod_trace_buffer (
@@ -234,7 +270,7 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
hicn_face_prod_trace_buffer (
vm, node, vnet_buffer (b3)->sw_if_index[VLIB_RX], b3, next3);
- /* enqueue */
+ // enqueue
vlib_validate_buffer_enqueue_x4 (vm, node, next_index, to_next,
n_left_to_next, bi0, bi1, bi2, bi3,
next0, next1, next2, next3);
@@ -246,8 +282,7 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
{
vlib_buffer_t *b0;
hicn_buffer_t *hicnb0;
- u32 bi0, swif;
- hicn_face_prod_state_t *prod_face = NULL;
+ u32 bi0;
u32 next0;
if (n_left_from > 1)
@@ -267,15 +302,17 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
b0 = vlib_get_buffer (vm, bi0);
hicnb0 = hicn_get_buffer (b0);
hicnb0->flags = HICN_FACE_FLAGS_DEFAULT;
- swif = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- prod_face = &face_state_vec[swif];
- next0 =
- hicn_face_prod_next_from_data_hdr (node, b0, &prod_face->prefix);
- vnet_buffer (b0)->ip.adj_index[VLIB_RX] =
- face_state_vec[swif].adj_index;
+ next0 = hicn_face_prod_next_from_data_hdr (b0);
stats.pkts_data_count++;
+ // counters
+ vlib_increment_combined_counter (
+ &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index,
+ HICN_FACE_COUNTERS_DATA_RX, 1,
+ vlib_buffer_length_in_chain (vm, b0));
+ stats.pkts_data_count += 1;
+
/* trace */
hicn_face_prod_trace_buffer (
vm, node, vnet_buffer (b0)->sw_if_index[VLIB_RX], b0, next0);
@@ -310,8 +347,7 @@ VLIB_REGISTER_NODE(hicn_face_prod_input_node) =
.n_next_nodes = HICN_FACE_PROD_N_NEXT,
.next_nodes =
{
- [HICN_FACE_PROD_NEXT_DATA_IP4] = "hicn4-face-input",
- [HICN_FACE_PROD_NEXT_DATA_IP6] = "hicn6-face-input",
+ [HICN_FACE_PROD_NEXT_PCS] = "hicn-data-pcslookup",
[HICN_FACE_PROD_NEXT_ERROR_DROP] = "error-drop",
},
};
@@ -320,4 +356,4 @@ VLIB_REGISTER_NODE(hicn_face_prod_input_node) =
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c
index 854fd81d3..4ee1c283f 100644
--- a/hicn-plugin/src/faces/face.c
+++ b/hicn-plugin/src/faces/face.c
@@ -62,16 +62,12 @@ mhash_t hicn_face_hashtb;
const static char *const hicn_face6_nodes[] = {
"hicn6-face-output", // this is the name you give your node in
// VLIB_REGISTER_NODE
- "hicn6-iface-output", // this is the name you give your node in
- // VLIB_REGISTER_NODE
NULL,
};
const static char *const hicn_face4_nodes[] = {
"hicn4-face-output", // this is the name you give your node in
// VLIB_REGISTER_NODE
- "hicn4-iface-output", // this is the name you give your node in
- // VLIB_REGISTER_NODE
NULL,
};
@@ -304,7 +300,7 @@ hicn_iface_to_face (hicn_face_t *face, const dpo_id_t *dpo)
*/
int
hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address, int sw_if,
- hicn_face_id_t *pfaceid, u8 is_app_prod)
+ hicn_face_id_t *pfaceid)
{
hicn_face_flags_t flags = (hicn_face_flags_t) 0;
diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h
index 39505c942..e4b759bec 100644
--- a/hicn-plugin/src/faces/face.h
+++ b/hicn-plugin/src/faces/face.h
@@ -27,6 +27,8 @@
#include <vpp_plugins/hicn/error.h>
+#include "face_flags.h"
+#include "../hicn_buffer_flags.h"
#include "../udp_tunnels/udp_tunnel.h"
#include "../hicn_logging.h"
@@ -117,40 +119,8 @@ typedef struct __attribute__ ((packed)) hicn_face_s
/* Pool of faces */
extern hicn_face_t *hicn_dpoi_face_pool;
-/* Flags */
-/* A face is complete and it stores all the information. A iface lacks of the
- adj index, therefore sending a packet through a iface require a lookup in
- the FIB. */
-#define HICN_FACE_FLAGS_DEFAULT 0x00
-#define HICN_FACE_FLAGS_FACE 0x01
-#define HICN_FACE_FLAGS_IFACE 0x02
-#define HICN_FACE_FLAGS_APPFACE_PROD \
- 0x04 /* Currently only IP face can be appface */
-#define HICN_FACE_FLAGS_APPFACE_CONS \
- 0x08 /* Currently only IP face can be appface */
-#define HICN_FACE_FLAGS_DELETED 0x10
-#define HICN_FACE_FLAGS_UDP 0x20
-
#define HICN_FACE_NULL (hicn_face_id_t) ~0
-#define HICN_FACE_FLAGS_APPFACE_PROD_BIT 2
-#define HICN_FACE_FLAGS_APPFACE_CONS_BIT 3
-
-#define HICN_BUFFER_FLAGS_DEFAULT 0x00
-#define HICN_BUFFER_FLAGS_NEW_FACE 0x02
-#define HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL 0x04
-#define HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL 0x08
-
-STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_PROD_BIT) ==
- HICN_FACE_FLAGS_APPFACE_PROD,
- "HICN_FACE_FLAGS_APPFACE_PROD_BIT and "
- "HICN_FACE_FLAGS_APPFACE_PROD must correspond");
-
-STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_CONS_BIT) ==
- HICN_FACE_FLAGS_APPFACE_CONS,
- "HICN_FACE_FLAGS_APPFACE_CONS_BIT and "
- "HICN_FACE_FLAGS_APPFACE_CONS must correspond");
-
/**
* @brief Definition of the virtual functin table for an hICN FACE DPO.
*/
@@ -484,7 +454,7 @@ hicn_face_get_with_dpo (const ip46_address_t *addr, u32 sw_if,
* reachable ip address, otherwise HICN_ERROR_NONE
*/
int hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address,
- int sw_if, hicn_face_id_t *pfaceid, u8 is_app_prod);
+ int sw_if, hicn_face_id_t *pfaceid);
/**
* @brief Create a new incomplete face ip. (Meant to be used by the data plane)
@@ -497,7 +467,7 @@ int hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address,
* reachable ip address, otherwise HICN_ERROR_NONE
*/
always_inline void
-hicn_iface_add (ip46_address_t *nat_address, int sw_if,
+hicn_iface_add (const ip46_address_t *nat_address, int sw_if,
hicn_face_id_t *pfaceid, u32 adj_index, u8 flags)
{
hicn_face_t *face;
@@ -615,7 +585,6 @@ hicn_face_ip4_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
*hicnb_flags |= HICN_BUFFER_FLAGS_NEW_FACE;
*index = idx;
- return ret;
}
else
{
@@ -623,15 +592,10 @@ hicn_face_ip4_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
hicn_face_id_t face_id = hicn_dpoi_get_index (face);
hicn_face_unlock_with_id (face_id);
ret = HICN_ERROR_FACE_ALREADY_CREATED;
+ *index = hicn_dpoi_get_index (face);
+ *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
}
- /* Code replicated on purpose */
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
- HICN_FACE_FLAGS_APPFACE_PROD_BIT;
-
- *index = hicn_dpoi_get_index (face);
-
return ret;
}
@@ -676,7 +640,7 @@ hicn_face_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
/*All (complete) faces are indexed by remote addess as well */
/* if the face exists, it adds a lock */
- hicn_face_t *face = hicn_face_get ((ip46_address_t *) nat_addr, sw_if,
+ hicn_face_t *face = hicn_face_get ((const ip46_address_t *) nat_addr, sw_if,
&hicn_face_hashtb, adj_index);
if (face == NULL)
@@ -684,8 +648,8 @@ hicn_face_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
hicn_face_id_t idx;
u8 face_flags = 0;
- hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, adj_index,
- face_flags);
+ hicn_iface_add ((const ip46_address_t *) nat_addr, sw_if, &idx,
+ adj_index, face_flags);
face = hicn_dpoi_get_from_idx (idx);
@@ -712,12 +676,8 @@ hicn_face_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
adj_nbr_walk (face->sw_if, FIB_PROTOCOL_IP6, hicn6_iface_adj_walk_cb,
face);
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |= HICN_BUFFER_FLAGS_NEW_FACE;
-
+ *hicnb_flags = HICN_BUFFER_FLAGS_NEW_FACE;
*index = idx;
-
- return ret;
}
else
{
@@ -725,15 +685,10 @@ hicn_face_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags,
hicn_face_id_t face_id = hicn_dpoi_get_index (face);
hicn_face_unlock_with_id (face_id);
ret = HICN_ERROR_FACE_ALREADY_CREATED;
+ *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
+ *index = hicn_dpoi_get_index (face);
}
- /* Code replicated on purpose */
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
- HICN_FACE_FLAGS_APPFACE_PROD_BIT;
-
- *index = hicn_dpoi_get_index (face);
-
return ret;
}
diff --git a/hicn-plugin/src/faces/face_flags.h b/hicn-plugin/src/faces/face_flags.h
new file mode 100644
index 000000000..61dee5465
--- /dev/null
+++ b/hicn-plugin/src/faces/face_flags.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __HICN_FACE_FLAGS_H__
+#define __HICN_FACE_FLAGS_H__
+
+/* Flags */
+/* A face is complete and it stores all the information. A iface lacks of the
+ adj index, therefore sending a packet through a iface require a lookup in
+ the FIB. */
+#define foreach_face_flag \
+ _ (0, FACE, "face") \
+ _ (1, IFACE, "iface") \
+ _ (2, APPFACE_PROD, "face is consumer face") \
+ _ (3, APPFACE_CONS, "face is consumer face") \
+ _ (4, DELETED, "face is deleted") \
+ _ (5, UDP, "face is udp")
+
+enum
+{
+ HICN_FACE_FLAGS_DEFAULT = 0,
+#define _(a, b, c) HICN_FACE_FLAGS_##b = (1 << a),
+ foreach_face_flag
+#undef _
+};
+
+#endif /* __HICN_FACE_FLAGS_H__ */ \ No newline at end of file
diff --git a/hicn-plugin/src/faces/face_node.c b/hicn-plugin/src/faces/face_node.c
index dc9bfffd0..6dedbe1c4 100644
--- a/hicn-plugin/src/faces/face_node.c
+++ b/hicn-plugin/src/faces/face_node.c
@@ -56,6 +56,7 @@ typedef struct
u32 next_index;
u32 sw_if_index;
u8 pkt_type;
+ hicn_error_t error;
u8 packet_data[60];
} hicn4_face_input_trace_t;
@@ -73,6 +74,7 @@ typedef struct
u32 next_index;
u32 sw_if_index;
u8 pkt_type;
+ hicn_error_t error;
u8 packet_data[60];
} hicn6_face_input_trace_t;
@@ -86,8 +88,9 @@ typedef enum
#define NEXT_MAPME_IP4 HICN4_FACE_INPUT_NEXT_MAPME
#define NEXT_MAPME_IP6 HICN6_FACE_INPUT_NEXT_MAPME
-#define NEXT_DATA_IP4 HICN4_FACE_INPUT_NEXT_DATA
-#define NEXT_DATA_IP6 HICN6_FACE_INPUT_NEXT_DATA
+
+#define NEXT_DATA_IP4 HICN4_FACE_INPUT_NEXT_DATA
+#define NEXT_DATA_IP6 HICN6_FACE_INPUT_NEXT_DATA
#define NEXT_ERROR_DROP_IP4 HICN4_FACE_INPUT_NEXT_ERROR_DROP
#define NEXT_ERROR_DROP_IP6 HICN6_FACE_INPUT_NEXT_ERROR_DROP
@@ -110,10 +113,11 @@ typedef enum
vlib_buffer_t *b0; \
u32 bi0, sw_if0; \
u32 next0 = NEXT_ERROR_DROP_IP##ipv; \
+ u8 is_icmp0; \
IP_HEADER_##ipv *ip_hdr = NULL; \
hicn_buffer_t *hicnb0; \
int from_tunnel0; \
- int ret0; \
+ int ret0 = HICN_ERROR_NONE; \
/* Prefetch for next iteration. */ \
if (n_left_from > 1) \
{ \
@@ -134,23 +138,35 @@ typedef enum
hicnb0 = hicn_get_buffer (b0); \
ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current (b0); \
\
- u8 is_icmp = ip_hdr->protocol == IPPROTO_ICMPV##ipv; \
- \
- from_tunnel0 = \
- (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
- hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
- sw_if0 = (from_tunnel0) * ~0 + \
- (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- \
- ret0 = hicn_face_ip##ipv##_add_and_lock ( \
- &hicnb0->face_id, &hicnb0->flags, &ip_hdr->dst_address, sw_if0, \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX], \
- /* Should not be used */ ~0); \
- /* Make sure the face is not created here */ \
- ASSERT (ret0 == HICN_ERROR_FACE_ALREADY_CREATED); \
+ /* Parse packet and cache useful info in opaque2 */ \
+ ret0 = hicn_data_parse_pkt (b0); \
+ is_icmp0 = ret0 == HICN_ERROR_PARSER_MAPME_PACKET; \
+ ret0 = (ret0 == HICN_ERROR_NONE) || \
+ (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \
\
- next0 = \
- is_icmp * NEXT_MAPME_IP##ipv + (1 - is_icmp) * NEXT_DATA_IP##ipv; \
+ /* If parsing is ok, send packet to next node */ \
+ if (PREDICT_FALSE (!ret0)) \
+ { \
+ next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \
+ } \
+ else \
+ { \
+ next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp0) * NEXT_DATA_IP##ipv; \
+ from_tunnel0 = \
+ (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
+ hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
+ sw_if0 = \
+ (from_tunnel0) * ~0 + \
+ (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ \
+ ret0 = hicn_face_ip##ipv##_add_and_lock ( \
+ &hicnb0->face_id, &hicnb0->flags, &ip_hdr->dst_address, sw_if0, \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX], \
+ /* Should not be used */ ~0); \
+ /* Make sure the face is not created here */ \
+ ASSERT (ret0 == HICN_ERROR_FACE_ALREADY_CREATED); \
+ } \
\
vlib_increment_combined_counter ( \
&counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, \
@@ -162,8 +178,9 @@ typedef enum
{ \
TRACE_INPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ t->error = ret0; \
t->next_index = next0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
sizeof (t->packet_data)); \
@@ -182,6 +199,7 @@ typedef enum
u32 bi0, bi1, sw_if0, sw_if1; \
u32 next0 = NEXT_ERROR_DROP_IP##ipv; \
u32 next1 = NEXT_ERROR_DROP_IP##ipv; \
+ u8 is_icmp0, is_icmp1; \
IP_HEADER_##ipv *ip_hdr0 = NULL; \
IP_HEADER_##ipv *ip_hdr1 = NULL; \
hicn_buffer_t *hicnb0; \
@@ -215,40 +233,95 @@ typedef enum
ip_hdr0 = (IP_HEADER_##ipv *) vlib_buffer_get_current (b0); \
ip_hdr1 = (IP_HEADER_##ipv *) vlib_buffer_get_current (b1); \
\
- u8 is_icmp0 = ip_hdr0->protocol == IPPROTO_ICMPV##ipv; \
- u8 is_icmp1 = ip_hdr1->protocol == IPPROTO_ICMPV##ipv; \
- \
- from_tunnel0 = \
- (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
- hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
- sw_if0 = (from_tunnel0) * ~0 + \
- (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- \
- ret0 = hicn_face_ip##ipv##_add_and_lock ( \
- &hicnb0->face_id, &hicnb0->flags, &ip_hdr0->dst_address, sw_if0, \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX], \
- /* Should not be used */ ~0); \
- /* Make sure the face is not created here */ \
- ASSERT (ret0 == HICN_ERROR_FACE_ALREADY_CREATED); \
- \
- from_tunnel1 = \
- (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
- hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
- sw_if1 = (from_tunnel1) * ~0 + \
- (1 - from_tunnel1) * vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
- \
- ret1 = hicn_face_ip##ipv##_add_and_lock ( \
- &hicnb1->face_id, &hicnb1->flags, &ip_hdr1->dst_address, sw_if1, \
- vnet_buffer (b1)->ip.adj_index[VLIB_RX], \
- /* Should not be used */ ~0); \
- /* Make sure the face is not created here */ \
- ASSERT (ret1 == HICN_ERROR_FACE_ALREADY_CREATED); \
- \
- next0 = \
- is_icmp0 * NEXT_MAPME_IP##ipv + (1 - is_icmp0) * NEXT_DATA_IP##ipv; \
- \
- next1 = \
- is_icmp1 * NEXT_MAPME_IP##ipv + (1 - is_icmp1) * NEXT_DATA_IP##ipv; \
+ /* Parse packet and cache useful info in opaque2 */ \
+ /* Parse packet and cache useful info in opaque2 */ \
+ ret0 = hicn_data_parse_pkt (b0); \
+ ret1 = hicn_data_parse_pkt (b1); \
+ is_icmp0 = ret0 == HICN_ERROR_PARSER_MAPME_PACKET; \
+ is_icmp1 = ret1 == HICN_ERROR_PARSER_MAPME_PACKET; \
+ ret0 = (ret0 == HICN_ERROR_NONE) || \
+ (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \
+ ret1 = (ret1 == HICN_ERROR_NONE) || \
+ (ret1 == HICN_ERROR_PARSER_MAPME_PACKET); \
+ if (PREDICT_TRUE (ret0 && ret1)) \
+ { \
+ next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp0) * NEXT_DATA_IP##ipv; \
+ \
+ next1 = is_icmp1 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp1) * NEXT_DATA_IP##ipv; \
+ \
+ from_tunnel0 = \
+ (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
+ hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
+ sw_if0 = \
+ (from_tunnel0) * ~0 + \
+ (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ \
+ ret0 = hicn_face_ip##ipv##_add_and_lock ( \
+ &hicnb0->face_id, &hicnb0->flags, &ip_hdr0->dst_address, sw_if0, \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX], \
+ /* Should not be used */ ~0); \
+ /* Make sure the face is not created here */ \
+ ASSERT (ret0 == HICN_ERROR_FACE_ALREADY_CREATED); \
+ \
+ from_tunnel1 = \
+ (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
+ hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
+ sw_if1 = \
+ (from_tunnel1) * ~0 + \
+ (1 - from_tunnel1) * vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
+ \
+ ret1 = hicn_face_ip##ipv##_add_and_lock ( \
+ &hicnb1->face_id, &hicnb1->flags, &ip_hdr1->dst_address, sw_if1, \
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX], \
+ /* Should not be used */ ~0); \
+ /* Make sure the face is not created here */ \
+ ASSERT (ret1 == HICN_ERROR_FACE_ALREADY_CREATED); \
+ } \
+ else if (ret0 && !ret1) \
+ { \
+ next1 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \
+ from_tunnel0 = \
+ (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
+ hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
+ sw_if0 = \
+ (from_tunnel0) * ~0 + \
+ (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ \
+ ret0 = hicn_face_ip##ipv##_add_and_lock ( \
+ &hicnb0->face_id, &hicnb0->flags, &ip_hdr0->dst_address, sw_if0, \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX], \
+ /* Should not be used */ ~0); \
+ /* Make sure the face is not created here */ \
+ ASSERT (ret0 == HICN_ERROR_FACE_ALREADY_CREATED); \
+ next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp0) * NEXT_DATA_IP##ipv; \
+ } \
+ else if (!ret0 && ret1) \
+ { \
+ next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \
+ from_tunnel1 = \
+ (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \
+ hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \
+ sw_if1 = \
+ (from_tunnel1) * ~0 + \
+ (1 - from_tunnel1) * vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
+ \
+ ret1 = hicn_face_ip##ipv##_add_and_lock ( \
+ &hicnb1->face_id, &hicnb1->flags, &ip_hdr1->dst_address, sw_if1, \
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX], \
+ /* Should not be used */ ~0); \
+ /* Make sure the face is not created here */ \
+ ASSERT (ret1 == HICN_ERROR_FACE_ALREADY_CREATED); \
+ next1 = is_icmp1 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp1) * NEXT_DATA_IP##ipv; \
+ } \
+ else \
+ { \
+ next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \
+ next1 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \
+ } \
\
vlib_increment_combined_counter ( \
&counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, \
@@ -265,8 +338,9 @@ typedef enum
{ \
TRACE_INPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ t->error = ret0; \
t->next_index = next0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
sizeof (t->packet_data)); \
@@ -277,8 +351,9 @@ typedef enum
{ \
TRACE_INPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
+ t->error = ret1; \
t->next_index = next1; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \
sizeof (t->packet_data)); \
@@ -461,80 +536,6 @@ typedef enum
HICN6_FACE_OUTPUT_N_NEXT,
} hicn6_face_output_next_t;
-/* static_always_inline void */
-/* hicn_reply_probe_v4 (vlib_buffer_t * b, hicn_face_t * face) */
-/* { */
-/* hicn_header_t *h0 = vlib_buffer_get_current (b); */
-/* hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data); */
-/* h0->v4.ip.saddr = h0->v4.ip.daddr; */
-/* h0->v4.ip.daddr = face_ip->local_addr.ip4; */
-/* vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if; */
-
-/* u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t) +
- * sizeof(u16)); */
-/* u16 dst_port = *dst_port_ptr; */
-/* u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t)); */
-
-/* *dst_port_ptr = *src_port_ptr; */
-/* *src_port_ptr = dst_port; */
-
-/* hicn_type_t type = hicn_get_buffer (b)->type; */
-/* hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0); */
-/* } */
-
-/* static_always_inline void */
-/* hicn_reply_probe_v6 (vlib_buffer_t * b, hicn_face_t * face) */
-/* { */
-/* hicn_header_t *h0 = vlib_buffer_get_current (b); */
-/* hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data); */
-/* h0->v6.ip.saddr = h0->v6.ip.daddr; */
-/* h0->v6.ip.daddr = face_ip->local_addr.ip6; */
-/* vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if; */
-
-/* u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t) +
- * sizeof(u16)); */
-/* u16 dst_port = *dst_port_ptr; */
-/* u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t)); */
-
-/* *dst_port_ptr = *src_port_ptr; */
-/* *src_port_ptr = dst_port; */
-
-/* hicn_type_t type = hicn_get_buffer (b)->type; */
-/* hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0); */
-
-/* } */
-
-/* static_always_inline u32 */
-/* hicn_face_match_probe (vlib_buffer_t * b, hicn_face_t * face, u32 * next) */
-/* { */
-
-/* u8 *ptr = vlib_buffer_get_current (b); */
-/* u8 v = *ptr & 0xf0; */
-/* u8 res = 0; */
-
-/* if ( v == 0x40 ) */
-/* { */
-/* u16 * dst_port = (u16 *)(ptr + sizeof(ip4_header_t) + sizeof(u16)); */
-/* if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT)) */
-/* { */
-/* hicn_reply_probe_v6(b, face); */
-/* *next = HICN4_FACE_NEXT_ECHO_REPLY; */
-/* res = 1; */
-/* } */
-/* } */
-/* else if ( v == 0x60 ) */
-/* { */
-/* u16 * dst_port = (u16 *)(ptr + sizeof(ip6_header_t) + sizeof(u16)); */
-/* if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT)) */
-/* { */
-/* hicn_reply_probe_v6(b, face); */
-/* *next = HICN6_FACE_NEXT_ECHO_REPLY; */
-/* res = 1; */
-/* } */
-/* } */
-/* return res; */
-/* } */
-
static inline void
hicn_face_rewrite_interest (vlib_main_t *vm, vlib_buffer_t *b0,
hicn_face_t *face, u32 *next)
@@ -546,6 +547,9 @@ hicn_face_rewrite_interest (vlib_main_t *vm, vlib_buffer_t *b0,
hicn_header_t *hicn = vlib_buffer_get_current (b0);
+ u8 is_v4 = ip46_address_is_ip4 (&face->nat_addr) &&
+ !ip6_address_is_loopback (&face->nat_addr.ip6);
+
// hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
ip46_address_t temp_addr;
@@ -553,11 +557,8 @@ hicn_face_rewrite_interest (vlib_main_t *vm, vlib_buffer_t *b0,
hicn_type_t type = hicn_get_buffer (b0)->type;
int ret = hicn_ops_vft[type.l1]->rewrite_interest (
type, &hicn->protocol, &face->nat_addr, &temp_addr);
-
if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED)
{
- u8 is_v4 = ip46_address_is_ip4 (&face->nat_addr) &&
- !ip6_address_is_loopback (&face->nat_addr.ip6);
ensure_offload_flags (b0, is_v4);
}
@@ -645,7 +646,7 @@ typedef struct
{ \
TRACE_OUTPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
t->next_index = next0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
@@ -724,7 +725,7 @@ typedef struct
{ \
TRACE_OUTPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
t->next_index = next0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
@@ -736,7 +737,7 @@ typedef struct
{ \
TRACE_OUTPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
t->next_index = next1; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \
@@ -812,12 +813,7 @@ VLIB_REGISTER_NODE (hicn4_face_output_node) = {
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = ARRAY_LEN (hicn4_face_output_error_strings),
.error_strings = hicn4_face_output_error_strings,
- .n_next_nodes = HICN4_FACE_OUTPUT_N_NEXT,
- /* Reusing the list of nodes from lookup to be compatible with arp */
- .next_nodes = { [HICN4_FACE_OUTPUT_NEXT_ERROR_DROP] = "error-drop",
- [HICN4_FACE_OUTPUT_NEXT_ECHO_REPLY] = "hicn4-face-input",
- [HICN4_FACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
- [HICN4_FACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" }
+ .sibling_of = "ip4-lookup",
};
static uword
@@ -882,13 +878,7 @@ VLIB_REGISTER_NODE (hicn6_face_output_node) = {
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = ARRAY_LEN (hicn6_face_output_error_strings),
.error_strings = hicn6_face_output_error_strings,
- .n_next_nodes = HICN6_FACE_OUTPUT_N_NEXT,
- /* Reusing the list of nodes from lookup to be compatible with neighbour
- discovery */
- .next_nodes = { [HICN6_FACE_OUTPUT_NEXT_ERROR_DROP] = "error-drop",
- [HICN6_FACE_OUTPUT_NEXT_ECHO_REPLY] = "hicn6-face-input",
- [HICN6_FACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
- [HICN6_FACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" }
+ .sibling_of = "ip6-lookup",
};
/*
@@ -897,4 +887,4 @@ VLIB_REGISTER_NODE (hicn6_face_output_node) = {
* Local Variables:
* eval: (c-set-style "gnu")
* End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/faces/iface_node.c b/hicn-plugin/src/faces/iface_node.c
index 84205af9b..3b6634d77 100644
--- a/hicn-plugin/src/faces/iface_node.c
+++ b/hicn-plugin/src/faces/iface_node.c
@@ -52,6 +52,7 @@ typedef struct
u32 next_index;
u32 sw_if_index;
u8 pkt_type;
+ hicn_error_t error;
u8 packet_data[60];
} hicn4_iface_input_trace_t;
@@ -69,6 +70,7 @@ typedef struct
u32 next_index;
u32 sw_if_index;
u8 pkt_type;
+ hicn_error_t error;
u8 packet_data[60];
} hicn6_iface_input_trace_t;
@@ -86,33 +88,9 @@ typedef enum
#define NEXT_INTEREST_IP4 HICN4_IFACE_INPUT_NEXT_INTEREST
#define NEXT_INTEREST_IP6 HICN6_IFACE_INPUT_NEXT_INTEREST
-#define ADDRESS_IP4 \
- ip_interface_address_t *ia = 0; \
- ip4_address_t *local_address = \
- ip4_interface_first_address (&ip4_main, swif, &ia)
-#define ADDRESS_IP6 \
- ip6_address_t *local_address = ip6_interface_first_address (&ip6_main, swif)
-
-#define ADDRESSX2_IP4 \
- ip_interface_address_t *ia0, *ia1; \
- ia0 = ia1 = 0; \
- ip4_address_t *local_address0 = \
- ip4_interface_first_address (&ip4_main, swif0, &ia0); \
- ip4_address_t *local_address1 = \
- ip4_interface_first_address (&ip4_main, swif1, &ia1);
-
-#define ADDRESSX2_IP6 \
- ip6_address_t *local_address0 = \
- ip6_interface_first_address (&ip6_main, swif0); \
- ip6_address_t *local_address1 = \
- ip6_interface_first_address (&ip6_main, swif1);
-
#define DPO_ADD_LOCK_FACE_IP4 hicn_face_ip4_add_and_lock
#define DPO_ADD_LOCK_FACE_IP6 hicn_face_ip6_add_and_lock
-//#define VLIB_EDGE_IP4 data_fwd_iface_ip4_vlib_edge
-//#define VLIB_EDGE_IP6 data_fwd_iface_ip6_vlib_edge
-
#define IP_HEADER_4 ip4_header_t
#define IP_HEADER_6 ip6_header_t
@@ -148,6 +126,7 @@ typedef enum
HICN4_IFACE_OUTPUT_NEXT_LOOKUP,
HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP,
HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN4_IFACE_OUTPUT_NEXT_PG,
HICN4_IFACE_OUTPUT_N_NEXT,
} hicn4_iface_output_next_t;
@@ -166,6 +145,7 @@ typedef enum
HICN6_IFACE_OUTPUT_NEXT_LOOKUP,
HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP,
HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN6_IFACE_OUTPUT_NEXT_PG,
HICN6_IFACE_OUTPUT_N_NEXT,
} hicn6_iface_output_next_t;
@@ -178,6 +158,9 @@ typedef enum
#define NEXT_UDP_ENCAP_IP4 HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP
#define NEXT_UDP_ENCAP_IP6 HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP
+#define NEXT_PG4 HICN4_IFACE_OUTPUT_NEXT_PG
+#define NEXT_PG6 HICN6_IFACE_OUTPUT_NEXT_PG
+
#define HICN_REWRITE_DATA_IP4 hicn_rewrite_iface_data4
#define HICN_REWRITE_DATA_IP6 hicn_rewrite_iface_data6
@@ -190,9 +173,11 @@ typedef enum
do \
{ \
vlib_buffer_t *b0; \
- u32 bi0, next0, next_iface0, sw_if0; \
+ u32 bi0, next0, next_iface0, sw_if0 = ~0; \
IP_HEADER_##ipv *ip_hdr = NULL; \
hicn_buffer_t *hicnb0; \
+ int ret0 = HICN_ERROR_NONE; \
+ u8 is_icmp0; \
/* Prefetch for next iteration. */ \
if (n_left_from > 1) \
{ \
@@ -213,41 +198,55 @@ typedef enum
hicnb0 = hicn_get_buffer (b0); \
ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current (b0); \
\
- stats.pkts_interest_count += 1; \
- \
- u8 is_icmp = ip_hdr->protocol == IPPROTO_ICMPV##ipv; \
- \
- next0 = \
- is_icmp * NEXT_MAPME_IP##ipv + (1 - is_icmp) * NEXT_INTEREST_IP##ipv; \
- \
- next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
- sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- \
- if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ /* Parse packet and cache useful info in opaque2 */ \
+ ret0 = hicn_interest_parse_pkt (b0); \
+ is_icmp0 = (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \
+ ret0 = (ret0 == HICN_ERROR_NONE) || \
+ (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \
+ if (PREDICT_FALSE (!ret0)) \
{ \
- next_iface0 = NEXT_UDP_ENCAP_IP4; \
- sw_if0 = ~0; \
+ next0 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \
} \
- else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ else \
{ \
- next_iface0 = NEXT_UDP_ENCAP_IP6; \
- sw_if0 = ~0; \
+ next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp0) * NEXT_INTEREST_IP##ipv; \
+ \
+ next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ \
+ if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ { \
+ next_iface0 = NEXT_UDP_ENCAP_IP4; \
+ sw_if0 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] != \
+ ADJ_INDEX_INVALID) \
+ { \
+ next_iface0 = NEXT_UDP_ENCAP_IP6; \
+ sw_if0 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \
+ { \
+ next_iface0 = NEXT_PG##ipv; \
+ } \
+ \
+ DPO_ADD_LOCK_FACE_IP##ipv ( \
+ &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr->src_address), \
+ sw_if0, vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \
} \
\
- DPO_ADD_LOCK_FACE_IP##ipv ( \
- &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr->src_address), sw_if0, \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \
- \
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
(b0->flags & VLIB_BUFFER_IS_TRACED))) \
{ \
TRACE_INPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = sw_if0; \
t->next_index = next0; \
+ t->error = ret0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
sizeof (t->packet_data)); \
} \
@@ -267,9 +266,12 @@ typedef enum
do \
{ \
vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1, next0, next1, next_iface0, next_iface1, sw_if0, sw_if1; \
+ u32 bi0, bi1, next0, next1; \
+ u32 next_iface0, next_iface1, sw_if0 = ~0, sw_if1 = ~0; \
+ u8 is_icmp0, is_icmp1; \
IP_HEADER_##ipv *ip_hdr0 = NULL; \
IP_HEADER_##ipv *ip_hdr1 = NULL; \
+ int ret0 = HICN_ERROR_NONE, ret1 = HICN_ERROR_NONE; \
hicn_buffer_t *hicnb0, *hicnb1; \
\
/* Prefetch for next iteration. */ \
@@ -300,63 +302,149 @@ typedef enum
\
stats.pkts_interest_count += 2; \
\
- u8 is_icmp0 = ip_hdr0->protocol == IPPROTO_ICMPV##ipv; \
- u8 is_icmp1 = ip_hdr1->protocol == IPPROTO_ICMPV##ipv; \
- \
- next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \
- (1 - is_icmp0) * NEXT_INTEREST_IP##ipv; \
- \
- next1 = is_icmp1 * NEXT_MAPME_IP##ipv + \
- (1 - is_icmp1) * NEXT_INTEREST_IP##ipv; \
- \
- next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
- sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- \
- if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ /* Parse packet and cache useful info in opaque2 */ \
+ ret0 = hicn_interest_parse_pkt (b0); \
+ ret1 = hicn_interest_parse_pkt (b1); \
+ is_icmp0 = ret0 == HICN_ERROR_PARSER_MAPME_PACKET; \
+ is_icmp1 = ret1 == HICN_ERROR_PARSER_MAPME_PACKET; \
+ ret0 = (ret0 == HICN_ERROR_NONE) || \
+ (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \
+ ret1 = (ret1 == HICN_ERROR_NONE) || \
+ (ret1 == HICN_ERROR_PARSER_MAPME_PACKET); \
+ \
+ if (PREDICT_TRUE (ret0 && ret1)) \
{ \
- next_iface0 = NEXT_UDP_ENCAP_IP4; \
- sw_if0 = ~0; \
+ next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp0) * NEXT_INTEREST_IP##ipv; \
+ \
+ next1 = is_icmp1 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp1) * NEXT_INTEREST_IP##ipv; \
+ \
+ next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ \
+ if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ { \
+ next_iface0 = NEXT_UDP_ENCAP_IP4; \
+ sw_if0 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] != \
+ ADJ_INDEX_INVALID) \
+ { \
+ next_iface0 = NEXT_UDP_ENCAP_IP6; \
+ sw_if0 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \
+ { \
+ next_iface0 = NEXT_PG##ipv; \
+ } \
+ \
+ next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \
+ sw_if1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
+ \
+ if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ { \
+ next_iface1 = NEXT_UDP_ENCAP_IP4; \
+ sw_if1 = ~0; \
+ } \
+ else if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] != \
+ ADJ_INDEX_INVALID) \
+ { \
+ next_iface1 = NEXT_UDP_ENCAP_IP6; \
+ sw_if1 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \
+ { \
+ next_iface1 = NEXT_PG##ipv; \
+ } \
+ \
+ DPO_ADD_LOCK_FACE_IP##ipv ( \
+ &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr0->src_address), \
+ sw_if0, vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \
+ \
+ DPO_ADD_LOCK_FACE_IP##ipv ( \
+ &(hicnb1->face_id), &hicnb1->flags, &(ip_hdr1->src_address), \
+ sw_if1, vnet_buffer (b1)->ip.adj_index[VLIB_RX], next_iface1); \
} \
- else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ else if (ret0 && !ret1) \
{ \
- next_iface0 = NEXT_UDP_ENCAP_IP6; \
- sw_if0 = ~0; \
+ next1 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \
+ next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp0) * NEXT_INTEREST_IP##ipv; \
+ next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ \
+ if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ { \
+ next_iface0 = NEXT_UDP_ENCAP_IP4; \
+ sw_if0 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] != \
+ ADJ_INDEX_INVALID) \
+ { \
+ next_iface0 = NEXT_UDP_ENCAP_IP6; \
+ sw_if0 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \
+ { \
+ next_iface0 = NEXT_PG##ipv; \
+ } \
+ \
+ DPO_ADD_LOCK_FACE_IP##ipv ( \
+ &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr0->src_address), \
+ sw_if0, vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \
} \
- \
- next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \
- sw_if1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
- \
- if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
- vnet_buffer (b1)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ else if (!ret0 && ret1) \
{ \
- next_iface1 = NEXT_UDP_ENCAP_IP4; \
- sw_if1 = ~0; \
+ next0 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \
+ next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \
+ sw_if1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
+ next1 = is_icmp1 * NEXT_MAPME_IP##ipv + \
+ (1 - is_icmp1) * NEXT_INTEREST_IP##ipv; \
+ \
+ if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ { \
+ next_iface1 = NEXT_UDP_ENCAP_IP4; \
+ sw_if1 = ~0; \
+ } \
+ else if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] != \
+ ADJ_INDEX_INVALID) \
+ { \
+ next_iface1 = NEXT_UDP_ENCAP_IP6; \
+ sw_if1 = ~0; \
+ } \
+ else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \
+ { \
+ next_iface1 = NEXT_PG##ipv; \
+ } \
+ \
+ DPO_ADD_LOCK_FACE_IP##ipv ( \
+ &(hicnb1->face_id), &hicnb1->flags, &(ip_hdr1->src_address), \
+ sw_if1, vnet_buffer (b1)->ip.adj_index[VLIB_RX], next_iface1); \
} \
- else if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \
- vnet_buffer (b1)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \
+ else \
{ \
- next_iface1 = NEXT_UDP_ENCAP_IP6; \
- sw_if1 = ~0; \
+ next0 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \
+ next1 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \
} \
\
- DPO_ADD_LOCK_FACE_IP##ipv ( \
- &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr0->src_address), sw_if0, \
- vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \
- \
- DPO_ADD_LOCK_FACE_IP##ipv ( \
- &(hicnb1->face_id), &hicnb1->flags, &(ip_hdr1->src_address), sw_if1, \
- vnet_buffer (b1)->ip.adj_index[VLIB_RX], next_iface1); \
- \
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
(b0->flags & VLIB_BUFFER_IS_TRACED))) \
{ \
TRACE_INPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = sw_if0; \
t->next_index = next0; \
+ t->error = ret0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
sizeof (t->packet_data)); \
} \
@@ -366,9 +454,10 @@ typedef enum
{ \
TRACE_INPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = sw_if1; \
t->next_index = next1; \
+ t->error = ret1; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \
sizeof (t->packet_data)); \
} \
@@ -435,9 +524,17 @@ hicn4_iface_input_format_trace (u8 *s, va_list *args)
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
hicn4_iface_input_trace_t *t = va_arg (*args, hicn4_iface_input_trace_t *);
- s = format (s, "IFACE_IP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- format_ip4_header, t->packet_data, sizeof (t->packet_data));
+ s = format (s, "IFACE_IP4_INPUT: pkt: %d, sw_if_index %d, next index %d",
+ (int) t->pkt_type, t->sw_if_index, t->next_index);
+
+ if (t->error)
+ {
+ s = format (s, " drop reason: %s", get_error_string (t->error));
+ }
+
+ s = format (s, "\n%U", format_ip4_header, t->packet_data,
+ sizeof (t->packet_data));
+
return (s);
}
@@ -544,6 +641,7 @@ hicn_rewrite_iface_data4 (vlib_main_t *vm, vlib_buffer_t *b0,
const hicn_face_t *iface, u32 *next)
{
ip4_header_t *ip0;
+ int ret = HICN_ERROR_NONE;
/* Get the pointer to the old ip and tcp header */
ip0 = vlib_buffer_get_current (b0);
@@ -563,9 +661,11 @@ hicn_rewrite_iface_data4 (vlib_main_t *vm, vlib_buffer_t *b0,
hicn_type_t type = hicn_get_buffer (b0)->type;
u8 flags = hicn_get_buffer (b0)->flags;
u8 reset_pl = flags & HICN_BUFFER_FLAGS_FROM_CS;
- int ret = hicn_ops_vft[type.l1]->rewrite_data (
- type, &hicn->protocol, &(iface->nat_addr), &(temp_addr), iface->pl_id,
- reset_pl);
+
+ ret = hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
+ &(iface->nat_addr), &(temp_addr),
+ iface->pl_id, reset_pl);
+
if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED)
{
ensure_offload_flags (b0, 1 /* is_v4 */);
@@ -577,6 +677,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0,
const hicn_face_t *iface, u32 *next)
{
ip6_header_t *ip0;
+ int ret = HICN_ERROR_NONE;
/* Get the pointer to the old ip and tcp header */
/* Copy the previous ip and tcp header to the new portion of memory */
@@ -598,9 +699,10 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0,
hicn_type_t type = hicn_get_buffer (b0)->type;
u8 flags = hicn_get_buffer (b0)->flags;
u8 reset_pl = flags & HICN_BUFFER_FLAGS_FROM_CS;
- int ret = hicn_ops_vft[type.l1]->rewrite_data (
- type, &hicn->protocol, &(iface->nat_addr), &(temp_addr), iface->pl_id,
- reset_pl);
+
+ ret = hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
+ &(iface->nat_addr), &(temp_addr),
+ iface->pl_id, reset_pl);
if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED)
{
@@ -653,7 +755,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0,
{ \
TRACE_OUTPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
t->next_index = next0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
@@ -731,7 +833,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0,
{ \
TRACE_OUTPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
t->next_index = next0; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \
@@ -743,7 +845,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0,
{ \
TRACE_OUTPUT_PKT_IP##ipv *t = \
vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST; \
t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
t->next_index = next1; \
clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \
@@ -824,7 +926,8 @@ VLIB_REGISTER_NODE (hicn4_iface_output_node) = {
.next_nodes = { [HICN4_IFACE_OUTPUT_NEXT_DROP] = "error-drop",
[HICN4_IFACE_OUTPUT_NEXT_LOOKUP] = "ip4-lookup",
[HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
- [HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" },
+ [HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap",
+ [HICN4_IFACE_OUTPUT_NEXT_PG] = "hicnpg-data" },
};
static uword
@@ -893,7 +996,8 @@ VLIB_REGISTER_NODE (hicn6_iface_output_node) = {
.next_nodes = { [HICN6_IFACE_OUTPUT_NEXT_DROP] = "error-drop",
[HICN6_IFACE_OUTPUT_NEXT_LOOKUP] = "ip6-lookup",
[HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
- [HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" },
+ [HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap",
+ [HICN6_IFACE_OUTPUT_NEXT_PG] = "hicnpg-data" },
};
/*
@@ -902,4 +1006,4 @@ VLIB_REGISTER_NODE (hicn6_iface_output_node) = {
* Local Variables:
* eval: (c-set-style "gnu")
* End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/hicn.c b/hicn-plugin/src/hicn.c
index 1131d4339..1789f5407 100644
--- a/hicn-plugin/src/hicn.c
+++ b/hicn-plugin/src/hicn.c
@@ -28,6 +28,7 @@
#include "face_db.h"
#include "udp_tunnels/udp_tunnel.h"
#include "route.h"
+#include "pg.h"
hicn_main_t hicn_main;
/* Module vars */
@@ -223,24 +224,29 @@ hicn_init (vlib_main_t *vm)
hicn_main_t *sm = &hicn_main;
- /* Init other elements in the 'main' struct */
+ // Init other elements in the 'main' struct
sm->is_enabled = 0;
error = hicn_api_plugin_hookup (vm);
- /* Init the dpo module */
+ // Init the dpo module
hicn_dpos_init ();
- /* Init the app manager */
+ // Init the app manager
address_mgr_init ();
+ // Init the face module
hicn_face_module_init (vm);
- /* Init the route module */
+ // Init the route module
hicn_route_init ();
+ // Init the UDP tunnels module
udp_tunnel_init ();
+ // Init the packet generator module
+ hicn_pg_init (vm);
+
return error;
}
diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h
index aaf16c917..22309e3e5 100644
--- a/hicn-plugin/src/hicn.h
+++ b/hicn-plugin/src/hicn.h
@@ -57,32 +57,44 @@ typedef u8 weight_t;
#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
#endif
-/* vlib_buffer cloning utilities impose that current_lentgh is more that
- * 2*CLIB_CACHE_LINE_BYTES. */
-/* This flag is used to mark packets whose lenght is less that
- * 2*CLIB_CACHE_LINE_BYTES. */
-#define HICN_BUFFER_FLAGS_PKT_LESS_TWO_CL 0x02
-#define HICN_BUFFER_FLAGS_FROM_CS 0x10
-
/* The following is stored in the opaque2 field in the vlib_buffer_t */
typedef struct
{
- /* hash of the name */
+ /**
+ * Hash of the name (8)
+ */
u64 name_hash;
- /* ids to prefetch a PIT/CS entry */
+ /**
+ * IDs to prefetch a PIT/CS entry (4+4+1+1)
+ */
u32 node_id;
u32 bucket_id;
u8 hash_entry_id;
u8 hash_bucket_flags;
+ /**
+ * hICN buffer flags (1)
+ */
u8 flags;
- u8 dpo_ctx_id; /* used for data path */
- u8 vft_id; /* " */
- hicn_face_id_t face_id; /* ingress iface, sizeof(u32) */
+ /**
+ * used for data path (1+1)
+ */
+ u8 dpo_ctx_id;
+ u8 vft_id;
+
+ /**
+ * Ingress face (4)
+ */
+ hicn_face_id_t face_id;
+ /**
+ * Cached packet info
+ */
hicn_type_t type;
+ hicn_name_t name;
+ u16 port;
} hicn_buffer_t;
STATIC_ASSERT (sizeof (hicn_buffer_t) <=
@@ -101,6 +113,28 @@ hicn_is_v6 (hicn_header_t *pkt_hdr)
return ((pkt_hdr->v4.ip.version_ihl >> 4) != 4);
}
+always_inline void
+hicn_buffer_get_name_and_namelen (vlib_buffer_t *b0, u8 **nameptr,
+ u16 *namelen)
+{
+ *nameptr = (u8 *) (&hicn_get_buffer (b0)->name);
+ *namelen = ip_address_is_v4 (&hicn_get_buffer (b0)->name.prefix) ?
+ HICN_V4_NAME_LEN :
+ HICN_V6_NAME_LEN;
+}
+
+always_inline u8
+hicn_buffer_is_v6 (vlib_buffer_t *b0)
+{
+ return hicn_get_buffer (b0)->type.l1 == IPPROTO_IPV6;
+}
+
+always_inline void
+hicn_buffer_set_flags (vlib_buffer_t *b, u8 flags)
+{
+ hicn_buffer_t *hb = hicn_get_buffer (b);
+ hb->flags |= flags;
+}
#endif /* __HICN_H__ */
/*
diff --git a/hicn-plugin/src/hicn_buffer_flags.h b/hicn-plugin/src/hicn_buffer_flags.h
new file mode 100644
index 000000000..7d99e6d33
--- /dev/null
+++ b/hicn-plugin/src/hicn_buffer_flags.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __HICN_BUFFER_FLAGS_H__
+#define __HICN_BUFFER_FLAGS_H__
+
+#define foreach_hicn_buffer_flag \
+ _ (0, NEW_FACE, "new face") \
+ _ (1, PKT_LESS_TWO_CL, "packet is less that 2 cache lines length") \
+ _ (2, FROM_UDP4_TUNNEL, "packet is from udp4 tunnel") \
+ _ (3, FROM_UDP6_TUNNEL, "packet is from udp6 tunnel") \
+ _ (4, FROM_CS, "packet is from cs") \
+ _ (5, FROM_PG, "packet is from packet generator")
+
+enum
+{
+ HICN_BUFFER_FLAGS_DEFAULT = 0,
+#define _(a, b, c) HICN_BUFFER_FLAGS_##b = (1 << a),
+ foreach_hicn_buffer_flag
+#undef _
+};
+
+#endif /* __HICN_BUFFER_FLAGS_H__ */ \ No newline at end of file
diff --git a/hicn-plugin/src/interest_hitcs_node.c b/hicn-plugin/src/interest_hitcs_node.c
index 947b4cb68..1af21191c 100644
--- a/hicn-plugin/src/interest_hitcs_node.c
+++ b/hicn-plugin/src/interest_hitcs_node.c
@@ -90,7 +90,6 @@ hicn_interest_hitcs_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
hicn_interest_hitcs_runtime_t *rt;
vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
f64 tnow;
- int ret;
rt = vlib_node_get_runtime_data (vm, hicn_interest_hitcs_node.index);
@@ -116,8 +115,6 @@ hicn_interest_hitcs_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
u16 namelen;
u32 bi0;
u32 next0 = HICN_INTEREST_HITCS_NEXT_ERROR_DROP;
- hicn_name_t name;
- hicn_header_t *hicn0;
hicn_buffer_t *hicnb0;
hicn_hash_node_t *node0;
hicn_pcs_entry_t *pitp;
@@ -150,8 +147,8 @@ hicn_interest_hitcs_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
hicn_get_internal_state (hicnb0, rt->pitcs, &node0, &strategy_vft0,
&dpo_vft0, &dpo_ctx_id0, &hash_entry0);
- ret = hicn_interest_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
- nameptr = (u8 *) (&name);
+ hicn_buffer_get_name_and_namelen (b0, &nameptr, &namelen);
+ isv6 = hicn_buffer_is_v6 (b0);
pitp = hicn_pit_get_data (node0);
dpo_id_t hicn_dpo_id0 = { .dpoi_type =
@@ -160,8 +157,7 @@ hicn_interest_hitcs_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
.dpoi_next_node = 0,
.dpoi_index = dpo_ctx_id0 };
- if (PREDICT_FALSE (ret != HICN_ERROR_NONE ||
- !hicn_node_compare (nameptr, namelen, node0)))
+ if (PREDICT_FALSE (!hicn_node_compare (nameptr, namelen, node0)))
{
/* Remove lock from the entry */
hicn_pcs_remove_lock (rt->pitcs, &pitp, &node0, vm, hash_entry0,
@@ -209,7 +205,7 @@ hicn_interest_hitcs_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
{
hicn_interest_hitcs_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_INTEREST;
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST;
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
t->next_index = next0;
}
@@ -285,4 +281,4 @@ VLIB_REGISTER_NODE (hicn_interest_hitcs_node) = {
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/interest_hitpit.h b/hicn-plugin/src/interest_hitpit.h
index 18ef94aa7..46659e67c 100644
--- a/hicn-plugin/src/interest_hitpit.h
+++ b/hicn-plugin/src/interest_hitpit.h
@@ -46,7 +46,7 @@ typedef struct
{
u32 next_index;
u32 sw_if_index;
- u8 pkt_type;
+ u32 pkt_type;
} hicn_interest_hitpit_trace_t;
typedef enum
@@ -65,4 +65,4 @@ typedef enum
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/interest_hitpit_node.c b/hicn-plugin/src/interest_hitpit_node.c
index 33dc782cd..c98baf7e9 100644
--- a/hicn-plugin/src/interest_hitpit_node.c
+++ b/hicn-plugin/src/interest_hitpit_node.c
@@ -79,8 +79,6 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
u16 namelen;
u32 bi0;
u32 next0 = HICN_INTEREST_HITPIT_NEXT_ERROR_DROP;
- hicn_name_t name;
- hicn_header_t *hicn0;
hicn_hash_node_t *node0;
const hicn_strategy_vft_t *strategy_vft0;
const hicn_dpo_vft_t *dpo_vft0;
@@ -92,7 +90,6 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
u32 outfaces_len;
hicn_hash_entry_t *hash_entry0;
hicn_buffer_t *hicnb0;
- int ret;
/* Prefetch for next iteration. */
if (n_left_from > 1)
@@ -118,8 +115,9 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
hicn_get_internal_state (hicnb0, rt->pitcs, &node0, &strategy_vft0,
&dpo_vft0, &dpo_ctx_id0, &hash_entry0);
- ret = hicn_interest_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
- nameptr = (u8 *) (&name);
+ hicn_buffer_get_name_and_namelen (b0, &nameptr, &namelen);
+ isv6 = hicn_buffer_is_v6 (b0);
+
pitp = hicn_pit_get_data (node0);
dpo_id_t hicn_dpo_id0 = { .dpoi_type =
dpo_vft0->hicn_dpo_get_type (),
@@ -131,8 +129,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
* Check if the hit is instead a collision in the
* hash table. Unlikely to happen.
*/
- if (PREDICT_FALSE (ret != HICN_ERROR_NONE ||
- !hicn_node_compare (nameptr, namelen, node0)))
+ if (PREDICT_FALSE (!hicn_node_compare (nameptr, namelen, node0)))
{
stats.interests_hash_collision++;
/* Remove lock from the entry */
@@ -227,7 +224,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
hicn_interest_hitpit_trace_t *t =
vlib_add_trace (vm, node, local_b0,
sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_INTEREST;
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST;
t->sw_if_index = vnet_buffer (local_b0)
->sw_if_index[VLIB_RX];
t->next_index = next0;
@@ -266,7 +263,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
{
hicn_interest_hitpit_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_INTEREST;
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST;
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
t->next_index = next0;
}
@@ -354,4 +351,4 @@ VLIB_REGISTER_NODE(hicn_interest_hitpit_node) =
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/interest_pcslookup_node.c b/hicn-plugin/src/interest_pcslookup_node.c
index ff0da12d7..e569573b7 100644
--- a/hicn-plugin/src/interest_pcslookup_node.c
+++ b/hicn-plugin/src/interest_pcslookup_node.c
@@ -57,7 +57,6 @@ hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
hicn_interest_pcslookup_next_t next_index;
hicn_interest_pcslookup_runtime_t *rt;
vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- int ret;
rt = vlib_node_get_runtime_data (vm, hicn_interest_pcslookup_node.index);
@@ -76,14 +75,11 @@ hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
while (n_left_from > 0 && n_left_to_next > 0)
{
vlib_buffer_t *b0;
- u8 isv6;
u8 *nameptr;
u16 namelen;
u32 bi0;
u32 next0 = HICN_INTEREST_PCSLOOKUP_NEXT_ERROR_DROP;
u64 name_hash = 0;
- hicn_name_t name;
- hicn_header_t *hicn0;
u32 node_id0 = 0;
index_t dpo_ctx_id0 = 0;
u8 vft_id0 = 0;
@@ -109,19 +105,15 @@ hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
- ret = hicn_interest_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
- if (PREDICT_TRUE (ret == HICN_ERROR_NONE))
- {
- next0 = HICN_INTEREST_PCSLOOKUP_NEXT_STRATEGY;
- }
- nameptr = (u8 *) (&name);
+ hicn_buffer_get_name_and_namelen (b0, &nameptr, &namelen);
+
+ next0 = HICN_INTEREST_PCSLOOKUP_NEXT_STRATEGY;
stats.pkts_processed++;
if (PREDICT_FALSE (
- ret != HICN_ERROR_NONE ||
hicn_hashtb_fullhash (nameptr, namelen, &name_hash) !=
- HICN_ERROR_NONE))
+ HICN_ERROR_NONE))
{
next0 = HICN_INTEREST_PCSLOOKUP_NEXT_ERROR_DROP;
}
@@ -149,7 +141,7 @@ hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
{
hicn_interest_pcslookup_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_INTEREST;
+ t->pkt_type = HICN_PACKET_TYPE_INTEREST;
t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
t->next_index = next0;
}
@@ -226,4 +218,4 @@ VLIB_REGISTER_NODE(hicn_interest_pcslookup_node) =
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/parser.h b/hicn-plugin/src/parser.h
index 0e60c526f..29405ebec 100644
--- a/hicn-plugin/src/parser.h
+++ b/hicn-plugin/src/parser.h
@@ -25,93 +25,149 @@
* @file parser.h
*/
-/*
- * Key type codes for header, header tlvs, body tlvs, and child tlvs
- */
-
-// FIXME(reuse lib struct, no more control ?)
-enum hicn_pkt_type_e
-{
- HICN_PKT_TYPE_INTEREST = 0,
- HICN_PKT_TYPE_CONTENT = 1,
-};
-
/**
- * @brief Parse an interest packet
+ * @brief Parse a interest packet
*
* @param pkt vlib buffer holding the interest
- * @param name return variable that will point to the hicn name
- * @param namelen return valiable that will hold the length of the name
- * @param pkt_hdrp return valiable that will point to the packet header
- * @param isv6 return variable that will be equale to 1 is the header is ipv6
+ * @param name [RETURNED] variable that will point to the hicn name
+ * @param namelen [RETURNED] variable that will hold the length of the name
+ * @param port [RETURNED] variable that will hold the source port of the packet
+ * @param pkt_hdrp [RETURNED] valiable that will point to the packet header
+ * @param isv6 [RETURNED] variable that will be equale to 1 is the header is
+ * ipv6
*/
always_inline int
-hicn_interest_parse_pkt (vlib_buffer_t *pkt, hicn_name_t *name, u16 *namelen,
- hicn_header_t **pkt_hdrp, u8 *isv6)
+hicn_interest_parse_pkt (vlib_buffer_t *pkt)
{
if (pkt == NULL)
return HICN_ERROR_PARSER_PKT_INVAL;
- hicn_header_t *pkt_hdr = vlib_buffer_get_current (pkt);
- *pkt_hdrp = pkt_hdr;
- u8 *ip_pkt = vlib_buffer_get_current (pkt);
- *isv6 = hicn_is_v6 (pkt_hdr);
- u8 ip_proto = (*isv6) * IPPROTO_IPV6;
- u8 next_proto_offset = 6 + (1 - *isv6) * 3;
- // in the ipv6 header the next header field is at byte 6
- // in the ipv4 header the protocol field is at byte 9
- hicn_type_t type =
- (hicn_type_t){ { .l4 = IPPROTO_NONE,
- .l3 = ip_pkt[next_proto_offset] == IPPROTO_UDP ?
- IPPROTO_ENCAP :
- IPPROTO_NONE,
- .l2 = ip_pkt[next_proto_offset],
- .l1 = ip_proto } };
+
+ int ret = HICN_LIB_ERROR_NONE;
+
+ hicn_header_t *pkt_hdr;
+ u8 *ip_pkt;
+ u8 ip_proto;
+ u8 next_proto_offset;
+ hicn_type_t type;
+ hicn_name_t *name;
+ u16 *port;
+ int isv6;
+
+ // start parsing first fields to get the protocols
+ pkt_hdr = vlib_buffer_get_current (pkt);
+ isv6 = hicn_is_v6 (pkt_hdr);
+
+ ip_pkt = vlib_buffer_get_current (pkt);
+ ip_proto = (1 - isv6) * IPPROTO_IP + (isv6) *IPPROTO_IPV6;
+
+ // in the ipv6 header the next header field is at byte 6 in the ipv4
+ // header the protocol field is at byte 9
+ next_proto_offset = 6 + (1 - isv6) * 3;
+
+ // get type info
+ type.l4 = IPPROTO_NONE;
+ type.l3 =
+ ip_pkt[next_proto_offset] == IPPROTO_UDP ? IPPROTO_ENCAP : IPPROTO_NONE;
+ type.l2 = ip_pkt[next_proto_offset];
+ type.l1 = ip_proto;
+
+ // cache hicn packet type in opaque2
hicn_get_buffer (pkt)->type = type;
- hicn_ops_vft[type.l1]->get_interest_name (type, &pkt_hdr->protocol, name);
- *namelen = (1 - (*isv6)) * HICN_V4_NAME_LEN + (*isv6) * HICN_V6_NAME_LEN;
+ // get name and name length
+ name = &hicn_get_buffer (pkt)->name;
+ ret =
+ hicn_ops_vft[type.l1]->get_interest_name (type, &pkt_hdr->protocol, name);
+ if (PREDICT_FALSE (ret))
+ {
+ if (type.l2 == IPPROTO_ICMPV4 || type.l2 == IPPROTO_ICMPV6)
+ {
+ return HICN_ERROR_PARSER_MAPME_PACKET;
+ }
+ return HICN_ERROR_PARSER_PKT_INVAL;
+ }
- return HICN_ERROR_NONE;
+ // get source port
+ port = &hicn_get_buffer (pkt)->port;
+ hicn_ops_vft[type.l1]->get_source_port (type, &pkt_hdr->protocol, port);
+ if (PREDICT_FALSE (ret))
+ {
+ return HICN_ERROR_PARSER_PKT_INVAL;
+ }
+
+ return ret;
}
/**
* @brief Parse a data packet
*
- * @param pkt vlib buffer holding the interest
- * @param name return variable that will point to the hicn name
- * @param namelen return valiable that will hold the length of the name
- * @param pkt_hdrp return valiable that will point to the packet header
- * @param isv6 return variable that will be equale to 1 is the header is ipv6
+ * @param pkt vlib buffer holding the data
+ * @param name [RETURNED] variable that will point to the hicn name
+ * @param namelen [RETURNED] variable that will hold the length of the name
+ * @param port [RETURNED] variable that will hold the source port of the packet
+ * @param pkt_hdrp [RETURNED] valiable that will point to the packet header
+ * @param isv6 [RETURNED] variable that will be equale to 1 is the header is
+ * ipv6
*/
always_inline int
-hicn_data_parse_pkt (vlib_buffer_t *pkt, hicn_name_t *name, u16 *namelen,
- hicn_header_t **pkt_hdrp, u8 *isv6)
+hicn_data_parse_pkt (vlib_buffer_t *pkt)
{
if (pkt == NULL)
return HICN_ERROR_PARSER_PKT_INVAL;
- hicn_header_t *pkt_hdr = vlib_buffer_get_current (pkt);
- *pkt_hdrp = pkt_hdr;
- *pkt_hdrp = pkt_hdr;
- u8 *ip_pkt = vlib_buffer_get_current (pkt);
- *isv6 = hicn_is_v6 (pkt_hdr);
- u8 ip_proto = (*isv6) * IPPROTO_IPV6;
- /*
- * in the ipv6 header the next header field is at byte 6 in the ipv4
- * header the protocol field is at byte 9
- */
- u8 next_proto_offset = 6 + (1 - *isv6) * 3;
- hicn_type_t type =
- (hicn_type_t){ { .l4 = IPPROTO_NONE,
- .l3 = ip_pkt[next_proto_offset] == IPPROTO_UDP ?
- IPPROTO_ENCAP :
- IPPROTO_NONE,
- .l2 = ip_pkt[next_proto_offset],
- .l1 = ip_proto } };
+
+ int ret = HICN_LIB_ERROR_NONE;
+
+ hicn_header_t *pkt_hdr;
+ u8 *ip_pkt;
+ u8 ip_proto;
+ int isv6;
+ u8 next_proto_offset;
+ hicn_type_t type;
+ hicn_name_t *name;
+ u16 *port;
+
+ // start parsing first fields to get the protocols
+ pkt_hdr = vlib_buffer_get_current (pkt);
+ isv6 = hicn_is_v6 (pkt_hdr);
+
+ ip_pkt = vlib_buffer_get_current (pkt);
+ ip_proto = (1 - isv6) * IPPROTO_IP + (isv6) *IPPROTO_IPV6;
+
+ // in the ipv6 header the next header field is at byte 6 in the ipv4
+ // header the protocol field is at byte 9
+ next_proto_offset = 6 + (1 - isv6) * 3;
+
+ // get type info
+ type.l4 = IPPROTO_NONE;
+ type.l3 =
+ ip_pkt[next_proto_offset] == IPPROTO_UDP ? IPPROTO_ENCAP : IPPROTO_NONE;
+ type.l2 = ip_pkt[next_proto_offset];
+ type.l1 = ip_proto;
+
+ // cache hicn packet type in opaque2
hicn_get_buffer (pkt)->type = type;
- hicn_ops_vft[type.l1]->get_data_name (type, &pkt_hdr->protocol, name);
- *namelen = (1 - (*isv6)) * HICN_V4_NAME_LEN + (*isv6) * HICN_V6_NAME_LEN;
- return HICN_ERROR_NONE;
+ // get name and name length
+ name = &hicn_get_buffer (pkt)->name;
+ ret = hicn_ops_vft[type.l1]->get_data_name (type, &pkt_hdr->protocol, name);
+ if (PREDICT_FALSE (ret))
+ {
+ if (type.l2 == IPPROTO_ICMPV4 || type.l2 == IPPROTO_ICMPV6)
+ {
+ return HICN_ERROR_PARSER_MAPME_PACKET;
+ }
+ return HICN_ERROR_PARSER_PKT_INVAL;
+ }
+
+ // get source port
+ port = &hicn_get_buffer (pkt)->port;
+ hicn_ops_vft[type.l1]->get_source_port (type, &pkt_hdr->protocol, port);
+ if (PREDICT_FALSE (ret))
+ {
+ return HICN_ERROR_PARSER_PKT_INVAL;
+ }
+
+ return ret;
}
#endif /* // __HICN_PARSER_H__ */
@@ -120,4 +176,4 @@ hicn_data_parse_pkt (vlib_buffer_t *pkt, hicn_name_t *name, u16 *namelen,
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/pg.c b/hicn-plugin/src/pg.c
index b77e8fcac..05172345b 100644
--- a/hicn-plugin/src/pg.c
+++ b/hicn-plugin/src/pg.c
@@ -18,57 +18,13 @@
#include <vnet/pg/pg.h>
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
+#include <vnet/fib/fib_entry_track.h>
#include "hicn.h"
#include "pg.h"
#include "parser.h"
#include "infra.h"
-
-/* Registration struct for a graph node */
-vlib_node_registration_t hicn_pg_interest_node;
-vlib_node_registration_t hicn_pg_data_node;
-
-/* Stats, which end up called "error" even though they aren't... */
-#define foreach_hicnpg_error \
- _ (PROCESSED, "hICN PG packets processed") \
- _ (DROPPED, "hICN PG packets dropped") \
- _ (INTEREST_MSGS_GENERATED, "hICN PG Interests generated") \
- _ (CONTENT_MSGS_RECEIVED, "hICN PG Content msgs received")
-
-typedef enum
-{
-#define _(sym, str) HICNPG_ERROR_##sym,
- foreach_hicnpg_error
-#undef _
- HICNPG_N_ERROR,
-} hicnpg_error_t;
-
-static char *hicnpg_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnpg_error
-#undef _
-};
-
-/*
- * Next graph nodes, which reference the list in the actual registration
- * block below
- */
-typedef enum
-{
- HICNPG_INTEREST_NEXT_V4_LOOKUP,
- HICNPG_INTEREST_NEXT_V6_LOOKUP,
- HICNPG_INTEREST_NEXT_DROP,
- HICNPG_N_NEXT,
-} hicnpg_interest_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u16 msg_type;
-} hicnpg_trace_t;
+#include "route.h"
hicnpg_main_t hicnpg_main = { .index = (u32) 0,
.index_ifaces = (u32) 1,
@@ -78,1183 +34,281 @@ hicnpg_main_t hicnpg_main = { .index = (u32) 0,
.n_ifaces = (u32) 1,
.sw_if = (u32) 0 };
-hicnpg_server_main_t hicnpg_server_main = {
- .node_index = 0,
-};
-
-/* packet trace format function */
-static u8 *
-format_hicnpg_trace (u8 *s, va_list *args)
-{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- hicnpg_trace_t *t = va_arg (*args, hicnpg_trace_t *);
-
- s = format (s, "HICNPG: pkt: %d, msg %d, sw_if_index %d, next index %d",
- (int) t->pkt_type, (int) t->msg_type, t->sw_if_index,
- t->next_index);
- return (s);
-}
-
-always_inline void hicn_rewrite_interestv4 (vlib_main_t *vm, vlib_buffer_t *b0,
- u32 seq_number, u16 lifetime,
- u32 next_flow, u32 iface);
-
-always_inline void hicn_rewrite_interestv6 (vlib_main_t *vm, vlib_buffer_t *b0,
- u32 seq_number, u16 lifetime,
- u32 next_flow, u32 iface);
-
-always_inline void convert_interest_to_data_v4 (vlib_main_t *vm,
- vlib_buffer_t *b0,
- vlib_buffer_t *rb, u32 bi0);
-
-always_inline void convert_interest_to_data_v6 (vlib_main_t *vm,
- vlib_buffer_t *b0,
- vlib_buffer_t *rb, u32 bi0);
-
-always_inline void calculate_tcp_checksum_v4 (vlib_main_t *vm,
- vlib_buffer_t *b0);
+/**
+ * Pool of hicnpg_server_t
+ */
+hicnpg_server_t *hicnpg_server_pool;
-always_inline void calculate_tcp_checksum_v6 (vlib_main_t *vm,
- vlib_buffer_t *b0);
/*
- * Node function for the icn packet-generator client. The goal here is to
- * manipulate/tweak a stream of packets that have been injected by the vpp
- * packet generator to generate icn request traffic.
+ * hicnph servrer FIB node type
*/
-static uword
-hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame)
-{
- u32 n_left_from, *from, *to_next;
- hicnpg_interest_next_t next_index;
- u32 pkts_processed = 0, pkts_dropped = 0;
- u32 interest_msgs_generated = 0;
- u32 bi0, bi1;
- vlib_buffer_t *b0, *b1;
- u8 pkt_type0 = 0, pkt_type1 = 0;
- u16 msg_type0 = 0, msg_type1 = 0;
- hicn_header_t *hicn0 = NULL, *hicn1 = NULL;
- hicn_name_t name0, name1;
- u16 namelen0, namelen1;
- hicnpg_main_t *hpgm = &hicnpg_main;
- int iface = 0;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- u32 next0 = HICNPG_INTEREST_NEXT_DROP;
- u32 next1 = HICNPG_INTEREST_NEXT_DROP;
- u32 sw_if_index0 = ~0, sw_if_index1 = ~0;
- u8 isv6_0;
- u8 isv6_1;
-
- /* Prefetch next iteration. */
- {
- vlib_buffer_t *p2, *p3;
-
- p2 = vlib_get_buffer (vm, from[2]);
- p3 = vlib_get_buffer (vm, from[3]);
-
- vlib_prefetch_buffer_header (p2, LOAD);
- vlib_prefetch_buffer_header (p3, LOAD);
-
- CLIB_PREFETCH (p2->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
- CLIB_PREFETCH (p3->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
- }
-
- /*
- * speculatively enqueue b0 and b1 to the current
- * next frame
- */
- to_next[0] = bi0 = from[0];
- to_next[1] = bi1 = from[1];
- from += 2;
- to_next += 2;
- n_left_from -= 2;
- n_left_to_next -= 2;
-
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
- vnet_buffer (b0)->sw_if_index[VLIB_RX] = hpgm->sw_if;
- vnet_buffer (b1)->sw_if_index[VLIB_RX] = hpgm->sw_if;
-
- /* Check icn packets, locate names */
- if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0,
- &isv6_0) == HICN_ERROR_NONE)
- {
- /* this node grabs only interests */
-
- /* Increment the appropriate message counter */
- interest_msgs_generated++;
-
- iface = (hpgm->index_ifaces % hpgm->n_ifaces);
- /* Rewrite and send */
- isv6_0 ?
- hicn_rewrite_interestv6 (
- vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
- hpgm->interest_lifetime, hpgm->index % hpgm->n_flows,
- iface) :
- hicn_rewrite_interestv4 (
- vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
- hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface);
-
- hpgm->index_ifaces++;
- if (iface == (hpgm->n_ifaces - 1))
- hpgm->index++;
-
- next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP :
- HICNPG_INTEREST_NEXT_V4_LOOKUP;
- }
- if (hicn_interest_parse_pkt (b1, &name1, &namelen1, &hicn1,
- &isv6_1) == HICN_ERROR_NONE)
- {
- /* this node grabs only interests */
-
- /* Increment the appropriate message counter */
- interest_msgs_generated++;
-
- iface = (hpgm->index_ifaces % hpgm->n_ifaces);
- /* Rewrite and send */
- isv6_1 ?
- hicn_rewrite_interestv6 (
- vm, b1, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
- hpgm->interest_lifetime, hpgm->index % hpgm->n_flows,
- iface) :
- hicn_rewrite_interestv4 (
- vm, b1, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
- hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface);
-
- hpgm->index_ifaces++;
- if (iface == (hpgm->n_ifaces - 1))
- hpgm->index++;
-
- next1 = isv6_1 ? HICNPG_INTEREST_NEXT_V6_LOOKUP :
- HICNPG_INTEREST_NEXT_V4_LOOKUP;
- }
- /* Send pkt to next node */
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
- vnet_buffer (b1)->sw_if_index[VLIB_TX] = ~0;
-
- pkts_processed += 2;
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
- {
- if (b0->flags & VLIB_BUFFER_IS_TRACED)
- {
- hicnpg_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = pkt_type0;
- t->msg_type = msg_type0;
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
- if (b1->flags & VLIB_BUFFER_IS_TRACED)
- {
- hicnpg_trace_t *t =
- vlib_add_trace (vm, node, b1, sizeof (*t));
- t->pkt_type = pkt_type1;
- t->msg_type = msg_type1;
- t->sw_if_index = sw_if_index1;
- t->next_index = next1;
- }
- }
- if (next0 == HICNPG_INTEREST_NEXT_DROP)
- {
- pkts_dropped++;
- }
- if (next1 == HICNPG_INTEREST_NEXT_DROP)
- {
- pkts_dropped++;
- }
- /*
- * verify speculative enqueues, maybe switch current
- * next frame
- */
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
- n_left_to_next, bi0, bi1, next0,
- next1);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 next0 = HICNPG_INTEREST_NEXT_DROP;
- u32 sw_if_index0;
- u8 isv6_0;
-
- /* speculatively enqueue b0 to the current next frame */
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- vnet_buffer (b0)->sw_if_index[VLIB_RX] = hpgm->sw_if;
-
- /* Check icn packets, locate names */
- if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0,
- &isv6_0) == HICN_ERROR_NONE)
- {
- /* this node grabs only interests */
-
- /* Increment the appropriate message counter */
- interest_msgs_generated++;
-
- iface = (hpgm->index_ifaces % hpgm->n_ifaces);
-
- /* Rewrite and send */
- isv6_0 ?
- hicn_rewrite_interestv6 (
- vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
- hpgm->interest_lifetime, hpgm->index % hpgm->n_flows,
- iface) :
- hicn_rewrite_interestv4 (
- vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
- hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface);
-
- hpgm->index_ifaces++;
- if (iface == (hpgm->n_ifaces - 1))
- hpgm->index++;
-
- next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP :
- HICNPG_INTEREST_NEXT_V4_LOOKUP;
- }
- /* Send pkt to ip lookup */
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
+fib_node_type_t hicnpg_server_fib_node_type;
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- hicnpg_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = pkt_type0;
- t->msg_type = msg_type0;
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
- pkts_processed += 1;
-
- if (next0 == HICNPG_INTEREST_NEXT_DROP)
- {
- pkts_dropped++;
- }
- /*
- * verify speculative enqueue, maybe switch current
- * next frame
- */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
- n_left_to_next, bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, hicn_pg_interest_node.index,
- HICNPG_ERROR_PROCESSED, pkts_processed);
- vlib_node_increment_counter (vm, hicn_pg_interest_node.index,
- HICNPG_ERROR_DROPPED, pkts_dropped);
- vlib_node_increment_counter (vm, hicn_pg_interest_node.index,
- HICNPG_ERROR_INTEREST_MSGS_GENERATED,
- interest_msgs_generated);
+/**
+ * Registered DPO type.
+ */
+dpo_type_t hicnpg_server_dpo_type;
- return (frame->n_vectors);
+static void
+hicnpg_server_restack (hicnpg_server_t *hicnpg_server)
+{
+ dpo_stack (
+ hicnpg_server_dpo_type, fib_proto_to_dpo (hicnpg_server->prefix.fp_proto),
+ &hicnpg_server->dpo,
+ fib_entry_contribute_ip_forwarding (hicnpg_server->fib_entry_index));
}
-void
-hicn_rewrite_interestv4 (vlib_main_t *vm, vlib_buffer_t *b0, u32 seq_number,
- u16 interest_lifetime, u32 next_flow, u32 iface)
+static hicnpg_server_t *
+hicnpg_server_from_fib_node (fib_node_t *node)
{
- hicn_header_t *h0 = vlib_buffer_get_current (b0);
-
- /* Generate the right src and dst corresponding to flow and iface */
- ip46_address_t src_addr = {
- .ip4 = hicnpg_main.pgen_clt_src_addr.ip4,
- };
- hicn_name_t dst_name = {
- .prefix.ip4 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip4,
- .suffix = seq_number,
- };
-
- src_addr.ip4.as_u32 += clib_host_to_net_u32 (iface);
- dst_name.prefix.ip4.as_u32 += clib_net_to_host_u32 (next_flow);
-
- /* Update locator and name */
- hicn_type_t type = hicn_get_buffer (b0)->type;
- HICN_OPS4->set_interest_locator (type, &h0->protocol, &src_addr);
- HICN_OPS4->set_interest_name (type, &h0->protocol, &dst_name);
-
- /* Update lifetime (currently L4 checksum is not updated) */
- HICN_OPS4->set_lifetime (type, &h0->protocol, interest_lifetime);
-
- /* Update checksums */
- HICN_OPS4->update_checksums (type, &h0->protocol, 0, 0);
+ ASSERT (hicnpg_server_fib_node_type == node->fn_type);
+ return ((hicnpg_server_t *) (((char *) node) -
+ STRUCT_OFFSET_OF (hicnpg_server_t, fib_node)));
}
/**
- * @brief Rewrite the IPv6 header as the next generated packet
- *
- * Set up a name prefix
- * - etiher generate interest in which the name varies only after the prefix
- * (inc : seq_number), then the flow acts on the prefix (CHECK)
- * seq_number => TCP, FLOW =>
- *
- * SRC : pgen_clt_src_addr.ip6 DST = generate name (pgen_clt_hicn_name.ip6)
- * ffff:ffff:ffff:ffff ffff:ffff:ffff:ffff
- * \__/ \__/
- * +iface + flow
- * Source is used to emulate different consumers.
- * FIXME iface is ill-named, better name it consumer id
- * Destination is used to iterate on the content.
+ * Function definition to backwalk a FIB node
*/
-void
-hicn_rewrite_interestv6 (vlib_main_t *vm, vlib_buffer_t *b0, u32 seq_number,
- u16 interest_lifetime, u32 next_flow, u32 iface)
+static fib_node_back_walk_rc_t
+hicnpg_server_fib_back_walk (fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
{
- hicn_header_t *h0 = vlib_buffer_get_current (b0);
-
- /* Generate the right src and dst corresponding to flow and iface */
- ip46_address_t src_addr = {
- .ip6 = hicnpg_main.pgen_clt_src_addr.ip6,
- };
- hicn_name_t dst_name = {
- .prefix.ip6 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip6,
- .suffix = seq_number,
- };
- src_addr.ip6.as_u32[3] += clib_host_to_net_u32 (iface);
- dst_name.prefix.ip6.as_u32[3] += clib_net_to_host_u32 (next_flow);
+ hicnpg_server_restack (hicnpg_server_from_fib_node (node));
- /* Update locator and name */
- hicn_type_t type = hicn_get_buffer (b0)->type;
- HICN_OPS6->set_interest_locator (type, &h0->protocol, &src_addr);
- HICN_OPS6->set_interest_name (type, &h0->protocol, &dst_name);
-
- /* Update lifetime */
- HICN_OPS6->set_lifetime (type, &h0->protocol, interest_lifetime);
-
- /* Update checksums */
- calculate_tcp_checksum_v6 (vm, b0);
+ return FIB_NODE_BACK_WALK_CONTINUE;
}
-void
-calculate_tcp_checksum_v4 (vlib_main_t *vm, vlib_buffer_t *b0)
+/**
+ * Function definition to get a FIB node from its index
+ */
+static fib_node_t *
+hicnpg_server_fib_node_get (fib_node_index_t index)
{
- ip4_header_t *ip0;
- tcp_header_t *tcp0;
- ip_csum_t sum0;
- u32 tcp_len0;
-
- ip0 = (ip4_header_t *) (vlib_buffer_get_current (b0));
- tcp0 =
- (tcp_header_t *) (vlib_buffer_get_current (b0) + sizeof (ip4_header_t));
- tcp_len0 = clib_net_to_host_u16 (ip0->length) - sizeof (ip4_header_t);
-
- /* Initialize checksum with header. */
- if (BITS (sum0) == 32)
- {
- sum0 = clib_mem_unaligned (&ip0->src_address, u32);
- sum0 =
- ip_csum_with_carry (sum0, clib_mem_unaligned (&ip0->dst_address, u32));
- }
- else
- sum0 = clib_mem_unaligned (&ip0->src_address, u64);
-
- sum0 = ip_csum_with_carry (
- sum0, clib_host_to_net_u32 (tcp_len0 + (ip0->protocol << 16)));
-
- /* Invalidate possibly old checksum. */
- tcp0->checksum = 0;
+ hicnpg_server_t *hpg_server;
- u32 tcp_offset = sizeof (ip4_header_t);
- sum0 = ip_incremental_checksum_buffer (vm, b0, tcp_offset, tcp_len0, sum0);
+ hpg_server = pool_elt_at_index (hicnpg_server_pool, index);
- tcp0->checksum = ~ip_csum_fold (sum0);
+ return (&hpg_server->fib_node);
}
-void
-calculate_tcp_checksum_v6 (vlib_main_t *vm, vlib_buffer_t *b0)
+/**
+ * Function definition to inform the FIB node that its last lock has gone.
+ */
+static void
+hicnpg_server_fib_last_lock_gone (fib_node_t *node)
{
- ip6_header_t *ip0;
- tcp_header_t *tcp0;
- ip_csum_t sum0;
- u32 tcp_len0;
-
- ip0 = (ip6_header_t *) (vlib_buffer_get_current (b0));
- tcp0 =
- (tcp_header_t *) (vlib_buffer_get_current (b0) + sizeof (ip6_header_t));
- tcp_len0 = clib_net_to_host_u16 (ip0->payload_length);
+ hicnpg_server_t *hpg_server;
- /* Initialize checksum with header. */
- if (BITS (sum0) == 32)
- {
- sum0 = clib_mem_unaligned (&ip0->src_address, u32);
- sum0 =
- ip_csum_with_carry (sum0, clib_mem_unaligned (&ip0->dst_address, u32));
- }
- else
- sum0 = clib_mem_unaligned (&ip0->src_address, u64);
-
- sum0 = ip_csum_with_carry (
- sum0, clib_host_to_net_u32 (tcp_len0 + (ip0->protocol << 16)));
+ hpg_server = hicnpg_server_from_fib_node (node);
- /* Invalidate possibly old checksum. */
- tcp0->checksum = 0;
-
- u32 tcp_offset = sizeof (ip6_header_t);
- sum0 = ip_incremental_checksum_buffer (vm, b0, tcp_offset, tcp_len0, sum0);
+ /**
+ * reset the stacked DPO to unlock it
+ */
+ dpo_reset (&hpg_server->dpo);
- tcp0->checksum = ~ip_csum_fold (sum0);
+ pool_put (hicnpg_server_pool, hpg_server);
}
-VLIB_REGISTER_NODE (hicn_pg_interest_node) = {
- .function = hicnpg_client_interest_node_fn,
- .name = "hicnpg-interest",
- .vector_size = sizeof (u32),
- .format_trace = format_hicnpg_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicnpg_error_strings),
- .error_strings = hicnpg_error_strings,
- .n_next_nodes = HICNPG_N_NEXT,
- .next_nodes = { [HICNPG_INTEREST_NEXT_V4_LOOKUP] = "ip4-lookup",
- [HICNPG_INTEREST_NEXT_V6_LOOKUP] = "ip6-lookup",
- [HICNPG_INTEREST_NEXT_DROP] = "error-drop" },
-};
-
-/*
- * Next graph nodes, which reference the list in the actual registration
- * block below
- */
-typedef enum
-{
- HICNPG_DATA_NEXT_DROP,
- HICNPG_DATA_NEXT_LOOKUP4,
- HICNPG_DATA_NEXT_LOOKUP6,
- HICNPG_DATA_N_NEXT,
-} hicnpg_data_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u16 msg_type;
-} icnpg_data_trace_t;
-
-/* packet trace format function */
-static u8 *
-format_hicnpg_data_trace (u8 *s, va_list *args)
+static void
+hicnpg_server_dpo_lock (dpo_id_t *dpo)
{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- hicnpg_trace_t *t = va_arg (*args, hicnpg_trace_t *);
-
- s = format (s, "HICNPG: pkt: %d, msg %d, sw_if_index %d, next index %d",
- (int) t->pkt_type, (int) t->msg_type, t->sw_if_index,
- t->next_index);
- return (s);
+ hicnpg_server_t *hpg_server;
+ hpg_server = hicnpg_server_get (dpo->dpoi_index);
+ fib_node_lock (&hpg_server->fib_node);
}
-static_always_inline int
-match_ip4_name (u32 *name, fib_prefix_t *prefix)
+static void
+hicnpg_server_dpo_unlock (dpo_id_t *dpo)
{
- u32 xor = 0;
-
- xor = *name & prefix->fp_addr.ip4.data_u32;
-
- return xor == prefix->fp_addr.ip4.data_u32;
+ hicnpg_server_t *hpg_server;
+ hpg_server = hicnpg_server_get (dpo->dpoi_index);
+ fib_node_unlock (&hpg_server->fib_node);
}
-static_always_inline int
-match_ip6_name (u8 *name, fib_prefix_t *prefix)
+static u8 *
+format_hicnpg_server_i (u8 *s, va_list *args)
{
- union
- {
- u32x4 as_u32x4;
- u64 as_u64[2];
- u32 as_u32[4];
- } xor_sum __attribute__ ((aligned (sizeof (u32x4))));
+ index_t hicnpg_server_i = va_arg (*args, index_t);
+ // u32 indent = va_arg (*args, u32);
+ u32 details = va_arg (*args, u32);
+ // vlib_counter_t to;
+ hicnpg_server_t *hpg;
- xor_sum.as_u64[0] = ((u64 *) name)[0] & prefix->fp_addr.ip6.as_u64[0];
- xor_sum.as_u64[1] = ((u64 *) name)[1] & prefix->fp_addr.ip6.as_u64[1];
+ hpg = hicnpg_server_get (hicnpg_server_i);
- return (xor_sum.as_u64[0] == prefix->fp_addr.ip6.as_u64[0]) &&
- (xor_sum.as_u64[1] == prefix->fp_addr.ip6.as_u64[1]);
-}
-
-/*
- * Return 0,1,2.
- * 0 matches
- * 1 does not match and the prefix is ip4
- * 2 does not match and the prefix is ip6
- */
-static_always_inline u32
-match_data (vlib_buffer_t *b, fib_prefix_t *prefix)
-{
- u8 *ptr = vlib_buffer_get_current (b);
- u8 v = *ptr & 0xf0;
- u32 next = 0;
+ // FIXME
+ s = format (s, "dpo-hicnpg-server:[%d]: ip-fib-index:%d ", hicnpg_server_i,
+ hpg->fib_index);
- if (PREDICT_TRUE (v == 0x40 && ip46_address_is_ip4 (&prefix->fp_addr)))
+ if (FIB_PROTOCOL_IP4 == hpg->prefix.fp_proto)
{
- if (!match_ip4_name ((u32 *) &(ptr[12]), prefix))
- next = 1;
+ s = format (s, "protocol:FIB_PROTOCOL_IP4 prefix: %U",
+ format_fib_prefix, &hpg->prefix);
}
- else if (PREDICT_TRUE (v == 0x60 && !ip46_address_is_ip4 (&prefix->fp_addr)))
+ else
{
- if (!match_ip6_name (&(ptr[8]), prefix))
- next = 2;
+ s = format (s, "protocol:FIB_PROTOCOL_IP6 prefix: %U",
+ format_fib_prefix, &hpg->prefix);
}
- return next;
-}
-
-/*
- * Return 0,1,2.
- * 0 matches
- * 1 does not match and the prefix is ip4
- * 2 does not match and the prefix is ip6
- */
-static_always_inline u32
-match_interest (vlib_buffer_t *b, fib_prefix_t *prefix)
-{
- u8 *ptr = vlib_buffer_get_current (b);
- u8 v = *ptr & 0xf0;
- u32 next = 0;
+#if 0
+ vlib_get_combined_counter (&(udp_encap_counters), uei, &to);
+ s = format (s, " to:[%Ld:%Ld]]", to.packets, to.bytes);s
+#endif
- if (PREDICT_TRUE (v == 0x40 && ip46_address_is_ip4 (&prefix->fp_addr)))
- {
- if (!match_ip4_name ((u32 *) &(ptr[16]), prefix))
- next = 1;
- }
- else if (PREDICT_TRUE (v == 0x60 && !ip46_address_is_ip4 (&prefix->fp_addr)))
+ if (details)
{
- if (!match_ip6_name (&(ptr[24]), prefix))
- next = 2;
+ s = format (s, " locks:%d", hpg->fib_node.fn_locks);
+ // s = format (s, "\n%UStacked on:", format_white_space, indent +
+ // 1); s = format (s, "\n%U%U", format_white_space, indent + 2,
+ // format_dpo_id,
+ // &hpg->dpo, indent + 3);
}
- return next;
+ return s;
}
-/*
- * Node function for the icn packet-generator client. The goal here is to
- * manipulate/tweak a stream of packets that have been injected by the vpp
- * packet generator to generate icn request traffic.
- */
-static uword
-hicnpg_client_data_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame)
+static u8 *
+format_hicnpg_server_dpo (u8 *s, va_list *args)
{
- u32 n_left_from, *from, *to_next;
- hicnpg_data_next_t next_index;
- u32 pkts_processed = 0;
- u32 content_msgs_received = 0;
- u32 bi0, bi1;
- vlib_buffer_t *b0, *b1;
- u8 pkt_type0 = 0, pkt_type1 = 0;
- u16 msg_type0 = 1, msg_type1 = 1;
- hicnpg_main_t *hpgm = &hicnpg_main;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- u32 next0 = HICNPG_DATA_NEXT_DROP;
- u32 next1 = HICNPG_DATA_NEXT_DROP;
- u32 sw_if_index0, sw_if_index1;
-
- /* Prefetch next iteration. */
- {
- vlib_buffer_t *p2, *p3;
-
- p2 = vlib_get_buffer (vm, from[2]);
- p3 = vlib_get_buffer (vm, from[3]);
-
- vlib_prefetch_buffer_header (p2, LOAD);
- vlib_prefetch_buffer_header (p3, LOAD);
-
- CLIB_PREFETCH (p2->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
- CLIB_PREFETCH (p3->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
- }
-
- /*
- * speculatively enqueue b0 and b1 to the current
- * next frame
- */
- to_next[0] = bi0 = from[0];
- to_next[1] = bi1 = from[1];
- from += 2;
- to_next += 2;
- n_left_from -= 2;
- n_left_to_next -= 2;
-
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
-
- next0 =
- HICNPG_DATA_NEXT_DROP + match_data (b0, hpgm->pgen_clt_hicn_name);
- next1 =
- HICNPG_DATA_NEXT_DROP + match_data (b1, hpgm->pgen_clt_hicn_name);
-
- if (PREDICT_FALSE (vnet_get_feature_count (
- vnet_buffer (b0)->feature_arc_index,
- vnet_buffer (b0)->sw_if_index[VLIB_RX]) > 1))
- vnet_feature_next (&next0, b0);
-
- if (PREDICT_FALSE (vnet_get_feature_count (
- vnet_buffer (b1)->feature_arc_index,
- vnet_buffer (b1)->sw_if_index[VLIB_RX]) > 1))
- vnet_feature_next (&next1, b1);
-
- if (next0 == HICNPG_DATA_NEXT_DROP)
- {
- /* Increment a counter */
- content_msgs_received++;
- }
-
- if (next1 == HICNPG_DATA_NEXT_DROP)
- {
- /* Increment a counter */
- content_msgs_received++;
- }
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
- {
- if (b0->flags & VLIB_BUFFER_IS_TRACED)
- {
- icnpg_data_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = pkt_type0;
- t->msg_type = msg_type0;
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
- if (b1->flags & VLIB_BUFFER_IS_TRACED)
- {
- icnpg_data_trace_t *t =
- vlib_add_trace (vm, node, b1, sizeof (*t));
- t->pkt_type = pkt_type1;
- t->msg_type = msg_type1;
- t->sw_if_index = sw_if_index1;
- t->next_index = next1;
- }
- }
-
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
- n_left_to_next, bi0, bi1, next0,
- next1);
- pkts_processed += 2;
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 next0 = HICNPG_DATA_NEXT_DROP;
- u32 sw_if_index0;
-
- /* speculatively enqueue b0 to the current next frame */
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-
- next0 =
- HICNPG_DATA_NEXT_DROP + match_data (b0, hpgm->pgen_clt_hicn_name);
-
- if (PREDICT_FALSE (vnet_get_feature_count (
- vnet_buffer (b0)->feature_arc_index,
- vnet_buffer (b0)->sw_if_index[VLIB_RX]) > 1))
- vnet_feature_next (&next0, b0);
+ index_t hpg_server_i = va_arg (*args, index_t);
+ u32 indent = va_arg (*args, u32);
- if (next0 == HICNPG_DATA_NEXT_DROP)
- {
- /* Increment a counter */
- content_msgs_received++;
- }
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- icnpg_data_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = pkt_type0;
- t->msg_type = msg_type0;
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
- n_left_to_next, bi0, next0);
-
- pkts_processed++;
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, hicn_pg_data_node.index,
- HICNPG_ERROR_PROCESSED, pkts_processed);
- vlib_node_increment_counter (vm, hicn_pg_data_node.index,
- HICNPG_ERROR_CONTENT_MSGS_RECEIVED,
- content_msgs_received);
- return (frame->n_vectors);
+ return (format (s, "%U", format_hicnpg_server_i, hpg_server_i, indent, 1));
}
-VLIB_REGISTER_NODE(hicn_pg_data_node) =
-{
- .function = hicnpg_client_data_node_fn,
- .name = "hicnpg-data",
- .vector_size = sizeof(u32),
- .format_trace = format_hicnpg_data_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicnpg_error_strings),
- .error_strings = hicnpg_error_strings,
- .n_next_nodes = HICNPG_DATA_N_NEXT,
- .next_nodes =
- {
- [HICNPG_DATA_NEXT_DROP] = "error-drop",
- [HICNPG_DATA_NEXT_LOOKUP4] = "ip4-lookup",
- [HICNPG_DATA_NEXT_LOOKUP6] = "ip6-lookup",
- },
+/*
+ * Virtual function table registered by hicn pg server
+ * for participation in the FIB object graph.
+ */
+const static fib_node_vft_t hicnpg_server_fib_vft = {
+ .fnv_get = hicnpg_server_fib_node_get,
+ .fnv_last_lock = hicnpg_server_fib_last_lock_gone,
+ .fnv_back_walk = hicnpg_server_fib_back_walk,
};
-VNET_FEATURE_INIT (hicn_data_input_ip4_arc, static) = {
- .arc_name = "ip4-unicast",
- .node_name = "hicnpg-data",
- .runs_before = VNET_FEATURES ("ip4-inacl"),
+const static dpo_vft_t hicnpg_server_dpo_vft = {
+ .dv_lock = hicnpg_server_dpo_lock,
+ .dv_unlock = hicnpg_server_dpo_unlock,
+ .dv_format = format_hicnpg_server_dpo,
};
-VNET_FEATURE_INIT (hicn_data_input_ip6_arc, static) = {
- .arc_name = "ip6-unicast",
- .node_name = "hicnpg-data",
- .runs_before = VNET_FEATURES ("ip6-inacl"),
+const static char *const hicnpg_server_ip4_nodes[] = {
+ "hicnpg-server-4",
+ NULL,
};
-/*
- * End of packet-generator client node
- */
-
-/*
- * Beginning of packet-generation server node
- */
-
-/* Registration struct for a graph node */
-vlib_node_registration_t hicn_pg_server_node;
-
-/* Stats, which end up called "error" even though they aren't... */
-#define foreach_icnpg_server_error \
- _ (PROCESSED, "hICN PG Server packets processed") \
- _ (DROPPED, "hICN PG Server packets dropped")
-
-typedef enum
-{
-#define _(sym, str) HICNPG_SERVER_ERROR_##sym,
- foreach_icnpg_server_error
-#undef _
- HICNPG_SERVER_N_ERROR,
-} icnpg_server_error_t;
-
-static char *icnpg_server_error_strings[] = {
-#define _(sym, string) string,
- foreach_icnpg_server_error
-#undef _
+const static char *const hicnpg_server_ip6_nodes[] = {
+ "hicnpg-server-6",
+ NULL,
};
-/*
- * Next graph nodes, which reference the list in the actual registration
- * block below
- */
-typedef enum
-{
- HICNPG_SERVER_NEXT_V4_LOOKUP,
- HICNPG_SERVER_NEXT_V6_LOOKUP,
- HICNPG_SERVER_NEXT_DROP,
- HICNPG_SERVER_N_NEXT,
-} icnpg_server_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u16 msg_type;
-} hicnpg_server_trace_t;
+const static char *const *const hicnpg_server_nodes[DPO_PROTO_NUM] = {
+ [DPO_PROTO_IP4] = hicnpg_server_ip4_nodes,
+ [DPO_PROTO_IP6] = hicnpg_server_ip6_nodes
+};
-/* packet trace format function */
-static u8 *
-format_icnpg_server_trace (u8 *s, va_list *args)
+clib_error_t *
+hicnpg_server_add_and_lock (fib_prefix_t *prefix, u32 *hicnpg_server_index,
+ ip46_address_t *locator, size_t payload_size)
{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- hicnpg_server_trace_t *t = va_arg (*args, hicnpg_server_trace_t *);
+ hicnpg_server_t *hpg;
+ index_t hpgi;
+ u32 fib_index;
+ fib_node_index_t fib_entry_index;
+ u32 buffer_index;
+ vlib_buffer_t *rb = NULL;
- s = format (
- s, "HICNPG SERVER: pkt: %d, msg %d, sw_if_index %d, next index %d",
- (int) t->pkt_type, (int) t->msg_type, t->sw_if_index, t->next_index);
- return (s);
-}
+ // Retrieve hicn fib table
+ fib_index =
+ fib_table_find_or_create_and_lock (prefix->fp_proto, 0, hicn_fib_src);
-/*
- * Node function for the icn packet-generator server.
- */
-static uword
-hicnpg_node_server_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame)
-{
- u32 n_left_from, *from, *to_next;
- icnpg_server_next_t next_index;
- u32 pkts_processed = 0, pkts_dropped = 0;
- u32 bi0, bi1;
- vlib_buffer_t *b0, *b1;
- u8 pkt_type0 = 0, pkt_type1 = 0;
- u16 msg_type0 = 0, msg_type1 = 0;
- hicn_header_t *hicn0 = NULL, *hicn1 = NULL;
- hicn_name_t name0, name1;
- u16 namelen0, namelen1;
+ // Check the prefix we are adding is not already in the table
+ fib_entry_index = fib_table_lookup_exact_match (fib_index, prefix);
- hicnpg_server_main_t *hpgsm = &hicnpg_server_main;
-
- from = vlib_frame_vector_args (frame);
-
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
+ if (fib_entry_index != FIB_NODE_INDEX_INVALID)
{
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- u32 next0 = HICNPG_SERVER_NEXT_DROP;
- u32 next1 = HICNPG_SERVER_NEXT_DROP;
- u8 isv6_0 = 0;
- u8 isv6_1 = 0;
- u32 sw_if_index0, sw_if_index1;
-
- /* Prefetch next iteration. */
- {
- vlib_buffer_t *p2, *p3;
-
- p2 = vlib_get_buffer (vm, from[2]);
- p3 = vlib_get_buffer (vm, from[3]);
-
- vlib_prefetch_buffer_header (p2, LOAD);
- vlib_prefetch_buffer_header (p3, LOAD);
-
- CLIB_PREFETCH (p2->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
- CLIB_PREFETCH (p3->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
- }
-
- /*
- * speculatively enqueue b0 and b1 to the current
- * next frame
- */
- to_next[0] = bi0 = from[0];
- to_next[1] = bi1 = from[1];
- from += 2;
- to_next += 2;
- n_left_from -= 2;
- n_left_to_next -= 2;
-
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
-
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
- vnet_buffer (b1)->sw_if_index[VLIB_TX] = ~0;
-
- u32 match0 = match_interest (b0, hpgsm->pgen_srv_hicn_name);
- u32 match1 = match_interest (b1, hpgsm->pgen_srv_hicn_name);
-
- if (match0)
- {
- next0 = match0 - 1;
- }
- else if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0,
- &isv6_0) == HICN_ERROR_NONE)
- {
- /* this node grabs only interests */
- vlib_buffer_t *rb = NULL;
- rb = vlib_get_buffer (vm, hpgsm->pgen_svr_buffer_idx);
-
- isv6_0 ? convert_interest_to_data_v6 (vm, b0, rb, bi0) :
- convert_interest_to_data_v4 (vm, b0, rb, bi0);
-
- next0 = isv6_0 ? HICNPG_SERVER_NEXT_V6_LOOKUP :
- HICNPG_SERVER_NEXT_V4_LOOKUP;
- }
-
- if (match1)
- {
- next1 = match1 - 1;
- }
- else if (hicn_interest_parse_pkt (b1, &name1, &namelen1, &hicn1,
- &isv6_1) == HICN_ERROR_NONE)
- {
- /* this node grabs only interests */
- vlib_buffer_t *rb = NULL;
- rb = vlib_get_buffer (vm, hpgsm->pgen_svr_buffer_idx);
-
- isv6_1 ? convert_interest_to_data_v6 (vm, b1, rb, bi1) :
- convert_interest_to_data_v4 (vm, b1, rb, bi1);
-
- next1 = isv6_1 ? HICNPG_SERVER_NEXT_V6_LOOKUP :
- HICNPG_SERVER_NEXT_V4_LOOKUP;
- }
- pkts_processed += 2;
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
- {
- if (b0->flags & VLIB_BUFFER_IS_TRACED)
- {
- hicnpg_server_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = pkt_type0;
- t->msg_type = msg_type0;
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
- if (b1->flags & VLIB_BUFFER_IS_TRACED)
- {
- hicnpg_server_trace_t *t =
- vlib_add_trace (vm, node, b1, sizeof (*t));
- t->pkt_type = pkt_type1;
- t->msg_type = msg_type1;
- t->sw_if_index = sw_if_index1;
- t->next_index = next1;
- }
- }
- if (next0 == HICNPG_SERVER_NEXT_DROP)
- {
- pkts_dropped++;
- }
- if (next1 == HICNPG_SERVER_NEXT_DROP)
- {
- pkts_dropped++;
- }
- /*
- * verify speculative enqueues, maybe switch current
- * next frame
- */
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
- n_left_to_next, bi0, bi1, next0,
- next1);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 next0 = HICNPG_SERVER_NEXT_DROP;
- u32 sw_if_index0 = ~0;
- u8 isv6_0 = 0;
-
- /* speculatively enqueue b0 to the current next frame */
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
-
- u32 match0 = match_interest (b0, hpgsm->pgen_srv_hicn_name);
-
- if (match0)
- {
- next0 = match0 - 1;
- }
- else if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0,
- &isv6_0) == HICN_ERROR_NONE)
- {
- /* this node grabs only interests */
- vlib_buffer_t *rb = NULL;
- rb = vlib_get_buffer (vm, hpgsm->pgen_svr_buffer_idx);
-
- isv6_0 ? convert_interest_to_data_v6 (vm, b0, rb, bi0) :
- convert_interest_to_data_v4 (vm, b0, rb, bi0);
-
- next0 = isv6_0 ? HICNPG_SERVER_NEXT_V6_LOOKUP :
- HICNPG_SERVER_NEXT_V4_LOOKUP;
- }
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- hicnpg_server_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = pkt_type0;
- t->msg_type = msg_type0;
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
- pkts_processed += 1;
-
- if (next0 == HICNPG_SERVER_NEXT_DROP)
- {
- pkts_dropped++;
- }
- /*
- * verify speculative enqueue, maybe switch current
- * next frame
- */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
- n_left_to_next, bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ // Route already existing.
+ return clib_error_return (0, "Route exist already.");
}
- vlib_node_increment_counter (vm, hicn_pg_server_node.index,
- HICNPG_SERVER_ERROR_PROCESSED, pkts_processed);
- vlib_node_increment_counter (vm, hicn_pg_server_node.index,
- HICNPG_SERVER_ERROR_DROPPED, pkts_dropped);
-
- return (frame->n_vectors);
-}
-
-void
-convert_interest_to_data_v4 (vlib_main_t *vm, vlib_buffer_t *b0,
- vlib_buffer_t *rb, u32 bi0)
-{
- hicn_header_t *h0 = vlib_buffer_get_current (b0);
-
- /* Get the packet length */
- u16 pkt_len = clib_net_to_host_u16 (h0->v4.ip.len);
+ // Allocate packet buffer
+ int n_buf = vlib_buffer_alloc (vlib_get_main (), &buffer_index, 1);
- /*
- * Rule of thumb: We want the size of the IP packet to be <= 1500 bytes
- */
- u16 bytes_to_copy = rb->current_length;
- if ((bytes_to_copy + pkt_len) > 1500)
+ if (n_buf == 0)
{
- bytes_to_copy = 1500 - pkt_len;
+ return clib_error_return (0, "Impossible to allocate paylod buffer.");
}
- /* Add content to the data packet */
- vlib_buffer_add_data (vm, &bi0, rb->data, bytes_to_copy);
- b0 = vlib_get_buffer (vm, bi0);
-
- h0 = vlib_buffer_get_current (b0);
-
- ip4_address_t src_addr = h0->v4.ip.saddr;
- h0->v4.ip.saddr = h0->v4.ip.daddr;
- h0->v4.ip.daddr = src_addr;
-
- h0->v4.ip.len = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
- h0->v4.ip.csum = ip4_header_checksum ((ip4_header_t *) &(h0->v4.ip));
- calculate_tcp_checksum_v4 (vm, b0);
+ // Initialize the buffer data with zeros
+ rb = vlib_get_buffer (vlib_get_main (), buffer_index);
+ memset (rb->data, 0, payload_size);
+ rb->current_length = payload_size;
+
+ // We can proceed. Get a new hicnpg_server_t
+ pool_get_aligned_zero (hicnpg_server_pool, hpg, 2 * CLIB_CACHE_LINE_BYTES);
+ hpgi = hpg - hicnpg_server_pool;
+
+ // Set DPO
+ dpo_set (
+ &hpg->dpo, hicnpg_server_dpo_type,
+ (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 : DPO_PROTO_IP6),
+ hpgi);
+
+ // Add the route via the hicnpg_server_dpo_type. In this way packets will
+ // endup in the hicnpg_server node
+ CLIB_UNUSED (fib_node_index_t new_fib_node_index) =
+ fib_table_entry_special_dpo_add (
+ fib_index, prefix, hicn_fib_src,
+ (FIB_ENTRY_FLAG_EXCLUSIVE | FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
+ &hpg->dpo);
+
+#if 0
+ vlib_validate_combined_counter (&(udp_encap_counters), uei);
+ vlib_zero_combined_counter (&(udp_encap_counters), uei);
+#endif
+
+ // Init remaining struct fields
+ fib_node_init (&hpg->fib_node, hicnpg_server_fib_node_type);
+ fib_node_lock (&hpg->fib_node);
+ hpg->fib_index = fib_index;
+ hpg->prefix = *prefix;
+ hpg->buffer_index = buffer_index;
+ hpg->fib_entry_index = fib_entry_index;
+ hpg->hicn_locator = *locator;
+
+ // track the destination address
+ // hpg->fib_entry_index =
+ // fib_entry_track (fib_index, &hpg->prefix,
+ // hicnpg_server_fib_node_type, hpgi, &hpg->fib_sibling);
+ // hicnpg_server_restack (hpg);
+
+ HICN_DEBUG ("Calling hicn enable for pg-server face");
+
+ hicn_face_id_t *vec_faces = NULL;
+ hicn_route_enable (prefix, &vec_faces);
+ if (vec_faces != NULL)
+ vec_free (vec_faces);
+
+ // Return the index of the hicnpg_server_t
+ *hicnpg_server_index = hpgi;
+
+ return NULL;
}
-void
-convert_interest_to_data_v6 (vlib_main_t *vm, vlib_buffer_t *b0,
- vlib_buffer_t *rb, u32 bi0)
+clib_error_t *
+hicn_pg_init (vlib_main_t *vm)
{
- hicn_header_t *h0 = vlib_buffer_get_current (b0);
-
- /* Get the packet length */
- uint16_t pkt_len =
- clib_net_to_host_u16 (h0->v6.ip.len) + sizeof (ip6_header_t);
+ hicnpg_server_fib_node_type = fib_node_register_new_type (
+ "hicnpg_server_fib_node", &hicnpg_server_fib_vft);
- /*
- * Figure out how many bytes we can add to the content
- *
- * Rule of thumb: We want the size of the IP packet to be <= 1400 bytes
- */
- u16 bytes_to_copy = rb->current_length;
- if ((bytes_to_copy + pkt_len) > 1500)
- {
- bytes_to_copy = 1500 - pkt_len;
- }
- /* Add content to the data packet */
- vlib_buffer_add_data (vm, &bi0, rb->data, bytes_to_copy);
+ hicnpg_server_dpo_type =
+ dpo_register_new_type (&hicnpg_server_dpo_vft, hicnpg_server_nodes);
- b0 = vlib_get_buffer (vm, bi0);
-
- h0 = vlib_buffer_get_current (b0);
- ip6_address_t src_addr = h0->v6.ip.saddr;
- h0->v6.ip.saddr = h0->v6.ip.daddr;
- h0->v6.ip.daddr = src_addr;
-
- h0->v6.ip.len = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0) -
- sizeof (ip6_header_t));
- h0->v6.tcp.data_offset_and_reserved |= 0x0f;
- h0->v6.tcp.urg_ptr = htons (0xffff);
-
- calculate_tcp_checksum_v6 (vm, b0);
+ return NULL;
}
-VLIB_REGISTER_NODE(hicn_pg_server_node) =
-{
- .function = hicnpg_node_server_fn,
- .name = "hicnpg-server",
- .vector_size = sizeof(u32),
- .format_trace = format_icnpg_server_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(icnpg_server_error_strings),
- .error_strings = icnpg_server_error_strings,
- .n_next_nodes = HICNPG_SERVER_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICNPG_SERVER_NEXT_V4_LOOKUP] = "ip4-lookup",
- [HICNPG_SERVER_NEXT_V6_LOOKUP] = "ip6-lookup",
- [HICNPG_SERVER_NEXT_DROP] = "error-drop",
- },
-};
-
-VNET_FEATURE_INIT (hicn_pg_server_ip6, static) = {
- .arc_name = "ip6-unicast",
- .node_name = "hicnpg-server",
- .runs_before = VNET_FEATURES ("ip6-inacl"),
-};
-
-VNET_FEATURE_INIT (hicn_pg_server_ip4, static) = {
- .arc_name = "ip4-unicast",
- .node_name = "hicnpg-server",
- .runs_before = VNET_FEATURES ("ip4-inacl"),
-};
-
-/*
- * End of packet-generator server node
- */
-
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/pg.h b/hicn-plugin/src/pg.h
index 7855248e6..deb585714 100644
--- a/hicn-plugin/src/pg.h
+++ b/hicn-plugin/src/pg.h
@@ -16,6 +16,8 @@
#ifndef __HICN_PG_H__
#define __HICN_PG_H__
+#include <vppinfra/pool.h>
+
/**
* @file pg.h
*
@@ -57,23 +59,58 @@
*/
typedef struct hicnpg_main_s
{
- u32 index; // used to compute the sequence number
- fib_prefix_t *pgen_clt_hicn_name; // hICN name to put in the destiantion
- // addess of an interest
- u32
- index_ifaces; /* used to mimic interests coming from different consumer */
- u32 n_ifaces; /* The source address will change from interest to interest */
- /* index_ifaces is used to keep a global reference to the iface used */
- /* and it is incremented when we want to change "consumer" */
- /* n_ifaces identifies how many consumers to simulate */
- u32 max_seq_number; // Use to limit the max sequence number
- u32 n_flows; // Use to simulate multiple flows (a flow always have the same
- // hICN name)
- ip46_address_t pgen_clt_src_addr; // Source addess base to use in the
- // interest
-
- u16 interest_lifetime; // Interest lifetime
- u32 sw_if; // Interface where to send interest and receives data
+ /*
+ * used to compute the sequence number
+ */
+ u32 index;
+
+ /*
+ * hICN name to put in the destination addess of an interest
+ */
+ fib_prefix_t *pgen_clt_hicn_name;
+
+ /*
+ * Used to mimic interests coming from different consumer. The source address
+ * will change from interest to interest index_ifaces is used to keep a
+ * global reference to the iface used and it is incremented when we want to
+ * change "consumer"
+ */
+ u32 index_ifaces;
+
+ /*
+ * n_ifaces identifies how many consumers to simulate
+ */
+ u32 n_ifaces;
+
+ /*
+ * Use to limit the max sequence number
+ */
+ u32 max_seq_number;
+
+ /*
+ * Use to simulate multiple flows (a flow always have the same hICN name)
+ */
+ u32 n_flows;
+
+ /*
+ * Source addess base to use in the interest
+ */
+ ip46_address_t pgen_clt_src_addr;
+
+ /*
+ * Interest lifetime
+ */
+ u16 interest_lifetime;
+
+ /*
+ * Interface where to send interest and receives data.
+ */
+ u32 sw_if;
+
+ /*
+ * Fib node type
+ */
+ fib_node_type_t hicn_fib_node_type;
} hicnpg_main_t;
extern hicnpg_main_t hicnpg_main;
@@ -83,18 +120,75 @@ extern hicnpg_main_t hicnpg_main;
*
* It stores the configuration and make it availables to the pg server node.
*/
-typedef struct hicnpg_server_main_s
+typedef struct hicnpg_server_s
{
- u32 node_index;
- /* Arbitrary content */
- u32 pgen_svr_buffer_idx;
- fib_prefix_t *pgen_srv_hicn_name;
-} hicnpg_server_main_t;
+ /*
+ * Prefix served by this packet generator server
+ */
+ fib_prefix_t prefix;
+
+ /*
+ * IP address to put in the destination addess of the data
+ */
+ ip46_address_t hicn_locator;
+
+ /*
+ * Buffer index
+ */
+ u32 buffer_index;
+
+ /**
+ * The DPO used to forward to the next node in the VLIB graph
+ */
+ dpo_id_t dpo;
-extern hicnpg_server_main_t hicnpg_server_main;
+ /*
+ * linkage into the FIB graph
+ */
+ fib_node_t fib_node;
+ /*
+ * Tracking information for the IP destination
+ */
+ fib_node_index_t fib_entry_index;
+
+ /*
+ * The FIB index
+ */
+ index_t fib_index;
+} hicnpg_server_t;
+
+STATIC_ASSERT (sizeof (hicnpg_server_t) <= 2 * CLIB_CACHE_LINE_BYTES,
+ "hicnpg_server_t is too large");
+
+extern hicnpg_server_t hicnpg_server_main;
extern vlib_node_registration_t hicn_pg_interest_node;
extern vlib_node_registration_t hicn_pg_data_node;
+extern dpo_type_t hicnpg_server_dpo_type;
+
+/**
+ * Pool of hicnpg_servers
+ */
+extern hicnpg_server_t *hicnpg_server_pool;
+
+always_inline hicnpg_server_t *
+hicnpg_server_get (index_t hpgi)
+{
+ return pool_elt_at_index (hicnpg_server_pool, hpgi);
+}
+
+always_inline u8
+dpo_is_pgserver (const dpo_id_t *dpo)
+{
+ return (dpo->dpoi_type == hicnpg_server_dpo_type);
+}
+
+clib_error_t *hicnpg_server_add_and_lock (fib_prefix_t *prefix,
+ u32 *hicnpg_server_index,
+ ip46_address_t *locator,
+ size_t payload_size);
+
+clib_error_t *hicn_pg_init (vlib_main_t *vm);
#endif // __HICN_PG_H__
diff --git a/hicn-plugin/src/pg_node.c b/hicn-plugin/src/pg_node.c
new file mode 100644
index 000000000..3672a6b72
--- /dev/null
+++ b/hicn-plugin/src/pg_node.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/vnet.h>
+#include <vnet/pg/pg.h>
+#include <vnet/ip/ip.h>
+#include <vnet/ethernet/ethernet.h>
+
+#include "hicn.h"
+#include "pg.h"
+#include "parser.h"
+#include "infra.h"
+
+/* Registration struct for a graph node */
+vlib_node_registration_t hicn_pg_interest_node;
+vlib_node_registration_t hicn_pg_data_node;
+
+/* Stats, which end up called "error" even though they aren't... */
+#define foreach_hicnpg_error \
+ _ (PROCESSED, "hICN PG packets processed") \
+ _ (DROPPED, "hICN PG packets dropped") \
+ _ (INTEREST_MSGS_GENERATED, "hICN PG Interests generated") \
+ _ (CONTENT_MSGS_RECEIVED, "hICN PG Content msgs received")
+
+typedef enum
+{
+#define _(sym, str) HICNPG_ERROR_##sym,
+ foreach_hicnpg_error
+#undef _
+ HICNPG_N_ERROR,
+} hicnpg_error_t;
+
+static char *hicnpg_error_strings[] = {
+#define _(sym, string) string,
+ foreach_hicnpg_error
+#undef _
+};
+
+/*
+ * Next graph nodes, which reference the list in the actual registration
+ * block below
+ */
+typedef enum
+{
+ HICNPG_INTEREST_NEXT_V4_LOOKUP,
+ HICNPG_INTEREST_NEXT_V6_LOOKUP,
+ HICNPG_INTEREST_NEXT_DROP,
+ HICNPG_N_NEXT,
+} hicnpg_interest_next_t;
+
+/* Trace context struct */
+typedef struct
+{
+ u32 next_index;
+ u32 sw_if_index;
+ u8 pkt_type;
+ u16 msg_type;
+} hicnpg_trace_t;
+
+/* packet trace format function */
+static u8 *
+format_hicnpg_trace (u8 *s, va_list *args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ hicnpg_trace_t *t = va_arg (*args, hicnpg_trace_t *);
+
+ s = format (s, "HICNPG: pkt: %d, msg %d, sw_if_index %d, next index %d",
+ (int) t->pkt_type, (int) t->msg_type, t->sw_if_index,
+ t->next_index);
+ return (s);
+}
+
+always_inline void hicn_rewrite_interestv4 (vlib_main_t *vm, vlib_buffer_t *b0,
+ u32 seq_number, u16 lifetime,
+ u32 next_flow, u32 iface);
+
+always_inline void hicn_rewrite_interestv6 (vlib_main_t *vm, vlib_buffer_t *b0,
+ u32 seq_number, u16 lifetime,
+ u32 next_flow, u32 iface);
+
+always_inline void convert_interest_to_data_v4 (vlib_main_t *vm,
+ vlib_buffer_t *b0,
+ vlib_buffer_t *rb, u32 bi0);
+
+always_inline void convert_interest_to_data_v6 (vlib_main_t *vm,
+ vlib_buffer_t *b0,
+ vlib_buffer_t *rb, u32 bi0);
+
+always_inline void calculate_tcp_checksum_v4 (vlib_main_t *vm,
+ vlib_buffer_t *b0);
+
+always_inline void calculate_tcp_checksum_v6 (vlib_main_t *vm,
+ vlib_buffer_t *b0);
+/*
+ * Node function for the icn packet-generator client. The goal here is to
+ * manipulate/tweak a stream of packets that have been injected by the vpp
+ * packet generator to generate icn request traffic.
+ */
+static uword
+hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame)
+{
+ u32 n_left_from, *from, *to_next;
+ hicnpg_interest_next_t next_index;
+ u32 pkts_processed = 0, pkts_dropped = 0;
+ u32 interest_msgs_generated = 0;
+ u32 bi0, bi1;
+ vlib_buffer_t *b0, *b1;
+ u8 pkt_type0 = 0, pkt_type1 = 0;
+ u16 msg_type0 = 0, msg_type1 = 0;
+ hicnpg_main_t *hpgm = &hicnpg_main;
+ int iface = 0;
+
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+ next_index = node->cached_next_index;
+
+ while (n_left_from > 0)
+ {
+ u32 n_left_to_next;
+
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+ while (n_left_from >= 4 && n_left_to_next >= 2)
+ {
+ u32 next0 = HICNPG_INTEREST_NEXT_DROP;
+ u32 next1 = HICNPG_INTEREST_NEXT_DROP;
+ u32 sw_if_index0 = ~0, sw_if_index1 = ~0;
+ u8 isv6_0;
+ u8 isv6_1;
+
+ /* Prefetch next iteration. */
+ {
+ vlib_buffer_t *p2, *p3;
+
+ p2 = vlib_get_buffer (vm, from[2]);
+ p3 = vlib_get_buffer (vm, from[3]);
+
+ vlib_prefetch_buffer_header (p2, LOAD);
+ vlib_prefetch_buffer_header (p3, LOAD);
+
+ CLIB_PREFETCH (p2->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
+ CLIB_PREFETCH (p3->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
+ }
+
+ /*
+ * speculatively enqueue b0 and b1 to the current
+ * next frame
+ */
+ to_next[0] = bi0 = from[0];
+ to_next[1] = bi1 = from[1];
+ from += 2;
+ to_next += 2;
+ n_left_from -= 2;
+ n_left_to_next -= 2;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
+
+ hicn_buffer_set_flags (b0, HICN_BUFFER_FLAGS_FROM_PG);
+ hicn_buffer_set_flags (b1, HICN_BUFFER_FLAGS_FROM_PG);
+
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+ sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
+ vnet_buffer (b0)->sw_if_index[VLIB_RX] = hpgm->sw_if;
+ vnet_buffer (b1)->sw_if_index[VLIB_RX] = hpgm->sw_if;
+
+ /* Check icn packets, locate names */
+ if (hicn_interest_parse_pkt (b0) == HICN_ERROR_NONE)
+ {
+ /* this node grabs only interests */
+ isv6_0 = hicn_buffer_is_v6 (b0);
+
+ /* Increment the appropriate message counter */
+ interest_msgs_generated++;
+
+ iface = (hpgm->index_ifaces % hpgm->n_ifaces);
+ /* Rewrite and send */
+ isv6_0 ?
+ hicn_rewrite_interestv6 (
+ vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
+ hpgm->interest_lifetime, hpgm->index % hpgm->n_flows,
+ iface) :
+ hicn_rewrite_interestv4 (
+ vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
+ hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface);
+
+ hpgm->index_ifaces++;
+ if (iface == (hpgm->n_ifaces - 1))
+ hpgm->index++;
+
+ next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP :
+ HICNPG_INTEREST_NEXT_V4_LOOKUP;
+ }
+ if (hicn_interest_parse_pkt (b1) == HICN_ERROR_NONE)
+ {
+ /* this node grabs only interests */
+ isv6_1 = hicn_buffer_is_v6 (b1);
+
+ /* Increment the appropriate message counter */
+ interest_msgs_generated++;
+
+ iface = (hpgm->index_ifaces % hpgm->n_ifaces);
+ /* Rewrite and send */
+ isv6_1 ?
+ hicn_rewrite_interestv6 (
+ vm, b1, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
+ hpgm->interest_lifetime, hpgm->index % hpgm->n_flows,
+ iface) :
+ hicn_rewrite_interestv4 (
+ vm, b1, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
+ hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface);
+
+ hpgm->index_ifaces++;
+ if (iface == (hpgm->n_ifaces - 1))
+ hpgm->index++;
+
+ next1 = isv6_1 ? HICNPG_INTEREST_NEXT_V6_LOOKUP :
+ HICNPG_INTEREST_NEXT_V4_LOOKUP;
+ }
+ /* Send pkt to next node */
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
+ vnet_buffer (b1)->sw_if_index[VLIB_TX] = ~0;
+
+ pkts_processed += 2;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
+ {
+ if (b0->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ hicnpg_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->pkt_type = pkt_type0;
+ t->msg_type = msg_type0;
+ t->sw_if_index = sw_if_index0;
+ t->next_index = next0;
+ }
+ if (b1->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ hicnpg_trace_t *t =
+ vlib_add_trace (vm, node, b1, sizeof (*t));
+ t->pkt_type = pkt_type1;
+ t->msg_type = msg_type1;
+ t->sw_if_index = sw_if_index1;
+ t->next_index = next1;
+ }
+ }
+ if (next0 == HICNPG_INTEREST_NEXT_DROP)
+ {
+ pkts_dropped++;
+ }
+ if (next1 == HICNPG_INTEREST_NEXT_DROP)
+ {
+ pkts_dropped++;
+ }
+ /*
+ * verify speculative enqueues, maybe switch current
+ * next frame
+ */
+ vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, bi1, next0,
+ next1);
+ }
+
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ u32 next0 = HICNPG_INTEREST_NEXT_DROP;
+ u32 sw_if_index0;
+ u8 isv6_0;
+
+ /* speculatively enqueue b0 to the current next frame */
+ bi0 = from[0];
+ to_next[0] = bi0;
+ from += 1;
+ to_next += 1;
+ n_left_from -= 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ hicn_buffer_set_flags (b0, HICN_BUFFER_FLAGS_FROM_PG);
+
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+ vnet_buffer (b0)->sw_if_index[VLIB_RX] = hpgm->sw_if;
+
+ /* Check icn packets, locate names */
+ if (hicn_interest_parse_pkt (b0) == HICN_ERROR_NONE)
+ {
+ /* this node grabs only interests */
+ isv6_0 = hicn_buffer_is_v6 (b0);
+
+ /* Increment the appropriate message counter */
+ interest_msgs_generated++;
+
+ iface = (hpgm->index_ifaces % hpgm->n_ifaces);
+
+ /* Rewrite and send */
+ isv6_0 ?
+ hicn_rewrite_interestv6 (
+ vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
+ hpgm->interest_lifetime, hpgm->index % hpgm->n_flows,
+ iface) :
+ hicn_rewrite_interestv4 (
+ vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number,
+ hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface);
+
+ hpgm->index_ifaces++;
+ if (iface == (hpgm->n_ifaces - 1))
+ hpgm->index++;
+
+ next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP :
+ HICNPG_INTEREST_NEXT_V4_LOOKUP;
+ }
+ /* Send pkt to ip lookup */
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ hicnpg_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->pkt_type = pkt_type0;
+ t->msg_type = msg_type0;
+ t->sw_if_index = sw_if_index0;
+ t->next_index = next0;
+ }
+ pkts_processed += 1;
+
+ if (next0 == HICNPG_INTEREST_NEXT_DROP)
+ {
+ pkts_dropped++;
+ }
+ /*
+ * verify speculative enqueue, maybe switch current
+ * next frame
+ */
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
+ }
+
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+
+ vlib_node_increment_counter (vm, hicn_pg_interest_node.index,
+ HICNPG_ERROR_PROCESSED, pkts_processed);
+ vlib_node_increment_counter (vm, hicn_pg_interest_node.index,
+ HICNPG_ERROR_DROPPED, pkts_dropped);
+ vlib_node_increment_counter (vm, hicn_pg_interest_node.index,
+ HICNPG_ERROR_INTEREST_MSGS_GENERATED,
+ interest_msgs_generated);
+
+ return (frame->n_vectors);
+}
+
+void
+hicn_rewrite_interestv4 (vlib_main_t *vm, vlib_buffer_t *b0, u32 seq_number,
+ u16 interest_lifetime, u32 next_flow, u32 iface)
+{
+ hicn_header_t *h0 = vlib_buffer_get_current (b0);
+
+ /* Generate the right src and dst corresponding to flow and iface */
+ ip46_address_t src_addr = {
+ .ip4 = hicnpg_main.pgen_clt_src_addr.ip4,
+ };
+ hicn_name_t dst_name = {
+ .prefix.ip4 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip4,
+ .suffix = seq_number,
+ };
+
+ src_addr.ip4.as_u32 += clib_host_to_net_u32 (iface);
+ dst_name.prefix.ip4.as_u32 += clib_net_to_host_u32 (next_flow);
+
+ /* Update locator and name */
+ hicn_type_t type = hicn_get_buffer (b0)->type;
+ HICN_OPS4->set_interest_locator (type, &h0->protocol, &src_addr);
+ HICN_OPS4->set_interest_name (type, &h0->protocol, &dst_name);
+
+ /* Update lifetime (currently L4 checksum is not updated) */
+ HICN_OPS4->set_lifetime (type, &h0->protocol, interest_lifetime);
+
+ /* Update checksums */
+ HICN_OPS4->update_checksums (type, &h0->protocol, 0, 0);
+}
+
+/**
+ * @brief Rewrite the IPv6 header as the next generated packet
+ *
+ * Set up a name prefix
+ * - etiher generate interest in which the name varies only after the prefix
+ * (inc : seq_number), then the flow acts on the prefix (CHECK)
+ * seq_number => TCP, FLOW =>
+ *
+ * SRC : pgen_clt_src_addr.ip6 DST = generate name (pgen_clt_hicn_name.ip6)
+ * ffff:ffff:ffff:ffff ffff:ffff:ffff:ffff
+ * \__/ \__/
+ * +iface + flow
+ * Source is used to emulate different consumers.
+ * FIXME iface is ill-named, better name it consumer id
+ * Destination is used to iterate on the content.
+ */
+void
+hicn_rewrite_interestv6 (vlib_main_t *vm, vlib_buffer_t *b0, u32 seq_number,
+ u16 interest_lifetime, u32 next_flow, u32 iface)
+{
+ hicn_header_t *h0 = vlib_buffer_get_current (b0);
+
+ /* Generate the right src and dst corresponding to flow and iface */
+ ip46_address_t src_addr = {
+ .ip6 = hicnpg_main.pgen_clt_src_addr.ip6,
+ };
+ hicn_name_t dst_name = {
+ .prefix.ip6 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip6,
+ .suffix = seq_number,
+ };
+ src_addr.ip6.as_u32[3] += clib_host_to_net_u32 (iface);
+ dst_name.prefix.ip6.as_u32[3] += clib_net_to_host_u32 (next_flow);
+
+ /* Update locator and name */
+ hicn_type_t type = hicn_get_buffer (b0)->type;
+ HICN_OPS6->set_interest_locator (type, &h0->protocol, &src_addr);
+ HICN_OPS6->set_interest_name (type, &h0->protocol, &dst_name);
+
+ /* Update lifetime */
+ HICN_OPS6->set_lifetime (type, &h0->protocol, interest_lifetime);
+
+ /* Update checksums */
+ calculate_tcp_checksum_v6 (vm, b0);
+}
+
+void
+calculate_tcp_checksum_v4 (vlib_main_t *vm, vlib_buffer_t *b0)
+{
+ ip4_header_t *ip0;
+ tcp_header_t *tcp0;
+ ip_csum_t sum0;
+ u32 tcp_len0;
+
+ ip0 = (ip4_header_t *) (vlib_buffer_get_current (b0));
+ tcp0 =
+ (tcp_header_t *) (vlib_buffer_get_current (b0) + sizeof (ip4_header_t));
+ tcp_len0 = clib_net_to_host_u16 (ip0->length) - sizeof (ip4_header_t);
+
+ /* Initialize checksum with header. */
+ if (BITS (sum0) == 32)
+ {
+ sum0 = clib_mem_unaligned (&ip0->src_address, u32);
+ sum0 =
+ ip_csum_with_carry (sum0, clib_mem_unaligned (&ip0->dst_address, u32));
+ }
+ else
+ sum0 = clib_mem_unaligned (&ip0->src_address, u64);
+
+ sum0 = ip_csum_with_carry (
+ sum0, clib_host_to_net_u32 (tcp_len0 + (ip0->protocol << 16)));
+
+ /* Invalidate possibly old checksum. */
+ tcp0->checksum = 0;
+
+ u32 tcp_offset = sizeof (ip4_header_t);
+ sum0 = ip_incremental_checksum_buffer (vm, b0, tcp_offset, tcp_len0, sum0);
+
+ tcp0->checksum = ~ip_csum_fold (sum0);
+}
+
+void
+calculate_tcp_checksum_v6 (vlib_main_t *vm, vlib_buffer_t *b0)
+{
+ ip6_header_t *ip0;
+ tcp_header_t *tcp0;
+ ip_csum_t sum0;
+ u32 tcp_len0;
+
+ ip0 = (ip6_header_t *) (vlib_buffer_get_current (b0));
+ tcp0 =
+ (tcp_header_t *) (vlib_buffer_get_current (b0) + sizeof (ip6_header_t));
+ tcp_len0 = clib_net_to_host_u16 (ip0->payload_length);
+
+ /* Initialize checksum with header. */
+ if (BITS (sum0) == 32)
+ {
+ sum0 = clib_mem_unaligned (&ip0->src_address, u32);
+ sum0 =
+ ip_csum_with_carry (sum0, clib_mem_unaligned (&ip0->dst_address, u32));
+ }
+ else
+ sum0 = clib_mem_unaligned (&ip0->src_address, u64);
+
+ sum0 = ip_csum_with_carry (
+ sum0, clib_host_to_net_u32 (tcp_len0 + (ip0->protocol << 16)));
+
+ /* Invalidate possibly old checksum. */
+ tcp0->checksum = 0;
+
+ u32 tcp_offset = sizeof (ip6_header_t);
+ sum0 = ip_incremental_checksum_buffer (vm, b0, tcp_offset, tcp_len0, sum0);
+
+ tcp0->checksum = ~ip_csum_fold (sum0);
+}
+
+VLIB_REGISTER_NODE (hicn_pg_interest_node) = {
+ .function = hicnpg_client_interest_node_fn,
+ .name = "hicnpg-interest",
+ .vector_size = sizeof (u32),
+ .format_trace = format_hicnpg_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN (hicnpg_error_strings),
+ .error_strings = hicnpg_error_strings,
+ .n_next_nodes = HICNPG_N_NEXT,
+ .next_nodes = { [HICNPG_INTEREST_NEXT_V4_LOOKUP] = "ip4-lookup",
+ [HICNPG_INTEREST_NEXT_V6_LOOKUP] = "ip6-lookup",
+ [HICNPG_INTEREST_NEXT_DROP] = "error-drop" },
+};
+
+/*
+ * Next graph nodes, which reference the list in the actual registration
+ * block below
+ */
+typedef enum
+{
+ HICNPG_DATA_NEXT_DROP,
+ HICNPG_DATA_NEXT_LOOKUP4,
+ HICNPG_DATA_NEXT_LOOKUP6,
+ HICNPG_DATA_N_NEXT,
+} hicnpg_data_next_t;
+
+/* Trace context struct */
+typedef struct
+{
+ u32 next_index;
+ u32 sw_if_index;
+ u8 pkt_type;
+ u16 msg_type;
+} icnpg_data_trace_t;
+
+/* packet trace format function */
+static u8 *
+format_hicnpg_data_trace (u8 *s, va_list *args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ hicnpg_trace_t *t = va_arg (*args, hicnpg_trace_t *);
+
+ s = format (s, "HICNPG: pkt: %d, msg %d, sw_if_index %d, next index %d",
+ (int) t->pkt_type, (int) t->msg_type, t->sw_if_index,
+ t->next_index);
+ return (s);
+}
+
+/*
+ * Node function for the icn packet-generator client. The goal here is to
+ * manipulate/tweak a stream of packets that have been injected by the vpp
+ * packet generator to generate icn request traffic.
+ */
+static uword
+hicnpg_client_data_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame)
+{
+ u32 n_left_from, *from, *to_next;
+ hicnpg_data_next_t next_index;
+ u32 pkts_processed = 0;
+ u32 content_msgs_received = 0;
+ u32 bi0, bi1;
+ vlib_buffer_t *b0, *b1;
+ u8 pkt_type0 = 0, pkt_type1 = 0;
+ u16 msg_type0 = 1, msg_type1 = 1;
+
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+ next_index = node->cached_next_index;
+
+ while (n_left_from > 0)
+ {
+ u32 n_left_to_next;
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+ while (n_left_from >= 4 && n_left_to_next >= 2)
+ {
+ u32 next0 = HICNPG_DATA_NEXT_DROP;
+ u32 next1 = HICNPG_DATA_NEXT_DROP;
+ u32 sw_if_index0, sw_if_index1;
+
+ /* Prefetch next iteration. */
+ {
+ vlib_buffer_t *p2, *p3;
+
+ p2 = vlib_get_buffer (vm, from[2]);
+ p3 = vlib_get_buffer (vm, from[3]);
+
+ vlib_prefetch_buffer_header (p2, LOAD);
+ vlib_prefetch_buffer_header (p3, LOAD);
+
+ CLIB_PREFETCH (p2->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
+ CLIB_PREFETCH (p3->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
+ }
+
+ /*
+ * speculatively enqueue b0 and b1 to the current
+ * next frame
+ */
+ to_next[0] = bi0 = from[0];
+ to_next[1] = bi1 = from[1];
+ from += 2;
+ to_next += 2;
+ n_left_from -= 2;
+ n_left_to_next -= 2;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
+
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+ sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
+
+ next0 = HICNPG_DATA_NEXT_DROP;
+ next1 = HICNPG_DATA_NEXT_DROP;
+
+ // Increment counter
+ content_msgs_received += 2;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
+ {
+ if (b0->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ icnpg_data_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->pkt_type = pkt_type0;
+ t->msg_type = msg_type0;
+ t->sw_if_index = sw_if_index0;
+ t->next_index = next0;
+ }
+ if (b1->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ icnpg_data_trace_t *t =
+ vlib_add_trace (vm, node, b1, sizeof (*t));
+ t->pkt_type = pkt_type1;
+ t->msg_type = msg_type1;
+ t->sw_if_index = sw_if_index1;
+ t->next_index = next1;
+ }
+ }
+
+ vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, bi1, next0,
+ next1);
+ pkts_processed += 2;
+ }
+
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ u32 next0 = HICNPG_DATA_NEXT_DROP;
+ u32 sw_if_index0;
+
+ /* speculatively enqueue b0 to the current next frame */
+ bi0 = from[0];
+ to_next[0] = bi0;
+ from += 1;
+ to_next += 1;
+ n_left_from -= 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+
+ next0 = HICNPG_DATA_NEXT_DROP;
+
+ // Increment a counter
+ content_msgs_received += 1;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ icnpg_data_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->pkt_type = pkt_type0;
+ t->msg_type = msg_type0;
+ t->sw_if_index = sw_if_index0;
+ t->next_index = next0;
+ }
+
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
+
+ pkts_processed++;
+ }
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+
+ vlib_node_increment_counter (vm, hicn_pg_data_node.index,
+ HICNPG_ERROR_PROCESSED, pkts_processed);
+ vlib_node_increment_counter (vm, hicn_pg_data_node.index,
+ HICNPG_ERROR_CONTENT_MSGS_RECEIVED,
+ content_msgs_received);
+ return (frame->n_vectors);
+}
+
+VLIB_REGISTER_NODE(hicn_pg_data_node) =
+{
+ .function = hicnpg_client_data_node_fn,
+ .name = "hicnpg-data",
+ .vector_size = sizeof(u32),
+ .format_trace = format_hicnpg_data_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(hicnpg_error_strings),
+ .error_strings = hicnpg_error_strings,
+ .n_next_nodes = HICNPG_DATA_N_NEXT,
+ .next_nodes =
+ {
+ [HICNPG_DATA_NEXT_DROP] = "error-drop",
+ [HICNPG_DATA_NEXT_LOOKUP4] = "ip4-lookup",
+ [HICNPG_DATA_NEXT_LOOKUP6] = "ip6-lookup",
+ },
+};
+
+VNET_FEATURE_INIT (hicn_data_input_ip4_arc, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "hicnpg-data",
+ .runs_before = VNET_FEATURES ("ip4-inacl"),
+};
+
+VNET_FEATURE_INIT (hicn_data_input_ip6_arc, static) = {
+ .arc_name = "ip6-unicast",
+ .node_name = "hicnpg-data",
+ .runs_before = VNET_FEATURES ("ip6-inacl"),
+};
+
+/*
+ * End of packet-generator client node
+ */
+
+/*
+ * Beginning of packet-generation server node
+ */
+
+/* Registration struct for a graph node */
+vlib_node_registration_t hicn_pg_server_node;
+
+/* Stats, which end up called "error" even though they aren't... */
+#define foreach_icnpg_server_error \
+ _ (PROCESSED, "hICN PG Server packets processed") \
+ _ (DROPPED, "hICN PG Server packets dropped")
+
+typedef enum
+{
+#define _(sym, str) HICNPG_SERVER_ERROR_##sym,
+ foreach_icnpg_server_error
+#undef _
+ HICNPG_SERVER_N_ERROR,
+} icnpg_server_error_t;
+
+static char *icnpg_server_error_strings[] = {
+#define _(sym, string) string,
+ foreach_icnpg_server_error
+#undef _
+};
+
+/*
+ * Next graph nodes, which reference the list in the actual registration
+ * block below
+ */
+typedef enum
+{
+ HICNPG_SERVER_NEXT_V4_LOOKUP,
+ HICNPG_SERVER_NEXT_V6_LOOKUP,
+ HICNPG_SERVER_NEXT_DROP,
+ HICNPG_SERVER_N_NEXT,
+} icnpg_server_next_t;
+
+/* Trace context struct */
+typedef struct
+{
+ u32 next_index;
+ u32 sw_if_index;
+ u8 pkt_type;
+ u16 msg_type;
+} hicnpg_server_trace_t;
+
+/* packet trace format function */
+static u8 *
+format_icnpg_server_trace (u8 *s, va_list *args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ hicnpg_server_trace_t *t = va_arg (*args, hicnpg_server_trace_t *);
+
+ s = format (
+ s, "HICNPG SERVER: pkt: %d, msg %d, sw_if_index %d, next index %d",
+ (int) t->pkt_type, (int) t->msg_type, t->sw_if_index, t->next_index);
+ return (s);
+}
+
+/*
+ * Node function for the icn packet-generator server.
+ */
+static uword
+hicnpg_node_server_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame, int isv6)
+{
+ u32 n_left_from, *from, *to_next;
+ icnpg_server_next_t next_index;
+ u32 pkts_processed = 0, pkts_dropped = 0;
+ u32 bi0, bi1;
+ vlib_buffer_t *b0, *b1;
+ u8 pkt_type0 = 0, pkt_type1 = 0;
+ u16 msg_type0 = 0, msg_type1 = 0;
+
+ from = vlib_frame_vector_args (frame);
+
+ n_left_from = frame->n_vectors;
+ next_index = node->cached_next_index;
+
+ while (n_left_from > 0)
+ {
+ u32 n_left_to_next;
+
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+ while (n_left_from >= 4 && n_left_to_next >= 2)
+ {
+ u32 next0 = HICNPG_SERVER_NEXT_DROP;
+ u32 next1 = HICNPG_SERVER_NEXT_DROP;
+ u32 sw_if_index0, sw_if_index1;
+ u32 hpgi0, hpgi1;
+ hicnpg_server_t *hpg0, *hpg1;
+
+ /* Prefetch next iteration. */
+ {
+ vlib_buffer_t *p2, *p3;
+
+ p2 = vlib_get_buffer (vm, from[2]);
+ p3 = vlib_get_buffer (vm, from[3]);
+
+ vlib_prefetch_buffer_header (p2, LOAD);
+ vlib_prefetch_buffer_header (p3, LOAD);
+
+ CLIB_PREFETCH (p2->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
+ CLIB_PREFETCH (p3->data, (2 * CLIB_CACHE_LINE_BYTES), STORE);
+ }
+
+ /*
+ * speculatively enqueue b0 and b1 to the current
+ * next frame
+ */
+ to_next[0] = bi0 = from[0];
+ to_next[1] = bi1 = from[1];
+ from += 2;
+ to_next += 2;
+ n_left_from -= 2;
+ n_left_to_next -= 2;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
+
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+ sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
+
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
+ vnet_buffer (b1)->sw_if_index[VLIB_TX] = ~0;
+
+ hpgi0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
+ hpgi1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX];
+
+ hpg0 = hicnpg_server_get (hpgi0);
+ hpg1 = hicnpg_server_get (hpgi1);
+
+ if (hicn_interest_parse_pkt (b0) == HICN_ERROR_NONE)
+ {
+ vlib_buffer_t *rb = NULL;
+ rb = vlib_get_buffer (vm, hpg0->buffer_index);
+
+ isv6 ? convert_interest_to_data_v6 (vm, b0, rb, bi0) :
+ convert_interest_to_data_v4 (vm, b0, rb, bi0);
+
+ next0 = isv6 ? HICNPG_SERVER_NEXT_V6_LOOKUP :
+ HICNPG_SERVER_NEXT_V4_LOOKUP;
+ }
+
+ if (hicn_interest_parse_pkt (b1) == HICN_ERROR_NONE)
+ {
+ vlib_buffer_t *rb = NULL;
+ rb = vlib_get_buffer (vm, hpg1->buffer_index);
+
+ isv6 ? convert_interest_to_data_v6 (vm, b1, rb, bi1) :
+ convert_interest_to_data_v4 (vm, b1, rb, bi1);
+
+ next1 = isv6 ? HICNPG_SERVER_NEXT_V6_LOOKUP :
+ HICNPG_SERVER_NEXT_V4_LOOKUP;
+ }
+ pkts_processed += 2;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
+ {
+ if (b0->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ hicnpg_server_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->pkt_type = pkt_type0;
+ t->msg_type = msg_type0;
+ t->sw_if_index = sw_if_index0;
+ t->next_index = next0;
+ }
+ if (b1->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ hicnpg_server_trace_t *t =
+ vlib_add_trace (vm, node, b1, sizeof (*t));
+ t->pkt_type = pkt_type1;
+ t->msg_type = msg_type1;
+ t->sw_if_index = sw_if_index1;
+ t->next_index = next1;
+ }
+ }
+ if (next0 == HICNPG_SERVER_NEXT_DROP)
+ {
+ pkts_dropped++;
+ }
+ if (next1 == HICNPG_SERVER_NEXT_DROP)
+ {
+ pkts_dropped++;
+ }
+ /*
+ * verify speculative enqueues, maybe switch current
+ * next frame
+ */
+ vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, bi1, next0,
+ next1);
+ }
+
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ u32 next0 = HICNPG_SERVER_NEXT_DROP;
+ u32 sw_if_index0 = ~0;
+ u32 hpgi0;
+ hicnpg_server_t *hpg0;
+
+ /* speculatively enqueue b0 to the current next frame */
+ bi0 = from[0];
+ to_next[0] = bi0;
+ from += 1;
+ to_next += 1;
+ n_left_from -= 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
+
+ hpgi0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
+ hpg0 = hicnpg_server_get (hpgi0);
+
+ if (hicn_interest_parse_pkt (b0) == HICN_ERROR_NONE)
+ {
+ /* this node grabs only interests */
+ vlib_buffer_t *rb = NULL;
+ rb = vlib_get_buffer (vm, hpg0->buffer_index);
+
+ isv6 ? convert_interest_to_data_v6 (vm, b0, rb, bi0) :
+ convert_interest_to_data_v4 (vm, b0, rb, bi0);
+
+ next0 = isv6 ? HICNPG_SERVER_NEXT_V6_LOOKUP :
+ HICNPG_SERVER_NEXT_V4_LOOKUP;
+ }
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ hicnpg_server_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->pkt_type = pkt_type0;
+ t->msg_type = msg_type0;
+ t->sw_if_index = sw_if_index0;
+ t->next_index = next0;
+ }
+ pkts_processed += 1;
+
+ if (next0 == HICNPG_SERVER_NEXT_DROP)
+ {
+ pkts_dropped++;
+ }
+ /*
+ * verify speculative enqueue, maybe switch current
+ * next frame
+ */
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
+ }
+
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+
+ vlib_node_increment_counter (vm, hicn_pg_server_node.index,
+ HICNPG_SERVER_ERROR_PROCESSED, pkts_processed);
+ vlib_node_increment_counter (vm, hicn_pg_server_node.index,
+ HICNPG_SERVER_ERROR_DROPPED, pkts_dropped);
+
+ return (frame->n_vectors);
+}
+
+void
+convert_interest_to_data_v4 (vlib_main_t *vm, vlib_buffer_t *b0,
+ vlib_buffer_t *rb, u32 bi0)
+{
+ hicn_header_t *h0 = vlib_buffer_get_current (b0);
+
+ /* Get the packet length */
+ u16 pkt_len = clib_net_to_host_u16 (h0->v4.ip.len);
+
+ /*
+ * Rule of thumb: We want the size of the IP packet to be <= 1500 bytes
+ */
+ u16 bytes_to_copy = rb->current_length;
+ if ((bytes_to_copy + pkt_len) > 1500)
+ {
+ bytes_to_copy = 1500 - pkt_len;
+ }
+ /* Add content to the data packet */
+ vlib_buffer_add_data (vm, &bi0, rb->data, bytes_to_copy);
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ h0 = vlib_buffer_get_current (b0);
+
+ ip4_address_t src_addr = h0->v4.ip.saddr;
+ h0->v4.ip.saddr = h0->v4.ip.daddr;
+ h0->v4.ip.daddr = src_addr;
+
+ h0->v4.ip.len = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
+ h0->v4.ip.csum = ip4_header_checksum ((ip4_header_t *) &(h0->v4.ip));
+ calculate_tcp_checksum_v4 (vm, b0);
+}
+
+void
+convert_interest_to_data_v6 (vlib_main_t *vm, vlib_buffer_t *b0,
+ vlib_buffer_t *rb, u32 bi0)
+{
+ hicn_header_t *h0 = vlib_buffer_get_current (b0);
+
+ /* Get the packet length */
+ uint16_t pkt_len =
+ clib_net_to_host_u16 (h0->v6.ip.len) + sizeof (ip6_header_t);
+
+ /*
+ * Figure out how many bytes we can add to the content
+ *
+ * Rule of thumb: We want the size of the IP packet to be <= 1400 bytes
+ */
+ u16 bytes_to_copy = rb->current_length;
+ if ((bytes_to_copy + pkt_len) > 1500)
+ {
+ bytes_to_copy = 1500 - pkt_len;
+ }
+ /* Add content to the data packet */
+ vlib_buffer_add_data (vm, &bi0, rb->data, bytes_to_copy);
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ h0 = vlib_buffer_get_current (b0);
+ ip6_address_t src_addr = h0->v6.ip.saddr;
+ h0->v6.ip.saddr = h0->v6.ip.daddr;
+ h0->v6.ip.daddr = src_addr;
+
+ h0->v6.ip.len = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0) -
+ sizeof (ip6_header_t));
+ h0->v6.tcp.data_offset_and_reserved |= 0x0f;
+ h0->v6.tcp.urg_ptr = htons (0xffff);
+
+ calculate_tcp_checksum_v6 (vm, b0);
+}
+
+VLIB_NODE_FN (hicn_pg_server6_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return hicnpg_node_server_fn (vm, node, frame, 1 /* is_v6 */);
+}
+
+VLIB_NODE_FN (hicn_pg_server4_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return hicnpg_node_server_fn (vm, node, frame, 0 /* is_v6 */);
+}
+
+VLIB_REGISTER_NODE(hicn_pg_server6_node) =
+{
+ .name = "hicnpg-server-6",
+ .vector_size = sizeof(u32),
+ .format_trace = format_icnpg_server_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(icnpg_server_error_strings),
+ .error_strings = icnpg_server_error_strings,
+ .n_next_nodes = HICNPG_SERVER_N_NEXT,
+ /* edit / add dispositions here */
+ .next_nodes =
+ {
+ [HICNPG_SERVER_NEXT_V4_LOOKUP] = "ip4-lookup",
+ [HICNPG_SERVER_NEXT_V6_LOOKUP] = "ip6-lookup",
+ [HICNPG_SERVER_NEXT_DROP] = "error-drop",
+ },
+};
+
+VLIB_REGISTER_NODE(hicn_pg_server4_node) =
+{
+ .name = "hicnpg-server-4",
+ .vector_size = sizeof(u32),
+ .format_trace = format_icnpg_server_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(icnpg_server_error_strings),
+ .error_strings = icnpg_server_error_strings,
+ .n_next_nodes = HICNPG_SERVER_N_NEXT,
+ /* edit / add dispositions here */
+ .next_nodes =
+ {
+ [HICNPG_SERVER_NEXT_V4_LOOKUP] = "ip4-lookup",
+ [HICNPG_SERVER_NEXT_V6_LOOKUP] = "ip6-lookup",
+ [HICNPG_SERVER_NEXT_DROP] = "error-drop",
+ },
+};
+
+/*
+ * End of packet-generator server node
+ */ \ No newline at end of file
diff --git a/hicn-plugin/src/route.c b/hicn-plugin/src/route.c
index a84891b9a..0c96e1412 100644
--- a/hicn-plugin/src/route.c
+++ b/hicn-plugin/src/route.c
@@ -34,6 +34,7 @@
#include "infra.h"
#include "udp_tunnels/udp_tunnel.h"
#include "mapme.h"
+#include "pg.h"
#define FIB_SOURCE_HICN 0x04 // Right after the FIB_SOURCE_INTERFACE priority
@@ -234,7 +235,7 @@ sync_hicn_fib_entry (hicn_dpo_ctx_t *fib_entry, hicn_face_id_t **pvec_faces)
do \
{ \
/* Careful, this adds a lock on the face if it exists */ \
- hicn_face_add (dpo, nh, sw_if, &face_id, 0); \
+ hicn_face_add (dpo, nh, sw_if, &face_id); \
vec_validate (vec_faces, index); \
vec_faces[index] = face_id; \
(index)++; \
@@ -294,10 +295,15 @@ sync_hicn_fib_entry (hicn_dpo_ctx_t *fib_entry, hicn_face_id_t **pvec_faces)
default:
continue;
}
- HICN_DEBUG ("Added new UDP face: %d because of route prefix %s",
+ HICN_DEBUG ("Added new UDP face: %d because of route prefix %U",
face_id, format_ip_prefix, &_fib_entry->fe_prefix);
udp_tunnel_add_existing (dpo->dpoi_index, proto);
}
+ else if (dpo_is_pgserver (dpo))
+ {
+ hicnpg_server_t *pg_server = hicnpg_server_get (dpo->dpoi_index);
+ ADD_FACE (&pg_server->hicn_locator);
+ }
}
const hicn_dpo_vft_t *strategy_vft = hicn_dpo_get_vft (fib_entry->dpo_type);
diff --git a/hicn-plugin/src/strategy_node.c b/hicn-plugin/src/strategy_node.c
index 66d9c2dbb..3ff2d0209 100644
--- a/hicn-plugin/src/strategy_node.c
+++ b/hicn-plugin/src/strategy_node.c
@@ -66,7 +66,7 @@ hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next,
f64 tnow, u8 *nameptr, u16 namelen, hicn_face_id_t outface,
int nh_idx, index_t dpo_ctx_id0,
const hicn_strategy_vft_t *strategy, dpo_type_t dpo_type,
- u8 isv6, vl_api_hicn_api_node_stats_get_reply_t *stats,
+ vl_api_hicn_api_node_stats_get_reply_t *stats,
u8 is_replication)
{
int ret;
@@ -81,6 +81,7 @@ hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next,
u8 hash_entry_id = 0;
u8 bucket_is_overflow = 0;
u32 bucket_id = ~0;
+ u8 isv6 = hicn_buffer_is_v6 (b0);
if (is_replication)
{
@@ -202,27 +203,22 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
while (n_left_from > 0 && n_left_to_next > 0)
{
- u8 isv6;
u8 *nameptr;
u16 namelen;
- hicn_name_t name;
- hicn_header_t *hicn0;
vlib_buffer_t *b0;
u32 bi0;
hicn_face_id_t outfaces[MAX_OUT_FACES];
u32 outfaces_len;
int nh_idx;
u32 next0 = next_index;
- int ret;
/* Prefetch for next iteration. */
if (n_left_from > 1)
{
vlib_buffer_t *b1;
b1 = vlib_get_buffer (vm, from[1]);
- CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (&b1->trace_handle, 2 * CLIB_CACHE_LINE_BYTES,
- STORE);
+ CLIB_PREFETCH (b1, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES, LOAD);
}
/* Dequeue a packet buffer */
bi0 = from[0];
@@ -248,7 +244,8 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
const hicn_strategy_vft_t *strategy =
hicn_dpo_get_strategy_vft (dpo_ctx->dpo_type);
- ret = hicn_interest_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
+ hicn_buffer_get_name_and_namelen (b0, &nameptr, &namelen);
+
stats.pkts_processed++;
/* Select next hop */
/*
@@ -256,8 +253,7 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
* the interest-pcslookup node due to misconfiguration in
* the punting rules.
*/
- if (PREDICT_TRUE (ret == HICN_ERROR_NONE &&
- HICN_IS_NAMEHASH_CACHED (b0) &&
+ if (PREDICT_TRUE (HICN_IS_NAMEHASH_CACHED (b0) &&
strategy->hicn_select_next_hop (
vnet_buffer (b0)->ip.adj_index[VLIB_TX], &nh_idx,
outfaces, &outfaces_len) == HICN_ERROR_NONE))
@@ -267,7 +263,6 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
* here. Already checked in the interest_pcslookup
* node
*/
- nameptr = (u8 *) (&name);
u32 clones[outfaces_len];
if (outfaces_len > 1)
{
@@ -295,7 +290,7 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
rt, local_b0, &next0, tnow, nameptr, namelen,
outfaces[nh], nh_idx,
vnet_buffer (local_b0)->ip.adj_index[VLIB_TX],
- strategy, dpo_ctx->dpo_type, isv6, &stats, 0);
+ strategy, dpo_ctx->dpo_type, &stats, 0);
}
else
{
@@ -304,7 +299,7 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
rt, local_b0, &next0, tnow, nameptr, namelen,
outfaces[nh], nh_idx,
vnet_buffer (local_b0)->ip.adj_index[VLIB_TX],
- strategy, dpo_ctx->dpo_type, isv6, &stats, 1);
+ strategy, dpo_ctx->dpo_type, &stats, 1);
}
/* Maybe trace */
@@ -314,7 +309,7 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
{
hicn_strategy_trace_t *t =
vlib_add_trace (vm, node, local_b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
+ t->pkt_type = HICN_PACKET_TYPE_DATA;
t->sw_if_index =
vnet_buffer (local_b0)->sw_if_index[VLIB_RX];
t->next_index = next0;
@@ -376,4 +371,4 @@ VLIB_REGISTER_NODE (hicn_strategy_node) =
* fd.io coding-style-patch-verification: ON
*
* Local Variables: eval: (c-set-style "gnu") End:
- */
+ */ \ No newline at end of file